Якщо Spring Security знаходиться в classpath, то вебдодатки за замовчуванням захищені. Spring Boot покладається на стратегію узгодження вмісту Spring Security, щоб визначити, чи використовувати httpBasic або formLogin. Також можна додати анотацію @EnableGlobalMethodSecurity з бажаними налаштуваннями, щоб впровадити засоби безпеки на рівні методів у вебдодаток.

UserDetailsService за замовчуванням надається для одного користувача. Ім'я користувача — user, а пароль — випадковий і виводиться на рівні WARN при запуску програми, як показано в наступному прикладі:

Using generated security password: 78fa095d-3f4c-48b1-ad50-e24c31d5cf35
Це генерований password is for development use only. This generated password is for development use only. Your security configuration must be updated before running your application in production.

Якщо ти здійснюєш тонке налаштування конфігурації журналювання, переконайся, що категорія org.springframework.boot.autoconfigure.security налаштована на реєстрацію повідомлень рівня WARN. В іншому випадку пароль за замовчуванням не виводиться.

Можна змінити ім'я користувача та пароль, вказавши spring.security.user.name та spring.security.user.password.

Основні функції, які тобі доступні за замовчуванням у вебдодатку, такі:

  • Бін UserDetailsService (або ReactiveUserDetailsService у разі застосування на WebFlux) зі сховищем у пам'яті та одним користувачем зі згенерованим паролем (властивості користувача див. SecurityProperties.User).

  • Вхід до системи за допомогою форм або захист за допомогою HTTP Basic (залежно від заголовка Accept у запиті) для всієї програми (включно з кінцевими точками актуатора, якщо актуатор знаходиться в classpath).

  • DefaultAuthenticationEventPublisher для публікації подій автентифікації.

Ти можеш передати інший AuthenticationEventPublisher, додавши для нього бін.

Засоби безпеки для MVC

Конфігурація засобів безпеки за замовчуванням реалізована в SecurityAutoConfiguration та UserDetailsServiceAutoConfiguration. SecurityAutoConfiguration імпортує SpringBootWebSecurityConfiguration для забезпечення веббезпеки, а UserDetailsServiceAutoConfiguration конфігурує автентифікацію, що також є актуальним для не пов'язаних з вебдодатків. Щоб повністю відключити стандартну конфігурацію засобів безпеки вебдодатка або об'єднати кілька компонентів Spring Security, таких як клієнт та сервер ресурсів OAuth2, додай бін типу SecurityFilterChain (при цьому конфігурація UserDetailsService або засоби безпеки для Actuator не будуть відключені).

Щоб, крім іншого, відключити конфігурацію UserDetailsService, можна додати бін типу UserDetailsService, AuthenticationProvider або AuthenticationManager.

Правила доступу можна перевизначати шляхом додавання біна користувача SecurityFilterChain або WebSecurityConfigurerAdapter. Spring Boot передбачає допоміжні методи, які можна використовувати для визначення правил доступу для кінцевих точок актуаторів і статичних ресурсів. EndpointRequest можна використовувати для створення RequestMatcher, що ґрунтується на властивості management.endpoints.web.base-path. PathRequest можна використовувати, щоб створити RequestMatcher для ресурсів, що знаходяться в місцях, які часто використовуються.

Безпека в WebFlux

Подобно додаткам Spring MVC можна захистити свої програми WebFlux, додавши залежність spring-boot-starter-security. Конфігурація засобів безпеки за замовчуванням реалізована в ReactiveSecurityAutoConfiguration та UserDetailsServiceAutoConfiguration. ReactiveSecurityAutoConfiguration імпортує WebFluxSecurityConfiguration для забезпечення веббезпеки, а UserDetailsServiceAutoConfiguration конфігурує автентифікацію, що також є актуальним для програм, не пов'язаних з веб. Щоб повністю відключити стандартну конфігурацію засобів безпеки вебдодатку, можна додати бін типу WebFilterChainProxy (при цьому конфігурація UserDetailsService або засоби безпеки для Actuator не відключаються).

