Skip to main content

How to programmatically set STS username/password credentials?

41 replies [Last post]
amason
Offline
Joined: 2007-02-26

Hi:

How does one go about setting programmatically (as would be highly desirable in unit tests) the username/password creds for an STS. We are using an STS IssuedToken for our target web services and supporting java and .net clients. I've gotten things to work with wsit-client.xml and import of STS and target web service client WSDL usin predefined STS configuration but i can't seem to figure out how to use programmatic creds this way.

I would like to be able to use something like the following but I suspect the problem is that this port is not the right port. It should be the STS port which a typical client program doesn't reference.
((BindingProvider)port).getRequestContext().put(BindingProvider.USERNAME_PROPERTY, username); ((BindingProvider)port).getRequestContext().put(BindingProvider.PASSWORD_PROPERTY, password);

Any advice?

Thanks, Alex

Reply viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
amason
Offline
Joined: 2007-02-26

Hi:

I think this issue is resolved. I downloaded Metro nightly build and the fix seems to work fine. Thanks, very much.

Alex

amason
Offline
Joined: 2007-02-26

This seems like a security issue. Why put the username/password in HTTP header if not really needed? This security is much weaker than the STS, isn't it.

amason
Offline
Joined: 2007-02-26

I have figured out how to make WebLogic ignore BASIC AUTH creds but I must again say that for security (as well as performance) reasons the credentials should not be placed in HTTP header IMHO at least in this case where I am trying to use a STS for authentication.

The setting is quite general in WebLogic and I am not sure I'd place in production
http://e-docs.bea.com/wls/docs92/wlsmbeanref/mbeans/SecurityConfiguratio...

kumarjayanti
Offline
Joined: 2003-12-10

Hi,

The problem is coming because

1. We are using Properties which were not originally meant to convey Message Security C redentials.
2. At the same time we did not want to invent another set of Properties to convey the Message Security Credentials (instead just decided to use what was in the standard).

I have forwarded this thread to our JAXWS folks to see what can be done. But i guess the issue is that the JAXWS Client would not know whether or not the Server requires BASIC AUTH and hence it has to send those PROPS whenever the client has them set.

So any solution for this would probably be a Property which would prevent those credentials to be sent in HTTP Authorization header.

Thanks.

amason
Offline
Joined: 2007-02-26

I would agree with the property. Perhaps another BindingProvider property like HTTP_BASIC_AUTH_PROPERTY? It could default to "true" and be checked in the HTTP client code.

So, perhaps I would use something like the following?

((BindingProvider)port).getRequestContext().put(BindingProvider.USERNAME_PROPERTY, userName)
((BindingProvider)port).getRequestContext().put(BindingProvider.PASSWORD_PROPERTY, password)
((BindingProvider)port).getRequestContext().put(BindingProvider.HTTP_BASIC_AUTH_PROPERTY, "false")

Let me know what you decide. The propagation of the credentials to STS works great but would like this gap closed if possible.

amason
Offline
Joined: 2007-02-26

Please advise as to whether a property will be added which allows me to disable unwanted HTTP authentication when programmatically setting STS credentials from a Java client.

Thanks!

amason
Offline
Joined: 2007-02-26

Hi:

Any news on this last request about being able to disable HTTP Basic authentication when using programmatic creds with an STS?

Thanks, Alex

kumarjayanti
Offline
Joined: 2003-12-10

It appears the query got lost during vacation.

I have resent your question to our JAXWS Experts on this.

Thanks.

kumarjayanti
Offline
Joined: 2003-12-10

Here is what our JAWX Folks replied...

---------------------
We cannot explain the following programming model from JAX-WS perspective.

((BindingProvider)port).getRequestContext().put(BindingProvider.USERNAME_PROPERTY, userName)
((BindingProvider)port).getRequestContext().put(BindingProvider.PASSWORD_PROPERTY, password)
((BindingProvider)port).getRequestContext().put(BindingProvider.HTTP_BASIC_AUTH_PROPERTY, "false")
----------------------

This means we would have to deprecate the use of these standard USERNAME and PASSWORD properties and instead define two new Username and Password Properties for use with WS-Security.

It appears the standard properties are specifically for BASIC AUTH and it seems
For HTTP basic auth, all requests should contain "Authorization" header.

Will let you know once we make the change.

Thanks.

amason
Offline
Joined: 2007-02-26

OK. That's fine w/ me too. Probably for the best in the end since unexpected side effects like this (sending username/password in HTTP Basic auth) may not get caught via testing.

I await your change eagerly.

Thanks much!

kumarjayanti
Offline
Joined: 2003-12-10

> I await your change eagerly.
Will try to do it ASAP.

kumarjayanti
Offline
Joined: 2003-12-10

