Spring Security的授权管理器实现

简介: Spring Security的授权管理器涉及用户登录后的token验证和权限检查。当用户携带token访问时,框架会验证token合法性及用户访问权限。自定义授权管理器`TokenAuthorizationManager`需实现`AuthorizationManager<RequestAuthorizationContext>`接口,处理校验逻辑,包括解析token、判断用户角色与访问资源的匹配。配置中在`SecurityConfig`注册该管理器以生效。测试表明,具有不同角色的用户可访问相应权限的资源,否则返回403错误。

Spring Security的授权管理器

当用户登录以后,携带了token访问后端,那么此时Spring Security框架就要对当前请求进行验证,验证包含了两部分,第一验证携带的token是否合法,第二验证当前用户是否拥有当前访问资源的权限。

1. 整体实现思路

暂时无法在飞书文档外展示此内容

  • 403错误:表示请求需要授权,前端一般会提示没有权限访问

2. 自定义授权管理器

我们创建一个类:TokenAuthorizationManager ,这个类有两个要求

  • 被spring容器进行管理,所以需要添加@Component注解
  • 实现AuthorizationManager<RequestAuthorizationContext>接口,并重写check方法,在方法中编写校验逻辑
package com.itheima.project.config;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.itheima.project.util.JwtUtil;
import com.itheima.project.vo.UserAuth;
import io.jsonwebtoken.Claims;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.authorization.AuthorizationDecision;
import org.springframework.security.authorization.AuthorizationManager;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.access.intercept.RequestAuthorizationContext;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest;
import java.util.function.Supplier;
/**
 * @author sjqn
 */
@Component
public class TokenAuthorizationManager implements AuthorizationManager<RequestAuthorizationContext> {
    @Override
    public AuthorizationDecision check(Supplier<Authentication> authentication, RequestAuthorizationContext requestAuthorizationContext) {
        //获取request
        HttpServletRequest request = requestAuthorizationContext.getRequest();
        //获取用户当前的请求地址
        String requestURI = request.getRequestURI();
        //获取token
        String token = request.getHeader("token");
        if(null == token || "".equals(token)){
            return new AuthorizationDecision(false);
        }
        //解析token
        Claims claims = JwtUtil.parseJWT("itcast", token);
        if (ObjectUtil.isEmpty(claims)) {
            //token失效
            return new AuthorizationDecision(false);
        }
        //获取userAuth
        UserAuth userAuth = JSONObject.parseObject(JSON.toJSONString(claims.get("user")),UserAuth.class);
        //存入上下文
        UsernamePasswordAuthenticationToken auth
                =new UsernamePasswordAuthenticationToken( userAuth, userAuth.getPassword(), userAuth.getAuthorities());
        SecurityContextHolder.getContext().setAuthentication(auth);
        //判断地址与对象中的角色是否匹配
        if(userAuth.getRoles().contains("ADMIN")){
            if("/hello/admin".equals(requestURI)){
                return new AuthorizationDecision(true);
            }
        }
        if(userAuth.getRoles().contains("USER")){
            if("/hello/user".equals(requestURI)){
                return new AuthorizationDecision(true);
            }
        }
        return new AuthorizationDecision(false);
    }
}

3. 注册授权管理器

授权管理器想要生效需要在SecurityConfig中进行注册才能使用

package com.itheima.project.config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
/**
 * @author sjqn
 */
@Configuration
public class SecurityConfig {
    @Autowired
    private TokenAuthorizationManager tokenAuthorizationManager;
    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http.authorizeHttpRequests().antMatchers("/security/login").permitAll()
                .anyRequest().access(tokenAuthorizationManager);
        
        //关闭session
        http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
        //关闭缓存
        http.headers().cacheControl().disable();
        
        http.csrf().disable();
        //返回
        return http.build();
    }
    @Bean
    public AuthenticationManager authenticationManager(AuthenticationConfiguration authenticationConfiguration) throws Exception {
        return authenticationConfiguration.getAuthenticationManager();
    }
    @Bean
    PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
}

4. 测试

重启项目之后可以采用postman或者apifox进行测试

  • 测试一:
  • 登录账号:user@qq.com     拥有角色:USER
  • 可以访问:/hello/user
  • 其他请求返回403
  • 测试二:
  • 登录账号:admin@qq.com     拥有角色:USER、ADMIN
  • 可以访问:/hello/user、/hello/user
目录
相关文章
|
5月前
|
安全 Java 数据安全/隐私保护
使用Spring Security实现细粒度的权限控制
使用Spring Security实现细粒度的权限控制
|
5月前
|
安全 Java 数据库
实现基于Spring Security的权限管理系统
实现基于Spring Security的权限管理系统
|
5月前
|
安全 Java 数据安全/隐私保护
解析Spring Security中的权限控制策略
解析Spring Security中的权限控制策略
|
6月前
|
JSON 安全 Java
Spring Security 6.x 微信公众平台OAuth2授权实战
上一篇介绍了OAuth2协议的基本原理,以及Spring Security框架中自带的OAuth2客户端GitHub的实现细节,本篇以微信公众号网页授权登录为目的,介绍如何在原框架基础上定制开发OAuth2客户端。
218 4
Spring Security 6.x 微信公众平台OAuth2授权实战
|
4月前
|
Java Spring
Spring Boot Admin 授权配置
Spring Boot Admin 授权配置
31 0
|
5月前
|
安全 Java 数据安全/隐私保护
使用Spring Security实现细粒度的权限控制
使用Spring Security实现细粒度的权限控制
|
5月前
|
安全 Java 数据安全/隐私保护
使用Java和Spring Security实现身份验证与授权
使用Java和Spring Security实现身份验证与授权
|
5月前
|
存储 安全 Java
Spring Security在企业级应用中的应用
Spring Security在企业级应用中的应用
|
6月前
|
存储 安全 Java
Spring Security与OAuth2集成开发
Spring Security与OAuth2集成开发
|
6月前
|
存储 安全 Java
Spring Boot中的OAuth2认证与授权
Spring Boot中的OAuth2认证与授权
下一篇
无影云桌面