资源服务器校验token
资源服务器校验token
基于token
1.远程调用认证服务验证Token
认证服务需要在AuthorizationServerConfigurerAdapter继承类中配置中增加以下代码,允许资源服务调用校验token的接口。
//配置端点的权限
@Override
public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
// 所有人可访问 /oauth/token_key 后面要获取公钥, 默认拒绝访问
security.tokenKeyAccess("permitAll()");
// 认证后可访问 /oauth/check_token , 默认拒绝访问
security.checkTokenAccess("isAuthenticated()");
security.allowFormAuthenticationForClients();
}
在资源服务的配置文件做如下配置:
//这个主要就是当前资源服务器的一些配置
@Override
public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
resources.resourceId(RESOURCE_ID).tokenStore(tokenStore)
.tokenServices(tokenService());
}
public ResourceServerTokenServices tokenService(){
// 远程认证服务器进行校验 token 是否有效
RemoteTokenServices service = new RemoteTokenServices();
// 请求认证服务器校验的地址,默认情况 这个地址在认证服务器它是拒绝访问,要设置为认证通过可访问
service.setCheckTokenEndpointUrl("http://localhost:8090/auth/oauth/check_token");
service.setClientId("dalianpai-pc");
service.setClientSecret("dalianpai");
return service;
}
断点的结果如图
我断点看了一下,如果设置成远程调用的话,每个接口请求都会远程请求check_token这个接口,有一定的网络开销,不推荐使用
2.本地
在资源服务ResourceServerConfig配置了token相关的Bean,在服务启动时完成初始化Bean,不需要去调用认证服务获取相关算法和签名密钥,启动不依赖于认证服务。
@Override
public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
resources.resourceId(RESOURCE_ID).tokenStore(tokenStore)
.tokenServices(tokenService());
}
// public ResourceServerTokenServices tokenService(){
// // 远程认证服务器进行校验 token 是否有效
// RemoteTokenServices service = new RemoteTokenServices();
// // 请求认证服务器校验的地址,默认情况 这个地址在认证服务器它是拒绝访问,要设置为认证通过可访问
// service.setCheckTokenEndpointUrl("http://localhost:8090/auth/oauth/check_token");
// service.setClientId("dalianpai-pc");
// service.setClientSecret("dalianpai");
// return service;
// }
public DefaultTokenServices tokenService(){
DefaultTokenServices service = new DefaultTokenServices();
service.setTokenStore(tokenStore);
return service;
}
断点的图,不走远程调用,会直接走jdbc去查,当然也可以设置成es的。
3.资源服务启动调用/oauth/token_key接口初始化tokenstore
这个个人尝试了没有成功,看到的博客如下:
https://blog.csdn.net/u012833261/article/details/115709381
基于jwt
在认证服务器
// JWT 签名秘钥
private static final String SIGNING_KEY = "dalianpai-key";
@Bean
public JwtAccessTokenConverter jwtAccessTokenConverter(){
JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
KeyStoreKeyFactory keyFactory = new KeyStoreKeyFactory(new ClassPathResource("oauth2.jks"), "oauth2".toCharArray());
converter.setKeyPair(keyFactory.getKeyPair("oauth2"));
//converter.setSigningKey(SIGNING_KEY);
return converter;
}
@Bean
public TokenStore tokenStore(){
return new JwtTokenStore(jwtAccessTokenConverter());
}
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
// 密码模式要设置认证管理器
endpoints.authenticationManager(authenticationManager);
// 刷新令牌获取新令牌时需要
endpoints.userDetailsService(customUserDetailsService);
// 令牌管理策略
endpoints.tokenStore(tokenStore).accessTokenConverter(jwtAccessTokenConverter)
// 授权码管理策略,针对授权码模式有效,会将授权码放到 auth_code 表,授权后就会删除它
endpoints.authorizationCodeServices(jdbcAuthorizationCodeServices());
}
在资源服务器
// JWT 签名秘钥
private static final String SIGNING_KEY = "dalianpai-key";
@Bean
public JwtAccessTokenConverter jwtAccessTokenConverter() {
JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
ClassPathResource classPathResource = new ClassPathResource("public.txt");
String publicKey = null;
try {
publicKey = IOUtils.toString(classPathResource.getInputStream(), "UTF-8");
System.out.println("publicKey:" + publicKey);
} catch (IOException e) {
e.printStackTrace();
}
converter.setVerifierKey(publicKey);
return converter;
// converter.setSigningKey(SIGNING_KEY);
// return converter;
}
@Bean
public TokenStore tokenStore() {
return new JwtTokenStore(jwtAccessTokenConverter());
}
//这个主要就是当前资源服务器的一些配置
@Override
public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
resources.resourceId(RESOURCE_ID).tokenStore(tokenStore);
}