解决Spring OAuth2 每次生成的access_token和refresh_token都是新的问题

解决Spring OAuth2 每次生成的access_token和refresh_token都是新的问题

一. 问题描述

我们的项目中使用到了Spring OAuth2,但是在利用Spring OAuth2生成access_token和refresh_token的时候,每次传递过来username和password,生成的对应的token都是一个新的值,过期时间也一直是最新的默认值89400秒,说明每次都是重新生成了一个token.

原因是自己这边采用的是默认的InMemory,把生成的token存在在了内存中,没有进行持久化.

二. 解决办法

将生成的token保存在redis中进行持久化即可.

package com.syc.cloud.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.io.ClassPathResource;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.NoOpPasswordEncoder;
import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.token.AuthorizationServerTokenServices;
import org.springframework.security.oauth2.provider.token.DefaultTokenServices;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;
import org.springframework.security.oauth2.provider.token.store.JwtTokenStore;
import org.springframework.security.oauth2.provider.token.store.KeyStoreKeyFactory;
import org.springframework.security.oauth2.provider.token.store.redis.RedisTokenStore;

@Configuration
@EnableAuthorizationServer
public class OauthServerConfig extends AuthorizationServerConfigurerAdapter {

    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        //super.configure(clients);

        clients.inMemory()
                .withClient("oauth-client")
                .secret("123456")
                .scopes("server")
                .authorizedGrantTypes("password","refresh_token")
                .accessTokenValiditySeconds(24*3600);
    }

    @Bean
    public JwtAccessTokenConverter jwtAccessTokenConverter(){
        JwtAccessTokenConverter converter=new JwtAccessTokenConverter();
        ClassPathResource resource=new ClassPathResource("syc-jwt.jks");
        KeyStoreKeyFactory factory=new KeyStoreKeyFactory(resource,"syc123".toCharArray());
        converter.setKeyPair(factory.getKeyPair("syc-jwt"));
        return converter;
    }

    @Autowired
    private RedisConnectionFactory redisConnectionFactory;

    @Bean
    public TokenStore tokenStore(){
        //return new JwtTokenStore(jwtAccessTokenConverter());
        //用RedisToken替换JwtToken,解决每次请求access_token和refresh_token都是新的问题.
        return new RedisTokenStore(redisConnectionFactory);
    }

    @Autowired
    @Qualifier("authenticationManagerBean")
    private AuthenticationManager authenticationManager;

    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
        //super.configure(endpoints);
        endpoints.tokenStore(tokenStore())
        .tokenEnhancer(jwtAccessTokenConverter())
        //.tokenServices(tokenServices())
        .authenticationManager(authenticationManager);
        //该字段设置设置refresh token是否重复使用,true:reuse;false:no reuse
        //.reuseRefreshTokens(false);
    }

    @Override
    public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
        security.tokenKeyAccess("permitAll()");
        security.checkTokenAccess("isAuthenticated()");
        security.allowFormAuthenticationForClients();
        //解决Encoded password does not look like BCrypt报错
        //因为springsecurity在最新版本升级后,默认把之前的明文密码方式给去掉了
        //https://spring.io/blog/2017/11/01/spring-security-5-0-0-rc1-released#password-storage-updated
        security.passwordEncoder(NoOpPasswordEncoder.getInstance());
    }
}



 

发布了234 篇原创文章 · 获赞 74 · 访问量 7万+

猜你喜欢

转载自blog.csdn.net/syc000666/article/details/96857326