在 Spring Boot 中结合使用 JWT 授权和 X-Auth-Tokens

问题描述 投票:0回答:1

我正在尝试将 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 令牌的正确方向吗?

spring spring-boot spring-security httpsession
1个回答
0
投票

您可以为 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);
    }
}
  1. 在您的
    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
标头中。

© www.soinside.com 2019 - 2024. All rights reserved.