Explorar o código

SEC-1430: Removed caching of username in session upon failed authentication. Improved Javadoc.

Luke Taylor %!s(int64=14) %!d(string=hai) anos
pai
achega
43be9ea2a4

+ 0 - 14
openid/src/main/java/org/springframework/security/openid/OpenIDAuthenticationFilter.java

@@ -123,8 +123,6 @@ public class OpenIDAuthenticationFilter extends AbstractAuthenticationProcessing
 
         if (!StringUtils.hasText(identity)) {
             String claimedIdentity = obtainUsername(request);
-            // Make the username available to the view
-            setLastUsername(claimedIdentity, request);
 
             try {
                 String returnToUrl = buildReturnToUrl(request);
@@ -159,21 +157,9 @@ public class OpenIDAuthenticationFilter extends AbstractAuthenticationProcessing
         // delegate to the authentication provider
         Authentication authentication = this.getAuthenticationManager().authenticate(token);
 
-        if (authentication.isAuthenticated()) {
-            setLastUsername(token.getIdentityUrl(), request);
-        }
-
         return authentication;
     }
 
-    private void setLastUsername(String username, HttpServletRequest request) {
-        HttpSession session = request.getSession(false);
-
-        if (session != null || getAllowSessionCreation()) {
-            request.getSession().setAttribute(UsernamePasswordAuthenticationFilter.SPRING_SECURITY_LAST_USERNAME_KEY, username);
-        }
-    }
-
     protected String lookupRealm(String returnToUrl) {
         String mapping = realmMapping.get(returnToUrl);
 

+ 2 - 2
sandbox/heavyduty/src/main/webapp/login.jsp

@@ -23,8 +23,8 @@
 
     <form name="f" action="<c:url value='j_spring_security_check'/>" method="POST">
       <table>
-        <tr><td>User:</td><td><input type='text' name='j_username' <% if (session.getAttribute(UsernamePasswordAuthenticationFilter.SPRING_SECURITY_LAST_USERNAME_KEY) != null) { %>value='<%= session.getAttribute(UsernamePasswordAuthenticationFilter.SPRING_SECURITY_LAST_USERNAME_KEY) %>'<% } %>></td></tr>
-        <tr><td>Password:</td><td><input type='password' name='j_password'></td></tr>
+        <tr><td>User:</td><td><input type='text' name='j_username' /></td></tr>
+        <tr><td>Password:</td><td><input type='password' name='j_password'/></td></tr>
         <tr><td><input type="checkbox" name="_spring_security_remember_me"></td><td>Don't ask for my password for two weeks</td></tr>
 
         <tr><td colspan='2'><input name="submit" type="submit"></td></tr>

+ 11 - 0
web/src/main/java/org/springframework/security/web/WebAttributes.java

@@ -7,7 +7,18 @@ package org.springframework.security.web;
  * @since 3.0.3
  */
 public final class WebAttributes {
+   /**
+    * Used to cache an {@code AccessDeniedException} in the request for rendering.
+    *
+    * @see org.springframework.security.web.access.AccessDeniedHandlerImpl
+    */
     public static final String ACCESS_DENIED_403 = "SPRING_SECURITY_403_EXCEPTION";
+
+   /**
+    * Used to cache an authentication-failure exception in the session.
+    *
+    * @see org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler
+    */
     public static final String AUTHENTICATION_EXCEPTION = "SPRING_SECURITY_LAST_EXCEPTION";
     public static final String LAST_USERNAME = "SPRING_SECURITY_LAST_USERNAME";
 }

+ 0 - 1
web/src/main/java/org/springframework/security/web/authentication/SimpleUrlAuthenticationSuccessHandler.java

@@ -55,6 +55,5 @@ public class SimpleUrlAuthenticationSuccessHandler extends AbstractAuthenticatio
         }
 
         session.removeAttribute(WebAttributes.AUTHENTICATION_EXCEPTION);
-        session.removeAttribute(WebAttributes.LAST_USERNAME);
     }
 }

+ 4 - 7
web/src/main/java/org/springframework/security/web/authentication/UsernamePasswordAuthenticationFilter.java

@@ -50,6 +50,10 @@ public class UsernamePasswordAuthenticationFilter extends AbstractAuthentication
 
     public static final String SPRING_SECURITY_FORM_USERNAME_KEY = "j_username";
     public static final String SPRING_SECURITY_FORM_PASSWORD_KEY = "j_password";
+    /**
+     * @deprecated If you want to retain the username, cache it in a customized {@code AuthenticationFailureHandler}
+     */
+    @Deprecated
     public static final String SPRING_SECURITY_LAST_USERNAME_KEY = "SPRING_SECURITY_LAST_USERNAME";
 
     private String usernameParameter = SPRING_SECURITY_FORM_USERNAME_KEY;
@@ -84,13 +88,6 @@ public class UsernamePasswordAuthenticationFilter extends AbstractAuthentication
 
         UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(username, password);
 
-        // Place the last username attempted into HttpSession for views
-        HttpSession session = request.getSession(false);
-
-        if (session != null || getAllowSessionCreation()) {
-            request.getSession().setAttribute(SPRING_SECURITY_LAST_USERNAME_KEY, TextEscapeUtils.escapeEntities(username));
-        }
-
         // Allow subclasses to set the "details" property
         setDetails(request, authRequest);
 

+ 3 - 2
web/src/main/java/org/springframework/security/web/authentication/session/SessionFixationProtectionStrategy.java

@@ -14,8 +14,9 @@ import java.util.*;
  * The default implementation of {@link SessionAuthenticationStrategy}.
  * <p>
  * Creates a new session for the newly authenticated user if they already have a session (as a defence against
- * session-fixation protection attacks), and copies their session attributes across to the new session
- * (can be disabled by setting {@code migrateSessionAttributes} to {@code false}).
+ * session-fixation protection attacks), and copies their session attributes across to the new session.
+ * The copying of the attributes can be disabled by setting {@code migrateSessionAttributes} to {@code false}
+ * (note that even in this case, internal Spring Security attributes will still be migrated to the new session).
  * <p>
  * This approach will only be effective if your servlet container always assigns a new session Id when a session is
  * invalidated and a new session created by calling {@link HttpServletRequest#getSession()}.

+ 1 - 6
web/src/main/java/org/springframework/security/web/authentication/ui/DefaultLoginPageGeneratingFilter.java

@@ -94,18 +94,13 @@ public class DefaultLoginPageGeneratingFilter extends GenericFilterBean {
     private String generateLoginPageHtml(HttpServletRequest request) {
         boolean loginError = request.getParameter(ERROR_PARAMETER_NAME) != null;
         String errorMsg = "none";
-        String lastUser = "";
 
         if (loginError) {
             HttpSession session = request.getSession(false);
 
             if(session != null) {
-                lastUser = (String) session.getAttribute(UsernamePasswordAuthenticationFilter.SPRING_SECURITY_LAST_USERNAME_KEY);
                 AuthenticationException ex = (AuthenticationException) session.getAttribute(WebAttributes.AUTHENTICATION_EXCEPTION);
                 errorMsg = ex != null ? ex.getMessage() : "none";
-                if (lastUser == null) {
-                    lastUser = "";
-                }
             }
         }
 
@@ -128,7 +123,7 @@ public class DefaultLoginPageGeneratingFilter extends GenericFilterBean {
             sb.append("<form name='f' action='").append(request.getContextPath()).append(authenticationUrl).append("' method='POST'>\n");
             sb.append(" <table>\n");
             sb.append("    <tr><td>User:</td><td><input type='text' name='");
-            sb.append(usernameParameter).append("' value='").append(lastUser).append("'></td></tr>\n");
+            sb.append(usernameParameter).append("' value='").append("'></td></tr>\n");
             sb.append("    <tr><td>Password:</td><td><input type='password' name='").append(passwordParameter).append("'/></td></tr>\n");
 
             if (rememberMeParameter != null) {

+ 0 - 6
web/src/test/java/org/springframework/security/web/authentication/UsernamePasswordAuthenticationFilterTests.java

@@ -55,8 +55,6 @@ public class UsernamePasswordAuthenticationFilterTests extends TestCase {
 
         Authentication result = filter.attemptAuthentication(request, new MockHttpServletResponse());
         assertTrue(result != null);
-        assertEquals("rod", request.getSession().getAttribute(
-                UsernamePasswordAuthenticationFilter.SPRING_SECURITY_LAST_USERNAME_KEY));
         assertEquals("127.0.0.1", ((WebAuthenticationDetails) result.getDetails()).getRemoteAddress());
     }
 
@@ -123,10 +121,6 @@ public class UsernamePasswordAuthenticationFilterTests extends TestCase {
             fail("Expected AuthenticationException");
         } catch (AuthenticationException e) {
         }
-
-        // Check username has still been set
-        assertEquals("rod", request.getSession().getAttribute(
-                UsernamePasswordAuthenticationFilter.SPRING_SECURITY_LAST_USERNAME_KEY));
     }
 
     /**