Spring Security OAuth 个性化token

个性化Token 目的

  • 默认通过调用 /oauth/token 返回的报文格式包含以下参数

    { "access_token": "e6669cdf-b6cd-43fe-af5c-f91a65041382", "token_type": "bearer", "refresh_token": "da91294d-446c-4a89-bdcf-88aee15a75e8", "expires_in": 43199, "scope": "server" }

并没包含用户的业务信息比如用户信息、租户信息等。

  • 扩展生成包含业务信息(如下),避免系统多次调用,直接可以通过认证接口获取到用户信息等,大大提高系统性能

    { "access_token":"a6f3b6d6-93e6-4eb8-a97d-3ae72240a7b0", "token_type":"bearer", "refresh_token":"710ab162-a482-41cd-8bad-26456af38e4f", "expires_in":42396, "scope":"server", "tenant_id":1, "license":"made by pigx", "dept_id":1, "user_id":1, "username":"admin" }

密码模式生成Token 源码解析

image

​ 主页参考红框部分

  • ResourceOwnerPasswordTokenGranter (密码模式)根据用户的请求信息,进行认证得到当前用户上下文信息

    1protected OAuth2Authentication getOAuth2Authentication(ClientDetails client, TokenRequest tokenRequest) { 2 Map<String, String> parameters = new LinkedHashMap<String, String>(tokenRequest.getRequestParameters()); 3 String username = parameters.get("username"); 4 String password = parameters.get("password"); 5 // Protect from downstream leaks of password 6 parameters.remove("password"); 7 Authentication userAuth = new UsernamePasswordAuthenticationToken(username, password); 8 ((AbstractAuthenticationToken) userAuth).setDetails(parameters); 9 10 userAuth = authenticationManager.authenticate(userAuth); 11 12 OAuth2Request storedOAuth2Request = getRequestFactory().createOAuth2Request(client, tokenRequest); 13 return new OAuth2Authentication(storedOAuth2Request, userAuth); 14}
  • 然后调用AbstractTokenGranter.getAccessToken() 获取OAuth2AccessToken

    1protected OAuth2AccessToken getAccessToken(ClientDetails client, TokenRequest tokenRequest) { 2 return tokenServices.createAccessToken(getOAuth2Authentication(client, tokenRequest)); 3}
  • 默认使用DefaultTokenServices来获取token

    1public OAuth2AccessToken createAccessToken(OAuth2Authentication authentication) throws AuthenticationException { 2 3 ... 一系列判断 ,合法性、是否过期等判断 4 OAuth2AccessToken accessToken = createAccessToken(authentication, refreshToken); 5 tokenStore.storeAccessToken(accessToken, authentication); 6 // In case it was modified 7 refreshToken = accessToken.getRefreshToken(); 8 if (refreshToken != null) { 9 tokenStore.storeRefreshToken(refreshToken, authentication); 10 } 11 return accessToken; 12} 13
  • createAccessToken 核心逻辑

    1// 默认刷新token 的有效期 2private int refreshTokenValiditySeconds = 60 * 60 * 24 * 30; // default 30 days. 3// 默认token 的有效期 4private int accessTokenValiditySeconds = 60 * 60 * 12; // default 12 hours. 5 6private OAuth2AccessToken createAccessToken(OAuth2Authentication authentication, OAuth2RefreshToken refreshToken) { 7 DefaultOAuth2AccessToken token = new DefaultOAuth2AccessToken(uuid); 8 token.setExpiration(Date) 9 token.setRefreshToken(refreshToken); 10 token.setScope(authentication.getOAuth2Request().getScope()); 11 return accessTokenEnhancer != null ? accessTokenEnhancer.enhance(token, authentication) : token; 12}

    如上代码,在拼装好token对象后会调用认证服务器配置TokenEnhancer( 增强器) 来对默认的token进行增强。

  • TokenEnhancer.enhance 通过上下文中的用户信息来个性化Token

    1public OAuth2AccessToken enhance(OAuth2AccessToken accessToken, OAuth2Authentication authentication) { 2 final Map<String, Object> additionalInfo = new HashMap<>(8); 3 PigxUser pigxUser = (PigxUser) authentication.getUserAuthentication().getPrincipal(); 4 additionalInfo.put("user_id", pigxUser.getId()); 5 additionalInfo.put("username", pigxUser.getUsername()); 6 additionalInfo.put("dept_id", pigxUser.getDeptId()); 7 additionalInfo.put("tenant_id", pigxUser.getTenantId()); 8 additionalInfo.put("license", SecurityConstants.PIGX_LICENSE); 9 ((DefaultOAuth2AccessToken) accessToken).setAdditionalInformation(additionalInfo); 10 return accessToken; 11}

基于pig 看下最终的实现效果

Pig 基于Spring Cloud、oAuth2.0开发基于Vue前后分离的开发平台,支持账号、短信、SSO等多种登录,提供配套视频开发教程。
https://gitee.com/log4j/pig

image

点赞
收藏

评论区

加载中...

相关推荐

MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1

文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s

Oracle 分组与拼接字符串同时使用

SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(

MySQL部分从库上面因为大量的临时表tmp_table造成慢查询

背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_

皕杰报表之UUID

​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为

手写Java HashMap源码

HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22

2020年前端实用代码段,为你的工作保驾护航

有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )

Spring Security OAuth 个性化token - HelloWorld