SEC-53: BasicProcessingFilter only to reauthenticate if the SecurityContextHolder contains an unauthenticated Authentication, or an Authentication with a different username.
This commit is contained in:
parent
690ab27a52
commit
d9be0f86fd
|
@ -12,6 +12,7 @@
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package net.sf.acegisecurity.ui.basicauth;
|
package net.sf.acegisecurity.ui.basicauth;
|
||||||
|
|
||||||
import net.sf.acegisecurity.Authentication;
|
import net.sf.acegisecurity.Authentication;
|
||||||
|
@ -101,10 +102,17 @@ import javax.servlet.http.HttpServletResponse;
|
||||||
* @version $Id$
|
* @version $Id$
|
||||||
*/
|
*/
|
||||||
public class BasicProcessingFilter implements Filter, InitializingBean {
|
public class BasicProcessingFilter implements Filter, InitializingBean {
|
||||||
|
//~ Static fields/initializers =============================================
|
||||||
|
|
||||||
private static final Log logger = LogFactory.getLog(BasicProcessingFilter.class);
|
private static final Log logger = LogFactory.getLog(BasicProcessingFilter.class);
|
||||||
|
|
||||||
|
//~ Instance fields ========================================================
|
||||||
|
|
||||||
private AuthenticationEntryPoint authenticationEntryPoint;
|
private AuthenticationEntryPoint authenticationEntryPoint;
|
||||||
private AuthenticationManager authenticationManager;
|
private AuthenticationManager authenticationManager;
|
||||||
|
|
||||||
|
//~ Methods ================================================================
|
||||||
|
|
||||||
public void setAuthenticationEntryPoint(
|
public void setAuthenticationEntryPoint(
|
||||||
AuthenticationEntryPoint authenticationEntryPoint) {
|
AuthenticationEntryPoint authenticationEntryPoint) {
|
||||||
this.authenticationEntryPoint = authenticationEntryPoint;
|
this.authenticationEntryPoint = authenticationEntryPoint;
|
||||||
|
@ -130,8 +138,7 @@ public class BasicProcessingFilter implements Filter, InitializingBean {
|
||||||
"An AuthenticationEntryPoint is required");
|
"An AuthenticationEntryPoint is required");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void destroy() {
|
public void destroy() {}
|
||||||
}
|
|
||||||
|
|
||||||
public void doFilter(ServletRequest request, ServletResponse response,
|
public void doFilter(ServletRequest request, ServletResponse response,
|
||||||
FilterChain chain) throws IOException, ServletException {
|
FilterChain chain) throws IOException, ServletException {
|
||||||
|
@ -165,10 +172,17 @@ public class BasicProcessingFilter implements Filter, InitializingBean {
|
||||||
password = token.substring(delim + 1);
|
password = token.substring(delim + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Only reauthenticate if username doesn't match ContextHolder and user isn't authenticated (see SEC-53)
|
||||||
|
Authentication existingAuth = SecurityContextHolder.getContext()
|
||||||
|
.getAuthentication();
|
||||||
|
|
||||||
|
if ((existingAuth == null)
|
||||||
|
|| !existingAuth.getName().equals(username)
|
||||||
|
|| !existingAuth.isAuthenticated()) {
|
||||||
UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(username,
|
UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(username,
|
||||||
password);
|
password);
|
||||||
authRequest.setDetails(new WebAuthenticationDetails(httpRequest,
|
authRequest.setDetails(new WebAuthenticationDetails(
|
||||||
false));
|
httpRequest, false));
|
||||||
|
|
||||||
Authentication authResult;
|
Authentication authResult;
|
||||||
|
|
||||||
|
@ -177,8 +191,8 @@ public class BasicProcessingFilter implements Filter, InitializingBean {
|
||||||
} catch (AuthenticationException failed) {
|
} catch (AuthenticationException failed) {
|
||||||
// Authentication failed
|
// Authentication failed
|
||||||
if (logger.isDebugEnabled()) {
|
if (logger.isDebugEnabled()) {
|
||||||
logger.debug("Authentication request for user: " +
|
logger.debug("Authentication request for user: "
|
||||||
username + " failed: " + failed.toString());
|
+ username + " failed: " + failed.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
SecurityContextHolder.getContext().setAuthentication(null);
|
SecurityContextHolder.getContext().setAuthentication(null);
|
||||||
|
@ -189,16 +203,16 @@ public class BasicProcessingFilter implements Filter, InitializingBean {
|
||||||
|
|
||||||
// Authentication success
|
// Authentication success
|
||||||
if (logger.isDebugEnabled()) {
|
if (logger.isDebugEnabled()) {
|
||||||
logger.debug("Authentication success: " +
|
logger.debug("Authentication success: "
|
||||||
authResult.toString());
|
+ authResult.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
SecurityContextHolder.getContext().setAuthentication(authResult);
|
SecurityContextHolder.getContext().setAuthentication(authResult);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
chain.doFilter(request, response);
|
chain.doFilter(request, response);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void init(FilterConfig arg0) throws ServletException {
|
public void init(FilterConfig arg0) throws ServletException {}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -183,6 +183,7 @@ public class BasicProcessingFilterTests extends TestCase {
|
||||||
MockHttpServletResponse response = new MockHttpServletResponse();
|
MockHttpServletResponse response = new MockHttpServletResponse();
|
||||||
|
|
||||||
// Test
|
// Test
|
||||||
|
assertNull(SecurityContextHolder.getContext().getAuthentication());
|
||||||
executeFilterInContainerSimulator(config, filter, request, response,
|
executeFilterInContainerSimulator(config, filter, request, response,
|
||||||
chain);
|
chain);
|
||||||
|
|
||||||
|
@ -280,7 +281,7 @@ public class BasicProcessingFilterTests extends TestCase {
|
||||||
|
|
||||||
// NOW PERFORM FAILED AUTHENTICATION
|
// NOW PERFORM FAILED AUTHENTICATION
|
||||||
// Setup our HTTP request
|
// Setup our HTTP request
|
||||||
token = "marissa:WRONG_PASSWORD";
|
token = "otherUser:WRONG_PASSWORD";
|
||||||
request = new MockHttpServletRequest();
|
request = new MockHttpServletRequest();
|
||||||
request.addHeader("Authorization",
|
request.addHeader("Authorization",
|
||||||
"Basic " + new String(Base64.encodeBase64(token.getBytes())));
|
"Basic " + new String(Base64.encodeBase64(token.getBytes())));
|
||||||
|
|
Loading…
Reference in New Issue