Soul网关-day08

Soul网关-day08

Soul-plugin-sofa测试(三)

​ 接第7天的话题,可以看到token为null以后直接返回errorResponse的类为 StatelessAuthFilter。这个类是框架定义的,那么我们是在哪里将这个Filter集成进我们的shiro框架呢?

​ eclipse和idea中都提供了调用查询的功能,这里可以看到:是在org.dromara.soul.admin.shiro.config.ShiroConfiguration中的

@Bean
public ShiroFilterFactoryBean shiroFilterFactoryBean(
        @Qualifier("shiroSecurityManager") final DefaultWebSecurityManager securityManager,
        @Qualifier("whiteList") final List<String> whiteList)

这个方法将ShiroFilterFactoryBean交给Spring托管,在这个方法中定义了一个filterMap;将StatelessAuthFilter塞进这个map中(key为statelessAuth),再将这个map塞进factoryBean的filter中。这个Filter定义了过滤器的行为;紧接在后的就是定义过滤器的作用域了,具体实现代码如下:

        Map<String, String> filterChainDefinitionMap = new LinkedHashMap<>();

        for (String s : whiteList) {
            filterChainDefinitionMap.put(s, "anon");
        }

        filterChainDefinitionMap.put("/**", "statelessAuth");
        factoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);

可以看到,在上述代码中,whiteList中定义的所有路径都不进行过滤操作(anon),而除了whiteList中的所有路径,都需要经过statelessAuth这个过滤器的过滤,所以这就能解释为什么有些请求路径可以被直接访问,而有些路径则不行,而whiteList是在soul-admin的配置文件中进行配置的:

application.yml:
	soul:
	  jwt:
    	key: 2095132720951327
      shiro:
    	white-list: /,/favicon.*,/static/**,/index**,/plugin,/platform/**,/websocket,/configs/**,/soul-client/**

​ ShiroConfiguration中还定义了:securityManager,并将自定义的shiroRealm作为Realm塞进了securityManager;ShiroRealm中主要定义了两个方法:

protected AuthorizationInfo doGetAuthorizationInfo(final PrincipalCollection principalCollection)
protected AuthenticationInfo doGetAuthenticationInfo(final AuthenticationToken authenticationToken) 

​ 其中doGetAuthenticationInfo是在shiro登陆时被调用的

​ doGetAuthorizationInfo方法是在一下两个阶段被调用的:

1:调用SecurityUtils.getSubject().isPermitted(String str)方法时会调用doGetAuthorizationInfo方法,

2:在配置文件中配置有类似/**=roles["user"]或者/**=perms[“user”](/**路径是开发者自行定义)的配置的时候会调用doGetAuthorizationInfo方法,这个时候有两种情况:
  2.1:当当前没有用户登录时shiro会帮我们跳转到login.jsp(默认会找根目录下的login.jsp)
  2.2:当前有登录用户时shiro会自动判定当前登录用户的角色或者权限符合访问当前访问路径,如果不符合那么将跳转到开发者所配置的未授权提示页面( <property name="unauthorizedUrl" value="/unauthorized.jsp"/>),这种调用情下doGetAuthorizationInfo方法只会被调用一次,除非更换了当前登录用户。

而在ShiroRealm的doGetAuthenticationInfo方法可以看到:

    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(final AuthenticationToken authenticationToken) {
        StatelessToken token = (StatelessToken) authenticationToken;
        if (token == null || token.getToken() == null) {
            return null;
        }

        String userName = JwtUtils.getIssuer(token.getToken());

        token.setUserName(userName);

        return new SimpleAuthenticationInfo(userName, token.getToken(), this.getName());
    }

从命名猜测,这里是将得到的 jwt token校验、解码后得到user的名称,为shiro管理的authenticationToken的userName属性赋予得到用户名。

​ 但似乎确实没太大关联,抓包以后可以看到:

在这里插入图片描述

而whiteList上只配置了/plugin这个路径,这个请求路径:/plugin/all必然会被statelessAuth这个过滤器所拦截,在statelessAuth这个类上的onAccessDenied方法上的逻辑是:

   //得到httpRequest
   HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
   //判断是否为Options的请求,如果是,则直接返回true;
   if (StringUtils.equals(HttpMethod.OPTIONS.name(), httpServletRequest.getMethod())) {
            return true;
        }
		//从request中获取X-Access-Token这个属性
        String tokenValue = httpServletRequest.getHeader(HEAD_TOKEN);
        if (StringUtils.isBlank(tokenValue)) {
            log.error("token is null.");
            unionFailResponse(servletResponse);
            return false;
        }
		//只有获取到了这个属性,才能构建出一个StatelessToken
        StatelessToken token = new StatelessToken();
        token.setToken(tokenValue);

        Subject subject = getSubject(servletRequest, servletResponse);

        try {
            //用token进行登录
            subject.login(token);
        } catch (Exception e) {
            log.error("token is warning. token : {}.", tokenValue, e);
            unionFailResponse(servletResponse);
            return false;
        }

        return true;

从上面的抓包很明显看出:并没有这个属性。大概需要求助了…问下如何构建这个request请求的。还不知道这个request请求到底哪出了问题…

### Soul 网关概述 Soul 网关是一款高性能、可扩展的微服务网关,其设计灵感来源于 Kong 和 Spring Cloud Gateway 等优秀开源项目[^2]。它支持多种协议和插件化功能,能够满足复杂的业务需求。 #### 特点 Soul 网关具有以下显著特点: - **高可用性和性能**:基于 WebFlux 框架构建,提供异步非阻塞的能力,从而提升系统的吞吐量和响应速度[^4]。 - **灵活的插件机制**:通过插件形式实现各种中间层逻辑处理,例如限流、熔断、日志记录等功能[^1]。 - **多协议支持**:除了 HTTP 协议外,还支持 Dubbo、gRPC 等其他通信协议[^5]。 #### 架构图 以下是 Soul 网关的核心架构概览: ```plaintext +-------------------+ | Admin UI | +---------+--------+ | v +---------+--------+ | Data Sync | -----> Redis/MQ (消息队列) +---------+--------+ | v +---------+--------+ | Plugin | +---------+--------+ | v +---------+--------+ | Gateway Engine | +---------+--------+ ``` 该架构展示了如何通过管理界面配置规则并实时同步到网关引擎中执行相应操作[^3]。 #### 安装与部署指南 为了快速上手 Soul 网关,可以按照如下方式准备开发环境: 1. 下载官方发布的最新版本源码或者二进制包; 2. 配置必要的依赖组件(如 MySQL 数据库用于存储元数据;Redis 或 Kafka 实现动态更新推送); 3. 启动应用后访问默认端口 `8080` 查看运行状态。 #### 示例代码片段 下面是一个简单的 Spring Boot 应用集成 Divide 插件的例子来展示如何定义路由规则: ```java import org.springframework.context.annotation.Bean; import org.springframework.stereotype.Component; @Component public class SoulConfig { @Bean public DivideRule divideRule() { DivideRule rule = new DivideRule(); rule.setContextPath("/example"); rule.setUrlList(Collections.singletonList("http://localhost:9090")); return rule; } } ``` 此段程序设置了当匹配路径 `/example` 的请求会转发给目标服务器监听于 `http://localhost:9090` 地址的服务实例上去完成后续调用过程。 ---
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值