From 031d1c5a7c680bfcf2b9a4a98e9d0ae0c613ff51 Mon Sep 17 00:00:00 2001
From: zhuo <2089219845@qq.com>
Date: 星期六, 15 三月 2025 11:42:24 +0800
Subject: [PATCH] 新增无需密码获取用户登录信息

---
 ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/UserDetailsServiceImpl.java         |    4 
 /dev/null                                                                                         |   36 -------
 ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/SysLoginService.java                |   56 +++++++++-
 ruoyi-framework/src/main/java/com/ruoyi/framework/web/ssoAuth/SsoCodeAuthenticationProvider.java  |   42 ++++++++
 ruoyi-framework/src/main/java/com/ruoyi/framework/web/ssoAuth/SsoCodeAuthenticationToken.java     |   63 ++++++++++++
 ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/UserDetailsByOpenIdServiceImpl.java |   47 +++++++++
 ruoyi-framework/src/main/java/com/ruoyi/framework/config/SecurityConfig.java                      |   25 ++++
 7 files changed, 226 insertions(+), 47 deletions(-)

diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/LocalDateTimeSerializerConfig.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/LocalDateTimeSerializerConfig.java
deleted file mode 100644
index 98a8763..0000000
--- a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/LocalDateTimeSerializerConfig.java
+++ /dev/null
@@ -1,36 +0,0 @@
-//package com.ruoyi.framework.config;
-//
-//import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
-//import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
-//import org.springframework.beans.factory.annotation.Value;
-//import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;
-//import org.springframework.context.annotation.Bean;
-//import org.springframework.context.annotation.Configuration;
-//
-//import java.time.LocalDateTime;
-//import java.time.format.DateTimeFormatter;
-//
-//@Configuration
-//public class LocalDateTimeSerializerConfig {
-//    @Value("${spring.jackson.date-format}")
-//    private String pattern;
-//
-//    @Bean
-//    public LocalDateTimeSerializer localDateTimeSerializer() {
-//        return new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(pattern));
-//    }
-//
-//    @Bean
-//    public LocalDateTimeDeserializer localDateTimeDeserializer() {
-//        return new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern(pattern));
-//    }
-//
-//    @Bean
-//    public Jackson2ObjectMapperBuilderCustomizer jackson2ObjectMapperBuilderCustomizer() {
-//        return builder -> {
-//            builder.serializerByType(LocalDateTime.class, localDateTimeSerializer());
-//            builder.deserializerByType(LocalDateTime.class, localDateTimeDeserializer());
-//            builder.simpleDateFormat(pattern);
-//        };
-//    }
-//}
diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/SecurityConfig.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/SecurityConfig.java
index 974a5e2..f4a7045 100644
--- a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/SecurityConfig.java
+++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/SecurityConfig.java
@@ -1,10 +1,13 @@
 package com.ruoyi.framework.config;
 
+import com.ruoyi.framework.web.ssoAuth.SsoCodeAuthenticationProvider;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
 import org.springframework.http.HttpMethod;
 import org.springframework.security.authentication.AuthenticationManager;
+import org.springframework.security.authentication.AuthenticationProvider;
 import org.springframework.security.authentication.ProviderManager;
 import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
 import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
@@ -21,6 +24,9 @@
 import com.ruoyi.framework.security.handle.AuthenticationEntryPointImpl;
 import com.ruoyi.framework.security.handle.LogoutSuccessHandlerImpl;
 
+import java.util.ArrayList;
+import java.util.List;
+
 /**
  * spring security閰嶇疆
  *
@@ -34,7 +40,15 @@
      * 鑷畾涔夌敤鎴疯璇侀�昏緫
      */
     @Autowired
+    @Qualifier("UserDetailsServiceImpl")
     private UserDetailsService userDetailsService;
