principal spring что это
What’s the «principal» in Spring Security?
I’m really new to Spring and Spring Security. I was reading about Spring Security and it came out the concept of principal, which should be the current logged user. But what if we have more than one current logged user? So, my question is, what exactly is then the principal in spring security?
I’ve read for example this tutorial:
and they seem to take into account that there’s just one current logged user, which isn’t often the case.
How do I retrieve a specific user? And how do I differentiate between users that are doing requests?
3 Answers 3
The principal is the currently logged in user. However, you retrieve it through the security context which is bound to the current thread and as such it’s also bound to the current request and its session.
SecurityContextHolder.getContext() internally obtains the current SecurityContext implementation through a ThreadLocal variable. Because a request is bound to a single thread this will get you the context of the current request.
To simplify you could say that the security context is in the session and contains user/principal and roles/authorities.
How do I retrieve a specific user?
You don’t. All APIs are designed to allow access to the user & session of the current request. Let user A be one of 100 currently authenticated users. If A issues a request against your server it will allocate one thread to process that request. If you then do SecurityContextHolder.getContext().getAuthentication() you do so in the context of this thread. By default from within that thread you don’t have access to the context of user B which is processed by a different thread.
And how do I differentiate between users that are doing requests?
You don’t have to, that’s what the Servlet container does for you.
Brief definition of Principal:
A Principal represents a user’s identity.
It can be a String object having username on a simple level or a complex UserDetails object.
Principal is just an old interface from Java SE 6.
As all interfaces without default implementation it simple defines some methods which are required to be implemented by the class which will implement that interface.
This interface represents the abstract notion of a principal, which can be used to represent any entity, such as an individual, a corporation, and a login id.
If we see the implementation that Spring uses for AbstractAuthenticationToken.class :
Also is important to mention:
abstract class AbstractAuthenticationToken implements Authentication and
interface Authentication extends Principal
Principal Interface also ensures that the implementer will implement equals() and hashCode() which makes much sense because the entity of Principal that represents an Organization or a Company or a Person must have some way of being compared with other entities.
Краткий обзор Spring Security
Итак, дорогой хабраюзер, предлагаю тебе рассмотреть такие аспекты Spring Security как:
Ключевые объекты контекста Spring Security:
Позволяет получить из источника данных объект пользователя и сформировать из него объект UserDetails который будет использоваться контекстом Spring Security.
Аутентификация
(1) Пользователю будет предложено войти в систему предоставив имя (логин или email) и пароль. Имя пользователя и пароль объединяются в экземпляр класса UsernamePasswordAuthenticationToken(экземпляр интерфейса Authentication) после чего он передается экземпляру AuthenticationManager для проверки.
(2) В случае если пароль не соответствует имени пользователя будет выброшено исключение BadCredentialsException с сообщением “Bad Credentials”.
(3) Если аутентификация прошла успешно возвращает полностью заполненный экземпляр Authentication.
(4) Для пользователя устанавливается контекст безопасности путем вызова метода SecurityContextHolder.getContext().setAuthentication(…), куда передается объект который вернул AuthenticationManager.
Подключение поддержки Security для SpringFramework приложения:
Ну и конечно же сам файл с настройкой security.xml
Пояснение к коду security.xml:
Подразумевается что на странице login.jsp есть форма с action=»/j_spring_security_check» в которой содержаться input’ы для имени и пароля с name=«j_username» и name=«j_password», а также checkbox c name=»_spring_security_remember_me». Это всё специальные значения которые требует Spring Security иначе параметры просто не будут передаваться в контекст безопасности. После успешного прохождения аутентификации пользователь будет перенаправлен на страницу /index где уже применяются правила авторизации. Если не указывать форму и url в http spring-security тогда по умолчанию будет работать basic authentication или можно подключить basic authentication насильно указав в http spring-security
На url /index* доступ могут иметь пользователи с правами ROLE_USER, а также гости (все подключения которые не прошли аутентификацию получают имя guest и права ROLE_ANONYMOUS).
Доступ к url /add* имеют только пользователи с правами ROLE_USER Доступ к url /delete* только пользователи с правами ROLE_ADMIN
Также, авторизованный доступ можно прикручивать на методы, для этого в security.xml нужно добавить, следующий элемент:
Также может осуществляться проверка хешированных паролей:
Извлечение принципала и полномочий с помощью Spring Security OAuth
Узнайте, как извлечь информацию о пользователе в настройке OAuth.
1. Обзор
В этом руководстве мы проиллюстрируем, как создать приложение, которое делегирует проверку подлинности пользователя третьей стороне, а также настраиваемому серверу авторизации с помощью Spring Boot и Spring Security OAuth.
Кроме того, мы продемонстрируем, как извлечь оба Principal и Authorities , используя интерфейсы Spring PrincipalExtractor и AuthoritiesExtractor .
Для ознакомления с Spring Security OAuth2, пожалуйста, обратитесь к этим статьям.
2. Зависимости Maven
Чтобы начать работу, нам нужно добавить зависимость spring-security-oauth2-auto configure в ваш pom.xml :
3. Аутентификация OAuth С Помощью Github
Далее, давайте создадим конфигурацию безопасности нашего приложения:
Короче говоря, мы говорим, что любой может получить доступ к конечной точке /login и что все остальные конечные точки потребуют аутентификации пользователя.
Хотя Spring создает большинство компонентов для нас по умолчанию, нам все равно нужно настроить некоторые свойства:
Вместо того, чтобы заниматься управлением учетными записями пользователей, мы делегируем его третьей стороне – в данном случае Github – что позволяет нам сосредоточиться на логике нашего приложения.
4. Извлечение Принципала и полномочий
При работе в качестве клиента OAuth и аутентификации пользователей через третью сторону мы должны рассмотреть три шага:
Хотя это может быть приемлемо, чаще всего мы оказываемся в ситуации, когда хотим иметь полный контроль над ними.
Для этого Spring предоставляет нам два интерфейса, которые мы можем использовать для переопределения его поведения по умолчанию :
По умолчанию Spring предоставляет два компонента – FixedPrincipalExtractor и FixedAuthoritiesExtractor |– , которые реализуют эти интерфейсы и имеют заранее определенную стратегию их создания для нас.
4.1. Настройка аутентификации Github
В нашем случае мы знаем, как выглядят пользовательские данные Github как и что мы можем использовать, чтобы адаптировать их в соответствии с нашими потребностями.
Для нашего приложения Principal мы просто будем использовать имя пользователя Github:
В зависимости от подписки нашего пользователя на Github – бесплатно или иным образом – мы дадим им GITHUB_USER_SUBSCRIBED или GITHUB_USER_FREE полномочия:
Затем нам также нужно создать бобы, используя эти классы:
4.2. Использование Пользовательского сервера авторизации
Мы также можем использовать наш собственный сервер авторизации для наших пользователей – вместо того, чтобы полагаться на третью сторону.
Давайте изменим наше приложение, чтобы аутентифицировать наших пользователей с помощью сервера авторизации, описанного в этой статье:
Таким образом, мы собираемся извлекать и обогащать их:
Затем мы добавим бобы в наш класс Security Config :
5. Заключение
При локальном запуске вы можете запустить и протестировать приложение по адресу localhost:8082
Аутентификация с использованием Spring Security и JWT-токенов
Всем привет! Хабр жив! Данный пост вряд ли соберёт кучу просмотров и комментов, но, надеюсь, немного поможет здоровью хабра.
В данной статье рассмотрим принцип аутентификации в веб-приложениях на платформе Spring с использованием относительно нового механизма аутентификации — JSON Web Token (JWT). Этот механизм уже обкатан и реализован для многих языков программирования.
Использование токена позволяет серверу не заботиться о сохранении состояния между запросами (HTTP-сессии), уменьшить количество запросов к БД — необходимые для восстановления данные могут сохраняться в токене. Непосредственно о токене JWT: сервер смешивает полезную нагрузку в формате JSON (заголовок и тело) с секретным ключом и генерирует хэш, прикрепляя его в качестве сигнатуры к полезной нагрузке. Полезная нагрузка кодируется алгоритмом base64Url, поэтому, естественно, не следует передавать в токене секретные данные. Стандартом JWT шифрование полезной нагрузки не предусмотрено. Шифруйте отдельно сами, если хотите, а задача токена — только обеспечить аутентификацию.
Предполагается, что читатель знаком с основами Spring Secutity. Про него можно прочитать здесь
1). Генерация токена
Для своего примера я взял одну из реализаций спецификации JWT. Токен генерируется следующим образом:
Теперь к Spring Security. Для реализации собственного механизма аутентификации нам необходимо реализовать свой фильтр и менеджер аутентификации.
2). Реализация фильтра
Фильтр — это объект класса, реализующего интерфейс javax.servlet.Filter, который перехватывает запросы на определённые URL и выполняет некоторые действия. Если имеется несколько фильтров, то они образуют цепочку фильтров — HTTP-запрос после приёма приложением проходит через эту цепочку. Каждый фильтр в цепочке может обработать запрос, пропустить его к следующим фильтрам в цепочке или не пропустить, сразу отправив ответ клиенту.
Задача нашего фильтра — передать токен из запроса менеджеру аутентификации и, в случае успешной аутентификации, установить контекст безопасности приложения.
Мы унаследовались от абстрактного класса org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter, который специально предназначен для аутентификации. При совпадении URL запроса с паттерном «/rest/**» автоматом произойдёт вызов функции attemptAuthentication().
Также в конструкторе мы установили два хэндлэра — AuthenticationSuccessHandler и AuthenticationFailureHandler. Если attemptAuthentication вернет объект Authentication, то сработает первый хэндлер, второй хэндлэр сработает при выбросе методом attemptAuthentication исключения AuthenticationException.
Как мы видим, при успешной аутентификации мы устанавливаем контекст безопасности приложения посредством SecurityContextHolder.getContext().setAuthentication(authentication). Установленный таким образом контекст является переменной ThreadLocal, т.е. доступен, пока жив поток работы с клиентом. После установки контекста мы направляем запрос пользователя к сервлету с первоначально запрашиваемым URL.
3). Менеджер аутентификации.
Менеджер аутентификации — это объект класса, реализующего интерфейс org.springframework.security.authentication.AuthenticationManager с единственным методом authenticate(). Данному методу нужно передать частично заполненный объект, реализующий интерфейс org.springframework.security.core.Authentication (контекстом безопасности приложения).
Задача менеджера аутентификации — в случае успешной аутентификации заполнить полностью объект Authentication и вернуть его. При заполнении нужно установить пользователя (principal), его права (authorities), выполнить setAuthenticated(true). В случае неудачи менеджер аутентификации должен выбросить исключение AuthenticationException.
Приведём пример реализации интерфейса org.springframework.security.core.Authentication:
Приведём реализацию менеджера аутентификации:
4). Как всё это собрать вместе
Во-первых, нужно установить фильтр. Сделать это можно 2-мя способами
Первый способ — определить фильтр в файле web.xml нашего приложения
При таком способе в конструкторе фильтра нужно сразу задать менеджер аутентификации, так как экземпляр фильтра не будет доступен в контексте приложения Spring. Если необходимо иметь фильтр или менеджер аутентификации в качестве бинов Spring, нужно воспользоваться вторым способом.
Второй способ — установка фильтра в конфигурации Spring Security.
Для примера покажем конфигурацию с использованием Java Config
В строке
.addFilterAfter(restTokenAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class)
мы добавили наш фильтр в цепочку фильтров после стандартного фильтра UsernamePasswordAuthenticationFilter.
На этом основная настройка механизма аутентификации в Spring Security с использованием JSON Web Token завершена.
Русские Блоги
Введение в архитектуру Spring Security
1. Технический обзор
1.1 Spring vs Spring Boot vs Spring Security
1.1.1 Spring Framework
Spring FrameworkОбеспечивает всестороннюю поддержку инфраструктуры для разработки приложений Java. Он содержит несколько полезных функций, таких как «внедрение зависимостей», и несколько готовых модулей:
Эти модули могут значительно сократить время разработки приложений. Например, в первые дни разработки Java Web нам нужно было написать много стандартного кода для вставки записей в источник данных. Однако с помощью модуля Spring JDBCJDBCTemplate, Мы можем упростить его до нескольких строк кода с небольшим объемом конфигурации.
Spring BootОн основан на Spring Framework, который предоставляет функции автоматической сборки для ваших приложений Spring, и его цель состоит в том, чтобы вы как можно быстрее приступили к разработке приложений. Ниже приведены некоторые функции Spring Boot:
1.1.3 Spring Security
Spring SecurityЭто инфраструктура безопасности, которая может предоставить декларативные решения для контроля доступа к безопасности для корпоративных приложений на базе Spring. Он предоставляет набор Bean-компонентов, которые можно настроить в контексте приложений Spring, полностью используя функции Spring IoC (Inversion of Control Inversion of Control), DI (Dependency Injection Dependency Injection) и AOP (Aspect-ориентированное программирование) для предоставления объявлений для прикладных систем. Функция безопасного контроля доступа сокращает объем написания большого количества повторяющегося кода для контроля безопасности системы предприятия.
Spring Security имеет следующие особенности:
Связь между Spring, Spring Boot и Spring Security показана ниже:
1.2 Интеграция Spring Security
Spring Security 5 в настоящее время поддерживает интеграцию со следующими технологиями:
Прежде чем войти в тему Spring Security, давайте сначала разберемся с его общей архитектурой:
Во-вторых, основные компоненты
2.1 SecurityContextHolder, SecurityContext и аутентификация
Самый основной объект SecurityContextHolder Это детали текущего контекста безопасности приложения, которые мы храним, в том числе сведения об основной части приложения, которое используется в настоящее время. Например, кто является действующим в настоящее время пользователем, прошел ли он проверку подлинности, и какие разрешения он имеет?
по умолчанию, SecurityContextHolder использование ThreadLocal Для сохранения этих подробностей это означает, что контекст безопасности всегда можно использовать для методов в одном и том же потоке выполнения, даже если контекст безопасности явно не передается в качестве параметра этих методов.
Получить информацию о текущем пользователе
Поскольку информация об идентичности привязана к текущему потоку выполнения, вы можете использовать следующий блок кода для получения имени пользователя в настоящий момент прошедшего проверку подлинности пользователя в приложении:
перевод getContext() Возвращенный объект SecurityContext Экземпляр интерфейса, соответствующий SecurityContext Интерфейс определяется следующим образом:
В интерфейсе SecurityContext определены два абстрактных метода, getAuthentication и setAuthentication. Когда вызывается метод getAuthentication, возвращается объект типа Authentication. Здесь Authentication также является интерфейсом, который определяется следующим образом:
Давайте кратко суммируем отношения между тремя объектами SecurityContextHolder, SecurityContext и Authentication. SecurityContextHolder используется для сохранения SecurityContext (объекта контекста безопасности). Вызывая методы в объекте SecurityContext, такие как метод getAuthentication, мы можем легко получить объект Authentication Используя этот объект, мы можем получить подробную информацию о проверенных пользователях.
Подробные определения SecurityContextHolder, SecurityContext и Authentication:
Три, проверка личности
3.1 Что такое аутентификация в Spring Security?
Давайте рассмотрим стандартную схему аутентификации, с которой все знакомы:
Первые три элемента составляют процесс аутентификации, поэтому мы рассмотрим их в Spring Security.
3.2 Пример процесса аутентификации Spring Security
После понимания процесса аутентификации, приведенного выше, давайте рассмотрим простой пример:
Интерфейс AuthenticationManager:
Класс SampleAuthenticationManager:
Класс AuthenticationExample:
В приведенном выше коде мы реализовали AuthenticationManager Любой пользователь с таким же именем пользователя и паролем будет проверен. Он назначает роль каждому пользователю. Процесс проверки приведенного выше кода заключается в следующем:
4. Основные услуги
4.1 AuthenticationManager, ProviderManager и AuthenticationProvider
Реализация интерфейса AuthenticationManager в Spring Security по умолчанию:ProviderManager, Но он непосредственно не обрабатывает сам запрос аутентификации, он делегирует настроенномуAuthenticationProviderСписки, каждый список запрашивается по очереди, чтобы увидеть, может ли он выполнить аутентификацию. Каждый провайдер провайдера сгенерирует исключение или вернет полностью заполненныйAuthenticationОбъекты.
Другими словами, в Spring Security всегда есть только одна основная запись аутентификации: AuthenticationManager, разные методы аутентификации: имя пользователя + пароль (UsernamePasswordAuthenticationToken), почтовый ящик + пароль, номер мобильного телефона и пароль для входа соответствуют трем AuthenticationProvider.
Давайте взглянемProviderManagerОсновной исходный код:
В процессе аутентификации ProviderManager он просматривает список провайдеров, чтобы определить, поддерживается ли текущий метод аутентификации объекта аутентификации. Если метод аутентификации поддерживается, для операции аутентификации будет вызван метод аутентификации объекта соответствующего провайдера (AuthenticationProvider). Если аутентификация не удалась, он возвращает ноль, следующий AuthenticationProvider продолжит попытки аутентификации, если все аутентификаторы не могут пройти аутентификацию успешно, ProviderManager сгенерирует ProviderNotFoundException Исключение.
В реальных проектах наиболее распространенным методом аутентификации является использование имени пользователя и пароля. Пользователь отправил имя пользователя и пароль в форме входа, а для зарегистрированных пользователей правильное имя пользователя и пароль были сохранены в базе данных, аутентификация отвечает за сравнение того же имени пользователя, предоставленного пароля и сохраненной базы данных. Являются ли пароли одинаковыми, достаточно.
В методе retrieveUser класса DaoAuthenticationProvider он вызовет метод loadUserByUsername объекта UserDetailsService, чтобы загрузить пользователя с переданным именем пользователя в качестве параметра.
4.3 UserDetails и UserDetailsService
4.3.1 Интерфейс UserDetails
Подпись метода retrieveUser в классе DaoAuthenticationProvider такова:
Этот метод возвращает объект UserDetails, где UserDetails также является интерфейсом, который определяется следующим образом:
Как следует из названия, UserDetails представляет подробную информацию о пользователе, этот интерфейс охватывает некоторые необходимые поля информации о пользователе, и конкретный класс реализации расширяет его. Ранее мы также представили интерфейс аутентификации, который определяется следующим образом для интерфейса UserDetails:
Кроме того, getAuthorities () в Authentication фактически передается getAuthorities () из UserDetails. Помните метод getUserDetails () в интерфейсе аутентификации? UserDetails заполняется после аутентификации провайдера (AuthenticationProvider).
4.3.2 Интерфейс UserDetailsService
Большинство провайдеров аутентификации пользуются UserDetails с участием UserDetailsService Интерфейс. Интерфейс UserDetailsService определяется следующим образом:
В интерфейсе UserDetailsService есть только один метод loadUserByUsername, который используется для загрузки соответствующих пользователей по имени пользователя. Когда не удается найти пользователя, соответствующего имени пользователя, возникает исключение UsernameNotFoundException.Обязанности UserDetailsService и AuthenticationProvider часто путают люди. Помните, что UserDetailsService отвечает только за загрузку пользовательской информации из определенного места (обычно базы данных), и ничего более.
Распространенными классами реализации UserDetailsService являются JdbcDaoImpl и InMemoryUserDetailsManager. Первый загружает пользователей из базы данных, а второй загружает пользователей из памяти. Конечно, вы также можете реализовать UserDetailsService самостоятельно.
4.4 Spring Security Architecture
Ранее мы представили основные компоненты Spring Security (SecurityContextHolder, SecurityContext и Authentication) и основные службы (AuthenticationManager, ProviderManager и AuthenticationProvider) и, наконец, рассмотрим общую архитектуру Spring Security: