From: maxcooper Date: Mon, 14 Jul 2003 18:55:14 +0000 (+0000) Subject: got it working again after refactoring out into separate class X-Git-Tag: rel-2_0-alpha1~47 X-Git-Url: https://git.internetallee.de/?a=commitdiff_plain;h=9adda745e149250fff9d54bd24627b8d02b4e9d9;p=securityfilter.git got it working again after refactoring out into separate class --- diff --git a/src/share/org/securityfilter/authenticator/BasicAuthenticator.java b/src/share/org/securityfilter/authenticator/BasicAuthenticator.java index 7eb43fe..529dcaa 100644 --- a/src/share/org/securityfilter/authenticator/BasicAuthenticator.java +++ b/src/share/org/securityfilter/authenticator/BasicAuthenticator.java @@ -1,7 +1,7 @@ /* - * $Header: /cvsroot/securityfilter/securityfilter/src/share/org/securityfilter/authenticator/BasicAuthenticator.java,v 1.1 2003/07/07 13:12:56 maxcooper Exp $ - * $Revision: 1.1 $ - * $Date: 2003/07/07 13:12:56 $ + * $Header: /cvsroot/securityfilter/securityfilter/src/share/org/securityfilter/authenticator/BasicAuthenticator.java,v 1.2 2003/07/14 18:55:14 maxcooper Exp $ + * $Revision: 1.2 $ + * $Date: 2003/07/14 18:55:14 $ * * ==================================================================== * The SecurityFilter Software License, Version 1.1 @@ -70,18 +70,19 @@ import java.security.Principal; * * @author Daya Sharma (iamdaya@yahoo.com, billydaya@sbcglobal.net) * @author Max Cooper (max@maxcooper.com) - * @version $Revision: 1.1 $ $Date: 2003/07/07 13:12:56 $ + * @version $Revision: 1.2 $ $Date: 2003/07/14 18:55:14 $ */ public class BasicAuthenticator implements Authenticator { - public static final String BASIC_WINDOW_SHOWN = "basic_window_shown"; - public static final String LOGIN_ATTEMPTS = "loginAttempts"; - protected static final String DUMMY_TOKEN = "dummyToken"; + public static final String LOGIN_ATTEMPTS = BasicAuthenticator.class.getName() + ".LOGIN_ATTEMPTS"; - public static final Base64 base64Helper = new Base64(); - - protected String tooManyIncorrectLogins; + // todo: allow this message to be configured, internationalized, etc. + public static final String LOGIN_FAILED_MESSAGE = "Sorry you are having problems logging in, please try again"; + public static final int MAX_ATTEMPTS = 3; protected SecurityRealmInterface realm; + protected String realmName; + protected Base64 base64Helper; + /** * Initialize this Authenticator. @@ -91,7 +92,8 @@ public class BasicAuthenticator implements Authenticator { */ public void init(FilterConfig filterConfig, SecurityConfig securityConfig) throws Exception { realm = securityConfig.getRealm(); - tooManyIncorrectLogins = "Sorry you are having problems logging in, please try again"; + realmName = securityConfig.getRealmName(); + base64Helper = new Base64(); } /** @@ -113,77 +115,101 @@ public class BasicAuthenticator implements Authenticator { * @return true if the filter should return after this method ends, false otherwise */ public boolean processLogin(SecurityRequestWrapper request, HttpServletResponse response) throws Exception { - if (basicAuthentication(request)) { - request.getSession().removeAttribute(BASIC_WINDOW_SHOWN); - String username = parseUsername(request.getHeader("Authorization")); - String password = parsePassword(request.getHeader("Authorization")); - Principal principal = realm.authenticate(username, password); - if (principal != null) { - // login successful - // invalidate old session if the user was already authenticated - // NOTE: we may want to check if the user re-authenticated as the same user, currently - // the session will be invalidated even if the user authenticates as the same user. - request.setUserPrincipal(principal); - String continueToURL = SecurityFilter.getContinueToURL(request); - request.getSession().setAttribute(DUMMY_TOKEN, DUMMY_TOKEN); - // This is the url that the user was initially accessing before being prompted for login. - response.sendRedirect(response.encodeRedirectURL(continueToURL)); - } else { - // login failed - // show the basic authentication window again. - showLogin(request.getCurrentRequest(), response); + if (request.getUserPrincipal() == null) { + // attempt to dig out authentication info only if the user has not yet been authenticated + String authorizationHeader = request.getHeader("Authorization"); + HttpSession session = request.getSession(); + if (authorizationHeader != null && session.getAttribute(LOGIN_ATTEMPTS) != null) { + String decoded = decodeBasicAuthorizationString(authorizationHeader); + String username = parseUsername(decoded); + String password = parsePassword(decoded); + Principal principal = realm.authenticate(username, password); + if (principal != null) { + // login successful + request.getSession().removeAttribute(LOGIN_ATTEMPTS); + request.setUserPrincipal(principal); + } else { + // login failed + // show the basic authentication window again. + showLogin(request.getCurrentRequest(), response); + return true; + } } } return false; } /** - * Returns true if this request includes BASIC auth info. + * All requests should be subject to security checking for BASIC authentication. * * @param request - * @return + * @return always false -- check all requests + */ + public boolean bypassSecurityForThisRequest(SecurityRequestWrapper request, URLPatternMatcher patternMatcher) { + return false; + } + + /** + * Show the login page. + * + * @param request the current request + * @param response the current response */ - private boolean basicAuthentication(HttpServletRequest request) { - return ( - request.getSession().getAttribute(BASIC_WINDOW_SHOWN) != null - && request.getHeader("Authorization") != null - ); + public void showLogin(HttpServletRequest request, HttpServletResponse response) throws IOException { + // save this request + SecurityFilter.saveRequestInformation(request); + + // determine the number of login attempts + int loginAttempts; + if (request.getSession().getAttribute(LOGIN_ATTEMPTS) != null) { + loginAttempts = ((Integer) request.getSession().getAttribute(LOGIN_ATTEMPTS)).intValue(); + loginAttempts += 1; + } else { + loginAttempts = 1; + } + request.getSession().setAttribute(LOGIN_ATTEMPTS, new Integer(loginAttempts)); + + if (loginAttempts <= MAX_ATTEMPTS) { + response.setHeader("WWW-Authenticate", "BASIC realm=\"" + realmName + "\""); + response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); + } else { + request.getSession().removeAttribute(LOGIN_ATTEMPTS); + response.sendError(HttpServletResponse.SC_UNAUTHORIZED, LOGIN_FAILED_MESSAGE); + } } /** * Parse the username out of the BASIC authorization header string. - * @param authorization - * @return + * @param decoded + * @return username parsed out of decoded string */ - private String parseUsername(String authorization) { - String unencoded = decodeBasicAuthorizationString(authorization); - if (unencoded == null) { + private String parseUsername(String decoded) { + if (decoded == null) { return null; } else { - int colon = unencoded.indexOf(':'); + int colon = decoded.indexOf(':'); if (colon < 0) { return null; } else { - return unencoded.substring(0, colon).trim(); + return decoded.substring(0, colon).trim(); } } } /** - * Parse the password out of the BASIC authorization header string. - * @param authorization - * @return + * Parse the password out of the decoded BASIC authorization header string. + * @param decoded + * @return password parsed out of decoded string */ - private String parsePassword(String authorization) { - String unencoded = decodeBasicAuthorizationString(authorization); - if (unencoded == null) { + private String parsePassword(String decoded) { + if (decoded == null) { return null; } else { - int colon = unencoded.indexOf(':'); + int colon = decoded.indexOf(':'); if (colon < 0) { return (null); } else { - return unencoded.substring(colon + 1).trim(); + return decoded.substring(colon + 1).trim(); } } } @@ -192,7 +218,7 @@ public class BasicAuthenticator implements Authenticator { * Decode the BASIC authorization string. * * @param authorization - * @return + * @return decoded string */ private String decodeBasicAuthorizationString(String authorization) { if (authorization == null || !authorization.toLowerCase().startsWith("basic ")) { @@ -203,55 +229,6 @@ public class BasicAuthenticator implements Authenticator { return new String(base64Helper.decodeBase64(authorization.getBytes())); } } - - /** - * Show the login page. - * - * @param request the current request - * @param response the current response - */ - public void showLogin(HttpServletRequest request, HttpServletResponse response) throws IOException { - // save this request - SecurityFilter.saveRequestInformation(request); - - // redirect to login page - request.getSession().setAttribute(BASIC_WINDOW_SHOWN, "shown"); - int loginAttempts = 1; - if (request.getSession().getAttribute(LOGIN_ATTEMPTS) != null) { - loginAttempts = ((Integer) request.getSession().getAttribute(LOGIN_ATTEMPTS)).intValue(); - loginAttempts += 1; - } - // todo: we can put some useful message here, perhaps a internationlizable format of message. - String loginAttemptMessage = "Login attempt number " + loginAttempts; - String logo; - if (loginAttempts <= 3) { - String realm = String.valueOf(Math.random()); - if (loginAttempts < 2) { - logo = "Basic Auth with Security Filter"; - } else { - logo = loginAttemptMessage; - } - String blankLine = " "; - logo = blankLine + blankLine + blankLine + logo + blankLine + blankLine; - System.err.println("response.setHeader \"WWW-Authenticate\", \"BASIC realm=\"" + logo + realm + "\""); - response.setHeader("WWW-Authenticate", "BASIC realm=\"" + realm + logo + "\""); - response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); - request.getSession().setAttribute(LOGIN_ATTEMPTS, new Integer(loginAttempts)); - } else { - request.getSession().removeAttribute(LOGIN_ATTEMPTS); - response.sendError(HttpServletResponse.SC_UNAUTHORIZED, tooManyIncorrectLogins); - } - } - - /** - * All requests should be subject to security checking for BASIC authentication. - * - * @param request - * @return always false -- check all requests - */ - public boolean bypassSecurityForThisRequest(SecurityRequestWrapper request, URLPatternMatcher patternMatcher) { - return false; - } } // ------------------------------------------------------------------------