@Test
  public void testFailedAuthenticationInvokesFailureHandler() throws Exception {
    // Setup our HTTP request
    MockHttpServletRequest request = createMockAuthenticationRequest();

    // Setup our filter configuration
    MockFilterConfig config = new MockFilterConfig(null, null);

    // Setup our expectation that the filter chain will not be invoked, as we redirect to
    // authenticationFailureUrl
    MockFilterChain chain = new MockFilterChain(false);
    MockHttpServletResponse response = new MockHttpServletResponse();

    // Setup our test object, to deny access
    MockAuthenticationFilter filter = new MockAuthenticationFilter(false);
    AuthenticationFailureHandler failureHandler = mock(AuthenticationFailureHandler.class);
    filter.setAuthenticationFailureHandler(failureHandler);

    // Test
    filter.doFilter(request, response, chain);

    verify(failureHandler)
        .onAuthenticationFailure(
            any(HttpServletRequest.class),
            any(HttpServletResponse.class),
            any(AuthenticationException.class));

    assertNull(SecurityContextHolder.getContext().getAuthentication());
  }
  @Test
  public void testFilterProcessesUrlVariationsRespected() throws Exception {
    // Setup our HTTP request
    MockHttpServletRequest request = createMockAuthenticationRequest();
    request.setServletPath("/j_OTHER_LOCATION");
    request.setRequestURI("/mycontext/j_OTHER_LOCATION");

    // Setup our filter configuration
    MockFilterConfig config = new MockFilterConfig(null, null);

    // Setup our expectation that the filter chain will not be invoked, as we redirect to
    // defaultTargetUrl
    MockFilterChain chain = new MockFilterChain(false);
    MockHttpServletResponse response = new MockHttpServletResponse();

    // Setup our test object, to grant access
    MockAuthenticationFilter filter = new MockAuthenticationFilter(true);
    filter.setFilterProcessesUrl("/j_OTHER_LOCATION");
    filter.setAuthenticationSuccessHandler(successHandler);

    // Test
    filter.doFilter(request, response, chain);
    assertEquals("/mycontext/logged_in.jsp", response.getRedirectedUrl());
    assertNotNull(SecurityContextHolder.getContext().getAuthentication());
    assertEquals(
        "test", SecurityContextHolder.getContext().getAuthentication().getPrincipal().toString());
  }
  @Test
  public void testSuccessfulAuthenticationInvokesSuccessHandlerAndSetsContext() throws Exception {
    // Setup our HTTP request
    MockHttpServletRequest request = createMockAuthenticationRequest();

    // Setup our filter configuration
    MockFilterConfig config = new MockFilterConfig(null, null);

    // Setup our expectation that the filter chain will be invoked, as we want to go to the location
    // requested in the session
    MockFilterChain chain = new MockFilterChain(true);
    MockHttpServletResponse response = new MockHttpServletResponse();

    // Setup our test object, to grant access
    MockAuthenticationFilter filter = new MockAuthenticationFilter(true);
    filter.setFilterProcessesUrl("/j_mock_post");
    AuthenticationSuccessHandler successHandler = mock(AuthenticationSuccessHandler.class);
    filter.setAuthenticationSuccessHandler(successHandler);

    // Test
    filter.doFilter(request, response, chain);

    verify(successHandler)
        .onAuthenticationSuccess(
            any(HttpServletRequest.class),
            any(HttpServletResponse.class),
            any(Authentication.class));

    assertNotNull(SecurityContextHolder.getContext().getAuthentication());
  }
  @Test
  public void testNormalOperationWithDefaultFilterProcessesUrl() throws Exception {
    // Setup our HTTP request
    MockHttpServletRequest request = createMockAuthenticationRequest();
    HttpSession sessionPreAuth = request.getSession();

    // Setup our filter configuration
    MockFilterConfig config = new MockFilterConfig(null, null);

    // Setup our expectation that the filter chain will not be invoked, as we redirect to
    // defaultTargetUrl
    MockFilterChain chain = new MockFilterChain(false);
    MockHttpServletResponse response = new MockHttpServletResponse();

    // Setup our test object, to grant access
    MockAuthenticationFilter filter = new MockAuthenticationFilter(true);

    filter.setFilterProcessesUrl("/j_mock_post");
    filter.setSessionAuthenticationStrategy(mock(SessionAuthenticationStrategy.class));
    filter.setAuthenticationSuccessHandler(successHandler);
    filter.setAuthenticationFailureHandler(failureHandler);
    filter.setAuthenticationManager(mock(AuthenticationManager.class));
    filter.afterPropertiesSet();

    // Test
    filter.doFilter(request, response, chain);
    assertEquals("/mycontext/logged_in.jsp", response.getRedirectedUrl());
    assertNotNull(SecurityContextHolder.getContext().getAuthentication());
    assertEquals(
        "test", SecurityContextHolder.getContext().getAuthentication().getPrincipal().toString());
    // Should still have the same session
    assertEquals(sessionPreAuth, request.getSession());
  }
  @Test
  public void testSuccessLoginThenFailureLoginResultsInSessionLosingToken() throws Exception {
    // Setup our HTTP request
    MockHttpServletRequest request = createMockAuthenticationRequest();

    // Setup our filter configuration
    MockFilterConfig config = new MockFilterConfig(null, null);

    // Setup our expectation that the filter chain will not be invoked, as we redirect to
    // defaultTargetUrl
    MockFilterChain chain = new MockFilterChain(false);
    MockHttpServletResponse response = new MockHttpServletResponse();

    // Setup our test object, to grant access
    MockAuthenticationFilter filter = new MockAuthenticationFilter(true);
    filter.setFilterProcessesUrl("/j_mock_post");
    filter.setAuthenticationSuccessHandler(successHandler);

    // Test
    filter.doFilter(request, response, chain);
    assertEquals("/mycontext/logged_in.jsp", response.getRedirectedUrl());
    assertNotNull(SecurityContextHolder.getContext().getAuthentication());
    assertEquals(
        "test", SecurityContextHolder.getContext().getAuthentication().getPrincipal().toString());

    // Now try again but this time have filter deny access
    // Setup our HTTP request
    // Setup our expectation that the filter chain will not be invoked, as we redirect to
    // authenticationFailureUrl
    chain = new MockFilterChain(false);
    response = new MockHttpServletResponse();

    // Setup our test object, to deny access
    filter = new MockAuthenticationFilter(false);
    filter.setFilterProcessesUrl("/j_mock_post");
    filter.setAuthenticationFailureHandler(failureHandler);

    // Test
    filter.doFilter(request, response, chain);
    assertNull(SecurityContextHolder.getContext().getAuthentication());
  }
  /** SEC-462 */
  @Test
  public void testLoginErrorWithNoFailureUrlSendsUnauthorizedStatus() throws Exception {
    MockHttpServletRequest request = createMockAuthenticationRequest();

    MockFilterConfig config = new MockFilterConfig(null, null);
    MockFilterChain chain = new MockFilterChain(true);
    MockHttpServletResponse response = new MockHttpServletResponse();

    MockAuthenticationFilter filter = new MockAuthenticationFilter(false);
    successHandler.setDefaultTargetUrl("http://monkeymachine.co.uk/");
    filter.setAuthenticationSuccessHandler(successHandler);

    filter.doFilter(request, response, chain);

    assertEquals(HttpServletResponse.SC_UNAUTHORIZED, response.getStatus());
  }
  /** SEC-571 */
  @Test
  public void testNoSessionIsCreatedIfAllowSessionCreationIsFalse() throws Exception {
    MockHttpServletRequest request = createMockAuthenticationRequest();

    MockFilterConfig config = new MockFilterConfig(null, null);
    MockFilterChain chain = new MockFilterChain(true);
    MockHttpServletResponse response = new MockHttpServletResponse();

    // Reject authentication, so exception would normally be stored in session
    MockAuthenticationFilter filter = new MockAuthenticationFilter(false);
    failureHandler.setAllowSessionCreation(false);
    filter.setAuthenticationFailureHandler(failureHandler);

    filter.doFilter(request, response, chain);

    assertNull(request.getSession(false));
  }
  /** SEC-1919 */
  @Test
  public void loginErrorWithInternAuthenticationServiceExceptionLogsError() throws Exception {
    MockHttpServletRequest request = createMockAuthenticationRequest();

    MockFilterChain chain = new MockFilterChain(true);
    MockHttpServletResponse response = new MockHttpServletResponse();

    Log logger = mock(Log.class);
    MockAuthenticationFilter filter = new MockAuthenticationFilter(false);
    ReflectionTestUtils.setField(filter, "logger", logger);
    filter.exceptionToThrow = new InternalAuthenticationServiceException("Mock requested to do so");
    successHandler.setDefaultTargetUrl("http://monkeymachine.co.uk/");
    filter.setAuthenticationSuccessHandler(successHandler);

    filter.doFilter(request, response, chain);

    verify(logger).error(anyString(), eq(filter.exceptionToThrow));
    assertEquals(HttpServletResponse.SC_UNAUTHORIZED, response.getStatus());
  }
  @Test
  public void testIgnoresAnyServletPathOtherThanFilterProcessesUrl() throws Exception {
    // Setup our HTTP request
    MockHttpServletRequest request = createMockAuthenticationRequest();
    request.setServletPath("/some.file.html");
    request.setRequestURI("/mycontext/some.file.html");

    // Setup our filter configuration
    MockFilterConfig config = new MockFilterConfig(null, null);

    // Setup our expectation that the filter chain will be invoked, as our request is for a page the
    // filter isn't monitoring
    MockFilterChain chain = new MockFilterChain(true);
    MockHttpServletResponse response = new MockHttpServletResponse();

    // Setup our test object, to deny access
    MockAuthenticationFilter filter = new MockAuthenticationFilter(false);

    // Test
    filter.doFilter(request, response, chain);
  }