【发布时间】:2018-11-20 10:29:03
【问题描述】:
我使用向移动应用程序公开 REST API 的 Web 应用程序。我将 Spring Boot 版本从 1.5.3.RELEASE 升级到 2.0.2.RELEASE,在修复了一些重大更改后,我面临一个无法解决的问题。
我关注了 Spring Boot 2.0 Migration Guide 和 Spring Boot Security 2.0 并查看了 Security changes in Spring Boot 2.0 M4。
问题在于应用使用 JWT 身份验证,并且有一个端点 (/auth/login) 接受用户凭据并生成一个长期存在的 JWT 作为回报。
有一个过滤器检查客户端发送的JWT令牌,并确定客户端是否可以访问请求的资源。
自定义安全配置如下:
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled=true)
public class SecurityConfiguration {
@Configuration
@Order(1)
public class AuthenticationConfiguration extends WebSecurityConfigurerAdapter {
// Some dependencies omitted
@Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
httpSecurity
// we don't need CSRF because JWT token is invulnerable
.csrf().disable()
.exceptionHandling().authenticationEntryPoint(unauthorizedHandler).and()
// don't create session
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
.authorizeRequests()
.antMatchers(HttpMethod.OPTIONS, "/**").permitAll()
.antMatchers(HttpMethod.GET, "/version/**").permitAll()
// Some more antMatchers() lines omitted
.antMatchers("/auth/**").permitAll()
.anyRequest().authenticated();
// Custom JWT based security filter
httpSecurity
.addFilterBefore(authenticationTokenFilterBean(), UsernamePasswordAuthenticationFilter.class);
// disable page caching
httpSecurity.headers().cacheControl();
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Bean
public JwtAuthenticationTokenFilter authenticationTokenFilterBean() throws Exception {
return new JwtAuthenticationTokenFilter(jwtTokenUtil);
}
}
@Configuration
@Order(2)
public class ClientVersionSupportConfiguration extends WebMvcConfigurerAdapter {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry
.addInterceptor(versionCheckingFilter())
.addPathPatterns("/**")
.excludePathPatterns("/error"); // Some more endpoints omitted
}
@Bean
public VersionCheckingInterceptor versionCheckingFilter() {
return new VersionCheckingInterceptor();
}
}
}
注意.antMatchers("/auth/**").permitAll() 行。 /auth 端点应该可以在没有 JWT 的情况下访问,因为当用户尚未登录时,JWT 尚未生成。
在升级 Spring Boot 之前,它可以正常工作,现在无法正常工作。检查 JWT 的过滤器拒绝登录尝试。看起来.permitAll() 没有让请求通过。 /version/** 也不起作用。从浏览器中点击它会出现错误页面。
我还尝试从配置中删除行,直到仍然存在:
httpSecurity
.authorizeRequests()
.antMatchers("/auth/**").permitAll()
它没有帮助。您能帮忙恢复原来的行为吗?
【问题讨论】:
-
找到了一个使用相同模式并适用于 Spring Boot 2 的演示应用程序。在 Github question 中寻求帮助
标签: java spring spring-boot spring-security jwt