黎星凯
2024-05-17 3520e86e2b00b9c1ee3f4fffd4ab49fe3d6c259e
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
package com.iplatform.security;
 
import com.iplatform.base.Constants;
import com.iplatform.base.DefaultUserPrincipal;
import com.iplatform.base.SecurityConstants;
import com.iplatform.base.cache.MenuCacheProvider;
import com.iplatform.base.service.UserServiceImpl;
import com.iplatform.base.util.UserUtils;
import com.iplatform.model.po.S_menu;
import com.iplatform.model.po.S_user_core;
import com.iplatform.security.config.SecurityProperties;
import com.walker.infrastructure.utils.PhoneNumberUtils;
import com.walker.infrastructure.utils.StringUtils;
import com.walker.web.UserType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
 
import java.util.HashMap;
import java.util.List;
import java.util.Map;
 
public class DefaultUserDetailsService implements UserDetailsService {
 
    protected final transient Logger logger = LoggerFactory.getLogger(getClass());
 
    private UserServiceImpl userService = null;
    private SecurityProperties securityProperties;
    private MenuCacheProvider menuCacheProvider;
 
    public void setMenuCacheProvider(MenuCacheProvider menuCacheProvider) {
        this.menuCacheProvider = menuCacheProvider;
    }
 
    public void setSecurityProperties(SecurityProperties securityProperties) {
        this.securityProperties = securityProperties;
    }
 
//    public void setPasswordEncoder(PasswordEncoder passwordEncoder) {
//        this.passwordEncoder = passwordEncoder;
//    }
 
    public void setUserService(UserServiceImpl userService) {
        this.userService = userService;
    }
 
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
//        UserPrincipal<S_user_core> userPrincipal = this.acquireUserPrincipal(username);
        logger.debug("loadUserByUsername = " + username);
        DefaultUserDetails userDetails = this.acquireUserPrincipal(username);
        if(userDetails == null) {
            throw new UsernameNotFoundException("not found user: " + username);
        }
        // 被禁用的用户也不能登录
        if(!userDetails.isEnabled()) {
            throw new UsernameNotFoundException("user is forbidden: " + username);
        }
 
        // 验证用户
        // 2023-01-28 验证密码放在登录回调中。
//        this.validateUserInfo(userDetails.getUserPrincipal());
        return userDetails;
    }
 
    /*private void validateUserInfo(UserPrincipal<S_user_core> userPrincipal){
        // 2023-01-26 通过 PlatformLoginCallback 来校验密码。
        PlatformLoginCallback loginCallback = LoginCallbackUtils.getLoginCallbackBean(UserType.getType(userPrincipal.getUserInfo().getUser_type()));
        if(loginCallback == null){
            throw new ApplicationRuntimeException("未找到: loginCallback, userType = " + userPrincipal.getUserInfo().getUser_type());
        }
        boolean success = loginCallback.validatePassword(userPrincipal);
        if(!success){
            throw new BadCredentialsException(ResponseCode.USER_CREDENTIALS_ERROR.getMessage());
        }
//        Authentication usernamePasswordAuthenticationToken = SecurityContextHolder.getContext().getAuthentication();
//        String password = usernamePasswordAuthenticationToken.getCredentials().toString();
//        if(!this.passwordEncoder.matches(password, userPrincipal.getPassword())){
//            throw new BadCredentialsException(ResponseCode.USER_CREDENTIALS_ERROR.getMessage());
//        }
        logger.debug("清空必要的缓存:或更新登录缓存");
    }*/
 
    public DefaultUserDetails acquireUserPrincipal(String loginId){
        if(StringUtils.isEmpty(loginId)){
            return null;
        }
 
        DefaultUserPrincipal userPrincipal = null;
 
        // 如果超级管理员,不能查数据库,直接创建对象。2022-11-06
        if(loginId.equals(Constants.SUPERVISOR_NAME_DEFAULT)){
            userPrincipal = (DefaultUserPrincipal) UserUtils.createSupervisor(this.securityProperties.getSupervisorPassword());
            DefaultUserDetails userDetails = new DefaultUserDetails(userPrincipal);
            // 2022-12-02
            userDetails.addGrantedAuthority(SecurityConstants.ROLE_SUPER_ADMIN);
            userDetails.addGrantedAuthority(SecurityConstants.ROLE_ADMIN);
            userDetails.addGrantedAuthority(SecurityConstants.ROLE_USER);
//            userDetails.addGrantedAuthority(com.walker.web.Constants.ROLE_ACTIVITI_USER);
            userDetails.setRoleIdListToPrincipal();
            return userDetails;
        }
 
        // 2023-06-28 根据登录账号是否手机号,支持移动端和PC端手机登录方式。
        boolean isPhoneNumber = PhoneNumberUtils.isCellPhoneNumber(loginId);
        Object[] userInfo = null;
        if(isPhoneNumber && !this.securityProperties.isUserNameIsPhone()){
            // 通过手机号字段查询用户
            userInfo = this.userService.queryLoginUser(loginId, true);
        } else {
            // 通过用户名自动查询用户
            userInfo = this.userService.queryLoginUser(loginId, false);
        }
 
        if(userInfo == null){
            logger.debug("用户不存在: " + loginId);
            return null;
        }
        S_user_core user = (S_user_core) userInfo[0];       // 用户信息一定存在
        List<String> roleIdList = (List<String>)userInfo[1];// 角色ID集合,不一定存在
        logger.debug("找到用户: " + user.getUser_name());
 
        // 加入普通用户具有的角色ID,权限根据角色ID判断
        userPrincipal = new DefaultUserPrincipal(user);
        // 设置登录时间,后面要计算过期,2022-11-14
        userPrincipal.setLastLoginTime(System.currentTimeMillis());
        DefaultUserDetails userDetails = new DefaultUserDetails(userPrincipal);
        if(roleIdList != null){
            for(String roleId : roleIdList){
                userDetails.addGrantedAuthority(roleId);
            }
        }
 
        // 2022-12-21,用户数据权限 =========================
        // 2023-07-17,由于oracle查询报错(in (:roleIds)),暂时关闭数据权限查询
//        Map<String, String> dataScopeMap = this.acquireUserDataScopeList(roleIdList);
//        if(dataScopeMap != null){
//            logger.debug("用户数据权限集合 = " + dataScopeMap);
//            userPrincipal.setDataScopeMap(dataScopeMap);
//        }
        // ================================================
 
        // 2022-11-15
        int userType = userDetails.getUserPrincipal().getUserInfo().getUser_type();
 
        /* 设置用户的角色类型 */
        if(userType == UserType.TYPE_SUPER){
            userDetails.addGrantedAuthority(SecurityConstants.ROLE_SUPER_ADMIN);
            userDetails.addGrantedAuthority(SecurityConstants.ROLE_ADMIN);
            userDetails.addGrantedAuthority(SecurityConstants.ROLE_USER);
 
        } else if(userType == UserType.TYPE_ADMIN || userType == UserType.TYPE_ADMIN_DEPT){
            userDetails.addGrantedAuthority(SecurityConstants.ROLE_ADMIN);
            userDetails.addGrantedAuthority(SecurityConstants.ROLE_USER);
 
//        } else if(userType == UserType.TYPE_NORMAL || userType == UserType.TYPE_APP_REG){
        } else if(userType == UserType.TYPE_NORMAL){
            userDetails.addGrantedAuthority(SecurityConstants.ROLE_USER);
 
        } else if(userType == UserType.TYPE_APP_REG){
            // 2023-01-27 app注册用户,不给任何角色权限
            // 2023-03-20 app注册用户,需要给'ROLE_USER',因为还需要访问公共权限(登录后都能看的如:/permit/**,/getInfo),但不给任何角色!
            userDetails.addGrantedAuthority(SecurityConstants.ROLE_USER);
 
        } else if(userType == UserType.TYPE_MERCHANT_ADMIN){
            // 2023-06-06 商户管理员(泛指独立业务单位的:单位管理员)
            userDetails.addGrantedAuthority(SecurityConstants.ROLE_MERCHANT);
            userDetails.addGrantedAuthority(SecurityConstants.ROLE_USER);
 
        } else
            throw new IllegalArgumentException("unknown user type: " + userType);
 
        // 添加工作流角色,否则activiti7老报错'无权限',2023-03-21
//        userDetails.addGrantedAuthority(com.walker.web.Constants.ROLE_ACTIVITI_USER);
        //
        userDetails.setRoleIdListToPrincipal();
 
        return userDetails;
    }
 
    /**
     * 由于oracle查询报错(in (:roleIds)),暂时关闭数据权限查询
     * @param roleIdList
     * @return
     * @date 2023-07-17
     */
    @Deprecated
    private Map<String, String> acquireUserDataScopeList(List<String> roleIdList){
        if(StringUtils.isEmptyList(roleIdList)){
            return null;
        }
        List<String> dataScopeMenuIdList = this.userService.queryUserDataScopeMenuIdList(roleIdList);
        if(StringUtils.isEmptyList(dataScopeMenuIdList)){
            return null;
        }
        Map<String, String> dataScopeMap = new HashMap<>(8);
        S_menu menu = null;
        for(String menuId : dataScopeMenuIdList){
            menu = this.menuCacheProvider.getCacheData(menuId);
            if(menu == null){
                throw new IllegalStateException("菜单缓存不存在:" + menuId);
            }
            dataScopeMap.put(menu.getParent_id(), menuId.replaceFirst(Constants.DATA_SCOPE_NAME, StringUtils.EMPTY_STRING));
        }
        return dataScopeMap;
    }
}