PigxUserDetailsServiceImpl.java 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. /*
  2. *
  3. * Copyright (c) 2018-2025, lengleng All rights reserved.
  4. *
  5. * Redistribution and use in source and binary forms, with or without
  6. * modification, are permitted provided that the following conditions are met:
  7. *
  8. * Redistributions of source code must retain the above copyright notice,
  9. * this list of conditions and the following disclaimer.
  10. * Redistributions in binary form must reproduce the above copyright
  11. * notice, this list of conditions and the following disclaimer in the
  12. * documentation and/or other materials provided with the distribution.
  13. * Neither the name of the pig4cloud.com developer nor the names of its
  14. * contributors may be used to endorse or promote products derived from
  15. * this software without specific prior written permission.
  16. * Author: lengleng (wangiegie@gmail.com)
  17. *
  18. */
  19. package com.pig4cloud.pigx.auth.service;
  20. import cn.hutool.core.util.ArrayUtil;
  21. import cn.hutool.core.util.StrUtil;
  22. import cn.hutool.json.JSONUtil;
  23. import com.pig4cloud.pigx.admin.api.dto.UserInfo;
  24. import com.pig4cloud.pigx.admin.api.entity.SysUser;
  25. import com.pig4cloud.pigx.admin.api.feign.RemoteUserService;
  26. import com.pig4cloud.pigx.common.core.constant.CommonConstant;
  27. import com.pig4cloud.pigx.common.core.constant.SecurityConstants;
  28. import com.pig4cloud.pigx.common.core.constant.enums.EnumLoginType;
  29. import com.pig4cloud.pigx.common.core.util.R;
  30. import com.pig4cloud.pigx.common.security.social.WxSocialConfig;
  31. import com.pig4cloud.pigx.common.security.util.PigxUserDetailsService;
  32. import lombok.AllArgsConstructor;
  33. import lombok.extern.slf4j.Slf4j;
  34. import org.springframework.security.core.GrantedAuthority;
  35. import org.springframework.security.core.authority.AuthorityUtils;
  36. import org.springframework.security.core.userdetails.User;
  37. import org.springframework.security.core.userdetails.UserDetails;
  38. import org.springframework.security.core.userdetails.UsernameNotFoundException;
  39. import org.springframework.stereotype.Service;
  40. import org.springframework.web.client.RestTemplate;
  41. import java.util.Arrays;
  42. import java.util.Collection;
  43. import java.util.HashSet;
  44. import java.util.Set;
  45. /**
  46. * 用户详细信息
  47. *
  48. * @author lengleng
  49. */
  50. @Slf4j
  51. @Service
  52. @AllArgsConstructor
  53. public class PigxUserDetailsServiceImpl implements PigxUserDetailsService {
  54. private static final String WX_AUTHORIZATION_CODE_URL = "https://api.weixin.qq.com/sns/oauth2/access_token" +
  55. "?appid=%s&secret=%s&code=%s&grant_type=authorization_code";
  56. private static final String REGEX = "@";
  57. private final RestTemplate restTemplate;
  58. private final RemoteUserService remoteUserService;
  59. private final WxSocialConfig wxSocialConfig;
  60. /**
  61. * 用户密码登录
  62. *
  63. * @param username 用户名
  64. * @return
  65. * @throws UsernameNotFoundException
  66. */
  67. @Override
  68. public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
  69. R<UserInfo> result = remoteUserService.info(username, SecurityConstants.FROM_IN);
  70. return getUserDetails(result);
  71. }
  72. /**
  73. * 根据社交登录code 登录
  74. *
  75. * @param inStr TYPE@CODE
  76. * @return UserDetails
  77. * @throws UsernameNotFoundException
  78. */
  79. @Override
  80. public UserDetails loadUserBySocial(String inStr) throws UsernameNotFoundException {
  81. String[] codeStr = inStr.split(REGEX);
  82. String type = codeStr[0];
  83. String code = codeStr[1];
  84. R<UserInfo> userInfo = null;
  85. if (EnumLoginType.WECHAT.getType().equals(type)) {
  86. String url = String.format(WX_AUTHORIZATION_CODE_URL
  87. , wxSocialConfig.getAppid(), wxSocialConfig.getSecret(), code);
  88. String result = restTemplate.getForObject(url, String.class);
  89. log.warn("微信响应报文:{}", result);
  90. Object obj = JSONUtil.parseObj(result).get("openid");
  91. if (obj != null) {
  92. userInfo = remoteUserService.social(EnumLoginType.WECHAT.getType(), obj.toString());
  93. }
  94. }
  95. return getUserDetails(userInfo);
  96. }
  97. /**
  98. * 构建userdetails
  99. *
  100. * @param result 用户信息
  101. * @return
  102. */
  103. private UserDetails getUserDetails(R<UserInfo> result) {
  104. if (result == null || result.getData() == null) {
  105. throw new UsernameNotFoundException("用户不存在");
  106. }
  107. UserInfo info = result.getData();
  108. Set<String> dbAuthsSet = new HashSet<>();
  109. if (ArrayUtil.isNotEmpty(info.getRoles())) {
  110. // 获取角色
  111. Arrays.stream(info.getRoles()).forEach(role -> dbAuthsSet.add(SecurityConstants.ROLE + role));
  112. // 获取资源
  113. dbAuthsSet.addAll(Arrays.asList(info.getPermissions()));
  114. }
  115. Collection<? extends GrantedAuthority> authorities
  116. = AuthorityUtils.createAuthorityList(dbAuthsSet.toArray(new String[0]));
  117. SysUser user = info.getSysUser();
  118. boolean enabled = StrUtil.equals(user.getDelFlag(), CommonConstant.STATUS_NORMAL);
  119. // 构造security用户
  120. return new User(info.getSysUser().getUsername(), SecurityConstants.BCRYPT + user.getPassword(), enabled,
  121. true, true, true, authorities);
  122. }
  123. }