Автоматическая настройка безопасности Spring Boot

Автоматическая настройка безопасности Spring Boot

1. Вступление

В этой статье мы рассмотрим самоуверенный подход Spring Boot к безопасности.

Проще говоря, мы собираемся сосредоточиться на конфигурации безопасности по умолчанию и на том, как мы можем отключить или настроить ее при необходимости.

Дальнейшее чтение:

Spring Security - безопасность отсутствует, фильтра нет, разрешение на доступВсе

Различия между access = "allowAll", filters = "none", security = "none" в Spring Security.

Read more

Spring Security Form Войти

Пример входа в Spring - Как настроить простую форму входа в систему, базовую конфигурацию XML безопасности и некоторые другие дополнительные методы настройки.

Read more

2. Настройка безопасности по умолчанию

Чтобы повысить безопасность нашего приложения Spring Boot, нам нужно добавитьsecurity starter dependency:


    org.springframework.boot
    spring-boot-starter-security

Это будет включать классSecurityAutoConfiguration, содержащий начальную / стандартную конфигурацию безопасности.

Обратите внимание на то, что мы не указали версию здесь, предполагая, что проект уже использует Boot в качестве родительского.

Проще говоря,by default, the Authentication gets enabled for the Application. Also, content negotiation is used to determine if basic or formLogin should be used.

Есть несколько предопределенных свойств, таких как:

spring.security.user.name
spring.security.user.password

Если мы не настроим пароль с помощью предопределенного свойстваspring.security.user.password и не запустим приложение, мы заметим, что пароль по умолчанию генерируется случайным образом и печатается в журнале консоли:

Using default security password: c8be15de-4488-4490-9dc6-fab3f91435c6

Дополнительные значения по умолчанию см. В разделе свойств безопасности на справочной страницеSpring Boot Common Application Properties.

3. Отключение автоконфигурации

Чтобы отменить автоконфигурацию безопасности и добавить нашу собственную конфигурацию, нам нужно исключить классSecurityAutoConfiguration.

Это можно сделать с помощью простого исключения:

@SpringBootApplication(exclude = { SecurityAutoConfiguration.class })
public class SpringBootSecurityApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringBootSecurityApplication.class, args);
    }
}

Или добавив некоторую конфигурацию в файлapplication.properties:

spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.security.SecurityAutoConfiguration

Есть также некоторые частные случаи, когда этой настройки недостаточно.

Например, почти каждое приложение Spring Boot запускается с Actuator в пути к классам. This causes problems because another auto-configuration class needs the one we’ve just excluded, поэтому приложение не запустится.

Чтобы решить эту проблему, нам нужно исключить этот класс; и, в зависимости от ситуации с Actuator, нам нужно исключитьManagementWebSecurityAutoConfiguration.

3.1. Отключение против Превосходная автоматическая настройка безопасности

Есть существенная разница между отключением автоконфигурации и ее превышением.

Отключение его похоже на добавление зависимости Spring Security и всей настройки с нуля. Это может быть полезно в нескольких случаях:

  1. Интеграция безопасности приложений с индивидуальным поставщиком безопасности

  2. Миграция устаревшего приложения Spring с уже существующей настройкой безопасности - в Spring Boot

Но в большинстве случаев нам не нужно полностью отключать автоконфигурацию безопасности.

Способ, которым сконфигурирован Spring Boot, позволяет превзойти автоматически настроенную защиту, добавляя наши новые / настраиваемые классы конфигурации. Обычно это проще, поскольку мы просто настраиваем существующие настройки безопасности в соответствии с нашими потребностями.

4. Настройка безопасности загрузки Spring

Если мы выбрали способ отключения автоконфигурации безопасности, нам, естественно, потребуется предоставить нашу собственную конфигурацию.

Как мы уже обсуждали ранее, это конфигурация безопасности по умолчанию; мы можем настроить его, изменив файл свойств.

Мы можем, например, переопределить пароль по умолчанию, добавив наш собственный:

security.user.password=password

Если нам нужна более гибкая конфигурация, например, с несколькими пользователями и ролями - теперь вам нужно использовать полный класс@Configuration:

@Configuration
@EnableWebSecurity
public class BasicConfiguration extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(AuthenticationManagerBuilder auth)
      throws Exception {
        auth
          .inMemoryAuthentication()
          .withUser("user")
            .password("password")
            .roles("USER")
            .and()
          .withUser("admin")
            .password("admin")
            .roles("USER", "ADMIN");
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
          .authorizeRequests()
          .anyRequest()
          .authenticated()
          .and()
          .httpBasic();
    }
}

Аннотация@EnableWebSecurity имеет решающее значение, если мы отключим конфигурацию безопасности по умолчанию.

Если отсутствует, приложение не запустится. Аннотация является необязательной, только если мы просто переопределяем поведение по умолчанию с помощьюWebSecurityConfigurerAdapter.