+
+    /**
+     * sso鑷畾涔夋牎楠�
+     */
+    @Autowired
+    @Qualifier("UserDetailsByOpenIdServiceImpl")
+    private UserDetailsService userDetailsServiceByOpenId;
 
     /**
      * 璁よ瘉澶辫触澶勭悊绫�
@@ -75,7 +89,16 @@
         DaoAuthenticationProvider daoAuthenticationProvider = new DaoAuthenticationProvider();
         daoAuthenticationProvider.setUserDetailsService(userDetailsService);
         daoAuthenticationProvider.setPasswordEncoder(bCryptPasswordEncoder());
-        return new ProviderManager(daoAuthenticationProvider);
+
+        // sso鐧婚檰閴存潈 Provider
+        SsoCodeAuthenticationProvider wxCodeAuthenticationProvider = new SsoCodeAuthenticationProvider();
+        wxCodeAuthenticationProvider.setUserDetailsService(userDetailsServiceByOpenId);
+        List<AuthenticationProvider> providers = new ArrayList<>();
+
+        providers.add(wxCodeAuthenticationProvider);
+        providers.add(daoAuthenticationProvider);
+
+        return new ProviderManager(providers);
     }
 
     /**
diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/SysLoginService.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/SysLoginService.java
index b6841dd..c5da313 100644
--- a/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/SysLoginService.java
+++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/SysLoginService.java
@@ -9,6 +9,7 @@
 import com.ruoyi.common.core.domain.entity.User;
 import com.ruoyi.framework.model.SsoOauthTokenModel;
 import com.ruoyi.framework.model.SsoUserInfoModel;
+import com.ruoyi.framework.web.ssoAuth.SsoCodeAuthenticationToken;
 import com.ruoyi.system.mapper.UserMapper;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.http.HttpEntity;
@@ -93,9 +94,6 @@
 
     @Autowired
     private RedisTemplate redisTemplate;
-
-    @Autowired
-    private UserMapper userMapper;
 
     /**
      * 鐧诲綍楠岃瘉
@@ -234,26 +232,68 @@
         // 鑾峰彇鍗曠偣鐧诲綍token
         SsoOauthTokenModel tokenModel = this.getSsoAccessToken(code);
         if (tokenModel == null) {
-            return null;
+            throw new RuntimeException("鍗曠偣鐧诲綍楠岃瘉澶辫触");
         }
 
         // 鑾峰彇鍗曠偣鐧诲綍鐢ㄦ埛淇℃伅
         SsoUserInfoModel userInfo = this.getSsoUserInfo(tokenModel.getAccess_token());
         if (userInfo == null) {
-            return null;
+            throw new RuntimeException("鍗曠偣鐧诲綍楠岃瘉澶辫触");
         }
 
         // 鏌ヨ鏈湴鐢ㄦ埛淇℃伅
+        LoginUser loginUser = this.getSsoLoginToken(userInfo.getEmployeeId());
+        recordLoginInfo(loginUser.getUserId());
 
-
-
+        // 鍒涘缓鐧诲綍淇℃伅
         AsyncManager.me().execute(AsyncFactory.recordLogininfor(userInfo.getEmployeeId(), Constants.LOGIN_SUCCESS, MessageUtils.message("user.single.login.success")));
         redisTemplate.opsForValue().set("ssoOauthToken:idToken:" + userInfo.getEmployeeId(), tokenModel.getId_token(), 3, TimeUnit.DAYS);
         // 鐢熸垚token
-        return tokenService.createToken(null);
+        return tokenService.createToken(loginUser);
     }
 
     /**
+     * ***** 鑾峰彇鏈湴鐢ㄦ埛淇℃伅 *****
+     * @param username
+     * @return
+     */
+    public LoginUser getSsoLoginToken(String username) {
+        // 鐢ㄦ埛楠岃瘉
+        Authentication authentication = null;
+        SysUser sysUser = sysUserService.selectUserByUserName(username);
+        if (sysUser == null) {
+            throw new ServiceException("鐢ㄦ埛涓嶅瓨鍦�");
+        }
+        try
+        {
+            // 鏃犻渶瀵嗙爜鑾峰彇鐢ㄦ埛淇℃伅
+            authentication = authenticationManager.authenticate(new SsoCodeAuthenticationToken(username));
+        }
+        catch (Exception e)
+        {
+            if (e instanceof BadCredentialsException)
+            {
+                AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.password.not.match")));
+                throw new UserPasswordNotMatchException();
+            }
+            else
+            {
+                AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, e.getMessage()));
+                throw new ServiceException(e.getMessage());
+            }
+        }
+        finally
+        {
+            AuthenticationContextHolder.clearContext();
+        }
+        AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success")));
+        return (LoginUser) authentication.getPrincipal();
+
+    }
+
+
+
+    /**
      * **** 鑾峰彇鍗曠偣鐧诲綍token ****
      * @param code
      * @return
diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/UserDetailsByOpenIdServiceImpl.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/UserDetailsByOpenIdServiceImpl.java
new file mode 100644
index 0000000..a97d073
--- /dev/null
+++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/UserDetailsByOpenIdServiceImpl.java
@@ -0,0 +1,47 @@
+package com.ruoyi.framework.web.service;
+
+import com.ruoyi.common.core.domain.entity.SysUser;
+import com.ruoyi.common.core.domain.model.LoginUser;
+import com.ruoyi.common.enums.UserStatus;
+import com.ruoyi.common.exception.base.BaseException;
+import com.ruoyi.common.utils.StringUtils;
+import com.ruoyi.framework.web.service.SysPermissionService;
+import com.ruoyi.system.service.ISysUserService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.core.userdetails.UserDetails;
+import org.springframework.security.core.userdetails.UserDetailsService;
+import org.springframework.security.core.userdetails.UsernameNotFoundException;
+import org.springframework.stereotype.Service;
+
+@Service("UserDetailsByOpenIdServiceImpl")
+public class UserDetailsByOpenIdServiceImpl implements UserDetailsService {
+
+
+
+    @Autowired
+    private ISysUserService userService;
+
+    @Autowired
+    private SysPermissionService permissionService;
+
+    @Override
+    public UserDetails loadUserByUsername(String openId) throws UsernameNotFoundException {
+        SysUser user = userService.selectUserByUserName(openId);
+        if (StringUtils.isNull(user)) {
+
+            throw new UsernameNotFoundException("鐧诲綍鐢ㄦ埛锛�" + openId + " 涓嶅瓨鍦�");
+        } else if (UserStatus.DELETED.getCode().equals(user.getDelFlag())) {
+
+            throw new BaseException("瀵逛笉璧凤紝鎮ㄧ殑璐﹀彿锛�" + openId + " 宸茶鍒犻櫎");
+        } else if (UserStatus.DISABLE.getCode().equals(user.getStatus())) {
+
+            throw new BaseException("瀵逛笉璧凤紝鎮ㄧ殑璐﹀彿锛�" + openId + " 宸插仠鐢�");
+        }
+  		// 鍜岃嫢渚濈殑鍖哄埆 鏄病鏈夐獙璇佸瘑鐮�
+        return createLoginUser(user);
+    }
+
+    public UserDetails createLoginUser(SysUser user) {
+        return new LoginUser(user.getUserId(), user.getDeptId(), user, permissionService.getMenuPermission(user));
+    }
+}
diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/UserDetailsServiceImpl.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/UserDetailsServiceImpl.java
index 5dcdf90..f6dac10 100644
--- a/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/UserDetailsServiceImpl.java
+++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/UserDetailsServiceImpl.java
@@ -20,14 +20,14 @@
  *
  * @author ruoyi
  */
