【问题标题】:spring OAuth2 zuul--Access token expired,invalid_tokenspring OAuth2 zuul--访问令牌过期,invalid_token
【发布时间】:2017-04-11 01:26:03
【问题描述】:

我有一个 spring zuul OAuth2 应用程序。

authServer--

OAuth2ServerConfiguration:

@Configuration
public class  {
    @Bean
    public TokenStore tokenStore() {
        return new InMemoryTokenStore();
    }

    @Configuration
    @EnableResourceServer
    protected static class ResourceServerConfiguration extends
            ResourceServerConfigurerAdapter {

        @Override
        public void configure(ResourceServerSecurityConfigurer resources) {
            resources.resourceId(RESOURCE_ID);
        }

        @Override
        public void configure(HttpSecurity http) throws Exception {            http .authorizeRequests()
                    .antMatchers( "/oauth/authorize/**","/oauth/check_token/**").permitAll()

                    .anyRequest().authenticated();
            // @formatter:on
        }

    }

    @Configuration
    @EnableAuthorizationServer
    protected static class AuthorizationServerConfiguration extends
            AuthorizationServerConfigurerAdapter {

        //private TokenStore tokenStore = new InMemoryTokenStore();
        @Autowired
        @Qualifier("authenticationManagerBean")
        private AuthenticationManager authenticationManager;


        @Autowired
        TokenStore tokenStore;

        @Autowired
        private CustomUserDetailService customUserDetailService;



        @Override
        public void configure(AuthorizationServerEndpointsConfigurer endpoints)
                throws Exception {
            // @formatter:off
            endpoints
                    .tokenStore(this.tokenStore)
                    .authenticationManager(this.authenticationManager)
                    .userDetailsService(customUserDetailService);
            // @formatter:on
        }

        @Override
        public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
            // @formatter:off
            clients
                    .inMemory()
                    .withClient("kksdi2388wmkwe")
                    .authorizedGrantTypes("authorization_code","password", "refresh_token")
                    .scopes("read", "write")
                    .resourceIds("ReadAndWriteResource")
                    .secret("kksd23isdmsisdi2")
                    .autoApprove(true)
                    .accessTokenValiditySeconds(120)
                    .refreshTokenValiditySeconds(1200);
            // @formatter:on
        }

        @Bean
        @Primary
        public DefaultTokenServices tokenServices() {
            DefaultTokenServices tokenServices = new DefaultTokenServices();
            tokenServices.setSupportRefreshToken(true);
            tokenServices.setTokenStore(this.tokenStore);
            return tokenServices;
        }

    }
}

网络安全:

@Configuration
@EnableWebSecurity
@Order(-20)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

     @Autowired
    private CustomAuthenticationProvider customAuthenticationProvider;



    @Override
     protected void configure(AuthenticationManagerBuilder auth) throws Exception {
    auth.authenticationProvider(customAuthenticationProvider);

    }

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



    @Override
    protected void configure(HttpSecurity http) throws Exception {
        // @formatter:off
        http
                .authorizeRequests()
                .antMatchers("/login", "/").permitAll()
                .and()
                .formLogin()
                .loginPage("/login")
                .permitAll()

                .and()
                .csrf().disable()
                .requestMatchers().antMatchers("/login", "/oauth/authorize", "/oauth/confirm_access")
                .and()
                .authorizeRequests().anyRequest().authenticated()
        ;

        // @formatter:on
    }


    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder(11);
    }


}

zuul 服务器:

security:
  user:
    password: none
  oauth2:
    client:
      accessTokenUri: http://localhost:9999/uaa/oauth/token
      userAuthorizationUri: http://localhost:9999/uaa/oauth/authorize
      clientId: kksdi2388wmkwe
      clientSecret: kksd23isdmsisdi2
        resource:
      userInfoUri: http://localhost:9999/uaa/user


