春季启动,OAuth2.0,Zuul身份验证问题

时间:2020-02-05 05:32:06

标签: spring spring-boot cookies oauth-2.0 microservices

我一直在尝试使用Zuul,Eureka和Spring boot构建应用程序,最近我决定尝试登录。提醒一下,我已经配置了身份验证服务(使用OAuth 2.0),并且可以使用CURL成功进行身份验证。我还可以向具有受保护资源的其他微服务(也仅使用CURL,因为我可以将令牌注入身份验证标头中)获取请求。我担心的是,我想使用Zuul作为网关。

enter image description here

简而言之,我基于该图所遵循的过程如下:

1)从Web资源管理器中,输入网关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)授权服务中的/ login是默认的Spring Boot,JWT,安全性登录索引

enter image description here

4)输入已配置的详细信息,单击“登录”,但没有任何反应。 Zuul不会重定向到UI微服务(图中未列出),我感觉没有生成Cookie并将其转发回Zuul,因此Zuul可以将其转发回Web资源管理器,因此,没有办法验证该Cookie。

如果您能解决我目前遇到的一些问题,我将不胜感激:

1)使用CURL作为认证服务器URL:localhost:9096/oauth/token\?grant_type=password\&username=test\&password=secret。它会生成Cookie吗?我认为并非如此,我得到的唯一回应就是代表令牌的JSON。这是否意味着我需要读取JSON并将其编码为Cookie?我需要一个cookie还是有其他方法可以做到这一点?我如何用Zuul做到这一点?

2)如何验证Zuul提供的Cookie?

3)我需要在Zuul服务器中创建cookie吗?还是在授权服务器中?

4)如何验证来自其他微服务(例如边缘微服务)的Cookie?

5)旧令牌被丢弃后,如何生成新令牌? (由于时间戳记),我在哪里生成新令牌? (在 Zuul 之内?我是否必须拨打身份验证服务器?”),如何将新令牌作为cookie持久保存?

6)如何处理从微服务内部经过时间戳的情况,例如: 当我在 edge microservice 中验证令牌时,我还有2秒钟的时间,然后,在将令牌传递给 microservice 之后,它没有剩余时间了。我认为一种解决方案可以是创建仅在微服务中使用的另一个令牌?还有其他方法吗?

7)我知道我可以向JWT添加更多有效负载,例如,如果要添加用户ID,我将如何进行呢?由于证书已签名,因此人们在更改客户ID时会遇到问题吗?

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();
    }
}

感谢您的帮助。

0 个答案:

没有答案