/** * Instantiates a new account state handler, that populates * the error map with LDAP error codes and corresponding exceptions. */ public DefaultAccountStateHandler() { this.errorMap = new HashMap<>(); this.errorMap.put(ActiveDirectoryAccountState.Error.ACCOUNT_DISABLED, new AccountDisabledException()); this.errorMap.put(ActiveDirectoryAccountState.Error.ACCOUNT_LOCKED_OUT, new AccountLockedException()); this.errorMap.put(ActiveDirectoryAccountState.Error.INVALID_LOGON_HOURS, new InvalidLoginTimeException()); this.errorMap.put(ActiveDirectoryAccountState.Error.INVALID_WORKSTATION, new InvalidLoginLocationException()); this.errorMap.put(ActiveDirectoryAccountState.Error.PASSWORD_MUST_CHANGE, new AccountPasswordMustChangeException()); this.errorMap.put(ActiveDirectoryAccountState.Error.PASSWORD_EXPIRED, new CredentialExpiredException()); this.errorMap.put(EDirectoryAccountState.Error.ACCOUNT_EXPIRED, new AccountExpiredException()); this.errorMap.put(EDirectoryAccountState.Error.LOGIN_LOCKOUT, new AccountLockedException()); this.errorMap.put(EDirectoryAccountState.Error.LOGIN_TIME_LIMITED, new InvalidLoginTimeException()); this.errorMap.put(EDirectoryAccountState.Error.PASSWORD_EXPIRED, new CredentialExpiredException()); this.errorMap.put(PasswordExpirationAccountState.Error.PASSWORD_EXPIRED, new CredentialExpiredException()); this.errorMap.put(PasswordPolicyControl.Error.ACCOUNT_LOCKED, new AccountLockedException()); this.errorMap.put(PasswordPolicyControl.Error.PASSWORD_EXPIRED, new CredentialExpiredException()); this.errorMap.put(PasswordPolicyControl.Error.CHANGE_AFTER_RESET, new AccountPasswordMustChangeException()); }
/** * Instantiates a new account state handler, that populates * the error map with LDAP error codes and corresponding exceptions. */ public DefaultAccountStateHandler() { this.errorMap = new HashMap<>(); this.errorMap.put(ActiveDirectoryAccountState.Error.ACCOUNT_DISABLED, new AccountDisabledException()); this.errorMap.put(ActiveDirectoryAccountState.Error.ACCOUNT_LOCKED_OUT, new AccountLockedException()); this.errorMap.put(ActiveDirectoryAccountState.Error.INVALID_LOGON_HOURS, new InvalidLoginTimeException()); this.errorMap.put(ActiveDirectoryAccountState.Error.INVALID_WORKSTATION, new InvalidLoginLocationException()); this.errorMap.put(ActiveDirectoryAccountState.Error.PASSWORD_MUST_CHANGE, new AccountPasswordMustChangeException()); this.errorMap.put(ActiveDirectoryAccountState.Error.PASSWORD_EXPIRED, new CredentialExpiredException()); this.errorMap.put(EDirectoryAccountState.Error.ACCOUNT_EXPIRED, new AccountExpiredException()); this.errorMap.put(EDirectoryAccountState.Error.LOGIN_LOCKOUT, new AccountLockedException()); this.errorMap.put(EDirectoryAccountState.Error.LOGIN_TIME_LIMITED, new InvalidLoginTimeException()); this.errorMap.put(EDirectoryAccountState.Error.PASSWORD_EXPIRED, new CredentialExpiredException()); this.errorMap.put(PasswordExpirationAccountState.Error.PASSWORD_EXPIRED, new CredentialExpiredException()); this.errorMap.put(PasswordPolicyControl.Error.ACCOUNT_LOCKED, new AccountLockedException()); this.errorMap.put(PasswordPolicyControl.Error.PASSWORD_EXPIRED, new CredentialExpiredException()); this.errorMap.put(PasswordPolicyControl.Error.CHANGE_AFTER_RESET, new CredentialExpiredException()); }
@Override protected HandlerResult authenticateUsernamePasswordInternal(final UsernamePasswordCredential c, final String originalPassword) throws GeneralSecurityException, PreventedException { try { final UsernamePasswordCredential creds = new UsernamePasswordCredential(c.getUsername(), c.getPassword()); final ResponseEntity<SimplePrincipal> authenticationResponse = api.authenticate(creds); if (authenticationResponse.getStatusCode() == HttpStatus.OK) { final SimplePrincipal principalFromRest = authenticationResponse.getBody(); if (principalFromRest == null || StringUtils.isBlank(principalFromRest.getId())) { throw new FailedLoginException("Could not determine authentication response from rest endpoint for " + c.getUsername()); } return createHandlerResult(c, this.principalFactory.createPrincipal(principalFromRest.getId(), principalFromRest.getAttributes()), new ArrayList<>()); } } catch (final HttpClientErrorException e) { if (e.getStatusCode() == HttpStatus.FORBIDDEN) { throw new AccountDisabledException("Could not authenticate forbidden account for " + c.getUsername()); } if (e.getStatusCode() == HttpStatus.UNAUTHORIZED) { throw new FailedLoginException("Could not authenticate account for " + c.getUsername()); } if (e.getStatusCode() == HttpStatus.NOT_FOUND) { throw new AccountNotFoundException("Could not locate account for " + c.getUsername()); } if (e.getStatusCode() == HttpStatus.LOCKED) { throw new AccountLockedException("Could not authenticate locked account for " + c.getUsername()); } if (e.getStatusCode() == HttpStatus.PRECONDITION_REQUIRED) { throw new AccountExpiredException("Could not authenticate expired account for " + c.getUsername()); } throw new FailedLoginException("Rest endpoint returned an unknown status code " + e.getStatusCode() + " for " + c.getUsername()); } throw new FailedLoginException("Rest endpoint returned an unknown response for " + c.getUsername()); }
@Override protected HandlerResult doAuthentication(final Credential credential) throws GeneralSecurityException, PreventedException { final GoogleAuthenticatorTokenCredential tokenCredential = (GoogleAuthenticatorTokenCredential) credential; if (!NumberUtils.isCreatable(tokenCredential.getToken())) { throw new PreventedException("Invalid non-numeric OTP format specified.", new IllegalArgumentException("Invalid token " + tokenCredential.getToken())); } final int otp = Integer.parseInt(tokenCredential.getToken()); LOGGER.debug("Received OTP [{}]", otp); final RequestContext context = RequestContextHolder.getRequestContext(); if (context == null) { new IllegalArgumentException("No request context could be found to locate an authentication event"); } final Authentication authentication = WebUtils.getAuthentication(context); if (authentication == null) { new IllegalArgumentException("Request context has no reference to an authentication event to locate a principal"); } final String uid = authentication.getPrincipal().getId(); LOGGER.debug("Received principal id [{}]", uid); final String secKey = this.credentialRepository.getSecret(uid); if (StringUtils.isBlank(secKey)) { throw new AccountNotFoundException(uid + " cannot be found in the registry"); } if (this.tokenRepository.exists(uid, otp)) { throw new AccountExpiredException(uid + " cannot reuse OTP " + otp + " as it may be expired/invalid"); } final boolean isCodeValid = this.googleAuthenticatorInstance.authorize(secKey, otp); if (isCodeValid) { this.tokenRepository.store(new GoogleAuthenticatorToken(otp, uid)); return createHandlerResult(tokenCredential, this.principalFactory.createPrincipal(uid), null); } throw new FailedLoginException("Failed to authenticate code " + otp); }
/** * Instantiates a new account state handler, that populates * the error map with LDAP error codes and corresponding exceptions. */ public DefaultAccountStateHandler() { this.errorMap = new HashMap<>(); this.errorMap.put(ActiveDirectoryAccountState.Error.ACCOUNT_DISABLED, new AccountDisabledException()); this.errorMap.put(ActiveDirectoryAccountState.Error.ACCOUNT_LOCKED_OUT, new AccountLockedException()); this.errorMap.put(ActiveDirectoryAccountState.Error.INVALID_LOGON_HOURS, new InvalidLoginTimeException()); this.errorMap.put(ActiveDirectoryAccountState.Error.INVALID_WORKSTATION, new InvalidLoginLocationException()); this.errorMap.put(ActiveDirectoryAccountState.Error.PASSWORD_MUST_CHANGE, new AccountPasswordMustChangeException()); this.errorMap.put(ActiveDirectoryAccountState.Error.PASSWORD_EXPIRED, new CredentialExpiredException()); this.errorMap.put(ActiveDirectoryAccountState.Error.ACCOUNT_EXPIRED, new AccountExpiredException()); this.errorMap.put(EDirectoryAccountState.Error.ACCOUNT_EXPIRED, new AccountExpiredException()); this.errorMap.put(EDirectoryAccountState.Error.LOGIN_LOCKOUT, new AccountLockedException()); this.errorMap.put(EDirectoryAccountState.Error.LOGIN_TIME_LIMITED, new InvalidLoginTimeException()); this.errorMap.put(EDirectoryAccountState.Error.PASSWORD_EXPIRED, new CredentialExpiredException()); this.errorMap.put(PasswordExpirationAccountState.Error.PASSWORD_EXPIRED, new CredentialExpiredException()); this.errorMap.put(PasswordPolicyControl.Error.ACCOUNT_LOCKED, new AccountLockedException()); this.errorMap.put(PasswordPolicyControl.Error.PASSWORD_EXPIRED, new CredentialExpiredException()); this.errorMap.put(PasswordPolicyControl.Error.CHANGE_AFTER_RESET, new AccountPasswordMustChangeException()); this.errorMap.put(FreeIPAAccountState.Error.FAILED_AUTHENTICATION, new FailedLoginException()); this.errorMap.put(FreeIPAAccountState.Error.PASSWORD_EXPIRED, new CredentialExpiredException()); this.errorMap.put(FreeIPAAccountState.Error.ACCOUNT_EXPIRED, new AccountExpiredException()); this.errorMap.put(FreeIPAAccountState.Error.MAXIMUM_LOGINS_EXCEEDED, new AccountLockedException()); this.errorMap.put(FreeIPAAccountState.Error.LOGIN_TIME_LIMITED, new InvalidLoginTimeException()); this.errorMap.put(FreeIPAAccountState.Error.LOGIN_LOCKOUT, new AccountLockedException()); this.errorMap.put(FreeIPAAccountState.Error.ACCOUNT_NOT_FOUND, new AccountNotFoundException()); this.errorMap.put(FreeIPAAccountState.Error.CREDENTIAL_NOT_FOUND, new FailedLoginException()); this.errorMap.put(FreeIPAAccountState.Error.ACCOUNT_DISABLED, new AccountDisabledException()); }
@Bean public AuthenticationFailureHandler authenticationFailureHandler() { ExceptionMappingAuthenticationFailureHandler failureHandler = new ExceptionMappingAuthenticationFailureHandler(); Map<String, String> failureUrlMap = new HashMap<>(); failureUrlMap.put(BadCredentialsException.class.getName(), LoginAuthenticationFailureHandler.PASS_ERROR_URL); failureUrlMap.put(CaptchaException.class.getName(), LoginAuthenticationFailureHandler.CODE_ERROR_URL); failureUrlMap.put(AccountExpiredException.class.getName(), LoginAuthenticationFailureHandler.EXPIRED_URL); failureUrlMap.put(LockedException.class.getName(), LoginAuthenticationFailureHandler.LOCKED_URL); failureUrlMap.put(DisabledException.class.getName(), LoginAuthenticationFailureHandler.DISABLED_URL); failureHandler.setExceptionMappings(failureUrlMap); return failureHandler; }
/** * @tests javax.security.auth.login.AccountExpiredException#AccountExpiredException( * java.lang.String) */ public final void testCtor2() { assertNull(new AccountExpiredException(null).getMessage()); String message = ""; assertSame(message, new AccountExpiredException(message).getMessage()); message = "message"; assertSame(message, new AccountExpiredException(message).getMessage()); }
@Override protected Object[] getData() { return new Object[] {new AccountExpiredException("message")}; }
/** * @tests javax.security.auth.login.AccountExpiredException#AccountExpiredException() */ public final void testCtor1() { assertNull(new AccountExpiredException().getMessage()); }