Теперь мы должны убедиться, что наша конфигурация безопасности применяется правильно, с помощью нескольких быстрых тестов:

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = RANDOM_PORT)
public class BasicConfigurationIntegrationTest {

    TestRestTemplate restTemplate;
    URL base;
    @LocalServerPort int port;

    @Before
    public void setUp() throws MalformedURLException {
        restTemplate = new TestRestTemplate("user", "password");
        base = new URL("http://localhost:" + port);
    }

    @Test
    public void whenLoggedUserRequestsHomePage_ThenSuccess()
     throws IllegalStateException, IOException {
        ResponseEntity response
          = restTemplate.getForEntity(base.toString(), String.class);

        assertEquals(HttpStatus.OK, response.getStatusCode());
        assertTrue(response
          .getBody()
          .contains("example"));
    }

    @Test
    public void whenUserWithWrongCredentials_thenUnauthorizedPage()
      throws Exception {

        restTemplate = new TestRestTemplate("user", "wrongpassword");
        ResponseEntity response
          = restTemplate.getForEntity(base.toString(), String.class);

        assertEquals(HttpStatus.UNAUTHORIZED, response.getStatusCode());
        assertTrue(response
          .getBody()
          .contains("Unauthorized"));
    }
}

Идея заключается в том, что за Spring Boot Security на самом деле стоит Spring Security, поэтому любая конфигурация безопасности, которую можно выполнить с этим или любая другая интеграция, которую он поддерживает, также может быть реализована в Spring Boot.

5. Автоматическая настройка Spring Boot OAuth2

Spring Boot имеет специальную поддержку автоматической настройки OAuth2.

Прежде чем мы перейдем к этому, давайте добавим зависимость Maven, чтобы начать настройку нашего приложения:


   org.springframework.security.oauth
   spring-security-oauth2

Эта зависимость включает набор классов, способных запускать механизм автоконфигурации, определенный в классеOAuth2AutoConfiguration.

Теперь у нас есть несколько вариантов продолжения, в зависимости от области применения.

5.1. Автоконфигурация сервера авторизации OAuth2

Если мы хотим, чтобы наше приложение было поставщиком OAuth2, мы можем использовать@EnableAuthorizationServer.

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

Using default security password: a81cb256-f243-40c0-a585-81ce1b952a98
security.oauth2.client.client-id = 39d2835b-1f87-4a77-9798-e2975f36972e
security.oauth2.client.client-secret = f1463f8b-0791-46fe-9269-521b86c55b71

Эти учетные данные можно использовать для получения токена доступа:

curl -X POST -u 39d2835b-1f87-4a77-9798-e2975f36972e:f1463f8b-0791-46fe-9269-521b86c55b71 \
 -d grant_type=client_credentials
 -d username=user
 -d password=a81cb256-f243-40c0-a585-81ce1b952a98 \
 -d scope=write  http://localhost:8080/oauth/token

5.2. Другие параметры автоконфигурации Spring Boot OAuth2

Spring Boot OAuth2 имеет несколько других вариантов использования, таких как:

  1. Сервер ресурсов -@EnableResourceServer

  2. Клиентское приложение -@EnableOAuth2Sso или@EnableOAuth2Client

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

Все специфические свойства OAuth2 можно найти вSpring Boot Common Application Properties.

6. Безопасность Spring Boot 2 против безопасности Spring Boot 1

По сравнению с Spring Boot 1,Spring Boot 2 has greatly simplified the auto-configuration.

В Spring Boot 2, если нам нужна собственная конфигурация безопасности, мы можем просто добавить настраиваемыйWebSecurityConfigurerAdapter.. Это отключит автоконфигурацию по умолчанию и включит нашу настраиваемую конфигурацию безопасности.

Spring Boot 2 использует большинство настроек Spring Security по умолчанию. Из-за этогоsome of the endpoints that were unsecured by default in Spring Boot 1 are now secured by default.

Эти конечные точки включают статические ресурсы, такие как / css /, /js/, / images /, /webjars/, /**/favicon.ico, и конечную точку ошибки. Если нам нужно разрешить неаутентифицированный доступ к этим конечным точкам, мы можем явно настроить это.

Чтобы упростить конфигурацию, связанную с безопасностью,Spring Boot 2 has removed the following Spring Boot 1 properties:

security.basic.authorize-mode
security.basic.enabled
security.basic.path
security.basic.realm
security.enable-csrf
security.headers.cache
security.headers.content-security-policy
security.headers.content-security-policy-mode
security.headers.content-type
security.headers.frame
security.headers.hsts
security.headers.xss
security.ignored
security.require-ssl
security.sessions

7. Заключение

В этой статье мы сосредоточились на конфигурации безопасности по умолчанию, предоставляемой Spring Boot. Мы видели, как механизм автоконфигурации безопасности можно отключить или переопределить, и как можно применить новую конфигурацию безопасности.

Исходный код можно найтиover on Github.