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;
|
}
|