目录

SpringSecurity 有两种授权方式

基于角色的授权

基于权限的授权

使用注解判断权限

过滤器


用户登录后会根据用户的身份进行角色划分,比如登录图书馆系统,一般就有管理员和普通学生等不同角色。

用户的一个操作实际上就是在访问我们提供的`接口`(编写的对应访问路径的 Servlet),比如登陆,就需要调用`/login`接口,退出登陆就要调用/`logout`接口,因此,决定用户能否使用某个功能,只需要决定用户是否能够访问对应的 Servlet

SpringSecurity 有两种授权方式

- 基于权限的授权:只要拥有某权限的用户,就可以访问某个路径

- 基于角色的授权:根据用户属于哪个角色来决定是否可以访问某个路径

基于角色的授权

需要配置 SpringSecurity决定哪些角色可以访问哪些页面

http
        .authorizeRequests()
        .antMatchers("/static/**").permitAll()
  		.antMatchers("/index").hasAnyRole("user", "admin")   //index页面可以由user或admin访问
        .anyRequest().hasRole("admin")   //除了上面以外的所有内容,只能是admin访问

可以创建一个实体类来接收用户的信息

@Data
public class AuthUser {
    String username;
    String password;
    String role;
}

修改一下用于验证用户信息的service

@Override
public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {
    AuthUser user = mapper.getPasswordByUsername(s);
    if(user == null)
        throw new UsernameNotFoundException("登录失败,用户名或密码错误!");
    return User
            .withUsername(user.getUsername())
            .password(user.getPassword())
            .roles(user.getRole())
            .build();
}

基于权限的授权

基于权限的授权与角色类似,需要以`hasAnyAuthority`或`hasAuthority`进行判断

例子

.anyRequest().hasAnyAuthority("page:index")
@Override
public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {
    AuthUser user = mapper.getPasswordByUsername(s);
    if(user == null)
        throw new UsernameNotFoundException("登录失败,用户名或密码错误!");
    return User
            .withUsername(user.getUsername())
            .password(user.getPassword())
            .authorities("page:index")
            .build();
}

使用注解判断权限

首先需要在相应的配置类(注意只是在 Mvc 的配置类上添加,就只针对 Controller 进行过滤,因为所有的 Controller 是由 Mvc 配置类进行注册的,如果需要为 Service 或其他 Bean 也启用权限判断,则需要在 Security 的配置类上添加)上开启

@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter

接着就可以直接在需要添加权限验证的请求映射上添加注解

通过添加`@PreAuthorize`注解,在执行之前判断判断权限,如果没有对应的权限或是对应的角色,将无法访问页面

@PreAuthorize("hasRole('user')")   //判断是否为user角色,只有此角色才可以访问
@RequestMapping("/index")
public String index(){
    return "index";
}

同样的还有`@PostAuthorize`注解,它是在方法执行之后再进行拦截

@PostAuthorize("hasRole('user')")
@RequestMapping("/index")
public String index(){
    System.out.println("执行了");
    return "index";
}

只要是由 Spring 管理的 Bean 都可以使用注解形式来控制权限,只要不具备访问权限,那么就无法执行方法并且会返回 403 页面

@Service
public class UserService {
    @PreAuthorize("hasAnyRole('user')")
    public void test(){
        System.out.println("成功执行");
    }
}

过滤器

使用`@PreFilter`和`@PostFilter`对集合类型的参数或返回值进行过滤

@PreFilter("filterObject.equals('zzp')")   //filterObject代表集合中每个元素,只要满足条件的元素才会留下
public void test(List<String> list){
    System.out.println("成功执行"+list);
}
@RequestMapping("/index")
public String index(){
    List<String> list = new LinkedList<>();
list.add("zzp")
    service.test(list);
    return "index";
}

当有多个集合时,需要使用`filterTarget`进行指定

@PreFilter(value = "filterObject.equals('lbwnb')", filterTarget = "list2")
public void test(List<String> list, List<String> list2){
    System.out.println("成功执行"+list);
}