Package org.mule.transport.http.ntlm

Source Code of org.mule.transport.http.ntlm.NTLMScheme

/*
* Copyright (c) MuleSoft, Inc.  All rights reserved.  http://www.mulesoft.com
* The software in this package is published under the terms of the CPAL v1.0
* license, a copy of which has been included with this distribution in the
* LICENSE.txt file.
*/
package org.mule.transport.http.ntlm;

import jcifs.ntlmssp.NtlmMessage;
import jcifs.ntlmssp.Type2Message;
import org.apache.commons.httpclient.Credentials;
import org.apache.commons.httpclient.HttpMethod;
import org.apache.commons.httpclient.NTCredentials;
import org.apache.commons.httpclient.auth.AuthChallengeParser;
import org.apache.commons.httpclient.auth.AuthScheme;
import org.apache.commons.httpclient.auth.AuthenticationException;
import org.apache.commons.httpclient.auth.InvalidCredentialsException;
import org.apache.commons.httpclient.auth.MalformedChallengeException;

import static jcifs.util.Base64.encode;

/**
* Reimplements {@link org.apache.commons.httpclient.auth.NTLMScheme} using JCIFS
* org.apache.commons.httpclient.auth.NTLMScheme. <p>
* This class has to be registered manually in order to be used:
* <code>
* AuthPolicy.registerAuthScheme(AuthPolicy.NTLM, NTLMScheme.class);
* </code>
*/
public class NTLMScheme implements AuthScheme
{

    private static enum AUTHENTICATION_STATE
    {
        UNINITIATED, INITIATED, TYPE1_MSG_GENERATED, TYPE2_MSG_RECEIVED, TYPE3_MSG_GENERATED, FAILED
    }

    private static final String NOT_IMPLEMENTED_ERROR = "Not implemented as it is deprecated anyway in Httpclient 3.x";

    /**
     * Authentication process authenticationState
     */
    private AUTHENTICATION_STATE authenticationState = AUTHENTICATION_STATE.UNINITIATED;

    /**
     * NTLM challenge string received form the server.
     */
    private String receivedNtlmChallenge = null;

    /**
     * Creates NTLM messages used during the authentication process.
     */
    private final NtlmMessageFactory ntlmMessageFactory = new NtlmMessageFactory();

    public String authenticate(Credentials credentials, HttpMethod method) throws AuthenticationException
    {
        if (authenticationState == AUTHENTICATION_STATE.UNINITIATED)
        {
            throw new IllegalStateException("NTLM authentication process has not been initiated");
        }

        NtlmMessage response;

        NTCredentials ntcredentials = getNTCredentials(credentials);
        if (authenticationState == AUTHENTICATION_STATE.INITIATED || authenticationState == AUTHENTICATION_STATE.FAILED)
        {
            // Original implementation used ntCredential info instead of null values
            response = ntlmMessageFactory.createType1Message(null, null);
            authenticationState = AUTHENTICATION_STATE.TYPE1_MSG_GENERATED;
        }
        else
        {
            Type2Message type2MessageFromChallenge = ntlmMessageFactory.createType2Message(receivedNtlmChallenge);
            response = ntlmMessageFactory.createType3Message(ntcredentials, type2MessageFromChallenge);
            authenticationState = AUTHENTICATION_STATE.TYPE3_MSG_GENERATED;
        }

        return ntlmMessageToString(response);
    }

    private NTCredentials getNTCredentials(Credentials credentials) throws InvalidCredentialsException
    {
        try
        {
            return (NTCredentials) credentials;
        }
        catch (ClassCastException e)
        {
            throw new InvalidCredentialsException("Credentials cannot be used for NTLM authentication: "
                                                  + credentials.getClass().getName());
        }
    }

    public String authenticate(Credentials credentials, String method, String uri) throws AuthenticationException
    {
        throw new RuntimeException(NOT_IMPLEMENTED_ERROR);
    }

    public String getID()
    {
        throw new RuntimeException(NOT_IMPLEMENTED_ERROR);
    }

    /**
     * Returns the authentication parameter with the given name, if available.
     * <p/>
     * There are no valid parameters for NTLM authentication so this method
     * <p/>
     * always returns <tt>null</tt>.
     * <p/>
     *
     * @param name The name of the parameter to be returned
     * @return the parameter with the given name
     */
    public String getParameter(String name)
    {
        if (name == null)
        {
            throw new IllegalArgumentException("Parameter name may not be null");
        }

        return null;
    }

    /**
     * The concept of an authentication realm is not supported by the NTLM
     * authentication scheme. Always returns <code>null</code>.
     *
     * @return <code>null</code>
     */

    public String getRealm()
    {
        return null;
    }

    /**
     * Returns textual designation of the NTLM authentication scheme.
     *
     * @return <code>ntlm</code>
     */
    public String getSchemeName()
    {
        return "ntlm";
    }

    /**
     * Tests if the NTLM authentication process has been completed.
     *
     * @return <tt>true</tt> if Basic authorization has been processed,
     *         <tt>false</tt> otherwise.
     */
    public boolean isComplete()
    {
        return authenticationState == AUTHENTICATION_STATE.TYPE3_MSG_GENERATED || authenticationState == AUTHENTICATION_STATE.FAILED;
    }

    /**
     * Returns <tt>true</tt>. NTLM authentication scheme is connection based.
     *
     * @return <tt>true</tt>.
     */
    public boolean isConnectionBased()
    {
        return true;
    }

    /**
     * Processes the NTLM challenge.
     *
     * @param challenge the challenge string
     * @throws MalformedChallengeException is thrown if the authentication challenge is malformed
     */
    public void processChallenge(final String challenge) throws MalformedChallengeException
    {
        String s = AuthChallengeParser.extractScheme(challenge);

        if (!s.equalsIgnoreCase(getSchemeName()))
        {
            throw new MalformedChallengeException("Invalid NTLM challenge: " + challenge);
        }

        int i = challenge.indexOf(' ');

        if (i != -1)
        {
            s = challenge.substring(i, challenge.length());
            receivedNtlmChallenge = s.trim();
            authenticationState = AUTHENTICATION_STATE.TYPE2_MSG_RECEIVED;
        }
        else
        {
            receivedNtlmChallenge = null;
            authenticationState = authenticationState == AUTHENTICATION_STATE.UNINITIATED ? AUTHENTICATION_STATE.INITIATED : AUTHENTICATION_STATE.FAILED;
        }
    }

    private String ntlmMessageToString(NtlmMessage ntlmMessage)
    {
        return "NTLM " + encode(ntlmMessage.toByteArray());
    }
}
TOP

Related Classes of org.mule.transport.http.ntlm.NTLMScheme

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.