Skip to content

Commit

Permalink
adding lockout expiration timestamp for attempt behaviour of authenti…
Browse files Browse the repository at this point in the history
…cation module
  • Loading branch information
skublik committed Mar 7, 2023
1 parent bfcda67 commit f56bcfb
Show file tree
Hide file tree
Showing 4 changed files with 127 additions and 81 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,9 @@ public void recordModuleAuthenticationAttemptSuccess(MidPointPrincipal principal
//authAttemptData.(behavioralData.getLastSuccessfulLogin());
authAttemptData.setLastSuccessfulAuthentication(event);

authAttemptData.setLockoutTimestamp(null);
authAttemptData.setLockoutExpirationTimestamp(null);

ActivationType activation = principal.getFocus().getActivation();
if (activation != null) {
if (LockoutStatusType.LOCKED.equals(activation.getLockoutStatus())) {
Expand Down Expand Up @@ -130,6 +133,8 @@ public void recordModuleAuthenticationAttemptFailure(MidPointPrincipal principal
lockoutExpirationTs = XmlTypeConverter.addDuration(event.getTimestamp(), lockoutDuration);
}
activation.setLockoutExpirationTimestamp(lockoutExpirationTs);
authAttemptData.setLockoutExpirationTimestamp(lockoutExpirationTs);
authAttemptData.setLockoutTimestamp(event.getTimestamp());
focusAfter.getTrigger().add(
new TriggerType()
.handlerUri(ModelPublicConstants.UNLOCK_TRIGGER_HANDLER_URI)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,6 @@

/**
* @author semancik
*
*/
public abstract class AuthenticationEvaluatorImpl<C extends AbstractCredentialType, T extends AbstractAuthenticationContext>
implements AuthenticationEvaluator<T>, MessageSourceAware {
Expand Down Expand Up @@ -171,7 +170,7 @@ private boolean checkCredentials(MidPointPrincipal principal, T authnCtx, Connec
return passwordMatches(connEnv, principal, getCredential(credentials), authnCtx);
}

private CredentialPolicyType getCredentialsPolicy(MidPointPrincipal principal, T authnCtx){
private CredentialPolicyType getCredentialsPolicy(MidPointPrincipal principal, T authnCtx) {
SecurityPolicyType securityPolicy = principal.getApplicableSecurityPolicy();
CredentialPolicyType credentialsPolicy;
try {
Expand All @@ -184,7 +183,6 @@ private CredentialPolicyType getCredentialsPolicy(MidPointPrincipal principal, T
return credentialsPolicy;
}


/**
* Special-purpose method used for Web Service authentication based on javax.security callbacks.
*
Expand All @@ -208,7 +206,6 @@ public String getAndCheckUserPassword(ConnectionEnvironment connEnv, String user
}
PasswordType passwordType = credentials.getPassword();


AuthenticationAttemptDataType authenticationAttemptData = getAuthenticationData(principal, connEnv);
// Lockout
if (isLockedOut(authenticationAttemptData, passwordCredentialsPolicy)) {
Expand Down Expand Up @@ -256,7 +253,7 @@ protected <C extends AbstractAuthenticationContext> MidPointPrincipal getAndChec
ObjectQuery query = authCtx.createFocusQuery();
String username = authCtx.getUsername();
if (query == null) {
recordModuleAuthenticationFailure(username, null, connEnv, null,"no username");
recordModuleAuthenticationFailure(username, null, connEnv, null, "no username");
throw new UsernameNotFoundException("web.security.provider.invalid.credentials");
}

Expand Down Expand Up @@ -298,12 +295,12 @@ protected <C extends AbstractAuthenticationContext> MidPointPrincipal getAndChec

protected boolean hasNoneAuthorization(MidPointPrincipal principal) {
Collection<Authorization> authorizations = principal.getAuthorities();
if (authorizations == null || authorizations.isEmpty()){
if (authorizations == null || authorizations.isEmpty()) {
return true;
}
boolean exist = false;
for (Authorization auth : authorizations){
if (auth.getAction() != null && !auth.getAction().isEmpty()){
for (Authorization auth : authorizations) {
if (auth.getAction() != null && !auth.getAction().isEmpty()) {
exist = true;
}
}
Expand Down Expand Up @@ -387,20 +384,29 @@ private int getFailedLogins(AuthenticationAttemptDataType authenticationAttemptD
}

private boolean isLockoutExpired(AuthenticationAttemptDataType authenticationAttemptData, CredentialPolicyType credentialsPolicy) {
Duration lockoutDuration = credentialsPolicy.getLockoutDuration();
if (lockoutDuration == null) {
return false;
}
XMLGregorianCalendar lockoutExpiration = authenticationAttemptData.getLockoutExpirationTimestamp();
if (lockoutExpiration != null) {
return clock.isPast(lockoutExpiration);
}

Duration lockoutDuration = credentialsPolicy.getLockoutDuration();
if (lockoutDuration == null) {
return false;
}

XMLGregorianCalendar lockTimestamp = authenticationAttemptData.getLockoutTimestamp();
if (lockTimestamp == null) {
LoginEventType lastFailedLogin = getLastFailedLogin(authenticationAttemptData);
if (lastFailedLogin == null) {
return true;
}
XMLGregorianCalendar lastFailedLoginTimestamp = lastFailedLogin.getTimestamp();
if (lastFailedLoginTimestamp == null) {
lockTimestamp = lastFailedLogin.getTimestamp();
if (lockTimestamp == null) {
return true;
}
XMLGregorianCalendar lockedUntilTimestamp = XmlTypeConverter.addDuration(lastFailedLoginTimestamp, lockoutDuration);
return clock.isPast(lockedUntilTimestamp);
}
XMLGregorianCalendar lockedUntilTimestamp = XmlTypeConverter.addDuration(lockTimestamp, lockoutDuration);
return clock.isPast(lockedUntilTimestamp);
}

private LoginEventType getLastFailedLogin(AuthenticationAttemptDataType authenticationAttemptData) {
Expand Down

0 comments on commit f56bcfb

Please sign in to comment.