diff --git a/maxkey-authentications/maxkey-authentication-provider/src/main/java/org/dromara/maxkey/authn/provider/AbstractAuthenticationProvider.java b/maxkey-authentications/maxkey-authentication-provider/src/main/java/org/dromara/maxkey/authn/provider/AbstractAuthenticationProvider.java index f071789e0..1d8298da5 100644 --- a/maxkey-authentications/maxkey-authentication-provider/src/main/java/org/dromara/maxkey/authn/provider/AbstractAuthenticationProvider.java +++ b/maxkey-authentications/maxkey-authentication-provider/src/main/java/org/dromara/maxkey/authn/provider/AbstractAuthenticationProvider.java @@ -64,6 +64,11 @@ public abstract class AbstractAuthenticationProvider { * 扫描认证 */ public static final String SCAN_CODE = "scancode"; + + /** + * 手机端APP + */ + public static final String APP = "app"; } protected ApplicationConfig applicationConfig; diff --git a/maxkey-authentications/maxkey-authentication-provider/src/main/java/org/dromara/maxkey/authn/provider/impl/AppAuthenticationProvider.java b/maxkey-authentications/maxkey-authentication-provider/src/main/java/org/dromara/maxkey/authn/provider/impl/AppAuthenticationProvider.java new file mode 100644 index 000000000..840687c8d --- /dev/null +++ b/maxkey-authentications/maxkey-authentication-provider/src/main/java/org/dromara/maxkey/authn/provider/impl/AppAuthenticationProvider.java @@ -0,0 +1,113 @@ +package org.dromara.maxkey.authn.provider.impl; + +import org.dromara.maxkey.authn.LoginCredential; +import org.dromara.maxkey.authn.jwt.AuthTokenService; +import org.dromara.maxkey.authn.provider.AbstractAuthenticationProvider; +import org.dromara.maxkey.authn.realm.AbstractAuthenticationRealm; +import org.dromara.maxkey.authn.session.SessionManager; +import org.dromara.maxkey.configuration.ApplicationConfig; +import org.dromara.maxkey.constants.ConstsLoginType; +import org.dromara.maxkey.entity.idm.UserInfo; +import org.dromara.maxkey.web.WebConstants; +import org.dromara.maxkey.web.WebContext; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.security.authentication.BadCredentialsException; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.AuthenticationException; + +/** + * @description: + * @author: orangeBabu + * @time: 19/8/2024 PM3:41 + */ +public class AppAuthenticationProvider extends AbstractAuthenticationProvider { + private static final Logger _logger = LoggerFactory.getLogger(AppAuthenticationProvider.class); + + public AppAuthenticationProvider() { + super(); + } + + public AppAuthenticationProvider( + AbstractAuthenticationRealm authenticationRealm, + ApplicationConfig applicationConfig, + SessionManager sessionManager, + AuthTokenService authTokenService) { + this.authenticationRealm = authenticationRealm; + this.applicationConfig = applicationConfig; + this.sessionManager = sessionManager; + this.authTokenService = authTokenService; + } + + + @Override + public String getProviderName() { + return "app" + PROVIDER_SUFFIX; + } + + @Override + public Authentication doAuthenticate(LoginCredential loginCredential) { + UsernamePasswordAuthenticationToken authenticationToken = null; + _logger.debug("Trying to authenticate user '{}' via {}", + loginCredential.getPrincipal(), getProviderName()); + try { + + _logger.debug("authentication {}", loginCredential); + + if(this.applicationConfig.getLoginConfig().isCaptcha()) { + captchaValid(loginCredential.getState(),loginCredential.getCaptcha()); + } + + emptyPasswordValid(loginCredential.getPassword()); + + emptyUsernameValid(loginCredential.getUsername()); + + //查询用户 + UserInfo userInfo = loadUserInfo(loginCredential.getUsername(), loginCredential.getPassword()); + + //Validate PasswordPolicy + authenticationRealm.getPasswordPolicyValidator().passwordPolicyValid(userInfo); + + statusValid(loginCredential, userInfo); + + //Match password + authenticationRealm.passwordMatches(userInfo, loginCredential.getPassword()); + + //apply PasswordSetType and resetBadPasswordCount + authenticationRealm.getPasswordPolicyValidator().applyPasswordPolicy(userInfo); + + authenticationToken = createOnlineTicket(loginCredential, userInfo); + // user authenticated + _logger.debug("'{}' authenticated successfully by {}.", + loginCredential.getPrincipal(), getProviderName()); + + authenticationRealm.insertLoginHistory(userInfo, + ConstsLoginType.LOCAL, + "", + "xe00000004", + WebConstants.LOGIN_RESULT.SUCCESS); + + } catch ( + AuthenticationException e) { + _logger.error("Failed to authenticate user {} via {}: {}", + loginCredential.getPrincipal(), + getProviderName(), + e.getMessage()); + WebContext.setAttribute( + WebConstants.LOGIN_ERROR_SESSION_MESSAGE, e.getMessage()); + } catch (Exception e) { + _logger.error("Login error Unexpected exception in {} authentication:\n{}", + getProviderName(), e.getMessage()); + } + + return authenticationToken; + } + + protected void captchaValid(String state ,String captcha) { + // for basic + if(!authTokenService.validateCaptcha(state,captcha)) { + throw new BadCredentialsException(WebContext.getI18nValue("login.error.captcha")); + } + } +} diff --git a/maxkey-authentications/maxkey-authentication-provider/src/main/java/org/dromara/maxkey/autoconfigure/AuthnProviderAutoConfiguration.java b/maxkey-authentications/maxkey-authentication-provider/src/main/java/org/dromara/maxkey/autoconfigure/AuthnProviderAutoConfiguration.java index 2bb59c5e5..a04933385 100644 --- a/maxkey-authentications/maxkey-authentication-provider/src/main/java/org/dromara/maxkey/autoconfigure/AuthnProviderAutoConfiguration.java +++ b/maxkey-authentications/maxkey-authentication-provider/src/main/java/org/dromara/maxkey/autoconfigure/AuthnProviderAutoConfiguration.java @@ -20,10 +20,7 @@ package org.dromara.maxkey.autoconfigure; import org.dromara.maxkey.authn.jwt.AuthTokenService; import org.dromara.maxkey.authn.provider.AbstractAuthenticationProvider; import org.dromara.maxkey.authn.provider.AuthenticationProviderFactory; -import org.dromara.maxkey.authn.provider.impl.MobileAuthenticationProvider; -import org.dromara.maxkey.authn.provider.impl.NormalAuthenticationProvider; -import org.dromara.maxkey.authn.provider.impl.ScanCodeAuthenticationProvider; -import org.dromara.maxkey.authn.provider.impl.TrustedAuthenticationProvider; +import org.dromara.maxkey.authn.provider.impl.*; import org.dromara.maxkey.authn.realm.AbstractAuthenticationRealm; import org.dromara.maxkey.authn.session.SessionManager; import org.dromara.maxkey.authn.support.rememberme.AbstractRemeberMeManager; @@ -51,13 +48,15 @@ public class AuthnProviderAutoConfiguration { NormalAuthenticationProvider normalAuthenticationProvider, MobileAuthenticationProvider mobileAuthenticationProvider, TrustedAuthenticationProvider trustedAuthenticationProvider, - ScanCodeAuthenticationProvider scanCodeAuthenticationProvider + ScanCodeAuthenticationProvider scanCodeAuthenticationProvider, + AppAuthenticationProvider appAuthenticationProvider ) { AuthenticationProviderFactory authenticationProvider = new AuthenticationProviderFactory(); authenticationProvider.addAuthenticationProvider(normalAuthenticationProvider); authenticationProvider.addAuthenticationProvider(mobileAuthenticationProvider); authenticationProvider.addAuthenticationProvider(trustedAuthenticationProvider); authenticationProvider.addAuthenticationProvider(scanCodeAuthenticationProvider); + authenticationProvider.addAuthenticationProvider(appAuthenticationProvider); return authenticationProvider; } @@ -89,6 +88,21 @@ public class AuthnProviderAutoConfiguration { ); } + @Bean + public AppAuthenticationProvider appAuthenticationProvider( + AbstractAuthenticationRealm authenticationRealm, + ApplicationConfig applicationConfig, + SessionManager sessionManager, + AuthTokenService authTokenService + ) { + return new AppAuthenticationProvider( + authenticationRealm, + applicationConfig, + sessionManager, + authTokenService + ); + } + @Bean public MobileAuthenticationProvider mobileAuthenticationProvider( AbstractAuthenticationRealm authenticationRealm, diff --git a/maxkey-web-frontend/maxkey-web-app/src/app/routes/passport/login/login.component.ts b/maxkey-web-frontend/maxkey-web-app/src/app/routes/passport/login/login.component.ts index 82e9e2756..69a90e6a9 100644 --- a/maxkey-web-frontend/maxkey-web-app/src/app/routes/passport/login/login.component.ts +++ b/maxkey-web-frontend/maxkey-web-app/src/app/routes/passport/login/login.component.ts @@ -102,6 +102,13 @@ export class UserLoginComponent implements OnInit, OnDestroy { //init socials,state this.authnService.clear(); + + this.get(); + + this.cdr.detectChanges(); + } + + get() { this.authnService .get({ remember_me: localStorage.getItem(CONSTS.REMEMBER) }) .pipe( @@ -141,7 +148,6 @@ export class UserLoginComponent implements OnInit, OnDestroy { } } }); - this.cdr.detectChanges(); } congressLogin(congress: string) { @@ -343,6 +349,8 @@ export class UserLoginComponent implements OnInit, OnDestroy { this.authnService.navigate({}); } else if (res.code === 20004) { this.qrexpire = true; + } else if (res.code === 20005) { + this.get() } // Handle response here diff --git a/maxkey-webs/maxkey-web-maxkey/src/main/java/org/dromara/maxkey/web/contorller/LoginEntryPoint.java b/maxkey-webs/maxkey-web-maxkey/src/main/java/org/dromara/maxkey/web/contorller/LoginEntryPoint.java index 75244a47a..7ee381cca 100644 --- a/maxkey-webs/maxkey-web-maxkey/src/main/java/org/dromara/maxkey/web/contorller/LoginEntryPoint.java +++ b/maxkey-webs/maxkey-web-maxkey/src/main/java/org/dromara/maxkey/web/contorller/LoginEntryPoint.java @@ -314,9 +314,9 @@ public class LoginEntryPoint { } catch (BusinessException businessException) { return new Message<>(businessException.getCode(), businessException.getMessage()); } + } else { + return new Message<>(20005, "state失效重新获取"); } - - return new Message<>(Message.FAIL); } @Operation(summary = "app扫描二维码", description = "扫描二维码登录", method = "POST")