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

Spring Security 5 – Вход в систему OAuth2

Узнайте, как аутентифицировать пользователей с помощью Facebook, Google или других учетных данных с помощью OAuth2 в Spring Security 5.

Автор оригинала: 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:

Client

Это простая HTML-страница, на которой отображаются ссылки для аутентификации с каждым клиентом.

После добавления к нему некоторого стиля мы можем изменить внешний вид страницы входа в систему: