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

63lcw9qa  于 2023-04-10  发布在  Spring
关注(0)|答案(1)|浏览(133)

我正在尝试设置Sping 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();
    }
}

有人能指出用X-Auth令牌交换JWT令牌的正确方向吗?

bejyjqdl

bejyjqdl1#

您可以为JWT令牌设置一个自定义身份验证过滤器,该过滤器将使用JWT令牌对用户进行身份验证,然后为经过身份验证的用户创建一个X-Auth令牌。
1.自定义JWT身份验证过滤器:

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标头中返回它。

相关问题