With Latest WSIT Nightly : https://jax-ws.dev.java.net/servlets/ProjectDocumentList?folderID=5472&e...

import com.sun.xml.wss.XWSSConstants;

((BindingProvider)port).getRequestContext().put(XWSSConstants.USERNAME_PROPERTY, username); ((BindingProvider)port).getRequestContext().put(XWSSConstants.PASSWORD_PROPERTY, password);

If you try it out let me know if it worked.

amason
Offline
Joined: 2007-02-26

I have downloaded and changed my code to use the two new properties but can't quite figure out what is the right callback configuration. Do you have an example? I wasn't running with any callback configuration with the previous fix.

kumarjayanti
Offline
Joined: 2003-12-10

There is NO callback configuration involved since we are talking about Programmatic Username a and Password.

Make sure you have a Policy which requires username-password and then in your code replace BindingProvider.USERNAME_PROPERTY by XWSSConstants.USERNAME_PROPERTY and same for PASSWORD_PROPERTY.

The Application should work if the password was correct and you should see a fault if you set the wrong password.

amason
Offline
Joined: 2007-02-26

I am using a preconfigured STS configuration with username/password. All of my confoguration was working fine with the previous fix (no callback handler). I updated to this nightly and then swapped out the HTTP programmatic constants for the XWSS constants and it seems like now it wants a callback configuration.

kumarjayanti
Offline
Joined: 2003-12-10

I am yet to write a test for this feature. Just sent a headsup to you to see if it works already. Will check and get back.

kumarjayanti
Offline
Joined: 2003-12-10

When i made the fix i missed out propagating the changep to STS Authentication. We have fixed the issue, you may try tomorrows nightly and let us know.

Thanks.

amason
Offline
Joined: 2007-02-26

So the last WSIT nightly I see is Feb 20, 2008, but your reply was Feb 24th. Is the Metro nightly now the nightly I need to be looking at?

What's the difference between the two? I was consuming the WSIT nightly since we need several fixes quickly.

Thanks, Alex

shyam_rao
Offline
Joined: 2006-05-05

> Yes, have that part down just fine and that's what I
> was expecting but what configuration needs to done in
> the wsit-client.xml?
>

You need to remove "CallbackHandlerConfiguration" element for username/password from client configuration for STS.

Search for this string "What is the algorithm used by WSIT runtime to Gather the Username and Password ?" in this article https://xwss.dev.java.net/articles/security_config.html#What_Are_Callbac...
to know the order in which WSIT Runtime looks for the username and password.

> Right now, it really appears like I either have to
> specify a default username and password in the file
> (whoch do not appear to be overridable)

You will get the answer for this from the article mentioned above.

If you are using NetBeans, then right click on "Web Service References" node for sts in client project -> select Edit webservices attribute -> select WSIT configuration tab -> expand Username Authentication and remove the value from default username/passward field.

This will remove the CallbackHandlerConfiguration element from client configuration file for STS.

Message was edited by: shyam_rao

amason
Offline
Joined: 2007-02-26

OK. Thanks. I got it working with valid credentials and realized I must have been picking up an old config file.

Now I am testing with invalid credentials which are validated by STS and notice a different exception when providing bad credentials via programmatic or via callback configuration. Is this intended? I would have expected similar behavior and prefer the SOAP Fault exception.

Programmatic bad creds exception. Stack trace partially truncated.

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.wss.jaxws.impl.SecurityClientPipe.process(SecurityClientPipe.java:208)
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)

Callback Configuration bad creds exception. Stack trace partially truncated.

javax.xml.ws.soap.SOAPFaultException: com.sun.xml.wss.XWSSecurityException: javax.security.auth.login.LoginException: java.lang.SecurityException: The username or password is not valid. Login information is case-sensitive. SS0029
at com.sun.xml.ws.fault.SOAP11Fault.getProtocolException(SOAP11Fault.java:188)
at com.sun.xml.ws.fault.SOAPFaultBuilder.createException(SOAPFaultBuilder.java:108)
at com.sun.xml.ws.client.dispatch.DispatchImpl.doInvoke(DispatchImpl.java:187)
at com.sun.xml.ws.client.dispatch.DispatchImpl.invoke(DispatchImpl.java:206)
at com.sun.xml.ws.security.trust.impl.TrustPluginImpl.invokeRST(TrustPluginImpl.java:488)
at com.sun.xml.ws.security.trust.impl.TrustPluginImpl.process(TrustPluginImpl.java:187)
at com.sun.xml.ws.security.trust.impl.client.STSIssuedTokenProviderImpl.issue(STSIssuedTokenProviderImpl.java:53)
at com.sun.xml.ws.api.security.trust.client.IssuedTokenManager.getIssuedToken(IssuedTokenManager.java:81)
at com.sun.xml.wss.jaxws.impl.SecurityClientPipe.invokeTrustPlugin(SecurityClientPipe.java:420)
at com.sun.xml.wss.jaxws.impl.SecurityClientPipe.process(SecurityClientPipe.java:169)
at com.sun.xml.ws.api.pipe.helper.PipeAdapter.processRequest(PipeAdapter.java:115)

