Spring boot, OAuth2.0, проблема аутентификации Zuul - PullRequest
0 голосов
/ 05 февраля 2020

Я пытался создать приложение с загрузкой Zuul, Eureka и Spring, и недавно я решил попробовать войти в систему. Напоминаю, что я уже настроил службу аутентификации (используя OAuth 2.0) и могу успешно пройти аутентификацию с использованием CURL. Я также могу получить петиции get для других микросервисов, которые имеют защищенные ресурсы (опять же только с CURL, потому что я могу вставить токен в заголовок аутентификации). Меня беспокоит то, что я хочу сделать это с Zuul в качестве шлюза.

enter image description here

Вкратце процесс, на котором я следую, основываясь на приведенной выше схеме, следующий :

1) В веб-обозревателе я ввожу IP-адрес шлюза.

2) Шлюз настраивается следующим образом, следовательно, он перенаправляет на сервер авторизации, выделенный в другом компьютер.

    authentication:
        path: /proxy/authentication/**
        serviceId: AuthenticationMicroservice
        stripPrefix: false
    @Override
    public void configure(final HttpSecurity http) throws Exception {
        http.authorizeRequests()
                .antMatchers("/proxy/authentication/**")
                .permitAll()
                .antMatchers("/**")
                .authenticated();

        // This is in charge of redirecting to the login index in the authentication server in case
        // you are not logged in.
        AuthenticationEntryPoint entryPoint = (request, response, authException) -> response.sendRedirect("/proxy/authentication/login");
        http.exceptionHandling()
                .authenticationEntryPoint(entryPoint);
    }

3) Вход / Вход в службе авторизации - это загрузка по умолчанию Spring, JWT, индекс безопасности входа в систему

enter image description here

4) Я ввожу уже настроенные данные, нажимаю «Войти», но ничего не происходит. Zuul не перенаправляет на микросервис пользовательского интерфейса (это не указано на диаграмме), я чувствую, что нет никакого кулинара ie, сгенерированного и отправленного обратно в Zuul, поэтому Zuul может переслать его обратно в веб-обозреватель, и, следовательно, есть нет способа проверить этого повара ie.

Буду признателен, если вы решите несколько вопросов, которые у меня есть на данный момент:

1) Использование CURL для URL-адреса сервера аутентификации: localhost:9096/oauth/token\?grant_type=password\&username=test\&password=secret. Это генерирует повара ie? Я думаю, что нет, единственное, что я получаю в ответ, это JSON, который представляет токен. Означает ли это, что мне нужно прочитать это JSON и закодировать его в коде ie? Мне нужен повар ie или есть другие способы сделать это? Как я могу сделать это с Zuul?

2) Как я могу проверить, что повар ie от Zuul?

3) Нужно ли создавать повара ie на сервере Zuul? Или на сервере авторизации?

4) Как я могу проверить, что повар ie из другого микросервиса , такого как пограничный микросервис?

5) Как создать новый токен после того, как старый токен был удален? (из-за отметки времени), Где генерировать этот новый токен? (В течение Zuul ? Нужно ли мне звонить на сервер аутентификации ?), Как я могу сохранить этот новый токен как повар ie?

6) Как я могу обработать случаи, когда временная метка истекла из микросервисов, например: Когда я проверяю токен в пограничном микросервисе , у меня есть еще 2 секунды, затем, после того, как я передаю токен в микросервис у него нет оставшегося времени. Я думаю, что одним из решений может быть создание другого токена, который будет использоваться только внутри микросервисов? Есть ли другие подходы к этому?

7) Я знаю, что могу добавить больше полезной нагрузки в JWT, например, если я хочу добавить идентификатор пользователя, как я буду продолжать это делать? Поскольку сертификат подписан, будут ли у меня проблемы с людьми, меняющими свой идентификатор клиента?

AuthorizationServerCode


@Configuration
@EnableAuthorizationServer
@EnableConfigurationProperties(SecurityProperties.class)
public class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter {

    private final DataSource dataSource;
    private final AuthenticationManager authenticationManager;
    private final PasswordEncoder passwordEncoder;
    private final SecurityProperties securityProperties;

    private JwtAccessTokenConverter jwtAccessTokenConverter;
    private TokenStore tokenStore;

    @Autowired
    public AuthorizationServerConfiguration(final DataSource dataSource, final AuthenticationManager authenticationManager, final PasswordEncoder passwordEncoder,
                                            final SecurityProperties securityProperties) {
        this.dataSource = dataSource;
        this.authenticationManager = authenticationManager;
        this.passwordEncoder = passwordEncoder;
        this.securityProperties = securityProperties;
    }

    /**
     * Reads data from the tokens themselves.
     * Not really a store since it never persists anything and
     * it uses the JwtAccessTokenConverter to generate and read the tokens.
     */
    @Bean
    TokenStore tokenStore() {
        if (tokenStore == null) {
            tokenStore = new JwtTokenStore(jwtAccessTokenConverter());
        }
        return tokenStore;
    }

    /**
     * The DefaultTokenServices uses the TokenStore to persist the tokens.
     */
    @Bean
    public DefaultTokenServices tokenServices(final TokenStore tokenStore,
                                              final ClientDetailsService clientDetailsService) {
        DefaultTokenServices tokenServices = new DefaultTokenServices();
        tokenServices.setSupportRefreshToken(true);
        tokenServices.setTokenStore(tokenStore);
        tokenServices.setClientDetailsService(clientDetailsService);
        tokenServices.setAuthenticationManager(this.authenticationManager);
        return tokenServices;
    }

    /**
     * Uses the self-signed certificate to sign the generated tokens.
     */
    @Bean
    public JwtAccessTokenConverter jwtAccessTokenConverter() {
        if (jwtAccessTokenConverter != null) {
            return jwtAccessTokenConverter;
        }

        JwtProperties jwtProperties = securityProperties.getJwt();
        KeyPair keyPair = keyPair(jwtProperties, keyStoreKeyFactory(jwtProperties));

        jwtAccessTokenConverter = new JwtAccessTokenConverter();
        jwtAccessTokenConverter.setKeyPair(keyPair);
        return jwtAccessTokenConverter;
    }

    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        clients.jdbc(dataSource);
    }

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

    @Override
    public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
        security.passwordEncoder(passwordEncoder).tokenKeyAccess("permitAll()").checkTokenAccess("isAuthenticated()");
    }

    private KeyPair keyPair(JwtProperties jwtProperties, KeyStoreKeyFactory keyStoreKeyFactory) {
        return keyStoreKeyFactory.getKeyPair(jwtProperties.getKeyPairAlias(), jwtProperties.getKeyPairPassword().toCharArray());
    }

    private KeyStoreKeyFactory keyStoreKeyFactory(JwtProperties jwtProperties) {
        return new KeyStoreKeyFactory(jwtProperties.getKeyStore(), jwtProperties.getKeyStorePassword().toCharArray());
    }
}

package com.training.inmedia.authenticationservice.configuration;

import com.training.inmedia.authenticationservice.authentication.UserDetailsService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.factory.PasswordEncoderFactories;
import org.springframework.security.crypto.password.PasswordEncoder;

@EnableWebSecurity
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {

    private UserDetailsService userDetailsService;
    private PasswordEncoder passwordEncoder;

    @Autowired
    public WebSecurityConfiguration(final UserDetailsService userDetailsService) {
        this.userDetailsService = userDetailsService;
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
    }

    /**
     * This bean is required to be injected into the AuthorizationServerConfiguration.
     */
    @Bean
    public PasswordEncoder passwordEncoder() {
        if (passwordEncoder == null) {
            passwordEncoder = PasswordEncoderFactories.createDelegatingPasswordEncoder();
        }
        return passwordEncoder;
    }

    /**
     * This bean is required to be injected into the AuthorizationServerConfiguration.
     */
    @Bean
    @Override
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }
}

Спасибо за вашу помощь.

...