Skip to content

Satoken 配置白名单只生效一次 #957

Description

@chenliang21210909

建议增加的新功能:

目前 我在使用satoken 和gateway 整合的时候遇到一个问题
我在使用satoken filter 的时候设置白名单的时候 是从nacos 取的动态的url 路径 但是 我频繁的更新我的nacos 配置 但是拦截器没有起作用 代码如下

 public SaReactorFilter getSaReactorFilter(IgnoreUrlsConfig ignoreUrlsConfig) {
        return new SaReactorFilter()
                // 拦截地址
                .addInclude("/**")
                // 配置白名单路径
                .setExcludeList(ignoreUrlsConfig.getUrls())
                // 鉴权方法:每次访问进入
                .setAuth(obj -> {
                    // 对于OPTIONS预检请求直接放行
                    SaRouter.match(SaHttpMethod.OPTIONS).stop();
                    //登录认证 app端 遗留个问题 app的端的token 是否可以访问小程序 目前是可以 如果 需要进行隔离 前缀需要分开 并且校验loginType 参考 ipad 和助手端
                    SaRouter.match(SystemType.SYSTEM_APP, r -> StpAppUtil.checkLogin()).stop();




                    // 登录认证:认证门店端 to-do 统一配置 //门店端新增餐饮登录认证
                    SaRouter.match(SystemType.SYSTEM_STORE, r -> {
                        StpUtil.checkLogin();
                        String loginType = StpUtil.getLoginType();
                        if (StringUtils.equals(loginType, "STORE_WEB")){throw NotLoginException.newInstance("STORE_WEB", "STORE_WEB", "请先登录", null);}
                    }).stop();

                    // 登录认证:认证 门店端 餐饮
                    SaRouter.match(SystemType.STORE_INDUSTRY, r -> {
                        StpUtil.checkLogin();
                        String loginType = StpUtil.getLoginType();
                        if (StringUtils.equals(loginType, "STORE_INDUSTRY")){throw NotLoginException.newInstance("STORE_INDUSTRY", "STORE_INDUSTRY", "请先登录", null);}
                    }).stop();


                    // 登录认证:认证 平台端
                    SaRouter.match(SystemType.SYSTEM_PORTAL, r -> StpPortalUtil.checkLogin()).stop();



                    //助手端认证
                    SaRouter.match(SystemType.ASSISTANT, r -> {
                        StpIPadUtil.checkLogin();
                        String loginType = StpIPadUtil.getLoginType();
                        if (StringUtils.equals(loginType, "PA")){throw NotLoginException.newInstance("PA", "PA", "请先登录", null);}
                    } ).stop();
                    //ipad 端登录认证
                    SaRouter.match(SystemType.IPAD, r -> {
                        StpIPadUtil.checkLogin();
                        String loginType = StpIPadUtil.getLoginType();
                        if(StringUtils.equals(loginType, "IPAD")){
                          throw NotLoginException.newInstance("IPAD", "IPAD", "请先登录", null);
                        }
                    }).stop();
                    //对于通过微服务 没有平台名称的不允许访问
                    throw new NotPermissionException("非法路径 不允许访问");

                })
                // setAuth方法异常处理
                .setError(this::handleException);
    }

白名单的路径是我从nacos 里取的 但是 nacos 自动刷新的时候 拦截器没有起作用

以下是我的修复如下

package com.yeqiao.gateway.config;

import cn.dev33.satoken.exception.NotLoginException;
import cn.dev33.satoken.exception.NotPermissionException;
import cn.dev33.satoken.reactor.context.SaReactorSyncHolder;
import cn.dev33.satoken.reactor.filter.SaReactorFilter;
import cn.dev33.satoken.router.SaHttpMethod;
import cn.dev33.satoken.router.SaRouter;
import cn.dev33.satoken.stp.StpUtil;
import cn.dev33.satoken.util.SaResult;
import com.yeqiao.gateway.constant.SystemType;
import com.yeqiao.gateway.util.StpAppUtil;
import com.yeqiao.gateway.util.StpIPadUtil;
import com.yeqiao.gateway.util.StpPortalUtil;
import com.yeqiao.gateway.util.StringUtils;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.web.server.ServerWebExchange;

