我有一个springboot微服务。这是由React客户端调用的。 react客户端通过登录表单对用户进行身份验证并将其登录。它使用我们的自定义身份验证服务。成功登录后,会发出JWT类型的令牌并保存在浏览器的本地存储中,然后客户端在调用微服务时通过HTTP Authorization标头提交。这是我实现的代码片段。
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
// ...
@Override
protected void configure(HttpSecurity http) throws Exception {
super.configure(http);
http.csrf().disable().headers().frameOptions().disable()
.and().sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and().authorizeRequests().antMatchers("/api/**").authenticated()
.antMatchers("/management/**").hasAuthority(AuthoritiesConstants.ADMIN)
.antMatchers("/swagger-resources/configuration/ui").permitAll()
.antMatchers("/health/**").permitAll()
.and()
.addFilterBefore(new JWTAuthorizationFilter(new MyAuthenticationProvider()),
UsernamePasswordAuthenticationFilter.class);
}
}
我有自己的AuthenticationProvider
实现,用于对我们的内部auth服务进行实际身份验证。这是我的过滤器类。为简单起见,我删除了不必要的代码。
public class JWTAuthorizationFilter extends OncePerRequestFilter {
private static final String UNAUTHORIZED_ERROR = "UNAUTHORIZED";
public static final String X_AUTHORIZATION_HEADER = "X-Authorization";
private static final String BEARER = "Bearer ";
private final Logger log = LoggerFactory.getLogger(JWTAuthorizationFilter.class);
private final AuthenticationProvider authenticationProvider;
public JWTAuthorizationFilter(AuthenticationProvider authProvider) {
super();
this.authenticationProvider = authProvider;
}
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
try {
String token = resolveToken(request);
Authentication authentication = this.authenticationProvider
.authenticate(new UsernamePasswordAuthenticationToken(null, token));
SecurityContextHolder.getContext().setAuthentication(authentication);
// invoking the next chain in the filter.
filterChain.doFilter(request, response);
} catch (AuthenticationException e) {
log.error("Security exception for user {} - {}", e.getMessage());
response.sendError(HttpServletResponse.SC_UNAUTHORIZED, UNAUTHORIZED_ERROR);
}
}
private String resolveToken(HttpServletRequest request) {
return request.getHeader(X_AUTHORIZATION_HEADER);
}
}
一切正常。然后我进行了代码审查,当时coulegue要求我使用AbstractAuthenticationProcessingFilter
代替OncePerRequestFilter
/ GenericFilterBean
。我检查了文档[1],它说AbstractAuthenticationProcessingFilter
主要用于基于浏览器的基于HTTP的身份验证请求。
顺便说一句,我尝试通过在那里移动我当前正在运行的逻辑来实现它,并将其与我的springboot微服务连接起来。但不幸的是,当我发送请求时,它给了我301永久HTTP状态代码和一些HTML用于登录表单。
这是我的问题。
AbstractAuthenticationProcessingFilter
作为此令牌吗?
认证。如果是这样的话怎么办?我查看了春季安全参考指南,但找不到上述问题的具体答案。
不幸的是,我无法共享我的代码,因为它使用了组织内部的一些专有库。我为此道歉。任何帮助表示赞赏。