1/*2 * Licensed to the Apache Software Foundation (ASF) under one or more3 * contributor license agreements. See the NOTICE file distributed with4 * this work for additional information regarding copyright ownership.5 * The ASF licenses this file to You under the Apache License, Version 2.06 * (the "License"); you may not use this file except in compliance with7 * the License. You may obtain a copy of the License at8*9* http://www.apache.org/licenses/LICENSE-2.010*11* Unless required by applicable law or agreed to in writing, software12* distributed under the License is distributed on an "AS IS" BASIS,13* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.14* See the License for the specific language governing permissions and15* limitations under the License.16*/17packageorg.apache.jetspeed.security.spi.impl;
1819import java.util.Collection;
2021import org.apache.jetspeed.security.SecurityException;
22import org.apache.jetspeed.security.om.InternalCredential;
23import org.apache.jetspeed.security.om.InternalUserPrincipal;
2425/***26 * <p>27 * Enforces a {@link #MaxPasswordAuthenticationFailuresInterceptor(int) maximum number of times} a user may provide an invalid password.28 * Once the maximum number of invalid authentications is reached, the credential is disabled.</p>29 * <p>30 * Note: the current count is <em>not</em> reset on valid authentication by this interceptor.31 * This is done by the {@link DefaultCredentialHandler} which invokes the interceptor(s) after authentication32 * and no interceptor {@link #afterAuthenticated(InternalUserPrincipal, String, InternalCredential, boolean) afterAuthenicated} 33 * method returns true.</p>34 * <p>35 * But, this interceptor <em>does</em> (re)sets the count on creation and on change of the password.</p>36 * <p>37 * 38 * @author <a href="mailto:ate@douma.nu">Ate Douma</a>39 * @version $Id$40 */41publicclassMaxPasswordAuthenticationFailuresInterceptorextendsAbstractInternalPasswordCredentialInterceptorImpl42 {
43privateint maxNumberOfAuthenticationFailures;
4445/***46 * <p>47 * Configure the maximum number of invalid authentications allowed in a row.</p>48 * <p>49 * A value of zero (0) disables the check</p>50 */51publicMaxPasswordAuthenticationFailuresInterceptor(int maxNumberOfAuthenticationFailures)
52 {
53this.maxNumberOfAuthenticationFailures = maxNumberOfAuthenticationFailures;
54 }
5556/***57 * Checks the current count of authentication failures when the credential is not expired and authentication failed.58 * @return true if the maximum number of invalid authentications is reached and the credential is disabled.59 * @see org.apache.jetspeed.security.spi.InternalPasswordCredentialInterceptor#afterAuthenticated(org.apache.jetspeed.security.om.InternalUserPrincipal, java.lang.String, org.apache.jetspeed.security.om.InternalCredential, boolean)60 */61publicboolean afterAuthenticated(InternalUserPrincipal internalUser, String userName,
62 InternalCredential credential, boolean authenticated) throws SecurityException
63 {
64boolean update = false;
65if ( !credential.isExpired() && !authenticated && maxNumberOfAuthenticationFailures > 0 )
66 {
67int authenticationFailures = credential.getAuthenticationFailures()+1;
68 credential.setAuthenticationFailures(authenticationFailures);
69if (authenticationFailures >= maxNumberOfAuthenticationFailures)
70 {
71 credential.setEnabled(false);
72 }
73 update = true;
74 }
75return update;
76 }
7778/***79 * Sets the count of invalid authentications to zero (0).80 * @see org.apache.jetspeed.security.spi.InternalPasswordCredentialInterceptor#beforeCreate(org.apache.jetspeed.security.om.InternalUserPrincipal, java.util.Collection, java.lang.String, InternalCredential, java.lang.String)81 */82publicvoid beforeCreate(InternalUserPrincipal internalUser, Collection credentials, String userName,
83 InternalCredential credential, String password) throws SecurityException
84 {
85 credential.setAuthenticationFailures(0);
86 }
8788/***89 * Resets the count of invalid authentications to zero (0).90 * @see org.apache.jetspeed.security.spi.InternalPasswordCredentialInterceptor#beforeSetPassword(org.apache.jetspeed.security.om.InternalUserPrincipal, java.util.Collection, java.lang.String, org.apache.jetspeed.security.om.InternalCredential, java.lang.String, boolean)91 */92publicvoid beforeSetPassword(InternalUserPrincipal internalUser, Collection credentials, String userName,
93 InternalCredential credential, String password, boolean authenticated) throws SecurityException
94 {
95 credential.setAuthenticationFailures(0);
96 }
97 }