将 Saml2 和 oAuth2 组合在同一个身份验证模块中

时间:2021-02-24 10:15:06

标签: spring-boot spring-security oauth-2.0 saml-2.0

我在 spring-boot 中开发了一个基于 spring-security 的认证模块,允许用户通过 oAuth2 认证到外部系统,如 AAD、ADFS ...

一切正常,但新客户端要求使用 Saml2 作为集成协议。

目前模块由以下几部分组成

SecurityConfig.java

@Override
protected void configure(HttpSecurity http) throws Exception {
    http
            .cors()
            .and()
            .sessionManagement()
            .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
            .and()
            .csrf()
            .disable()
            .formLogin()
            .disable()
            .httpBasic()
            .disable()
            .exceptionHandling()
            .authenticationEntryPoint(new RestAuthenticationEntryPoint())
            .and()
            // only allow access to specified URIs
            .authorizeRequests()
            .antMatchers("/auth/**", "/oauth2/**", "/public/**")
            .permitAll()
            // only allow access with fully authenticated requests
            .anyRequest()
            .fullyAuthenticated()
            .and()
            // configure OAuth2 login
            .oauth2Login()
            // configure token endpoint for hack
            .tokenEndpoint()
            .accessTokenResponseClient(getAccessTokenResponseClient())
            .and()
            // endpoint for authorization (the endpoint we expose and knows the third party to go to)
            .authorizationEndpoint()
            .baseUri(OAUTH2_AUTHORIZE_BASE_URI)
            .authorizationRequestResolver(oauth2AuthorizationRequestResolver)
            .authorizationRequestRepository(httpCookieOAuth2AuthorizationRequestRepository)
            .and()
            // endpoint for callback (where the third party service calls back after authenticating a user)
            .redirectionEndpoint()
            .baseUri("/oauth2/callback/*")
            .and()
            // the service to use
            .userInfoEndpoint()
            .userService(customOAuth2UserService)
            .and()
            .successHandler(oAuth2AuthenticationSuccessHandler)
            .failureHandler(oAuth2AuthenticationFailureHandler);

    // Add our custom Token based authentication filter
    http.addFilterBefore(tokenAuthenticationFilter, UsernamePasswordAuthenticationFilter.class);
}

应用程序.yaml

spring:
  security:
    oauth2:
      client:
        registration:
          example1:
            clientId: -----------------
            clientSecret: -----------------
            redirectUriTemplate: -----------------
            grant-type: authorization_code
            authorizationGrantType: authorization_code
            tokenName: code
            authenticationScheme: query
            clientAuthenticationScheme: form
          example2:
            clientId: -----------------
            clientSecret: -----------------
            tenant-id: -----------------
            active-directory-groups: -----------------
            redirectUriTemplate: -----------------
            grant-type: authorization_code
            authorizationGrantType: authorization_code
            tokenName: code
            authenticationScheme: query
            clientAuthenticationScheme: form

我对与 Saml2 集成的疑虑如下:

  1. 可以在同一个应用程序中组合两种身份验证,您是否可以在 Application.yaml 中使用类似的内容?
spring:
  security:
    saml2:
      relyingparty:
        registration:
          aad: 
            identityprovider:
              entity-id: -----------------
              verification.credentials:
                - certificate-location: "classpath:certs/aad.cert"
              singlesignon.url: -----------------
              singlesignon.sign-request: false
          okta:
            identityprovider:
              entity-id: -----------------
              verification.credentials:
                - certificate-location: "classpath:certs/okta.cert"
              singlesignon.url: -----------------
              singlesignon.sign-request: false
    oauth2:
      client:
        registration:
          example1:
            clientId: -----------------
            clientSecret: -----------------
            redirectUriTemplate: -----------------
            grant-type: authorization_code
            authorizationGrantType: authorization_code
            tokenName: code
            authenticationScheme: query
            clientAuthenticationScheme: form
          example2:
            clientId: -----------------
            clientSecret: -----------------
            tenant-id: -----------------
            active-directory-groups: -----------------
            redirectUriTemplate: -----------------
            grant-type: authorization_code
            authorizationGrantType: authorization_code
            tokenName: code
            authenticationScheme: query
            clientAuthenticationScheme: form
  1. 如果之前的配置是可能的,它会如何在“SecurityConfig.java -> configure (HttpSecurity http)”中表示?是否可以在当前配置中输入 saml2Login?

  2. 我看过一些不完整的例子,他们谈论使用“authenticationProvider”来实现这种类型的案例。有谁知道这是否有效?

public void configure(AuthenticationManagerBuilder auth) throws Exception {
          auth.authenticationProvider(oauth2AuthenticationProvider());
          auth.authenticationProvider(saml2AuthenticationProvider());
          auth.authenticationProvider(DDBBAuthenticationProvider());
}

感谢您的帮助!

1 个答案:

答案 0 :(得分:1)

  1. for 的一个关键点是,您的应用程序不应需要了解 SAML 作为一项旧技术。您会希望您的 UI 和 API 具有现代感并使用 OAuth 令牌。

  2. 无法回答这个问题。

  3. 听起来您应该使用授权服务器 (AS) 而不是在您自己的身份验证模块中做太多事情。第三方系统内置了对许多提供商的支持,并且花费了数年时间进行开发。

以 Curity 产品支持的 all of these options 为例,您可以下载该产品的免费社区版。

就一般模式而言:

  • 您的应用使用 OAuth 和 OpenID Connect 并与 AS 交互
  • 如果业务合作伙伴想要针对他们自己的身份提供者使用 SAML 登录,您只需在 AS 中进行 SAML 配置更改 - 对您的应用程序进行零代码更改