You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于Spring Authorization Server实现SAML 2.0联邦SSO登录的方案咨询

Spring Authorization Server 实现 SAML SSO 方案

核心结论

Spring Authorization Server(SAS)官方目前不原生支持SAML 2.0协议,它的核心定位是实现OAuth 2.1和OpenID Connect 1.0标准。但可以通过将SAS作为SAML Service Provider(SP)对接外部SAML Identity Provider(IDP),再把SAML断言转换为OAuth2身份信息的方式,实现你需要的流程。

实现流程与指南

目标流程:SAS登录页→重定向至SAML IDP登录页→用户登录→IDP返回SAML断言→SAS验证断言并生成JWT令牌

1. 引入依赖

需要同时引入Spring Authorization Server和Spring SAML 2.0 SP的核心依赖:

<!-- Spring Authorization Server -->
<dependency>
    <groupId>org.springframework.security</groupId>
    <artifactId>spring-security-oauth2-authorization-server</artifactId>
    <version>1.2.3</version>
</dependency>
<!-- Spring SAML 2.0 Service Provider -->
<dependency>
    <groupId>org.springframework.security</groupId>
    <artifactId>spring-security-saml2-service-provider</artifactId>
    <version>6.2.3</version>
</dependency>

2. 配置SAML 2.0 SP(SAS作为SP)

在application.yml中配置SAML IDP的元数据信息,包括实体ID、SSO地址、验证证书等:

spring:
  security:
    saml2:
      relyingparty:
        registration:
          saml-idp:
            entity-id: "https://your-sas-domain/saml/sp"
            assertion-consumer-service-url: "https://your-sas-domain/login/saml2/sso/saml-idp"
            idp:
              entity-id: "https://saml-idp-domain/idp/entity"
              single-sign-on-url: "https://saml-idp-domain/idp/sso"
              verification:
                credentials:
                  - certificate-location: "classpath:saml-idp-cert.crt"

3. 整合SAML登录与Authorization Server

自定义SecurityFilterChain,将SAML登录流程接入SAS的身份验证体系:

@Configuration
@EnableWebSecurity
public class SecurityConfig {

    @Bean
    public SecurityFilterChain defaultSecurityFilterChain(HttpSecurity http) throws Exception {
        http
            .authorizeHttpRequests(authorize -> authorize
                .anyRequest().authenticated()
            )
            .saml2Login(saml2 -> saml2
                .loginPage("/login") // 触发重定向到SAML IDP的入口页
                .successHandler((request, response, authentication) -> {
                    // SAML登录成功后,将SAML认证信息存入SecurityContext
                    SecurityContextHolder.getContext().setAuthentication(authentication);
                })
            );
        return http.build();
    }

    // 配置Authorization Server客户端信息
    @Bean
    public RegisteredClientRepository registeredClientRepository() {
        RegisteredClient client = RegisteredClient.withId(UUID.randomUUID().toString())
            .clientId("your-sp-client-id")
            .clientSecret("{noop}your-sp-client-secret")
            .clientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_BASIC)
            .authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE)
            .authorizationGrantType(AuthorizationGrantType.REFRESH_TOKEN)
            .redirectUri("https://your-client-domain/callback")
            .scope(OidcScopes.OPENID)
            .scope(OidcScopes.PROFILE)
            .build();
        return new InMemoryRegisteredClientRepository(client);
    }

    // 配置Authorization Server基础设置
    @Bean
    public AuthorizationServerSettings authorizationServerSettings() {
        return AuthorizationServerSettings.builder()
            .issuer("https://your-sas-domain")
            .build();
    }
}

4. 转换SAML断言为OAuth2用户信息

自定义UserDetailsService,将SAML断言中的用户信息转换为Authorization Server可识别的UserDetails:

@Service
public class SamlUserDetailsService implements UserDetailsService {

    @Override
    public UserDetails loadUserByUsername(String nameId) throws UsernameNotFoundException {
        // 从SAML断言中提取用户标识(NameID)和权限信息
        return User.withUsername(nameId)
            .password("{noop}") // SAML登录无需本地密码
            .authorities("ROLE_USER")
            .build();
    }
}

5. 测试流程

  1. 客户端发起OAuth2授权请求:
    https://your-sas-domain/oauth2/authorize?client_id=your-sp-client-id&response_type=code&redirect_uri=https://your-client-domain/callback&scope=openid
    
  2. 页面跳转到SAS登录页,自动重定向至SAML IDP登录界面
  3. 用户在IDP完成登录后,IDP将SAML断言发送至SAS的ACS地址
  4. SAS验证断言有效性,生成用户Authentication
  5. 用户完成授权确认后,SAS返回授权码至客户端
  6. 客户端使用授权码交换JWT令牌:
    POST https://your-sas-domain/oauth2/token
    

关键注意事项

  • 确保SAML IDP与SAS的实体ID、ACS地址完全匹配,证书验证配置正确
  • 可通过自定义OidcUserInfoMapper将SAML断言中的额外字段(如邮箱、角色)写入JWT声明
  • 生产环境建议使用数据库存储RegisteredClient和用户信息,而非内存实现

内容的提问来源于stack exchange,提问作者pradhan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 12:21:23