«1. Введение

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

В этом руководстве мы рассмотрим различные способы проверки ролей пользователей в Java для Spring Security.

2. Проверка роли пользователя в Java

Spring Security предоставляет несколько способов проверки ролей пользователя в коде Java. Мы рассмотрим каждый из них ниже.

2.1. @PreAuthorize

Первый способ проверить роли пользователей в Java — использовать аннотацию @PreAuthorize, предоставленную Spring Security. Эту аннотацию можно применить к классу или методу, и она принимает одно строковое значение, представляющее выражение SpEL.

Прежде чем мы сможем использовать эту аннотацию, мы должны сначала включить глобальную безопасность методов. Это можно сделать в коде Java, добавив аннотацию @EnableGlobalMethodSecurity к любому классу конфигурации.

Затем Spring Security предоставляет два выражения, которые мы можем использовать с аннотацией @PreAuthorize для проверки ролей пользователей:

@PreAuthorize("hasRole('ROLE_ADMIN')")
@GetMapping("/user/{id}")
public String getUser(@PathVariable("id") String id) {
    ...
}

Мы также можем проверить несколько ролей в одном выражении:

@PreAuthorize("hasAnyRole('ROLE_ADMIN','ROLE_MANAGER')")
@GetMapping("/users")
public String getUsers() {
    ...
}

В этом случае, запрос будет разрешен, если у пользователя есть какая-либо из указанных ролей.

Если метод вызывается без соответствующей роли, Spring Security выдает исключение и перенаправляет на страницу с ошибкой.

2.2. SecurityContext

Следующий способ проверки ролей пользователей в коде Java — это класс SecurityContext.

По умолчанию Spring Security использует локальную копию этого класса. Это означает, что каждый запрос в нашем приложении имеет свой контекст безопасности, который содержит сведения о пользователе, делающем запрос.

Чтобы использовать его, мы просто вызываем статические методы в SecurityContextHolder:

Authentication auth = SecurityContextHolder.getContext().getAuthentication();
if (auth != null && auth.getAuthorities().stream().anyMatch(a -> a.getAuthority().equals("ADMIN"))) {
    ...
}

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

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

2.3. UserDetailsService

Третий способ поиска ролей пользователей в коде Java — использование UserDetailsService. Этот bean-компонент мы можем внедрить в любое место нашего приложения и вызывать его по мере необходимости:

@GetMapping("/users")
public String getUsers() {
    UserDetails details = userDetailsService.loadUserByUsername("mike");
    if (details != null && details.getAuthorities().stream()
      .anyMatch(a -> a.getAuthority().equals("ADMIN"))) {
        // ...
    }
}

Опять же, мы должны использовать здесь имя авторитета, а не полное имя роли с префиксом.

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

2.4. Запрос сервлета

Если мы используем Spring MVC, мы также можем проверить роли пользователей в Java с помощью класса HttpServletRequest:

@GetMapping("/users")
public String getUsers(HttpServletRequest request) {
    if (request.isUserInRole("ROLE_ADMIN")) {
        ...
    }
}

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

В этой статье мы рассмотрели несколько различных способов проверки. для ролей, использующих код Java с Spring Security.

Как всегда, примеры кода из этой статьи можно найти на GitHub.