SaasAuthCenterController.java 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. package com.persagy.account.controller;
  2. import java.io.UnsupportedEncodingException;
  3. import java.util.Map;
  4. import java.util.concurrent.TimeUnit;
  5. import org.apache.commons.collections4.map.HashedMap;
  6. import org.springframework.beans.factory.annotation.Autowired;
  7. import org.springframework.data.redis.core.RedisTemplate;
  8. import org.springframework.validation.annotation.Validated;
  9. import org.springframework.web.bind.annotation.RequestBody;
  10. import org.springframework.web.bind.annotation.RequestMapping;
  11. import org.springframework.web.bind.annotation.RequestMethod;
  12. import org.springframework.web.bind.annotation.RestController;
  13. import com.alibaba.fastjson.JSONObject;
  14. import com.persagy.account.config.ApplicationProperties;
  15. import com.persagy.account.manage.SaasAuthHandler;
  16. import com.persagy.account.pojo.vo.thirty.SaasCodeTokenVO;
  17. import com.persagy.account.pojo.vo.thirty.SaasCodeVO;
  18. import com.persagy.common.constant.SaasCommonConstant;
  19. import com.persagy.common.enums.ResponseCode;
  20. import com.persagy.common.utils.ResponseResult;
  21. import com.persagy.common.utils.ResponseResultUtil;
  22. import com.persagy.common.utils.StringUtil;
  23. import com.persagy.security.util.BouncycastleCipher;
  24. import com.persagy.security.util.SecureAES;
  25. import cn.hutool.core.util.BooleanUtil;
  26. import cn.hutool.core.util.IdUtil;
  27. import cn.hutool.crypto.digest.DigestAlgorithm;
  28. import cn.hutool.crypto.digest.MD5;
  29. import io.swagger.annotations.Api;
  30. import io.swagger.annotations.ApiOperation;
  31. /**
  32. * 三方授权中心
  33. * @version 1.0.0
  34. * @company persagy
  35. * @author zhangqiankun
  36. * @date 2021年4月27日 下午3:08:16
  37. */
  38. @RestController
  39. @Api(tags = "授权管理")
  40. @RequestMapping(value = "/authCenter", method = RequestMethod.POST)
  41. public class SaasAuthCenterController {
  42. private static MD5 md5 = MD5.create();
  43. @Autowired
  44. private SaasAuthHandler saasAuthHandler;
  45. @Autowired
  46. private ApplicationProperties properties;
  47. //@Autowired
  48. //private ISaasAccountService saasAccountService;
  49. @Autowired
  50. private BouncycastleCipher bouncycastleCipher;
  51. @Autowired
  52. private RedisTemplate<String, Object> redisTemplate;
  53. /**
  54. * 申请授权码
  55. */
  56. @ApiOperation(value = "申请授权码")
  57. @RequestMapping(value = "code")
  58. public ResponseResult getCode(@RequestBody @Validated SaasCodeVO model) {
  59. String code = this.saasAuthHandler.getCode(model.getClientId(), model.getRedirectUrl(), null, null, null);
  60. Map<String, String> result = new HashedMap<String, String>(1);
  61. result.put("code", code);
  62. return ResponseResultUtil.successResult(result);
  63. }
  64. /**
  65. * 根据授权码获取token
  66. * @throws UnsupportedEncodingException
  67. */
  68. @ApiOperation(value = "根据授权码获取token")
  69. @RequestMapping(value = "codeToken")
  70. public ResponseResult getCodeToken(@RequestBody @Validated SaasCodeTokenVO model) throws UnsupportedEncodingException {
  71. // 验证客户端ID是否存在
  72. Boolean member = this.redisTemplate.opsForSet().isMember(SaasCommonConstant.SAAS_CLIENT_ID_REDIS_KEY, model.getClientId());
  73. if (!BooleanUtil.isTrue(member)) {
  74. return ResponseResultUtil.errorResult(ResponseCode.A0001.getCode(), ResponseCode.A0001.getDesc());
  75. }
  76. // 验证是否授权码存在
  77. String code = (String) this.redisTemplate.opsForHash().get(model.getClientId(), SaasCommonConstant.CODE_REDIS_HASH_KEY);
  78. if (StringUtil.isBlank(code)) {
  79. return ResponseResultUtil.errorResult(ResponseCode.A0301.getCode(), ResponseCode.A0301.getDesc());
  80. }
  81. if (!model.getCode().equals(code)) {
  82. return ResponseResultUtil.errorResult(ResponseCode.A0303.getCode(), ResponseCode.A0303.getDesc());
  83. }
  84. // 判断token是否已存在
  85. long expire = Long.parseLong(this.properties.getTokenExpire());
  86. String accountId = (String) this.redisTemplate.opsForHash().get(model.getClientId(), SaasCommonConstant.ACCOUNT_ID_REDIS_HASH_KEY);
  87. if (StringUtil.isBlank(accountId)) {
  88. return ResponseResultUtil.errorResult(ResponseCode.A0402.getCode(), ResponseCode.A0402.getDesc());
  89. }
  90. // token放入redis,key-accountId
  91. String token = (String) this.redisTemplate.opsForValue().get(accountId);
  92. if (StringUtil.isBlank(token)) {
  93. token = this.bouncycastleCipher.encrypt(this.getAccessToken(code), DigestAlgorithm.MD5);
  94. this.redisTemplate.opsForValue().set(accountId, token, expire, TimeUnit.SECONDS);
  95. } else {
  96. this.redisTemplate.expire(accountId, expire, TimeUnit.SECONDS);
  97. }
  98. // MD5生成 refreshToken,放进hash存储
  99. String refreshToken = md5.digestHex(this.getRefreshToken());
  100. this.redisTemplate.opsForHash().put(model.getClientId(), SaasCommonConstant.REFRESH_TOKEN_REDIS_HASH_KEY, refreshToken);
  101. // AES加密出账号信息所需字段,组合为token
  102. SecureAES aes = new SecureAES(properties.getAesKey(), properties.getAesIv());
  103. String tokenPrefix = aes.encrypt(this.getTokenPrefix(model.getClientId(), accountId));
  104. token = tokenPrefix + SaasCommonConstant.POINT_JOIN_SYMBOL + token;
  105. Map<String, Object> map = new HashedMap<String, Object>();
  106. map.put("refreshToken", refreshToken);
  107. map.put("accessToken", token);
  108. map.put("expire", expire);
  109. return ResponseResultUtil.successResult(map);
  110. }
  111. /**
  112. * 这里的数据,均为登录时指定,为登录时指定的
  113. *
  114. * @param clientId
  115. * @param accountId
  116. * @return
  117. */
  118. private String getTokenPrefix(String clientId, String accountId) {
  119. String appId = (String) this.redisTemplate.opsForHash().get(clientId, SaasCommonConstant.APP_ID_REDIS_HASH_KEY);
  120. String groupCode = (String) this.redisTemplate.opsForHash().get(clientId, SaasCommonConstant.GROUP_CODE_REDIS_HASH_KEY);
  121. JSONObject result = new JSONObject();
  122. result.put(SaasCommonConstant.ACCOUNT_ID, accountId);
  123. result.put(SaasCommonConstant.GROUP_CODE, groupCode);
  124. result.put(SaasCommonConstant.APP_ID, appId);
  125. return result.toJSONString();
  126. }
  127. /**
  128. * 根据授权码组合token原信息
  129. * @param code
  130. * @return
  131. */
  132. private String getAccessToken(String code) {
  133. JSONObject object = new JSONObject();
  134. object.put("code", code);
  135. return object.toJSONString();
  136. }
  137. /**
  138. * 获取refreshToken
  139. * @param code
  140. * @return
  141. */
  142. private String getRefreshToken() {
  143. JSONObject object = new JSONObject();
  144. object.put("time", System.currentTimeMillis());
  145. object.put("state", IdUtil.fastSimpleUUID());
  146. return object.toJSONString();
  147. }
  148. }