SpringCloud — анализ и реализация принципа единого входа на основе Oauth2.
SpringCloud — анализ и реализация принципа единого входа на основе Oauth2.

Единый вход (SSO) — это процесс аутентификации, который позволяет пользователям получать доступ к нескольким системам с помощью одного входа. В этой статье будет глубоко проанализирован принцип единого входа и подробно описано, как реализовать единый вход в среду Spring Cloud. С помощью конкретных архитектурных схем и примеров кода мы продемонстрируем рабочий механизм и преимущества SSO, чтобы помочь разработчикам лучше понять и применять эту технологию.

1. Знакомство с единым входом

1. Знакомство с единым входом

Единый вход (SSO) — это механизм аутентификации, который позволяет пользователям получать доступ к нескольким взаимно доверенным прикладным системам после прохождения одной проверки личности. Это упрощает операции пользователя, улучшает взаимодействие с пользователем и снижает сложность управления несколькими системами аутентификации. В современных распределенных системах и микросервисных архитектурах единый вход особенно важен, поскольку он позволяет сократить количество повторных операций входа в систему, унифицировать вход для аутентификации пользователей, а также повысить безопасность и управляемость системы.

2. Принцип единого входа

Основной принцип единого входа заключается в обеспечении доступа к нескольким системам путем совместного использования статуса аутентификации. Его основные шаги включают в себя:

  • Аутентификация пользователя:Пользователь находится вSSOЦентр сертификации для входа,Центр аутентификации генерирует токен после проверки личности пользователя.
  • Обмен токенами:Когда пользователи получают доступ к другим доверенным прикладным системам,Носите этот жетон. Система приложения подтверждает личность пользователя путем проверки Токена.
  • Управление сеансами:SSOСостояние сеанса пользователя управления системой,Убедитесь, что пользователям не нужно повторно входить в систему в течение срока действия.

3. Схема архитектуры единого входа

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


2. Реализация единого входа

Реализация единого входа в среде Spring Cloud требует рассмотрения следующих шагов:

шаг

описывать

Создать центр сертификации

Создайте специальную службу аутентификации, отвечающую за вход пользователей и генерацию токенов. Эта функциональность может быть достигнута с помощью Spring Security и OAuth2.

Настройка службы шлюза

Маршрутизация запросов и проверка токена реализуются через Spring Cloud Gateway или Zuul.

Интеграция сервисов приложений

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

1. Создать сертификационный центр

Центр аутентификации отвечает за аутентификацию пользователей и генерацию токенов. Полномочия аутентификации могут быть реализованы с использованием Spring Security и OAuth2.

① Добавьте зависимость OAuth2.

Добавьте в проект зависимость OAuth2:

Язык кода:xml
копировать
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-oauth2-client</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-oauth2-resource-server</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.security</groupId>
    <artifactId>spring-security-oauth2-jose</artifactId>
</dependency>
② Настройка сервера аутентификации OAuth2.

Создайте и настройте сервер аутентификации OAuth2:

Язык кода:java
копировать
@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {

    @Autowired
    private AuthenticationManager authenticationManager;

    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        clients.inMemory()
                .withClient("client-id")
                .secret("{noop}client-secret")
                .authorizedGrantTypes("authorization_code", "refresh_token", "password")
                .scopes("read", "write")
                .redirectUris("http://localhost:8081/login/oauth2/code/custom");
    }

    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
        endpoints.authenticationManager(authenticationManager)
                 .tokenStore(new InMemoryTokenStore());
    }
}
③ Настройка Spring Security

Создайте и настройте Spring Security:

Язык кода:java
копировать
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication()
            .withUser("user")
            .password("{noop}password")
            .roles("USER");
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
            .anyRequest().authenticated()
            .and()
            .formLogin().permitAll();
    }

    @Bean
    @Override
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }
}

2. Настройте службу шлюза.

Служба шлюза отвечает за маршрутизацию запросов и проверку токенов. Для этого мы используем Spring Cloud Gateway.

① Добавьте зависимость службы шлюза.

Добавьте в проект зависимость службы шлюза:

