ForgotPassword

This commit is contained in:
MaxKey
2022-04-25 22:00:45 +08:00
parent d6856b1f54
commit 7ddde38019
25 changed files with 599 additions and 160 deletions

View File

@@ -17,21 +17,26 @@
package org.maxkey.web.contorller;
public class ImageCaptcha {
String id;
String state;
String image;
public ImageCaptcha(String id, String image) {
public ImageCaptcha(String state, String image) {
super();
this.id = id;
this.state = state;
this.image = image;
}
public String getId() {
return id;
public String getState() {
return state;
}
public void setId(String id) {
this.id = id;
public void setState(String state) {
this.state = state;
}
public String getImage() {
return image;
}

View File

@@ -88,7 +88,7 @@ public class ImageCaptchaEndpoint {
}else {
state = authJwtService.genJwt();
}
kaptchaKey = authJwtService.resolveTicket(state);
kaptchaKey = authJwtService.resolveJWTID(state);
_logger.trace("kaptchaKey {} , Captcha Text is {}" ,kaptchaKey, kaptchaValue);
momentaryService.put("", kaptchaKey, kaptchaValue);

View File

@@ -30,7 +30,6 @@ import org.maxkey.constants.ConstsStatus;
import org.maxkey.entity.UserInfo;
import org.maxkey.password.onetimepwd.AbstractOtpAuthn;
import org.maxkey.password.onetimepwd.OtpAuthnService;
import org.maxkey.persistence.MomentaryService;
import org.maxkey.web.WebConstants;
import org.maxkey.web.WebContext;
import org.slf4j.Logger;
@@ -70,8 +69,6 @@ public abstract class AbstractAuthenticationProvider {
protected OnlineTicketService onlineTicketServices;
protected MomentaryService momentaryService;
protected AuthJwtService authJwtService;
public static ArrayList<GrantedAuthority> grantedAdministratorsAuthoritys = new ArrayList<GrantedAuthority>();

View File

@@ -19,11 +19,14 @@ package org.maxkey.authn.jwt;
import java.text.ParseException;
import java.util.Date;
import org.apache.commons.lang3.StringUtils;
import org.joda.time.DateTime;
import org.maxkey.authn.SigninPrincipal;
import org.maxkey.configuration.AuthJwkConfig;
import org.maxkey.crypto.jwt.HMAC512Service;
import org.maxkey.entity.UserInfo;
import org.maxkey.persistence.MomentaryService;
import org.maxkey.web.WebContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -44,6 +47,8 @@ public class AuthJwtService {
AuthJwkConfig authJwkConfig;
CongressService congressService;
MomentaryService momentaryService;
public AuthJwtService(AuthJwkConfig authJwkConfig) throws JOSEException {
this.authJwkConfig = authJwkConfig;
@@ -51,12 +56,16 @@ public class AuthJwtService {
this.hmac512Service = new HMAC512Service(authJwkConfig.getSecret());
}
public AuthJwtService(AuthJwkConfig authJwkConfig,CongressService congressService) throws JOSEException {
public AuthJwtService(AuthJwkConfig authJwkConfig,CongressService congressService,MomentaryService momentaryService) throws JOSEException {
this.authJwkConfig = authJwkConfig;
this.congressService = congressService;
this.momentaryService = momentaryService;
this.hmac512Service = new HMAC512Service(authJwkConfig.getSecret());
}
/**
@@ -156,7 +165,7 @@ public class AuthJwtService {
return signedJWT.getJWTClaimsSet();
}
public String resolveTicket(String authToken) throws ParseException {
public String resolveJWTID(String authToken) throws ParseException {
JWTClaimsSet claims = resolve(authToken);
return claims.getJWTID();
}
@@ -177,4 +186,21 @@ public class AuthJwtService {
return authJwt;
}
public boolean validateCaptcha(String state,String captcha) {
try {
String jwtId = resolveJWTID(state);
if(StringUtils.isNotBlank(jwtId) &&StringUtils.isNotBlank(captcha)) {
Object momentaryCaptcha = momentaryService.get("", jwtId);
_logger.debug("captcha : {}, momentary Captcha : {}" ,captcha, momentaryCaptcha);
if (!StringUtils.isBlank(captcha) && captcha.equals(momentaryCaptcha.toString())) {
momentaryService.remove("", jwtId);
return true;
}
}
} catch (ParseException e) {
_logger.debug("Exception ",e);
}
return false;
}
}

View File

@@ -26,7 +26,6 @@ import org.maxkey.configuration.ApplicationConfig;
import org.maxkey.constants.ConstsLoginType;
import org.maxkey.entity.Institutions;
import org.maxkey.entity.UserInfo;
import org.maxkey.persistence.MomentaryService;
import org.maxkey.web.WebConstants;
import org.maxkey.web.WebContext;
import org.slf4j.Logger;
@@ -59,13 +58,11 @@ public class MfaAuthenticationProvider extends AbstractAuthenticationProvider {
AbstractAuthenticationRealm authenticationRealm,
ApplicationConfig applicationConfig,
OnlineTicketService onlineTicketServices,
AuthJwtService authJwtService,
MomentaryService momentaryService) {
AuthJwtService authJwtService) {
this.authenticationRealm = authenticationRealm;
this.applicationConfig = applicationConfig;
this.onlineTicketServices = onlineTicketServices;
this.authJwtService = authJwtService;
this.momentaryService = momentaryService;
}
@Override

View File

@@ -18,7 +18,6 @@
package org.maxkey.authn.provider;
import java.text.ParseException;
import org.apache.commons.lang3.StringUtils;
import org.maxkey.authn.AbstractAuthenticationProvider;
import org.maxkey.authn.LoginCredential;
import org.maxkey.authn.jwt.AuthJwtService;
@@ -28,7 +27,6 @@ import org.maxkey.configuration.ApplicationConfig;
import org.maxkey.constants.ConstsLoginType;
import org.maxkey.entity.Institutions;
import org.maxkey.entity.UserInfo;
import org.maxkey.persistence.MomentaryService;
import org.maxkey.web.WebConstants;
import org.maxkey.web.WebContext;
import org.slf4j.Logger;
@@ -60,13 +58,11 @@ public class NormalAuthenticationProvider extends AbstractAuthenticationProvider
AbstractAuthenticationRealm authenticationRealm,
ApplicationConfig applicationConfig,
OnlineTicketService onlineTicketServices,
AuthJwtService authJwtService,
MomentaryService momentaryService) {
AuthJwtService authJwtService) {
this.authenticationRealm = authenticationRealm;
this.applicationConfig = applicationConfig;
this.onlineTicketServices = onlineTicketServices;
this.authJwtService = authJwtService;
this.momentaryService = momentaryService;
}
@Override
@@ -138,19 +134,8 @@ public class NormalAuthenticationProvider extends AbstractAuthenticationProvider
*/
protected void captchaValid(String state ,String captcha) throws ParseException {
// for basic
String ticket = authJwtService.resolveTicket(state);
if(ticket == null) {
if(!authJwtService.validateCaptcha(state,captcha)) {
throw new BadCredentialsException(WebContext.getI18nValue("login.error.captcha"));
}
Object momentaryCaptcha = momentaryService.get("", ticket);
_logger.info("captcha : {} , momentary Captcha : {} " ,captcha, momentaryCaptcha);
if (StringUtils.isBlank(captcha) || !captcha.equals(momentaryCaptcha.toString())) {
_logger.debug("login captcha valid error.");
throw new BadCredentialsException(WebContext.getI18nValue("login.error.captcha"));
}
momentaryService.remove("", ticket);
}
}
}

View File

@@ -73,7 +73,7 @@ public class AuthorizationUtils {
AuthJwtService authJwtService,
OnlineTicketService onlineTicketService) throws ParseException {
if(authJwtService.validateJwtToken(authorization)) {
String ticket = authJwtService.resolveTicket(authorization);
String ticket = authJwtService.resolveJWTID(authorization);
OnlineTicket onlineTicket = onlineTicketService.get(ticket);
if(onlineTicket != null) {
setAuthentication(onlineTicket.getAuthentication());

View File

@@ -87,16 +87,14 @@ public class AuthenticationAutoConfiguration implements InitializingBean {
AbstractAuthenticationRealm authenticationRealm,
ApplicationConfig applicationConfig,
OnlineTicketService onlineTicketServices,
AuthJwtService authJwtService,
MomentaryService momentaryService
AuthJwtService authJwtService
) {
_logger.debug("init authentication Provider .");
return new NormalAuthenticationProvider(
authenticationRealm,
applicationConfig,
onlineTicketServices,
authJwtService,
momentaryService
authJwtService
);
}
@@ -134,6 +132,7 @@ public class AuthenticationAutoConfiguration implements InitializingBean {
public AuthJwtService authJwtService(
AuthJwkConfig authJwkConfig,
RedisConnectionFactory redisConnFactory,
MomentaryService momentaryService,
@Value("${maxkey.server.persistence}") int persistence) throws JOSEException {
CongressService congressService;
if (persistence == ConstsPersistence.REDIS) {
@@ -142,7 +141,7 @@ public class AuthenticationAutoConfiguration implements InitializingBean {
congressService = new InMemoryCongressService();
}
AuthJwtService authJwtService = new AuthJwtService(authJwkConfig,congressService);
AuthJwtService authJwtService = new AuthJwtService(authJwkConfig,congressService,momentaryService);
return authJwtService;
}

View File

@@ -124,6 +124,32 @@ public class OtpAuthnService {
}
return otpAuthn;
}
public AbstractOtpAuthn getMailOtpAuthn(String instId) {
AbstractOtpAuthn otpAuthn = otpAuthnStore.getIfPresent(instId);
if(otpAuthn == null) {
EmailSenders emailSender =
emailSendersService.findOne("where instid = ? ", new Object[]{instId}, new int[]{Types.VARCHAR});
String credentials = PasswordReciprocal.getInstance().decoder(emailSender.getCredentials());
EmailConfig emailConfig =
new EmailConfig(
emailSender.getAccount(),
credentials,
emailSender.getSmtpHost(),
emailSender.getPort(),
ConstsBoolean.isTrue(emailSender.getSslSwitch()),
emailSender.getSender());
MailOtpAuthn mailOtpAuthn = new MailOtpAuthn(emailConfig);
mailOtpAuthn.setInterval(60 * 5);//5 minute
if(redisOptTokenStore != null) {
mailOtpAuthn.setOptTokenStore(redisOptTokenStore);
}
otpAuthn = mailOtpAuthn;
}
otpAuthnStore.put(instId, otpAuthn);
return otpAuthn;
}
public void setRedisOptTokenStore(RedisOtpTokenStore redisOptTokenStore) {
this.redisOptTokenStore = redisOptTokenStore;