Skip to main content

Using UsernameToken with SSL

27 replies [Last post]
vladchuk
Offline
Joined: 2006-10-22
Points: 0

I've been trying to use UsernameToken authentication over SSL without much luck. The use case is very simple: the SOAP request should contain a header like this:

some_user
some_password

Is it possible to configure this (that is to set the username and password) programmatically?
Also, how to programmatically extract the credentials on the service side?

Any help with this would be much appreciated.

Reply viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
vladchuk
Offline
Joined: 2006-10-22
Points: 0

I still can't get my hands on the complete source. The CVS location you specified seems to be contain what's in the distribution. For example, the package com.sun.xml.ws.api.message is nowhere to be found.

Any othe places I might look?

kumarjayanti
Offline
Joined: 2003-12-10
Points: 0

Hi,

> I still can't get my hands on the complete source.
> The CVS location you specified seems to be contain
> what's in the distribution. For example, the package
> com.sun.xml.ws.api.message is nowhere to be found.

For this one you will need to checkout the JAXWS workspace.

https://jax-ws-sources.dev.java.net/source/browse/jax-ws-sources/

On the otherhand, if you just checkout WSIT workspace, it would have under the wsit/lib/runtime directory the source code ZIP of all the technologies including JAXWS, look for jaxws-api.src.zip and jaxws-rt.src.zip.

You can actually use Netbeans to debug through the entire sources once you have the WSIT project open in NetBeans and then pointing netbeans to unzipped sources for JAXWS etc.

I wish i could somehow reproduce your problem.... I know our thing works on TOMCAT as well, so i am suspecting somehow that the JAXWS implementation from WebLogic or some other interference is causing the Failure.

Specifically do you have this Annotation in your WebService Client :

@WebServiceRef(wsdlLocation = "https://localhost:8181/SSLWebService/SSLWebServiceService?wsdl")

Thanks.

vladchuk
Offline
Joined: 2006-10-22
Points: 0

For some reason weblogic ignores the @WebServiceRef annotation so I just call the service = new Service(wsdl_url, service_name). Besides, how client gets the WSD L (via http or https) should be irrelevant - what matters is what protocol is used to hit the endpoint.

Thanks to the source code pointers I have made some progress in troubleshooting this nasty problem. It turns out that if a separate (as in a different VM) client is used there is no problem whatsoever. Not so in my case - when the client and server run in the same container. For some reason the Packet.wasTransportSecure is not set for the client, however, since there is no policy for the client the SecurityRecipient.createMessage() is short-circuited and never gets to the check for transport protocol. When ran in the same container the client and server seem to share some parameters (context or some such) so the method does not return early, the security check is made and the infamous exception is thrown.

On the surface it looks like a shortcoming in design, at least I don't know how avoid this situation given that the client and the server share the same container, which is not at all inconceivable. Perhaps this could be rectified somehow. Please let me know.

kumarjayanti
Offline
Joined: 2003-12-10
Points: 0

> For some reason weblogic ignores the @WebServiceRef
> annotation so I just call the service = new
> Service(wsdl_url, service_name). Besides, how
> client gets the WSD L (via http or https) should be
> irrelevant - what matters is what protocol is used to
> hit the endpoint.

That's correct but then check what your WSDL has in it for

and make sure it has "https"

For example when i try to access the service WSDL as http then the soap:address gets rewritten to :

And it is this URL which is used by the Proxy to make the connection. And so my invocation fails with the same error that you are seeing.

>
> On the surface it looks like a shortcoming in design,
> at least I don't know how avoid this situation given
> that the client and the server share the same
> container, which is not at all inconceivable. Perhaps
> this could be rectified somehow. Please let me know.

