1. Обзор
В этом руководстве показано, как получить данные пользователя в Spring Security.
Текущий аутентифицированный пользователь доступен в Spring через ряд различных механизмов. Давайте сначала рассмотрим наиболее распространенное решение — программный доступ.
2. Получите пользователя в компоненте
Самый простой способ получить текущего аутентифицированного принципала — это статический вызов SecurityContextHolder
:
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
String currentPrincipalName = authentication.getName();
Улучшение этого фрагмента заключается в том, что перед попыткой доступа к нему сначала проверяется наличие аутентифицированного пользователя:
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if (!(authentication instanceof AnonymousAuthenticationToken)) {
String currentUserName = authentication.getName();
return currentUserName;
}
Конечно, у такого статического вызова есть недостатки, и снижение тестируемости кода является одним из наиболее очевидных. Вместо этого мы рассмотрим альтернативные решения для этого очень распространенного требования.
3. Получите пользователя в контроллере
У нас есть дополнительные параметры в аннотированном bean -компоненте @Controller .
Мы можем определить принципала напрямую как аргумент метода , и он будет корректно разрешен фреймворком:
@Controller
public class SecurityController {
@RequestMapping(value = "/username", method = RequestMethod.GET)
@ResponseBody
public String currentUserName(Principal principal) {
return principal.getName();
}
}
В качестве альтернативы мы также можем использовать токен аутентификации :
@Controller
public class SecurityController {
@RequestMapping(value = "/username", method = RequestMethod.GET)
@ResponseBody
public String currentUserName(Authentication authentication) {
return authentication.getName();
}
}
API класса Authentication
очень открытый, поэтому фреймворк остается максимально гибким. Из-за этого субъект Spring Security может быть получен только как объект
и должен быть приведен к правильному экземпляру UserDetails
:
UserDetails userDetails = (UserDetails) authentication.getPrincipal();
System.out.println("User has authorities: " + userDetails.getAuthorities());
И, наконец, вот прямо из HTTP-запроса :
@Controller
public class GetUserWithHTTPServletRequestController {
@RequestMapping(value = "/username", method = RequestMethod.GET)
@ResponseBody
public String currentUserNameSimple(HttpServletRequest request) {
Principal principal = request.getUserPrincipal();
return principal.getName();
}
}
4. Получить пользователя через пользовательский интерфейс
Чтобы полностью использовать внедрение зависимостей Spring и иметь возможность получать аутентификацию везде, а не только в компонентах @Controller
, нам нужно скрыть статический доступ за простым фасадом:
public interface IAuthenticationFacade {
Authentication getAuthentication();
}
@Component
public class AuthenticationFacade implements IAuthenticationFacade {
@Override
public Authentication getAuthentication() {
return SecurityContextHolder.getContext().getAuthentication();
}
}
Фасад предоставляет объект Authentication
, скрывая статическое состояние и сохраняя код несвязанным и полностью тестируемым:
@Controller
public class GetUserWithCustomInterfaceController {
@Autowired
private IAuthenticationFacade authenticationFacade;
@RequestMapping(value = "/username", method = RequestMethod.GET)
@ResponseBody
public String currentUserNameSimple() {
Authentication authentication = authenticationFacade.getAuthentication();
return authentication.getName();
}
}
5. Получить пользователя в JSP
Доступ к текущему аутентифицированному принципалу также можно получить на страницах JSP , используя поддержку Spring Security Taglib.
Во-первых, нам нужно определить тег на странице:
<%@ taglib prefix="security" uri="http://www.springframework.org/security/tags" %>
Далее мы можем обратиться к принципалу :
<security:authorize access="isAuthenticated()">
authenticated as <security:authentication property="principal.username" />
</security:authorize>
6. Получите пользователя в Thymeleaf
Thymeleaf — это современный механизм веб-шаблонов на стороне сервера с хорошей интеграцией с инфраструктурой Spring MVC .
Давайте посмотрим, как получить доступ к текущему аутентифицированному принципалу на странице с движком Thymeleaf.
Во- первых, нам нужно добавить зависимости thymeleaf-spring5
и thymeleaf-extras-springsecurity5
для интеграции Thymeleaf со Spring Security:
<dependency>
<groupId>org.thymeleaf.extras</groupId>
<artifactId>thymeleaf-extras-springsecurity5</artifactId>
</dependency>
<dependency>
<groupId>org.thymeleaf</groupId>
<artifactId>thymeleaf-spring5</artifactId>
</dependency>
Теперь мы можем ссылаться на принципала на HTML-странице с помощью атрибута sec:authorize
:
<html xmlns:th="https://www.thymeleaf.org"
xmlns:sec="https://www.thymeleaf.org/thymeleaf-extras-springsecurity5">
<body>
<div sec:authorize="isAuthenticated()">
Authenticated as <span sec:authentication="name"></span></div>
</body>
</html>
7. Заключение
В этой статье показано, как получить информацию о пользователе в приложении Spring, начиная с общего статического механизма доступа, за которым следует несколько более эффективных способов внедрения принципала.
Реализацию этих примеров можно найти в проекте GitHub . Это проект на основе Eclipse, поэтому его легко импортировать и запускать как есть. При локальном запуске проекта мы можем получить доступ к HTML-коду домашней страницы здесь:
http://localhost:8080/spring-security-rest-custom/foos/1