使用 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 身份验证