如何在Spring Security中配置多个oauth2重定向uri

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

鉴于我有 3 个 oauth2 提供商,我如何自定义他们的客户端注册重定向-Uris。

它们并不都符合默认模式 /login/oauth2/code/{registrationId}

  1. Azure AD B2C 有自定义:
    /openId
  2. Salesforce 默认为
    /login/oauth2/code/sf
  3. 流程默认为
    /login/oauth2/code/flow

这是SecurityFilterChain

    @Bean
public SecurityFilterChain clientSecurityFilterChain(
        HttpSecurity http,
        OAuth2ClientProperties bootClientProperties,
        InMemoryClientRegistrationRepository clientRegistrationRepository,
        SpringAddonsOidcProperties springAddonsOidcProperties,
        LogoutProperties logoutProperties) throws Exception {

    http.csrf(AbstractHttpConfigurer::disable);
    http.oauth2Login(login -> login
            .successHandler(trapsAuthenticationSuccessHandler())
            .failureHandler(trapsAuthenticationFailureHandler())
            .authorizationEndpoint(auth -> auth
                    .authorizationRequestResolver(new SpringAddonsOAuth2AuthorizationRequestResolver(bootClientProperties, clientRegistrationRepository, springAddonsOidcProperties.getClient())))
            .redirectionEndpoint(endpoint -> endpoint
                    .baseUri("/openId/*"))
                    );
    http.exceptionHandling(ex -> ex
            .authenticationEntryPoint(trapsLoginUrlAuthenticationEntryPoint()));
    http.logout(logout ->
        logout.logoutSuccessHandler(new DelegatingOidcClientInitiatedLogoutSuccessHandler(clientRegistrationRepository, logoutProperties, "{baseUrl}")));
    http.authorizeHttpRequests(auth ->
            auth.anyRequest().permitAll());
    return http.build();
}

这是配置:

### IDP: Azure AD B2C ###
spring.security.oauth2.client.provider.b2c.jwk-set-uri=${b2c-jwks-endpoint}
spring.security.oauth2.client.provider.b2c.authorization-uri=${b2c-authorization-endpoint}
spring.security.oauth2.client.provider.b2c.token-uri=${b2c-token-endpoint}

spring.security.oauth2.client.registration.b2c-retrieve.authorization-grant-type=authorization_code
spring.security.oauth2.client.registration.b2c-retrieve.client-id=${b2c-client-id}
spring.security.oauth2.client.registration.b2c-retrieve.client-secret=${b2c-client-secret}
spring.security.oauth2.client.registration.b2c-retrieve.provider=b2c
spring.security.oauth2.client.registration.b2c-retrieve.scope=${b2c-client-id},openid
spring.security.oauth2.client.registration.b2c-retrieve.redirect-uri={baseUrl}/openId

spring.security.oauth2.client.registration.b2c-save.authorization-grant-type=authorization_code
spring.security.oauth2.client.registration.b2c-save.client-id=${b2c-client-id}
spring.security.oauth2.client.registration.b2c-save.client-secret=${b2c-client-secret}
spring.security.oauth2.client.registration.b2c-save.provider=b2c
spring.security.oauth2.client.registration.b2c-save.scope=${b2c-client-id},openid
spring.security.oauth2.client.registration.b2c-save.redirect-uri={baseUrl}/openId
### IDP: Azure AD B2C ###

### IDP: Salesforce ###
sf-issuer=https://lv-direct--inttrn.sandbox.my.site.com/giportal
sf-secret=${secret-2}
spring.security.oauth2.client.provider.sf.issuer-uri=${sf-issuer}
spring.security.oauth2.client.registration.sf.authorization-grant-type=authorization_code
spring.security.oauth2.client.registration.sf.client-name=Salesforce (oidc)
spring.security.oauth2.client.registration.sf.client-id=${client-id-2}
spring.security.oauth2.client.registration.sf.client-secret=${client-secret-2}
spring.security.oauth2.client.registration.sf.redirect-uri={baseUrl}/login/oauth2/code/sf
spring.security.oauth2.client.registration.sf.provider=sf
spring.security.oauth2.client.registration.sf.scope=openid
### IDP: Salesforce IDP ###

