在上述入门程序中, 用户名、密码都是框架默认帮我们生成的, 方式不够友好,SpringSecurity也为我们提供了通过配置的形式声明合法的账户信息的方式。
A.声明配置类,定义用户名密码信息
@Configuration
@EnableWebSecurity//开启web安全设置生效
public class SecurityConfig extends WebSecurityConfigurerAdapter {
/**
* 构建认证服务,并将对象注入spring IOC容器,用户登录时,会调用该服务进行用户合法信息认证
* @return
*/
@Bean
public UserDetailsService userDetailsService(){
//从内存获取用户认证信息的服务类(了解)后期用户的信息要从表中获取
InMemoryUserDetailsManager inMemoryUserDetailsManager = new InMemoryUserDetailsManager();
//构建用户,真实开发中用户信息要从数据库加载构建
UserDetails u1 = User
.withUsername("itcast")
.password("{noop}123456")//{noop}:no operration--》表示登录时对避免不做任何操作,说白了就是明文比对
.authorities("P5", "ROLE_ADMIN")//用户的权限信息
.build();
UserDetails u2 = User
.withUsername("itheima")
.password("{noop}123456")
.authorities("P7", "ROLE_SELLER","ROLE_ADMIN")//如果角色也作为一种权限资源,则角色名称的前缀必须加ROLE_
.build();
inMemoryUserDetailsManager.createUser(u1);
inMemoryUserDetailsManager.createUser(u2);
return inMemoryUserDetailsManager;
}
}
说明:
1.在userDetailsService()方法中 返回了一个UserDetailsService对象给spring容器管理,当用户发生登录认证行为时,Spring Security底层会自动调用UserDetailsService类型bean提供的用户信息进行合法比对,如果比对成功则资源放行,否则就认证失败;
2.当前暂时使用InMemoryUserDetailsManager实现类,后续我们也可手动实现UserDetailsService接口,做最大程度的自定义;
B.测试配置账户信息
通过测试,配置的账户和密码信息都是有效的。
4、SpringSecurity自定义授权配置
经过上一小结配置,我们发现用户认证通过后,资源是都可被访问的。如果我们想为不同的用户指定不同的访问资源,该如何实现呢?
接下来,我们通过配置为不同用户访问授权。
4.1 基于编码方式定义授权
@Configuration
@EnableWebSecurity
//@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Bean
@Override
public UserDetailsService userDetailsService(){
InMemoryUserDetailsManager inMemoryUserDetailsManager = new InMemoryUserDetailsManager();
inMemoryUserDetailsManager.createUser(User.withUsername("itcast").password("{noop}123456").authorities("P1","ROLE_ADMIN").build());
inMemoryUserDetailsManager.createUser(User.withUsername("itheima").password("{noop}123456").authorities("O1","ROLE_SELLER").build());
return inMemoryUserDetailsManager;
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.formLogin()//开启默认form表单登录方式
.and()
.logout()//登出用默认的路径登出 /logout
.permitAll()//允许所有的用户访问登录或者登出的路径
.and()
.csrf().disable()//启用CSRF,防止CSRF攻击
.authorizeRequests()//授权方法,该方法后有若干子方法进行不同的授权规则处理
//允许所有账户都可访问(不登录即可访问),同时可指定多个路径
.antMatchers("/register").permitAll()
//开发方式1:基于配置
// .antMatchers("/a1","/a2").hasRole("seller")//拥有seller角色的用户可访问a1和a2资源
//拥有指定的任意角色都可以访问对应资源
// .antMatchers("/b1").hasAnyRole("manager1","manager2")
//用户任意指定的aa bb都可以访问c1资源
// .antMatchers("/c1").hasAnyAuthority("aa","bb")
// .antMatchers("/d").denyAll()//拒绝任意用户访问
// .antMatchers("/e").anonymous()//允许匿名访问
//指定IP可以访问
// .antMatchers("/f").hasIpAddress("localhost/82")