amason
Offline
Joined: 2007-02-26

OK. I think I've got some more information.

The programmatic credentials fix appears to have the side effect of doing HTTP authentication as well as STS authentication. When I put in bad creds an error is actually coming back from HTTP authentication which is called prior to STS realm authentication. Any way to avoid this? I really don't want two sets of authentication here. THe STS authentication is sufficient for these web service requests. I have proven this double authentication by using a debugger and valid credentials and, sure enough, my JAAS Login Module gets called from two quite different places, one which looks like HTTP authentication and another which looks like the expected STS Realm Authentication.

Alex

kumarjayanti
Offline
Joined: 2003-12-10

Just setting the BindingProvider Properties does not enable BASIC AUTH.

HTTP Basic Authentication is enabled only if you have the following in your web.xml :


BASIC
....

So do you have this entry in your web.xml ?

kumarjayanti
Offline
Joined: 2003-12-10

I did some more digging and found that :
The JAXWS client pre-emptively sends the authentication header when the Properties are set. Here is the method which gets called in JAXWS HTTPClientTransport..

private void writeBasicAuthAsNeeded(Packet context, Map> reqHeaders) {
String user = (String) context.invocationProperties.get(BindingProvider.USERNAME_PROPERTY);
if (user != null) {
String pw = (String) context.invocationProperties.get(BindingProvider.PASSWORD_PROPERTY);
if (pw != null) {
StringBuffer buf = new StringBuffer(user);
buf.append(":");
buf.append(pw);
String creds = printBase64Binary(buf.toString().getBytes());
reqHeaders.put("Authorization", Collections.singletonList("Basic "+creds));
}
}
}

So i believe ON WebLogic Server your STS is somehow trying to do BASIC AUTH.

Here is how one can enable BASIC AUTH with JAXWS on GlassFish :
http://docs.sun.com/app/docs/doc/819-3669/6n5sg7cgd?a=view

Thanks.

shyam_rao
Offline
Joined: 2006-05-05

> i believe ON WebLogic Server your STS is somehow
> trying to do BASIC AUTH.
>
>
> Here is how one can enable BASIC AUTH with JAXWS on
> GlassFish :
> http://docs.sun.com/app/docs/doc/819-3669/6n5sg7cgd?a=
> view

I failed to reproduce your problem. I enforced Basic Authentication in the way its mentioned in the above link(changed web.xml and sun-web.xml). I see only soap fault, when i set wrong username/password in BindingProvider.

Without enforcing Basic Authentication also, i don't see any issue here.

Don't know, how WebLogic process/enforce BASIC AUTH ?
And why does weblogic process the HTTP Basic AUTH, if it is not enabled for STS ?

shyam_rao
Offline
Joined: 2006-05-05

> Yes, have that part down just fine and that's what I
> was expecting but what configuration needs to done in
> the wsit-client.xml?
>
> Right now, it really appears like I either have to
> specify a default username and password in the file
> (whoch do not appear to be overridable)

I will get back to you on this.

kumarjayanti
Offline
Joined: 2003-12-10

I will file an issue and fix this soon.

Thanks.

amason
Offline
Joined: 2007-02-26

Thanks much. Can you also take a look at the other issue I mentioned that's preventing us from moving to newer nightly builds? It's basically related to TransactionManager and the fact that WLS 9.2 has one but it's not JTA 1.1 compatible. My proposed fix is basically class checking for both javax.transaction.TransactionManager as well as the TransactionSynchronizationRegistry interfaces as that appears to be what TransactionManagerImpl requires (it implements the second interface). So basically the isJTAAvailable is really asking the question "is JTA 1.1 available?" We don't need TX in our webservices so we're fine with it returning false for this platform. WLS 10 of course will not be a problem, but we're not ready for that just now.

jfialli
Offline
Joined: 2003-06-16

> Thanks much. Can you also take a look at the other
> issue I mentioned that's preventing us from moving to
> newer nightly builds? It's basically related to
> TransactionManager and the fact that WLS 9.2 has one
> but it's not JTA 1.1 compatible. My proposed fix is
> basically class checking for both
> javax.transaction.TransactionManager as well as the
> TransactionSynchronizationRegistry interfaces as that
> appears to be what TransactionManagerImpl requires
> (it implements the second interface). So basically
> the isJTAAvailable is really asking the question "is
> JTA 1.1 available?" We don't need TX in our
> webservices so we're fine with it returning false for
> this platform. WLS 10 of course will not be a
> problem, but we're not ready for that just now.
Already reported as part of following wsit issue 573.