import java.util.*;

/**
 * <p>
 *  Sa-Token 权限认证配置类
 * </p>
 *
 * @author yeqiao
 * @since 2022-04-27
 */


@Configuration
public class SaTokenConfig {

    @Bean
    public SaReactorFilter getSaReactorFilter(IgnoreUrlsConfig ignoreUrlsConfig) {
        return new SaReactorFilter()
                // 拦截地址
                .addInclude("/**")
                // 鉴权方法:每次访问进入
                .setAuth(obj -> {
                    // 对于OPTIONS预检请求直接放行
                    SaRouter.match(SaHttpMethod.OPTIONS).stop();
                    SaRouter.match("/**").notMatch(ignoreUrlsConfig.getUrls()).check( ts -> {

                        //登录认证 app端 遗留个问题 app的端的token 是否可以访问小程序 目前是可以 如果 需要进行隔离 前缀需要分开 并且校验loginType 参考 ipad 和助手端
                        SaRouter.match(SystemType.SYSTEM_APP, r -> StpAppUtil.checkLogin()).stop();

                        // 登录认证:认证门店端 to-do 统一配置 //门店端新增餐饮登录认证
                        SaRouter.match(SystemType.SYSTEM_STORE, r -> {
                            StpUtil.checkLogin();
                            String loginType = StpUtil.getLoginType();
                            if (StringUtils.equals(loginType, "STORE_WEB")){throw NotLoginException.newInstance("STORE_WEB", "STORE_WEB", "请先登录", null);}
                        }).stop();

                        // 登录认证:认证 门店端 餐饮
                        SaRouter.match(SystemType.STORE_INDUSTRY, r -> {
                            StpUtil.checkLogin();
                            String loginType = StpUtil.getLoginType();
                            if (StringUtils.equals(loginType, "STORE_INDUSTRY")){throw NotLoginException.newInstance("STORE_INDUSTRY", "STORE_INDUSTRY", "请先登录", null);}
                        }).stop();


                        // 登录认证:认证 平台端
                        SaRouter.match(SystemType.SYSTEM_PORTAL, r -> StpPortalUtil.checkLogin()).stop();



                        //助手端认证
                        SaRouter.match(SystemType.ASSISTANT, r -> {
                            StpIPadUtil.checkLogin();
                            String loginType = StpIPadUtil.getLoginType();
                            if (StringUtils.equals(loginType, "PA")){throw NotLoginException.newInstance("PA", "PA", "请先登录", null);}
                        } ).stop();
                        //ipad 端登录认证
                        SaRouter.match(SystemType.IPAD, r -> {
                            StpIPadUtil.checkLogin();
                            String loginType = StpIPadUtil.getLoginType();
                            if(StringUtils.equals(loginType, "IPAD")){
                                throw NotLoginException.newInstance("IPAD", "IPAD", "请先登录", null);
                            }
                        }).stop();
                        //对于通过微服务 没有平台名称的不允许访问
                        throw new NotPermissionException("非法路径 不允许访问");
                    });
                })
                // setAuth方法异常处理
                .setError(this::handleException);
    }

    private SaResult handleException(Throwable e) {
        //设置错误返回格式为JSON
        ServerWebExchange exchange = SaReactorSyncHolder.getContext();
        ServerHttpResponse response = exchange.getResponse();
        response.getHeaders().setContentType(MediaType.APPLICATION_JSON);
        response.getHeaders().setAccessControlAllowOrigin("*");
        response.getHeaders().setCacheControl("no-cache");
        SaResult result;

        if(e instanceof NotLoginException){
            result = new SaResult(401, "请先登录",null);
        }else if(e instanceof NotPermissionException){
            result = new SaResult(403, "没有权限访问",null);
        }else{
            result = new SaResult(500, "内部错误",e.getMessage());
        }
        return result;

    }
}

在auth 里单独认证的。希望后期这个白名单也可以做成动态的 还是读之前的值 感觉是首次只初始化了一次 既然框架有白名单的功能 不想下沉在做一次了

应用场景阐述:

< 备注:请尽量详细描述功能应用场景 >

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions