【发布时间】:2018-03-14 21:03:00
【问题描述】:
我正在开发一个 Spring Boot 服务,它正在接收请求标头中另一个服务中生成的 JWT 令牌。 我的目标是在我的 Spring Boot 应用程序中验证 JWT 令牌的有效性。
经过一段时间的研究,我决定使用 Spring Security 的 WebSecurityConfig 并拥有某种实际上是过滤器的中间件。
我已将过滤器配置为不适用于我的应用程序中定义的所有请求。但无论如何,过滤器都会应用于配置为 permitAll() 的请求。
我完全被这一切弄糊涂了,不知道我错过了什么。最后我决定寻求帮助。请帮忙。
这是我的代码。
安全配置:
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
JWTAuthenticationFilter jwtAuthenticationFilter;
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.authorizeRequests()
.antMatchers("/").permitAll()
.antMatchers("/req").permitAll()
.and()
.authorizeRequests()
.anyRequest().authenticated()
.and()
// And filter other requests to check the presence of JWT in header
.addFilterBefore(jwtAuthenticationFilter,
BasicAuthenticationFilter.class);
}
@Override
public void configure(WebSecurity webSecurity) {
webSecurity
.ignoring()
.antMatchers("/req");
}
}
过滤器:
@Component
public class JWTAuthenticationFilter extends GenericFilterBean {
@Autowired
TokenAuthenticationService tokenAuthenticationService = new TokenAuthenticationService();
@Override
public void doFilter(ServletRequest request,
ServletResponse response,
FilterChain filterChain)
throws IOException, ServletException {
boolean authentication = tokenAuthenticationService
.getAuthentication((HttpServletRequest)request);
if (!authentication) {
((HttpServletResponse) response).setStatus(HttpServletResponse.SC_UNAUTHORIZED);
return;
}
filterChain.doFilter(request,response);
}
}
身份验证服务:
@Component
class TokenAuthenticationService {
@Value("${security.authentication.token.secret}")
private String SECRET;
@Value("${security.authentication.token.token_prefix}")
private String TOKEN_PREFIX;
@Value("${security.authentication.token.header_string}")
private String HEADER_STRING;
boolean getAuthentication(HttpServletRequest request) throws UnsupportedEncodingException {
String token = request.getHeader(HEADER_STRING);
if (token != null) {
// parse the token.
DecodedJWT jwt;
try {
Algorithm algorithm = Algorithm.HMAC256(SECRET);
JWTVerifier verifier = JWT.require(algorithm)
.build(); //Reusable verifier instance
jwt = verifier.verify(token);
return true;
} catch (UnsupportedEncodingException exception){
//UTF-8 encoding not supported
UnsupportedEncodingException ex = exception;
return false;
} catch (JWTVerificationException exception){
//Invalid signature/claims
JWTVerificationException ex = exception;
return false;
}
}
return false;
}
}
【问题讨论】:
-
您写了 我已将过滤器配置为不适用于所有请求,但我在您的过滤器中看不到此类代码。您始终对请求进行身份验证。
-
那么 antMatchers().permitAll() 和 ignoring().antMatchers() 不是意味着要在这些路径上跳过过滤器吗?你能告诉我这个配置如何应用于过滤器类的例子吗?
-
ignoring().antMatchers()应该可以工作,因为它排除了整个过滤器链,但是 Spring Boot 会自动将所有 servlet 过滤器添加到应用程序中。您是否在 Spring Boot 配置中排除了过滤器? -
@dur 您是否在 Spring Boot 配置中排除了过滤器?我没有这样做。但是我是否需要它,因为在我的过滤器类中我想从 application.properties 注入值,如果我理解正确,它会将它排除在组件扫描链中?
标签: java spring spring-boot spring-security jwt