From 4350a2c3426145e20035b495e4afe29de1b5a4c2 Mon Sep 17 00:00:00 2001 From: hongawen <83944980@qq.com> Date: Thu, 15 Jun 2023 16:01:50 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../config/AuthorizationServerConfig.java | 12 +- .../njcn/auth/config/WebSecurityConfig.java | 36 +- .../njcn/auth/controller/AuthController.java | 12 +- .../CaptchaTokenGranter.java | 13 +- .../PreAuthenticatedUserDetailsService.java | 5 +- .../security/granter/SmsTokenGranter.java | 92 +++++ .../AbstractSmsAuthenticationProvider.java | 337 ++++++++++++++++++ .../Sm4AuthenticationProvider.java | 2 +- .../provider/SmsAuthenticationProvider.java | 73 ++++ .../token/SmsCodeAuthenticationToken.java | 62 ++++ .../service/CustomUserDetailsService.java | 28 ++ .../auth/service/UserDetailsServiceImpl.java | 16 +- pqs-auth/src/test/java/AuthTest.java | 6 +- .../pojo/constant/SecurityConstants.java | 2 + .../njcn/redis/pojo/enums/RedisKeyEnum.java | 5 + .../com/njcn/user/api/UserFeignClient.java | 11 + .../UserFeignClientFallbackFactory.java | 6 + .../com/njcn/user/enums/UserResponseEnum.java | 1 + .../com/njcn/user/pojo/po/AuthClient.java | 4 +- .../njcn/user/controller/UserController.java | 18 + .../com/njcn/user/service/IUserService.java | 10 + .../user/service/impl/UserServiceImpl.java | 11 + 22 files changed, 720 insertions(+), 42 deletions(-) rename pqs-auth/src/main/java/com/njcn/auth/security/{extension/captcha => granter}/CaptchaTokenGranter.java (90%) rename pqs-auth/src/main/java/com/njcn/auth/security/{extension/refresh => granter}/PreAuthenticatedUserDetailsService.java (91%) create mode 100644 pqs-auth/src/main/java/com/njcn/auth/security/granter/SmsTokenGranter.java create mode 100644 pqs-auth/src/main/java/com/njcn/auth/security/provider/AbstractSmsAuthenticationProvider.java rename pqs-auth/src/main/java/com/njcn/auth/security/{sm4 => provider}/Sm4AuthenticationProvider.java (98%) create mode 100644 pqs-auth/src/main/java/com/njcn/auth/security/provider/SmsAuthenticationProvider.java create mode 100644 pqs-auth/src/main/java/com/njcn/auth/security/token/SmsCodeAuthenticationToken.java create mode 100644 pqs-auth/src/main/java/com/njcn/auth/service/CustomUserDetailsService.java diff --git a/pqs-auth/src/main/java/com/njcn/auth/config/AuthorizationServerConfig.java b/pqs-auth/src/main/java/com/njcn/auth/config/AuthorizationServerConfig.java index 3e69c8402..502beadb2 100644 --- a/pqs-auth/src/main/java/com/njcn/auth/config/AuthorizationServerConfig.java +++ b/pqs-auth/src/main/java/com/njcn/auth/config/AuthorizationServerConfig.java @@ -5,8 +5,9 @@ import cn.hutool.core.util.StrUtil; import com.njcn.auth.filter.CustomClientCredentialsTokenEndpointFilter; import com.njcn.auth.pojo.bo.BusinessUser; import com.njcn.auth.security.clientdetails.ClientDetailsServiceImpl; -import com.njcn.auth.security.extension.captcha.CaptchaTokenGranter; -import com.njcn.auth.security.extension.refresh.PreAuthenticatedUserDetailsService; +import com.njcn.auth.security.granter.CaptchaTokenGranter; +import com.njcn.auth.security.granter.PreAuthenticatedUserDetailsService; +import com.njcn.auth.security.granter.SmsTokenGranter; import com.njcn.auth.service.UserDetailsServiceImpl; import com.njcn.common.pojo.constant.SecurityConstants; import com.njcn.common.pojo.enums.auth.ClientEnum; @@ -89,10 +90,11 @@ public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdap granterList.add(new CaptchaTokenGranter(endpoints.getTokenServices(), endpoints.getClientDetailsService(), endpoints.getOAuth2RequestFactory(), authenticationManager, redisUtil )); - + // 添加短信授权模式授权者 + granterList.add(new SmsTokenGranter(endpoints.getTokenServices(), endpoints.getClientDetailsService(), + endpoints.getOAuth2RequestFactory(), authenticationManager, redisUtil + )); //todo... 后续可以扩展更多授权模式,比如:微信小程序、移动app - - CompositeTokenGranter compositeTokenGranter = new CompositeTokenGranter(granterList); endpoints.authenticationManager(authenticationManager) .accessTokenConverter(jwtAccessTokenConverter()) diff --git a/pqs-auth/src/main/java/com/njcn/auth/config/WebSecurityConfig.java b/pqs-auth/src/main/java/com/njcn/auth/config/WebSecurityConfig.java index edeb8f34a..b04da8287 100644 --- a/pqs-auth/src/main/java/com/njcn/auth/config/WebSecurityConfig.java +++ b/pqs-auth/src/main/java/com/njcn/auth/config/WebSecurityConfig.java @@ -1,6 +1,7 @@ package com.njcn.auth.config; -import com.njcn.auth.security.sm4.Sm4AuthenticationProvider; +import com.njcn.auth.security.provider.Sm4AuthenticationProvider; +import com.njcn.auth.security.provider.SmsAuthenticationProvider; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.context.annotation.Bean; @@ -29,6 +30,8 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter { private final Sm4AuthenticationProvider sm4AuthenticationProvider; + private final SmsAuthenticationProvider smsAuthenticationProvider; + @Override protected void configure(HttpSecurity http) throws Exception { @@ -63,21 +66,6 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter { - - /** - * 用户名密码认证授权提供者 - * - * @return - */ - @Bean - public DaoAuthenticationProvider daoAuthenticationProvider() { - DaoAuthenticationProvider provider = new DaoAuthenticationProvider(); - provider.setUserDetailsService(sysUserDetailsService); - provider.setPasswordEncoder(passwordEncoder()); - provider.setHideUserNotFoundExceptions(false); // 是否隐藏用户不存在异常,默认:true-隐藏;false-抛出异常; - return provider; - } - /** * 重写父类自定义AuthenticationManager 将provider注入进去 * 当然我们也可以考虑不重写 在父类的manager里面注入provider @@ -85,10 +73,24 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter { @Bean @Override protected AuthenticationManager authenticationManager(){ - return new ProviderManager(sm4AuthenticationProvider); + return new ProviderManager(sm4AuthenticationProvider,smsAuthenticationProvider); } + + /** + * 用户名密码认证授权提供者 + */ + @Bean + public DaoAuthenticationProvider daoAuthenticationProvider() { + DaoAuthenticationProvider provider = new DaoAuthenticationProvider(); + provider.setUserDetailsService(sysUserDetailsService); + provider.setPasswordEncoder(passwordEncoder()); + // 是否隐藏用户不存在异常,默认:true-隐藏;false-抛出异常; + provider.setHideUserNotFoundExceptions(false); + return provider; + } + /** * 密码编码器 *
diff --git a/pqs-auth/src/main/java/com/njcn/auth/controller/AuthController.java b/pqs-auth/src/main/java/com/njcn/auth/controller/AuthController.java
index ef1fbc0bf..e49cd2e5d 100644
--- a/pqs-auth/src/main/java/com/njcn/auth/controller/AuthController.java
+++ b/pqs-auth/src/main/java/com/njcn/auth/controller/AuthController.java
@@ -75,15 +75,19 @@ public class AuthController extends BaseController {
@ApiImplicitParam(name = SecurityConstants.USERNAME, value = "登录用户名"),
@ApiImplicitParam(name = SecurityConstants.PASSWORD, value = "登录密码"),
@ApiImplicitParam(name = SecurityConstants.IMAGE_CODE, value = "图形验证码"),
+ @ApiImplicitParam(name = SecurityConstants.PHONE, value = "手机号"),
+ @ApiImplicitParam(name = SecurityConstants.SMS_CODE, value = "短信验证码"),
})
@PostMapping("/token")
public Object postAccessToken(@ApiIgnore Principal principal, @RequestParam @ApiIgnore Map
+ * Protected so subclasses can override.
+ *
+ * Subclasses will usually store the original credentials the user supplied (not
+ * salted or encoded passwords) in the returned
+ * Subclasses are not required to perform any caching, as the
+ *
+ * Most of the time subclasses will not perform credentials inspection in this method,
+ * instead performing it in
+ * {@link #additionalAuthenticationChecks(UserDetails, SmsCodeAuthenticationToken)}
+ * so that code related to credentials validation need not be duplicated across two
+ * methods.
+ * UserDetails for a given authentication request. Generally a subclass
+ * will at least compare the {@link Authentication#getCredentials()} with a
+ * {@link UserDetails#getPassword()}. If custom logic is needed to compare additional
+ * properties of UserDetails and/or
+ * SmsCodeAuthenticationToken, these should also appear in this
+ * method.
+ *
+ * @param userDetails as retrieved from the
+ * {@link #retrieveUser(String, SmsCodeAuthenticationToken)} or
+ * UserCache
+ * @param authentication the current request that needs to be authenticated
+ *
+ * @throws AuthenticationException AuthenticationException if the credentials could
+ * not be validated (generally a BadCredentialsException, an
+ * AuthenticationServiceException)
+ */
+ protected abstract void additionalAuthenticationChecks(UserDetails userDetails,
+ SmsCodeAuthenticationToken authentication)
+ throws AuthenticationException;
+
+ public final void afterPropertiesSet() throws Exception {
+ Assert.notNull(this.userCache, "A user cache must be set");
+ Assert.notNull(this.messages, "A message source must be set");
+ doAfterPropertiesSet();
+ }
+
+ public Authentication authenticate(Authentication authentication)
+ throws AuthenticationException {
+ Assert.isInstanceOf(SmsCodeAuthenticationToken.class, authentication,
+ () -> messages.getMessage(
+ "AbstractSmsAuthenticationProvider.onlySupports",
+ "Only SmsCodeAuthenticationToken is supported"));
+
+ // Determine username
+ String username = (authentication.getPrincipal() == null) ? "NONE_PROVIDED"
+ : authentication.getName();
+
+ boolean cacheWasUsed = true;
+ UserDetails user = this.userCache.getUserFromCache(username);
+
+ if (user == null) {
+ cacheWasUsed = false;
+
+ try {
+ user = retrieveUser(username,
+ (SmsCodeAuthenticationToken) authentication);
+ }
+ catch (UsernameNotFoundException notFound) {
+ logger.debug("User '" + username + "' not found");
+
+ if (hideUserNotFoundExceptions) {
+ throw new BadCredentialsException(messages.getMessage(
+ "AbstractSmsAuthenticationProvider.badCredentials",
+ "Bad credentials"));
+ }
+ else {
+ throw notFound;
+ }
+ }
+
+ Assert.notNull(user,
+ "retrieveUser returned null - a violation of the interface contract");
+ }
+
+ try {
+ preAuthenticationChecks.check(user);
+ additionalAuthenticationChecks(user,
+ (SmsCodeAuthenticationToken) authentication);
+ }
+ catch (AuthenticationException exception) {
+ if (cacheWasUsed) {
+ // There was a problem, so try again after checking
+ // we're using latest data (i.e. not from the cache)
+ cacheWasUsed = false;
+ user = retrieveUser(username,
+ (SmsCodeAuthenticationToken) authentication);
+ preAuthenticationChecks.check(user);
+ additionalAuthenticationChecks(user,
+ (SmsCodeAuthenticationToken) authentication);
+ }
+ else {
+ throw exception;
+ }
+ }
+
+ postAuthenticationChecks.check(user);
+
+ if (!cacheWasUsed) {
+ this.userCache.putUserInCache(user);
+ }
+
+ Object principalToReturn = user;
+
+ if (forcePrincipalAsString) {
+ principalToReturn = user.getUsername();
+ }
+
+ return createSuccessAuthentication(principalToReturn, authentication, user);
+ }
+
+ /**
+ * Creates a successful {@link Authentication} object.
+ * Authentication object.
+ * UserDetails from an
+ * implementation-specific location, with the option of throwing an
+ * AuthenticationException immediately if the presented credentials are
+ * incorrect (this is especially useful if it is necessary to bind to a resource as
+ * the user in order to obtain or generate a UserDetails).
+ * AbstractSmsAuthenticationProvider will by default cache the
+ * UserDetails. The caching of UserDetails does present
+ * additional complexity as this means subsequent requests that rely on the cache will
+ * need to still have their credentials validated, even if the correctness of
+ * credentials was assured by subclasses adopting a binding-based strategy in this
+ * method. Accordingly it is important that subclasses either disable caching (if they
+ * want to ensure that this method is the only method that is capable of
+ * authenticating a request, as no UserDetails will ever be cached) or
+ * ensure subclasses implement
+ * {@link #additionalAuthenticationChecks(UserDetails, SmsCodeAuthenticationToken)}
+ * to compare the credentials of a cached UserDetails with subsequent
+ * authentication requests.
+ * UserDetails
+ *
+ * @return the user information (never null - instead an exception should
+ * the thrown)
+ *
+ * @throws AuthenticationException if the credentials could not be validated
+ * (generally a BadCredentialsException, an
+ * AuthenticationServiceException or
+ * UsernameNotFoundException)
+ */
+ protected abstract UserDetails retrieveUser(String username,
+ SmsCodeAuthenticationToken authentication)
+ throws AuthenticationException;
+
+ public void setForcePrincipalAsString(boolean forcePrincipalAsString) {
+ this.forcePrincipalAsString = forcePrincipalAsString;
+ }
+
+ /**
+ * By default the AbstractSmsAuthenticationProvider throws a
+ * BadCredentialsException if a username is not found or the password is
+ * incorrect. Setting this property to false will cause
+ * UsernameNotFoundExceptions to be thrown instead for the former. Note
+ * this is considered less secure than throwing BadCredentialsException
+ * for both exceptions.
+ *
+ * @param hideUserNotFoundExceptions set to false if you wish
+ * UsernameNotFoundExceptions to be thrown instead of the non-specific
+ * BadCredentialsException (defaults to true)
+ */
+ public void setHideUserNotFoundExceptions(boolean hideUserNotFoundExceptions) {
+ this.hideUserNotFoundExceptions = hideUserNotFoundExceptions;
+ }
+
+ public void setMessageSource(MessageSource messageSource) {
+ this.messages = new MessageSourceAccessor(messageSource);
+ }
+
+ public void setUserCache(UserCache userCache) {
+ this.userCache = userCache;
+ }
+
+ public boolean supports(Class> authentication) {
+ return (SmsCodeAuthenticationToken.class
+ .isAssignableFrom(authentication));
+ }
+
+ protected UserDetailsChecker getPreAuthenticationChecks() {
+ return preAuthenticationChecks;
+ }
+
+ /**
+ * Sets the policy will be used to verify the status of the loaded
+ * UserDetails before validation of the credentials takes place.
+ *
+ * @param preAuthenticationChecks strategy to be invoked prior to authentication.
+ */
+ public void setPreAuthenticationChecks(UserDetailsChecker preAuthenticationChecks) {
+ this.preAuthenticationChecks = preAuthenticationChecks;
+ }
+
+ protected UserDetailsChecker getPostAuthenticationChecks() {
+ return postAuthenticationChecks;
+ }
+
+ public void setPostAuthenticationChecks(UserDetailsChecker postAuthenticationChecks) {
+ this.postAuthenticationChecks = postAuthenticationChecks;
+ }
+
+ public void setAuthoritiesMapper(GrantedAuthoritiesMapper authoritiesMapper) {
+ this.authoritiesMapper = authoritiesMapper;
+ }
+
+ private class DefaultPreAuthenticationChecks implements UserDetailsChecker {
+ public void check(UserDetails user) {
+ if (!user.isAccountNonLocked()) {
+ logger.debug("User account is locked");
+
+ throw new LockedException(messages.getMessage(
+ "AbstractSmsAuthenticationProvider.locked",
+ "User account is locked"));
+ }
+
+ if (!user.isEnabled()) {
+ logger.debug("User account is disabled");
+
+ throw new DisabledException(messages.getMessage(
+ "AbstractSmsAuthenticationProvider.disabled",
+ "User is disabled"));
+ }
+
+ if (!user.isAccountNonExpired()) {
+ logger.debug("User account is expired");
+
+ throw new AccountExpiredException(messages.getMessage(
+ "AbstractSmsAuthenticationProvider.expired",
+ "User account has expired"));
+ }
+ }
+ }
+
+ private class DefaultPostAuthenticationChecks implements UserDetailsChecker {
+ public void check(UserDetails user) {
+ if (!user.isCredentialsNonExpired()) {
+ logger.debug("User account credentials have expired");
+
+ throw new CredentialsExpiredException(messages.getMessage(
+ "AbstractSmsAuthenticationProvider.credentialsExpired",
+ "User credentials have expired"));
+ }
+ }
+ }
+ }
+
diff --git a/pqs-auth/src/main/java/com/njcn/auth/security/sm4/Sm4AuthenticationProvider.java b/pqs-auth/src/main/java/com/njcn/auth/security/provider/Sm4AuthenticationProvider.java
similarity index 98%
rename from pqs-auth/src/main/java/com/njcn/auth/security/sm4/Sm4AuthenticationProvider.java
rename to pqs-auth/src/main/java/com/njcn/auth/security/provider/Sm4AuthenticationProvider.java
index 9218875ca..8492ca17d 100644
--- a/pqs-auth/src/main/java/com/njcn/auth/security/sm4/Sm4AuthenticationProvider.java
+++ b/pqs-auth/src/main/java/com/njcn/auth/security/provider/Sm4AuthenticationProvider.java
@@ -1,4 +1,4 @@
-package com.njcn.auth.security.sm4;
+package com.njcn.auth.security.provider;
import com.njcn.auth.pojo.bo.BusinessUser;
import com.njcn.common.utils.sm.Sm4Utils;
diff --git a/pqs-auth/src/main/java/com/njcn/auth/security/provider/SmsAuthenticationProvider.java b/pqs-auth/src/main/java/com/njcn/auth/security/provider/SmsAuthenticationProvider.java
new file mode 100644
index 000000000..39e39d1ca
--- /dev/null
+++ b/pqs-auth/src/main/java/com/njcn/auth/security/provider/SmsAuthenticationProvider.java
@@ -0,0 +1,73 @@
+package com.njcn.auth.security.provider;
+
+import com.njcn.auth.security.token.SmsCodeAuthenticationToken;
+import com.njcn.auth.service.UserDetailsServiceImpl;
+import com.njcn.common.pojo.exception.BusinessException;
+import com.njcn.user.enums.UserResponseEnum;
+import lombok.AllArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.AuthenticationException;
+import org.springframework.security.core.userdetails.UserDetails;
+import org.springframework.stereotype.Component;
+
+/**
+ * 手机短信码验证完后,返回用户的
+ * @author hongawen
+ * @version 1.0.0
+ * @date 2021年06月08日 15:43
+ */
+@Slf4j
+@Component
+@AllArgsConstructor
+public class SmsAuthenticationProvider extends AbstractSmsAuthenticationProvider {
+
+ private final UserDetailsServiceImpl userDetailsService;
+
+
+ /**
+ * 校验密码有效性.
+ * 因为手机号验证码登录,验证码没问题后,密码无需校验,直接返回该用户的token信息便可以
+ *
+ * @param userDetails 用户详细信息
+ * @param authentication 用户登录的密码
+ * @throws AuthenticationException .
+ */
+ @Override
+ protected void additionalAuthenticationChecks(
+ UserDetails userDetails, SmsCodeAuthenticationToken authentication)
+ throws AuthenticationException {
+
+ }
+
+ /**
+ * 获取用户
+ *
+ * @param phone 手机号
+ * @param authentication 认证token
+ * @throws AuthenticationException .
+ */
+ @Override
+ protected UserDetails retrieveUser(
+ String phone, SmsCodeAuthenticationToken authentication)
+ throws AuthenticationException {
+ //根据手机号获取用户信息
+ UserDetails loadedUser = userDetailsService.loadUserByPhone(phone);
+ if (loadedUser == null) {
+ throw new BusinessException(UserResponseEnum.LOGIN_PHONE_NOT_REGISTER);
+ }
+ return loadedUser;
+ }
+
+
+ /**
+ * 授权持久化.
+ */
+ @Override
+ protected Authentication createSuccessAuthentication(Object principal,
+ Authentication authentication, UserDetails user) {
+ return super.createSuccessAuthentication(principal, authentication, user);
+ }
+
+
+}
\ No newline at end of file
diff --git a/pqs-auth/src/main/java/com/njcn/auth/security/token/SmsCodeAuthenticationToken.java b/pqs-auth/src/main/java/com/njcn/auth/security/token/SmsCodeAuthenticationToken.java
new file mode 100644
index 000000000..e249b5d6e
--- /dev/null
+++ b/pqs-auth/src/main/java/com/njcn/auth/security/token/SmsCodeAuthenticationToken.java
@@ -0,0 +1,62 @@
+package com.njcn.auth.security.token;
+
+import org.springframework.security.authentication.AbstractAuthenticationToken;
+import org.springframework.security.core.GrantedAuthority;
+import org.springframework.util.Assert;
+
+import java.util.Collection;
+
+/**
+ * UsernamePasswordAuthenticationToken 一样,
+ * 继承 AbstractAuthenticationToken 抽象类,
+ * 需要实现 getPrincipal 和 getCredentials 两个方法。
+ * 在用户名/密码认证中,principal 表示用户名,
+ * credentials 表示密码,在此,我们可以让它们指代手机号和验证码。
+ *
+ * @author hongawen
+ * @version 1.0.0
+ * @date 2023年06月14日 16:25
+ */
+public class SmsCodeAuthenticationToken extends AbstractAuthenticationToken {
+
+ private final Object principal;
+
+ private Object credentials;
+
+ public SmsCodeAuthenticationToken(Object principal, Object credentials) {
+ super(null);
+ this.principal = principal;
+ this.credentials = credentials;
+ setAuthenticated(false);
+ }
+ public SmsCodeAuthenticationToken(Object principal, Object credentials,
+ Collection extends GrantedAuthority> authorities) {
+ super(authorities);
+ this.principal = principal;
+ this.credentials = credentials;
+ super.setAuthenticated(true);
+ }
+
+ @Override
+ public Object getCredentials() {
+ return this.credentials;
+ }
+
+ @Override
+ public Object getPrincipal() {
+ return this.principal;
+ }
+
+ @Override
+ public void setAuthenticated(boolean isAuthenticated) throws IllegalArgumentException {
+ Assert.isTrue(!isAuthenticated,
+ "Cannot set this token to trusted - use constructor which takes a GrantedAuthority list instead");
+ super.setAuthenticated(false);
+ }
+
+ @Override
+ public void eraseCredentials() {
+ super.eraseCredentials();
+ this.credentials = null;
+ }
+}
diff --git a/pqs-auth/src/main/java/com/njcn/auth/service/CustomUserDetailsService.java b/pqs-auth/src/main/java/com/njcn/auth/service/CustomUserDetailsService.java
new file mode 100644
index 000000000..2addd2849
--- /dev/null
+++ b/pqs-auth/src/main/java/com/njcn/auth/service/CustomUserDetailsService.java
@@ -0,0 +1,28 @@
+package com.njcn.auth.service;
+
+import org.springframework.security.core.userdetails.UserDetails;
+import org.springframework.security.core.userdetails.UserDetailsService;
+import org.springframework.security.core.userdetails.UsernameNotFoundException;
+
+/**
+ * @author hongawen
+ * @version 1.0.0
+ * @date 2023年06月15日 10:26
+ */
+public interface CustomUserDetailsService extends UserDetailsService {
+
+ /**
+ * @param username 用户名
+ * @return 用户信息
+ * @throws UsernameNotFoundException
+ */
+ UserDetails loadUserByUsername(String username) throws UsernameNotFoundException;
+
+ /**
+ * @param phone 手机号
+ * @return 用户信息
+ * @throws UsernameNotFoundException
+ */
+ UserDetails loadUserByPhone(String phone) throws UsernameNotFoundException;
+
+}
diff --git a/pqs-auth/src/main/java/com/njcn/auth/service/UserDetailsServiceImpl.java b/pqs-auth/src/main/java/com/njcn/auth/service/UserDetailsServiceImpl.java
index ca5a1a767..b581b5992 100644
--- a/pqs-auth/src/main/java/com/njcn/auth/service/UserDetailsServiceImpl.java
+++ b/pqs-auth/src/main/java/com/njcn/auth/service/UserDetailsServiceImpl.java
@@ -25,7 +25,7 @@ import org.springframework.stereotype.Service;
@Slf4j
@Service
@AllArgsConstructor
-public class UserDetailsServiceImpl implements UserDetailsService {
+public class UserDetailsServiceImpl implements CustomUserDetailsService {
private final UserFeignClient userFeignClient;
@@ -44,4 +44,18 @@ public class UserDetailsServiceImpl implements UserDetailsService {
return businessUser;
}
+ @Override
+ public UserDetails loadUserByPhone(String phone) throws UsernameNotFoundException {
+ String clientId = RequestUtil.getOAuth2ClientId();
+ BusinessUser businessUser = new BusinessUser(phone, null, null);
+ businessUser.setClientId(clientId);
+ HttpResult> getUserByIdList(@RequestBody List