001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017: package org.apache.jetspeed.security.impl;
018:
019: import java.util.Iterator;
020: import java.util.LinkedList;
021: import java.util.List;
022:
023: import org.apache.commons.logging.Log;
024: import org.apache.commons.logging.LogFactory;
025: import org.apache.jetspeed.Jetspeed;
026: import org.apache.jetspeed.login.LoginConstants;
027: import org.apache.jetspeed.pipeline.PipelineException;
028: import org.apache.jetspeed.pipeline.valve.AbstractValve;
029: import org.apache.jetspeed.pipeline.valve.ValveContext;
030: import org.apache.jetspeed.request.RequestContext;
031: import org.apache.jetspeed.security.PasswordCredential;
032: import org.apache.jetspeed.security.SecurityException;
033: import org.apache.jetspeed.security.SecurityHelper;
034: import org.apache.jetspeed.security.User;
035: import org.apache.jetspeed.security.UserManager;
036: import org.apache.jetspeed.security.UserPrincipal;
037:
038: /**
039: * LoginValidationValve
040: *
041: * @author <a href="mailto:ate@apache.org">Ate Douma</a>
042: * @version $Id: LoginValidationValveImpl.java 544402 2007-06-05 06:20:00Z taylor $
043: */
044: public class LoginValidationValveImpl extends AbstractValve implements
045: org.apache.jetspeed.pipeline.valve.LoginValidationValve {
046: private static final Log log = LogFactory
047: .getLog(LoginValidationValveImpl.class);
048:
049: private int maxNumberOfAuthenticationFailures;
050: private List sessionAttributes;
051:
052: /**
053: * Creates a LoginValidationValveImpl instance which doesn't evaluate the maxNumberOfAuthenticationFailures
054: * for LoginConstant.ERROR_FINAL_LOGIN_ATTEMPT error reporting.
055: */
056: public LoginValidationValveImpl(List sessionAttributes) {
057: this .sessionAttributes = sessionAttributes;
058: }
059:
060: /**
061: * <p>
062: * Creates a LoginValidationValveImpl instance which can evaluate {@link PasswordCredential#getAuthenticationFailures()}
063: * to determine if a user only has one login attempt available before the maxNumberOfAuthenticationFailures parameter
064: * value is reached and the credential will be disabled.</p>
065: * <p>
066: * The provided maxNumberOfAuthenticationFailures value should be equal to the value configured for the
067: * MaxPasswordAuthenticationFailuresInterceptor (and > 2 to be useful).</p>
068: */
069: public LoginValidationValveImpl(
070: int maxNumberOfAuthenticationFailures) {
071: this .maxNumberOfAuthenticationFailures = maxNumberOfAuthenticationFailures;
072: this .sessionAttributes = new LinkedList();
073: }
074:
075: /**
076: * <p>
077: * Creates a LoginValidationValveImpl instance which can evaluate {@link PasswordCredential#getAuthenticationFailures()}
078: * to determine if a user only has one login attempt available before the maxNumberOfAuthenticationFailures parameter
079: * value is reached and the credential will be disabled.</p>
080: * <p>
081: * The provided maxNumberOfAuthenticationFailures value should be equal to the value configured for the
082: * MaxPasswordAuthenticationFailuresInterceptor (and > 2 to be useful).</p>
083: */
084: public LoginValidationValveImpl(
085: int maxNumberOfAuthenticationFailures,
086: List sessionAttributes) {
087: this .maxNumberOfAuthenticationFailures = maxNumberOfAuthenticationFailures;
088: this .sessionAttributes = sessionAttributes;
089: }
090:
091: /**
092: * @see org.apache.jetspeed.pipeline.valve.Valve#invoke(org.apache.jetspeed.request.RequestContext, org.apache.jetspeed.pipeline.valve.ValveContext)
093: */
094: public void invoke(RequestContext request, ValveContext context)
095: throws PipelineException {
096: try {
097: if (request.getRequest().getUserPrincipal() == null) {
098: if (request
099: .getSessionAttribute(LoginConstants.RETRYCOUNT) != null) {
100: // we have a login attempt failure
101: String userName = (String) request
102: .getSessionAttribute(LoginConstants.USERNAME);
103: if (userName != null && !userName.equals("")) {
104: UserManager um = (UserManager) Jetspeed
105: .getComponentManager().getComponent(
106: UserManager.class);
107: if (um != null) {
108: User user = null;
109: try {
110: user = um.getUser(userName);
111: UserPrincipal userPrincipal = (UserPrincipal) SecurityHelper
112: .getPrincipal(
113: user.getSubject(),
114: UserPrincipal.class);
115: if (!userPrincipal.isEnabled()) {
116: request
117: .setSessionAttribute(
118: LoginConstants.ERRORCODE,
119: LoginConstants.ERROR_USER_DISABLED);
120: } else {
121: PasswordCredential pwdCredential = SecurityHelper
122: .getPasswordCredential(user
123: .getSubject());
124: if (pwdCredential == null
125: || !pwdCredential
126: .isEnabled()) {
127: request
128: .setSessionAttribute(
129: LoginConstants.ERRORCODE,
130: LoginConstants.ERROR_CREDENTIAL_DISABLED);
131: } else if (pwdCredential
132: .isExpired()) {
133: request
134: .setSessionAttribute(
135: LoginConstants.ERRORCODE,
136: LoginConstants.ERROR_CREDENTIAL_EXPIRED);
137: } else if (maxNumberOfAuthenticationFailures > 1
138: && pwdCredential
139: .getAuthenticationFailures() == maxNumberOfAuthenticationFailures - 1) {
140: request
141: .setSessionAttribute(
142: LoginConstants.ERRORCODE,
143: LoginConstants.ERROR_FINAL_LOGIN_ATTEMPT);
144: } else {
145: request
146: .setSessionAttribute(
147: LoginConstants.ERRORCODE,
148: LoginConstants.ERROR_INVALID_PASSWORD);
149: }
150: }
151: } catch (SecurityException sex) {
152: request
153: .setSessionAttribute(
154: LoginConstants.ERRORCODE,
155: LoginConstants.ERROR_UNKNOWN_USER);
156: }
157: }
158: } else {
159: request.setSessionAttribute(
160: LoginConstants.ERRORCODE,
161: LoginConstants.ERROR_UNKNOWN_USER);
162: }
163: }
164: } else {
165: if (request
166: .getSessionAttribute(LoginConstants.LOGIN_CHECK) == null) {
167: clearSessionAttributes(request);
168: request.getRequest().getSession().setAttribute(
169: LoginConstants.LOGIN_CHECK, "true");
170: }
171: }
172:
173: context.invokeNext(request);
174: } catch (Exception e) {
175: log.error("Exception in request pipeline: "
176: + e.getMessage(), e);
177: throw new PipelineException(e.toString(), e);
178: }
179: }
180:
181: private void clearSessionAttributes(RequestContext request) {
182: Iterator attributes = this .sessionAttributes.iterator();
183: while (attributes.hasNext()) {
184: String attribute = (String) attributes.next();
185: request.getRequest().getSession()
186: .removeAttribute(attribute);
187: }
188: }
189:
190: public String toString() {
191: return "LoginValidationValve";
192: }
193:
194: }
|