黎星凯
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
package com.iplatform.security;
 
import com.iplatform.base.PlatformLoginCallback;
import com.iplatform.base.pojo.RequestLogin;
import com.iplatform.security.exception.PcUserStopAppException;
import com.iplatform.security.util.LoginCallbackUtils;
import com.walker.web.CaptchaType;
import com.walker.web.ClientType;
import com.walker.web.LoginType;
import com.walker.web.ResponseCode;
import com.walker.web.UserType;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.InternalAuthenticationServiceException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.authentication.dao.AbstractUserDetailsAuthenticationProvider;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
 
/**
 * 自定义认证提供者,由平台自己决定如何对比密码验证,如果不定制则spring会自动比较密码。
 * @author 时克英
 * @date 2023-01-28
 */
public class DefaultAuthenticationProvider extends AbstractUserDetailsAuthenticationProvider {
 
    @Override
    protected void additionalAuthenticationChecks(UserDetails userDetails
            , UsernamePasswordAuthenticationToken authentication) throws AuthenticationException {
        if(!(authentication instanceof DefaultAuthenticationToken)){
            throw new InternalAuthenticationServiceException("UsernamePasswordAuthenticationToken 必须是: DefaultAuthenticationToken", null);
        }
        DefaultAuthenticationToken defaultAuthenticationToken = (DefaultAuthenticationToken)authentication;
        RequestLogin requestLogin = defaultAuthenticationToken.getRequestLogin();
 
        // 非APP用户能否登录手机APP?可以在这里判断,2023-03-20
        if(!this.allowPcUserAccessApp){
            if(requestLogin.getClientType().equalsIgnoreCase(ClientType.MOBILE.getIndex())){
                DefaultUserDetails defaultUserDetails = (DefaultUserDetails) userDetails;
                if(defaultUserDetails.getUserPrincipal().getUserInfo().getUser_type() != UserType.TYPE_APP_REG){
                    // 登录方式为移动端,同时用户类别为非app用户,禁止登录
                    throw new PcUserStopAppException(null);
                }
            }
        }
 
        // 通过登录类型,获取配置的登录回调对象,委派实现密码验证。
        // 2023-12-28 移动端登录验证
        CaptchaType captchaType = CaptchaType.getType(requestLogin.getVerifyType());
        PlatformLoginCallback loginCallback = LoginCallbackUtils.getLoginCallbackBean(LoginType.getType(requestLogin.getLoginType()), true, captchaType);
        if(loginCallback == null){
            throw new InternalAuthenticationServiceException("loginCallback未找到:" + requestLogin.getLoginType());
        }
        boolean success = loginCallback.validatePassword(((DefaultUserDetails)userDetails).getUserPrincipal());
        if(!success){
            throw new BadCredentialsException(ResponseCode.USER_CREDENTIALS_ERROR.getMessage());
        }
        logger.debug("++++++++++++ 自动验证密码为正确, loginType = " + requestLogin.getLoginType());
    }
 
    @Override
    protected UserDetails retrieveUser(String username
            , UsernamePasswordAuthenticationToken authentication) throws AuthenticationException {
        try{
            UserDetails loadedUser = this.userDetailsService.loadUserByUsername(username);
            if(loadedUser == null){
                throw new InternalAuthenticationServiceException("UserDetailsService returned null, which is an interface contract violation");
            }
            return loadedUser;
 
        } catch (Exception ex){
            if(ex instanceof UsernameNotFoundException){
                logger.debug("+++++++++++++++ " + ex.getMessage());
                throw ex;
            }
            if(ex instanceof InternalAuthenticationServiceException){
                throw ex;
            }
            throw new InternalAuthenticationServiceException(ex.getMessage(), ex);
        }
    }
 
    public void setUserDetailsService(UserDetailsService userDetailsService) {
        this.userDetailsService = userDetailsService;
    }
 
    /**
     * 设置是否允许'后台PC用户'访问登录手机APP
     * @param allowPcUserAccessApp
     * @date 2023-03-20
     */
    public void setAllowPcUserAccessApp(boolean allowPcUserAccessApp) {
        this.allowPcUserAccessApp = allowPcUserAccessApp;
    }
 
    private boolean allowPcUserAccessApp = true;
    private UserDetailsService userDetailsService;
}