### IDP: Flow ###
flow-issuer=https://id-lv-test.athenapaas.com/auth/realms/customer-portal
flow-secret=${secret-3}
spring.security.oauth2.client.provider.flow.issuer-uri=${flow-issuer}
spring.security.oauth2.client.registration.flow.authorization-grant-type=authorization_code
spring.security.oauth2.client.registration.flow.client-name=Flow (Keycloak - oidc)
spring.security.oauth2.client.registration.flow.client-id=${client-id-3}
spring.security.oauth2.client.registration.flow.client-secret=${client-secret-3}
spring.security.oauth2.client.registration.flow.redirect-uri={baseUrl}/login/oauth2/code/flow
spring.security.oauth2.client.registration.flow.provider=flow
spring.security.oauth2.client.registration.flow.scope=openid
### IDP: Flow ###

我可以看到正确的重定向 uri 已传递给提供程序,当提供程序重定向回来时,不会调用 oauth2 安全过滤器。

注意:我使用的是 Spring Boot 3.2.3 和 Spring Security 6.2.2

以下是调试日志:

logging.level.org.springframework.security=DEBUG

:: Spring Boot ::                (v3.2.3)

Standard Commons Logging discovery in action with spring-jcl: please remove commons-logging.jar from classpath in order to avoid potential conflicts
2024-03-21 11:28:15,214 [LAP***::] DEBUG org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder - No authenticationProviders and no parentAuthenticationManager defined. Returning null.
2024-03-21 11:28:16,924 [LAP***::] INFO  org.springframework.security.web.DefaultSecurityFilterChain - Will secure any request with [org.springframework.security.web.session.DisableEncodeUrlFilter@61a7930e, org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter@60eacbbf, org.springframework.security.web.context.SecurityContextHolderFilter@7f129873, org.springframework.security.web.header.HeaderWriterFilter@40f7fb45, org.springframework.web.filter.CorsFilter@36e6e59f, org.springframework.security.web.authentication.logout.LogoutFilter@c521a79, org.springframework.security.oauth2.client.web.OAuth2AuthorizationRequestRedirectFilter@5ce59833, org.springframework.security.oauth2.client.web.OAuth2LoginAuthenticationFilter@22071f0, org.springframework.security.web.savedrequest.RequestCacheAwareFilter@504f2bcd, org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter@51dd74a0, org.springframework.security.web.authentication.AnonymousAuthenticationFilter@676beb9f, org.springframework.security.web.access.ExceptionTranslationFilter@36afd06f, org.springframework.security.web.access.intercept.AuthorizationFilter@2d3bb293]
2024-03-21 11:29:18,839 [LAP***::] DEBUG org.springframework.security.web.FilterChainProxy - Securing OPTIONS /config
2024-03-21 11:29:19,036 [LAP***::] DEBUG org.springframework.security.web.FilterChainProxy - Securing POST /config
2024-03-21 11:29:19,079 [LAP***::] DEBUG org.springframework.security.web.FilterChainProxy - Secured POST /config
2024-03-21 11:29:19,312 [LAP***:0502ff48-95de-42f0-8ef6-2a02a1aa9e4a:98910f08-2904-464b-801f-e69ae6d5e773] DEBUG org.springframework.security.web.authentication.AnonymousAuthenticationFilter - Set SecurityContextHolder to anonymous SecurityContext
2024-03-21 11:29:19,328 [LAP***::] DEBUG org.springframework.security.web.savedrequest.HttpSessionRequestCache - Saved request https://localhost:8444/config?continue to session
2024-03-21 11:29:19,331 [LAP***::] DEBUG org.springframework.security.web.savedrequest.HttpSessionRequestCache - Saved request https://localhost:8444/config?continue to session
2024-03-21 11:29:19,506 [LAP***::] DEBUG org.springframework.security.web.FilterChainProxy - Securing GET /oauth2/authorization/b2c-retrieve
2024-03-21 11:29:19,551 [LAP***::] DEBUG org.springframework.security.web.DefaultRedirectStrategy - Redirecting to https://sys-login.lvgig.co.uk/270***/oauth2/v2.0/authorize?response_type=code&client_id=f3b***&scope=f3b***%20openid&state=55ViNeTEVyXndja9l69-vTTTZgwPOj1qeSwnXBf_zhA%3D&redirect_uri=https://localhost:8444/openId&nonce=7XVzDwtfW3D-zgoioI1seJly7dtY4Woy5-XNxRKSTic&p=B2C_1A_RPRetrieveQuoteQA3&product=car&style=new&ujt=retrievequote&response_mode=form_post&code_challenge=O53oNMjGap2D3B1GBReVh7knG72A4ngN4vc9i5Vj5vc&code_challenge_method=S256
2024-03-21 11:30:02,729 [LAP***::] DEBUG org.springframework.security.web.FilterChainProxy - Securing POST /openId
2024-03-21 11:30:02,748 [LAP***::] DEBUG org.springframework.security.web.FilterChainProxy - Secured POST /openId
2024-03-21 11:30:02,809 [LAP***::] ERROR com.lv.gi.journeyengine.services.core.impl.DefaultWorkflowServiceImpl - No Workflow found given requestContext