-@Service
+@Service("UserDetailsServiceImpl")
 public class UserDetailsServiceImpl implements UserDetailsService
 {
     private static final Logger log = LoggerFactory.getLogger(UserDetailsServiceImpl.class);
 
     @Autowired
     private ISysUserService userService;
-    
+
     @Autowired
     private SysPasswordService passwordService;
 
diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/web/ssoAuth/SsoCodeAuthenticationProvider.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/web/ssoAuth/SsoCodeAuthenticationProvider.java
new file mode 100644
index 0000000..f882b7b
--- /dev/null
+++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/web/ssoAuth/SsoCodeAuthenticationProvider.java
@@ -0,0 +1,42 @@
+package com.ruoyi.framework.web.ssoAuth;
+
+import org.springframework.security.authentication.AuthenticationProvider;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.userdetails.UserDetails;
+import org.springframework.security.core.userdetails.UserDetailsService;
+import org.springframework.security.core.AuthenticationException;
+public class SsoCodeAuthenticationProvider implements AuthenticationProvider {
+
+    private UserDetailsService userDetailsService;
+
+    @Override
+    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
+        SsoCodeAuthenticationToken authenticationToken = (SsoCodeAuthenticationToken) authentication;
+
+        String openId = (String) authenticationToken.getPrincipal();
+
+        UserDetails userDetails = userDetailsService.loadUserByUsername(openId);
+
+        // 姝ゆ椂閴存潈鎴愬姛鍚庯紝搴斿綋閲嶆柊 new 涓�涓嫢鏈夐壌鏉冪殑 authenticationResult 杩斿洖
+        SsoCodeAuthenticationToken authenticationResult = new SsoCodeAuthenticationToken(userDetails, userDetails.getAuthorities());
+
+        authenticationResult.setDetails(authenticationToken.getDetails());
+
+        return authenticationResult;
+    }
+
+
+    @Override
+    public boolean supports(Class<?> authentication) {
+        // 鍒ゆ柇 authentication 鏄笉鏄� WxCodeAuthenticationToken 鐨勫瓙绫绘垨瀛愭帴鍙�
+        return SsoCodeAuthenticationToken.class.isAssignableFrom(authentication);
+    }
+
+    public UserDetailsService getUserDetailsService() {
+        return userDetailsService;
+    }
+
+    public void setUserDetailsService(UserDetailsService userDetailsService) {
+        this.userDetailsService = userDetailsService;
+    }
+}
diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/web/ssoAuth/SsoCodeAuthenticationToken.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/web/ssoAuth/SsoCodeAuthenticationToken.java
new file mode 100644
index 0000000..b783f36
--- /dev/null
+++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/web/ssoAuth/SsoCodeAuthenticationToken.java
@@ -0,0 +1,63 @@
+package com.ruoyi.framework.web.ssoAuth;
+
+import org.springframework.security.authentication.AbstractAuthenticationToken;
+import org.springframework.security.core.GrantedAuthority;
+import org.springframework.security.core.SpringSecurityCoreVersion;
+
+import java.util.Collection;
+
+public class SsoCodeAuthenticationToken extends AbstractAuthenticationToken {
+
+    private static final long serialVersionUID = SpringSecurityCoreVersion.SERIAL_VERSION_UID;
+
+    /**
+     * 鍦� UsernamePasswordAuthenticationToken 涓瀛楁浠h〃鐧诲綍鐨勭敤鎴峰悕锛�
+     * 鍦ㄨ繖閲屽氨浠h〃鐧诲綍鐨刼penId
+     */
+    private final Object principal;
+
+    /**
+     * 鏋勫缓涓�涓病鏈夐壌鏉冪殑 SsoCodeAuthenticationToken
+     */
+    public SsoCodeAuthenticationToken(Object principal) {
+        super(null);
+        this.principal = principal;
+        setAuthenticated(false);
+    }
+
+    /**
+     * 鏋勫缓鎷ユ湁閴存潈鐨� SsoCodeAuthenticationToken
+     */
+    public SsoCodeAuthenticationToken(Object principal, Collection<? extends GrantedAuthority> authorities) {
+        super(authorities);
+        this.principal = principal;
+        // must use super, as we override
+        super.setAuthenticated(true);
+    }
+
+    @Override
+    public Object getCredentials() {
+        return null;
+    }
+
+    @Override
+    public Object getPrincipal() {
+        return this.principal;
+    }
+
+    @Override
+    public void setAuthenticated(boolean isAuthenticated) throws IllegalArgumentException {
+        if (isAuthenticated) {
+            throw new IllegalArgumentException(
+                    "Cannot set this token to trusted - use constructor which takes a GrantedAuthority list instead");
+        }
+
+        super.setAuthenticated(false);
+    }
+
+    @Override
+    public void eraseCredentials() {
+        super.eraseCredentials();
+    }
+
+}

--
Gitblit v1.9.3