Spring Security — это чрезвычайно полезная технология. Это позволяет защитить ваше приложение, не будучи слишком навязчивым, и позволяет подключать множество различных механизмов аутентификации. С другой стороны, не так-то просто попасть в один из тех инструментов, которые мне приходится переучивать при каждом прикосновении к нему. В этом посте я опишу некоторые основы Spring Security и как вы можете использовать его для защиты различных частей вашего приложения по-разному.
Конфигурация Spring Security
Давайте посмотрим на часть конфигурации для Spring Security, вы можете найти полный исходный код на Github . Я использую Spring Boot, но большинство частей должно быть одинаковым для всех приложений Spring.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
|
@Configuration public class SecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http .httpBasic() .and() .authorizeRequests().antMatchers( "/secret/**" ).authenticated() .and() .authorizeRequests().antMatchers( "/**" ).permitAll(); } } |
В простейшем случае вы просто настраиваете HttpSecurity
используя цепочку методов, которая является обычной в Spring Security. В этом случае мы включаем HTTP Basic Auth и требуем аутентификацию для одной конечной точки (все ниже /secure/
). Все остальные запросы (обозначенные /**
) будут разрешены. Здесь используются шаблоны с синтаксисом пути Ant, но вы также можете использовать другой RequestMatcher
чтобы решить, для каких частей вашего приложения требуется какая аутентификация.
Все функциональные возможности загрузки Spring реализованы в виде цепочки фильтров. Вызов функции httpBasic()
выше фактически гарантирует, что соответствующий фильтр добавлен в цепочку фильтров. В этом случае BasicAuthenticationFilter
проверит наличие заголовка Authorization
и оценит его. Если он найден, он добавит объект Authentication
в контекст и выполнит остальную часть цепочки фильтров. В конце цепочки находится FilterSecurityInterceptor
который проверяет, требует ли запрашиваемый ресурс аутентификации и соответствует ли тот, который установлен, запрошенным ролям.
Вы также можете исключить некоторые части приложения из аутентификации, настроив WebSecurity
. Следующий метод удостоверяется, что любые запросы к /resources/
пропускают конфигурацию выше.
1
2
3
4
|
@Override public void configure(WebSecurity web) throws Exception { web.ignoring().antMatchers( "/resources/**" ); } |
Под капотом это добавит дополнительную цепочку фильтров, которая запускается для настроенного пути и ничего не делает.
Несколько цепочек фильтров
Иногда бывает необходимо использовать разные механизмы аутентификации для разных частей вашего приложения. Для этого Spring Security позволяет добавить несколько объектов конфигурации. Для этого является обычной практикой использование классов внутренней конфигурации, которые также могут совместно использовать некоторые части вмещающего приложения. Следующий класс добавляет две разные цепочки фильтров Spring Security.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
|
public class SecurityConfig { @Configuration public static class ApiConfiguration extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { // doesn't really make sense to protect a REST API using form login but it is just for illustration http .formLogin() .and() .authorizeRequests().antMatchers( "/secret/**" ).authenticated() .and() .authorizeRequests().antMatchers( "/**" ).permitAll(); } @Override public void configure(WebSecurity web) throws Exception { web.ignoring().antMatchers( "/resources/**" ); } } @Order ( 1 ) @Configuration public static class ActuatorConfiguration extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http .antMatcher( "/management/**" ) .httpBasic() .and() .authorizeRequests().antMatchers( "/management/**" ).authenticated(); } @Override public void configure(WebSecurity web) throws Exception { super .configure(web); } } } |
Оба класса наследуются от класса конфигурации адаптера и настраивают их HttpSecurity
. Каждый из этих классов добавляет цепочку фильтров, и выполняется первый соответствующий ему класс. Аннотация @Order
может использоваться, чтобы влиять на порядок цепочек фильтров, чтобы убедиться, что сначала выполняется правильная @Order
.
Также может быть необходимо ограничить цепочку фильтров только определенной частью приложения, чтобы она не запускалась для других частей. ActuatorConfiguration
ограничивается только сопоставлением запросов к /management/
. Помните, что в конфигурации есть два разных места, которые принимают RequestMatcher
. Один в начале ограничивает URL, для которого запускается цепочка фильтров. Те, что после authorizeRequests()
используются для определения того, какие запросы требуют какой тип аутентификации.
Обратите внимание, что настройка WebSecurity
не связана с одной из конфигураций HttpSecurity
поскольку они добавляют свою собственную цепочку фильтров, только порядок может отличаться. Если вы добавите шаблон в обе конфигурации, он будет работать даже на одном и том же экземпляре WebSecurity
.
И последнее: если вы используете пользовательский фильтр аутентификации (например, для аутентификации на основе токенов), вам, возможно, придется позаботиться о том, чтобы вы также не регистрировали свой фильтр как фильтр сервлетов. Вы можете повлиять на это, настроив метод, возвращающий FilterRegistrationBean
и приняв экземпляр вашего Filter
. просто создайте новый FilterRegistrationBean
для вашего фильтра и установите значение false
.
Ссылка: | Spring Security и несколько цепочек фильтров от нашего партнера JCG Флориана Хопфа в блоге Dev Time . |