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

Руководство по @CurrentSecurityContext в Spring Security

Чтение из контекста безопасности Spring может потребовать немного шаблонного кода. С помощью аннотации @CurrentSecurityContext мы можем ввести нужные нам значения.

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

1. Обзор

Spring Security обрабатывает получение и анализ учетных данных для проверки подлинности для нас.

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

2. Аннотация @CurrentSecurityContext

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

SecurityContext context = SecurityContextHolder.getContext();
Authentication authentication = context.getAuthentication();

Однако теперь есть @CurrentSecurityContext аннотация, которая поможет нам .

Кроме того, использование аннотаций делает код более декларативным и делает объект authentication инъекционным. С помощью @CurrentSecurityContext мы также можем получить доступ к реализации Principal текущего пользователя.

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

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

Если у нас есть последняя версия Spring Boot, то нам нужно только включить зависимость для spring-boot-starter-security :


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

В противном случае мы можем обновить spring-security-core до минимальной версии 5.2.1.RELEASE:


    org.springframework.security
    spring-security-core
    5.2.1.RELEASE

4. Реализация с помощью @CurrentSecurityContext

Мы можем использовать SpEL (язык выражений Spring) с @CurrentSecurityContext для введения объекта Authentication или Principal . Заклинание работает вместе с поиском типов. Проверка типа по умолчанию не выполняется, но мы можем включить ее с помощью параметра error On Invalid Type аннотации @CurrentSecurityContext|/.

4.1. Получение Объекта аутентификации

Давайте прочитаем объект Authentication , чтобы мы могли вернуть его данные:

@GetMapping("/authentication")
public Object getAuthentication(@CurrentSecurityContext(expression = "authentication") 
  Authentication authentication) {
    return authentication.getDetails();
}

Обратите внимание, что выражение SpEL ссылается на сам объект authentication .

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

@Test
public void givenOAuth2Context_whenAccessingAuthentication_ThenRespondTokenDetails() {
    ClientCredentialsResourceDetails resourceDetails = 
      getClientCredentialsResourceDetails("baeldung", singletonList("read"));
    OAuth2RestTemplate restTemplate = getOAuth2RestTemplate(resourceDetails);

    String authentication = executeGetRequest(restTemplate, "/authentication");

    Pattern pattern = Pattern.compile("\\{\"remoteAddress\":\".*"
      + "\",\"sessionId\":null,\"tokenValue\":\".*"
      + "\",\"tokenType\":\"Bearer\",\"decodedDetails\":null}");
    assertTrue("authentication", pattern.matcher(authentication).matches());
}

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

4.2. Получение Доверителя

Если нам нужен только Принципал из наших аутентификационных данных, мы можем изменить выражение SpEL и введенный объект:

@GetMapping("/principal")
public String getPrincipal(@CurrentSecurityContext(expression = "authentication.principal") 
  Principal principal) { 
    return principal.getName(); 
}

В этом случае мы возвращаем только имя Principal , используя метод getName .

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

@Test
public void givenOAuth2Context_whenAccessingPrincipal_ThenRespondBaeldung() {
    ClientCredentialsResourceDetails resourceDetails = 
       getClientCredentialsResourceDetails("baeldung", singletonList("read"));
    OAuth2RestTemplate restTemplate = getOAuth2RestTemplate(resourceDetails);

    String principal = executeGetRequest(restTemplate, "/principal");

    assertEquals("baeldung", principal);
}

Здесь мы видим имя baeldung , которое было добавлено к учетным данным клиента, которое было найдено и возвращено из объекта Principal , введенного в обработчик.

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

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

Мы сделали это, воспользовавшись преимуществами SpEL и аннотацией @CurrentSecurityContext .

Как всегда, полный исходный код примеров доступен на GitHub .