This is something that i am unable to accept. The Client and Server zip files that i attached to this thread are both servlets (WAR's) and i deployed them to the SAME GlassFish instance and it works perfectly.

Not sure how to help you out....
Thanks.

vladchuk
Offline
Joined: 2006-10-22
Points: 0

Well, I thought the problem was that both the client and the server were deployed as part of the same webapp so I separated them. Still no dice - I think Weblogic just doesn't like Metro...

Message was edited by: vladchuk

kaumar
Offline
Joined: 2007-09-18
Points: 0

Now that I've tried this using a web app I run into the same problem (WSS1601).
However what is puzzling to me is that the service sends an OK response (HTTP 200). The exception seems to occur after that.

Here is the stack trace:
25.9.2007 10:31:53 com.sun.xml.ws.security.opt.impl.incoming.SecurityRecipient createMessage
SEVERE: WSS1601: Security Requirements not met - Transport binding configured in policy but incoming message was not SSL enabled
25.9.2007 10:31:53 com.sun.xml.wss.jaxws.impl.SecurityClientPipe process
SEVERE: WSSPIPE0025: Error in Verifying Security in the Inbound Message.com.sun.xml.wss.XWSSecurityException: WSS1601: Security Requirements not met - Transport binding configured in policy but incoming message was not SSL enabled
at com.sun.xml.ws.security.opt.impl.incoming.SecurityRecipient.createMessage(SecurityRecipient.java:806)
at com.sun.xml.ws.security.opt.impl.incoming.SecurityRecipient.validateMessage(SecurityRecipient.java:226)
at com.sun.xml.wss.jaxws.impl.SecurityPipeBase.verifyInboundMessage(SecurityPipeBase.java:423)
at com.sun.xml.wss.jaxws.impl.SecurityClientPipe.process(SecurityClientPipe.java:233)
at com.sun.xml.ws.api.pipe.helper.PipeAdapter.processRequest(PipeAdapter.java:115)
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:134)
at com.sun.xml.ws.client.sei.SyncMethodHandler.invoke(SyncMethodHandler.java:244)
at com.sun.xml.ws.client.sei.SyncMethodHandler.invoke(SyncMethodHandler.java:224)
at com.sun.xml.ws.client.sei.SEIStub.invoke(SEIStub.java:117)
at $Proxy347.getFile(Unknown Source)
at fi.op.ws.web.TestServlet.getFile(Unknown Source)
at fi.op.ws.web.TestServlet.doGet(Unknown Source)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:707)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:820)
at weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run(StubSecurityHelper.java:226)
at weblogic.servlet.internal.StubSecurityHelper.invokeServlet(StubSecurityHelper.java:124)
at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:283)
at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:175)
at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.run(WebAppServletContext.java:3370)
at weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:321)
at weblogic.security.service.SecurityManager.runAs(Unknown Source)
at weblogic.servlet.internal.WebAppServletContext.securedExecute(WebAppServletContext.java:2117)
at weblogic.servlet.internal.WebAppServletContext.execute(WebAppServletContext.java:2023)
at weblogic.servlet.internal.ServletRequestImpl.run(ServletRequestImpl.java:1359)
at weblogic.work.ExecuteThread.execute(ExecuteThread.java:200)
at weblogic.work.ExecuteThread.run(ExecuteThread.java:172)
Exception: javax.xml.ws.WebServiceException: WSSPIPE0025: Error in Verifying Security in the Inbound Message.

regards
Martti

kumarjayanti
Offline
Joined: 2003-12-10
Points: 0

Did you use WebLogic as well in your test ?.

Thanks

kaumar
Offline
Joined: 2007-09-18
Points: 0

Yes, I'm using Weblogic 10. Symmetric Binding using UsernameToken works fine. It is only SSL with UsernameToken that fails.

Btw, if I only define the TransportBinding-policy at binding-level and not any operation-level policies, the web service responds OK (but WSS1601 still appears).

regards
Martti

kumarjayanti
Offline
Joined: 2003-12-10
Points: 0

Hi,

