Prompts-MCP 686 skills · ai / design / design-pattern / framework / fundamentals / habit / lang / tech-selection /mcp/sse
framework framework/spring-security/oauth2-authorization-server.md medium

spring-security-oauth2-authorization-server

Spring Authorization Server 授权服务器 — 注册 client、走授权码 + PKCE、签发 token,与资源服务器分工(签发 vs 验签)。Use when 搭授权服务器 / 配 RegisteredClient / 签发 token / 接授权码 PKCE 时。

授权服务器授权码模式pkceregisteredclientauthorizationserversettingstoken 签发
paths
  • *.java

Spring Security · OAuth2 授权服务器

本条只管「授权服务器侧怎么注册 client、签发 token」。token 发出去后由资源服务器验签oauth2-resource-server.md——授权服务器签发、资源服务器验签,是两端,别混在一个应用里写。选哪种授权模式见 oauth2-grant-types.md

规则

维度 约定
依赖 spring-boot-starter-oauth2-authorization-server(独立于资源服务器 starter,由 Spring Authorization Server 提供)
默认配置 OAuth2AuthorizationServerConfiguration.applyDefaultSecurity(http) 暴露 /oauth2/authorize/oauth2/token/oauth2/jwks 等标准端点
client 注册 RegisteredClient + RegisteredClientRepository(生产用 JdbcRegisteredClientRepository 落库,别只用内存版)
授权码 + PKCE 公共客户端(SPA / App 无法保密 secret)必须 requireProofKey(true) 强制 PKCE,挡授权码拦截攻击
签名密钥 暴露 JWKSource(RSA/EC 密钥对),私钥签 token、公钥发布在 /oauth2/jwks 供资源服务器拉取验签
issuer AuthorizationServerSettings.builder().issuer(...),须与资源服务器配的 issuer-uri 一致

正例

@Bean
public RegisteredClientRepository registeredClientRepository() {
    // 授权码 + PKCE 的公共客户端:不发 client secret,强制 PKCE
    RegisteredClient spaClient = RegisteredClient.withId(UUID.randomUUID().toString())
        .clientId("spa-app")
        .clientAuthenticationMethod(ClientAuthenticationMethod.NONE)   // 公共客户端无 secret
        .authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE)
        .authorizationGrantType(AuthorizationGrantType.REFRESH_TOKEN)
        .redirectUri("https://app.example.com/callback")
        .scope("read")
        .clientSettings(ClientSettings.builder().requireProofKey(true).build()) // 强制 PKCE
        .build();
    return new InMemoryRegisteredClientRepository(spaClient);
}

@Bean
public AuthorizationServerSettings authorizationServerSettings() {
    // issuer 必须与资源服务器的 issuer-uri 完全一致,否则验签时 iss 校验失败
    return AuthorizationServerSettings.builder().issuer("https://auth.example.com").build();
}

反例

// ❌ 公共客户端(SPA/App)却不强制 PKCE:授权码可被中间人拦截后直接换 token
RegisteredClient.withId(id).clientId("spa-app")
    .clientAuthenticationMethod(ClientAuthenticationMethod.NONE)
    .authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE)
    .redirectUri("https://app.example.com/callback")
    .build();   // 缺 requireProofKey(true)

❌ 在同一个应用里既配授权服务器签发又配资源服务器自校验、还把签名私钥同时给两端:签发与验签是两端职责,私钥只留在授权服务器,资源服务器只拿 JWKS 公钥。

自检

  • [ ] 用 spring-boot-starter-oauth2-authorization-server 而非资源服务器 starter?
  • [ ] RegisteredClient 落库(JdbcRegisteredClientRepository),不是只用内存版上生产?
  • [ ] 公共客户端(SPA/App)requireProofKey(true) 强制了 PKCE?
  • [ ] issuer 与资源服务器的 issuer-uri 一致,私钥只在授权服务器、公钥经 JWKS 发布?

相关