JSEC-123 - added intermediary abstract class to consolidate common executeLogin behavior
git-svn-id: https://svn.apache.org/repos/asf/incubator/jsecurity/trunk@711064 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/src/org/jsecurity/authc/UsernamePasswordToken.java b/src/org/jsecurity/authc/UsernamePasswordToken.java
index 6bb8341..17f52a5 100644
--- a/src/org/jsecurity/authc/UsernamePasswordToken.java
+++ b/src/org/jsecurity/authc/UsernamePasswordToken.java
@@ -98,7 +98,7 @@
* @param password the password string submitted for authentication
*/
public UsernamePasswordToken(final String username, final String password) {
- this(username, password.toCharArray(), false, null);
+ this(username, password != null ? password.toCharArray() : null, false, null);
}
/**
@@ -128,7 +128,7 @@
* @since 0.2
*/
public UsernamePasswordToken(final String username, final String password, final InetAddress inetAddress) {
- this(username, password.toCharArray(), false, inetAddress);
+ this(username, password != null ? password.toCharArray() : null, false, inetAddress);
}
/**
@@ -158,7 +158,7 @@
* @since 0.9
*/
public UsernamePasswordToken(final String username, final String password, final boolean rememberMe) {
- this(username, password.toCharArray(), rememberMe, null);
+ this(username, password != null ? password.toCharArray() : null, rememberMe, null);
}
/**
@@ -197,7 +197,7 @@
*/
public UsernamePasswordToken(final String username, final String password,
final boolean rememberMe, final InetAddress inetAddress) {
- this(username, password.toCharArray(), rememberMe, inetAddress);
+ this(username, password != null ? password.toCharArray() : null, rememberMe, inetAddress);
}
/*--------------------------------------------
diff --git a/src/org/jsecurity/web/WebUtils.java b/src/org/jsecurity/web/WebUtils.java
index 790d43d..1962a6c 100644
--- a/src/org/jsecurity/web/WebUtils.java
+++ b/src/org/jsecurity/web/WebUtils.java
@@ -20,6 +20,9 @@
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.jsecurity.SecurityUtils;
+import org.jsecurity.session.Session;
+import org.jsecurity.subject.Subject;
import org.jsecurity.util.StringUtils;
import org.jsecurity.util.ThreadContext;
@@ -27,7 +30,6 @@
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
-import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.InetAddress;
@@ -228,7 +230,7 @@
*
* @param request the incoming ServletRequest
* @return the <code>InetAddress</code> associated with the current request, or <code>null</code> if the
- * address cannot be resolved/determined.
+ * address cannot be resolved/determined.
*/
public static InetAddress getInetAddress(ServletRequest request) {
InetAddress clientAddress = null;
@@ -491,9 +493,9 @@
}
public static void saveRequest(ServletRequest request) {
+ Subject subject = SecurityUtils.getSubject();
+ Session session = subject.getSession();
HttpServletRequest httpRequest = toHttp(request);
- HttpSession session = httpRequest.getSession();
-
SavedRequest savedRequest = new SavedRequest(httpRequest);
session.setAttribute(SAVED_REQUEST_KEY, savedRequest);
}
@@ -501,7 +503,8 @@
public static SavedRequest getAndClearSavedRequest(ServletRequest request) {
SavedRequest savedRequest = getSavedRequest(request);
if (savedRequest != null) {
- HttpSession session = WebUtils.toHttp(request).getSession();
+ Subject subject = SecurityUtils.getSubject();
+ Session session = subject.getSession();
session.removeAttribute(SAVED_REQUEST_KEY);
}
return savedRequest;
@@ -509,12 +512,11 @@
public static SavedRequest getSavedRequest(ServletRequest request) {
SavedRequest savedRequest = null;
-
- HttpSession session = WebUtils.toHttp(request).getSession(false);
+ Subject subject = SecurityUtils.getSubject();
+ Session session = subject.getSession(false);
if (session != null) {
savedRequest = (SavedRequest) session.getAttribute(SAVED_REQUEST_KEY);
}
-
return savedRequest;
}
diff --git a/src/org/jsecurity/web/filter/AccessControlFilter.java b/src/org/jsecurity/web/filter/AccessControlFilter.java
index 9b28de3..225ce1d 100644
--- a/src/org/jsecurity/web/filter/AccessControlFilter.java
+++ b/src/org/jsecurity/web/filter/AccessControlFilter.java
@@ -44,13 +44,19 @@
*/
public static final String DEFAULT_LOGIN_URL = "/login.jsp";
- /** Constant representing the HTTP 'GET' request method, equal to <code>GET</code>. */
+ /**
+ * Constant representing the HTTP 'GET' request method, equal to <code>GET</code>.
+ */
public static final String GET_METHOD = "GET";
- /** Constant representing the HTTP 'POST' request method, equal to <code>POST</code>. */
+ /**
+ * Constant representing the HTTP 'POST' request method, equal to <code>POST</code>.
+ */
public static final String POST_METHOD = "POST";
- /** The login url to used to authenticate a user, used when redirecting users if authentication is required. */
+ /**
+ * The login url to used to authenticate a user, used when redirecting users if authentication is required.
+ */
private String loginUrl = DEFAULT_LOGIN_URL;
/**
@@ -136,11 +142,7 @@
*/
public boolean onPreHandle(ServletRequest request, ServletResponse response, Object mappedValue) throws Exception {
//mapped value is ignored - not needed for most (if not all) authc Filters.
- if (isAccessAllowed(request, response, mappedValue)) {
- return true;
- } else {
- return onAccessDenied(request, response);
- }
+ return isAccessAllowed(request, response, mappedValue) || onAccessDenied(request, response);
}
/**
diff --git a/src/org/jsecurity/web/filter/authc/AuthenticatingFilter.java b/src/org/jsecurity/web/filter/authc/AuthenticatingFilter.java
new file mode 100644
index 0000000..9c5f9cd
--- /dev/null
+++ b/src/org/jsecurity/web/filter/authc/AuthenticatingFilter.java
@@ -0,0 +1,109 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.jsecurity.web.filter.authc;
+
+import org.jsecurity.authc.AuthenticationException;
+import org.jsecurity.authc.AuthenticationToken;
+import org.jsecurity.authc.UsernamePasswordToken;
+import org.jsecurity.subject.Subject;
+import org.jsecurity.web.WebUtils;
+
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import java.net.InetAddress;
+
+/**
+ * An <code>AuthenticationFilter</code> that is capable of automatically performing an authentication attempt
+ * based on the incoming request.
+ *
+ * @author Les Hazlewood
+ * @since 0.9
+ */
+public abstract class AuthenticatingFilter extends AuthenticationFilter {
+
+ protected boolean executeLogin(ServletRequest request, ServletResponse response) throws Exception {
+ AuthenticationToken token = createToken(request, response);
+ if (token == null) {
+ String msg = "createToken method implementation returned null. A valid non-null AuthenticationToken " +
+ "must be created in order to execute a login attempt.";
+ throw new IllegalStateException(msg);
+ }
+ try {
+ Subject subject = getSubject(request, response);
+ subject.login(token);
+ return onLoginSuccess(token, subject, request, response);
+ } catch (AuthenticationException e) {
+ return onLoginFailure(token, e, request, response);
+ }
+ }
+
+ protected abstract AuthenticationToken createToken(ServletRequest request, ServletResponse response) throws Exception;
+
+ protected AuthenticationToken createToken(String username, String password,
+ ServletRequest request, ServletResponse response) {
+ boolean rememberMe = isRememberMe(request);
+ InetAddress inet = getInetAddress(request);
+ return createToken(username, password, rememberMe, inet);
+ }
+
+ protected AuthenticationToken createToken(String username, String password,
+ boolean rememberMe, InetAddress inet) {
+ return new UsernamePasswordToken(username, password, rememberMe, inet);
+ }
+
+ protected boolean onLoginSuccess(AuthenticationToken token, Subject subject,
+ ServletRequest request, ServletResponse response) throws Exception {
+ return true;
+ }
+
+ protected boolean onLoginFailure(AuthenticationToken token, AuthenticationException e,
+ ServletRequest request, ServletResponse response) {
+ return false;
+ }
+
+ /**
+ * Returns the InetAddress associated with the current subject. This method is primarily provided for use
+ * during construction of an <code>AuthenticationToken</code>.
+ * <p/>
+ * The default implementation merely returns
+ * {@link WebUtils#getInetAddress(javax.servlet.ServletRequest) WebUtils.getInetAddress(request)}.
+ *
+ * @param request the incoming ServletRequest
+ * @return the <code>InetAddress</code> to associate with the login attempt.
+ */
+ protected InetAddress getInetAddress(ServletRequest request) {
+ return WebUtils.getInetAddress(request);
+ }
+
+ /**
+ * Returns <code>true</code> if "rememberMe" should be enabled for the login attempt associated with the
+ * current <code>request</code>, <code>false</code> otherwise.
+ * <p/>
+ * This implementation always returns <code>false</code> and is provided as a template hook to subclasses that
+ * support <code>rememberMe</code> logins and wish to determine <code>rememberMe</code> in a custom mannner
+ * based on the current <code>request</code>.
+ *
+ * @param request the incoming ServletRequest
+ * @return <code>true</code> if "rememberMe" should be enabled for the login attempt associated with the
+ * current <code>request</code>, <code>false</code> otherwise.
+ */
+ protected boolean isRememberMe(ServletRequest request) {
+ return false;
+ }
+}
diff --git a/src/org/jsecurity/web/filter/authc/AuthenticationFilter.java b/src/org/jsecurity/web/filter/authc/AuthenticationFilter.java
index 8c05285..a9abe68 100644
--- a/src/org/jsecurity/web/filter/authc/AuthenticationFilter.java
+++ b/src/org/jsecurity/web/filter/authc/AuthenticationFilter.java
@@ -85,8 +85,8 @@
}
if (successUrl == null) {
- throw new IllegalArgumentException("Success URL not available via saved request or by calling getSuccessUrl(). " +
- "One of these must be non-null for issueSuccessRedirect() to work.");
+ throw new IllegalStateException("Success URL not available via saved request or by calling " +
+ "getSuccessUrl(). One of these must be non-null for issueSuccessRedirect() to work.");
}
WebUtils.issueRedirect(request, response, successUrl);
diff --git a/src/org/jsecurity/web/filter/authc/BasicHttpAuthenticationFilter.java b/src/org/jsecurity/web/filter/authc/BasicHttpAuthenticationFilter.java
index 426ece3..629cb49 100644
--- a/src/org/jsecurity/web/filter/authc/BasicHttpAuthenticationFilter.java
+++ b/src/org/jsecurity/web/filter/authc/BasicHttpAuthenticationFilter.java
@@ -20,19 +20,14 @@
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
-import org.jsecurity.authc.AuthenticationException;
import org.jsecurity.authc.AuthenticationToken;
-import org.jsecurity.authc.UsernamePasswordToken;
import org.jsecurity.codec.Base64;
-import org.jsecurity.subject.Subject;
import org.jsecurity.web.WebUtils;
-import static org.jsecurity.web.WebUtils.toHttp;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
-import java.net.InetAddress;
/**
* Requires the requesting user to be {@link org.jsecurity.subject.Subject#isAuthenticated() authenticated} for the
@@ -66,15 +61,21 @@
* @see <a href="http://en.wikipedia.org/wiki/Basic_access_authentication">Basic Access Authentication</a>
* @since 0.9
*/
-public class BasicHttpAuthenticationFilter extends AuthenticationFilter {
+public class BasicHttpAuthenticationFilter extends AuthenticatingFilter {
- /** This class's private logger. */
- private static final Log log = LogFactory.getLog(BasicHttpAuthenticationFilter.class);
+ /**
+ * This class's private logger.
+ */
+ private static final Log log = LogFactory.getLog(BasicHttpAuthenticationFilter.class);
- /** HTTP Authorization header, equal to <code>Authorization</code> */
+ /**
+ * HTTP Authorization header, equal to <code>Authorization</code>
+ */
protected static final String AUTHORIZATION_HEADER = "Authorization";
-
- /** HTTP Authentication header, equal to <code>WWW-Authenticate</code> */
+
+ /**
+ * HTTP Authentication header, equal to <code>WWW-Authenticate</code>
+ */
protected static final String AUTHENTICATE_HEADER = "WWW-Authenticate";
/**
@@ -83,10 +84,14 @@
*/
private String applicationName = "application";
- /** The authcScheme to look for in the <code>Authorization</code> header, defaults to <code>BASIC</code> */
+ /**
+ * The authcScheme to look for in the <code>Authorization</code> header, defaults to <code>BASIC</code>
+ */
private String authcScheme = HttpServletRequest.BASIC_AUTH;
-
- /** The authzScheme value to look for in the <code>Authorization</code> header, defaults to <code>BASIC</code> */
+
+ /**
+ * The authzScheme value to look for in the <code>Authorization</code> header, defaults to <code>BASIC</code>
+ */
private String authzScheme = HttpServletRequest.BASIC_AUTH;
/**
@@ -144,7 +149,7 @@
* Unless overridden by this method, the default value is <code>BASIC</code>
*
* @param authzScheme the HTTP <code>Authorization</code> header value that this filter will respond to as
- * indicating a login request.
+ * indicating a login request.
*/
public void setAuthzScheme(String authzScheme) {
this.authzScheme = authzScheme;
@@ -155,7 +160,7 @@
* the HTTP Basic challenge response. The default value is <code>BASIC</code>.
*
* @return the HTTP <code>WWW-Authenticate</code> header scheme that this filter will use when sending the HTTP
- * Basic challenge response.
+ * Basic challenge response.
* @see #sendChallenge
*/
public String getAuthcScheme() {
@@ -167,7 +172,7 @@
* HTTP Basic challenge response. The default value is <code>BASIC</code>.
*
* @param authcScheme the HTTP <code>WWW-Authenticate</code> header scheme that this filter will use when
- * sending the Http Basic challenge response.
+ * sending the Http Basic challenge response.
* @see #sendChallenge
*/
public void setAuthcScheme(String authcScheme) {
@@ -181,7 +186,7 @@
* @param response outgoing ServletResponse
* @return true if the request should be processed; false if the request should not continue to be processed
*/
- protected boolean onAccessDenied(ServletRequest request, ServletResponse response) {
+ protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {
boolean loggedIn = false; //false by default or we wouldn't be in this method
if (isLoginAttempt(request, response)) {
loggedIn = executeLogin(request, response);
@@ -220,8 +225,8 @@
* @param request the incoming <code>ServletRequest</code>
* @return the <code>Authorization</code> header's value.
*/
- protected String getAuthzHeader( ServletRequest request ) {
- HttpServletRequest httpRequest = toHttp(request);
+ protected String getAuthzHeader(ServletRequest request) {
+ HttpServletRequest httpRequest = WebUtils.toHttp(request);
return httpRequest.getHeader(AUTHORIZATION_HEADER);
}
@@ -261,7 +266,7 @@
if (log.isDebugEnabled()) {
log.debug("Authentication required: sending 401 Authentication challenge response.");
}
- HttpServletResponse httpResponse = toHttp(response);
+ HttpServletResponse httpResponse = WebUtils.toHttp(response);
httpResponse.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
String authcHeader = getAuthcScheme() + " realm=\"" + getApplicationName() + "\"";
httpResponse.setHeader(AUTHENTICATE_HEADER, authcHeader);
@@ -269,31 +274,25 @@
}
/**
- * Executes a login attempt with the provided credentials in the http header and returns <code>true</code>
- * if the login attempt is successful and <code>false</code> otherwise.
+ * Creates an AuthenticationToken for use during login attempt with the provided credentials in the http header.
* <p/>
* This implementation:
* <ol><li>acquires the username and password based on the request's
* {@link #getAuthzHeader(javax.servlet.ServletRequest) authorization header} via the
* {@link #getPrincipalsAndCredentials(String, javax.servlet.ServletRequest) getPrincipalsAndCredentials} method</li>
* <li>The return value of that method is converted to an <code>AuthenticationToken</code> via the
- * {@link #createToken(String, String, javax.servlet.ServletRequest) createToken} method</li>
- * <li>Finally, the login attempt is executed using that token by calling
- * {@link #executeLogin(org.jsecurity.authc.AuthenticationToken, javax.servlet.ServletRequest, javax.servlet.ServletResponse)}</li>
+ * {@link #createToken(String, String, javax.servlet.ServletRequest, javax.servlet.ServletResponse) createToken} method</li>
+ * <li>The created <code>AuthenticationToken</code> is returned.</li>
* </ol>
*
* @param request incoming ServletRequest
* @param response outgoing ServletResponse
- * @return true if the subject was successfully logged in, false otherwise
+ * @return the AuthenticationToken used to execute the login attempt
*/
- protected boolean executeLogin(ServletRequest request, ServletResponse response) {
- if (log.isDebugEnabled()) {
- log.debug("Attempting to authenticate Subject based on Http BASIC Authentication request...");
- }
-
+ protected AuthenticationToken createToken(ServletRequest request, ServletResponse response) {
String authorizationHeader = getAuthzHeader(request);
- if (authorizationHeader == null || authorizationHeader.length() == 0 ) {
- return false;
+ if (authorizationHeader == null || authorizationHeader.length() == 0) {
+ return null;
}
if (log.isDebugEnabled()) {
@@ -301,58 +300,14 @@
}
String[] prinCred = getPrincipalsAndCredentials(authorizationHeader, request);
- if ( prinCred == null || prinCred.length < 2 ) {
- return false;
+ if (prinCred == null || prinCred.length < 2) {
+ return null;
}
String username = prinCred[0];
String password = prinCred[1];
- if (log.isDebugEnabled()) {
- log.debug("Processing login request for username [" + username + "]");
- }
-
- AuthenticationToken token = createToken(username, password, request );
- if ( token != null ) {
- return executeLogin(token, request, response );
- }
-
- //always default to false. If we've made it to this point in the code, that
- //means the authentication attempt either never occured, or wasn't successful:
- return false;
- }
-
- /**
- * Executes a login attmept for the
- * {@link #getSubject(javax.servlet.ServletRequest, javax.servlet.ServletResponse) currently executing}
- * <code>Subject</code> using the specified authentication <code>token</code>.
- * <p/>
- * The login attempt constitutes calling {@link Subject#login currentSubject.login(token)}. If the method
- * call returns successfully, <code>true</code> is returned, <code>false</code> otherwise.
- *
- * @param token the <code>AuthenticationToken</code> representing the submitted username and password.
- * @param request the incoming ServletRequest
- * @param response the outgoing ServletResponse
- * @return <code>true</code> if the authentication attempt is successful, <code>false</code> otherwise.
- */
- protected boolean executeLogin( AuthenticationToken token, ServletRequest request, ServletResponse response ) {
- Subject subject = getSubject(request, response);
- if ( token != null && subject != null ) {
- try {
- subject.login(token);
- if (log.isDebugEnabled()) {
- log.debug("Successfully logged in user [" + token.getPrincipal() + "]");
- }
- return true;
- } catch (AuthenticationException ae) {
- if (log.isDebugEnabled()) {
- log.debug("Unable to log in user [" + token.getPrincipal()+ "]", ae);
- }
- }
- }
-
- //always default to false - authentication attempt never occurred or wasn't successful:
- return false;
+ return createToken(username, password, request, response);
}
/**
@@ -364,16 +319,16 @@
* {@link #getPrincipalsAndCredentials(String, String) getPrincipalsAndCredentials(scheme,encoded)} method.
*
* @param authorizationHeader the authorization header obtained from the request.
- * @param request the incoming ServletRequest
+ * @param request the incoming ServletRequest
* @return the username (index 0)/password pair (index 1) submitted by the user for the given header value and request.
* @see #getAuthzHeader(javax.servlet.ServletRequest)
*/
- protected String[] getPrincipalsAndCredentials( String authorizationHeader, ServletRequest request ) {
- if ( authorizationHeader == null ) {
+ protected String[] getPrincipalsAndCredentials(String authorizationHeader, ServletRequest request) {
+ if (authorizationHeader == null) {
return null;
}
String[] authTokens = authorizationHeader.split(" ");
- if ( authTokens == null || authTokens.length < 2 ) {
+ if (authTokens == null || authTokens.length < 2) {
return null;
}
return getPrincipalsAndCredentials(authTokens[0], authTokens[1]);
@@ -389,76 +344,14 @@
* <code>String decoded = Base64.decodeToString(encoded);<br/>
* return decoded.split(":");</code>
*
- * @param scheme the {@link #getAuthcScheme() authcScheme} found in the request
- * {@link #getAuthzHeader(javax.servlet.ServletRequest) authzHeader}. It is ignored by this implementation,
- * but available to overriding implementations should they find it useful.
+ * @param scheme the {@link #getAuthcScheme() authcScheme} found in the request
+ * {@link #getAuthzHeader(javax.servlet.ServletRequest) authzHeader}. It is ignored by this implementation,
+ * but available to overriding implementations should they find it useful.
* @param encoded the Base64-encoded username:password value found after the scheme in the header
* @return the username (index 0)/password (index 1) pair obtained from the encoded header data.
*/
- protected String[] getPrincipalsAndCredentials( String scheme, String encoded ) {
+ protected String[] getPrincipalsAndCredentials(String scheme, String encoded) {
String decoded = Base64.decodeToString(encoded);
return decoded.split(":");
}
-
- /**
- * Creates an AuthenticationToken based on the username and password and incoming request to be submitted to
- * the {@link Subject#login Subject.login} method for authentication.
- * <p/>
- * The default implementation acquires the request's associated
- * {@link #getInetAddress(javax.servlet.ServletRequest) inetAddress} as well as a potential
- * {@link #isRememberMeEnabled(javax.servlet.ServletRequest) rememberMe} status, and with the given
- * <code>username</code> and <code>password</code>, returns a
- * <code>new {@link org.jsecurity.authc.UsernamePasswordToken UsernamePasswordToken}</code>. That is:
- * <p/>
- * <code>InetAddress addr = getInetAddress(request);<br/>
- * boolean rememberMe = isRememberMeEnabled(request);<br/>
- * return new UsernamePasswordToken(username, password, rememberMe, addr );</code>
- * <p/>
- * It should be noted that Basic HTTP Authentication does not support any concept of <code>rememberMe</code, but
- * we still allow subclasses to enable this feature for any given request via the
- * {@link #isRememberMeEnabled(javax.servlet.ServletRequest) isRememberMeEnabled} method if subclasses wish to
- * override that method in custom environments.
- *
- * @param username the username obtained from the request's 'Authorization' header.
- * @param password the password obtained from the request's 'Authorization' header.
- * @param request the incoming ServletRequest.
- * @return a constructed <code>AuthenticationToken</code> that will be used to execute a login attempt for the
- * current <code>Subject</code>.
- */
- protected AuthenticationToken createToken( String username, String password, ServletRequest request ) {
- InetAddress addr = getInetAddress(request);
- boolean rememberMe = isRememberMeEnabled(request);
- return new UsernamePasswordToken(username, password, rememberMe, addr );
- }
-
- /**
- * Returns the InetAddress associated with the current subject. This method is primarily provided for use
- * during construction of an <code>AuthenticationToken</code>.
- * <p/>
- * The default implementation merely returns
- * {@link WebUtils#getInetAddress(javax.servlet.ServletRequest) WebUtils.getInetAddress(request)}.
- *
- * @param request the incoming ServletRequest
- * @return the <code>InetAddress</code> to associate with the login attempt.
- */
- protected InetAddress getInetAddress( ServletRequest request ) {
- return WebUtils.getInetAddress(request);
- }
-
- /**
- * Returns <code>true</code> if "rememberMe" should be enabled for the login attempt associated with the
- * current <code>request</code>, <code>false</code> otherwise.
- * <p/>
- * This implementation always returns <code>false</code> in all cases because Basic HTTP Authentication does not
- * support the concept of <code>rememberMe</code>. However, this method is provided as a template hook to
- * subclasses that might wish to determine <code>rememberMe</code> in a custom mannner based on the current
- * <code>request</code>.
- * @param request the incoming ServletRequest
- * @return <code>true</code> if "rememberMe" should be enabled for the login attempt associated with the
- * current <code>request</code>, <code>false</code> otherwise.
- */
- protected boolean isRememberMeEnabled( ServletRequest request ) {
- return false;
- }
-
}
diff --git a/src/org/jsecurity/web/filter/authc/FormAuthenticationFilter.java b/src/org/jsecurity/web/filter/authc/FormAuthenticationFilter.java
index 7d04b54..8b4bc2b 100644
--- a/src/org/jsecurity/web/filter/authc/FormAuthenticationFilter.java
+++ b/src/org/jsecurity/web/filter/authc/FormAuthenticationFilter.java
@@ -21,14 +21,14 @@
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jsecurity.authc.AuthenticationException;
+import org.jsecurity.authc.AuthenticationToken;
import org.jsecurity.authc.UsernamePasswordToken;
+import org.jsecurity.subject.Subject;
import org.jsecurity.web.WebUtils;
-import static org.jsecurity.web.WebUtils.toHttp;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
-import java.net.InetAddress;
/**
* Requires the requesting user to be authenticated for the request to continue, and if they are not, forces the user
@@ -57,7 +57,7 @@
* @see org.jsecurity.web.filter.authc.PassThruAuthenticationFilter
* @since 0.9
*/
-public class FormAuthenticationFilter extends AuthenticationFilter {
+public class FormAuthenticationFilter extends AuthenticatingFilter {
public static final String DEFAULT_ERROR_KEY_ATTRIBUTE_NAME = "jsecLoginFailure";
@@ -65,7 +65,7 @@
public static final String DEFAULT_PASSWORD_PARAM = "password";
public static final String DEFAULT_REMEMBER_ME_PARAM = "rememberMe";
- private static final Log log = LogFactory.getLog(FormAuthenticationFilter.class);
+ private static final Log log = LogFactory.getLog(FormAuthenticationFilter.class);
private String usernameParam = DEFAULT_USERNAME_PARAM;
private String passwordParam = DEFAULT_PASSWORD_PARAM;
@@ -173,31 +173,31 @@
* @return <code>true</code> if the request is an HTTP <code>POST</code>, <code>false</code> otherwise.
*/
protected boolean isLoginSubmission(ServletRequest request, ServletResponse response) {
- return (request instanceof HttpServletRequest) && toHttp(request).getMethod().equalsIgnoreCase(POST_METHOD);
+ return (request instanceof HttpServletRequest) && WebUtils.toHttp(request).getMethod().equalsIgnoreCase(POST_METHOD);
}
- protected boolean executeLogin(ServletRequest request, ServletResponse response) throws Exception {
- String username = getUsername(request, response);
- String password = getPassword(request, response);
- boolean rememberMe = isRememberMe(request, response);
- InetAddress inet = getInetAddress(request, response);
+ protected AuthenticationToken createToken(ServletRequest request, ServletResponse response) {
+ String username = getUsername(request);
+ String password = getPassword(request);
+ return createToken(username, password, request, response);
+ }
- char[] passwordChars = null;
- if (password != null) {
- passwordChars = password.toCharArray();
- }
+ protected boolean isRememberMe(ServletRequest request) {
+ return WebUtils.isTrue(request, getRememberMeParam());
+ }
- UsernamePasswordToken token = new UsernamePasswordToken(username, passwordChars, rememberMe, inet);
+ protected boolean onLoginSuccess(AuthenticationToken token, Subject subject,
+ ServletRequest request, ServletResponse response) throws Exception {
+ issueSuccessRedirect(request, response);
+ //we handled the success redirect directly, prevent the chain from continuing:
+ return false;
+ }
- try {
- getSubject(request, response).login(token);
- issueSuccessRedirect(request, response);
- return false;
- } catch (AuthenticationException e) {
- setFailureAttribute(request, e);
- //login failed, let request continue back to the login page:
- return true;
- }
+ protected boolean onLoginFailure(AuthenticationToken token, AuthenticationException e,
+ ServletRequest request, ServletResponse response) {
+ setFailureAttribute(request, e);
+ //login failed, let request continue back to the login page:
+ return true;
}
protected void setFailureAttribute(ServletRequest request, AuthenticationException ae) {
@@ -205,19 +205,13 @@
request.setAttribute(getFailureKeyAttribute(), className);
}
- protected String getUsername(ServletRequest request, ServletResponse response) {
+ protected String getUsername(ServletRequest request) {
return WebUtils.getCleanParam(request, getUsernameParam());
}
- protected String getPassword(ServletRequest request, ServletResponse response) {
+ protected String getPassword(ServletRequest request) {
return WebUtils.getCleanParam(request, getPasswordParam());
}
- protected boolean isRememberMe(ServletRequest request, ServletResponse response) {
- return WebUtils.isTrue(request, getRememberMeParam());
- }
- protected InetAddress getInetAddress(ServletRequest request, ServletResponse response) {
- return WebUtils.getInetAddress(request);
- }
}