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请求到底哪出了问题…

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值