Автор оригинала: Loredana Crusoveanu.
1. Обзор
Spring Security 5 вводит новый Конфигурация входа в систему OAuth2 класс, который мы можем использовать для настройки внешнего сервера авторизации.
В этой статье мы рассмотрим некоторые из различных вариантов конфигурации, доступных для oauth2 Login() элемента .
2. Зависимости Maven
В проекте Spring Boot все, что нам нужно, – это добавить стартер spring-boot-starter-oauth2-клиент :
org.springframework.boot spring-boot-starter-oauth2-client 2.3.3.RELEASE
В проекте без загрузки, в дополнение к стандартным зависимостям Spring и Spring Security, нам также необходимо явно добавить зависимости spring-security-oauth2-client и spring-security-oauth2-jose :
org.springframework.security spring-security-oauth2-client 5.3.4.RELEASE org.springframework.security spring-security-oauth2-jose 5.3.4.RELEASE
3. Настройка клиентов
В проекте Spring Boot все, что нам нужно сделать, это добавить несколько стандартных свойств для каждого клиента, который мы хотим настроить.
Давайте настроим наш проект для входа в систему с клиентами, зарегистрированными в Google и Facebook в качестве поставщиков аутентификации.
3.1. Получение Учетных Данных Клиента
Чтобы получить учетные данные клиента для аутентификации Google OAuth2, перейдите в Консоль Google API – раздел “Учетные данные”.
Здесь мы создадим учетные данные типа “Идентификатор клиента OAuth2” для нашего веб-приложения. Это приводит к тому, что Google устанавливает для нас идентификатор клиента и секрет.
Мы также должны настроить авторизованный URI перенаправления в консоли Google, на который пользователи будут перенаправлены после успешного входа в систему с помощью Google.
По умолчанию Spring Boot настраивает URL-адрес перенаправления как /login/oauth2/code/{идентификатор регистрации}. Поэтому для Google мы добавим URI:
http://localhost:8081/login/oauth2/code/google
Facebook Facebook для получения учетных данных клиента для аутентификации с помощью Facebook нам необходимо зарегистрировать приложение на веб-сайте Facebook для разработчиков и настроить соответствующий URI как “Действительный URI перенаправления OAuth”:
http://localhost:8081/login/oauth2/code/facebook
3.3. Конфигурация безопасности
Затем нам нужно добавить учетные данные клиента в файл application.properties . Свойства безопасности Spring имеют префикс “spring.security.oauth2.client.registration” , за которым следует имя клиента, а затем имя свойства клиента:
spring.security.oauth2.client.registration.google.client-id=spring.security.oauth2.client.registration.google.client-secret= spring.security.oauth2.client.registration.facebook.client-id= spring.security.oauth2.client.registration.facebook.client-secret=
Добавление этих свойств по крайней мере для одного клиента включит автоконфигурацию клиента Oauth2 класс , который настраивает все необходимые компоненты.
Автоматическая конфигурация веб-безопасности эквивалентна определению простого вход в систему oauth2() элемент:
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.anyRequest().authenticated()
.and()
.oauth2Login();
}
}Здесь мы видим, что элемент oauth2 Login() используется аналогично уже известным элементам http Basic() и form Logic () .
Теперь, когда мы попытаемся получить доступ к защищенному URL-адресу, приложение отобразит автоматически сгенерированную страницу входа с двумя клиентами:
3.4. Другие Клиенты
Обратите внимание, что в дополнение к Google и Facebook проект Spring Security также содержит конфигурации по умолчанию для GitHub и Okta. Эти конфигурации по умолчанию предоставляют всю необходимую информацию для аутентификации, что позволяет нам вводить только учетные данные клиента.
Если мы хотим использовать другого поставщика проверки подлинности, не настроенного в Spring Security, нам нужно будет определить полную конфигурацию с такой информацией, как URI авторизации и URI токена. Здесь рассмотрим конфигурации по умолчанию в Spring Security, чтобы получить представление о необходимых свойствах.
4. Настройка в проекте без загрузки
4.1. Создание Репозитория регистрации Клиентов.
Если мы не работаем с приложением Spring Boot, нам нужно будет определить Репозиторий регистрации клиентов bean , содержащий внутреннее представление информации о клиентах, принадлежащей серверу авторизации:
@Configuration
@EnableWebSecurity
@PropertySource("classpath:application.properties")
public class SecurityConfig extends WebSecurityConfigurerAdapter {
private static List clients = Arrays.asList("google", "facebook");
@Bean
public ClientRegistrationRepository clientRegistrationRepository() {
List registrations = clients.stream()
.map(c -> getRegistration(c))
.filter(registration -> registration != null)
.collect(Collectors.toList());
return new InMemoryClientRegistrationRepository(registrations);
}
} Здесь мы создаем репозиторий регистрации клиентов в памяти со списком объектов Регистрации клиентов .
4.2. Построение Объектов Регистрации Клиентов
Давайте посмотрим на метод get Registration () , который создает эти объекты:
private static String CLIENT_PROPERTY_KEY
= "spring.security.oauth2.client.registration.";
@Autowired
private Environment env;
private ClientRegistration getRegistration(String client) {
String clientId = env.getProperty(
CLIENT_PROPERTY_KEY + client + ".client-id");
if (clientId == null) {
return null;
}
String clientSecret = env.getProperty(
CLIENT_PROPERTY_KEY + client + ".client-secret");
if (client.equals("google")) {
return CommonOAuth2Provider.GOOGLE.getBuilder(client)
.clientId(clientId).clientSecret(clientSecret).build();
}
if (client.equals("facebook")) {
return CommonOAuth2Provider.FACEBOOK.getBuilder(client)
.clientId(clientId).clientSecret(clientSecret).build();
}
return null;
}Здесь мы читаем учетные данные клиента из аналогичного файла application.properties , а затем используем CommonOauth2Provider перечисление, уже определенное в Spring Security для остальных свойств клиента для клиентов Google и Facebook.
Каждый экземпляр Регистрации клиента соответствует клиенту.
4.3. Регистрация Репозитория Регистрации Клиентов
Наконец, мы должны создать Авторизованная клиентская служба OAuth2 bean на основе репозитория регистрации клиентов bean и регистрация с помощью элемента oauth2Login() :
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().anyRequest().authenticated()
.and()
.oauth2Login()
.clientRegistrationRepository(clientRegistrationRepository())
.authorizedClientService(authorizedClientService());
}
@Bean
public OAuth2AuthorizedClientService authorizedClientService() {
return new InMemoryOAuth2AuthorizedClientService(
clientRegistrationRepository());
}Как показано здесь, мы можем использовать репозиторий регистрации клиентов() метод oauth2 Login() для регистрации пользовательского репозитория регистрации.
Нам также придется определить пользовательскую страницу входа в систему, так как она больше не будет создаваться автоматически. Более подробную информацию об этом мы увидим в следующем разделе.
Давайте продолжим дальнейшую настройку нашего процесса входа в систему.
5. Настройка входа в систему oauth2()
Существует несколько элементов, которые использует процесс OAuth2 и которые мы можем настроить с помощью методов oauth2 Login () .
Обратите внимание, что все эти элементы имеют конфигурации по умолчанию в Spring Boot, и явная конфигурация не требуется.
Давайте посмотрим, как мы можем настроить их в нашей конфигурации.
5.1. Пользовательская страница Входа В Систему
Несмотря на то, что Spring Boot создает для нас страницу входа по умолчанию, мы обычно хотим определить нашу собственную настроенную страницу.
Давайте начнем с настройки нового URL-адреса входа для элемента oauth2 Login() с помощью метода |/страница входа() :
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/oauth_login")
.permitAll()
.anyRequest()
.authenticated()
.and()
.oauth2Login()
.loginPage("/oauth_login");
}Здесь мы настроили наш URL-адрес для входа в систему на /oauth_login.
Далее давайте определим LoginController с помощью метода, который сопоставляется с этим URL-адресом:
@Controller
public class LoginController {
private static String authorizationRequestBaseUri
= "oauth2/authorization";
Map oauth2AuthenticationUrls
= new HashMap<>();
@Autowired
private ClientRegistrationRepository clientRegistrationRepository;
@GetMapping("/oauth_login")
public String getLoginPage(Model model) {
// ...
return "oauth_login";
}
} Этот метод должен отправить карту доступных клиентов и их конечных точек авторизации в представление , которое мы получим из компонента ClientRegistrationRepository :
public String getLoginPage(Model model) {
Iterable clientRegistrations = null;
ResolvableType type = ResolvableType.forInstance(clientRegistrationRepository)
.as(Iterable.class);
if (type != ResolvableType.NONE &&
ClientRegistration.class.isAssignableFrom(type.resolveGenerics()[0])) {
clientRegistrations = (Iterable) clientRegistrationRepository;
}
clientRegistrations.forEach(registration ->
oauth2AuthenticationUrls.put(registration.getClientName(),
authorizationRequestBaseUri + "/" + registration.getRegistrationId()));
model.addAttribute("urls", oauth2AuthenticationUrls);
return "oauth_login";
} Наконец, нам нужно определить наши oauth_login.html страница:
Login with:
Это простая HTML-страница, на которой отображаются ссылки для аутентификации с каждым клиентом.
После добавления к нему некоторого стиля мы можем изменить внешний вид страницы входа в систему: