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

Простой единый знак-на с весенней безопасности OAuth2

Простая реализация SSO с использованием Spring Security 5 и Boot.

Автор оригинала: Sampada Wagde.

1. Обзор

В этом учебнике мы обсудим, как реализовать SSO – Единый знак на – с помощью весенней безопасности OAuth и весенняя загрузка, используя Keycloak в качестве сервера авторизации.

Мы будем использовать 4 отдельных приложения:

  • Сервер авторизации , который является центральным механизмом аутентификации
  • Ресурсный сервер — поставщик Фу секунда
  • Два клиентских приложения – приложения с использованием SSO

Проще говоря, когда пользователь пытается получить доступ к ресурсу через одно приложение Клиента, он будет перенаправлен на аутентификацию сначала через сервер авторизации. Keycloak войдет в систему пользователя, и пока он входит в первое приложение, если ко второму приложению Клиента доступен с помощью того же браузера, пользователю больше не нужно будет вводить свои учетные данные.

Мы будем использовать Код авторизации тип гранта из OAuth2 для привода делегирования аутентификации.

Мы будем использовать стек OAuth в Spring Security 5. Если вы хотите использовать стека наследия Spring Security OAuth, посмотрите на предыдущую статью: Простой единый знак-On с весенней безопасности OAuth2 (наследие стек)

В соответствии с миграционное руководство :

Весенняя безопасность относится к этой функции как OAuth 2.0 Логин в то время как весенняя безопасность OAuth относится к нему как SSO

Дальнейшее чтение:

Весенняя безопасность 5 – OAuth2 Логин

Новое весной безопасности OAuth2 – Проверка претензий

Вторичный Facebook Логин с весенней социальной

Хорошо, давайте запрыгнем прямо с этого.

2. Сервер авторизации

Ранее стек Spring Security OAuth предлагал возможность настройки сервера авторизации в качестве весеннего приложения.

Тем не менее, стек OAuth был deprecated к весне, и теперь мы будем использовать Keycloak в качестве нашего сервера авторизации.

На этот раз мы наберем наш сервер авторизации в встроенный сервер Keycloak в приложении Spring Boot .

В нашем предварительное , Мы определим двух клиентов, ssoClient-1 и ssoClient-2 , по одному для каждого приложения клиента.

3. Ресурсный сервер

Далее нам нужен ресурсный сервер или API REST, который предоставит нам Фу s наше клиентское приложение будет потреблять.

Это по существу то же самое, что мы использовали для наших угловых клиентских приложений ранее.

4. Клиентские приложения

Теперь давайте посмотрим на наше приложение для клиентов Thymeleaf; Конечно, мы будем использовать Spring Boot, чтобы свести к минимуму конфигурацию.

Имейте в виду, что Мы должны иметь 2 из них, чтобы продемонстрировать один знак-On функциональность .

4.1. Зависимость от Maven

Во-первых, нам понадобится следующая зависимость в нашем пом.xml :


    org.springframework.boot
    spring-boot-starter-web


    org.springframework.boot
    spring-boot-starter-oauth2-client


    org.springframework.boot
    spring-boot-starter-thymeleaf


    org.thymeleaf.extras
    thymeleaf-extras-springsecurity5


    org.springframework
    spring-webflux


    io.projectreactor.netty
    reactor-netty

Чтобы включить всю поддержку клиентов, в которой мы нуждаемся, включая безопасность, нам просто нужно добавить весна-загрузка-стартер-oauth2-клиент . Кроме того, так как старые РестТемплет будет deprecated, мы собираемся использовать его WebClient , и именно поэтому мы добавили весна-webflux и реактор-нетти .

4.2. Конфигурация безопасности

Далее, самая важная часть, конфигурация безопасности нашего первого клиент-приложения:

@EnableWebSecurity
public class UiSecurityConfig extends WebSecurityConfigurerAdapter {
    
    @Override
    public void configure(HttpSecurity http) throws Exception {
        http.antMatcher("/**")
          .authorizeRequests()
          .antMatchers("/")
          .permitAll()
          .anyRequest()
          .authenticated()
          .and()
          .oauth2Login();
    }

    @Bean
    WebClient webClient(ClientRegistrationRepository clientRegistrationRepository, 
      OAuth2AuthorizedClientRepository authorizedClientRepository) {
        ServletOAuth2AuthorizedClientExchangeFilterFunction oauth2 = 
          new ServletOAuth2AuthorizedClientExchangeFilterFunction(clientRegistrationRepository, 
          authorizedClientRepository);
        oauth2.setDefaultOAuth2AuthorizedClient(true);
        return WebClient.builder().apply(oauth2.oauth2Configuration()).build();
    }
}

Основной частью этой конфигурации является oauth2Login () метод, который используется для поддержки входа в систему OAuth 2.0 Spring Security. Поскольку мы используем Keycloak, который по умолчанию является единым решением для веб-приложений и веб-сервисов RESTful, нам не нужно добавлять дополнительную конфигурацию для SSO.

Наконец, мы также определили WebClient боб, чтобы выступать в качестве простого клиента HTTP для обработки запросов, которые будут отправлены на наш ресурсный сервер.

А вот и application.yml :

spring:
  security:
    oauth2:
      client:
        registration:
          custom:
            client-id: ssoClient-1
            client-secret: ssoClientSecret-1
            scope: read,write
            authorization-grant-type: authorization_code
            redirect-uri: http://localhost:8082/ui-one/login/oauth2/code/custom
        provider:
          custom:
            authorization-uri: http://localhost:8083/auth/realms/baeldung/protocol/openid-connect/auth
            token-uri: http://localhost:8083/auth/realms/baeldung/protocol/openid-connect/token
            user-info-uri: http://localhost:8083/auth/realms/baeldung/protocol/openid-connect/userinfo
            user-name-attribute: preferred_username
  thymeleaf:
    cache: false
    
server: 
  port: 8082
  servlet: 
    context-path: /ui-one

resourceserver:
  api:
    project:
      url: http://localhost:8081/sso-resource-server/api/foos/        

Вот, spring.security.oauth2.client.registration является корневым пространством имен для регистрации клиента. Мы определили клиента с регистрационным идентификатором пользовательские . Затем мы определили его клиент-ID , клиент-секретный , область , разрешение-грант типа и перенаправить-ури , что, конечно, должно быть таким же, как это определено для нашего сервера авторизации.

После этого мы определили нашего поставщика услуг или сервер авторизации, опять же с тем же идентификатором пользовательские , и перечислены вниз его различных URI для весенней безопасности в использовании. Это все, что нам нужно определить, и рамки делает весь процесс входа в систему, в том числе перенаправление на Keycloak, бесшовно для нас .

Также обратите внимание, что в нашем примере мы выкатили наш сервер авторизации, но, конечно, мы также можем использовать других, сторонних провайдеров, таких как Facebook или GitHub .

4.3. Контроллер

Давайте теперь реализуем наш контроллер в клиентском приложении, чтобы попросить Фу s от нашего ресурсного сервера:

@Controller
public class FooClientController {

    @Value("${resourceserver.api.url}")
    private String fooApiUrl;

    @Autowired
    private WebClient webClient;

    @GetMapping("/foos")
    public String getFoos(Model model) {
        List foos = this.webClient.get()
            .uri(fooApiUrl)
            .retrieve()
            .bodyToMono(new ParameterizedTypeReference>() {
            })
            .block();
        model.addAttribute("foos", foos);
        return "foos";
    }
}

Как мы видим, у нас есть только один метод, который будет блюдо из ресурсов для foos шаблон. Нам не нужно было добавлять код для входа в систему.

4.4. Фронт-Энд

Теперь давайте рассмотрим передовую конфигурацию нашего клиент-приложения. Мы не собираемся, чтобы сосредоточиться на том, что здесь, главным образом потому, что мы уже охвачены на сайте .

Наше клиентское приложение здесь имеет очень простой передний конец; Вот индекс.html :

И foos.html :

Spring OAuth Client Thymeleaf -1
Hi, preferred_username   
    

All Foos:

ID Name
No foos
ID Name

foos.html страница нуждается в подлинности пользователей. Если неиспытуемый пользователь пытается получить доступ к foos.html , они будут перенаправлены на страницу входа Keycloak в первую .

4.5. Второе клиентское приложение

Мы настройим второе приложение, Весна OAuth Клиент Thymeleaf -2 с помощью другого client_id ssoClient-2 .

Это будет в основном так же, как первое приложение, которое мы только что описали.

тем application.yml будет отличаться, чтобы включить различные client_id , client_secret и redirect_uri в своем spring.security.oauth2.client.registration:

spring:
  security:
    oauth2:
      client:
        registration:
          custom:
            client-id: ssoClient-2
            client-secret: ssoClientSecret-2
            scope: read,write
            authorization-grant-type: authorization_code
            redirect-uri: http://localhost:8084/ui-two/login/oauth2/code/custom

И, конечно, мы должны иметь другой серверный порт для него, так что мы можем запустить их параллельно:

server: 
  port: 8084
  servlet: 
    context-path: /ui-two

Наконец, мы будем настроить передний конец HTMLs иметь название, как Весенний OAuth Клиент Thymeleaf – 2 вместо – 1 так что мы можем различать два.

5. Тестирование поведения SSO

Чтобы проверить поведение SSO, давайте забудем наши приложения.

Нам нужно, чтобы все наши 4 Boot Apps – сервер авторизации, ресурсный сервер и оба клиентских приложения – были запущены для этого.

Теперь давайте откроем браузер, скажем Chrome, и войдите в систему, чтобы Клиент-1 использование учетных данных (электронная почта защищена) /123 . Далее, в другом окне или вкладке, ударил URL для Клиент-2 . При нажатии кнопки входа, мы будем перенаправлены на Фус страницы сразу, минуя этап проверки подлинности.

Аналогичным образом, если пользователь входит в систему Клиент-2 во-первых, они не должны вводить свое имя пользователя/пароль для Клиент-1 .

6. Заключение

В этом учебнике мы сосредоточились на реализации единого знака использования Spring Security OAuth2 и Spring Boot с использованием Keycloak в качестве поставщика идентификационных данных.

Как всегда, полный исходный код можно найти более на GitHub .