Spring 引导 JWT:GET 的禁止 403 错误 API

Spring Boot JWT : Forbidden 403 error for GET API

我正在学习为我的端点实施 JWT 身份验证。 我能够使用 POST 调用成功生成 JWT 代码。 但在 SecurityConfig Class 中验证简单 GET API 时遇到问题。期待一些帮助。 在这个问题上卡了 2 天,找不到任何关于这个的东西。

我在调试模式下配置了日志,也发现了以下错误。我在现有的堆栈溢出线程上找不到任何合适的解决方案。

DEBUG 8196 --- [nio-8080-exec-2] o.apache.coyote.http11.Http11Processor   : Error parsing HTTP request header        
java.io.EOFException: null
at org.apache.tomcat.util.net.NioEndpoint$NioSocketWrapper.fillReadBuffer(NioEndpoint.java:1231) ~[tomcat-embed-core-9.0.39.jar:9.0.39]
at org.apache.tomcat.util.net.NioEndpoint$NioSocketWrapper.read(NioEndpoint.java:1141) ~[tomcat-embed-core-9.0.39.jar:9.0.39]
at org.apache.coyote.http11.Http11InputBuffer.fill(Http11InputBuffer.java:795) ~[tomcat-embed-core-9.0.39.jar:9.0.39]
at org.apache.coyote.http11.Http11InputBuffer.parseRequestLine(Http11InputBuffer.java:359) ~[tomcat-embed-core-9.0.39.jar:9.0.39]
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:261) ~[tomcat-embed-core-9.0.39.jar:9.0.39]
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) [tomcat-embed-core-9.0.39.jar:9.0.39]
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:868) [tomcat-embed-core-9.0.39.jar:9.0.39]
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1590) [tomcat-embed-core-9.0.39.jar:9.0.39]
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) [tomcat-embed-core-9.0.39.jar:9.0.39]
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source) [na:1.8.0_191]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) [na:1.8.0_191]
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-embed-core-9.0.39.jar:9.0.39]
at java.lang.Thread.run(Unknown Source) [na:1.8.0_191]

错误:GET API

{
"timestamp": "2020-11-22T17:20:57.227+00:00",
"status": 403,
"error": "Forbidden",
"message": "",
"path": "/hello"

}

SecurityConfig.class

@Override
protected void configure(HttpSecurity http) throws Exception{
    http.csrf().disable();
    http.authorizeRequests().antMatchers("/authenticate").permitAll()
    .antMatchers("/hello").authenticated().and()
    .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);

    http.addFilterBefore(jwtRequestFilter, UsernamePasswordAuthenticationFilter.class);
}

已将我的代码上传到 Repo 以便更好地参考。 https://github.com/rohit-shinde/spring-jwt-tutorial

JwtRequestFilter.java -> doFilterInternal -> line 44

好像是个小错别字

我想你的意思是:

...
        if(username != null && SecurityContextHolder.getContext() != null) {
            UserDetails userDetails = myUserDetailsService.loadUserByUsername(username);
            if(jwtUtils.validateToken(jwt, userDetails)) {
                UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
                authenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
                SecurityContextHolder.getContext().setAuthentication(authenticationToken);
            }
        }
        filterChain.doFilter(request, response);
...

或者也许:

...
        if(username != null && SecurityContextHolder.getContext().getAuthentication() == null) {
            UserDetails userDetails = myUserDetailsService.loadUserByUsername(username);
            if(jwtUtils.validateToken(jwt, userDetails)) {
                UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
                authenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
                SecurityContextHolder.getContext().setAuthentication(authenticationToken);
            }
        }
        filterChain.doFilter(request, response);
...

请注意,我在第一个代码段中将 SecurityContextHolder.getContext() == null 更改为 SecurityContextHolder.getContext() != null。在第二个片段中,我将其更改为 SecurityContextHolder.getContext().getAuthentication() == null.

根据 this answerSecurityContextHolder.getContext() 不应为空。