This commit is contained in:
MaxKey
2022-04-21 17:06:05 +08:00
parent 586e473e48
commit 7bba47a46c
26 changed files with 688 additions and 435 deletions

View File

@@ -20,6 +20,7 @@ package org.maxkey.authn;
import java.util.ArrayList;
import java.util.HashMap;
import org.maxkey.authn.jwt.AuthJwtService;
import org.maxkey.authn.online.OnlineTicketService;
import org.maxkey.authn.realm.AbstractAuthenticationRealm;
import org.maxkey.configuration.ApplicationConfig;
@@ -28,6 +29,7 @@ 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;
@@ -51,7 +53,14 @@ public abstract class AbstractAuthenticationProvider {
public final static String NORMAL = "normal";
public final static String TFA = "tfa";
public final static String MOBILE = "mobile";
public final static String TRUSTED = "trusted";
}
protected static String PROVIDER_SUFFIX = "AuthenticationProvider";
private static HashMap<String,AbstractAuthenticationProvider> providers =
new HashMap<String,AbstractAuthenticationProvider>();
protected ApplicationConfig applicationConfig;
protected AbstractAuthenticationRealm authenticationRealm;
@@ -62,87 +71,42 @@ public abstract class AbstractAuthenticationProvider {
protected OnlineTicketService onlineTicketServices;
protected MomentaryService momentaryService;
protected AuthJwtService authJwtService;
public static ArrayList<GrantedAuthority> grantedAdministratorsAuthoritys = new ArrayList<GrantedAuthority>();
static {
grantedAdministratorsAuthoritys.add(new SimpleGrantedAuthority("ROLE_ADMINISTRATORS"));
}
protected abstract String getProviderName();
public abstract String getProviderName();
public abstract Authentication authenticate(LoginCredential authentication);
public abstract Authentication authentication(LoginCredential loginCredential,boolean isTrusted);
public abstract Authentication doAuthenticate(LoginCredential authentication);
@SuppressWarnings("rawtypes")
public boolean supports(Class authentication) {
return (UsernamePasswordAuthenticationToken.class.isAssignableFrom(authentication));
}
protected void changeSession(Authentication authentication) {
HashMap<String,Object> sessionAttributeMap = new HashMap<String,Object>();
for(String attributeName : WebContext.sessionAttributeNameList) {
sessionAttributeMap.put(attributeName, WebContext.getAttribute(attributeName));
WebContext.removeAttribute(attributeName);
}
//new Session
WebContext.getSession().invalidate();
for(String attributeName : WebContext.sessionAttributeNameList) {
WebContext.setAttribute(attributeName, sessionAttributeMap.get(attributeName));
}
public Authentication authenticate(LoginCredential authentication){
if(authentication.getAuthType().equalsIgnoreCase("trusted")) {
return null;
}
AbstractAuthenticationProvider provider = providers.get(authentication.getAuthType() + PROVIDER_SUFFIX);
return provider == null ? null : provider.doAuthenticate(authentication);
}
/**
* session validate.
*
* @param sessionId String
*/
protected void sessionValid(String sessionId) {
if (sessionId == null || !sessionId.equals(WebContext.getSession().getId())) {
_logger.debug("login session valid error.");
_logger.debug("login session sessionId " + sessionId);
_logger.debug("login getSession sessionId " + WebContext.getSession().getId());
String message = WebContext.getI18nValue("login.error.session");
throw new BadCredentialsException(message);
}
public Authentication authenticate(LoginCredential authentication,boolean trusted){
AbstractAuthenticationProvider provider = providers.get(AuthType.TRUSTED + PROVIDER_SUFFIX);
return provider == null ? null : provider.doAuthenticate(authentication);
}
/**
* session validate.
*
* @param jwtToken String
*/
protected void jwtTokenValid(String jwtToken) {
/*
* if(jwtToken!=null && ! jwtToken.equals("")){
* if(jwtLoginService.jwtTokenValidation(j_jwtToken)){ return; } }
*/
String message = WebContext.getI18nValue("login.error.session");
_logger.debug("login session valid error.");
throw new BadCredentialsException(message);
public void addAuthenticationProvider(AbstractAuthenticationProvider provider) {
providers.put(provider.getProviderName(), provider);
}
protected void authTypeValid(String authType) {
_logger.debug("Login AuthN Type " + authType);
if (authType != null && (
authType.equalsIgnoreCase(AuthType.NORMAL)
|| authType.equalsIgnoreCase(AuthType.TFA)
|| authType.equalsIgnoreCase(AuthType.MOBILE)
)
) {
return;
}
final String message = WebContext.getI18nValue("login.error.authtype");
_logger.debug("Login AuthN type must eq basic or tfa Error message is {}" , message);
throw new BadCredentialsException(message);
}
/**
* captcha validate .
*
@@ -189,28 +153,7 @@ public abstract class AbstractAuthenticationProvider {
}
}
/**
* mobile validate.
*
* @param otpCaptcha String
* @param authType String
* @param userInfo UserInfo
*/
protected void mobilecaptchaValid(String password, String authType, UserInfo userInfo) {
// for mobile password
if (applicationConfig.getLoginConfig().isMfa()
&& authType.equalsIgnoreCase(AuthType.MOBILE)) {
UserInfo validUserInfo = new UserInfo();
validUserInfo.setUsername(userInfo.getUsername());
validUserInfo.setId(userInfo.getId());
AbstractOtpAuthn smsOtpAuthn = otpAuthnService.getByInstId(userInfo.getInstId());
if (password == null || !smsOtpAuthn.validate(validUserInfo, password)) {
String message = WebContext.getI18nValue("login.error.captcha");
_logger.debug("login captcha valid error.");
throw new BadCredentialsException(message);
}
}
}
/**
* login user by j_username and j_cname first query user by j_cname if first

View File

@@ -33,7 +33,7 @@ public class LoginCredential implements Authentication {
String congress;
String username;
String password;
String sessionId;
String state;
String captcha;
String otpCaptcha;
String remeberMe;
@@ -126,15 +126,15 @@ public class LoginCredential implements Authentication {
this.password = password;
}
public String getSessionId() {
return sessionId;
}
public String getState() {
return state;
}
public void setSessionId(String sessionId) {
this.sessionId = sessionId;
}
public void setState(String state) {
this.state = state;
}
public String getCaptcha() {
public String getCaptcha() {
return captcha;
}
@@ -233,12 +233,14 @@ public class LoginCredential implements Authentication {
@Override
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append("LoginCredential [username=");
builder.append("LoginCredential [congress=");
builder.append(congress);
builder.append(", username=");
builder.append(username);
builder.append(", password=");
builder.append("******");
builder.append(", sessionId=");
builder.append(sessionId);
builder.append(password);
builder.append(", state=");
builder.append(state);
builder.append(", captcha=");
builder.append(captcha);
builder.append(", otpCaptcha=");

View File

@@ -15,10 +15,14 @@
*/
package org.maxkey.authn;
package org.maxkey.authn.provider;
import java.util.ArrayList;
import org.maxkey.authn.AbstractAuthenticationProvider;
import org.maxkey.authn.LoginCredential;
import org.maxkey.authn.SigninPrincipal;
import org.maxkey.authn.jwt.AuthJwtService;
import org.maxkey.authn.online.OnlineTicket;
import org.maxkey.authn.online.OnlineTicketService;
import org.maxkey.authn.realm.AbstractAuthenticationRealm;
@@ -27,13 +31,11 @@ import org.maxkey.configuration.ApplicationConfig;
import org.maxkey.constants.ConstsLoginType;
import org.maxkey.entity.Institutions;
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;
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;
@@ -46,47 +48,40 @@ import org.springframework.security.web.authentication.WebAuthenticationDetails;
* @author Crystal.Sea
*
*/
public class RealmAuthenticationProvider extends AbstractAuthenticationProvider {
public class MfaAuthenticationProvider extends AbstractAuthenticationProvider {
private static final Logger _logger =
LoggerFactory.getLogger(RealmAuthenticationProvider.class);
LoggerFactory.getLogger(MfaAuthenticationProvider.class);
protected String getProviderName() {
return "RealmAuthenticationProvider";
public String getProviderName() {
return "normal" + PROVIDER_SUFFIX;
}
public RealmAuthenticationProvider() {
public MfaAuthenticationProvider() {
super();
}
public RealmAuthenticationProvider(
public MfaAuthenticationProvider(
AbstractAuthenticationRealm authenticationRealm,
ApplicationConfig applicationConfig,
AbstractOtpAuthn tfaOtpAuthn,
OtpAuthnService otpAuthnService,
OnlineTicketService onlineTicketServices) {
OnlineTicketService onlineTicketServices,
AuthJwtService authJwtService,
MomentaryService momentaryService) {
this.authenticationRealm = authenticationRealm;
this.applicationConfig = applicationConfig;
this.tfaOtpAuthn = tfaOtpAuthn;
this.otpAuthnService = otpAuthnService;
this.onlineTicketServices = onlineTicketServices;
this.authJwtService = authJwtService;
this.momentaryService = momentaryService;
}
@Override
public Authentication authenticate(LoginCredential loginCredential) {
public Authentication doAuthenticate(LoginCredential loginCredential) {
UsernamePasswordAuthenticationToken authenticationToken = null;
_logger.debug("Trying to authenticate user '{}' via {}",
loginCredential.getPrincipal(), getProviderName());
try {
_logger.debug("authentication " + loginCredential);
//sessionValid(loginCredential.getSessionId());
//jwtTokenValid(j_jwtToken);
authTypeValid(loginCredential.getAuthType());
Institutions inst = (Institutions)WebContext.getAttribute(WebConstants.CURRENT_INST);
if(inst.getCaptchaSupport().equalsIgnoreCase("YES")) {
@@ -107,12 +102,10 @@ public class RealmAuthenticationProvider extends AbstractAuthenticationProvider
//Validate PasswordPolicy
authenticationRealm.getPasswordPolicyValidator().passwordPolicyValid(userInfo);
if(loginCredential.getAuthType().equalsIgnoreCase(AuthType.MOBILE)) {
mobilecaptchaValid(loginCredential.getPassword(),loginCredential.getAuthType(),userInfo);
}else {
//Match password
authenticationRealm.passwordMatches(userInfo, loginCredential.getPassword());
}
//Match password
authenticationRealm.passwordMatches(userInfo, loginCredential.getPassword());
//apply PasswordSetType and resetBadPasswordCount
authenticationRealm.getPasswordPolicyValidator().applyPasswordPolicy(userInfo);
@@ -121,8 +114,6 @@ public class RealmAuthenticationProvider extends AbstractAuthenticationProvider
_logger.debug("'{}' authenticated successfully by {}.",
loginCredential.getPrincipal(), getProviderName());
changeSession(authenticationToken);
authenticationRealm.insertLoginHistory(userInfo,
ConstsLoginType.LOCAL,
"",
@@ -143,46 +134,6 @@ public class RealmAuthenticationProvider extends AbstractAuthenticationProvider
return authenticationToken;
}
/**
* trustAuthentication.
* @param username String
* @param type String
* @param provider String
* @param code String
* @param message String
* @return boolean
*/
@Override
public Authentication authentication(LoginCredential loginCredential,boolean isTrusted) {
UserInfo loadeduserInfo = loadUserInfo(loginCredential.getUsername(), "");
statusValid(loginCredential , loadeduserInfo);
if (loadeduserInfo != null) {
//Validate PasswordPolicy
authenticationRealm.getPasswordPolicyValidator().passwordPolicyValid(loadeduserInfo);
if(!isTrusted) {
authenticationRealm.passwordMatches(loadeduserInfo, loginCredential.getPassword());
}
//apply PasswordSetType and resetBadPasswordCount
authenticationRealm.getPasswordPolicyValidator().applyPasswordPolicy(loadeduserInfo);
Authentication authentication = createOnlineSession(loginCredential,loadeduserInfo);
authenticationRealm.insertLoginHistory( loadeduserInfo,
loginCredential.getAuthType(),
loginCredential.getProvider(),
loginCredential.getCode(),
loginCredential.getMessage()
);
return authentication;
}else {
String i18nMessage = WebContext.getI18nValue("login.error.username");
_logger.debug("login user {} not in this System . {}" ,
loginCredential.getUsername(),i18nMessage);
throw new BadCredentialsException(WebContext.getI18nValue("login.error.username"));
}
}
public UsernamePasswordAuthenticationToken createOnlineSession(LoginCredential credential,UserInfo userInfo) {
//Online Tickit
OnlineTicket onlineTicket = new OnlineTicket();

View File

@@ -0,0 +1,142 @@
/*
* Copyright [2022] [MaxKey of copyright http://www.maxkey.top]
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.maxkey.authn.provider;
import org.maxkey.authn.LoginCredential;
import org.maxkey.authn.online.OnlineTicketService;
import org.maxkey.authn.realm.AbstractAuthenticationRealm;
import org.maxkey.configuration.ApplicationConfig;
import org.maxkey.constants.ConstsLoginType;
import org.maxkey.entity.UserInfo;
import org.maxkey.password.onetimepwd.AbstractOtpAuthn;
import org.maxkey.password.onetimepwd.OtpAuthnService;
import org.maxkey.web.WebConstants;
import org.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;
/**
* Mobile Authentication provider.
* @author Crystal.Sea
*
*/
public class MobileAuthenticationProvider extends NormalAuthenticationProvider {
private static final Logger _logger =
LoggerFactory.getLogger(MobileAuthenticationProvider.class);
public String getProviderName() {
return "mobile" + PROVIDER_SUFFIX;
}
public MobileAuthenticationProvider() {
super();
}
public MobileAuthenticationProvider(
AbstractAuthenticationRealm authenticationRealm,
ApplicationConfig applicationConfig,
OtpAuthnService otpAuthnService,
OnlineTicketService onlineTicketServices) {
this.authenticationRealm = authenticationRealm;
this.applicationConfig = applicationConfig;
this.otpAuthnService = otpAuthnService;
this.onlineTicketServices = onlineTicketServices;
}
@Override
public Authentication authenticate(LoginCredential loginCredential) {
UsernamePasswordAuthenticationToken authenticationToken = null;
_logger.debug("Trying to authenticate user '{}' via {}",
loginCredential.getPrincipal(), getProviderName());
try {
_logger.debug("authentication " + loginCredential);
emptyPasswordValid(loginCredential.getPassword());
emptyUsernameValid(loginCredential.getUsername());
UserInfo userInfo = loadUserInfo(loginCredential.getUsername(),loginCredential.getPassword());
statusValid(loginCredential , userInfo);
//Validate PasswordPolicy
authenticationRealm.getPasswordPolicyValidator().passwordPolicyValid(userInfo);
mobilecaptchaValid(loginCredential.getPassword(),userInfo);
//apply PasswordSetType and resetBadPasswordCount
authenticationRealm.getPasswordPolicyValidator().applyPasswordPolicy(userInfo);
authenticationToken = createOnlineSession(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 {}: {}",
new Object[] { 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;
}
/**
* mobile validate.
*
* @param otpCaptcha String
* @param authType String
* @param userInfo UserInfo
*/
protected void mobilecaptchaValid(String password, UserInfo userInfo) {
// for mobile password
if (applicationConfig.getLoginConfig().isMfa()) {
UserInfo validUserInfo = new UserInfo();
validUserInfo.setUsername(userInfo.getUsername());
validUserInfo.setId(userInfo.getId());
AbstractOtpAuthn smsOtpAuthn = otpAuthnService.getByInstId(userInfo.getInstId());
if (password == null || !smsOtpAuthn.validate(validUserInfo, password)) {
String message = WebContext.getI18nValue("login.error.captcha");
_logger.debug("login captcha valid error.");
throw new BadCredentialsException(message);
}
}
}
}

View File

@@ -0,0 +1,178 @@
/*
* Copyright [2022] [MaxKey of copyright http://www.maxkey.top]
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.maxkey.authn.provider;
import java.util.ArrayList;
import org.maxkey.authn.AbstractAuthenticationProvider;
import org.maxkey.authn.LoginCredential;
import org.maxkey.authn.SigninPrincipal;
import org.maxkey.authn.jwt.AuthJwtService;
import org.maxkey.authn.online.OnlineTicket;
import org.maxkey.authn.online.OnlineTicketService;
import org.maxkey.authn.realm.AbstractAuthenticationRealm;
import org.maxkey.authn.web.AuthorizationUtils;
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;
import org.slf4j.LoggerFactory;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.web.authentication.WebAuthenticationDetails;
/**
* database Authentication provider.
* @author Crystal.Sea
*
*/
public class NormalAuthenticationProvider extends AbstractAuthenticationProvider {
private static final Logger _logger =
LoggerFactory.getLogger(NormalAuthenticationProvider.class);
public String getProviderName() {
return "normal" + PROVIDER_SUFFIX;
}
public NormalAuthenticationProvider() {
super();
}
public NormalAuthenticationProvider(
AbstractAuthenticationRealm authenticationRealm,
ApplicationConfig applicationConfig,
OnlineTicketService onlineTicketServices,
AuthJwtService authJwtService,
MomentaryService momentaryService) {
this.authenticationRealm = authenticationRealm;
this.applicationConfig = applicationConfig;
this.onlineTicketServices = onlineTicketServices;
this.authJwtService = authJwtService;
this.momentaryService = momentaryService;
}
@Override
public Authentication doAuthenticate(LoginCredential loginCredential) {
UsernamePasswordAuthenticationToken authenticationToken = null;
_logger.debug("Trying to authenticate user '{}' via {}",
loginCredential.getPrincipal(), getProviderName());
try {
_logger.debug("authentication " + loginCredential);
Institutions inst = (Institutions)WebContext.getAttribute(WebConstants.CURRENT_INST);
if(inst.getCaptchaSupport().equalsIgnoreCase("YES")) {
captchaValid(loginCredential.getCaptcha(),loginCredential.getAuthType());
}
emptyPasswordValid(loginCredential.getPassword());
emptyUsernameValid(loginCredential.getUsername());
UserInfo userInfo = loadUserInfo(loginCredential.getUsername(),loginCredential.getPassword());
statusValid(loginCredential , userInfo);
//Validate PasswordPolicy
authenticationRealm.getPasswordPolicyValidator().passwordPolicyValid(userInfo);
//Match password
authenticationRealm.passwordMatches(userInfo, loginCredential.getPassword());
//apply PasswordSetType and resetBadPasswordCount
authenticationRealm.getPasswordPolicyValidator().applyPasswordPolicy(userInfo);
authenticationToken = createOnlineSession(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 {}: {}",
new Object[] { 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;
}
public UsernamePasswordAuthenticationToken createOnlineSession(LoginCredential credential,UserInfo userInfo) {
//Online Tickit
OnlineTicket onlineTicket = new OnlineTicket();
userInfo.setOnlineTicket(onlineTicket.getTicketId());
SigninPrincipal principal = new SigninPrincipal(userInfo);
//set OnlineTicket
principal.setOnlineTicket(onlineTicket);
ArrayList<GrantedAuthority> grantedAuthoritys = authenticationRealm.grantAuthority(userInfo);
principal.setAuthenticated(true);
for(GrantedAuthority administratorsAuthority : grantedAdministratorsAuthoritys) {
if(grantedAuthoritys.contains(administratorsAuthority)) {
principal.setRoleAdministrators(true);
_logger.trace("ROLE ADMINISTRATORS Authentication .");
}
}
_logger.debug("Granted Authority {}" , grantedAuthoritys);
principal.setGrantedAuthorityApps(authenticationRealm.queryAuthorizedApps(grantedAuthoritys));
UsernamePasswordAuthenticationToken authenticationToken =
new UsernamePasswordAuthenticationToken(
principal,
"PASSWORD",
grantedAuthoritys
);
authenticationToken.setDetails(
new WebAuthenticationDetails(WebContext.getRequest()));
onlineTicket.setAuthentication(authenticationToken);
//store onlineTicket
this.onlineTicketServices.store(onlineTicket.getTicketId(), onlineTicket);
/*
* put Authentication to current session context
*/
AuthorizationUtils.setAuthentication(authenticationToken);
return authenticationToken;
}
}

View File

@@ -0,0 +1,84 @@
/*
* Copyright [2022] [MaxKey of copyright http://www.maxkey.top]
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.maxkey.authn.provider;
import org.maxkey.authn.LoginCredential;
import org.maxkey.authn.online.OnlineTicketService;
import org.maxkey.authn.realm.AbstractAuthenticationRealm;
import org.maxkey.configuration.ApplicationConfig;
import org.maxkey.entity.UserInfo;
import org.maxkey.web.WebContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.core.Authentication;
/**
* Trusted Authentication provider.
* @author Crystal.Sea
*
*/
public class TrustedAuthenticationProvider extends NormalAuthenticationProvider {
private static final Logger _logger =
LoggerFactory.getLogger(TrustedAuthenticationProvider.class);
public String getProviderName() {
return "trusted" + PROVIDER_SUFFIX;
}
public TrustedAuthenticationProvider() {
super();
}
public TrustedAuthenticationProvider(
AbstractAuthenticationRealm authenticationRealm,
ApplicationConfig applicationConfig,
OnlineTicketService onlineTicketServices) {
this.authenticationRealm = authenticationRealm;
this.applicationConfig = applicationConfig;
this.onlineTicketServices = onlineTicketServices;
}
@Override
public Authentication doAuthenticate(LoginCredential loginCredential) {
UserInfo loadeduserInfo = loadUserInfo(loginCredential.getUsername(), "");
statusValid(loginCredential , loadeduserInfo);
if (loadeduserInfo != null) {
//Validate PasswordPolicy
authenticationRealm.getPasswordPolicyValidator().passwordPolicyValid(loadeduserInfo);
//apply PasswordSetType and resetBadPasswordCount
authenticationRealm.getPasswordPolicyValidator().applyPasswordPolicy(loadeduserInfo);
Authentication authentication = createOnlineSession(loginCredential,loadeduserInfo);
authenticationRealm.insertLoginHistory( loadeduserInfo,
loginCredential.getAuthType(),
loginCredential.getProvider(),
loginCredential.getCode(),
loginCredential.getMessage()
);
return authentication;
}else {
String i18nMessage = WebContext.getI18nValue("login.error.username");
_logger.debug("login user {} not in this System . {}" ,
loginCredential.getUsername(),i18nMessage);
throw new BadCredentialsException(WebContext.getI18nValue("login.error.username"));
}
}
}

View File

@@ -0,0 +1 @@
package org.maxkey.authn.provider;

View File

@@ -131,7 +131,7 @@ public class BasicEntryPoint implements AsyncHandlerInterceptor {
if(!isAuthenticated){
LoginCredential loginCredential =new LoginCredential(headerCredential.getUsername(),"",ConstsLoginType.BASIC);
authenticationProvider.authentication(loginCredential,true);
authenticationProvider.authenticate(loginCredential,true);
_logger.info("Authentication "+headerCredential.getUsername()+" successful .");
}

View File

@@ -110,7 +110,7 @@ public class HttpHeaderEntryPoint implements AsyncHandlerInterceptor {
if(!isAuthenticated){
LoginCredential loginCredential =new LoginCredential(httpHeaderUsername,"",ConstsLoginType.HTTPHEADER);
authenticationProvider.authentication(loginCredential,true);
authenticationProvider.authenticate(loginCredential,true);
_logger.info("Authentication "+httpHeaderUsername+" successful .");
}

View File

@@ -79,7 +79,7 @@ public class HttpJwtEntryPoint implements AsyncHandlerInterceptor {
if(signedJWT != null) {
String username =signedJWT.getJWTClaimsSet().getSubject();
LoginCredential loginCredential =new LoginCredential(username,"",ConstsLoginType.JWT);
authenticationProvider.authentication(loginCredential,true);
authenticationProvider.authenticate(loginCredential,true);
_logger.debug("JWT Logined in , username " + username);
}

View File

@@ -97,7 +97,7 @@ public class HttpKerberosEntryPoint implements AsyncHandlerInterceptor {
if(notOnOrAfter.isAfterNow()){
LoginCredential loginCredential =new LoginCredential(kerberosToken.getPrincipal(),"",ConstsLoginType.KERBEROS);
loginCredential.setProvider(kerberosUserDomain);
authenticationProvider.authentication(loginCredential,true);
authenticationProvider.authenticate(loginCredential,true);
_logger.debug("Kerberos Logined in , username " + kerberosToken.getPrincipal());
}

View File

@@ -100,7 +100,7 @@ public class HttpWsFederationEntryPoint implements AsyncHandlerInterceptor {
}
LoginCredential loginCredential =new LoginCredential(
wsFederationCredential.getAttributes().get("").toString(),"",ConstsLoginType.WSFEDERATION);
authenticationProvider.authentication(loginCredential,true);
authenticationProvider.authenticate(loginCredential,true);
return true;
} else {
_logger.warn("SAML assertions are blank or no longer valid.");

View File

@@ -1,5 +1,5 @@
/*
* Copyright [2020] [MaxKey of copyright http://www.maxkey.top]
* Copyright [2022] [MaxKey of copyright http://www.maxkey.top]
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -18,7 +18,6 @@
package org.maxkey.autoconfigure;
import org.maxkey.authn.AbstractAuthenticationProvider;
import org.maxkey.authn.RealmAuthenticationProvider;
import org.maxkey.authn.SavedRequestAwareAuthenticationSuccessHandler;
import org.maxkey.authn.jwt.AuthJwtService;
import org.maxkey.authn.jwt.CongressService;
@@ -26,6 +25,9 @@ import org.maxkey.authn.jwt.InMemoryCongressService;
import org.maxkey.authn.jwt.RedisCongressService;
import org.maxkey.authn.online.OnlineTicketService;
import org.maxkey.authn.online.OnlineTicketServiceFactory;
import org.maxkey.authn.provider.MobileAuthenticationProvider;
import org.maxkey.authn.provider.NormalAuthenticationProvider;
import org.maxkey.authn.provider.TrustedAuthenticationProvider;
import org.maxkey.authn.realm.AbstractAuthenticationRealm;
import org.maxkey.authn.web.SessionListenerAdapter;
import org.maxkey.configuration.ApplicationConfig;
@@ -34,6 +36,7 @@ import org.maxkey.constants.ConstsPersistence;
import org.maxkey.password.onetimepwd.AbstractOtpAuthn;
import org.maxkey.password.onetimepwd.OtpAuthnService;
import org.maxkey.password.onetimepwd.token.RedisOtpTokenStore;
import org.maxkey.persistence.MomentaryService;
import org.maxkey.persistence.redis.RedisConnectionFactory;
import org.maxkey.persistence.repository.LoginHistoryRepository;
import org.maxkey.persistence.repository.LoginRepository;
@@ -68,20 +71,61 @@ public class AuthenticationAutoConfiguration implements InitializingBean {
public AbstractAuthenticationProvider authenticationProvider(
AbstractAuthenticationRealm authenticationRealm,
ApplicationConfig applicationConfig,
AbstractOtpAuthn tfaOtpAuthn,
OtpAuthnService otpAuthnService,
OnlineTicketService onlineTicketServices
OnlineTicketService onlineTicketServices,
AuthJwtService authJwtService,
MomentaryService momentaryService
) {
_logger.debug("init authentication Provider .");
return new RealmAuthenticationProvider(
NormalAuthenticationProvider normal = new NormalAuthenticationProvider(
authenticationRealm,
applicationConfig,
onlineTicketServices,
authJwtService,
momentaryService
);
normal.addAuthenticationProvider(normal);
return normal;
}
@Bean(name = "mobileAuthenticationProvider")
public AbstractAuthenticationProvider mobileAuthenticationProvider(
AbstractAuthenticationRealm authenticationRealm,
ApplicationConfig applicationConfig,
OtpAuthnService otpAuthnService,
OnlineTicketService onlineTicketServices,
AbstractAuthenticationProvider authenticationProvider
) {
MobileAuthenticationProvider mobile = new MobileAuthenticationProvider(
authenticationRealm,
applicationConfig,
tfaOtpAuthn,
otpAuthnService,
onlineTicketServices
);
);
authenticationProvider.addAuthenticationProvider(mobile);
_logger.debug("init Mobile authentication Provider .");
return mobile;
}
@Bean(name = "trustedAuthenticationProvider")
public AbstractAuthenticationProvider trustedAuthenticationProvider(
AbstractAuthenticationRealm authenticationRealm,
ApplicationConfig applicationConfig,
OnlineTicketService onlineTicketServices,
AbstractAuthenticationProvider authenticationProvider
) {
TrustedAuthenticationProvider trusted = new TrustedAuthenticationProvider(
authenticationRealm,
applicationConfig,
onlineTicketServices
);
authenticationProvider.addAuthenticationProvider(trusted);
_logger.debug("init Mobile authentication Provider .");
return trusted;
}
@Bean(name = "authJwtService")