在SpringSecurity中身份和权限是分开的,身份也成为角色,其实这里身份和权限标记就是在我们实现的UserDetailsService中设置的

@Slf4j
@Component
public class MyUserDetailsService implements UserDetailsService {
@Autowired
public PasswordEncoder passwordEncoder() {//密码加密
return new BCryptPasswordEncoder();
}

@Override
public UserDetails loadUserByUsername(String userName) throws UsernameNotFoundException {
String pas = passwordEncoder().encode("123456");//
return new User(userName, pas, AuthorityUtils.commaSeparatedStringToAuthorityList("admin,ROLE_root"));
}
}

这里需要注意 :带了ROLE_开头的代表角色,区分大小写!
URL身份、权限配置有两种方式,第一种为代码配置,第二种为注解,起第二种默认为全部关闭

代码配置身份权限校验

@Configuration
@EnableWebSecurity
public class MySecurityConfig extends WebSecurityConfigurerAdapter {

@Bean
public PasswordEncoder passwordEncoder(){//密码加密
return new BCryptPasswordEncoder();
}
@Override
protected void configure(HttpSecurity http) throws Exception {

http
.authorizeRequests()
.antMatchers("/auth/**","/logut/**").permitAll()
.antMatchers("/a").hasAuthority("admin")
.antMatchers("/b").hasRole("root")
.anyRequest()
.authenticated()
.and()
.formLogin()
.permitAll()
.and()
.cors().disable();
}
}

上述配置中,/auth和/logut请求全部放开,这里后面有两个*,这里由于文章编辑器的字符识别,我这里就不打了,然后/a需要admin权限才能访问,/b的话就需要root身份才能访问!这里标识用户权限的就是MyUserDetailsService里面标识的!其中需要注意的是,权限可以为任意字符串标识,而身份的话需要在字符串前加上ROLE_作为前缀,而身份校验的时候则不需要ROLE_作为前缀。这里我测试过了,没什么问题,测试的流程我就不演示了,因为我这里不单是整合SpringSecurity还整合了SpringSecurity OAuth所以登录的流程有些差异!

注解方式身份权限校验
这种方式个人觉得是比较灵活的,而且后期自己模块的权限可以独立配置,无需频繁更改SpringSecurity的核心配置,也就是MySecurityConfig 中的代码!
1.开启注解校验
标记在启动类即可

@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true, jsr250Enabled = true)

2.剔除MySecurityConfig 中的身份、权限配置代码

@Override
protected void configure(HttpSecurity http) throws Exception {

http
.authorizeRequests()
.antMatchers("/auth/**","/logut/**").permitAll()
.anyRequest()
.authenticated()
.and()
.formLogin()
.permitAll()
.and()
.cors().disable();
}

3.在请求上标记需要的身份,权限

@RequestMapping("/a")
public R a(){
log.info("hello");
JSONObject result=new JSONObject();
result.put("data1","a");
return R.ok().setData(result);
}

@Secured("ROLE_root")
@RequestMapping("/b")
public R b(){
log.info("b");
JSONObject result=new JSONObject();
result.put("data1","a");
return R.ok().setData(result);
}


@Secured("ROLE_hr")//专门用于判断是否具有角色,能写在方法或者类上面参数以ROLE_开头
@RequestMapping("/c")
public R c(){
log.info("c");
JSONObject result=new JSONObject();
result.put("data1","c");
return R.ok().setData(result);
}

@PreAuthorize("hasRole('ROLE_root')")
@RequestMapping("/d")
public R d(){
log.info("c");
JSONObject result=new JSONObject();
result.put("data1","d");
return R.ok().setData(result);
}

@PreAuthorize("hasAuthority('root')")
//PreAuthorize允许以ROLE_开头,也可以不以ROLE_开头,注意配置类中是不允许的
@RequestMapping("/e")
public R e(){
log.info("e");
JSONObject result=new JSONObject();
result.put("data1","e");
return R.ok().setData(result);
}


@PreAuthorize("hasAuthority('admin')")//代表执行前判断权限,
@RequestMapping("/f")
public R f(){
log.info("f");
JSONObject result=new JSONObject();
result.put("data1","f");
return R.ok().setData(result);
}

那么这里还是采用上面的MyUserDetailsService 的用户权限,登录的用户有admin权限,和ROLE_root身份,那么这里请求a是登录即可访问,b需要ROLE_root身份才能访问,c需要ROLE_hr身份才能访问!d的需要ROLE_root身份才能访问、e需要root权限才能访问、f需要admin权限才能访问,那么根据MyUserDetailsService 中配置的用户登录身份权限,a、b、d、f是能够访问的!

@Secured(“ROLE_root”):专门用于判断是否具有角色,能写在方法或者类上面参数以ROLE_开头

@PreAuthorize(“hasAuthority(‘admin’)”):即可判断权限,也可以判断身份,当然还可以使用正则判断,如果是判断身份,那么需要填写hasRole(‘ROLE_root’)如方法d,如果判断权限需要填写"hasAuthority(‘admin’)",如方法e、f

@PostAuthorize表示请求执行完后再判断权限,很少用,这两个注解都是方法或者类级别的注解