Gymterview
senior

Как работает 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 для межсервисного взаимодействия.