likes
comments
collection
share

一个基于 Spring Security 的动态权限控制快速使用包

作者站长头像
站长
· 阅读数 13

前言

在日常项目中,Spring Security 的默认认证流程满足不了的需求。

但是,一般的项目对于认证、鉴权这块儿的需要又是十分类似的。

所以,我针对日常项目的认证鉴权需求,将 Spring Security 进行了一层包装。

项目地址、以及测试项目地址,都放在文尾了。

项目说明

本项目完全基于 Spring Security,只针对日常开发项目中的认证、动态权限需求做一层封装。

干净纯洁,没有其他乱七八糟的功能。

可用于项目快速开发Spring Security 框架学习

另鉴于目前 JWT 用的最多,内置封装逻辑为,认证成功后生成 token 返回。

token 中包含 userId、roleIds。Token 内容示例:

 {
 alg: "HS256"
 }.
 {
 roles: "10,1,5",
 exp: 1626480624,
 userId: "1"
 }.
 [signature]

效果展示

  1. 正常登录

    一个基于 Spring Security 的动态权限控制快速使用包

  2. 缺少参数登录

    一个基于 Spring Security 的动态权限控制快速使用包

  3. 正常访问

    一个基于 Spring Security 的动态权限控制快速使用包

  4. 无权限访问

    一个基于 Spring Security 的动态权限控制快速使用包

  5. 未登录访问

    一个基于 Spring Security 的动态权限控制快速使用包

  6. Token 错误访问

    一个基于 Spring Security 的动态权限控制快速使用包

包说明

 ├─authentication 鉴权相关处理
 ├─authorization  认证相关处理
 ├─config         Security配置
 ├─constant       常量
 ├─filter         过滤器(登录入口、JWT 处理入口)
 ├─handle         认证、鉴权结果处理器
 ├─loginlogic     抽象登录逻辑
 │  └─base
 ├─model          实体
 └─utils          工具类

总体流程

登录请求

一个基于 Spring Security 的动态权限控制快速使用包

业务请求

一个基于 Spring Security 的动态权限控制快速使用包

快速使用

  1. 引入依赖

此包未发布到中央仓库,请自行安装至本地仓库。

 <dependency>
     <groupId>pri.damai</groupId>
     <artifactId>fast-security</artifactId>
     <version>0.0.1-SNAPSHOT</version>
 </dependency>
  1. 提供用户查询接口。

    也就是对接用户数据库。

 @Component
 public class UserServiceImpl{
  
     static List<FastUserInfo> userList = new ArrayList<>();
     // .....
     public FastUserInfo loadUserByPhone(String phone) {
         return userList.stream()
                 .filter(user -> user.getPhone().equals(phone))
                 .findAny()
                 .orElseThrow(() -> new AuthenticationServiceException("无此用户"));
     }
 }
  1. 实现登录逻辑

    有几种登录方式,就有几种实现类。注意getSupportLoginType()返回值要区别开。

 @Component
 public class PhoneLogin extends AbstractLoginLogic {
  
     @Resource
     UserServiceImpl userService;
  
     @Override
     public String getSupportLoginType() {
         return "phone";
     }
  
     @Override
     public void checkParam(LoginData loginData) throws AuthenticationException {
         String msg = null;
         if (loginData.getPhone() == null) {
             msg = "手机号不可为空";
         }
         if (loginData.getPhoneVerifyCode() == null) {
             msg = msg + ", 短信验证码不可为空";
         }
         if (!Objects.equals(msg, null)) {
             this.throwException(msg);
         }
     }
  
     @Override
     protected void login(LoginData loginData) throws AuthenticationException {
         if (!"22".equals(loginData.getPhoneVerifyCode())) {
             this.throwException("验证码错误");
         }
         // 具体登录逻辑
         FastUserInfo fastUserInfo = this.getUserDetails(loginData);
     }
  
     @Override
     public FastUserInfo getUserDetails(LoginData loginData) {
         return userService.loadUserByPhone(loginData.getPhone());
     }
  
     private void throwException(String msg) {
         throw new AuthenticationServiceException(msg);
     }
 }
  1. 实现 ResourceService 接口 。

    通过此接口,提供权限查询功能。也就是对接权限数据库。缓存不缓存就在于你自己的实现了。

 @Component
 public class MyResourceImpl implements ResourceService {
  
     static HashMap<String, List<String>> roleMap = new HashMap<>();
     // ......
     @Override
     public List<String> getRolesByUrl(String url) {
         return roleMap.get(url);
     }
 }

其他扩展功能

可选 yml 配置

以下配置均有默认值,有指定要求时再配置即可。

 fast-security:
   not-login-urls: # 指定无需登录即可访问的接口
     - /user
   login-url: # 指定登录接口的url
   expiration: # 指定 token 过期时间
   jwt-secret: # 指定 Jwt 密匙
   authentication-failed-code: # 指定登录失败错误码
   unauthorized-code: # 指定未认证错误码
   permission-denied-code:  # 指定未授权错误码
   no-roles-pass: # 未配置Url时,是否直接放行

登录成功处理器

在实际开发中,我们可能需要存储 token。可实现 LoginSuccessResultHandler 接口来自定义功能。

 @Component
 public class GGLoginSuccessResultHandler implements LoginSuccessResultHandler {
     @Override
     public Object handleResult(UserDetails userDetails, String token) {
         // 保存 token or 其他操作
         return null;
     }
 }

自定义登录失败处理器

@Component
public class GGLoginFailureResultHandler implements LoginFailureResultHandler {
    @Override
    public Object handleResult(AuthenticationException e) {
        return null;
    }
}

GIT地址

Fast-Security

Fast-Security-Test

对你有用的话,记得点个小星星⭐⭐⭐。

转载自:https://juejin.cn/post/6986595187812204551
评论
请登录