Щоб також вимкнути конфігурацію UserDetailsService, можна додати бін типу ReactiveUserDetailsService або ReactiveAuthenticationManager.

Правила доступу та використання декількох компонентів Spring Security, такі як клієнт та сервер ресурсів OAuth 2, можна налаштувати шляхом додавання кастомного біну SecurityWebFilterChain. Spring Boot передбачає допоміжні методи, які можна використовувати для визначення правил доступу для кінцевих точок актуаторів і статичних ресурсів. EndpointRequest можна використовувати для створення ServerWebExchangeMatcher, який базується на властивості management.endpoints.web.base-path.

PathRequest можна використовувати, щоб створити ServerWebExchangeMatcher для ресурсів, що знаходяться в місцях, які часто використовуються.

Наприклад, можна налаштувати конфігурацію засобів безпеки, додавши щось на зразок:

Java
import org.springframework.boot.autoconfigure.security.reactive.PathRequest;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.web.server.ServerHttpSecurity;
import org.springframework.security.web.server.SecurityWebFilterChain;
import static org.springframework.security.config.Customizer.withDefaults;
@Configuration(proxyBeanMethods = false)
public class MyWebFluxSecurityConfiguration {
    @Bean
    public SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
        http.authorizeExchange((exchange) -> {
            exchange.matchers(PathRequest.toStaticResources().atCommonLocations()).permitAll();
            exchange.pathMatchers("/foo", "/bar").authenticated();
        });
        http.formLogin(withDefaults());
        return http.build();
    }
}
Kotlin

import org.springframework.boot.autoconfigure.security.reactive.PathRequest
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.security.config.web.server.ServerHttpSecurity
import org.springframework.security.web.server.SecurityWebFilterChain
@Configuration(proxyBeanMethods = false)
class MyWebFluxSecurityConfiguration {
    @Bean
    fun springSecurityFilterChain(http: ServerHttpSecurity): SecurityWebFilterChain {
        http.authorizeExchange { spec ->
            spec.matchers(PathRequest.toStaticResources().atCommonLocations()).permitAll()
            spec.pathMatchers("/foo", "/bar").authenticated()
        }
        http.formLogin()
        return http.build()
    }
}/code>

OAuth2

OAuth2 — це система авторизації, що широко використовується, яка підтримується Spring.

Клієнт

Якщо у твоєму classpath є spring-security-oauth2-client, можна скористатися деякими можливостями автоконфігурації для встановлення клієнтів OAuth2/Open ID Connect. Ця конфігурація використовує властивості OAuth2ClientProperties. Ці властивості застосовні як до сервлетів, так і до реактивних програм.

Можна зареєструвати кілька клієнтів і постачальників OAuth2 під префіксом spring.security.oauth2.client, як показано в наступному приклад:

Properties

