文章目录
token处理
基本的token参数
使用jwt替换默认的token
扩展和解析jwt的信息
基本的token配置参数 AuthorizationServerConfigurerAdapter
认证服务器继承AuthorizationServerConfigurerAdapter 重写 configure(ClientDetailsServiceConfigurer clients)配置token
@Configuration
@EnableAuthorizationServer
public class WhaleAuthenticationServiceConfig extends AuthorizationServerConfigurerAdapter {
// 如果不继承AuthorizationServerConfigurerAdapter类 它会自动在bean容器中找这两个bean
@Autowired
private AuthenticationManager authenticationManager;
@Qualifier("demoUserDetailsService")
@Autowired
private UserDetailsService userDetailsService;
/**
*
* @param endpoints oauth/token 的入口点
* @throws Exception
*/
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
// super.configure(endpoints);
endpoints.authenticationManager(authenticationManager).userDetailsService(userDetailsService);
}
/**
* 客户端配置 我们的认证服务器会给哪些第三方发令牌
* 此时 demo application 中
* security.oauth2.client.client-id=whale
* security.oauth2.client.client-secret=123456
* 将失效
*
* 相关配置从此方法读取
*
* @param clients
* @throws Exception
*/
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
// super.configure(clients);
// clients.inMemory() token 存入内存
// clients.jdbc() token 存入数据库
clients.inMemory()
.withClient("whale")
.secret("123456")
.accessTokenValiditySeconds(7200) // token有效时间 单位秒
.authorizedGrantTypes("refresh_token","password") //支持哪些授权模式 token刷新和密码模式
.scopes("all","read","write"); //相当于权限,配置了这个参数,请求里面可以不带scope参,如果带了参数,必须在配置的这个scope范围之内
}
}
测试
多个client配置
代码
重构
client的配置从application中获取,达到复用性
OAuth2ClientProperties
spring中已经有了 OAuth2ClientProperties这个实体,它有三个属性
clientId、clientSecret 、defaultSecret
org.springframework.boot.autoconfigure.security.oauth2.OAuth2ClientProperties
@ConfigurationProperties(
prefix = "security.oauth2.client"
)
public class OAuth2ClientProperties {
private String clientId;
private String clientSecret = UUID.randomUUID().toString();
private boolean defaultSecret = true;
······················
但我们还需要一个超时时间的属性
重新写一个类
public class OAuth2ClientProperties implements Serializable {
private String clientId;
private String clientSecret;
//令牌过期时间单位为秒 0 是 永不过期
private int accessTokenValiditySeconds = 7200;
ok
支持数组配置 OAuth2Properties
public class OAuth2Properties implements Serializable {
private OAuth2ClientProperties[] clients = {};
SecurityProperties
//client 配置
private OAuth2Properties oauth2 = new OAuth2Properties();
AuthenticationServiceConfig
WhaleAuthenticationServiceConfig
/**
* 客户端配置 我们的认证服务器会给哪些第三方发令牌
* 此时 demo application 中
* security.oauth2.client.client-id=whale
* security.oauth2.client.client-secret=123456
* 将失效
*
* 相关配置从此方法读取
*
* @param clients
* @throws Exception
*/
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
InMemoryClientDetailsServiceBuilder builder = clients.inMemory();
OAuth2ClientProperties[] clientProperties = securityProperties.getOauth2().getClients();
if(ArrayUtils.isNotEmpty(clientProperties)){
for (OAuth2ClientProperties client : clientProperties) {
builder.withClient(client.getClientId())
.secret(client.getClientSecret())
.accessTokenValiditySeconds(client.getAccessTokenValiditySeconds())
.authorizedGrantTypes("refresh_token","password") //支持哪些授权模式 token刷新和密码模式
.scopes("all","read","write") ; //相当于权限,配置了这个参数,请求里面可以不带scope参,如果带了参数,必须在配置的这个scope范围之内
}
}
}
demo application 配置属性
whale.security.oauth2.clients[0].clientId = whale
whale.security.oauth2.clients[0].clientSecret = 123456
whale.security.oauth2.clients[0].accessTokenValiditySeconds = 3600
测试
令牌的存储
我们的token令牌生成后,服务如果重启,令牌就会失效,因为我们的令牌是存储到内存里面的
解决 用redis存储令牌
redis好处就是我们不用维护数据表,且性能比较好
TokenStoreConfig
@Configuration
public class TokenStoreConfig {
@Autowired
private RedisConnectionFactory redisConnectionFactory;
@Bean
public TokenStore tokenStore(){
return new RedisTokenStore(redisConnectionFactory);
}
}
WhaleAuthenticationServiceConfig
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
// super.configure(endpoints);
// endpoints.authenticationManager(authenticationManager).userDetailsService(userDetailsService);
endpoints.tokenStore(tokenStore)
.authenticationManager(authenticationManager)
.userDetailsService(userDetailsService);
}
测试
报错
org.springframework.data.redis.connection.RedisConnection.set([B[B)V
解决
https://blog.csdn.net/smollsnail/article/details/78954225
-
spring-data-redis 2.0版本中set(String,String)被弃用了,要使用RedisConnection.stringCommands().set(…),所有我自定义一个RedisTokenStore,代码和RedisTokenStore一样,只是把所有conn.set(…)都换成conn…stringCommands().set(…)
-
最简单的方法就是直接在pom里面使用新版本如spring-security-oauth2–2.3.3.RELEASE,这样就能覆盖老的引用,新版本已经fix这个问题
我是直接在core 的pom中引入spring-security-oauth2–2.3.3.RELEASE的依赖
然而依赖中的版本号还是原有的版本号,没有变化
又重新回看了所有pom文件
发现我们的顶级pom中配置了dependencyManagement,它是优先级最高的依赖
并且如果我们的子pom文件中没有写依赖版本号,他会向上寻找在父pom 中的dependencyManagement中确定版本号
所有我把spring-security-oauth2–2.3.3.RELEASE的依赖直接写在dependencyManagement的第一行,优先级最高了
父pom
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.security.oauth</groupId>
<artifactId>spring-security-oauth2</artifactId>
<version>2.3.3.RELEASE</version>
</dependency>
`````````````````
最后回到测试 成功请求
redis里面也有了数据