我正在使用Spring Security
和JWT
保护REST API(我不使用Spring Boot
)。
[当我尝试将身份验证请求(/login
)发送到我的REST API时,我在邮递员上收到了Could not get any response
这是我的JWT过滤器
public class JwtAuthenticationFilter extends UsernamePasswordAuthenticationFilter {
...
public AuthenticationFilter(AuthenticationManager authenticationManager) {
super.setAuthenticationManager(authenticationManager);
}
@Override
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
try {
... // getting the credentials from the request
return getAuthenticationManager().authenticate(new UsernamePasswordAuthenticationToken(credentials.login, credentials.password));
}
catch (IOException e) { throw new RuntimeException(e); }
}
@Override
protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain,
Authentication authResult) throws IOException, ServletException {
... // generating the jwtToken;
response.setHeader("Authorization", jwtToken);
}
}
[当我调试我的应用程序时,一切正常,并且执行了successfulAuthentication
方法,并且我在标题请求response.setHeader("Authorization", jwtToken);
中插入了正确的令牌。
但是之后,就像我的REST API(或Spring Security或Tomcat)一样,不发送任何响应!
这里是安全性配置:
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
...
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.authorizeRequests()
.anyRequest().authenticated()
.and()
.addFilter(new JwtAuthenticationFilter(authenticationManager()));
http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
}
...
}
对于/login
以外的其他HTTP请求,我在Postman中得到了(403)HTML响应,而NOT得到了JSON响应。
<!doctype html>
<html lang="en">
<head>
<title>HTTP Status 403 – Forbidden</title>
...
那么,为什么我的服务器没有响应/login
请求?以及为什么Spring Security不为所有http请求发送JSON响应?
登录请求后的日志
DEBUG org.springframework.security.web.FilterChainProxy - /login at position 1 of 11 in additional filter chain; firing Filter: 'WebAsyncManagerIntegrationFilter'
DEBUG org.springframework.security.web.FilterChainProxy - /login at position 2 of 11 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'
DEBUG org.springframework.security.web.FilterChainProxy - /login at position 3 of 11 in additional filter chain; firing Filter: 'HeaderWriterFilter'
DEBUG org.springframework.security.web.FilterChainProxy - /login at position 4 of 11 in additional filter chain; firing Filter: 'LogoutFilter'
DEBUG org.springframework.security.web.util.matcher.OrRequestMatcher - Trying to match using Ant [pattern='/logout', GET]
DEBUG org.springframework.security.web.util.matcher.AntPathRequestMatcher - Request 'POST /login' doesn't match 'GET /logout'
DEBUG org.springframework.security.web.util.matcher.OrRequestMatcher - Trying to match using Ant [pattern='/logout', POST]
DEBUG org.springframework.security.web.util.matcher.AntPathRequestMatcher - Checking match of request : '/login'; against '/logout'
DEBUG org.springframework.security.web.util.matcher.OrRequestMatcher - Trying to match using Ant [pattern='/logout', PUT]
DEBUG org.springframework.security.web.util.matcher.AntPathRequestMatcher - Request 'POST /login' doesn't match 'PUT /logout'
DEBUG org.springframework.security.web.util.matcher.OrRequestMatcher - Trying to match using Ant [pattern='/logout', DELETE]
DEBUG org.springframework.security.web.util.matcher.AntPathRequestMatcher - Request 'POST /login' doesn't match 'DELETE /logout'
DEBUG org.springframework.security.web.util.matcher.OrRequestMatcher - No matches found
DEBUG org.springframework.security.web.FilterChainProxy - /login at position 5 of 11 in additional filter chain; firing Filter: 'JwtAuthenticationFilter'
DEBUG org.springframework.security.web.util.matcher.AntPathRequestMatcher - Checking match of request : '/login'; against '/login'
DEBUG security.JwtAuthenticationFilter - Request is to process authentication
DEBUG org.springframework.security.authentication.ProviderManager - Authentication attempt using org.springframework.security.authentication.dao.DaoAuthenticationProvider
DEBUG org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler - Creating new EntityManager for shared EntityManager invocation
Hibernate: select ...
DEBUG org.springframework.security.web.header.writers.HstsHeaderWriter - Not injecting HSTS header since it did not match the requestMatcher org.springframework.security.web.header.writers.HstsHeaderWriter$SecureRequestMatcher@5b319bff
DEBUG org.springframework.security.web.context.SecurityContextPersistenceFilter - SecurityContextHolder now cleared, as request processing completed
首先,我将讨论您得到的响应不在Json中(对于所有其他请求)。请参阅,首先应分配url端点处的方法以产生您所请求的内容。而您想要的内容,您可以在邮递员的JSON标头中提及,它应该是Accepts:Application/json
另一件事是服务器不响应您的登录请求的原因,最好的配置应由您决定。
http.csrf().disable()
//You can give the request that you want to allow
.anyRequest().authenticated()
.and()
.addFilter(new JwtAuthenticationFilter(authenticationManager()));
我认为您需要配置spring安全性以允许所有/ login请求,以便它可以对您的第一个身份验证请求进行身份验证。
您的配置意味着需要验证所有请求才能访问,甚至是第一个登录请求。
所以尝试添加“ .antMatchers(” / login“)。permitAll()”
并且在使用自定义jwt登录时也要禁用formLogin。
http.csrf().and().formLogin().disable()
.authorizeRequests()
.antMatchers("/login").permitAll()
.anyRequest().authenticated()
.and()
.addFilter(new JwtAuthenticationFilter(authenticationManager()));
http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);