zuul:
  routes:
    auth-server: /auth-server/**
    resource: /resource/**

zuul 应用:

@SpringBootApplication
@EnableZuulProxy
@EnableOAuth2Sso
public class Application extends WebSecurityConfigurerAdapter {

  public static void main(String[] args) {
    SpringApplication.run(Application.class, args);
  }

  @Override
  public void configure(HttpSecurity http) throws Exception {


    http
            .logout().permitAll()
            .and().authorizeRequests()
            .mvcMatchers("/login/**").permitAll()
                      .anyRequest().authenticated();
  }


}

问题:

登录后:

可以访问:AuthServer“http://localhost:8080/auth-server/uaa/user”和“http://localhost:8080/api/test


但是当 access_token 过期时, 只能访问:"http://localhost:8080/api/test", 访问AuthServer“http://localhost:8080/auth-server/uaa/user”时遇到错误--

<error_description>
Access token expired: 530c9247-2331-47e3-a6c0-ed61814642f5
</error_description>
<error>invalid_token</error>

我无法从请求标头中获取 access_token,

如何解决?

【问题讨论】:

    标签: spring spring-security spring-security-oauth2 netflix-zuul spring-oauth2


    【解决方案1】:

    在一切之前检查您的 OAUTH 服务器应用程序服务器和您的客户端应用程序服务器的时间和时区是否分开在两台不同的机器上。

    我认为您的 OAUTH 服务器配置存在一些问题。 OAUTH 服务器本身受“基本访问身份验证”保护:https://en.wikipedia.org/wiki/Basic_access_authentication

    这与他的请求标头上的令牌一起使用: '授权':基本=Base64.encode(用户名+''+密码)。 如果您错过了这个令牌,那么您将无法访问您的 OAUTH 服务器上的任何端点。 我的工作正常,你可以测试一下:

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        // @formatter:off
        http.formLogin().loginPage("/login").permitAll()
                .and().requestMatchers().antMatchers("/login", "/oauth/authorize", "/oauth/confirm_access", "/fonts/**", "/css/**")
                .and().authorizeRequests().antMatchers("/fonts/**", "/css/**").anonymous().anyRequest().authenticated();
        // @formatter:on
    }
    

    你为什么禁用 csrf 保护?

    【讨论】:

    • 嗨,谢谢你的回答,为了简化问题,csrf被禁用了。我可以登录,并通过zuul代理访问:AuthServer "http://localhost:8080/auth-server/uaa/user"和`“localhost:8080/api/test,but after 120s,access_token expired, can only localhost:8080/api/test"` 可以访问,但AuthServer "http://localhost:8080/auth-server/uaa/user" 不能访问。错误是:Access token expired: a09e4446-a01c-4e8a-86c4-635c1a30c4fb &lt;error&gt;invalid_token&lt;/error&gt;
    • 我也有这个问题! access_token 没有得到更新,我必须再次重新发送 authorization_code 以获得新的 access_token。
    • 很抱歉听到这个问题......我已经为这个问题苦苦挣扎了两天......我曾经使用 JWT 没有这个问题,但不是 customTokenStore 或 InMemoryTokenStore 有问题。
    • 我觉得和你的token store没关系,我也改了,发给你我自己的token store 或许能找到线索:
    • 理论上spring zuul,应该可以刷新access_token,但是不知道为什么不行,如果不是通过zuul,当token过期时,访问安全URLlocalhost:8080/api/test,貌似矛盾,不知道问题出在哪里
    【解决方案2】:

    这些是我的令牌存储配置:

    @Autowired
        @Qualifier("datasource")
        private DataSource dataSource;
    
        @Bean
        public TokenStore tokenStore() {
            return new JdbcTokenStore(dataSource);
        }
    
    
        @Bean
        protected AuthorizationCodeServices authorizationCodeServices() {
            return new JdbcAuthorizationCodeServices(dataSource);
        }
    
        @Override
        public void configure(AuthorizationServerSecurityConfigurer oauthServer)
                throws Exception {
            oauthServer.tokenKeyAccess("permitAll()").checkTokenAccess("isAuthenticated()");
        }
    
        @Override
        public void configure(AuthorizationServerEndpointsConfigurer endpoints)
                throws Exception {
            endpoints.authorizationCodeServices(authorizationCodeServices())
                    .authenticationManager(authenticationManager).tokenStore(tokenStore())
                    .approvalStoreDisabled();
        }
    

    【讨论】:

    • jdbcTokenStore 有效吗?当 access_ 令牌过期时。是否可以访问 AuthServer 或 ResourceServer 数据?
    • 是的,它有效,您必须为您的资源添加一些配置。
    • 我对jdbc不熟悉,我尝试了mongodb token store,但是没有设置authorizationCodeServiceapprovalStoreDisabled(),,你可以尝试取消设置authorizationCodeService看看是否有效?跨度>
    • 你添加了@SessionAttributes("authorizationRequest") 并设置了AuthServer的会话值吗?
    • 作为 Oauth2 规则,当您使用 Authorization_Code 授权类型时,您需要将其保存在您的令牌存储中。这个配置说亲爱的令牌存储请做一个表,我可以保存我的授权码。所以你的数据库中有 3 个表,OAUTH_ACCESS_TOKEN、OAUTH_REFRESH_TOKEN 和 OAUTH_CODE
    猜你喜欢
    • 1970-01-01
    • 2020-08-19
    • 2016-01-04
    • 1970-01-01
    • 2019-03-10
    • 2015-04-12
    • 2017-12-02
    • 1970-01-01
    • 2018-12-01
    相关资源
    最近更新 更多