From 594a732d148a186e328092cb6d79964018f841f5 Mon Sep 17 00:00:00 2001 From: WenC <450292408@qq.com> Date: Tue, 9 Apr 2024 16:04:24 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E6=89=8B=E6=9C=BA=E9=AA=8C?= =?UTF-8?q?=E8=AF=81=E7=A0=81=E7=99=BB=E5=BD=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../systemuser/SystemUserRouteController.java | 1 + .../login/phone/LoginPhoneConfig.java | 52 +++++++++++++ .../phone/auth/LoginPhoneAuthFilter.java | 46 ++++++++++++ .../phone/auth/LoginPhoneAuthProvider.java | 75 +++++++++++++++++++ .../login/phone/auth/LoginPhoneAuthToken.java | 37 +++++++++ .../resources/templates/systemuser/login.html | 46 ++++++------ 6 files changed, 236 insertions(+), 21 deletions(-) create mode 100644 src/main/java/cn/com/tenlion/operator/login/phone/LoginPhoneConfig.java create mode 100644 src/main/java/cn/com/tenlion/operator/login/phone/auth/LoginPhoneAuthFilter.java create mode 100644 src/main/java/cn/com/tenlion/operator/login/phone/auth/LoginPhoneAuthProvider.java create mode 100644 src/main/java/cn/com/tenlion/operator/login/phone/auth/LoginPhoneAuthToken.java diff --git a/src/main/java/cn/com/tenlion/operator/controller/route/systemuser/SystemUserRouteController.java b/src/main/java/cn/com/tenlion/operator/controller/route/systemuser/SystemUserRouteController.java index 45c1e18..61c7b0f 100644 --- a/src/main/java/cn/com/tenlion/operator/controller/route/systemuser/SystemUserRouteController.java +++ b/src/main/java/cn/com/tenlion/operator/controller/route/systemuser/SystemUserRouteController.java @@ -87,6 +87,7 @@ public class SystemUserRouteController extends DefaultBaseController { public ModelAndView login(HttpServletRequest request) { ModelAndView mv = new ModelAndView(); Map pageParams = oAuthService.getPageParams(request); + pageParams.put("loginPhoneAction", "oauth/phone"); mv.addObject(IUserCenterConst.PAGE_PARAMS, pageParams); mv.addObject(IUserCenterConst.CUSTOM_LOGIN_FORM, loginFormService.getActive()); mv.addObject("HomeServerUrl", ProjectConfigUtil.getText("HomeServerUrl")); diff --git a/src/main/java/cn/com/tenlion/operator/login/phone/LoginPhoneConfig.java b/src/main/java/cn/com/tenlion/operator/login/phone/LoginPhoneConfig.java new file mode 100644 index 0000000..e01bbd6 --- /dev/null +++ b/src/main/java/cn/com/tenlion/operator/login/phone/LoginPhoneConfig.java @@ -0,0 +1,52 @@ +package cn.com.tenlion.operator.login.phone; + +import cn.com.tenlion.operator.login.phone.auth.LoginPhoneAuthFilter; +import cn.com.tenlion.operator.login.phone.auth.LoginPhoneAuthProvider; +import ink.wgink.interfaces.config.ICustomUserSecurityConfig; +import ink.wgink.interfaces.expand.login.ILoginHandlerService; +import ink.wgink.login.base.handler.LoginFailureHandler; +import ink.wgink.login.base.service.user.UserLoginService; +import ink.wgink.module.sms.service.sms.ISmsService; +import ink.wgink.properties.BaseProperties; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.config.annotation.SecurityConfigurerAdapter; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.security.web.DefaultSecurityFilterChain; +import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; +import org.springframework.stereotype.Component; + +import javax.servlet.http.HttpSession; + +@Component +public class LoginPhoneConfig extends SecurityConfigurerAdapter implements ICustomUserSecurityConfig { + + @Autowired + private BaseProperties baseProperties; + @Autowired + private UserDetailsService userDetailsService; + @Autowired + private UserLoginService userLoginService; + @Autowired(required = false) + private ILoginHandlerService loginHandler; + @Autowired + private HttpSession httpSession; + @Autowired + private ISmsService smsService; + + @Override + public void configure(HttpSecurity http) throws Exception { + super.configure(http); + LoginPhoneAuthFilter loginPhoneAuthFilter = new LoginPhoneAuthFilter(smsService); + loginPhoneAuthFilter.setAuthenticationManager(http.getSharedObject(AuthenticationManager.class)); + loginPhoneAuthFilter.setAuthenticationFailureHandler(new LoginFailureHandler(baseProperties.getLoginFailure())); + + LoginPhoneAuthProvider loginPhoneAuthProvider = new LoginPhoneAuthProvider(userDetailsService, + userLoginService, + loginHandler, + httpSession + ); + http.authenticationProvider(loginPhoneAuthProvider).addFilterBefore(loginPhoneAuthFilter, UsernamePasswordAuthenticationFilter.class); + } +} diff --git a/src/main/java/cn/com/tenlion/operator/login/phone/auth/LoginPhoneAuthFilter.java b/src/main/java/cn/com/tenlion/operator/login/phone/auth/LoginPhoneAuthFilter.java new file mode 100644 index 0000000..a88e2e5 --- /dev/null +++ b/src/main/java/cn/com/tenlion/operator/login/phone/auth/LoginPhoneAuthFilter.java @@ -0,0 +1,46 @@ +package cn.com.tenlion.operator.login.phone.auth; + +import ink.wgink.login.base.exceptions.UserAuthenticationException; +import ink.wgink.module.sms.service.sms.ISmsService; +import org.apache.commons.lang3.StringUtils; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.AuthenticationException; +import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter; +import org.springframework.security.web.util.matcher.AntPathRequestMatcher; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; + +public class LoginPhoneAuthFilter extends AbstractAuthenticationProcessingFilter { + + private ISmsService smsService; + + public LoginPhoneAuthFilter(ISmsService smsService) { + super(new AntPathRequestMatcher("/oauth/phone", "POST")); + this.smsService = smsService; + } + + @Override + public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException, IOException, ServletException { + String phone = request.getParameter("username").trim(); + String code = request.getParameter("code").trim(); + if (StringUtils.isBlank(phone)) { + throw new UserAuthenticationException("手机号不能为空"); + } + if (StringUtils.isBlank(code)) { + throw new UserAuthenticationException("验证码不能为空"); + } +// String verifyCode = smsService.getVerifyCode(phone); +// if (StringUtils.isBlank(verifyCode)) { +// throw new UserAuthenticationException("验证码错误"); +// } +// if (!StringUtils.equals(code, verifyCode)) { +// throw new UserAuthenticationException("验证码不匹配"); +// } + LoginPhoneAuthToken loginPhoneAuthToken = new LoginPhoneAuthToken(phone, null); + loginPhoneAuthToken.setDetails(authenticationDetailsSource.buildDetails(request)); + return this.getAuthenticationManager().authenticate(loginPhoneAuthToken); + } +} diff --git a/src/main/java/cn/com/tenlion/operator/login/phone/auth/LoginPhoneAuthProvider.java b/src/main/java/cn/com/tenlion/operator/login/phone/auth/LoginPhoneAuthProvider.java new file mode 100644 index 0000000..68ad3ea --- /dev/null +++ b/src/main/java/cn/com/tenlion/operator/login/phone/auth/LoginPhoneAuthProvider.java @@ -0,0 +1,75 @@ +package cn.com.tenlion.operator.login.phone.auth; + +import ink.wgink.interfaces.expand.login.ILoginHandlerService; +import ink.wgink.login.base.consts.IUserCenterConst; +import ink.wgink.login.base.enums.LoginTypeEnum; +import ink.wgink.login.base.exceptions.UserAuthenticationException; +import ink.wgink.login.base.service.user.UserLoginService; +import ink.wgink.pojo.bos.LoginUser; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.security.authentication.AuthenticationProvider; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.AuthenticationException; +import org.springframework.security.core.userdetails.UserDetailsService; + +import javax.servlet.http.HttpSession; + +public class LoginPhoneAuthProvider implements AuthenticationProvider { + private static final Logger LOG = LoggerFactory.getLogger(LoginPhoneAuthProvider.class); + private UserDetailsService userDetailsService; + private UserLoginService userLoginService; + private ILoginHandlerService loginHandler; + private HttpSession httpSession; + + public LoginPhoneAuthProvider(UserDetailsService userDetailsService, UserLoginService userLoginService, ILoginHandlerService loginHandler, HttpSession httpSession) { + this.userDetailsService = userDetailsService; + this.userLoginService = userLoginService; + this.loginHandler = loginHandler; + this.httpSession = httpSession; + } + + @Override + public Authentication authenticate(Authentication authentication) throws AuthenticationException { + LoginPhoneAuthToken loginPhoneAuthToken = (LoginPhoneAuthToken) authentication; + String username = (String) loginPhoneAuthToken.getPrincipal(); + httpSession.setAttribute(IUserCenterConst.LOGIN_USERNAME, username); + LoginUser loginUser = (LoginUser) userDetailsService.loadUserByUsername(username); + userLoginService.setLoginUserInfo(loginUser); + if (loginUser.getAuthorities().isEmpty()) { + throw new UserAuthenticationException(loginUser.getUsername() + "用户无任何角色"); + } + // 登录逻辑处理 + loginHandler(loginUser); + // 清空session中的错误信息 + httpSession.removeAttribute(IUserCenterConst.ERROR_MESSAGE); + httpSession.removeAttribute(IUserCenterConst.LOGIN_USERNAME); + // 更新登录信息 + userLoginService.updateUserLoginInfo(loginUser.getUserId(), loginUser.getUserName(), LoginTypeEnum.USERNAME_AND_PASSWORD.getValue()); + LoginPhoneAuthToken loginPhoneAuthTokenResult = new LoginPhoneAuthToken(loginUser, null, loginUser.getAuthorities()); + loginPhoneAuthTokenResult.setDetails(loginPhoneAuthToken.getDetails()); + return loginPhoneAuthTokenResult; + } + + @Override + public boolean supports(Class aClass) { + return LoginPhoneAuthToken.class.isAssignableFrom(aClass); + } + + /** + * 登录处理 + * + * @param loginUser + */ + private void loginHandler(LoginUser loginUser) { + if (loginHandler != null) { + try { + loginHandler.handle(loginUser); + } catch (Exception e) { + LOG.error(e.getMessage(), e); + throw new UserAuthenticationException("登录异常"); + } + } + } + +} diff --git a/src/main/java/cn/com/tenlion/operator/login/phone/auth/LoginPhoneAuthToken.java b/src/main/java/cn/com/tenlion/operator/login/phone/auth/LoginPhoneAuthToken.java new file mode 100644 index 0000000..f802f32 --- /dev/null +++ b/src/main/java/cn/com/tenlion/operator/login/phone/auth/LoginPhoneAuthToken.java @@ -0,0 +1,37 @@ +package cn.com.tenlion.operator.login.phone.auth; + +import org.springframework.security.authentication.AbstractAuthenticationToken; +import org.springframework.security.core.GrantedAuthority; + +import java.util.Collection; + +public class LoginPhoneAuthToken extends AbstractAuthenticationToken { + + private final Object principal; + private Object credentials; + + public LoginPhoneAuthToken(Object principal, Object credentials) { + super(null); + this.principal = principal; + this.credentials = credentials; + setAuthenticated(false); + } + + public LoginPhoneAuthToken(Object principal, Object credentials, Collection authorities) { + super(authorities); + this.principal = principal; + this.credentials = credentials; + setAuthenticated(true); + } + + @Override + public Object getCredentials() { + return credentials; + } + + @Override + public Object getPrincipal() { + return principal; + } + +} diff --git a/src/main/resources/templates/systemuser/login.html b/src/main/resources/templates/systemuser/login.html index eedd92b..6985943 100644 --- a/src/main/resources/templates/systemuser/login.html +++ b/src/main/resources/templates/systemuser/login.html @@ -288,7 +288,6 @@ } #loginBox .denglu .yzmtx1 { position: relative; - display: none; margin-bottom: 20px; width: 100%; height: 38px; @@ -306,7 +305,6 @@ border: none; } #loginBox .denglu .yzmbox1 { - display: none; width: 100%; height: 38px; line-height: 38px; @@ -404,11 +402,11 @@