Authentication authentication) {
...
User user = (User) authentication.getPrincipal();
order.setUser(user);
...
}
С Authentication в руках, вы можете вызвать getPrincipal(), чтобы получить основной (principal) объект, который в этом случае является User. Обратите внимание, что getPrincipal() возвращает java.util.Object, поэтому вам нужно привести его к User.
Однако, возможно, самым чистым решением является просто принимать на вход объект User в методе processOrder(), но аннотировать его @AuthenticationPrincipal, чтобы он был субъектом проверки подлинности:
@PostMapping
public String processOrder(@Valid Order order, Errors errors, SessionStatus sessionStatus,
@AuthenticationPrincipal User user) {
if (errors.hasErrors()) {
return "orderForm";
}
order.setUser(user);
orderRepo.save(order);
sessionStatus.setComplete();
return "redirect:/";
}
Что хорошо в @AuthenticationPrincipal, так это то, что он не требует приведения (как с Authentication), и он ограничивает код безопасности самой аннотацией. К моменту получения объекта User в processOrder() он готов к использованию для Оrder.
Есть еще один способ определить, кто является аутентифицированным пользователем, хотя это немного грязно в том смысле, что он очень тяжел для кода, специфичного для безопасности. Вы можете получить объект аутентификации из контекста безопасности и затем запросить его участника (principal) следующим образом:
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
User user = (User) authentication.getPrincipal();
Несмотря на то, что этот фрагмент имеет большой объем кода для обеспечения безопасности, он имеет одно преимущество перед другими описанными подходами: его можно использовать в любом месте приложения, а не только в методах обработчика контроллера. Это делает его пригодным для использования на более низких уровнях кода.
Итог:
--Spring Security autoconfiguration отличный способ начать работу с безопасностью, но большинству приложений необходимо явно настроить безопасность для удовлетворения своих уникальных требований безопасности.
-User details могут управляться в хранилищах пользователей, поддерживаемых реляционными базами данных,
LDAP или полностью настраиваемыми реализациями.
-Spring Security автоматически защищает от CSRF-атак.
-Информация об аутентифицированном пользователе может быть получена через объект SecurityContext (возвращается из SecurityContextHolder.getContext () ) или внедряется в контроллеры с помощью @AuthenticationPrincipal.
Spring in Action Covers Spring 5.0 перевод на русский. Глава 5
5. Работа со свойствами конфигурации
В этой главе рассматриваются
Тонкая настройка автоконфигурирования bean-ов
Применение свойств конфигурации к компонентам приложения
Работа с Spring профилями.
Вы помните те времена, когда iPhone впервые вышел? Небольшой кусок металла и стекла едва ли соответствовал описанию того, что мир представлял себе как телефон. И все же, он стал пионером современной эпохи смартфонов, изменив все в том, как мы общаемся. Хотя сенсорные телефоны во многих отношениях проще и мощнее, чем их предшественник, флип-телефон, когда iPhone был впервые анонсирован, было трудно представить, как устройство с одной кнопкой может использоваться для звонков.
В некотором смысле автоконфигурация Spring Boot выглядит также. Автоматическая конфигурация значительно упрощает разработку приложений Spring. Но после десятилетия установки значений свойств в конфигурации Spring XML и вызова методов setter в экземплярах bean не сразу видно, как установить свойства bean, для которых нет явной конфигурации.
К счастью, Spring Boot предоставляет способ со свойствами конфигурации. Свойства конфигурации - это не что иное, как свойства компонентов в контексте приложения Spring, которые можно задать из нескольких источников свойств, включая системные свойства JVM, аргументы командной строки и переменные среды.
В этой главе вы сделаете шаг назад от реализации новых функций в приложении Taco Cloud, чтобы изучить свойства конфигурации. То, что вы узнаете, несомненно, окажется полезным по мере продвижения вперед в последующих главах. Мы начнем с того, как использовать свойства конфигурации для точной настройки того, что Spring Boot автоматически настраивает.
5.1 Тонкая настройка автоконфигурации
Прежде чем мы слишком глубоко погрузимся в свойства конфигурации, важно установить, что в Spring: есть два разных (но связанных) типа конфигураций:
-Bean wiring - конфигурация, которая объявляет компоненты приложения, которые будут созданы как bean в контексте приложения Spring и как они должны быть внедрены друг в друга.
-Property injection - конфигурация, задающая значения для компонентов в контексте приложения Spring.
И в конфигурации Spring на основе XML и Java конфигурации, эти два типа конфигураций часто объявляются явно в одном и том же месте. В конфигурации Java метод @Bean - аннотированный, вероятно, создаст экземпляр bean, а затем установит значения его свойств. Например, рассмотрим следующий метод @Bean, объявляющий источник данных для встроенной базы данных H2:
@Bean
public DataSource dataSource() {
return new EmbeddedDataSourceBuilder()
.setType(H2)
.addScript("taco_schema.sql")
.addScripts("user_data.sql", "ingredient_data.sql")
.build();
}
Здесь методы addScript() и addScripts() задают некоторые строковые свойства с именами SQL-скриптов, которые должны применяться к базе данных после того, как источник данных готов. Таким образом вы можете настроить bean-компонент DataSource, если вы не используете Spring Boot. Автоконфигурация делает этот метод совершенно ненужным.
Если зависимость (dependency) H2 доступна в пути к классам во время выполнения, Spring Boot автоматически создает соответствующий компонент DataSource в контексте приложения Spring. Bean применяет сценарии SQL schema.sql и data.sql.
Но что, если вы хотите назвать сценарии SQL как-нибудь иначе? Или что, если вам нужно указать более двух сценариев SQL? Именно здесь вступают в силу свойства конфигурации. Но прежде чем вы сможете начать использовать свойства конфигурации, вам необходимо понять, откуда эти свойства берутся.
5.1.1 Понимание абстракции среды Spring
Абстракция среды Spring - это универсальный магазин для любого настраиваемого свойства. Он абстрагирует происхождение свойств, так что bean-ы, нуждающиеся в этих свойствах, могут получать их из среды Spring. Окружающая среда Spring получает их от нескольких источников свойств, включая:
-Свойства системы JVM
-Переменные среды операционной системы
-Аргумент командной строки
-Конфигурационные файлы приложения
Затем он агрегирует эти свойства в один источник, из которого можно производить внедрения Spring bean-ов. На рис. 5.1 показано, как свойства из источников свойств перетекают через абстракцию среды Spring в Spring beans.
Рисунок 5.1 Spring окружение подтягивает свойства из различных источников, и делает их доступными для bean-ов в контексте приложения.
Bean-компоненты, которые автоматически настраиваются Spring Boot, настраиваются свойствами, полученными из среды Spring. В качестве простого примера предположим, что вы хотите, чтобы базовый контейнер сервлета приложения прослушивал запросы на каком-либо порту, отличном от порта по умолчанию 8080. Для этого укажите другой порт, установив свойство server.port в src/main/resources/application.properties:
server.port=9090
Лично я предпочитаю использовать YAML при настройке свойств конфигурации. Поэтому, вместо того, чтобы использовать application.properties, я мог бы создал server.port в src / main/resources/application.yml:
server:
port: 9090
Если вы предпочитаете настраивать это свойство извне, вы также можете указать порт при запуске приложения с помощью аргумента командной строки:
$ java -jar tacocloud-0.0.5-SNAPSHOT.jar --server.port=9090
Если вы хотите, чтобы приложение всегда запускалось на определенном порту, вы можете установить его один раз в качестве переменной среды операционной системы:
$ export SERVER_PORT=9090
Обратите внимание, что при установке свойств в качестве переменных среды стиль именования немного отличается, чтобы учесть ограничения, накладываемые операционной системой на имена переменных среды. Все нормально. Spring может интерпретировать SERVER_PORT как server.port без проблем.
Как я уже сказал, существует несколько способов настройки свойств конфигурации. И когда мы перейдем к главе 14, вы увидите еще один способ установки свойств конфигурации на централизованном сервере конфигурации. Фактически, есть несколько сотен свойств конфигурации, которые вы можете использовать для настройки, в том числе и для настройки поведения Spring bean-ов. Вы уже видели несколько: server.port в этой главе и security.user.name и security.user.password в предыдущей главе.
Невозможно изучить все доступные свойства конфигурации в этой главе. Тем не менее, давайте рассмотрим несколько наиболее полезных свойств конфигурации, с которыми вы обычно сталкиваетесь. Мы начнем с нескольких свойств, которые позволяют настроить источник данных с автоматической настройкой.
5.1.2 Конфигурация источника данных
На данный момент приложение Taco Cloud все еще не завершено, но у вас будет еще несколько глав, чтобы позаботиться об этом, прежде чем вы будете готовы развернуть приложение. Таким образом, встроенная база данных H2, которую вы используете в качестве источника данных, идеально подходит для ваших нужд. Но как только вы возьмете приложение в производство, вы, вероятно, захотите рассмотреть более постоянное решение для базы данных.