Язык кода:xml
копировать
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-oauth2-client</artifactId>
</dependency>
② Добавить конфигурацию шлюза.

Добавьте конфигурацию шлюза в application.yml:

Язык кода:yaml
копировать
spring:
  cloud:
    gateway:
      routes:
        - id: user-service
          uri: lb://USER-SERVICE
          predicates:
            - Path=/user/**
          filters:
            - TokenRelay
  security:
    oauth2:
      client:
        provider:
          custom:
            authorization-uri: http://localhost:8080/oauth/authorize
            token-uri: http://localhost:8080/oauth/token
            user-info-uri: http://localhost:8080/userinfo
            jwk-set-uri: http://localhost:8080/.well-known/jwks.json
        registration:
          custom:
            client-id: client-id
            client-secret: client-secret
            authorization-grant-type: authorization_code
            redirect-uri: "{baseUrl}/login/oauth2/code/{registrationId}"
            scope: read,write

3. Интеграция сервисов приложений

Каждый микросервис необходимо настроить как сервер ресурсов, чтобы обеспечить проверку токена каждого запроса.

① Добавьте зависимости к каждому сервису.

Добавьте зависимость сервера ресурсов OAuth2 к каждой службе:

Язык кода:xml
копировать
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-oauth2-resource-server</artifactId>
</dependency>
② Добавьте конфигурацию для каждой службы.

Добавьте конфигурацию сервера ресурсов OAuth2 в файл application.yml:

Язык кода:yaml
копировать
spring:
  security:
    oauth2:
      resourceserver:
        jwt:
          issuer-uri: http://localhost:8080/
③ Настройка политики безопасности.

Создайте и настройте Spring Security, чтобы обеспечить проверку токенов всех запросов:

Язык кода:java
копировать
@Configuration
@EnableWebSecurity
public class ResourceServerConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
            .antMatchers("/public/**").permitAll()
            .anyRequest().authenticated()
            .and()
            .oauth2ResourceServer().jwt();
    }
}

4. Напишите интерфейс единого входа

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

① Получите код авторизации.

Сначала клиентскому приложению необходимо направить пользователя в центр сертификации SSO для входа в систему и получения кода авторизации.

Этого можно добиться с помощью перенаправления браузера:

Язык кода:java
копировать
@GetMapping("/login")
public void login(HttpServletResponse response) throws IOException {
    String authorizationUri = "http://localhost:8080/oauth/authorize";
    String clientId = "client-id";
    String redirectUri = "http://localhost:8081/callback";
    String responseType = "code";
    String scope = "read write";

    String authUrl = authorizationUri + "?response_type=" + responseType
            + "&client_id=" + clientId
            + "&redirect_uri=" + URLEncoder.encode(redirectUri, "UTF-8")
            + "&scope=" + URLEncoder.encode(scope, "UTF-8");

    response.sendRedirect(authUrl);
}
② Получить токен доступа

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

Клиентскому приложению необходимо использовать этот код авторизации для запроса токена доступа:

Язык кода:java
копировать
@GetMapping("/callback")
public String callback(@RequestParam("code") String code, Model model) {
    String tokenUri = "http://localhost:8080/oauth/token";
    String clientId = "client-id";
    String clientSecret = "client-secret";
    String redirectUri = "http://localhost:8081/callback";

    RestTemplate restTemplate = new RestTemplate();

    HttpHeaders headers = new HttpHeaders();
    headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
    headers.setBasicAuth(clientId, clientSecret);

    MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
    params.add("grant_type", "authorization_code");
    params.add("code", code);
    params.add("redirect_uri", redirectUri);

    HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<>(params, headers);

    ResponseEntity<Map> response = restTemplate.exchange(tokenUri, HttpMethod.POST, request, Map.class);

    Map<String, Object> responseBody = response.getBody();
    String accessToken = (String) responseBody.get("access_token");

    model.addAttribute("accessToken", accessToken);

    return "home";
}
③ Используйте токен доступа для доступа к защищенным ресурсам.

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

Вот пример кода использования RestTemplate для доступа к защищенному ресурсу:

Язык кода:java
копировать
@GetMapping("/resource")
public String getResource(@RequestParam("accessToken") String accessToken, Model model) {
    String resourceUri = "http://localhost:8082/resource";

    RestTemplate restTemplate = new RestTemplate();

    HttpHeaders headers = new HttpHeaders();
    headers.setBearerAuth(accessToken);

    HttpEntity<String> request = new HttpEntity<>(headers);

    ResponseEntity<String> response = restTemplate.exchange(resourceUri, HttpMethod.GET, request, String.class);

    String resource = response.getBody();

    model.addAttribute("resource", resource);

    return "resource";
}

5. Пример структуры проекта

Примерная структура проекта выглядит следующим образом:

Язык кода:xml
копировать
/sso-auth-server
  ├── src/main/java/com/example/auth
  │   ├── AuthorizationServerConfig.java
  │   ├── SecurityConfig.java
  │   └── Application.java
  └── src/main/resources
      └── application.yml

/sso-gateway
  ├── src/main/java/com/example/gateway
  │   └── Application.java
  └── src/main/resources
      └── application.yml

/sso-user-service
  ├── src/main/java/com/example/user
  │   ├── ResourceServerConfig.java
  │   └── Application.java
  └── src/main/resources
      └── application.yml

/sso-client
  ├── src/main/java/com/example/client
  │   ├── SsoController.java
  │   └── Application.java
  └── src/main/resources
      └── application.yml

Данная структура состоит из четырех основных частей:

  • Сервер аутентификации (sso-auth-server):Ответственный Аутентификация пользователяиTokenгенерировать。
  • Служба шлюза (sso-gateway): отвечает за маршрутизацию запросов и проверку токена.
  • Пользовательская служба (sso-user-service): действует как сервер ресурсов и предоставляет защищенные ресурсы.
  • Клиентское приложение (sso-client): отвечает за то, чтобы пользователи могли войти в систему, получить токены и получить доступ к защищенным ресурсам.

3. Краткое описание единого входа

1. Преимущества единого входа

Преимущества

описывать

Улучшенный пользовательский интерфейс

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

Улучшения безопасности

Унифицированный вход для аутентификации и централизованное управление могут повысить безопасность системы и снизить риск независимого управления каждой системой аутентификационной информацией.

Управление упрощено

Централизованное управление идентификационной информацией пользователей и логикой аутентификации упрощает обслуживание и управление системой.

Повышение производительности

Это сокращает время, которое пользователи тратят на переключение между различными системами, тем самым повышая общую эффективность работы.

Сокращение затрат на разработку

Разработчикам необходимо реализовать логику аутентификации и авторизации только один раз, что может сэкономить затраты на разработку и поддержку нескольких систем аутентификации.

Единое управление пользователями

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

Улучшите аудит и соблюдение требований

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

Легко интегрироваться и расширяться

Новые прикладные системы можно легко интегрировать без необходимости настройки отдельных процессов входа и аутентификации для каждой новой системы.

2. Краткое описание единого входа

Единый вход (SSO) играет важную роль в современных распределенных системах. Он не только улучшает взаимодействие с пользователем, но и повышает безопасность системы. Реализация единого входа через Spring Cloud позволяет в полной мере использовать экосистему и мощные функции Spring для достижения эффективной аутентификации личности и управления авторизацией.

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

  • Выбор технологии:Выберите тот, который соответствует потребностям вашего бизнесаSSOМетод реализации,Например, на основе OAuth2, JWT или CAS и т. д.
  • политика безопасности:Обеспечить передачу данныхи Безопасность хранения,Используйте технологию шифрования для защиты информации пользователя,Защититесь от атак.
  • Оптимизация производительности:через балансировку нагрузки、Такие технологии, как кэширование и асинхронная обработка, повышают скорость отклика и стабильность системы.
  • Управление пользователями:Централизованно управляйте идентификационной информацией пользователей.,Обеспечьте согласованность и точность пользовательских данных.
  • Ведение журнала и мониторинг:Внедрить комплексное журналированиеи Механизм мониторинга,Своевременно выявлять и устранять потенциальные проблемы,Обеспечить нормальную работу системы.
  • механизм отказоустойчивости:Прочная конструкциямеханизм отказоустойчивость, гарантирующая возможность быстрого восстановления системы в случае сбоя.

Благодаря вышеуказанным мерам общая производительность системы единого входа может быть эффективно улучшена для удовлетворения бизнес-потребностей и требований безопасности предприятия.

boy illustration
Неразрушающее увеличение изображений одним щелчком мыши, чтобы сделать их более четкими артефактами искусственного интеллекта, включая руководства по установке и использованию.
boy illustration
Копикодер: этот инструмент отлично работает с Cursor, Bolt и V0! Предоставьте более качественные подсказки для разработки интерфейса (создание навигационного веб-сайта с использованием искусственного интеллекта).
boy illustration
Новый бесплатный RooCline превосходит Cline v3.1? ! Быстрее, умнее и лучше вилка Cline! (Независимое программирование AI, порог 0)
boy illustration
Разработав более 10 проектов с помощью Cursor, я собрал 10 примеров и 60 подсказок.
boy illustration
Я потратил 72 часа на изучение курсорных агентов, и вот неоспоримые факты, которыми я должен поделиться!
boy illustration
Идеальная интеграция Cursor и DeepSeek API
boy illustration
DeepSeek V3 снижает затраты на обучение больших моделей
boy illustration
Артефакт, увеличивающий количество очков: на основе улучшения характеристик препятствия малым целям Yolov8 (SEAM, MultiSEAM).
boy illustration
DeepSeek V3 раскручивался уже три дня. Сегодня я попробовал самопровозглашенную модель «ChatGPT».
boy illustration
Open Devin — инженер-программист искусственного интеллекта с открытым исходным кодом, который меньше программирует и больше создает.
boy illustration
Эксклюзивное оригинальное улучшение YOLOv8: собственная разработка SPPF | SPPF сочетается с воспринимаемой большой сверткой ядра UniRepLK, а свертка с большим ядром + без расширения улучшает восприимчивое поле
boy illustration
Популярное и подробное объяснение DeepSeek-V3: от его появления до преимуществ и сравнения с GPT-4o.
boy illustration
9 основных словесных инструкций по доработке академических работ с помощью ChatGPT, эффективных и практичных, которые стоит собрать
boy illustration
Вызовите deepseek в vscode для реализации программирования с помощью искусственного интеллекта.
boy illustration
Познакомьтесь с принципами сверточных нейронных сетей (CNN) в одной статье (суперподробно)
boy illustration
50,3 тыс. звезд! Immich: автономное решение для резервного копирования фотографий и видео, которое экономит деньги и избавляет от беспокойства.
boy illustration
Cloud Native|Практика: установка Dashbaord для K8s, графика неплохая
boy illustration
Краткий обзор статьи — использование синтетических данных при обучении больших моделей и оптимизации производительности
boy illustration
MiniPerplx: новая поисковая система искусственного интеллекта с открытым исходным кодом, спонсируемая xAI и Vercel.
boy illustration
Конструкция сервиса Synology Drive сочетает проникновение в интрасеть и синхронизацию папок заметок Obsidian в облаке.
boy illustration
Центр конфигурации————Накос
boy illustration
Начинаем с нуля при разработке в облаке Copilot: начать разработку с минимальным использованием кода стало проще
boy illustration
[Серия Docker] Docker создает мультиплатформенные образы: практика архитектуры Arm64
boy illustration
Обновление новых возможностей coze | Я использовал coze для создания апплета помощника по исправлению домашних заданий по математике
boy illustration
Советы по развертыванию Nginx: практическое создание статических веб-сайтов на облачных серверах
boy illustration
Feiniu fnos использует Docker для развертывания личного блокнота Notepad
boy illustration
Сверточная нейронная сеть VGG реализует классификацию изображений Cifar10 — практический опыт Pytorch
boy illustration
Начало работы с EdgeonePages — новым недорогим решением для хостинга веб-сайтов
boy illustration
[Зона легкого облачного игрового сервера] Управление игровыми архивами
boy illustration
Развертывание SpringCloud-проекта на базе Docker и Docker-Compose