/** * 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()); }
/** * Create handle authentication failure action. * * @param flow the flow */ protected void createHandleAuthenticationFailureAction(final Flow flow) { final ActionState handler = createActionState(flow, "handleAuthenticationFailure", createEvaluateAction("authenticationExceptionHandler")); createTransitionForState(handler, AccountDisabledException.class.getSimpleName(), CasWebflowConstants.VIEW_ID_ACCOUNT_DISABLED); createTransitionForState(handler, AccountLockedException.class.getSimpleName(), CasWebflowConstants.VIEW_ID_ACCOUNT_LOCKED); createTransitionForState(handler, AccountPasswordMustChangeException.class.getSimpleName(), CasWebflowConstants.VIEW_ID_MUST_CHANGE_PASSWORD); createTransitionForState(handler, CredentialExpiredException.class.getSimpleName(), CasWebflowConstants.VIEW_ID_EXPIRED_PASSWORD); createTransitionForState(handler, InvalidLoginLocationException.class.getSimpleName(), CasWebflowConstants.VIEW_ID_INVALID_WORKSTATION); createTransitionForState(handler, InvalidLoginTimeException.class.getSimpleName(), CasWebflowConstants.VIEW_ID_INVALID_AUTHENTICATION_HOURS); createTransitionForState(handler, FailedLoginException.class.getSimpleName(), CasWebflowConstants.STATE_ID_INIT_LOGIN_FORM); createTransitionForState(handler, AccountNotFoundException.class.getSimpleName(), CasWebflowConstants.STATE_ID_INIT_LOGIN_FORM); createTransitionForState(handler, UnauthorizedServiceForPrincipalException.class.getSimpleName(), CasWebflowConstants.STATE_ID_INIT_LOGIN_FORM); createTransitionForState(handler, PrincipalException.class.getSimpleName(), CasWebflowConstants.STATE_ID_INIT_LOGIN_FORM); createTransitionForState(handler, UnsatisfiedAuthenticationPolicyException.class.getSimpleName(), CasWebflowConstants.STATE_ID_INIT_LOGIN_FORM); createTransitionForState(handler, UnauthorizedAuthenticationException.class.getSimpleName(), CasWebflowConstants.VIEW_ID_AUTHENTICATION_BLOCKED); createStateDefaultTransition(handler, CasWebflowConstants.STATE_ID_INIT_LOGIN_FORM); }
@Override public Subject authenticate(AuthenticationToken authToken, LoginContext loginContext) throws LoginException { LOGGER.trace("authenticate() {}", authToken); Account account = getAccountRepository().findAccount(authToken); if (account == null) { throw new AccountNotFoundException(authToken.toString()); } if (account.isLocked()) { throw new AccountLockedException(account.getPrincipal().getName()); } LOGGER.trace("authenticate() {} - found account {}", authToken, account); return new AuthenticatedSubject( account, null, authToken, getSessionConfigurations().getConfiguration(authToken.getSystem()), loginContext); }
@Override public Subject authenticate(AuthenticationToken authToken, LoginContext loginContext) throws LoginException { LOGGER.trace("authenticate() {}", authToken); Account account = getAccountRepository().findAccount(authToken); if (account == null) { throw new AccountNotFoundException(authToken.toString()); } if (account.isLocked()) { throw new AccountLockedException(account.getPrincipal().getName()); } if (!getCredentialsMatcher().matches(account, authToken)) { throw new BadCredentialException(String.valueOf(authToken.getToken())); } LOGGER.trace("authenticate() {} - found account {}", authToken, account); return new AuthenticatedSubject( account, null, authToken, getSessionConfigurations().getConfiguration(authToken.getSystem()), loginContext); }
/** * 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()); }
@Test public void correctHandlersOrder() { final AuthenticationExceptionHandlerAction handler = new AuthenticationExceptionHandlerAction(); final MessageContext ctx = mock(MessageContext.class); final Map<String, Class<? extends Exception>> map = new HashMap<>(); map.put("accountLocked", AccountLockedException.class); map.put("accountNotFound", AccountNotFoundException.class); final String id = handler.handle(new AuthenticationException(map), ctx); assertEquals(id, AccountLockedException.class.getSimpleName()); }
@ExceptionHandler(GeneralSecurityException.class) public ResponseEntity<RestResponse> handleGeneralSecurityException(HttpServletRequest req, GeneralSecurityException ex) { if (ex instanceof DigestException /* || ... */) { logger.error("Security error executing {} {}", req.getMethod(), req.getRequestURI(), ex); return new ResponseEntity<>(new RestErrorResponse( INTERNAL_SERVER_ERROR.value(), getMsg(ex.getMessage()), exceptionToErrorCode(ex)), INTERNAL_SERVER_ERROR); // 500 } if (ex instanceof AccountLockedException) { logger.warn("Trying to access a locked account at {} {}", req.getMethod(), req.getRequestURI(), ex); } else { logger.debug("Security error executing {} {}", req.getMethod(), req.getRequestURI(), ex); } return new ResponseEntity<>(new RestErrorResponse( UNAUTHORIZED.value(), getMsg(ex.getMessage()), exceptionToErrorCode(ex)), UNAUTHORIZED); // 401 }
/** * @tests javax.security.auth.login.AccountLockedException#AccountLockedException( * java.lang.String) */ public final void testCtor2() { assertNull(new AccountLockedException(null).getMessage()); String message = ""; assertSame(message, new AccountLockedException(message).getMessage()); message = "message"; assertSame(message, new AccountLockedException(message).getMessage()); }
@Override public Subject authenticate(AuthenticationToken token, LoginContext loginContext) throws LoginException { LOGGER.trace("authenticate() {}", token); FacebookToken facebookToken = (FacebookToken) token; // verification signature if possible if (facebookToken.getSignedRequest() != null && facebookToken.getUserId() != null) { FacebookUnsignedRequest facebookUnsignedRequest = facebookClient.unsignRequest(facebookToken.getSignedRequest()); if (!facebookToken.getUserId().equals(facebookUnsignedRequest.getUserId())) { throw new BadCredentialException("Invalid Facebook Signed Request"); } } // get user FacebookAccessToken facebookAccessToken = (FacebookAccessToken) facebookToken.readCredentials(); JsonObject me = facebookClient.getMe(facebookAccessToken); facebookToken.setMe(me); if (facebookToken.getUserId() != null && !facebookToken.getUserId().equals(me.getString("id"))) { throw new BadCredentialException("Invalid Facebook Access Token for Facebook user ID " + facebookToken.getUserId() + ". Token was for Facebook user ID " + me.getString("id")); } // get local account Account account = getAccountRepository().findAccount(token); if (account == null) { throw new AccountNotFoundException(token.toString()); } if (account.isLocked()) { throw new AccountLockedException(account.getPrincipal().getName()); } LOGGER.trace("authenticate() {} - found account {}", token, account); return new AuthenticatedSubject( account, null, token, getSessionConfigurations().getConfiguration(token.getSystem()), loginContext); }
/** * Checks for errors from standard read/write requests and performs * occasional status checks. * * @param line the response from the server to analyze * @param caller what we tried to do * @throws CredentialNotFoundException if permission denied * @throws AccountLockedException if the user is blocked * @throws HttpRetryException if the database is locked or action was * throttled and a retry failed * @throws AssertionError if assertions fail * @throws UnknownError in the case of a MediaWiki bug * @since 0.18 */ protected void checkErrorsAndUpdateStatus(String line, String caller) throws IOException, LoginException { // perform various status checks every 100 or so edits if (statuscounter > statusinterval) { // purge user rights in case of desysop or loss of other priviliges user.getUserInfo(); if ((assertion & ASSERT_SYSOP) == ASSERT_SYSOP && !user.isA("sysop")) // assert user.isA("sysop") : "Sysop privileges missing or revoked, or session expired"; throw new AssertionError("Sysop privileges missing or revoked, or session expired"); // check for new messages if ((assertion & ASSERT_NO_MESSAGES) == ASSERT_NO_MESSAGES && hasNewMessages()) // assert !hasNewMessages() : "User has new messages"; throw new AssertionError("User has new messages"); statuscounter = 0; } else statuscounter++; // successful if (line.contains("result=\"Success\"")) return; // empty response from server if (line.isEmpty()) throw new UnknownError("Received empty response from server!"); // assertions if ((assertion & ASSERT_BOT) == ASSERT_BOT && line.contains("error code=\"assertbotfailed\"")) // assert !line.contains("error code=\"assertbotfailed\"") : "Bot privileges missing or revoked, or session expired."; throw new AssertionError("Bot privileges missing or revoked, or session expired."); if ((assertion & ASSERT_USER) == ASSERT_USER && line.contains("error code=\"assertuserfailed\"")) // assert !line.contains("error code=\"assertuserfailed\"") : "Session expired."; throw new AssertionError("Session expired."); if (line.contains("error code=\"permissiondenied\"")) throw new CredentialNotFoundException("Permission denied."); // session expired or stupidity // rate limit (automatic retry), though might be a long one (e.g. email) if (line.contains("error code=\"ratelimited\"")) { log(Level.WARNING, caller, "Server-side throttle hit."); throw new HttpRetryException("Action throttled.", 503); } // blocked! (note here the \" in blocked is deliberately missing for emailUser() if (line.contains("error code=\"blocked") || line.contains("error code=\"autoblocked\"")) { log(Level.SEVERE, caller, "Cannot " + caller + " - user is blocked!."); throw new AccountLockedException("Current user is blocked!"); } // database lock (automatic retry) if (line.contains("error code=\"readonly\"")) { log(Level.WARNING, caller, "Database locked!"); throw new HttpRetryException("Database locked!", 503); } // unknown error if (line.contains("error code=\"unknownerror\"")) throw new UnknownError("Unknown MediaWiki API error, response was " + line); // generic (automatic retry) throw new IOException("MediaWiki error, response was " + line); }
@Override protected Object[] getData() { return new Object[] {new AccountLockedException("message")}; }
/** * @tests javax.security.auth.login.AccountLockedException#AccountLockedException() */ public final void testCtor1() { assertNull(new AccountLockedException().getMessage()); }