Какие основные механизмы авторизации и аутентификации существуют в современных приложениях?

Ответ

Аутентификация (Authentication) — проверка личности пользователя ("кто ты?"). Авторизация (Authorization) — проверка прав доступа к ресурсам ("что тебе разрешено?").

Основные механизмы:

1. На основе токенов (Token-Based):

  • JWT (JSON Web Token): Компактный самодостаточный токен в формате JSON. Содержит заголовок, полезную нагрузку (claims) и подпись.
    // Пример создания JWT с библиотекой jjwt
    String token = Jwts.builder()
        .setSubject("user123")
        .claim("roles", "ROLE_ADMIN")
        .setExpiration(Date.from(Instant.now().plusSeconds(3600)))
        .signWith(SignatureAlgorithm.HS256, secretKey)
        .compact();

    Плюсы: Статус-лесс, масштабируемость. Минусы: Сложность отзыва до истечения срока.

2. Протоколы делегирования доступа:

  • OAuth 2.0: Протокол авторизации, позволяющий приложению получать ограниченный доступ к данным пользователя в другом сервисе (например, "Войти через Google"). Основные потоки (grants): Authorization Code (для веб-приложений), Client Credentials (для сервис-сервисного взаимодействия), Resource Owner Password Credentials (устаревший).
  • OpenID Connect (OIDC): Надстройка над OAuth 2.0 для аутентификации. Возвращает ID Token (JWT) с информацией о пользователе.

3. Фреймворки:

  • Spring Security: Всеобъемлющий фреймворк для Java.
    @Configuration
    @EnableWebSecurity
    public class SecurityConfig {
        @Bean
        public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
            http
                .authorizeHttpRequests(authz -> authz
                    .requestMatchers("/admin/**").hasRole("ADMIN")
                    .anyRequest().authenticated()
                )
                .oauth2ResourceServer(OAuth2ResourceServerConfigurer::jwt);
            return http.build();
        }
    }

    Аннотации: @PreAuthorize("hasRole('ADMIN')"), @Secured("ROLE_USER").

4. Другие: Basic Auth (логин/пароль в заголовке, небезопасно без HTTPS), Session-Based Auth (stateful, сессия хранится на сервере).

Best Practice: Для REST API использовать JWT или OAuth 2.0 / OIDC. Никогда не хранить секретные ключи или пароли в клиентском коде.

Ответ 18+ 🔞

А, слушай, ну вот опять эти два термина, которые все путают, как хуй с пальцем! Смотри, раз и навсегда, чтобы в голове отложилось, блядь.

Аутентификация — это когда ты доказываешь, что ты — это ты. "Кто ты, сука?" — вот главный вопрос. Показал паспорт, логин с паролем, отпечаток пальца — всё, ты прошёл.

Авторизация — это уже про права. "А что тебе, собственно, можно, чувак?" Ты уже внутрь пролез, а теперь смотришь — можно ли тебе в этот кабинет, или только в сортир.

Ну и как это всё работает, блядь?

1. Токены, ёпта (Token-Based): Вот это сейчас модно, статус-лесс, всё такое. Самый популярный — JWT (JSON Web Token). Это такая бумажка, но в цифре. Внутри записано, кто ты и что тебе можно. И она самодостаточная, её можно проверить, не лазая в базу каждый раз.

// Вот так эту бумажку штампуют, смотри
String token = Jwts.builder()
    .setSubject("user123") // Кто ты?
    .claim("roles", "ROLE_ADMIN") // А чем тебе можно заниматься?
    .setExpiration(Date.from(Instant.now().plusSeconds(3600))) // Через час — в пизду, протухнешь
    .signWith(SignatureAlgorithm.HS256, secretKey) // И подпись, чтобы не подделали, блядь
    .compact();

Чем хорошо: Серверу похуй, он не помнит тебя. Масштабируется легко. Чем плохо: А как её отозвать, если чувак нахуйничал? Жди, пока срок действия не кончится. Хуйня.

2. Большие, взрослые протоколы:

  • OAuth 2.0: Это не про то, чтобы войти в приложение! Это про авторизацию, ёпта! Чтобы твоё приложение могло попросить у Гугла доступ к календарю пользователя, например. "Дай, пожалуйста, доступ к этому и этому". Пользователь говорит: "Да, можно". И всё. Основные способы (grants): Authorization Code (для нормальных веб-приложений), Client Credentials (когда сервис тупо общается с сервисом).
  • OpenID Connect (OIDC): А вот это уже надстройка над OAuth, чтобы как раз аутентифицировать. То есть узнать, кто пользователь. Возвращает тебе ID Token (опять же JWT), где написано имя, почта и прочая хуйня.

3. Фреймворки, которые всё за тебя делают: Ну, Spring Security, куда же без него. Это такой злой батя, который стоит на входе и всех проверяет.

@Configuration
@EnableWebSecurity
public class SecurityConfig {
    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http
            .authorizeHttpRequests(authz -> authz
                .requestMatchers("/admin/**").hasRole("ADMIN") // Сюда только админы, остальные — нахуй
                .anyRequest().authenticated() // На всё остальное просто зайди как человек
            )
            .oauth2ResourceServer(OAuth2ResourceServerConfigurer::jwt); // А проверять будем по JWT
        return http.build();
    }
}

А потом над методами можно вешать @PreAuthorize("hasRole('ADMIN')") — красиво и понятно.

4. Всякое старое и не очень:

  • Basic Auth: Логин и пароль, засунутые прямо в заголовок запроса. Без HTTPS — это как кричать свой пароль в толпу, ядрёна вошь.
  • Сессии (Session-Based): Старый добрый способ. Зашёл — тебе на сервере выделили ячейку памяти (сессию), дали её номер в куки. Сервер тебя помнит. Stateful, блядь. Масштабируется хуже, но зато токен можно убить мгновенно.

Итог, блядь, для современных REST API: Бери JWT или OAuth 2.0 / OIDC. И никогда, слышишь, НИКОГДА не пихай секретные ключи или пароли в код, который уходит на фронтенд! Это пиздец как небезопасно, тебя потом найдут и выебут с позором.