欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Spring Boot 自定义 Shiro 过滤器,无法使用 @Autowired 解决方法

程序员文章站 2022-06-28 19:30:33
在 Spring Boot 中集成 Shiro,并使用 JWT 进行接口认证。 为了统一对 Token 进行过滤,所以自定义了一个 过滤器。 期间遇到了以下几个问题,这里逐一进行记录,以备日后查阅。 问题一:JwtTokenFilter 无法使用 @Autowired 因为自定义了一个 JWT To ......

在 spring boot 中集成 shiro,并使用 jwt 进行接口认证。

为了统一对 token 进行过滤,所以自定义了一个 jwttokenfilter 过滤器。

期间遇到了以下几个问题,这里逐一进行记录,以备日后查阅。

问题一:jwttokenfilter 无法使用 @autowired

因为自定义了一个 jwt token 工具类,用来解析和创建 token,jwttokenfilter 中需要用到此工具类,这里本来可以直接手动进行 new 一个新的实例,但由于在 spring 配置文件中定义了 jwt 签名密钥和过期时间,所以想使用 spring @configurationproperties 注解进行值得注入,所以这里必须不能手动 new 一个新的实例。

所以在 shiroconfiguration 配置文件中将 jwttokenfilter 过滤器交由 spring 管理:

@bean
public jwttokenfilter jwttokenfilter() {
    return new jwttokenfilter();
}

启动项目进行测试,jwttokenfilter 过滤器中 jwtutil 类成功注入,但又遇到了另外一个问题。

问题二:anon 过滤器失效

在问题一解决后,登录接口一直显示需要认证,所以在只能将 shirofilterfactorybean 中定义的 jwttokenfilter 又改为原先手动 new:

@bean(name = "shirofilter")
public shirofilterfactorybean shirofilterfactorybean() {
    shirofilterfactorybean shirofilterfactorybean = new shirofilterfactorybean();
    shirofilterfactorybean.setsecuritymanager(securitymanager());
    // 注册自定义过滤器
    map<string, filter> filtermap = new linkedhashmap<>(8);
    // 这里只能使用 new 新建实例
    filtermap.put("authc", new jwttokenfilter());
    shirofilterfactorybean.setfilters(filtermap);
    map<string, string> filterchains = new linkedhashmap<>(8);
    filterchains.put("/v1/admin/login", "anon");
    filterchains.put("/**", "authc");
    shirofilterfactorybean.setfilterchaindefinitionmap(filterchains);
    return shirofilterfactorybean;
}

接着创建一个 spring 的上下文管理工具类,代码如下:

package com.nwgdk.ums.common.util;

import org.springframework.beans.beansexception;
import org.springframework.context.applicationcontext;
import org.springframework.context.applicationcontextaware;
import org.springframework.stereotype.component;

/**
 * spring 上下文工具类
 *
 * @author nwgdk
 */
@component
public class springcontextutil implements applicationcontextaware {

    private static applicationcontext applicationcontext;

    @override
    public void setapplicationcontext(applicationcontext applicationcontext) throws beansexception {
        springcontextutil.applicationcontext = applicationcontext;
    }

    /**
     * 获取上下文
     */
    public static applicationcontext getapplicationcontext() {
        return applicationcontext;
    }

    /**
     * 通过 bena 名称获取上下文中的 bean
     */
    public static object getbean(string name) {
        return applicationcontext.getbean(name);
    }

    /**
     * 通过类型获取上下文中的bean
     */
    public static object getbean(class<?> requiredtype) {
        return applicationcontext.getbean(requiredtype);
    }
}

接着,在 jwttokenfilter 过滤器中通过以上工具类获取 jwtutil 工具类:

if (stringutils.isnotempty(jwttoken)) {
    if (jwtutil == null) {
        jwtutil = (jwtutil) springcontextutil.getbean("jwtutil");
    }
}

启动项目进行测试,成功登录。