|  | @@ -15,19 +15,16 @@
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  package org.springframework.security.ui.ntlm;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -import org.springframework.security.AuthenticationException;
 | 
	
		
			
				|  |  | -import org.springframework.security.ui.AuthenticationEntryPoint;
 | 
	
		
			
				|  |  | -import org.apache.commons.logging.Log;
 | 
	
		
			
				|  |  | -import org.apache.commons.logging.LogFactory;
 | 
	
		
			
				|  |  | -import org.springframework.beans.factory.InitializingBean;
 | 
	
		
			
				|  |  | -import org.springframework.util.Assert;
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  |  import java.io.IOException;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  import javax.servlet.ServletException;
 | 
	
		
			
				|  |  |  import javax.servlet.http.HttpServletRequest;
 | 
	
		
			
				|  |  |  import javax.servlet.http.HttpServletResponse;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +import org.springframework.security.AuthenticationException;
 | 
	
		
			
				|  |  | +import org.springframework.security.ui.AuthenticationEntryPoint;
 | 
	
		
			
				|  |  | +import org.springframework.util.Assert;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |  /**
 | 
	
		
			
				|  |  |   * Used by <code>ExceptionTranslationFilter</code> to assist with the NTLM
 | 
	
		
			
				|  |  |   * negotiation.  Also handles redirecting the user to the authentication
 | 
	
	
		
			
				|  | @@ -39,76 +36,73 @@ import javax.servlet.http.HttpServletResponse;
 | 
	
		
			
				|  |  |   * @version $Id$
 | 
	
		
			
				|  |  |   */
 | 
	
		
			
				|  |  |  public class NtlmProcessingFilterEntryPoint implements AuthenticationEntryPoint {
 | 
	
		
			
				|  |  | -    //~ Static fields/initializers =====================================================================================
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -    private static final Log logger = LogFactory.getLog(NtlmProcessingFilterEntryPoint.class);
 | 
	
		
			
				|  |  | +    //~ Instance fields ================================================================================================
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    /** Where to redirect the browser to if authentication fails */
 | 
	
		
			
				|  |  | +    private String authenticationFailureUrl;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -	//~ Instance fields ================================================================================================
 | 
	
		
			
				|  |  | +    //~ Methods ========================================================================================================
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -	/** Where to redirect the browser to if authentication fails		*/
 | 
	
		
			
				|  |  | -	private String authenticationFailureUrl;
 | 
	
		
			
				|  |  | +    /**
 | 
	
		
			
				|  |  | +     * Sets the authentication failure URL.
 | 
	
		
			
				|  |  | +     *
 | 
	
		
			
				|  |  | +     * @param authenticationFailureUrl the authentication failure URL.
 | 
	
		
			
				|  |  | +     */
 | 
	
		
			
				|  |  | +    public void setAuthenticationFailureUrl(String authenticationFailureUrl) {
 | 
	
		
			
				|  |  | +        Assert.hasLength(authenticationFailureUrl, "authenticationFailureUrl must be specified");
 | 
	
		
			
				|  |  | +        this.authenticationFailureUrl = authenticationFailureUrl;
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -	//~ Methods ========================================================================================================
 | 
	
		
			
				|  |  | +    /**
 | 
	
		
			
				|  |  | +     * Sends an NTLM challenge to the browser requiring authentication. The
 | 
	
		
			
				|  |  | +     * WWW-Authenticate header is populated with the appropriate information
 | 
	
		
			
				|  |  | +     * during the negotiation lifecycle by calling the getMessage() method
 | 
	
		
			
				|  |  | +     * from an NTLM-specific subclass of {@link NtlmBaseException}:
 | 
	
		
			
				|  |  | +     * <p>
 | 
	
		
			
				|  |  | +     * <ul>
 | 
	
		
			
				|  |  | +     * <li>{@link NtlmBeginHandshakeException}: NTLM
 | 
	
		
			
				|  |  | +     * <li>{@link NtlmType2MessageException}: NTLM <base64-encoded type-2-message>
 | 
	
		
			
				|  |  | +     * </ul>
 | 
	
		
			
				|  |  | +     *
 | 
	
		
			
				|  |  | +     * If the {@link AuthenticationException} is not a subclass of
 | 
	
		
			
				|  |  | +     * {@link NtlmBaseException}, then redirect the user to the authentication
 | 
	
		
			
				|  |  | +     * failure URL.
 | 
	
		
			
				|  |  | +     *
 | 
	
		
			
				|  |  | +     * @param request The {@link HttpServletRequest} object.
 | 
	
		
			
				|  |  | +     * @param response Then {@link HttpServletResponse} object.
 | 
	
		
			
				|  |  | +     * @param authException Either {@link NtlmBeginHandshakeException},
 | 
	
		
			
				|  |  | +     * 						{@link NtlmType2MessageException}, or
 | 
	
		
			
				|  |  | +     * 						{@link AuthenticationException}
 | 
	
		
			
				|  |  | +     */
 | 
	
		
			
				|  |  | +    public void commence(final HttpServletRequest request, final HttpServletResponse response, final AuthenticationException authException) throws IOException, ServletException {
 | 
	
		
			
				|  |  | +        final HttpServletResponse resp = (HttpServletResponse) response;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -	/**
 | 
	
		
			
				|  |  | -	 * Sets the authentication failure URL.
 | 
	
		
			
				|  |  | -	 *
 | 
	
		
			
				|  |  | -	 * @param authenticationFailureUrl the authentication failure URL.
 | 
	
		
			
				|  |  | -	 */
 | 
	
		
			
				|  |  | -	public void setAuthenticationFailureUrl(String authenticationFailureUrl) {
 | 
	
		
			
				|  |  | -		Assert.hasLength(authenticationFailureUrl, "authenticationFailureUrl must be specified");
 | 
	
		
			
				|  |  | -		this.authenticationFailureUrl = authenticationFailureUrl;
 | 
	
		
			
				|  |  | -	}
 | 
	
		
			
				|  |  | +        if (authException instanceof NtlmBaseException) {
 | 
	
		
			
				|  |  | +            if (authException instanceof NtlmType2MessageException) {
 | 
	
		
			
				|  |  | +                ((NtlmType2MessageException) authException).preserveAuthentication();
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +            resp.setHeader("WWW-Authenticate", authException.getMessage());
 | 
	
		
			
				|  |  | +            resp.setHeader("Connection", "Keep-Alive");
 | 
	
		
			
				|  |  | +            resp.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
 | 
	
		
			
				|  |  | +            resp.setContentLength(0);
 | 
	
		
			
				|  |  | +            resp.flushBuffer();
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -	/**
 | 
	
		
			
				|  |  | -	 * Sends an NTLM challenge to the browser requiring authentication. The
 | 
	
		
			
				|  |  | -	 * WWW-Authenticate header is populated with the appropriate information
 | 
	
		
			
				|  |  | -	 * during the negotiation lifecycle by calling the getMessage() method
 | 
	
		
			
				|  |  | -	 * from an NTLM-specific subclass of {@link NtlmBaseException}:
 | 
	
		
			
				|  |  | -	 * <p>
 | 
	
		
			
				|  |  | -	 * <ul>
 | 
	
		
			
				|  |  | -	 * <li>{@link NtlmBeginHandshakeException}: NTLM
 | 
	
		
			
				|  |  | -	 * <li>{@link NtlmType2MessageException}: NTLM <base64-encoded type-2-message>
 | 
	
		
			
				|  |  | -	 * </ul>
 | 
	
		
			
				|  |  | -	 *
 | 
	
		
			
				|  |  | -	 * If the {@link AuthenticationException} is not a subclass of
 | 
	
		
			
				|  |  | -	 * {@link NtlmBaseException}, then redirect the user to the authentication
 | 
	
		
			
				|  |  | -	 * failure URL.
 | 
	
		
			
				|  |  | -	 *
 | 
	
		
			
				|  |  | -	 * @param request The {@link HttpServletRequest} object.
 | 
	
		
			
				|  |  | -	 * @param response Then {@link HttpServletResponse} object.
 | 
	
		
			
				|  |  | -	 * @param authException Either {@link NtlmBeginHandshakeException},
 | 
	
		
			
				|  |  | -	 * 						{@link NtlmType2MessageException}, or
 | 
	
		
			
				|  |  | -	 * 						{@link AuthenticationException}
 | 
	
		
			
				|  |  | -	 */
 | 
	
		
			
				|  |  | -	public void commence(final HttpServletRequest request, final HttpServletResponse response, final AuthenticationException authException) throws IOException, ServletException {
 | 
	
		
			
				|  |  | -		final HttpServletResponse resp = (HttpServletResponse) response;
 | 
	
		
			
				|  |  | +            return;
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -		if (authException instanceof NtlmBaseException) {
 | 
	
		
			
				|  |  | -			if (authException instanceof NtlmType2MessageException) {
 | 
	
		
			
				|  |  | -				((NtlmType2MessageException) authException).preserveAuthentication();
 | 
	
		
			
				|  |  | -			}
 | 
	
		
			
				|  |  | -			resp.setHeader("WWW-Authenticate", authException.getMessage());
 | 
	
		
			
				|  |  | -			resp.setHeader("Connection", "Keep-Alive");
 | 
	
		
			
				|  |  | -			resp.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
 | 
	
		
			
				|  |  | -			resp.setContentLength(0);
 | 
	
		
			
				|  |  | -			resp.flushBuffer();
 | 
	
		
			
				|  |  | -			
 | 
	
		
			
				|  |  | -			return;
 | 
	
		
			
				|  |  | -		}
 | 
	
		
			
				|  |  | -		
 | 
	
		
			
				|  |  | -		if (authenticationFailureUrl == null) {
 | 
	
		
			
				|  |  | -	        if (!response.isCommitted()) {
 | 
	
		
			
				|  |  | -	            ((HttpServletResponse) response).sendError(HttpServletResponse.SC_FORBIDDEN, authException.getMessage());
 | 
	
		
			
				|  |  | -	        }
 | 
	
		
			
				|  |  | -		} else {
 | 
	
		
			
				|  |  | -			String url = authenticationFailureUrl;
 | 
	
		
			
				|  |  | -			if (!url.startsWith("http://") && !url.startsWith("https://")) {
 | 
	
		
			
				|  |  | -				url = ((HttpServletRequest) request).getContextPath() + url;
 | 
	
		
			
				|  |  | -			}
 | 
	
		
			
				|  |  | +        if (authenticationFailureUrl == null) {
 | 
	
		
			
				|  |  | +            if (!response.isCommitted()) {
 | 
	
		
			
				|  |  | +                ((HttpServletResponse) response).sendError(HttpServletResponse.SC_FORBIDDEN, authException.getMessage());
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +        } else {
 | 
	
		
			
				|  |  | +            String url = authenticationFailureUrl;
 | 
	
		
			
				|  |  | +            if (!url.startsWith("http://") && !url.startsWith("https://")) {
 | 
	
		
			
				|  |  | +                url = ((HttpServletRequest) request).getContextPath() + url;
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -			resp.sendRedirect(resp.encodeRedirectURL(url));
 | 
	
		
			
				|  |  | -		}
 | 
	
		
			
				|  |  | -	}
 | 
	
		
			
				|  |  | +            resp.sendRedirect(resp.encodeRedirectURL(url));
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  }
 |