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.impl;
18  
19  import java.util.Iterator;
20  import java.util.LinkedList;
21  import java.util.List;
22  
23  import org.apache.commons.logging.Log;
24  import org.apache.commons.logging.LogFactory;
25  import org.apache.jetspeed.Jetspeed;
26  import org.apache.jetspeed.login.LoginConstants;
27  import org.apache.jetspeed.pipeline.PipelineException;
28  import org.apache.jetspeed.pipeline.valve.AbstractValve;
29  import org.apache.jetspeed.pipeline.valve.ValveContext;
30  import org.apache.jetspeed.request.RequestContext;
31  import org.apache.jetspeed.security.PasswordCredential;
32  import org.apache.jetspeed.security.SecurityException;
33  import org.apache.jetspeed.security.SecurityHelper;
34  import org.apache.jetspeed.security.User;
35  import org.apache.jetspeed.security.UserManager;
36  import org.apache.jetspeed.security.UserPrincipal;
37  
38  /***
39   * LoginValidationValve
40   *
41   * @author <a href="mailto:ate@apache.org">Ate Douma</a>
42   * @version $Id: LoginValidationValveImpl.java 544402 2007-06-05 06:20:00Z taylor $
43   */
44  public class LoginValidationValveImpl extends AbstractValve implements org.apache.jetspeed.pipeline.valve.LoginValidationValve
45  {
46      private static final Log log = LogFactory.getLog(LoginValidationValveImpl.class);
47      
48      private int maxNumberOfAuthenticationFailures;
49      private List sessionAttributes; 
50      
51      /***
52       * Creates a LoginValidationValveImpl instance which doesn't evaluate the maxNumberOfAuthenticationFailures 
53       * for LoginConstant.ERROR_FINAL_LOGIN_ATTEMPT error reporting.
54       */
55      public LoginValidationValveImpl(List sessionAttributes)
56      {
57          this.sessionAttributes = sessionAttributes;
58      }
59  
60      /***
61       * <p>
62       * Creates a LoginValidationValveImpl instance which can evaluate {@link PasswordCredential#getAuthenticationFailures()}
63       * to determine if a user only has one login attempt available before the maxNumberOfAuthenticationFailures parameter
64       * value is reached and the credential will be disabled.</p>
65       * <p>
66       * The provided maxNumberOfAuthenticationFailures value should be equal to the value configured for the
67       * MaxPasswordAuthenticationFailuresInterceptor (and > 2 to be useful).</p>
68       */
69      public LoginValidationValveImpl(int maxNumberOfAuthenticationFailures)
70      {
71          this.maxNumberOfAuthenticationFailures = maxNumberOfAuthenticationFailures;
72          this.sessionAttributes = new LinkedList();
73      }
74  
75      /***
76       * <p>
77       * Creates a LoginValidationValveImpl instance which can evaluate {@link PasswordCredential#getAuthenticationFailures()}
78       * to determine if a user only has one login attempt available before the maxNumberOfAuthenticationFailures parameter
79       * value is reached and the credential will be disabled.</p>
80       * <p>
81       * The provided maxNumberOfAuthenticationFailures value should be equal to the value configured for the
82       * MaxPasswordAuthenticationFailuresInterceptor (and > 2 to be useful).</p>
83       */
84      public LoginValidationValveImpl(int maxNumberOfAuthenticationFailures, List sessionAttributes)
85      {
86          this.maxNumberOfAuthenticationFailures = maxNumberOfAuthenticationFailures;
87          this.sessionAttributes = sessionAttributes;
88      }
89  
90      /***
91       * @see org.apache.jetspeed.pipeline.valve.Valve#invoke(org.apache.jetspeed.request.RequestContext, org.apache.jetspeed.pipeline.valve.ValveContext)
92       */
93      public void invoke(RequestContext request, ValveContext context) throws PipelineException
94      {
95          try
96          {
97              if ( request.getRequest().getUserPrincipal() == null )
98              {
99                  if ( request.getSessionAttribute(LoginConstants.RETRYCOUNT) != null )
100                 {
101                     // we have a login attempt failure
102                     String userName = (String)request.getSessionAttribute(LoginConstants.USERNAME);
103                     if ( userName != null && !userName.equals(""))
104                     {
105                         UserManager um = (UserManager)Jetspeed.getComponentManager().getComponent(UserManager.class);
106                         if ( um != null )
107                         {
108                             User user = null;
109                             try
110                             {
111                                 user = um.getUser(userName);
112                                 UserPrincipal userPrincipal = (UserPrincipal)SecurityHelper.getPrincipal(user.getSubject(), UserPrincipal.class);
113                                 if ( !userPrincipal.isEnabled() )
114                                 {
115                                     request.setSessionAttribute(LoginConstants.ERRORCODE, LoginConstants.ERROR_USER_DISABLED);
116                                 }
117                                 else
118                                 {
119                                     PasswordCredential pwdCredential = SecurityHelper.getPasswordCredential(user.getSubject());
120                                     if ( pwdCredential == null || !pwdCredential.isEnabled() )
121                                     {
122                                         request.setSessionAttribute(LoginConstants.ERRORCODE, LoginConstants.ERROR_CREDENTIAL_DISABLED);
123                                     }
124                                     else if ( pwdCredential.isExpired() )
125                                     {
126                                         request.setSessionAttribute(LoginConstants.ERRORCODE, LoginConstants.ERROR_CREDENTIAL_EXPIRED);
127                                     }
128                                     else if ( maxNumberOfAuthenticationFailures > 1 && pwdCredential.getAuthenticationFailures() == maxNumberOfAuthenticationFailures -1  )
129                                     {
130                                         request.setSessionAttribute(LoginConstants.ERRORCODE, LoginConstants.ERROR_FINAL_LOGIN_ATTEMPT);
131                                     }
132                                     else
133                                     {
134                                         request.setSessionAttribute(LoginConstants.ERRORCODE, LoginConstants.ERROR_INVALID_PASSWORD);
135                                     }
136                                 }
137                             }
138                             catch (SecurityException sex)
139                             {
140                                 request.setSessionAttribute(LoginConstants.ERRORCODE, LoginConstants.ERROR_UNKNOWN_USER);
141                             }
142                         }
143                     }
144                     else
145                     {
146                         request.setSessionAttribute(LoginConstants.ERRORCODE, LoginConstants.ERROR_UNKNOWN_USER);
147                     }
148                 }
149             }
150             else
151             {
152                 if (request.getSessionAttribute(LoginConstants.LOGIN_CHECK) == null)
153                 {
154                     clearSessionAttributes(request);
155                     request.getRequest().getSession().setAttribute(LoginConstants.LOGIN_CHECK, "true");
156                 }                
157             }
158             
159             context.invokeNext(request);
160         }
161         catch (Exception e)
162         {
163             log.error("Exception in request pipeline: " + e.getMessage(), e);
164             throw new PipelineException(e.toString(), e);
165         }
166     }
167     
168     private void clearSessionAttributes(RequestContext request)
169     {       
170         Iterator attributes = this.sessionAttributes.iterator();
171         while (attributes.hasNext())
172         {
173             String attribute = (String)attributes.next();
174             request.getRequest().getSession().removeAttribute(attribute);
175         }
176     }
177 
178     public String toString()
179     {
180         return "LoginValidationValve";
181     }
182 
183 }