返回 Skill 列表
extension
分类: 开发与工程无需 API Key

spring-authorization-server

Spring Authorization Server用于构建OAuth 2.1和OpenID Connect提供者。使用时机:用户提到“OAuth2服务器”、“授权服务器”、“OIDC提供者”、“令牌端点”,询问关于“如何实现OAuth2”、“创建授权服务器”、“签发JWT令牌”、“自定义OAuth提供者”。不适用于:OAuth2客户端配置 - 应该使用`spring-security`,资源服务器JWT验证 - 也应该使用`spring-security`。

person作者: jakexiaohubgithub

Spring Authorization Server - Quick Reference

Full Reference: See advanced.md for JPA client persistence, JWT configuration, custom token claims, user info endpoint, consent controller, token revocation, resource server integration, and testing.

Deep Knowledge: Use mcp__documentation__fetch_docs with technology: spring-authorization-server for comprehensive documentation.

Dependencies

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-oauth2-authorization-server</artifactId>
</dependency>

OAuth 2.1 Flows

Authorization Code + PKCE:

Client ──(1) Authorization Request + code_challenge──▶ Auth Server
      ◀──(2) Authorization Code──────────────────────
      ──(3) Token Request + code_verifier────────────▶
      ◀──(4) Access Token + Refresh Token + ID Token─

Basic Configuration

@Configuration
@EnableWebSecurity
public class SecurityConfig {

    @Bean
    @Order(1)
    public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http)
            throws Exception {
        OAuth2AuthorizationServerConfiguration.applyDefaultSecurity(http);

        http.getConfigurer(OAuth2AuthorizationServerConfigurer.class)
            .oidc(Customizer.withDefaults());  // Enable OpenID Connect

        http.exceptionHandling(exceptions -> exceptions
                .defaultAuthenticationEntryPointFor(
                    new LoginUrlAuthenticationEntryPoint("/login"),
                    new MediaTypeRequestMatcher(MediaType.TEXT_HTML)
                )
            )
            .oauth2ResourceServer(oauth2 -> oauth2.jwt(Customizer.withDefaults()));

        return http.build();
    }

    @Bean
    @Order(2)
    public SecurityFilterChain defaultSecurityFilterChain(HttpSecurity http) throws Exception {
        http.authorizeHttpRequests(authorize -> authorize.anyRequest().authenticated())
            .formLogin(Customizer.withDefaults());
        return http.build();
    }
}

Client Registration

@Bean
public RegisteredClientRepository registeredClientRepository() {
    RegisteredClient webClient = RegisteredClient.withId(UUID.randomUUID().toString())
        .clientId("web-client")
        .clientSecret("{noop}secret")
        .clientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_BASIC)
        .authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE)
        .authorizationGrantType(AuthorizationGrantType.REFRESH_TOKEN)
        .redirectUri("http://localhost:8080/login/oauth2/code/web-client")
        .scope(OidcScopes.OPENID)
        .scope(OidcScopes.PROFILE)
        .scope("read")
        .clientSettings(ClientSettings.builder()
            .requireAuthorizationConsent(true)
            .requireProofKey(true)  // PKCE required
            .build())
        .tokenSettings(TokenSettings.builder()
            .accessTokenTimeToLive(Duration.ofMinutes(15))
            .refreshTokenTimeToLive(Duration.ofDays(7))
            .reuseRefreshTokens(false)
            .build())
        .build();

    return new InMemoryRegisteredClientRepository(webClient);
}

Best Practices

| Do | Don't | |----|-------| | Require PKCE for public clients | Allow plain authorization code | | Use short-lived access tokens | Long-lived access tokens | | Rotate refresh tokens | Reuse refresh tokens indefinitely | | Store keys securely (Vault) | Hardcode keys in config | | Validate redirect URIs strictly | Allow open redirects |

When NOT to Use This Skill

  • OAuth2 Client Configuration - Use spring-security
  • Resource Server - For validating JWT tokens use spring-security
  • Basic Authentication - Use spring-security
  • Session Management - Use spring-session

Anti-Patterns

| Anti-Pattern | Why It's Bad | Better Approach | |-------------|--------------|-----------------| | Reusing refresh tokens | Security risk if compromised | Rotate on each use | | Long-lived access tokens | Increased exposure window | Keep to 15-30 min | | Hardcoded client secrets | Secrets in version control | Use secret management | | No PKCE for SPAs | Code interception vulnerability | Always require PKCE | | Wildcard redirect URIs | Open redirect vulnerability | Whitelist exact URIs |

Quick Troubleshooting

| Issue | Possible Cause | Solution | |-------|---------------|----------| | 401 at /oauth2/authorize | User not authenticated | Check SecurityFilterChain order | | Invalid client error | Client not registered | Verify RegisteredClientRepository | | JWKS endpoint 404 | JWKSource bean missing | Ensure JWKSource configured | | Token validation fails | Issuer mismatch | Check issuer URL matches | | PKCE validation fails | code_verifier mismatch | Verify PKCE implementation |

Production Checklist

  • [ ] HTTPS everywhere
  • [ ] RSA keys in secure storage
  • [ ] Client secrets encrypted
  • [ ] PKCE required for public clients
  • [ ] Token lifetimes configured
  • [ ] Consent flow implemented
  • [ ] Token revocation working
  • [ ] Rate limiting enabled
  • [ ] Audit logging configured

Reference Documentation