Spring Cloud Security настраивает интеграцию JWT и OAuth2 для реализации единого входа — пример
Spring Cloud Security настраивает интеграцию JWT и OAuth2 для реализации единого входа — пример

использоватьOAuth2иJWTосознатьЕдиный вход。Вот простой пример:

  1. Пользователи проходят аутентификацию в нашем приложении.
  2. Приложение отправит запрос на внешний сервер аутентификации OAuth2 для получения токена доступа.
  3. Сервер аутентификации проверит личность пользователя и вернет токен доступа.
  4. Приложение будет использовать токен доступа для отправки запроса на сервер ресурсов.
  5. Сервер ресурсов проверит токен доступа и вернет защищенные данные.

В этом примере показано, как OAuth2 и JWT работают вместе для реализации единого входа и авторизации. Используя Spring Cloud Security, мы можем легко реализовать эти функции и обеспечить мощную и гибкую поддержку безопасности. Демонстрирует, как использовать Spring Cloud Security и Spring Cloud Gateway для реализации единого входа на основе JWT и OAuth2:

Создать сервер авторизации

Мы будем использовать Spring Security OAuth2 для создания нашего сервера авторизации. Вот некоторые ключевые конфигурации:

Язык кода:javascript
копировать
@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("client-secret")
                .authorizedGrantTypes("password")
                .scopes("read", "write")
                .accessTokenValiditySeconds(3600);
    }

    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
        endpoints.authenticationManager(authenticationManager)
                .tokenStore(tokenStore())
                .accessTokenConverter(accessTokenConverter());
    }

    @Bean
    public TokenStore tokenStore() {
        return new JwtTokenStore(accessTokenConverter());
    }

    @Bean
    public JwtAccessTokenConverter accessTokenConverter() {
        JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
        converter.setSigningKey("signing-key");
        return converter;
    }
}

Мы настроили службу сведений о клиенте в памяти, используя имя пользователя и пароль в качестве типа авторизации. Мы также установили срок действия токена доступа на 3600 секунд. Мы также настроили AuthorizationServerEndpointsConfigurer для использования tokenStore и accessTokenConverter для обработки токенов JWT. Здесь мы используем закрытый ключ для подписи токена JWT, чтобы гарантировать, что он не был подделан.

Создать сервер ресурсов

Далее мы создадим ресурсы сервера, чтобы только прошедшие проверку подлинности пользователи могли получить доступ к защищенным конечным точкам API. Вот некоторые ключевые конфигурации:

Язык кода:javascript
копировать
@Configuration
@EnableResourceServer
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {

    @Override
    public void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                .antMatchers("/api/**")
                .authenticated();
    }

    @Override
    public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
        resources.tokenStore(tokenStore());
    }

    @Bean
    public TokenStore tokenStore() {
        return new JwtTokenStore(jwtAccessTokenConverter());
    }

    @Bean
    public JwtAccessTokenConverter jwtAccessTokenConverter() {
        JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
        converter.setVerifierKey("verifier-key");
        return converter;
    }
}

Эта конфигурация включит сервер ресурсов и настроит защищенные конечные точки API, для доступа к которым требуется проверка подлинности OAuth2. Мы также настроили bean-компонент tokenStore и bean-компонент jwtAccessTokenConverter для обработки токенов JWT. Здесь мы использовали открытый ключ для проверки токена JWT, который будет использоваться для проверки подписи токена JWT. Нам необходимо предоставить открытый ключ, который будет использоваться для проверки подписи JWT. При использовании JWT нам необходимо подписать токен JWT, чтобы гарантировать, что он не был подделан.

Создать шлюз

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

Язык кода:javascript
копировать
@Configuration
@EnableWebFluxSecurity
@EnableReactiveMethodSecurity
public class GatewaySecurityConfig {

    @Autowired
    private JwtTokenProvider jwtTokenProvider;

    @Bean
    public SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity http) {
        http.authorizeExchange()
                .pathMatchers("/api/auth/**").permitAll()
                .anyExchange().authenticated()
                .and()
                .oauth2ResourceServer().jwt()
                .and()
                .addFilterAt(jwtAuthenticationFilter(), SecurityWebFiltersOrder.AUTHENTICATION)
                .csrf().disable();

        return http.build();
    }

    @Bean
    public ReactiveJwtDecoder jwtDecoder() {
        return NimbusJwtDecoder.withPublicKey(this.jwtTokenProvider.getPublicKey()).build();
    }

    @Bean
    public JwtAuthenticationFilter jwtAuthenticationFilter() {
        return new JwtAuthenticationFilter(jwtDecoder());
    }

}

Здесь мы используем аннотацию @EnableWebFluxSecurity для включения Spring Security, а затем используем аннотацию @EnableReactiveMethodSecurity для включения безопасности на уровне метода. Мы используем компонент JwtTokenProvider, который содержит открытый и закрытый ключи для проверки и подписи токена JWT. Мы также создали bean-компонент SecurityWebFilterChain для настройки цепочки фильтров безопасности. Мы разрешаем анонимный доступ к конечной точке авторизации, все остальные конечные точки требуют аутентификации OAuth2. Мы использовали oauth2ResourceServer().jwt() для настройки проверки токена JWT, а затем добавили JwtAuthenticationFilter, который анализирует токен JWT и преобразует его в объект аутентификации Spring Security. Наконец, мы отключили защиту CSRF, поскольку она нам не нужна на шлюзе.

Создайте JwtTokenProvider.

нам все еще нужно Создайте JwtTokenProvider. bean-компонент, который содержит открытый и закрытый ключи, используемые для проверки и подписи токенов JWT. Вот некоторые ключевые конфигурации:

Язык кода:javascript
копировать
@Component
public class JwtTokenProvider {

    private final String publicKey;
    private final String privateKey;

    public JwtTokenProvider() throws Exception {
        KeyPair keyPair = KeyPairUtils.generateKeyPair("RSA", 2048);
        this.publicKey = new String(Base64.getEncoder().encode(keyPair.getPublic().getEncoded()));
        this.privateKey = new String(Base64.getEncoder().encode(keyPair.getPrivate().getEncoded()));
    }

    public String getPublicKey() {
        return publicKey;
    }

    public String getPrivateKey() {
        return privateKey;
    }

}

Здесь мы используем класс инструмента KeyPairUtils для создания пары ключей RSA и сохранения ее в компоненте JwtTokenProvider. Мы можем использовать этот компонент для получения открытого и закрытого ключей, которые затем можно использовать для проверки и подписи токена JWT.

Создайте фильтр JwtAuthenticationFilter.

наконец,Нам нужно разработать фильтр JwtAuthenticationFilter. bean, этот фильтр используется для анализа токенов JWT и преобразования их в Spring. Security Объект аутентификации. Вот некоторые ключевые конфигурации:

Язык кода:javascript
копировать
public class JwtAuthenticationFilter extends AbstractAuthenticationProcessingFilter {

    private final ReactiveJwtDecoder jwtDecoder;

    public JwtAuthenticationFilter(ReactiveJwtDecoder jwtDecoder) {
        super("/api/**");
        this.jwtDecoder = jwtDecoder;
    }

    @Override
    public Mono<Authentication> attemptAuthentication(ServerWebExchange exchange) {
        String authHeader = exchange.getRequest().getHeaders().getFirst(HttpHeaders.AUTHORIZATION);

        if (authHeader != null && authHeader.startsWith("Bearer ")) {
            String authToken = authHeader.substring(7);
            return this.jwtDecoder.decode(authToken)
                    .map((jwt) -> new UsernamePasswordAuthenticationToken(jwt.getSubject(), null, jwt.getClaim("authorities").asList(String.class)))
                    .cast(Authentication.class)
                    .onErrorResume((ex) -> Mono.empty());
        } else {
            return Mono.empty();
        }
    }

}

Здесь мы создаем bean-компонент JwtAuthenticationFilter и наследуем AbstractAuthenticationProcessingFilter. Мы использовали компонент ReactiveJwtDecoder для анализа токена JWT и преобразования его в объект Spring Security Authentication. Мы реализовали метод tryAuthentication, который пытается проанализировать токен JWT и использовать его для создания нового объекта UsernamePasswordAuthenticationToken. Наконец, мы используем onErrorResume для обработки любых ошибок и возврата пустого объекта Mono.

тест

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

Язык кода:javascript
копировать
curl --request GET \
  --url http://localhost:8080/api/users \
  --header 'Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c'

Эта команда отправит шлюзу запрос GET, содержащий токен JWT, с использованием заголовка авторизации. Если все в порядке, шлюз перенаправит запрос в правильный микросервис и пройдет аутентификацию с использованием токена JWT. Если токен JWT недействителен или срок его действия истек, шлюз вернет ответ 401 Unauthorized.

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