Рубрики
Без рубрики

Введение в выражения безопасности Spring

Простое и практичное руководство по выражениям безопасности Spring.

Автор оригинала: baeldung.

1. введение

В этом уроке мы сосредоточимся на выражениях безопасности Spring и, конечно же, на практических примерах с этими выражениями.

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

Эта статья является расширением выражений безопасности Spring – Пример hasRole .

2. Зависимости Maven

Чтобы использовать Spring Security, вам необходимо включить следующий раздел в свой pom.xml файл:


    
        org.springframework.security
        spring-security-web
        5.2.3.RELEASE
    

Последнюю версию можно найти здесь .

И краткое примечание – эта зависимость распространяется только на безопасность Spring; не забудьте добавить s pring-core и spring-context для полного веб-приложения.

3. Конфигурация

Во-первых, давайте взглянем на конфигурацию Java.

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

@Configuration
@EnableAutoConfiguration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityJavaConfig extends WebSecurityConfigurerAdapter {
    ...
}

Конечно, мы можем также выполнить конфигурацию XML:



    

4. Выражения веб-безопасности

Теперь давайте начнем рассматривать выражения безопасности:

  • hasRole , hasAnyRole
  • имеет Полномочия , имеет Какие-Либо Полномочия
  • PermitAll , denyAll
  • isAnonymous , isRememberMe , IsAuthenticated , isFullyAuthenticated
  • принципал , аутентификация
  • hasPermission

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

4.1. hasRole, hasAnyRole

Эти выражения отвечают за определение контроля доступа или авторизации к определенным URL-адресам или методам в вашем приложении.

Давайте рассмотрим пример:

@Override
protected void configure(final HttpSecurity http) throws Exception {
    ...
    .antMatchers("/auth/admin/*").hasRole("ADMIN")
    .antMatchers("/auth/*").hasAnyRole("ADMIN","USER")
    ...
}

В этом примере мы указываем доступ ко всем ссылкам, начинающимся с /auth/ , ограниченный пользователями, которые вошли в систему с ролью USER или ролью ADMIN. Кроме того, для доступа к ссылкам, начинающимся с /auth/admin/ , нам необходимо иметь ADMIN роль в системе.

Та же конфигурация может быть достигнута в XML-файле путем записи:


    
    

4.2. имеет Полномочия, имеет Какие-Либо Полномочия

Роли и полномочия весной схожи.

Основное отличие заключается в том, что роли имеют специальную семантику – начиная с Spring Security 4, префикс ‘ ROLE_ ‘ автоматически добавляется (если его еще нет) любым методом, связанным с ролью.

Таким образом, имеет полномочия(‘ROLE_ADMIN’) аналогичен hasRole(‘ADMIN’) , потому что префикс ‘ ROLE_ ‘ добавляется автоматически.

Но хорошая вещь в использовании властей заключается в том, что нам не нужно использовать РОЛЬ_ префикс вообще.

Вот краткий пример, в котором мы определяем пользователей с определенными полномочиями:

@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
    auth.inMemoryAuthentication()
      .withUser("user1").password(encoder().encode("user1Pass"))
      .authorities("USER")
      .and().withUser("admin").password(encoder().encode("adminPass"))
      .authorities("ADMIN");
}

Тогда мы, конечно, можем использовать эти авторитетные выражения:

@Override
protected void configure(final HttpSecurity http) throws Exception {
    ...
    .antMatchers("/auth/admin/*").hasAuthority("ADMIN")
    .antMatchers("/auth/*").hasAnyAuthority("ADMIN", "USER")
    ...
}

Как мы видим, здесь мы вообще не упоминаем роли. Кроме того, начиная с весны 5, нам нужен компонент PasswordEncoder:

@Bean
public PasswordEncoder passwordEncoder() {
    return new BCryptPasswordEncoder();
}

Наконец, мы, конечно, можем достичь той же функциональности, используя конфигурацию XML:


    
        
            
            
        
    

И:


    
    

4.3. Разрешение, отказ

Эти две аннотации также довольно просты. Мы можем либо разрешить доступ к какому-либо URL-адресу в нашем сервисе, либо отказать в доступе.

Давайте посмотрим на пример:

...
.antMatchers("/*").permitAll()
...

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

Мы также можем запретить доступ ко всему нашему пространству URL-адресов:

...
.antMatchers("/*").denyAll()
...

И опять же, та же конфигурация может быть выполнена и с конфигурацией XML:


     
     

4.4. isAnonymous, isRememberMe, IsAuthenticated, isFullyAuthenticated

В этом подразделе мы сосредоточимся на выражениях, связанных со статусом входа пользователя. Давайте начнем с пользователя, который не вошел на нашу страницу. Указав следующее в конфигурации Java, мы разрешаем всем неавторизованным пользователям доступ к нашей главной странице:

...
.antMatchers("/*").anonymous()
...

То же самое в конфигурации XML:


    

Если мы хотим обезопасить веб-сайт, чтобы все, кто его использует, должны были войти в систему, нам нужно использовать метод IsAuthenticated() :

...
.antMatchers("/*").authenticated()
...

или версия XML:


    

Кроме того, у нас есть два дополнительных выражения: is Remember Me() и is Fully Authenticated() . Благодаря использованию файлов cookie Spring обеспечивает возможность запоминания, поэтому нет необходимости каждый раз входить в систему. Вы можете прочитать больше о Remember Me здесь .

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

...
.antMatchers("/*").rememberMe()
...

или версия XML:


    

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

Для этого мы можем указать isFullyAuthenticated () , который возвращает true , если пользователь не является анонимным или пользователем remember-me:

...
.antMatchers("/*").fullyAuthenticated()
...

или версия XML:


    

4.5. принципал, аутентификация

Эти выражения позволяют получить доступ к объекту principal , представляющему текущего авторизованного (или анонимного) пользователя, и текущему объекту Authentication из SecurityContext соответственно.

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

И аутентификация предоставляет информацию о полном Аутентификации объекте, а также о предоставленных ему полномочиях.

Оба они более подробно описаны в следующей статье: Получение информации о пользователе в Spring Security .

4.6. API-интерфейсы hasPermission

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

Давайте рассмотрим пример. У нас есть сервис, который позволяет совместно писать статьи с главным редактором, решающим, какая статья, предложенная другими авторами, должна быть опубликована.

Чтобы разрешить использование такой услуги, мы можем создать следующие методы с методами контроля доступа:

@PreAuthorize("hasPermission(#articleId, 'isEditor')")
public void acceptArticle(Article article) {
   …
}

Только авторизованный пользователь может вызвать этот метод, а также пользователь должен иметь разрешение является редактором в сервисе.

Нам также необходимо не забыть явно настроить PermissionEvaluator в контексте нашего приложения:


    



    

где реализация пользовательского интерфейса будет классом, реализующим PermissionEvaluator.

Конечно, мы также можем сделать это с конфигурацией Java:

@Override
protected MethodSecurityExpressionHandler expressionHandler() {
    DefaultMethodSecurityExpressionHandler expressionHandler = 
      new DefaultMethodSecurityExpressionHandler();
    expressionHandler.setPermissionEvaluator(new CustomInterfaceImplementation());
    return expressionHandler;
}

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

Этот учебник представляет собой всеобъемлющее введение и руководство по выражениям безопасности Spring.

Все примеры, обсуждаемые здесь, доступны в проекте GitHub .