我正在尝试将 Spring Boot 3 设置为使用 JWT 身份验证和带有 X-Auth 令牌的 HTTP 会话。目标是使用 X-Auth 令牌作为主要身份验证方法,但用户可以使用授予 JWT 访问令牌的外部提供商进行身份验证。
我已经成功创建了两个不同的授权端点,一个在
/auth
使用基于表单的登录并返回 X-Auth 令牌,另一个在 /authJwt
。 JWT 授权仅在 /authJwt
启用,所有其他端点均使用 X-Auth 令牌进行保护。
是否可以通过使用 JWT 进行身份验证来启用 X-Auth 令牌的生成?我已将 HTTP 会话配置为始终创建,并且调用
/authJwt
在 HTTP 标头中返回 X-Auth 令牌。但是 X-Auth 令牌在尝试进行身份验证时无效。
这是我正在使用的安全配置(我删除了一些不相关的部分):
@Configuration
@EnableWebSecurity()
public class WebSecurityConfiguration {
// Endpoints which will be public and not require authentication
private static final String[] AUTH_WHITELIST = {
"/auth"
};
/**
* Filter chain for authenticating using JWT tokens
*/
@Bean
@Order(1)
public SecurityFilterChain oAuth2ResourceFilterChain(HttpSecurity httpSecurity) throws Exception {
httpSecurity
.securityMatcher("/authJwt")
.cors().and().csrf().disable()
.requestCache().disable().exceptionHandling().and()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.ALWAYS)
.and()
.authorizeHttpRequests().anyRequest().authenticated()
.and()
.oauth2ResourceServer()
.jwt();
return httpSecurity.build();
}
/**
* Filter chain for enabling authentication.
*/
@Bean
public SecurityFilterChain filterChain(HttpSecurity httpSecurity) throws Exception {
httpSecurity
.cors().and().csrf().disable()
.requestCache().disable().exceptionHandling().and()
.formLogin().loginPage("/auth").usernameParameter("loginName").passwordParameter("loginPassword")
.successHandler((request, response, authentication) -> response.setStatus(HttpServletResponse.SC_OK))
.and()
.authorizeHttpRequests(requests -> requests
.requestMatchers(AUTH_WHITELIST).permitAll()
.anyRequest().authenticated()
)
// Return 401 on no session
.exceptionHandling().authenticationEntryPoint(new HttpStatusEntryPoint(HttpStatus.UNAUTHORIZED))
.and()
.logout();
return httpSecurity.build();
}
}
这是会话的配置:
@Configuration()
@EnableSpringHttpSession
public class SpringHttpSessionConfig {
@Bean
public MapSessionRepository sessionRepository() {
return new MapSessionRepository(new ConcurrentHashMap<>());
}
@Bean
public HttpSessionIdResolver httpSessionIdResolver() {
return HeaderHttpSessionIdResolver.xAuthToken();
}
}
有人能指出用 JWT 令牌交换 X-Auth 令牌的正确方向吗?
您可以为 JWT 令牌设置一个自定义身份验证过滤器,它将使用 JWT 令牌对用户进行身份验证,然后为经过身份验证的用户创建一个 X-Auth 令牌。
自定义过滤器:
import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import java.io.IOException;
public class JwtAuthenticationFilter extends AbstractAuthenticationProcessingFilter {
public JwtAuthenticationFilter() {
super("/authJwt");
}
@Override
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response)
throws AuthenticationException, IOException, ServletException {
String token = request.getHeader("Authorization");
// JWT authentication logic
return null; // return the authenticated user
}
@Override
protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain,
Authentication authResult) throws IOException, ServletException {
// Generate X-Auth token for the authenticated user
String xAuthToken = "GENERATED_X_AUTH_TOKEN";
response.setHeader("X-Auth-Token", xAuthToken);
// Continue processing the request
chain.doFilter(request, response);
}
}
WebSecurityConfiguration
类中注册自定义过滤器:@Configuration
@EnableWebSecurity()
public class WebSecurityConfiguration {
@Bean
public JwtAuthenticationFilter jwtAuthenticationFilter() throws Exception {
return new JwtAuthenticationFilter();
}
@Bean
public SecurityFilterChain oAuth2ResourceFilterChain(HttpSecurity httpSecurity) throws Exception {
httpSecurity
.securityMatcher("/authJwt")
.cors().and().csrf().disable()
.requestCache().disable().exceptionHandling().and()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.ALWAYS)
.and()
.authorizeHttpRequests().anyRequest().authenticated()
.and()
.oauth2ResourceServer()
.jwt()
.and()
.addFilterBefore(jwtAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class);
return httpSecurity.build();
}
}
现在,当用户向
/authJwt
端点发送带有有效 JWT 令牌的请求时,过滤器使用 JWT 令牌对用户进行身份验证,生成 X-Auth 令牌并将其返回到X-Auth-Token
标头中。