https://wsit.dev.java.net/issues/show_bug.cgi?id=573

The tested patch is already same as proposed fix.
This change needs to be approved for FCS branch.
Fix will be checked into trunk immediately.

-Joe

amason
Offline
Joined: 2007-02-26

Please let me know what nightly build will have programmatic credentials propagated from proxy to STS as well as the TransactionManager resolution.

Thanks, Alex

amason
Offline
Joined: 2007-02-26

Hi:

Is there any update on this issue?

Specifically, am looking for propagation of Java security credentials set on web service binding propagated automatically to STS binding as is customary with .NET.

Thanks for any update, Alex

kumarjayanti
Offline
Joined: 2003-12-10

We are commited to fixing this. But it may require some more time. Here is the issue that you can track : https://wsit.dev.java.net/issues/show_bug.cgi?id=610

The delay is mainly because we are currently planning our .NEXT work which would require some internal API restructuring and fixing this bug also requires some addition to the integration layer between WS-Security and WS-Trust implementations in WSIT.

Thanks.

amason
Offline
Joined: 2007-02-26

This bug appears to be fixed.

Is there an example of how to do it? I have downloaded today's build 12/7 and it doesn't seem to work, but perhaps I am not doing it correctly.

Thanks!

shyam_rao
Offline
Joined: 2006-05-05

> This bug appears to be fixed.
>
> Is there an example of how to do it? I have
> downloaded today's build 12/7 and it doesn't seem to
> work, but perhaps I am not doing it correctly.

Having the following two line in the client program will solve the problem. By setting username/passward programatically in client, propagates these automatically to STS.

((BindingProvider)port).getRequestContext().put(BindingProvider.USERNAME_PROPERTY, username); ((BindingProvider)port).getRequestContext().put(BindingProvider.PASSWORD_PROPERTY, password);

amason
Offline
Joined: 2007-02-26

Yes, have that part down just fine and that's what I was expecting but what configuration needs to done in the wsit-client.xml?

Right now, it really appears like I either have to specify a default username and password in the file (whoch do not appear to be overridable) or I get various errors that I have not specified a callback handler configuration. Are there unit test or examples I can look at?

Thanks,Alex

shyam_rao
Offline
Joined: 2006-05-05

> Right now, it really appears like I either have to specify a default username and password > in the file (whoch do not appear to be overridable)

I will get back to you on this soon.

amason
Offline
Joined: 2007-02-26

Great. Thanks. I will volunteer that this is a non-Glassfish environment so am sincerely hoping this fix was not Glassfish specific.

Alex

jdg6688
Offline
Joined: 2005-11-02

Alternatively, you can write your own UserNamePasswordCallbackHandler for getting
your username and password and setting this call back handler in the wsit-client.xml for the STS client configuration.

Check wsit\wsit\samples\ws-trust\src\common\SampleUsernamePasswordCallbackHandler.java
for an example and
wsit\wsit\samples\ws-trust\src\fs\etc\clientconfig\wsit-client.xml
for the client configuration.

amason
Offline
Joined: 2007-02-26

Yes, but that again doesn't lend itself to unit testing very well where you may ant to provide different credentials per test or within a test method testing out an API against different users unless you start modifiying the file for setup/tearDown or have lots of different files. The programmatic way is much preferable in this case and I look forward to trying it out.

kumarjayanti
Offline
Joined: 2003-12-10

Hi,

You have hit an unsupported usecase. I mean programmatically setting the Username and Password for STS using the JAXWS USERNAME and PASSWORD properties in not supported, since the STS is hidden from the enduser.

Is this really important for you. Can you not specify the default username and password in STS client configuration (pre-configured STS).

Can you describe the usecase a bit more. From where do you intend to get the username and password for the STS invocation ?.

In other words would it help if you just set those properties on the Client Stub and WSIT would then propagate these properties to the STS Invocation. If this will work for you then i believe we can make a fix for this bug that you have hit upon early next week.

Thanks.

amason
Offline
Joined: 2007-02-26

Thanks for the response. Our end goal is a .NET client but we need to test our Java web service with auotmated unit tests (JUnit) and messing around with the STS client WSDL file and classpath in multiple tests is awkward. I also believe that on .NET I can set the username/password programatically on the target (not STS) proxy and somehow it gets to the STS so would be nice to be similar.

amason
Offline
Joined: 2007-02-26

A little more information.

1) Yes, I've gotten the preconfigured STS to work but in a unit test it's likely we'll want to be switching users to tests our APIs as different users.

2) I am dependent on an answer to another post this morning (unrelated but preventing us from moving to newer nightly builds)

http://forums.java.net/jive/thread.jspa?threadID=27101&tstart=0