Thanks for the full stack-trace, all the while i was thinking this error was being thrown on the Server Side, but now i see that the server side is probably ok and it appears Packet.wasTransportSecure() is not being set on the Client side for an SSL scenario when running on WebLogic. (not sure if vladchuk's issue was exactly the same or whether he was seeing an issue on server side as well)

Let me ask our JAXWS experts and get back.

Thanks

vladchuk
Offline
Joined: 2006-10-22
Points: 0

This is exactly the error I see. Perhaps I could have been more explicit, including supplying the stack trace, but I'm pretty sure I mentioned before that the server side was OK - it's the client that's reported as not using SSL for some reason.

Good to know I'm not the only one!

kumarjayanti
Offline
Joined: 2003-12-10
Points: 0

Hi,

Packet.wasTransportSecure() on the Client Side will be set to true by the following peice of code in JAXWS (HttpClientTransport.java)

http://fisheye5.cenqua.com/browse/jax-ws-sources/jaxws-ri/rt/src/com/sun...

293 if (httpConnection instanceof HttpsURLConnection) {
294 https = true;
295 }

370 public boolean isSecure() {
371 return https;
372 }

Since you have the code with you now and i believe you are able to debug through it, can you please put a breakpoint in this and see if this "https" is getting set to true . That will be a great help for us.

Thanks.

vladchuk
Offline
Joined: 2006-10-22
Points: 0

I think we are getting close. The https flag is not getting set because... the connection is of type SOAPHttpsURLConnection (weblogic's) which extends HttpURLConnection but doesn't extend HttpsURLConnection, so the instanceof check fails.

I have no idea how to get rid of the weblogic's stuff. They really don't want you using anything but weblogic. I tried setting java.protocol.handler.pkgs = sun.net.www.protocol - no good. Ideas welcome...

kumarjayanti
Offline
Joined: 2003-12-10
Points: 0

Hi,

So this is good to know, atleast you found the root cause. I will ask our JAXWS folks to see if they can fix this code in JAXWS.

Thanks.

raveechin
Offline
Joined: 2009-10-20
Points: 0

Kumar,

I am facing the "WSS1601: Security Requirements not met - Transport binding configured in policy but incoming message was not SSL enabled" on Glassfish V2.

Here is the server-side policy:






classname="edmc.soa.security.UsernameAuthenticationHandler"/>




























sp:IncludeToken="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy/IncludeToken/AlwaysToRecipient">








































It does not matter if I use http or https on the client side, the error prevails.

Your help will be deeply appreciated.

kumarjayanti
Offline
Joined: 2003-12-10
Points: 0

Hi,

I looked at your client and server policy. Did you write those policies by hand ?. The reason i am asking is because your client side policy seems to be a complete copy of the server side policy minus the server side Validator and plus the client side CallbackHandler.

In reality the client side config only needs to have the CallbackHandler config.

See attached client (NewWebServiceService.xml ) and server ( wsit-test.NewWebService.xml ) files generated by NetBeans for a particular service.

I don't think this is the cause of the failure you are seeing though...

How do we proceed from here, we need to be able to reproduce the issue at our end in order to be able to fix any real issue here.

Thanks.

kumarjayanti
Offline
Joined: 2003-12-10
Points: 0

Hi,

Actually can you do the following experiment.

1. Remove the TransportSecurity Policies and the UsernameToken from the WSDL
2. Run you App using SSL again
3. In your Service Endpoint (method being invoked) can you try and access
HttpServletRequest.getScheme() and see if it returns "https"

For eg, i just tried the following code in a sample webservice and it shows the scheme as http when i run it without SSL.

@Resource WebServiceContext wsContext;
/**
* Web service operation
*/
@WebMethod
public String operation(@WebParam(name = "arg") String arg) {
// TODO implement operation
System.out.println("Hello " + arg);
HttpServletRequest req = (HttpServletRequest) wsContext.getMessageContext().get(wsContext.getMessageContext().SERVLET_REQUEST);
System.out.println("Scheme=======" + req.getScheme());

}

This will help us determine where the problem is...

Thanks.

vladchuk
Offline
Joined: 2006-10-22
Points: 0

Indeed, I duplicated the client and service configuration - just didn't know better.

I ran the test you requested and got the following: if client uses http - http is confirmed in the service, if https is used by client then https is confirmed in the service. No surprises here.

Please let me know - this is a show stopper for us.

kumarjayanti
Offline
Joined: 2003-12-10
Points: 0

Hi,

> I ran the test you requested and got the following:
> if client uses http - http is confirmed in the
> service, if https is used by client then https is
> confirmed in the service. No surprises here.

If this is indeed happening then i see no reason for the failure in Policy Verification. Because all our SSL based tests would have similarly failed then...

Can you please do one more help. Use the latest WSIT nightly and try to run the same scenario on GF V2.

Just thinking loud, has it got to do with classpath issues that you mention in the other thread.

Thanks.

vladchuk
Offline
Joined: 2006-10-22
Points: 0

I'm afraid that would be a pretty big deal - to install, configure and run this on Glassfish. Besides, if it works on Glassfish that wouldn't do us any good since we need to run this on Weblogic. Don't you guys know already that this works on Glassfish? By the way, I am now using v.1.0 FCS and getting the same results.

Also, it would help if I had the complete source for Metro - do you know where I could get that? The source available for download seems deficient - it doesn't contain all the classes (for example the Packet).

kumarjayanti
Offline
Joined: 2003-12-10
Points: 0

> I'm afraid that would be a pretty big deal - to
> install, configure and run this on Glassfish.
> Besides, if it works on Glassfish that wouldn't do us
> any good since we need to run this on Weblogic. Don't
> you guys know already that this works on Glassfish?

Yes we have a whole bunch of tests that are working. by asking you to test on GF i just wanted to be sure that it is not a problem with your classpaths etc on WebLogic Server.

> By the way, I am now using v.1.0 FCS and getting the
> same results.
>
> Also, it would help if I had the complete source for
> Metro - do you know where I could get that? The
> source available for download seems deficient - it
> doesn't contain all the classes (for example the
> Packet).

If you set up a CVS client you can checkout the entire source using

cvs -d:pserver:@cvs.dev.java.net:/cvs co wsit

Let me run your scenario again on GF today so i am doubly sure we do not have a problem on Metro. But i can only try and run on GF and tell you what was the result. I will use the exact same policy as yours.

Thanks.

kumarjayanti
Offline
Joined: 2003-12-10
Points: 0

Hi,

I just tried what you were trying using Glassgfish today. I used the latest nightly of WSIT (not the Metro FCS). And it works perfectly fine. I do not have any doubt that Metro FCS will also work.

Do you have the following annotation on your client code :

@WebServiceRef(wsdlLocation = "https://localhost:8181/SSLWebService/SSLWebServiceService?wsdl")

i.e a WebServiceRef with "https" URL as above. This is required for the client to actually make a https request.

Attached are the cleaned netbeans projects for the client and server that do exactly what you are looking for.

And here are the request and response :

-----------------------------------------------------------
---[HTTP request]---
SOAPAction: "http://test/SSLWebService/operationRequest"
Accept: text/xml, multipart/related, text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2
Content-Type: text/xml;charset="utf-8"
https://localhost:8181/SSLWebService/SSLWebServiceServicehttp://test/SSLWebService/operationRequest

http://www.w3.org/2005/08/addressing/anonymous

uuid:7b4bf2fa-9804-401e-bd70-54fe366469bc2007-09-20T11:51:21Z2007-09-20T11:56:21ZwsitwsitWORLD
--------------------
Hello WORLD
Scheme=======https
---[HTTP response 200]---
Transfer-encoding: chunked
null: HTTP/1.1 200 OK
Content-type: text/xml;charset="utf-8"
Server: Sun Java System Application Server 9.1
X-powered-by: Servlet/2.5
Date: Thu, 20 Sep 2007 11:51:21 GMT
http://www.w3.org/2005/08/addressing/anonymoushttp://test/SSLWebService/operationResponseuuid:d064a60b-ace7-4746-a13b-09cc31aa074d2007-09-20T11:51:21Z2007-09-20T11:56:21ZHello WORLD
--------------------

-----------------------------------------------

The WSDL of the Service is :
---------------------------------------------





























































































---------------------------------------------

Sorry for the Long Post, but i have no other way since i do not have WebLogic installed.

Thanks.

vladchuk
Offline
Joined: 2006-10-22
Points: 0

I think I figured out how to configure this on the client. Now the server is the problem. Curiously, if authentication doesn't succeed I get the error to that effect, but if it does I get this:

WSS1601: Security Requirements not met - Transport binding configured in policy but incoming message was not SSL enabled

The client is accessing the service on the https protocol. Am I missing something else? Isn't using the https on the client side sufficient for the transport to use SSL?
FYI, I am running this on Weblogic 10 - both the client and service are part of the web application.

Please share if you know the answer to this puzzle.

kumarjayanti
Offline
Joined: 2003-12-10
Points: 0

Have you figured out how to set the username-password programmatically.

You can set BindingProvider.USERNAME_PROPERTY and BindingProvider.PASSWORD_PROPERTY on the RequestContext() of the Client Stub (BindingProvider) then the Username and Password are picked up from the value of those properties.

Alternately you can provide a CallbackHandler that handles the JAAS NameCallback and PasswordCallback.

For accessing the credentials on the Server side you can do the following :

@WebService
public class YourWebService {

@Resource WebServiceContext context;

public String sayHello(String arg) {
try {
System.out.println("\nRequester Subject " +
com.sun.xml.wss.SubjectAccessor.getRequesterSubject(context));
} catch (Exception e) {
throw new RuntimeException(e);
}

}
}

The Subject would have the information.

For the Problem that you are seeing :

WSS1601: Security Requirements not met - Transport binding configured in policy but incoming message was not SSL enabled

The WSIT/Metro Security implementation tries to verify if the message actually arrived on Secure transport as part of Policy Verification. This check seems to be working on GlassFish and Tomcat, but somehow for WebLogic in your case this seems to have a problem.

Here is what we check for :

There is a Flag on the JAXWS Packet called :

/**
* True if this message came from a transport (IOW inbound),
* and in paricular from a "secure" transport. A transport
* needs to set this flag appropriately.
*
*

* This is a requirement from the security team.
*/
// TODO: expose this as a property
public boolean wasTransportSecure;

http://fisheye5.cenqua.com/browse/~raw,r=MAIN/jax-ws-sources/jaxws-ri/rt...

And it appears this flag is somehow not set to true in your case.

Can you please provide some more details of your setup. Mean time, I will try to send an email to our JAXWS experts to respond to this.

Thanks.

vladchuk
Offline
Joined: 2006-10-22
Points: 0

Attached please find my policies for the client and the server. Currently, the client policy is a part of the wsit-client.xml (which is on the classpath) and server policy is part of the wsdl that lives in the web-inf/wsdl. By the way, is is the correct way to configure it?

As I mentioned earlier, both client and server are part of the same web application deployed to same instance of Weblogic 10. Client is invoked via a JSP page. Everything works fine: the client is sending the UsernameToken, the server is validating the credentials in the usernameValidatior but if this validation succeeds I then get the error about incoming message not being SSL.

Please let me know if you need any more information and I would really appreciate a prompt resolution to this, if possible. Thanks.

jitu
Offline
Joined: 2003-06-14
Points: 0

Packet.wasTransportSecure is set when the connection is HttpsURLConnection on the client side. On the server, it is set when HttpServletRequest.getScheme() is "https"

vladchuk
Offline
Joined: 2006-10-22
Points: 0

So, how does this translate to the real world - what must one do to ensure that these conditions are met? If client is accessing the endpoint via "https" that should be sufficient, right? Or is there some other configuration that needs to take place at the client/server?

kumarjayanti
Offline
Joined: 2003-12-10
Points: 0

> So, how does this translate to the real world - what
> must one do to ensure that these conditions are met?
> If client is accessing the endpoint via "https" that
> should be sufficient, right?

Yes it should be sufficient, but it appears there is some issue when you are running on WebLogic. Some incompatibility that we need to debug and find out. Have you tried the same scenario on GlassFish (just to see if it works there).

Do you have WSIT Milestone 6 or later builds or are you using some older builds.

Thanks.