更新1: 我尝试根据以下内容更改以下内容:https://docs.spring.io/spring-security/reference/servlet/oauth2/login/advanced.html#oauth2login-advanced-redirection-endpoint,仍然不起作用。

${je-url} --> {baseUrl} in the config redirect-uri's

.baseUri("/openId") --> .baseUri("/openId/*")

我已经更新了原来的问题以反映这一点。

更新2: 如果我从 SecurityFilterChain 中注释掉以下内容,Salesforce 和 Flow 提供商将再次工作:

//              .authorizationEndpoint(auth -> auth
//                      .authorizationRequestResolver(new SpringAddonsOAuth2AuthorizationRequestResolver(bootClientProperties, clientRegistrationRepository, springAddonsOidcProperties.getClient())))
//              .redirectionEndpoint(endpoint -> endpoint
//                      .baseUri("/openId/*"))

我现在怀疑,我如何使用 SpringAddonsOAuth2AuthorizationRequestResolver (来自 https://github.com/ch4mpy/spring-addons)导致其他提供程序崩溃,并可能增加此问题的混乱。

spring spring-security
1个回答
0
投票

对重定向 uri 的调用由 Spring Security 的 OAuth2LoginAuthenticationFilter 处理

通常通过 Spring Security DSL 配置,例如:

@Bean
public SecurityFilterChain clientSecurityFilterChain(HttpSecurity http) throws Exception {
    http.oauth2Login(login -> login
            .redirectionEndpoint(endpoint -> endpoint
                    .baseUri("/openId"))
    );
    return http.build();
}

正如我发现的,如果重定向 uri 需要包含 2 种模式,这允许有限的范围:/openId & /login/oauth2/code/*

但是我发现我可以对 OAuth2LoginAuthenticationFilter 进行后处理以允许自定义重定向 uri 匹配,如下所示:

private static ObjectPostProcessor<OAuth2LoginAuthenticationFilter> postProcessor = new ObjectPostProcessor<>() {
    @Override
    public <O extends OAuth2LoginAuthenticationFilter> O postProcess(O object) {
        object.setRequiresAuthenticationRequestMatcher(
                new OrRequestMatcher(
                        AntPathRequestMatcher.antMatcher("/openId"),
                        AntPathRequestMatcher.antMatcher("/login/oauth2/code/*")));
        return object;
    }
};

@Bean
public SecurityFilterChain clientSecurityFilterChain(HttpSecurity http) throws Exception {
    http.oauth2Login(login -> login
            .addObjectPostProcessor(postProcessor)
    );
    return http.build();
}
© www.soinside.com 2019 - 2024. All rights reserved.