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

为OAuth2 Spring Boot创建自定义OpenID身份提供商

Hey Alex, 我来帮你理清在Spring Boot OAuth2基础上搭建自定义OpenID身份提供商(IDP)的具体路径——其实OIDC本身就是OAuth2的上层扩展,所以咱们不用从零开始,只需要给现有OAuth2授权服务补上OIDC的核心特性就行~

核心逻辑先搞懂

OIDC本质是在OAuth2的授权码流程上,新增了身份认证的标准化能力:它通过id_token(一种JWT格式的令牌)来传递用户的身份信息,同时提供了一系列标准端点(比如用户信息端点、JWKS密钥端点)让客户端能安全地验证用户身份。你之前做的OAuth2授权是管“能不能访问API”,现在OIDC要管“你是谁”,两者完全兼容。

具体实现步骤(基于Spring Security OAuth2 Authorization Server)

现在Spring官方推荐用spring-security-oauth2-authorization-server这个模块(旧的Spring Security OAuth已经停止维护了,建议升级到这个),下面是具体操作:

1. 补上OIDC相关依赖

如果还没加,在你的pom.xml(Maven)里添上:

<dependency>
    <groupId>org.springframework.security</groupId>
    <artifactId>spring-security-oauth2-authorization-server</artifactId>
    <version>1.2.3</version> <!-- 用最新稳定版就行 -->
</dependency>

Gradle的话就加这个:

implementation 'org.springframework.security:spring-security-oauth2-authorization-server:1.2.3'

2. 给现有授权服务器配置OIDC特性

Spring的这个模块默认已经集成了OIDC的核心组件,你只需要在配置里启用它:

如果你用的是新版Spring Security 6+的配置方式(推荐)

@Bean
public RegisteredClientRepository registeredClientRepository() {
    RegisteredClient yourClient = RegisteredClient.withId(UUID.randomUUID().toString())
            .clientId("你的客户端ID")
            .clientSecret("{bcrypt}你的客户端密钥") // 记得用BCrypt加密
            .authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE)
            .authorizationGrantType(AuthorizationGrantType.REFRESH_TOKEN)
            .redirectUri("https://你的客户端回调地址")
            // 必须添加OIDC的标准scope,openid是核心,profile/email可选
            .scope(OidcScopes.OPENID)
            .scope(OidcScopes.PROFILE)
            .scope(OidcScopes.EMAIL)
            .scope("你原来的OAuth2权限范围")
            .build();
    return new InMemoryRegisteredClientRepository(yourClient);
}

// 默认配置就会启用所有OIDC标准端点,不用额外改
@Bean
public AuthorizationServerSettings authorizationServerSettings() {
    return AuthorizationServerSettings.builder().build();
}

如果你用的是旧版的@EnableAuthorizationServer配置

@Configuration
@EnableAuthorizationServer
public class AuthServerConfig implements AuthorizationServerConfigurer {

    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        clients.inMemory()
                .withClient("你的客户端ID")
                .secret("{bcrypt}你的客户端密钥")
                .authorizedGrantTypes("authorization_code", "refresh_token")
                // 一定要加openid这个scope,不然不会生成id_token
                .scopes("openid", "profile", "email", "你原来的权限范围");
    }

    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
        endpoints
                .authenticationManager(authenticationManager)
                .userDetailsService(userDetailsService)
                // 启用OIDC的ID Token生成器
                .oidcIdTokenGenerator(customOidcIdTokenGenerator());
    }

    // 自定义ID Token里的用户信息(比如加用户ID、昵称这些自定义字段)
    @Bean
    public OidcIdTokenGenerator customOidcIdTokenGenerator() {
        DefaultOidcIdTokenGenerator generator = new DefaultOidcIdTokenGenerator();
        generator.setClaimMapper(claims -> {
            // 从Authentication里拿你的用户对象,把信息塞到ID Token里
            YourUserEntity user = (YourUserEntity) claims.get(Principal.class.getName());
            claims.put("user_id", user.getId());
            claims.put("nickname", user.getNickname());
            return claims;
        });
        return generator;
    }

    // 你原来的tokenServices、authenticationManager这些配置保持不变就行
}

3. 不用自己写OIDC标准端点!

Spring的授权服务器已经帮你实现了所有OIDC要求的标准端点,直接就能用:

  • 授权端点:/oauth2/authorize(请求时要带scope=openid才会走OIDC流程)
  • Token端点:/oauth2/token(返回的响应里会包含id_token、access_token、refresh_token)
  • 用户信息端点:/userinfo(用access_token就能获取用户详细信息)
  • JWKS密钥端点:/.well-known/jwks.json(客户端用来验证ID Token签名的公钥)
  • OIDC发现端点:/.well-known/openid-configuration(客户端可以自动获取IDP的所有配置信息)

4. 自定义身份信息映射(如果需要)

如果你的用户系统不是用默认的UserDetails,可以实现OidcUserInfoMapper接口,把你的用户对象转换成OIDC标准的OidcUserInfo,这样用户信息端点就能正确返回符合标准的用户数据。

5. 测试一下流程

用Postman或者随便一个OIDC客户端工具测一遍:

  1. 访问授权端点:GET /oauth2/authorize?response_type=code&client_id=你的客户端ID&redirect_uri=你的回调地址&scope=openid%20profile
  2. 登录你的系统,授权后会跳转到回调地址,拿到授权码code
  3. 用授权码换Token:POST /oauth2/token,参数填grant_type=authorization_code、code=刚才拿到的码、redirect_uri=你的回调地址、client_id和client_secret
  4. 看响应里的id_token,解码后应该能看到用户的身份信息(比如sub是用户唯一标识,还有你自定义的字段)
  5. 调用/userinfo端点,带上access_token,应该能拿到用户的详细信息
几个关键注意点
  • 一定要给客户端配置openid这个scope,否则不会生成id_token,等于没启用OIDC
  • ID Token要用非对称加密(RSA)签名,Spring默认会自动生成密钥对,但生产环境建议用自己的密钥(可以配置在application.yml里)
  • ID Token里的sub字段是用户的唯一标识,必须要有,其他字段比如name、email是可选的,尽量符合OIDC标准
  • 如果要做单点登录(SSO),多个客户端只要信任这个IDP,就能用id_token实现跨应用登录

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 07:48:27