天天看点

SpringSecurity安全框架学习三、用户授权

作者:想要瘦下去的老胖墩

基于权限与角色访问控制

hasAuthority方法:如果当前的主体具有指定的权限则返回true,否则返回false,这种只支持单权限操作

在配置类SecurityConfigTest设置当前访问地址有哪些权限 .antMatchers("/test/index").hasAuthority("admin")

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

        http.formLogin()
                //登录页面设置
                .loginPage("/login.html")
                //登录访问路径
                .loginProcessingUrl("/user/login")
                //登录成功后跳转的页面
                .defaultSuccessUrl("/test/index").permitAll()
                //设置白名单
                .and().authorizeRequests()
                .antMatchers("/test/hello","/user/login").permitAll()
      
                //当前登录用户只有具有admin权限才能访问
                .antMatchers("/test/index").hasAuthority("admins")
      
                //关闭csrf防护
                .anyRequest().authenticated()
                .and().csrf().disable();

    }           

在UserDetailsService,把返回User对象设置权限

List auths = AuthorityUtils.commaSeparatedStringToAuthorityList("admins");

@Service("userDetailsService")
public class MyUserDetailsService implements UserDetailsService {
    @Autowired
    private UsersMapper usersMapper;
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        QueryWrapper<UsersEntity> wrapper = new QueryWrapper<>();
        wrapper.eq("username",username);
        wrapper.last(" limit 1");
        UsersEntity user =  usersMapper.selectOne(wrapper);
        if(user ==null || user.getId() == null){
            throw new UsernameNotFoundException("用户名或密码错误");
        }

        List<GrantedAuthority> auths = AuthorityUtils.commaSeparatedStringToAuthorityList("admins");

        return new User("admin",new BCryptPasswordEncoder().encode("123456"),auths);
    }


}           

hasAnyAuthority:如果当前的主体有任何提供的角色(给定的座位一个逗号分隔的字符串列表)的话返回true

//有admins或者managers允许访问/test/index

.antMatchers("/test/index").hasAnyAuthority("admins,managers")

hashRole:如果用户具备给定角色就允许访问返回true,否则出现403

.antMatchers("/test/index").hasRole("sale")

源码中会判断是否以ROLE_为开头,不包含会加上

SpringSecurity安全框架学习三、用户授权

在UserDetailsService中配置角色也要加上

List<GrantedAuthority> auths = AuthorityUtils.commaSeparatedStringToAuthorityList("admins,ROLE_sale");

hasAnyRole:表示用户具备任何一个条件都可以访问

.antMatchers("/test/index").hasAnyRole("cole","sale")

认证授权注解使用

@Secured:用户有某个角色,可以访问方法

启动类(配置类)开启注解@EnableGlobalMethodSecurity(securedEnabled = true)

@MapperScan("com.cdq.securitydemo1.mapper")

@EnableGlobalMethodSecurity(securedEnabled = true)

@SpringBootApplication

public class Securitydemo1Application

在controller控制层的方法上面使用注解,设置角色

@GetMapping("/update")

@Secured({"ROLE_sale","ROLE_manager"})

public String update(){ return "update"; }

在前面的例子中在MyUserDetailsService为用户添加了ROLE_sale角色

List<GrantedAuthority> auths = AuthorityUtils.commaSeparatedStringToAuthorityList("admins,ROLE_sale");

启动验证可以访问,修改角色名称重新启动登录后访问报403

@PreAuthorize:预授权

在启动类@EnableGlobalMethodSecurity注解中添加prePostEnabled = true

@EnableGlobalMethodSecurity(securedEnabled = true,prePostEnabled = true)

在controller方法中添加@PreAuthorize注解

@GetMapping("/update")

@PreAuthorize("hasAnyAuthority('admins')")

public String update(){ return "update"; }

@PostAuthorize:方法执行之后校验授权

在启动类@EnableGlobalMethodSecurity注解中添加prePostEnabled = true

@EnableGlobalMethodSecurity(securedEnabled = true,prePostEnabled = true)

在controller方法中添加@PostAuthorize注解

@GetMapping("/update")
@PostAuthorize("hasAnyAuthority('admins')")
public String update(){
    return "update";
}           

@PostFilter 过滤返回数据

@GetMapping("/getAll")
@PostFilter("filterObject.username =='admin'")
@PostAuthorize("hasAnyAuthority('admins')")
public List<UsersEntity> getAll(){
    List<UsersEntity> list = new ArrayList<>();
    list.add(new UsersEntity(1,"admin","123456"));
    list.add(new UsersEntity(2,"张三","123456"));
    return list;
}           

只返回符合条件的数据

SpringSecurity安全框架学习三、用户授权

@PreFilter:过滤参数

@GetMapping("/getAll")
@PreFilter("filterObject.username =='admin'")
@PostAuthorize("hasAnyAuthority('admins')")
public List<UsersEntity> postUsers(List<UsersEntity> list){
    
    return list;
}           

继续阅读