简体   繁体   中英

Client resource post fails for NTLM authentication. Works for Basic Authentication in apache

I have the following code to make a POST request to the server. However, the web server can be either Apache or IIS.

Client client = new Client(new Context(), Protocol.HTTP);   
ClientResource resource = new ClientResource(url);
resource.setRetryOnError(false);
resource.setNext(client);

resource.setChallengeResponse(ChallengeScheme.HTTP_BASIC,userName,pwd);

response = resource.post(representation);

The following code works for apache but fails for IIS with the following error:

WARNING: Couldn't find any helper support the HTTP_NTLM challenge scheme.
WARNING: Couldn't find any helper support the HTTP_Negotiate challenge scheme.
Exception in thread "main" Unauthorized (401) - The request requires user authentication

Probably the reason is that apache uses basic authentication and IIS uses NTML. The first try was obviously to change the challenge scheme in case of IIS to NTLM as shown below but got the same error (also I have already added the net extension for restlet jar).

 resource.setChallengeResponse(ChallengeScheme.HTTP_NTLM, userName, pwd);

Also, I think there is a way using the Apache http client (NTCredentials) class but I would still like to use the restlet jars to avoid making lots of changes to existing code.

Any suggestions ? Any help would be appreciated. Thanks in advance.

There is no built-in support for NTLM in Restlet. An issue in the Restlet Github repository tackles such aspect: https://github.com/restlet/restlet-framework-java/issues/467 .

I also saw a page in the Restlet documentation regarding NTLM: http://restlet.com/technical-resources/restlet-framework/guide/2.3/core/security/ntml-authentication . But it seems to be a bit outdated especially for the HTTPClient section. Moreover the HTTP client extension is deprecated and will be removed in version 3. The Jetty extension should be used instead.

That said, you could make a try using the support of NTLM available in Java itself. For this, you need to use the default HTTP client of Restlet, the one used when no client connector is provided in the classpath. Here is a sample of use:

final String username = "username";
final String password = "password";
// Create your own authenticator
Authenticator a = new Authenticator() {
    public PasswordAuthentication getPasswordAuthentication() {
        return (new PasswordAuthentication(
                  username, password.toCharArray()));
    }
};
// Sets the default Authenticator
Authenticator.setDefault(a);

ClientResource cr = new ClientResource("http://...");
cr.post(...);

This link could help you to do that: http://examples.javacodegeeks.com/core-java/net/authenticator/access-password-protected-url-with-authenticator/ .

Hope it helps you, Thierry

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM