我正在学习为我的端点实现JWT身份验证。我能够使用POST调用成功生成JWT代码。但面临着在SecurityConfig类中验证简单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]
错误:获取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
。
根据这个答案,SecurityContextHolder.getContext()
不应该为空。