制作用于春季启动的黑名单JWT令牌

时间:2019-08-27 11:58:11

标签: reactjs spring-boot jwt blacklist

在这个问题上我待了好几个星期的每个人都将带有弹簧启动的JWT芯片列入黑名单,这是我在用户尝试断开其密钥令牌在给定的mongoDB数据库中的存储时我所做的

@PutMapping(value = "/destroy", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
public JwtBlacklist logout(@RequestBody Map<String,String> json, HttpSession httpSession) throws UnsupportedEncodingException {

    String token = json.get("token");

    JwtBlacklist jwtBlacklist = new JwtBlacklist();
    jwtBlacklist.setToken(token);
    jwtBlacklistRepository.save(jwtBlacklist);

    return jwtBlacklistRepository.save(jwtBlacklist);
}   

它将密钥完美地存储在给定的数据库中,无需担心 这是图片 https://ibb.co/dcX0Vnh“令牌存储”

现在最大的问题是,当我尝试将用户在连接过程中必须使用的令牌列入黑名单时,并且当断开该令牌的连接时,此处的JWTFilter.java代码不再有效

public class JWTFilter extends GenericFilterBean {
    @Value("${app.jwtSecret}")
    public String jwtsecret;
    @Autowired
    public JwtBlacklistRepository jwtBlacklistRepository;

    @Override
    public void doFilter(final ServletRequest req,
                         final ServletResponse res,
                         final FilterChain chain) throws IOException, ServletException {

        final HttpServletRequest request = (HttpServletRequest) req;
        final HttpServletResponse response = (HttpServletResponse) res;
        final String authHeader = request.getHeader("authorization");

        if ("OPTIONS".equals(request.getMethod())) {
            response.setStatus(HttpServletResponse.SC_OK);

            chain.doFilter(req, res);
        } else {

            if (authHeader == null || !authHeader.startsWith("Bearer ")) {
                throw new ServletException("Missing or invalid Authorization header");
            }

            final String token = authHeader.substring(7);
            JwtBlacklist blacklist = this.jwtBlacklistRepository.findByTokenEquals(token);

                    if(blacklist == null) {
                        final Claims claims = Jwts.parser().setSigningKey("topsecretjwtpass".getBytes(StandardCharsets.UTF_8)).parseClaimsJws(token).getBody();
                        request.setAttribute("claims", claims);
                    } else {
                        throw new ServletException("Invalid token." + "");

                    }

            chain.doFilter(req, res);
        }

    }
} 

现在,当我尝试使用黑名单令牌或不使用黑名单令牌进行查询时,我会出现此错误

  

{“时间戳”:“ 2019-08-27T11:54:52.063 + 0000”,“状态”:500,“错误”:“内部   服务器错误“,”消息“:”无消息   available“,” trace“:” java.lang.NullPointerException \ n \ tat   com.monarque.bank.monarque.config.JWTFilter.doFilter(JWTFilter.java:47)\ n \ tat   org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)\ n \ tat   org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)\ n \ tat   org.springframework.security.web.FilterChainProxy $ VirtualFilterChain.doFilter(FilterChainProxy.java:320)\ n \ tat   org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:127)\ n \ tat   org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:91)\ n \ tat   org.springframework.security.web.FilterChainProxy $ VirtualFilterChain.doFilter(FilterChainProxy.java:334)\ n \ tat   org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:119)\ n \ tat   org.springframework.security.web.FilterChainProxy $ VirtualFilterChain.doFilter(FilterChainProxy.java:334)\ n \ tat   org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:137)\ n \ tat   org.springframework.security.web.FilterChainProxy $ VirtualFilterChain.doFilter(FilterChainProxy.java:334)\ n \ tat   org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:111)\ n \ tat   org.springframework.security.web.FilterChainProxy $ VirtualFilterChain.doFilter(FilterChainProxy.java:334)\ n \ tat   org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:170)\ n \ tat   org.springframework.security.web.FilterChainProxy $ VirtualFilterChain.doFilter(FilterChainProxy.java:334)\ n \ tat   org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:63)\ n \ tat   org.springframework.security.web.FilterChainProxy $ VirtualFilterChain.doFilter(FilterChainProxy.java:334)\ n \ tat   org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:116)\ n \ tat   org.springframework.security.web.FilterChainProxy $ VirtualFilterChain.doFilter(FilterChainProxy.java:334)\ n \ tat   org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:74)\ n \ tat   org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)\ n \ tat   org.springframework.security.web.FilterChainProxy $ VirtualFilterChain.doFilter(FilterChainProxy.java:334)\ n \ tat   org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:105)\ n \ tat   org.springframework.security.web.FilterChainProxy $ VirtualFilterChain.doFilter(FilterChainProxy.java:334)\ n \ tat   org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:56)\ n \ tat   org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)\ n \ tat   org.springframework.security.web.FilterChainProxy $ VirtualFilterChain.doFilter(FilterChainProxy.java:334)\ n \ tat   org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:215)\ n \ tat   org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:178)\ n \ tat   org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:357)\ n \ tat   org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:270)\ n \ tat   org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)\ n \ tat   org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)\ n \ tat   org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99)\ n \ tat   org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)\ n \ tat   org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)\ n \ tat   org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)\ n \ tat   org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:92)\ n \ tat   org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)\ n \ tat   org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)\ n \ tat   org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)\ n \ tat   org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:93)\ n \ tat   org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)\ n \ tat   org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)\ n \ tat   org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)\ n \ tat   org.springframework.session.web.http.SessionRepositoryFilter.doFilterInternal(SessionRepositoryFilter.java:151)\ n \ tat   org.springframework.session.web.http.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:81)\ n \ tat   org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)\ n \ tat   org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)\ n \ tat   org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:200)\ n \ tat   org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)\ n \ tat   org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)\ n \ tat   org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)\ n \ tat   org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:200)\ n \ tat   org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)\ n \ tat   org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:490)\ n \ tat   org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139)\ n \ tat   org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)\ n \ tat   org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74)\ n \ tat   org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)\ n \ tat   org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:408)\ n \ tat   org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)\ n \ tat   org.apache.coyote.AbstractProtocol $ ConnectionHandler.process(AbstractProtocol.java:834)\ n \ tat   org.apache.tomcat.util.net.NioEndpoint $ SocketProcessor.doRun(NioEndpoint.java:1415)\ n \ tat   org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)\ n \ tat   java.base / java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)\ n \ tat   java.base / java.util.concurrent.ThreadPoolExecutor $ Worker.run(ThreadPoolExecutor.java:628)\ n \ tat   org.apache.tomcat.util.threads.TaskThread $ WrappingRunnable.run(TaskThread.java:61)\ n \ tat   java.base / java.lang.Thread.run(Thread.java:835)\ n“,”路径“:” / v1 / users / fa26eea5-7dce-4d79-a7f7-1f848cc58966“}


