Pages

Thursday, April 23, 2009

JAX-WS web service proxy client and HTTP authentication

In a project I need to set the HTTP authentication on a JAX-WS proxy client. So let's do it. We only have to set the username and password on the bindingprovider.

@WebServiceRef()
private static TEST_ORDER_INTERACTION tEST_ORDER_INTERACTION;

public static void main(String [] args) throws MalformedURLException {
tEST_ORDER_INTERACTION = new TEST_ORDER_INTERACTION();

Test_order_interactionPortType port = tEST_ORDER_INTERACTION.getTest_order_interactionPort();
((BindingProvider) test_order_interactionPortType).getRequestContext().put(BindingProvider.USERNAME_PROPERTY,"ac-erpweb01\\oracle");
((BindingProvider) test_order_interactionPortType).getRequestContext().put(BindingProvider.PASSWORD_PROPERTY,"test");


Too bad this was not working for me. The Web Service, I called uses NTLM authentication ( Microsoft ). So we need to use our own Authenticator. Just create an Authenticator case.

package test.client;

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

public class MyAuthenticator extends Authenticator {

private String user;
private String password;

public MyAuthenticator(String user,String password) {
this.user = user;
this.password = password;
}


@Override
protected PasswordAuthentication getPasswordAuthentication() {
PasswordAuthentication auth = new PasswordAuthentication(user,password.toCharArray());
return auth;
}
}

Use this authenticator

@WebServiceRef()
private static TEST_ORDER_INTERACTION tEST_ORDER_INTERACTION;

public static void main(String [] args) throws MalformedURLException {
tEST_ORDER_INTERACTION = new TEST_ORDER_INTERACTION();

Test_order_interactionPortType port = tEST_ORDER_INTERACTION.getTest_order_interactionPort();

MyAuthenticator myAuth = new MyAuthenticator("ac-erpweb01\\oracle","test");
Authenticator.setDefault(myAuth);

Now we have set the HTTP authentication, we can not use the HTTP analyzer of JDeveloper anymore to see the soap messages. To see the soap request and response we can set a JAX-WS parameter. -Dcom.sun.xml.ws.transport.http.client.HttpTransportPipe.dump=true ,this will dump the data in your console output.

27 comments:

  1. Hi Edwin,

    We have generated web service proxy based on a wsld file for a web service secured with NTLM authentication. Running the code that connects to the web service from a java class main method as you described here works fine, but when running the same code from a web application deployed on weblogic server (we have tried both integrated and standalone) we get the following error: com.sun.xml.ws.client.ClientTransportException: The server sent HTTP status code 401: Unauthorized.
    Is there another approach for web applications deployed in weblogic?

    Best regards,
    Delia

    ReplyDelete
  2. Hi Delia,

    I didn't test this on a j2ee server but i read something you cant use this with the standard security of weblogic. Maybe you can disable the standard security.

    Does your webapp already have authentication. and what if you configure this for ntlm and remove the authenticator. like described in this blog

    http://fusionsecurity.blogspot.com/2010/02/kerberos-and-weblogic-server-on-windows.html

    thanks

    ReplyDelete
  3. Hi Edwin,
    I'm applying WS policy to the BPEL Process "oracle/wss_http_token_service_policy".
    While testing through EM its working fine.
    But now i want to call the same BPEL process [with WS policy configured to it] using a proxy.
    I've created a client for this BPEL process using Eclipse.

    Q1: Now i don't know where shall i set the User-id & Password for the above policy. [i.e. WSS Username in EM].

    Q2: I've tried sending user-id password through methods
    stub.setUsername("weblogic");
    stub.setPassword("weblogic1");
    Where in SOA the matching credentials are set for the same?

    Q3: If u can provide me with a sample code for the above would be gr8.

    Regards,
    Rupesh

    ReplyDelete
  4. Hi,

    can you read this http://biemond.blogspot.com/2010/08/things-you-need-to-do-for-owsm-11g.html

    The only thing you need to do for these policies is to add some Users to the myrealm Security Realm in the WebLogic Console.

    # Map reqContext = ((BindingProvider) request_Response_ptt).getRequestContext();
    # reqContext.put(BindingProvider.USERNAME_PROPERTY, "test" );
    # reqContext.put(BindingProvider.PASSWORD_PROPERTY, "weblogic1" );

    hope this helps

    ReplyDelete
  5. Edwin
    Thanks for the reply ...

    Actually the issue was with the PROXY CREATION method i was using.

    While creating PROXY, i had copied the .WSDL & .XSD file inside Webcontent/WEB-INF folder.

    When i kept the same file outside WEB-INF i.e. in Webcontent folder & created the proxy, everything went fine.

    Now when i am trying to set user-id , password through java it's working fine.

    Regards,
    Rupesh

    ReplyDelete
  6. Dear Edwin,
    I have one more doubt not related to this post but some thing else.

    I want to know, how to implement WSIF/Java binding in SOA 11G?

    I am able to create and test the webservice by invoking it through partnerlink using SOAP binding. But m not able to achive the same using JAVA binding.

    Kindly guide me with the steps to achive the same.

    Regards,
    Rupesh ...

    ReplyDelete
  7. Hi,

    Can you give more info about the process after the java binding. And why dont you use the Spring component , that will work.

    thanks

    ReplyDelete
  8. Just like Delia, we've had to create a Java 6 app that accesses a NTLM secured web page (not web service) because Oracle Service Bus does not support NTLM.

    The Java app runs perfectly from the Unix commandline (on the same host as the OSB), but when the Java app is deployed to the OSB and invoked from a proxy service, we also get:

    HTTP status code 401: Unauthorized

    Help!

    ReplyDelete
  9. Edwin,

    We are experiencing exactly the same issue as Delia.

    We have our OSB installed on a Unix host. Our Java app executed from the Unix cmdline connects to the NTLM-secured web service just fine, but when the JAR fiel is deployed to the OSB and invoked by a proxy service it fails with the 401: Unauthorized HTTP status code.

    Why is this and how can we overcome it?

    ReplyDelete
  10. Hi,

    on a j2ee server you should do the following, make a passthrough servlet which does the ntlm authentication.

    download jcifs http://jcifs.samba.org/

    Download the apache httpcomponents http://hc.apache.org/
    in this 4.03 release zip there is a txt file NTLM_SUPPORT.txt follow these steps.

    in this file they explain, how to do this.

    and set this httpclient.getParams().setParameter(CoreProtocolPNames.USE_EXPECT_CONTINUE, Boolean.FALSE);

    thanks

    ReplyDelete
  11. Edwin,
    I actually found a resolution to my problem! In my code I replaced:

    HttpURLConnection http = (HttpURLConnection) new URL(myUrk).openConnection();

    with:

    URL url = new URL(null, myUrl, new sun.net.www.protocol.http.Handler());
    HttpURLConnection http = (HttpURLConnection) url.openConnection();

    This forces the Weblogic container to use the Sun HTTP handler, not the WLS handler.

    Works a treat.

    ReplyDelete
  12. Hi,

    Well done, that is good news and then this blogpost code should work in the weblogic j2ee server.

    thanks

    ReplyDelete
  13. set -DUseSunHttpHandler=true as java option and webservice proxy with NTLM will work.

    ReplyDelete
    Replies
    1. fantastic! tks! previous solutions did not work at all!

      Delete
  14. Thanks by setting -DUseSunHttpHandler=true My SOA composite having spring component is able to get a URL resource on a different server.However, will it have any impact on other application deployed on the same server?

    Thanks,
    Srini

    ReplyDelete
    Replies
    1. Hi,

      Don't know but this can have some side effects.

      thanks

      Delete
    2. Yes it does, it disables the 2 way SSL implemented in weblogic http handler : from what I have seen, weblogic does not send anymore its private key when negotiating a 2 way SSL connection.

      Guillaume

      Delete
    3. Yes it does, it disables the 2 way SSL implemented in weblogic http handler : from what I have seen, weblogic does not send anymore its private key when negotiating a 2 way SSL connection.

      Guillaume

      Delete
    4. Maybe, these options will help:

      -Dssl.SocketFactory.provider=sun.security.ssl.SSLSocketFactoryImpl -Dssl.ServerSocketFactory.provider=sun.security.ssl.SSLSocketFactoryImpl

      Delete
  15. Hi Edwin, I need to do this, but with JAX-RPC, any idea ??

    ReplyDelete
    Replies
    1. Hi,

      Did you read this http://www.coderanch.com/t/430008/Web-Services/java/Setting-WEb-services-credentials maybe it helps.

      thanks

      Delete
  16. Hello,
    I want to call the web-service's operation through a proxy.
    My client at this point can invoke all operation but NOT when I upload my client on the server because a proxy is needed.
    I have tried
    1. ProxySelector
    2. System.setPropertY(name,value)
    3. Using a bindingProvider and putting "http.proxyHost" and "http.proxyPort" properties.

    These solutions don't work (3) or are system-wide and i don't want them.
    Is there another solution?
    Kind regards,
    Dimitris

    ReplyDelete
    Replies
    1. Hi,

      Indeed it looks like you can only do it system wide but is there no exclude url property. Maybe you can use a decompiler and look at the fabric jars.

      and can you use the normal java proxy parameters, and set the noProxyHosts
      java -Dhttp.proxyHost=webcache.mydomain.com -Dhttp.proxyPort=8080 -Dhttp.noProxyHosts=”localhost|host.mydomain.com”

      thanks

      Delete
  17. It works! Simple and clean

    Thanks,

    Luis

    ReplyDelete
  18. Any idea on how to make this work on Websphere ? We are facing 401 authentication issue

    ReplyDelete
  19. Hi Edwin,
    How can we add application level authentication for a xml over http in OSB?

    Thanks in advance..

    ReplyDelete