// Path: spring/spring-security/src/main/java/org/juiser/spring/security/authentication/HeaderAuthenticationToken.java
// public class HeaderAuthenticationToken extends AbstractAuthenticationToken {
// 
//     private final String headerName;
// 
//     private final String headerValue;
// 
//     public HeaderAuthenticationToken(String headerName, String headerValue) {
//         super(null);
//         Assert.hasText(headerName, "headerName cannot be null or empty.");
//         this.headerName = headerName;
//         Assert.hasText(headerValue, "headerValue cannot be null or empty.");
//         this.headerValue = headerValue;
//     }
// 
//     public String getHeaderName() {
//         return headerName;
//     }
// 
//     @Override
//     public Object getCredentials() {
//         return this.headerValue;
//     }
// 
//     @Override
//     public Object getPrincipal() {
//         return this.headerValue;
//     }
// }


import org.juiser.spring.security.authentication.HeaderAuthenticationToken;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.InternalAuthenticationServiceException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.util.matcher.RequestHeaderRequestMatcher;
import org.springframework.security.web.util.matcher.RequestMatcher;
import org.springframework.util.Assert;
import org.springframework.web.filter.GenericFilterBean;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

    /**
     * Clears the {@link SecurityContextHolder} and returns {@code true}.
     */
    protected boolean unsuccessfulAuthentication(HttpServletRequest request,
                                                 HttpServletResponse response,
                                                 FilterChain chain,
                                                 AuthenticationException failed)
        throws IOException, ServletException {

        SecurityContextHolder.clearContext();

        if (log.isDebugEnabled()) {
            log.debug("Authentication request failed: " + failed.toString(), failed);
            log.debug("Updated SecurityContextHolder to contain null Authentication");
            log.debug("Continuing filter chain with null Authentication");
        }

        return true;
    }

    protected Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response)
        throws AuthenticationException, IOException, ServletException {

        String name = getHeaderName();

        String value = request.getHeader(name);

        Assert.hasText(value, "Missing expected request header value.");

// Path: spring/spring-security/src/main/java/org/juiser/spring/security/authentication/HeaderAuthenticationToken.java
// public class HeaderAuthenticationToken extends AbstractAuthenticationToken {
// 
//     private final String headerName;
// 
//     private final String headerValue;
// 
//     public HeaderAuthenticationToken(String headerName, String headerValue) {
//         super(null);
//         Assert.hasText(headerName, "headerName cannot be null or empty.");
//         this.headerName = headerName;
//         Assert.hasText(headerValue, "headerValue cannot be null or empty.");
//         this.headerValue = headerValue;
//     }
// 
//     public String getHeaderName() {
//         return headerName;
//     }
// 
//     @Override
//     public Object getCredentials() {
//         return this.headerValue;
//     }
// 
//     @Override
//     public Object getPrincipal() {
//         return this.headerValue;
//     }
// }


// Path: spring/spring-security/src/main/java/org/juiser/spring/security/web/authentication/HeaderAuthenticationFilter.java
import org.juiser.spring.security.authentication.HeaderAuthenticationToken;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.InternalAuthenticationServiceException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.util.matcher.RequestHeaderRequestMatcher;
import org.springframework.security.web.util.matcher.RequestMatcher;
import org.springframework.util.Assert;
import org.springframework.web.filter.GenericFilterBean;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;


    /**
     * Clears the {@link SecurityContextHolder} and returns {@code true}.
     */
    protected boolean unsuccessfulAuthentication(HttpServletRequest request,
                                                 HttpServletResponse response,
                                                 FilterChain chain,
                                                 AuthenticationException failed)
        throws IOException, ServletException {

        SecurityContextHolder.clearContext();

        if (log.isDebugEnabled()) {
            log.debug("Authentication request failed: " + failed.toString(), failed);
            log.debug("Updated SecurityContextHolder to contain null Authentication");
            log.debug("Continuing filter chain with null Authentication");
        }

        return true;
    }

    protected Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response)
        throws AuthenticationException, IOException, ServletException {

        String name = getHeaderName();

        String value = request.getHeader(name);

        Assert.hasText(value, "Missing expected request header value.");

        HeaderAuthenticationToken token = new HeaderAuthenticationToken(name, value);