Bootstrap

SpringSecurity:授权

目录

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);

}

;