【问题标题】:Spring Security: Multiple OpenID Connect Clients for Different Paths?Spring Security:不同路径的多个 OpenID Connect 客户端?
【发布时间】:2019-07-22 07:24:18
【问题描述】:

使用 Spring Boot 2.1.5 和 Spring Security 5,我尝试使用两个不同的 OpenID 客户端(基于 Keycloak)。这是我们在application.properties 中的内容。

spring.security.oauth2.client.registration.keycloak-endusersclient.client-id=endusersclient
spring.security.oauth2.client.registration.keycloak-endusersclient.client-secret=7b41aaa4-277f-47cf-9eab-91afacd55d2c
spring.security.oauth2.client.provider.keycloak-endusersclient.issuer-uri=https://mydomain/auth/realms/endusersrealm

spring.security.oauth2.client.registration.keycloak-employeesclient.client-id=employeesclient
spring.security.oauth2.client.registration.keycloak-employeesclient.client-secret=7b41aaa4-277f-47cf-9eab-91afacd55d2d
spring.security.oauth2.client.provider.keycloak-employeesclient.issuer-uri=https://mydomain/auth/realms/employeesrealm

从上面的 sn-p 可以看出,我们正在尝试将一个 OpenID 客户端用于最终用户(客户),另一个用于员工。

在安全配置类中,我们看看如何在不同的模式上配置安全性如下:

public class OpenIDConnectSecurityConfig extends
WebSecurityConfigurerAdapter
{
    @Override
    protected void configure(HttpSecurity http) throws Exception {

    // avoid multiple concurrent sessions
    http.sessionManagement().maximumSessions(1);


    http.authorizeRequests()
            .antMatchers("/endusers/**").authenticated()
            .antMatchers("/employees/**").authenticated()
            .anyRequest().permitAll().and()
            .oauth2Login()
            .successHandler(new OpenIDConnectAuthenticationSuccessHandler())
            .and()
            .logout().logoutSuccessUrl("/");

我不明白的是如何配置每个 OpenID 客户端以触发单独的 URL 模式。在上面的示例中,我们希望看到在点击以“/endusers”开头的 URL 时使用 endusers 客户端,并在点击以“/employees”开头的 URL 时使用 employees 客户端。

这个可以吗?

【问题讨论】:

    标签: spring spring-boot spring-security


    【解决方案1】:

    对于多租户情况,您需要使用 AuthenticationManagerResolver,其中 endusersclient 和 employeesclient 是您的租户。

    public class CustomAuthenticationManagerResolver implements AuthenticationManagerResolver<HttpServletRequest> {
    
    
    @Override
    public AuthenticationManager resolve(HttpServletRequest request) {
        return fromTenant();
    }
    
    private AuthenticationManager fromTenant(HttpServletRequest request) {
                String[] pathParts = request.getRequestURI().split("/");
    //TODO find your tanent from the path and return the auth manager
    }
    

    // 在你的类中,应该如下所示

    private CustomAuthenticationManagerResolver customAuthenticationManagerResolver;
    
    http.authorizeRequests()
            .antMatchers("/endusers/**").authenticated()
            .antMatchers("/employees/**").authenticated()
            .anyRequest().permitAll().and().oauth2ResourceServer().authenticationManagerResolver(this.customAuthenticationManagerResolver);
    

    【讨论】:

    • 以上解决方案适用于多租户
    【解决方案2】:

    对于不透明令牌(多租户配置)

    @组件 公共类 CustomAuthenticationManagerResolver 实现 AuthenticationManagerResolver {

    @Override
    public AuthenticationManager resolve(HttpServletRequest request) {
        String tenantId = request.getHeader("tenant");
        OpaqueTokenIntrospector opaqueTokenIntrospector;
        if (tenantId.equals("1")) {
            opaqueTokenIntrospector =  new NimbusOpaqueTokenIntrospector(
                    "https://test/authorize/oauth2/introspect",
                    "test",
                    "test"
            );
        } else {
            opaqueTokenIntrospector =  new NimbusOpaqueTokenIntrospector(
                    "https://test/authorize/oauth2/introspect",
                    "test",
                    "test");
        }
        return new OpaqueTokenAuthenticationProvider(opaqueTokenIntrospector)::authenticate;
    }
    

    }

    网络安全配置

     @Autowired
     private CustomAuthenticationManagerResolver customAuthenticationManagerResolver;
    
    
    
    
     @Override
        public void configure(HttpSecurity http) throws Exception {
         http.anyRequest()
                        .authenticated().and().oauth2ResourceServer()
                        .authenticationEntryPoint(restEntryPoint).authenticationManagerResolver(customAuthenticationManagerResolver);
    }
    

    【讨论】:

      猜你喜欢
      • 2018-11-15
      • 2016-06-28
      • 2017-12-16
      • 2022-11-08
      • 2015-02-09
      • 2019-09-13
      • 2017-04-30
      • 2012-10-22
      • 1970-01-01
      相关资源
      最近更新 更多