View Javadoc

1   /* 
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8   *
9   *     http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * 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 and
15  * limitations under the License.
16  */
17  package org.apache.jetspeed.security.spi.impl;
18  
19  import java.util.Collection;
20  
21  import org.apache.jetspeed.security.SecurityException;
22  import org.apache.jetspeed.security.om.InternalCredential;
23  import org.apache.jetspeed.security.om.InternalUserPrincipal;
24  
25  /***
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 authentication
32   * 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   */
41  public class MaxPasswordAuthenticationFailuresInterceptor extends AbstractInternalPasswordCredentialInterceptorImpl
42  {
43      private int maxNumberOfAuthenticationFailures;
44      
45      /***
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       */
51      public MaxPasswordAuthenticationFailuresInterceptor(int maxNumberOfAuthenticationFailures)
52      {
53          this.maxNumberOfAuthenticationFailures = maxNumberOfAuthenticationFailures;
54      }
55      
56      /***
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       */
61      public boolean afterAuthenticated(InternalUserPrincipal internalUser, String userName,
62              InternalCredential credential, boolean authenticated) throws SecurityException
63      {
64          boolean update = false;
65          if ( !credential.isExpired() && !authenticated && maxNumberOfAuthenticationFailures > 0 )
66          {
67              int authenticationFailures = credential.getAuthenticationFailures()+1;
68              credential.setAuthenticationFailures(authenticationFailures);
69              if (authenticationFailures >= maxNumberOfAuthenticationFailures)
70              {
71                  credential.setEnabled(false);
72              }
73              update = true;
74          }
75          return update;
76      }
77      
78      /***
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       */
82      public void beforeCreate(InternalUserPrincipal internalUser, Collection credentials, String userName,
83              InternalCredential credential, String password) throws SecurityException
84      {
85          credential.setAuthenticationFailures(0);
86      }
87      
88      /***
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       */
92      public void beforeSetPassword(InternalUserPrincipal internalUser, Collection credentials, String userName,
93              InternalCredential credential, String password, boolean authenticated) throws SecurityException
94      {
95          credential.setAuthenticationFailures(0);
96      }
97  }