spring.security.oauth2.client.registration.my-client-1.client-id=abcd
spring.security.oauth2.client.registration.my-client-1.client-secret=password
spring.security.oauth2.client.registration.my-client-1.client-name=Client for user scope
spring.security.oauth2.client.registration.my-client-1.provider=my-oauth-provider
spring.security.oauth2.client.registration.my-client-1.scope=user
spring.security.oauth2.client.registration.my-client-1.redirect-uri=https://my-redirect-uri.com
spring.security.oauth2.client.registration.my-client-1.client-authentication-method=basic
spring.security.oauth2.client.registration.my-client-1.authorization-grant-type=authorization-code
spring.security.oauth2.client.registration.my-client-2.client-id=abcd
spring.security.oauth2.client.registration.my-client-2.client-secret=password
spring.security.oauth2.client.registration.my-client-2.client-name=Client for email scope
spring.security.oauth2.client.registration.my-client-2.provider=my-oauth-provider
spring.security.oauth2.client.registration.my-client-2.scope=email
spring.security.oauth2.client.registration.my-client-2.redirect-uri=https://my-redirect-uri.com
spring.security.oauth2.client.registration.my-client-2.client-authentication-method=basic
spring.security.oauth2.client.registration.my-client-2.authorization-grant-type=authorization_code
spring.security.oauth2.client.provider.my-oauth-provider.authorization-uri=https://my-auth-server/oauth/authorize
spring.security.oauth2.client.provider.my-oauth-provider.token-uri=https://my-auth-server/oauth/token
spring.security.oauth2.client.provider.my-oauth-provider.user-info-uri=https://my-auth-server/userinfo
spring.security.oauth2.client.provider.my-oauth-provider.user-info-authentication-method=header
spring.security.oauth2.client.provider.my-oauth-provider.jwk-set-uri=https://my-auth-server/token_keys
spring.security.oauth2.client.provider.my-oauth-provider.user-name-attribute=name
Yaml

  security:
    oauth2:
      client:
        registration:
          my-client-1:
            client-id: "abcd"
            client-secret: "password"
            client-name: "Client for user scope"
            provider: "my-oauth-provider"
            scope: "user"
            redirect-uri: "https://my-redirect-uri.com"
            client-authentication-method: "basic"
            authorization-grant-type: "authorization-code"
          my-client-2:
            client-id: "abcd"
            client-secret: "password"
            client-name: "Client for email scope"
            provider: "my-oauth-provider"
            scope: "email"
            redirect-uri: "https://my-redirect-uri.com"
            client-authentication-method: "basic"
            authorization-grant-type: "authorization_code"
        provider:
          my-oauth-provider:
            authorization-uri: "https://my-auth-server/oauth/authorize"
            token-uri: "https://my-auth-server/oauth/token"
            user-info-uri: "https://my-auth-server/userinfo"
            user-info-authentication-method: "header"
            jwk-set-uri: "https://my-auth-server/token_keys"
            user-name-attribute: "name"
        

Для постачальників OpenID Connect, які підтримують виявлення OpenID Connect, конфігурацію можна ще більше спростити. Постачальник повинен бути налаштований з використанням issuer-uri, який є URI-ідентифікатором, який додає твердження про те, що цей URI-ідентифікатор є ідентифікатором видавця. Наприклад, якщо переданий issuer-uri — "https://example.com", запит OpenID Provider Configuration Request буде зроблений на "https://example.com/.well-known/openid-configuration". Очікується, що результатом буде відповідь OpenID Provider Configuration Response. У цьому прикладі показано, як постачальник OpenID Connect можна налаштувати за допомогою issuer-uri:

Properties
spring.security.oauth2.client.provider.oidc-provider.issuer-uri=https://dev-123456.oktapreview.com/oauth2/default/
Yaml
spring:
  security:
    oauth2:
      client:
        provider:
          oidc-provider:
            issuer-uri: "https://dev-123456.oktapreview.com/oauth2/default/"

