1. введение
В этой статье мы рассмотрим самоуверенный подход Spring Boot к безопасности.
Проще говоря, мы сосредоточимся на конфигурации безопасности по умолчанию и на том, как мы можем отключить или настроить ее, если это необходимо.
Дальнейшее чтение:
Spring Security – безопасность отсутствует, фильтры отсутствуют, доступ разрешен
Вход в форму безопасности Spring
2. Настройка Безопасности По Умолчанию
Чтобы добавить безопасность в наше приложение Spring Boot, нам нужно добавить зависимость security starter :
org.springframework.boot spring-boot-starter-security
Это будет включать класс SecurityAutoConfiguration , содержащий начальную конфигурацию безопасности/по умолчанию.
Обратите внимание, что мы не указали здесь версию, предполагая, что проект уже использует Boot в качестве родительского.
Проще говоря, по умолчанию Аутентификация для приложения включена. Кроме того, согласование содержимого используется для определения того, следует ли использовать базовый вход или вход в форму.
Существуют некоторые предопределенные свойства, такие как:
spring.security.user.name spring.security.user.password
Если мы не настроим пароль с помощью предопределенного свойства spring.security.user.password и не запустим приложение, мы заметим, что пароль по умолчанию генерируется случайным образом и печатается в журнале консоли:
Using default security password: c8be15de-4488-4490-9dc6-fab3f91435c6
Дополнительные сведения по умолчанию см. в разделе Свойства безопасности на справочной странице Общие свойства приложения Spring Boot|/.
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 запускается с Приводом в пути к классу. Это вызывает проблемы , потому что другой класс автоматической настройки нуждается в том, который мы только что исключили , поэтому приложение не запустится.
Чтобы устранить эту проблему, нам нужно исключить этот класс; и, в зависимости от ситуации с приводом, нам нужно исключить ManagementWebSecurityAutoConfiguration .
3.1. Отключение по сравнению с Превосходящая Автоматическая Настройка безопасности
Существует существенная разница между отключением автоматической настройки и ее преодолением.
Отключив его, вы просто добавите зависимость от безопасности Spring и всю настройку с нуля. Это может быть полезно в нескольких случаях:
- Интеграция безопасности приложений с настраиваемым поставщиком безопасности
- Миграция устаревшего приложения Spring с уже существующей настройкой безопасности – для загрузки Spring
Но в большинстве случаев нам не нужно будет полностью отключать автоматическую настройку безопасности.
Способ настройки Spring Boot позволяет превзойти автоматически настроенную безопасность, добавив в наши новые/пользовательские классы конфигурации. Как правило, это проще, так как мы просто настраиваем существующую систему безопасности для удовлетворения наших потребностей.
4. Настройка Безопасности Весенней Загрузки
Если мы выбрали путь отключения автоматической настройки безопасности, нам, естественно, необходимо предоставить свою собственную конфигурацию.
Как мы уже обсуждали ранее, это конфигурация безопасности по умолчанию; мы можем настроить ее, изменив файл свойств.
Мы можем, например, переопределить пароль по умолчанию, добавив свой собственный:
spring.security.user.password=password
Если нам нужна более гибкая конфигурация, например, с несколькими пользователями и ролями, нам нужно использовать полный класс @Configuration :
@Configuration @EnableWebSecurity public class BasicConfiguration extends WebSecurityConfigurerAdapter { @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { PasswordEncoder encoder = PasswordEncoderFactories.createDelegatingPasswordEncoder(); auth .inMemoryAuthentication() .withUser("user") .password(encoder.encode("password")) .roles("USER") .and() .withUser("admin") .password(encoder.encode("admin")) .roles("USER", "ADMIN"); } @Override protected void configure(HttpSecurity http) throws Exception { http .authorizeRequests() .anyRequest() .authenticated() .and() .httpBasic(); } }
То @EnableWebSecurity аннотация имеет решающее значение, если мы отключим конфигурацию безопасности по умолчанию.
Если отсутствует, приложение не запустится. Аннотация необязательна только в том случае, если мы просто переопределяем поведение по умолчанию с помощью WebSecurityConfigurerAdapter .
Кроме того, обратите внимание, что нам необходимо использовать PasswordEncoder для установки паролей при использовании Spring Boot 2 . Для получения более подробной информации см. Наше руководство по кодеру паролей по умолчанию в Spring Security 5 .
Теперь мы должны убедиться, что наша конфигурация безопасности применяется правильно, с помощью нескольких быстрых тестов в реальном времени:
@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 { ResponseEntityresponse = restTemplate.getForEntity(base.toString(), String.class); assertEquals(HttpStatus.OK, response.getStatusCode()); assertTrue(response.getBody().contains("Baeldung")); } @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, по сути, стоит безопасность Spring, поэтому любая конфигурация безопасности, которая может быть выполнена с помощью этой, или любая интеграция, которую она поддерживает, также может быть реализована в Spring Boot.
5. Автоматическая настройка Spring Boot OAuth2 (с использованием устаревшего стека)
Spring Boot имеет специальную поддержку автоматической настройки для OAuth2.
Поддержка Spring Security OAuth , поставляемая с Spring Boot 1.x, была удалена в более поздних версиях загрузки вместо первоклассной поддержки OAuth, поставляемой в комплекте с Spring Security 5 . Мы увидим, как это использовать, в следующем разделе.
Для устаревшего стека (с использованием Spring Security OAuth) сначала нам нужно добавить зависимость 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, такие как:
- Сервер ресурсов – @EnableResourceServer
- Клиентское приложение – @EnableOAuth2Sso или @EnableOAuth2Client
Если нам нужно, чтобы наше приложение было одним из вышеперечисленных типов, нам просто нужно добавить некоторую конфигурацию в свойства приложения, как описано в приведенных выше ссылках.
Все специфические свойства OAuth2 можно найти в разделе Общие свойства приложения Spring Boot .
6. Автоматическая настройка Spring Boot OAuth2 (с использованием нового стека)
Чтобы использовать новый стек, нам необходимо добавить зависимости, основанные на том, что мы хотим настроить – сервер авторизации, сервер ресурсов или клиентское приложение.
Давайте рассмотрим их по очереди.
6.1. Поддержка Сервера авторизации OAuth2
Как мы видели в предыдущем разделе, стек Spring Security OAuth предлагал возможность настройки сервера авторизации в качестве приложения Spring. Но проект устарел, и Spring на данный момент не поддерживает свой собственный сервер авторизации. Вместо этого рекомендуется использовать существующих хорошо зарекомендовавших себя поставщиков, таких как Okta, Keycloak и Forgerock.
Тем не менее, Spring Boot упрощает настройку таких поставщиков. Для примера конфигурации скрытого ключа мы можем обратиться либо к Краткому руководству по использованию скрытого ключа с загрузкой Spring, либо к скрытому ключу, встроенному в приложение для загрузки Spring .
6.2. Поддержка сервера ресурсов OAuth2
Чтобы включить поддержку сервера ресурсов, нам нужно добавить эту зависимость:
org.springframework.boot spring-boot-starter-oauth2-resource-server
Для получения информации о последней версии перейдите по ссылке Maven Central .
Кроме того, в нашей конфигурации безопасности нам необходимо включить oauth2 ResourceServer() DSL:
@Configuration public class JWTSecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http ... .oauth2ResourceServer(oauth2 -> oauth2.jwt()); ... } }
Наш сервер ресурсов OAuth 2.0 с Spring Security 5 дает подробное представление об этой теме.
6.3. Поддержка клиентов OAuth2
Подобно тому, как мы настроили сервер ресурсов, клиентское приложение также нуждается в собственных зависимостях и DSL.
Вот конкретная зависимость для поддержки клиентов OAuth2:
org.springframework.boot spring-boot-starter-oauth2-client
Последнюю версию можно найти по адресу Maven Central .
Spring Security 5 также обеспечивает первоклассную поддержку входа в систему с помощью DSL oauth2login ().
Для получения подробной информации о поддержке единого входа в новом стеке, пожалуйста, обратитесь к нашему Простому единому входу в систему с помощью Spring Security OAuth2 .
7. Spring Boot 2 Безопасность против Spring Boot 1 Безопасность
По сравнению с Spring Boot 1, Spring Boot 2 значительно упростил автоматическую настройку .
В Spring Boot 2, если нам нужна собственная конфигурация безопасности, мы можем просто добавить пользовательский WebSecurityConfigurerAdapter . Это отключит автоматическую настройку по умолчанию и включит нашу пользовательскую конфигурацию безопасности.
Spring Boot 2 использует большинство настроек Spring Security по умолчанию. Из-за этого некоторые конечные точки, которые по умолчанию не были защищены в Spring Boot 1, теперь защищены по умолчанию .
Эти конечные точки включают статические ресурсы, такие как/css/**,/js/**,/images/**,/webjars/**,/**/favicon.ico и конечную точку ошибки. Если нам нужно разрешить неаутентифицированный доступ к этим конечным точкам, мы можем явно настроить это.
Чтобы упростить конфигурацию, связанную с безопасностью, Spring Boot 2 удалил следующие свойства Spring Boot 1 :
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
8. Заключение
В этой статье мы сосредоточились на конфигурации безопасности по умолчанию, предоставляемой Spring Boot. Мы увидели, как механизм автоматической настройки безопасности может быть отключен или переопределен, и как можно применить новую конфигурацию безопасности.
Исходный код OAuth2 можно найти в нашем репозитории OAuth2 на GitHub для устаревшего и нового стека. Остальную часть кода можно найти на учебниках GitHub .