Kiến trúc:
- 1 Authorization Server (Spring Authorization Server) — identity provider, phát JWT.
- N Resource Server (microservices) — validate token cục bộ (không cần network call đến auth server mỗi request).
Flow:
1. Client → POST /oauth2/token (client credentials hoặc authorization code + PKCE)
2. AuthServer → trả JWT
3. Client → GET /api/data với header "Authorization: Bearer <JWT>"
4. ResourceServer → verify chữ ký JWT (public key qua JWKS endpoint)
→ check claims (iss, exp, scope)
5. Trả 200 hoặc 401OAuth 2.1 vs 2.0: loại bỏ grant type nguy hiểm:
- ❌ Implicit Grant (token trong URL fragment — dễ leak).
- ❌ Password Grant (client cầm credential user — phishing risk).
- ✅ PKCE bắt buộc với Authorization Code (chống code interception).
Spring Security 6:
@Configuration
@EnableWebSecurity
class SecurityConfig {
@Bean
SecurityFilterChain filter(HttpSecurity http) throws Exception {
return http
.authorizeHttpRequests(a -> a.anyRequest().authenticated())
.oauth2ResourceServer(o -> o.jwt(j -> j.jwkSetUri("https://auth/jwks")))
.build();
}
}Thực tế: đa số team dùng auth server bên thứ 3 (Keycloak, Auth0, Okta) thay vì tự build — security phức tạp, dễ sai.
Architecture:
- One Authorization Server (Spring Authorization Server) — identity provider, issues JWTs.
- N Resource Servers (microservices) — validate tokens locally (no network call to the auth server per request).
Flow:
1. Client → POST /oauth2/token (client credentials or authorization code + PKCE)
2. AuthServer → returns JWT
3. Client → GET /api/data with "Authorization: Bearer <JWT>"
4. ResourceServer → verifies JWT signature (public key from JWKS endpoint)
→ checks claims (iss, exp, scope)
5. Returns 200 or 401OAuth 2.1 vs 2.0: drops dangerous grant types:
- ❌ Implicit Grant (tokens in URL fragments — leakable).
- ❌ Password Grant (client holds user credentials — phishing risk).
- ✅ PKCE required for Authorization Code (prevents code interception).
Spring Security 6:
@Configuration
@EnableWebSecurity
class SecurityConfig {
@Bean
SecurityFilterChain filter(HttpSecurity http) throws Exception {
return http
.authorizeHttpRequests(a -> a.anyRequest().authenticated())
.oauth2ResourceServer(o -> o.jwt(j -> j.jwkSetUri("https://auth/jwks")))
.build();
}
}In practice: most teams use a third-party auth server (Keycloak, Auth0, Okta) instead of building one — security is complex and error-prone.