0

I have a web application, written in Java, that makes a JAX-WS web service call to an exchange server using Exchange Web Services.

When I compile and run the application using Java 1.6.0_34, it works fine.

If I compile and run it with Java 1.7.0_07, I get the following error:

com.sun.xml.ws.client.ClientTransportException: request requires HTTP authentication: Unauthorized
    at com.sun.xml.ws.transport.http.client.HttpClientTransport.checkResponseCode(HttpClientTransport.java:212)
    at com.sun.xml.ws.transport.http.client.HttpTransportPipe.process(HttpTransportPipe.java:149)
    at com.sun.xml.ws.transport.http.client.HttpTransportPipe.processRequest(HttpTransportPipe.java:86)
    at com.sun.xml.ws.api.pipe.Fiber.__doRun(Fiber.java:595)
    at com.sun.xml.ws.api.pipe.Fiber._doRun(Fiber.java:554)
    at com.sun.xml.ws.api.pipe.Fiber.doRun(Fiber.java:539)
    at com.sun.xml.ws.api.pipe.Fiber.runSync(Fiber.java:436)
    at com.sun.xml.ws.client.Stub.process(Stub.java:248)
    at com.sun.xml.ws.client.sei.SEIStub.doProcess(SEIStub.java:135)
    at com.sun.xml.ws.client.sei.SyncMethodHandler.invoke(SyncMethodHandler.java:109)
    at com.sun.xml.ws.client.sei.SyncMethodHandler.invoke(SyncMethodHandler.java:89)
    at com.sun.xml.ws.client.sei.SEIStub.invoke(SEIStub.java:118)
    at $Proxy62.getUserAvailability(Unknown Source)
    ...

This also occurs if I compile it with 1.6.0_34 and run it with 1.7.0_07.

I looked for changes to JAX-WS between Java 6 and 7, but I only found some notes about possible compile errors.

I'm not sure what to look at next, as obviously the authentication code hasn't been changed, so why is it failing?

Here's the method that I think should be setting up the authentication:

/**
 *  Set up Authentication
 *
 */
protected void setupAuthenticator(){
    if(authenticator == null){
        authenticator = new Authenticator(){
            protected PasswordAuthentication getPasswordAuthentication(){
                String superusername = ExchangeServerPortFactory.this.adDomain
                                + "\\" 
                                + ExchangeServerPortFactory.this.username;
                String superPassword = ExchangeServerPortFactory.this.password;
                return new PasswordAuthentication(superusername
                                         ,superPassword.toCharArray());
            }
        };
        Authenticator.setDefault(authenticator);
    }
}

I tried changing "\\" to "\\\\" because I found a message on a forum somewhere where this solved a similar problem, but it didn't do me any good.

Samuel Edwin Ward
  • 6,526
  • 3
  • 34
  • 62
  • Can you tried generating the client with `wsimport` of JDK 7? – Paul Vargas Nov 06 '12 at 15:50
  • @PaulVargas, unfortunately it does not seem to make any difference. – Samuel Edwin Ward Nov 29 '12 at 17:05
  • You could run the application via a local proxy, so you can intercept the request and response. Maybe there is a firewall rule on user-agent. I think by default JaxWS might mention the JDK version in the http user-agent header. – Hugo Dec 10 '12 at 10:38
  • Just some hints: you could use wireshark to monitor the status of your connection, and see what's happening actually on the wire in these 2 cases. It's a fantastic tool for such troubleshooting analysis. It the SOAP request actually sent on the wire? Are there difference in java 6 and java 7? What does you server answer to your request? Do your remote webservice require authentication? You could also try with another JDK 1.6.XX and see what happen. Recent JDK releases have fixed security holes, it may be that some authentication HTTP headers need to be generated in some other way. – JayZee Dec 10 '12 at 13:26
  • Hi samuel, can you please add the code where you set up the authentication? – F. Mayoral Dec 10 '12 at 14:36
  • Thank you samuel, I assume we are talking about NTLM authentication, are we? – F. Mayoral Dec 10 '12 at 15:07
  • @fer13488, I don't think so. – Samuel Edwin Ward Dec 10 '12 at 15:22

2 Answers2

0

Ok, this is what I got so far, you are calling a exchange service, but you are using a basic authentication method right now, what you need is a NTML authentication, i have no clue why this is working with j6 and not with j7, but i suppose that the client is parsing your request based on a the service's wsdl which may define that it's an exchange service, and maybe j7 have a specific authenticatior for NTML authentication, but again, it's a very long shot and i'm assuming lot's of things.

(All credits to Marcel Levy)

First, create an authenticator:

import java.net.Authenticator;
import java.net.PasswordAuthentication;

public class NtlmAuthenticator extends Authenticator {

  private final String username;
  private final char[] password;

  public NtlmAuthenticator(final String username, final String password) {
    super();
    this.username = new String(username);
    this.password = password.toCharArray(); 
  }

  @Override
  public PasswordAuthentication getPasswordAuthentication() {
    return (new PasswordAuthentication (username, password));
  }
}

In your application, set up the authenticator as the default:

String username = "DOMAIN\\USERNAME";
String password = "PASSWORD"

NtlmAuthenticator authenticator = new NtlmAuthenticator(username, password);
Authenticator.setDefault(authenticator);

You probably tried this, if so, please ignore this answer.

Community
  • 1
  • 1
F. Mayoral
  • 175
  • 1
  • 10
0

It seems to work in 1.7.0u10 or later.

I can only guess that this is because of bug 8003948 which was fixed in that release.

Samuel Edwin Ward
  • 6,526
  • 3
  • 34
  • 62