Как работает OAuth 2.0 и OpenID Connect?
OAuth 2.0 — протокол авторизации, позволяющий приложению получить ограниченный доступ к ресурсам пользователя без передачи его пароля. OpenID Connect (OIDC) — надстройка над OAuth 2.0, добавляющая аутентификацию.
Роли в OAuth 2.0
| Роль | Описание | Пример |
|---|---|---|
| Resource Owner | Владелец ресурса (пользователь) | Клиент банка |
| Client | Приложение, запрашивающее доступ | Мобильное приложение банка |
| Authorization Server | Сервер авторизации | Keycloak, Auth0 |
| Resource Server | Сервер с защищёнными ресурсами | API банка (Spring Boot) |
Authorization Code Flow (основной поток)
Используется для серверных веб-приложений. Самый безопасный поток.
Схема Authorization Code Flow
Пользователь Приложение (Client) Auth Server API (Resource Server)
│ │ │ │
│── "Войти" ───>│ │ │
│ │── Redirect ───────>│ │
│ │ /authorize? │ │
│ │ response_type=code│ │
│ │ &client_id=XXX │ │
│ │ &scope=openid │ │
│<── Страница логина ───────────────│ │
│── логин/пароль ──────────────────>│ │
│<── Redirect callback?code=CODE ──│ │
│ │── POST /token ───>│ │
│ │ code=CODE │ │
│ │ client_secret=YYY│ │
│ │<── access_token ──│ │
│ │ refresh_token │ │
│ │ id_token (OIDC) │ │
│ │── GET /api ────────────────────────────>│
│ │ Authorization: Bearer access_token │
│ │<── Данные ──────────────────────────────│
Authorization Code + PKCE (для SPA и мобильных приложений)
PKCE (Proof Key for Code Exchange) защищает от перехвата authorization code.
Пример
// 1. Генерация code_verifier
String codeVerifier = generateRandomString(128);
// 2. Вычисление code_challenge
String codeChallenge = Base64.getUrlEncoder()
.withoutPadding()
.encodeToString(
MessageDigest.getInstance("SHA-256").digest(codeVerifier.getBytes())
);
// 3. Отправка code_challenge в /authorize
// 4. При обмене code на token отправка code_verifier
// Сервер проверяет: SHA256(code_verifier) == code_challenge
Client Credentials Flow (сервис-к-сервису)
Используется для межсервисного взаимодействия без участия пользователя.
Пример
curl -X POST https://auth.mybank.com/oauth/token \
-d "grant_type=client_credentials" \
-d "client_id=payment-service" \
-d "client_secret=SECRET" \
-d "scope=transfer.create transfer.read"
Настройка Client Credentials в Spring Boot
@Bean
public OAuth2AuthorizedClientManager authorizedClientManager(
ClientRegistrationRepository clientRegistrationRepository,
OAuth2AuthorizedClientRepository authorizedClientRepository) {
OAuth2AuthorizedClientProvider provider =
OAuth2AuthorizedClientProviderBuilder.builder()
.clientCredentials()
.build();
DefaultOAuth2AuthorizedClientManager manager =
new DefaultOAuth2AuthorizedClientManager(
clientRegistrationRepository, authorizedClientRepository);
manager.setAuthorizedClientProvider(provider);
return manager;
}
OpenID Connect (OIDC)
OIDC добавляет к OAuth 2.0:
- ID Token — JWT с информацией о пользователе (sub, email, name)
- UserInfo Endpoint —
/userinfoдля получения расширенной информации - Discovery —
/.well-known/openid-configurationс описанием всех эндпоинтов - Стандартные scopes:
openid,profile,email
Настройка Spring Security + OAuth 2.0 Resource Server
Пример
spring:
security:
oauth2:
resourceserver:
jwt:
issuer-uri: https://auth.mybank.com/realms/bank
Конфигурация SecurityFilterChain
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests(auth -> auth
.requestMatchers("/api/public/**").permitAll()
.requestMatchers("/api/accounts/**").hasRole("MANAGER")
.requestMatchers("/api/admin/**").hasRole("ADMIN")
.anyRequest().authenticated()
)
.oauth2ResourceServer(oauth2 -> oauth2
.jwt(jwt -> jwt
.jwtAuthenticationConverter(jwtAuthenticationConverter())
)
);
return http.build();
}
}
В банках OAuth 2.0 / OIDC является стандартом для аутентификации пользователей и авторизации межсервисных запросов. Как правило, используется Keycloak или аналогичный сервер авторизации.
На собеседовании: интервьюер хочет услышать про роли (Resource Owner, Client, Auth Server, Resource Server), описание Authorization Code Flow и понимание разницы между OAuth 2.0 (авторизация) и OIDC (аутентификация). Частая ошибка — путать аутентификацию и авторизацию и не знать Client Credentials Flow для межсервисного взаимодействия.