За замовчуванням OAuth2LoginAuthenticationFilter у Spring Security обробляє тільки URL-адреси, відповідні /login/oauth2/code/*. Якщо потрібно налаштувати redirect-uri на використання іншого шаблону, потрібно створити конфігурацію для обробки цього шаблону. Наприклад, для додатків сервлетів можна додати власну SecurityFilterChain, яка буде схожа на таку:

Java
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.web.SecurityFilterChain;
@Configuration(proxyBeanMethods = false)
public class MyOAuthClientConfiguration {
    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http.authorizeRequests((requests) -> requests.anyRequest().authenticated());
        http.oauth2Login((login) -> login.redirectionEndpoint().baseUri("custom-callback"));
        return http.build();
    }
}
Kotlin
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.security.config.annotation.web.builders.HttpSecurity
import org.springframework.security.web.SecurityFilterChain
@Configuration(proxyBeanMethods = false)
class MyOAuthClientConfiguration {
    @Bean
    fun securityFilterChain(http: HttpSecurity): SecurityFilterChain {
        http.authorizeRequests().anyRequest().authenticated()
        http.oauth2Login().redirectionEndpoint().baseUri("custom-callback")
        return http.build()
    }
}
Spring Boot автоматично конфігурує InMemoryOAuth2AuthorizedClientService, який використовується Spring Security для керування процедурами реєстрації клієнтів. InMemoryOAuth2AuthorizedClientService має обмежені можливості, тому ми рекомендуємо використовувати його тільки в оточеннях розробки. У виробничих оточеннях використовуй JdbcOAuth2AuthorizedClientService або створи власну реалізацію OAuth2AuthorizedClientService.

Реєстрація клієнтів OAuth2 для спільних постачальників

Для поширених постачальників OAuth2 та OpenID, включно з Google, Github, Facebook та Okta, ми передбачаємо набір постачальників за замовчуванням (google, github, facebook та okta, відповідно).

Якщо не потрібно налаштовувати цих постачальників, то можеш встановити атрибут provider для того, для якого потрібно вивести значення за замовчуванням. До того ж, якщо ключ для реєстрації клієнта збігається з постачальником, що підтримується за замовчуванням, Spring Boot визначить і його.

Іншими словами, дві конфігурації в наступному прикладі використовують постачальника Google:

Properties
spring.security.oauth2.client.registration.my-client.client-id=abcd
spring.security.oauth2.client.registration.my-client.client-secret=password
spring.security.oauth2.client.registration.my-client.provider=google
spring.security.oauth2.client.registration.google.client-id=abcd
spring.security.oauth2.client.registration.google.client-secret=password
Yaml
spring:
  security:
    oauth2:
      client:
        registration:
          my-client:
            client-id: "abcd"
            client-secret: "password"
            provider: "google"
          google:
            client-id: "abcd"
            client-secret: "password"
        

Сервер ресурсів

Якщо у твоєму classpath є spring-security-oauth2-resource-server, Spring Boot може встановити сервер ресурсів OAuth2. Для конфігурації JWT необхідно вказати JWK Set URI або OIDC Issuer URI, як показано в наступних прикладах:

Properties
spring. security.oauth2.resourceserver.jwt.jwk-set-uri=https://example.com/oauth2/default/v1/keys
Yaml
spring:
  security:
    oauth2:
      resourceserver:
        jwt:
          jwk-set-uri: "https://example.com/oauth2/default/v1/keys"
Properties
spring.security.oauth2.resourceserver. jwt.issuer-uri=https://dev-123456.oktapreview.com/oauth2/default/
Yaml
spring:
  security:
    oauth2:
      resourceserver:
        jwt:
          issuer-uri: "https://dev-123456.oktapreview.com/oauth2/default/"
Якщо сервер авторизації не підтримує JWK Set URI, то можна налаштувати сервер ресурсів з відкритим ключем, який використовується для перевірки JWT-сигнатури. Це можна зробити за допомогою властивості spring.security.oauth2.resourceserver.jwt.public-key-location, де значення має вказувати на файл, який містить відкритий ключ, закодований у форматі PEM x509.

Ті ж властивості застосовні як для сервлетних, так і для реактивних додатків.

До того ж, можна визначити власний бін JwtDecoder для сервлетних додатків або ReactiveJwtDecoder для реактивних програм.

У випадках, якщо замість JWT використовуються непрозорі токени, можна налаштувати такі властивості для валідації токенів за допомогою інтроспекції:

Properties
spring.security.oauth2.resourceserver.opaquetoken.introspection-uri=https://example.com/check-token
spring.security.oauth2.resourceserver.opaquetoken.client-id=my-client-id
spring.security.oauth2.resourceserver.opaquetoken.client-secret=my-client-secret
Yaml
spring:
  security:
    oauth2:
      resourceserver:
        opaquetoken:
          introspection-uri: "https://example.com/check-token"
          client-id: "my-client-id"
          client-secret: "my-client-secret"

Знову ж, ті самі властивості застосовні як для сервлетних, так і для реактивних додатків.

В якості альтернативи можна визначити власний бін OpaqueTokenIntrospector для сервлетних додатків або ReactiveOpaqueTokenIntrospector для реактивних додатків.

Сервер авторизації

Наразі Spring Security не передбачає підтримки для реалізації сервера авторизації OAuth 2.0. Однак ця функціональність доступна з проєкту Spring Security OAuth, який з часом буде повністю витіснений Spring Security. До того часу можна використовувати модуль spring-security-oauth2-autoconfigure для простого налаштування сервера авторизації OAuth 2.0; див. документацію для ознайомлення з інструкціями.