SpringSecurityOAuth2.x的刷新token接⼝oauthtoken⾃定义修
参考资料:
Spring Security OAuth 2.x的刷新token⽅法⾃定义修改
使⽤maven依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
<version>1.3.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.security.oauth</groupId>
<artifactId>spring-security-oauth2</artifactId>
<version>2.0.9.RELEASE</version>
</dependency>
需求:
旧项⽬的其中⼀个前端页⾯会频繁调⽤token刷新⽅法。
刷新的token接⼝会返回⼀个新的token令牌值给前端,旧的token令牌作废掉。
刷新接⼝时Oauth2框架⾃带的接⼝
/oauth/token?access_token=8192be8f-4564-42cc-9f0f-7049be5ee085&grant_type=refresh_token&refresh_token=4f9ad8f9-885c-4cab-9f39-dc18887b526a&scope=read 请求参数:
access_token: af917135-211e-4dc4-8403-e436a414f7da
grant_type: refresh_token
refresh_token: 4c6f36e8-fb51-44d5-8f87-1ce7e55aa504
scope: read
返回数据:
access_token: "fcb856b1-c325-46cd-bad4-f5d423688a5d"
expires_in: 1799
refresh_token: "4c6f36e8-fb51-44d5-8f87-1ce7e55aa504"
scope: "read"
token_type: "bearer"
⽽前端页⾯可以打开新的窗⼝,这个新窗⼝也需要⽤到token访问后端。
到这个新窗⼝也触发到某⼀个前端页⾯的刷新token机制时,会调⽤token刷新接⼝。
导致新窗⼝的token值变更的,⽽旧窗⼝的token值没有变
旧窗⼝再次携带旧token请求后端时因为token⽆效,重定向跳转到的登录页⾯。
解决⽅法:
⽅法1、调⽤刷新token⽅法时,不进⾏token更新,返回原来的token内容。
可以避免两个窗⼝的token不⼀样导致跳转到登录页⾯。
本地调式代码后,发现刷新token的最终⽅法是调⽤ DefaultTokenServices类的刷新token⽅法
spring framework是什么框架的
OAuth2AccessToken refreshAccessToken(String refreshTokenValue, TokenRequest tokenRequest)
⽹上搜索资料,可以在配置时,⾃定义的tokenService代替默认实现类。
具体配置类,主要查看第8⾏,配置endpoints
1 @Configuration
2 @EnableAuthorizationServer
3public class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter {
4
5    @Override
6public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
7// ⾃定义tokenservice⽅法
8        kenServices(tokenServices(endpoints));
9        kenStore(tokenStore).userApprovalHandler(userApprovalHandler)
10//                .reuseRefreshTokens(false)
11                .authenticationManager(authenticationManager).userDetailsService(defaultUsersDetailsService);
12    }
13
14private MyTokenService tokenServices(AuthorizationServerEndpointsConfigurer endpoints) {
15        MyTokenService tokenServices = new MyTokenService();
16        tokenServices.setTokenStore(tokenStore);
17        tokenServices.setSupportRefreshToken(true);//⽀持刷新token
18        tokenServices.setReuseRefreshToken(true);
19        tokenServices.ClientDetailsService());
20        tokenServices.TokenEnhancer());
21        addUserDetailsService(tokenServices, defaultUsersDetailsService);
22return tokenServices;
23    }
24
25private void addUserDetailsService(MyTokenService tokenServices, UserDetailsService userDetailsService) {
26if (userDetailsService != null) {
27            PreAuthenticatedAuthenticationProvider provider = new PreAuthenticatedAuthenticationProvider();
28            provider.setPreAuthenticatedUserDetailsService(new UserDetailsByNameServiceWrapper<>(
29                    userDetailsService));
30            tokenServices.setAuthenticationManager(new ProviderManager(Arrays.asList(provider)));
31        }
32    }
⾃定义的类MyTokenService是复制 DefaultTokenService代码
修改了刷新token的⽅法
MyTokenService.java
1public class MyTokenService implements AuthorizationServerTokenServices, ResourceServerTokenServices,
2        ConsumerTokenServices, InitializingBean {
3/**
4    * 修改刷新token⽅法,只更新token时间,不更换旧的token值
5    * @param refreshTokenValue
6    * @param tokenRequest
7    * @return
8    * @throws AuthenticationException
9*/
10    @Override
11    @Transactional(noRollbackFor={InvalidTokenException.class, InvalidGrantException.class})
12public OAuth2AccessToken refreshAccessToken(String refreshTokenValue, TokenRequest tokenRequest)
13throws AuthenticationException {
14
15。。。前⾯没动
16
17        OAuth2AccessToken accessToken = createAccessToken(authentication, refreshToken);
18// 保留token原值
19        ((DefaultOAuth2AccessToken)accessToken).RequestParameters().get("access_token"));
20        tokenStore.storeAccessToken(accessToken, authentication);
21if (!reuseRefreshToken) {
22            tokenStore.storeRefreshToken(refreshToken, authentication);
23        }
24return accessToken;
25    }
重新启动项⽬,刷新token接⼝调⽤后,返回的还是原来的token值

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。