使用 Spring Security 在一个应用程序中结合数据库和 SAML 身份验证

Posted

技术标签:

【中文标题】使用 Spring Security 在一个应用程序中结合数据库和 SAML 身份验证【英文标题】:Combine database and SAML authentication in one application using spring security 【发布时间】:2020-07-25 16:59:32 【问题描述】:

我正在尝试使用 spring security(spring-security-starter) 在 spring boot(2.2.4) 应用程序中实现身份验证和授权。

用例:基于用户名我想为特定的身份验证提供者重定向用户

如果用户名以 'mit.com' 结尾 使用数据库验证用户(我使用的是休眠)- 为此,我可以使用 spring 的 UserDetailService

如果用户名以 'einfochips.com' 结尾 使用 SAML 2.0 验证用户 协议 - 使用 Okta、SSOCircle、OneLogin 等身份提供者。

我不知道该怎么做。我尝试使用自定义过滤器,但做不到。

我浏览了很多文章,但无法做到这一点。

我编写了以下代码,仅使用 SAML 进行身份验证。它工作正常。将用户带到 okta idp 进行登录。

package com.example.demo;

import static org.springframework.security.extensions.saml2.config.SAMLConfigurer.saml;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.saml.userdetails.SAMLUserDetailsService;

@EnableWebSecurity
@Configuration
@EnableGlobalMethodSecurity(securedEnabled = true)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter 

    @Autowired
    SAMLUserDetailsService userDetailsService;

    @Value("$security.saml2.metadata-url")
    String metadataUrl;

    @Value("$server.ssl.key-alias")
    String keyAlias;

    @Value("$server.ssl.key-store-password")
    String password;

    @Value("$server.port")
    String port;

    @Value("$server.ssl.key-store")
    String keyStoreFilePath;   

    //Uisng SAML2.0
    @Override
    protected void configure(final HttpSecurity http) throws Exception 
        http.csrf().disable()
            .authorizeRequests()
                .antMatchers("/").permitAll()
                .anyRequest().authenticated()
                .and()
            .apply(saml())
                .serviceProvider()
                    .keyStore()
                        .storeFilePath(this.keyStoreFilePath)
                        .password(this.password)
                        .keyname(this.keyAlias)
                        .keyPassword(this.password)
                        .and()
                    .protocol("https")
                    .hostname(String.format("%s:%s", "localhost", this.port))
                    .basePath("/")
                    .and().userDetailsService(userDetailsService)
                .identityProvider()
                .metadataFilePath(this.metadataUrl);
    


任何人都可以指导我,以便我可以配置为使用任何 IDP,如 okta、ssocircle、OneLogin 等。

【问题讨论】:

【参考方案1】:

利用 Spring Security 的 AuthenticationProvider 实现多个自定义身份验证提供程序并以适当的顺序注册它们(按顺序评估它们)。

自定义数据库身份验证提供程序

public class MitComAuthProvider implements AuthenticationProvider 
   public Authentication authenticate(Authentication auth) 
      // if user matches 'mit.com', auth with database
      // look up and auth
      // else return null (to try next auth provider)
   

自定义SAML Authentication Provider(由Spring Security 提供并实现AuthenticationProvider)。

public class EInfoChipsAuthProvider extends SAMLAuthenticationProvider 
   public Authentication authenticate(Authentication auth) 
      // if user matches 'einfochips.com', auth with SAML
      // super.authentication(auth)
      // else return null (to try next auth provider) or throw auth exception
   

然后,在您的 WebSecurityConfigurerAdapter 中注册两个身份验证提供程序

public class SecurityConfiguration extends WebSecurityConfigurerAdapter 

   @Autowired
   private MitComAuthProvider mitComAuthProvider;

   @Autowired
   private EInfoChipsAuthProvider eInfoChipsAuthProvider;

   public void configure(AuthenticationManagerBuilder auth) throws Exception 
       auth.authenticationProvider(mitComAuthProvider);
       auth.authenticationProvider(eInfoChipsAuthProvider);
   

   ...

【讨论】:

如果 SAML 身份验证提供程序在哪里放置 idp 元数据,以便用户将被重定向到 idp 进行身份验证。我正在从配置方法重定向用户,但如何在自定义 SAMLAuthentication 提供程序中编写重定向内容?这就是我卡住的地方?

以上是关于使用 Spring Security 在一个应用程序中结合数据库和 SAML 身份验证的主要内容,如果未能解决你的问题,请参考以下文章

Spring Security:OAuth 在获取访问令牌之前陷入重定向循环,但初始页面旁边的任何页面都不受保护

使用 spring-security-saml 在应用程序中没有配置 IDP 错误

Spring Security:简单的保护一个SpringBoot应用程序(总结)

使用 Spring Security 在一个应用程序中结合数据库和 SAML 身份验证

使用一个 Spring Security 保护两个独立的 Java 应用程序

使用 Spring Security 保护 REST API