SocialTokenGranter.java 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. /*
  2. * Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
  3. *
  4. * Redistribution and use in source and binary forms, with or without
  5. * modification, are permitted provided that the following conditions are met:
  6. *
  7. * Redistributions of source code must retain the above copyright notice,
  8. * this list of conditions and the following disclaimer.
  9. * Redistributions in binary form must reproduce the above copyright
  10. * notice, this list of conditions and the following disclaimer in the
  11. * documentation and/or other materials provided with the distribution.
  12. * Neither the name of the dreamlu.net developer nor the names of its
  13. * contributors may be used to endorse or promote products derived from
  14. * this software without specific prior written permission.
  15. * Author: Chill 庄骞 (smallchill@163.com)
  16. */
  17. package org.springblade.auth.granter;
  18. import me.zhyd.oauth.model.AuthCallback;
  19. import me.zhyd.oauth.model.AuthResponse;
  20. import me.zhyd.oauth.model.AuthUser;
  21. import me.zhyd.oauth.request.AuthRequest;
  22. import org.springblade.auth.constant.AuthConstant;
  23. import org.springblade.auth.service.BladeUserDetails;
  24. import org.springblade.auth.utils.TokenUtil;
  25. import org.springblade.core.social.props.SocialProperties;
  26. import org.springblade.core.social.utils.SocialUtil;
  27. import org.springblade.core.tool.api.R;
  28. import org.springblade.core.tool.support.Kv;
  29. import org.springblade.core.tool.utils.BeanUtil;
  30. import org.springblade.core.tool.utils.Func;
  31. import org.springblade.core.tool.utils.WebUtil;
  32. import org.springblade.system.user.entity.User;
  33. import org.springblade.system.user.entity.UserInfo;
  34. import org.springblade.system.user.entity.UserOauth;
  35. import org.springblade.system.user.feign.IUserClient;
  36. import org.springframework.security.authentication.AbstractAuthenticationToken;
  37. import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
  38. import org.springframework.security.core.Authentication;
  39. import org.springframework.security.core.authority.AuthorityUtils;
  40. import org.springframework.security.oauth2.common.exceptions.InvalidGrantException;
  41. import org.springframework.security.oauth2.provider.*;
  42. import org.springframework.security.oauth2.provider.token.AbstractTokenGranter;
  43. import org.springframework.security.oauth2.provider.token.AuthorizationServerTokenServices;
  44. import javax.servlet.http.HttpServletRequest;
  45. import java.util.LinkedHashMap;
  46. import java.util.Map;
  47. import java.util.Objects;
  48. /**
  49. * 第三方登录认证类
  50. *
  51. * @author Chill
  52. */
  53. public class SocialTokenGranter extends AbstractTokenGranter {
  54. private static final String GRANT_TYPE = "social";
  55. private static final Integer AUTH_SUCCESS_CODE = 2000;
  56. private final IUserClient userClient;
  57. private final SocialProperties socialProperties;
  58. protected SocialTokenGranter(AuthorizationServerTokenServices tokenServices, ClientDetailsService clientDetailsService, OAuth2RequestFactory requestFactory, IUserClient userClient, SocialProperties socialProperties) {
  59. super(tokenServices, clientDetailsService, requestFactory, GRANT_TYPE);
  60. this.userClient = userClient;
  61. this.socialProperties = socialProperties;
  62. }
  63. @Override
  64. protected OAuth2Authentication getOAuth2Authentication(ClientDetails client, TokenRequest tokenRequest) {
  65. // 请求头租户信息
  66. HttpServletRequest request = WebUtil.getRequest();
  67. String tenantId = Func.toStr(request.getHeader(TokenUtil.TENANT_HEADER_KEY), TokenUtil.DEFAULT_TENANT_ID);
  68. Map<String, String> parameters = new LinkedHashMap<>(tokenRequest.getRequestParameters());
  69. // 开放平台来源
  70. String sourceParameter = parameters.get("source");
  71. // 匹配是否有别名定义
  72. String source = socialProperties.getAlias().getOrDefault(sourceParameter, sourceParameter);
  73. // 开放平台授权码
  74. String code = parameters.get("code");
  75. // 开放平台状态吗
  76. String state = parameters.get("state");
  77. // 获取开放平台授权数据
  78. AuthRequest authRequest = SocialUtil.getAuthRequest(source, socialProperties);
  79. AuthCallback authCallback = new AuthCallback();
  80. authCallback.setCode(code);
  81. authCallback.setState(state);
  82. AuthResponse authResponse = authRequest.login(authCallback);
  83. AuthUser authUser;
  84. if (authResponse.getCode() == AUTH_SUCCESS_CODE) {
  85. authUser = (AuthUser) authResponse.getData();
  86. } else {
  87. throw new InvalidGrantException("social grant failure, auth response is not success");
  88. }
  89. // 组装数据
  90. UserOauth userOauth = Objects.requireNonNull(BeanUtil.copy(authUser, UserOauth.class));
  91. userOauth.setSource(authUser.getSource());
  92. userOauth.setTenantId(tenantId);
  93. userOauth.setUuid(authUser.getUuid());
  94. // 远程调用,获取认证信息
  95. R<UserInfo> result = userClient.userAuthInfo(userOauth);
  96. BladeUserDetails bladeUserDetails;
  97. if (result.isSuccess()) {
  98. User user = result.getData().getUser();
  99. Kv detail = result.getData().getDetail();
  100. if (user == null || user.getId() == null) {
  101. throw new InvalidGrantException("social grant failure, user is null");
  102. }
  103. bladeUserDetails = new BladeUserDetails(user.getId(), user.getPhone(),
  104. tenantId, result.getData().getOauthId(), user.getName(), user.getRealName(), user.getDeptId(), user.getPostId(), user.getRoleId(), Func.join(result.getData().getRoles()), Func.toStr(userOauth.getAvatar(), TokenUtil.DEFAULT_AVATAR),
  105. userOauth.getUsername(), AuthConstant.ENCRYPT + user.getPassword(), detail, true, true, true, true,
  106. AuthorityUtils.commaSeparatedStringToAuthorityList(Func.join(result.getData().getRoles())));
  107. } else {
  108. throw new InvalidGrantException("social grant failure, feign client return error");
  109. }
  110. // 组装认证数据,关闭密码校验
  111. Authentication userAuth = new UsernamePasswordAuthenticationToken(bladeUserDetails, null, bladeUserDetails.getAuthorities());
  112. ((AbstractAuthenticationToken) userAuth).setDetails(parameters);
  113. OAuth2Request storedOAuth2Request = getRequestFactory().createOAuth2Request(client, tokenRequest);
  114. // 返回 OAuth2Authentication
  115. return new OAuth2Authentication(storedOAuth2Request, userAuth);
  116. }
  117. }