Solon

sa-token-solon-plugin

<dependency>
    <groupId>org.noear</groupId>
    <artifactId>sa-token-solon-plugin</artifactId>
</dependency>

1、描述

签权扩展插件,对 sa-token 签权框架进行适配。

2、拦截处理的适配对比

拦截类实现机制备注
SaTokenFilter基于 Filter 实现(对静态文件有控制权)v1.12.3 后支持
SaTokenInterceptor基于 RouterInterceptor 实现(只对动态路由有效)v1.12.3 后支持
SaTokenPathFilter [弃用]同于 SaTokenFilter
SaTokenPathInterceptor [弃用]基于 Handler 实现(将由 SaTokenInterceptor 替代)

要了解它们的作用范围,可以看下《请求处理过程示意图》

3、对接使用示例

  • 配置:
# sa-token配置
sa-token:
  # token名称 (同时也是cookie名称)
  token-name: satoken
  # token有效期,单位s 默认30天, -1代表永不过期
  timeout: 2592000
  # token临时有效期 (指定时间内无操作就视为token过期) 单位: 秒
  activity-timeout: -1
  # 是否允许同一账号并发登录 (为true时允许一起登录, 为false时新登录挤掉旧登录)
  allow-concurrent-login: true
  # 在多人登录同一账号时,是否共用一个token (为true时所有登录共用一个token, 为false时每次登录新建一个token)
  is-share: true
  # token风格
  token-style: uuid
  # 是否输出操作日志
  is-log: false
  • 对接代码:

1)添加拦截器(用于支持"路径规则"和"注解处理",支持 @SaIgnore 注解):

@Configuration
public class Config {
  @Bean(index = -100) //-100,是顺序位(低值优先)
  public void tokenPathInterceptor() {
     return new SaTokenInterceptor(); //用于支持规划处理及注解处理
  }
}

2)一般,我们会在 SaTokenInterceptor 上增加一些必要的路由规则和一些必要设定:

@Configuration
public class Config {
  @Bean(index = -100)  //-100,是顺序位(低值优先)
  public void tokenPathInterceptor() {
     return new SaTokenInterceptor()
        // 指定 [拦截路由] 与 [放行路由]
        .addInclude("/**").addExclude("/favicon.ico")

        // 认证函数: 每次请求执行
        .setAuth(req -> {
          // System.out.println("---------- sa全局认证");
          SaRouter.match("/**", StpUtil::checkLogin);

          // 根据路由划分模块,不同模块不同鉴权
          SaRouter.match("/user/**", r -> StpUtil.checkPermission("user"));
          SaRouter.match("/admin/**", r -> StpUtil.checkPermission("admin"));
        })

        // 异常处理函数:每次认证函数发生异常时执行此函数 //包括注解异常
        .setError(e -> {
          System.out.println("---------- sa全局异常 ");
          return AjaxJson.getError(e.getMessage());
        })

        // 前置函数:在每次认证函数之前执行
        .setBeforeAuth(req -> {
          // ---------- 设置一些安全响应头 ----------
          SaHolder.getResponse()
              // 服务器名称
              .setServer("sa-server")
              // 是否可以在iframe显示视图: DENY=不可以 | SAMEORIGIN=同域下可以 | ALLOW-FROM uri=指定域名下可以
              .setHeader("X-Frame-Options", "SAMEORIGIN")
              // 是否启用浏览器默认XSS防护: 0=禁用 | 1=启用 | 1; mode=block 启用, 并在检查到XSS攻击时,停止渲染页面
              .setHeader("X-XSS-Protection", "1; mode=block")
              // 禁用浏览器内容嗅探
              .setHeader("X-Content-Type-Options", "nosniff");
        });
  }
}

3)它还可以支持“注解”控制权限:

// 登录认证:只有登录之后才能进入该方法 
@SaCheckLogin                        
@Mapping("info")
public String info() {
    return "查询用户信息";
}

// 角色认证:必须具有指定角色才能进入该方法 
@SaCheckRole("super-admin")        
@Mapping("add")
public String add() {
    return "用户增加";
}

// 权限认证:必须具有指定权限才能进入该方法 
@SaCheckPermission("user-add")        
@Mapping("add")
public String add() {
    return "用户增加";
}

4、Sa Token Redis Dao 使用示例

  • 添加 redisx 框架依赖
<dependency>
    <groupId>org.noear</groupId>
    <artifactId>redisx</artifactId>
</dependency>
  • 配置:
sa-token-dao: #名字可以随意取
  redis:
    server: "localhost:6379"
    password: 123456
    db: 1
    maxTotal: 200
  • 构建Bean代码:
@Configuration
public class Config {
    @Bean
    public SaTokenDao saTokenDaoInit(@Inject("${sa-token-dao.redis}") SaTokenDaoOfRedis saTokenDao) {
        return saTokenDao;
    }
}

5、借用 solon.auth 的注解与模板标签能力(如果用不到,则不引入;一般是用不到的)

添加桥接配置代码

@Configuration
public class AuthBridgingConfig {
    @Bean
    public AuthAdapter initAuth(){
        return new AuthAdapter()
                .processor(new AuthProcessorImpl()) //设定认证处理器
                .failure((ctx, rst) -> { //设定默认的验证失败处理
                    ctx.render(rst);
                });
    }

    public static class AuthProcessorImpl implements AuthProcessor {
        @Override
        public boolean verifyIp(String ip) {
            return false;
        }

        @Override
        public boolean verifyLogined() {
            return StpUtil.isLogin();
        }

        @Override
        public boolean verifyPath(String path, String method) {
            return false;
        }

        @Override
        public boolean verifyPermissions(String[] permissions, Logical logical) {
            if (Logical.AND == logical) {
                return StpUtil.hasPermissionAnd(permissions);
            } else {
                return StpUtil.hasPermissionOr(permissions);
            }
        }

        @Override
        public boolean verifyRoles(String[] roles, Logical logical) {
            if (Logical.AND == logical) {
                return StpUtil.hasRoleAnd(roles);
            } else {
                return StpUtil.hasRoleOr(roles);
            }
        }
    }
}

使用 solon.auth 的后台模板标签能力(支持所有已适配模板):

<@authPermissions name="user:del">
我有user:del权限
</@authPermissions>

<@authRoles name="admin">
我有admin角色
</@authRoles>

具体可参考

https://gitee.com/noear/solon-examples/tree/main/3.Solon-Web/demo3032-auth_sa_token