这是模特

public class JwtBlacklist {
    @Id
    private String _id;
    @Indexed(direction = IndexDirection.ASCENDING)
    private String token;

    public String get_id() {
        return _id;
    }

    public void set_id(String _id) {
        this._id = _id;
    }

    public String getToken() {
        return token;
    }

    public void setToken(String token) {
        this.token = token;
    }

    @Override
    public String toString() {
        return "JwtBlacklist{" +
                "_id='" + _id + '\'' +
                ", token='" + token + '\'' +
                '}';
    }
}

这是JwtBlacklist的存储库


import com.monarque.bank.monarque.dao.models.JwtBlacklist;
import org.springframework.data.mongodb.repository.MongoRepository;


public interface JwtBlacklistRepository extends MongoRepository<JwtBlacklist,String> {


JwtBlacklist findByTokenEquals(String token);

}

2 个答案:

答案 0 :(得分:0)

出现此错误是因为您正在使用 Filter Bean,并且无法将Bean注入GenericFilter 。 我知道要解决此问题的一种方法是延迟加载您的存储库。

只需检查doFilter()的第一行,如果您的存储库为空,则为null 获取您的ServletContext并延迟加载它。 例如:

if (jwtBlacklistRepository == null) { //Lazy Load because filter
    ServletContext servletContext = req.getServletContext();
    WebApplicationContext webApplicationContext = WebApplicationContextUtils.getWebApplicationContext(servletContext);
    jwtBlacklistRepository = webApplicationContext.getBean(JwtBlacklistRepository.class);
}

基本上,您被迫将该bean加载到过滤器中。 (如果我对此声明有误,请纠正我)。

答案 1 :(得分:0)

总而言之,发生问题是因为您的JWTFilter不是由Spring管理的,所以您不能仅仅要求他为您注入bean和属性。

幸运的是,有一种简单的方法可以使工作正常!

尝试看看添加以下init方法是否对您有用:

public class JWTFilter extends GenericFilterBean {
  @Value("${app.jwtSecret}")
  public String jwtsecret;
  @Autowired
  public JwtBlacklistRepository jwtBlacklistRepository;

  //ask spring to inject the values based on current context
  @PostConstruct
  public void init() {
    SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this);
  }

  @Override
  public void doFilter(final ServletRequest req,
                       final ServletResponse res,
                       final FilterChain chain) throws IOException, 
  ServletException {

  ....
  }
}

这种方法,请spring为您注射。

相关问题