JAX-WS SSO using an STS

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

JAX-WS SSO using an STS

pat7
I implemented a business service (transfer service) based on the cxf
framework and spring boot. A user has to send to the business service a saml
token, which is issued by the STS. The business service redirects the
request via a security policy to the STS, which authenticates the user via
Usernametoken.  
I test the business service and STS with the following client example:

https://github.com/coheigea/testcases/tree/master/apache/cxf/cxf-sts

This example involves a SSO test for the business service and the STS.
Everything worked fine but I have two questions, which I do not understand.

1) The issued SAML token is only valid for the transfer service if the token
is first issued for the transfer service, isn’t it? If I have a second
service (for example change user address service), this issued SAML token
for the transfer service is not valid for the “change user address service”.
Therefore, I think SSO is only valid for one service address if I use only
one STS.
Is there a possibility to establish SSO for various service addresses, which
I am trust?


2) I implemented only an issue and validate operation for the STS and test
the SSO with the following client code example:

STSClient sts = new STSClient(bus);
sts.setWsdlLocation("https://localhost:8443/services/SecurityTokenService?wsdl");
sts.setServiceName("{http://docs.oasis-open.org/ws-sx/ws-trust/200512/}SecurityTokenService");
sts.setEndpointName("{http://docs.oasis-open.org/ws-sx/ws-trust/200512/}UT_Port");
                       
Map<String,Object> prop = new HashMap<String, Object>();
prop.put("security.sts.token.username", "myclientkey");
prop.put("security.sts.token.properties", "clientKeystore.properties");
prop.put("security.sts.usecert", true);
                       
((BindingProvider) proxy).getRequestContext().put("ws-security.username",
"anna");
((BindingProvider) proxy).getRequestContext().put("ws-security.password",
"anna123");
((BindingProvider) proxy).getRequestContext().put("ws-security.sts.client",
sts);
((BindingProvider)
proxy).getRequestContext().put("ws-security.callback-handler",
Testcallback.class.getName());
                       
getshipment(proxy);

((BindingProvider)
proxy).getRequestContext().remove("ws-security.username");
((BindingProvider)
proxy).getRequestContext().remove("ws-security.password");
for(int i=1;i<5;i++){
        System.out.println("\n" + new Date());
        getlistshipments(proxy);
        Thread.sleep(900000);
}

After a request I wait until 15 minutes and send then a new request. A token
is standard 30 minutes valid. After sending the second request, the STS
throw an exception because no renew operation is found. This is the
behaviour, which I am expected. However, after the exception the STS
authenticate the user again via a callback handler, which I do not
understand. How is this possible because I remove the username and password?
Maybe CXF stores elsewhere the username and password?




--
Sent from: http://cxf.547215.n5.nabble.com/cxf-user-f547216.html
Reply | Threaded
Open this post in threaded view
|

Re: JAX-WS SSO using an STS

coheigea
Administrator
Answers inline.

On Tue, Jan 16, 2018 at 12:55 PM, pat7 <[hidden email]> wrote:

>
>
> 1) The issued SAML token is only valid for the transfer service if the
> token
> is first issued for the transfer service, isn’t it? If I have a second
> service (for example change user address service), this issued SAML token
> for the transfer service is not valid for the “change user address
> service”.
> Therefore, I think SSO is only valid for one service address if I use only
> one STS.
> Is there a possibility to establish SSO for various service addresses,
> which
> I am trust?
>

Yep correct. The client sends an "AppliesTo" address (which is the address
of the remote service by default) to the STS which embeds it in the issued
SAML token. The token is only valid for this recipient then. You can weaken
this if you want to by setting the "enableAppliesTo" property of the
STSClient to "false".


> 2) I implemented only an issue and validate operation for the STS and test
> the SSO with the following client code example:
>
> STSClient sts = new STSClient(bus);
> sts.setWsdlLocation("https://localhost:8443/services/
> SecurityTokenService?wsdl");
> sts.setServiceName("{http://docs.oasis-open.org/ws-sx/ws-trust/200512/}
> SecurityTokenService");
> sts.setEndpointName("{http://docs.oasis-open.org/ws-sx/ws-
> trust/200512/}UT_Port");
>
> Map<String,Object> prop = new HashMap<String, Object>();
> prop.put("security.sts.token.username", "myclientkey");
> prop.put("security.sts.token.properties", "clientKeystore.properties");
> prop.put("security.sts.usecert", true);
>
> ((BindingProvider) proxy).getRequestContext().put("ws-security.username",
> "anna");
> ((BindingProvider) proxy).getRequestContext().put("ws-security.password",
> "anna123");
> ((BindingProvider) proxy).getRequestContext().
> put("ws-security.sts.client",
> sts);
> ((BindingProvider)
> proxy).getRequestContext().put("ws-security.callback-handler",
> Testcallback.class.getName());
>
> getshipment(proxy);
>
> ((BindingProvider)
> proxy).getRequestContext().remove("ws-security.username");
> ((BindingProvider)
> proxy).getRequestContext().remove("ws-security.password");
> for(int i=1;i<5;i++){
>         System.out.println("\n" + new Date());
>         getlistshipments(proxy);
>         Thread.sleep(900000);
> }
>
> After a request I wait until 15 minutes and send then a new request. A
> token
> is standard 30 minutes valid. After sending the second request, the STS
> throw an exception because no renew operation is found. This is the
> behaviour, which I am expected. However, after the exception the STS
> authenticate the user again via a callback handler, which I do not
> understand. How is this possible because I remove the username and
> password?
> Maybe CXF stores elsewhere the username and password?
>

Are you sure that a second request is actually being sent? The client
should cache the token and re-use it as long as it is valid, and only then
request a new token from the STS.

Colm.


>
>
>
>
> --
> Sent from: http://cxf.547215.n5.nabble.com/cxf-user-f547216.html
>



--
Colm O hEigeartaigh

Talend Community Coder
http://coders.talend.com
Reply | Threaded
Open this post in threaded view
|

Re: JAX-WS SSO using an STS

pat7
Thx for reply.

Ad 1) Consequently, if I am allow SSO on the server side, the client side is
able to use the saml token for one service address or different service
addresses. The client side has to do action if he want to use the saml token
again until it expire. Hope I get it.

Ad 2) Yes I am sure that the seceond request is sent.
Both methods (getshipment(proxy) & getlistshipments(proxy)) are implemented
at the business service, transferservice.  
With the conmand Thread.sleep(900000) I want to see the error msg if the
saml token is expired. Because I do not configure the Renew operation on the
STS.
Furthermore, I saw at the logs on the server side. All five request are sent
to the server.
I do not understand how the client is reauthenticated without the username
and passwort.

I receive this error msg on the client side:
Jän 17, 2018 11:57:25 AM org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor
handleMessageInternal
WARNUNG: The request is a SOAP Fault, but it is not secured
Jän 17, 2018 11:57:25 AM org.apache.cxf.ws.security.trust.STSTokenRetriever
renewToken
WARNUNG: Error renewing a token
org.apache.cxf.binding.soap.SoapFault: Implementation for this operation not
found.

...and afterwards I receive the information from the output of the response
on the console.

Did anybody have the same problems?

Regrads,
Patrick




--
Sent from: http://cxf.547215.n5.nabble.com/cxf-user-f547216.html
Reply | Threaded
Open this post in threaded view
|

Re: JAX-WS SSO using an STS

coheigea
Administrator
Hi Patrick,

The problem is that STSClient caches the security properties. You can clear
them instead by doing something like:

STSClient stsClient =
            (STSClient)((BindingProvider)
port).getRequestContext().get(SecurityConstants.STS_CLIENT);
stsClient.getProperties().clear();

Colm.

On Wed, Jan 17, 2018 at 11:37 AM, pat7 <[hidden email]> wrote:

> Thx for reply.
>
> Ad 1) Consequently, if I am allow SSO on the server side, the client side
> is
> able to use the saml token for one service address or different service
> addresses. The client side has to do action if he want to use the saml
> token
> again until it expire. Hope I get it.
>
> Ad 2) Yes I am sure that the seceond request is sent.
> Both methods (getshipment(proxy) & getlistshipments(proxy)) are implemented
> at the business service, transferservice.
> With the conmand Thread.sleep(900000) I want to see the error msg if the
> saml token is expired. Because I do not configure the Renew operation on
> the
> STS.
> Furthermore, I saw at the logs on the server side. All five request are
> sent
> to the server.
> I do not understand how the client is reauthenticated without the username
> and passwort.
>
> I receive this error msg on the client side:
> Jän 17, 2018 11:57:25 AM org.apache.cxf.ws.security.
> wss4j.WSS4JInInterceptor
> handleMessageInternal
> WARNUNG: The request is a SOAP Fault, but it is not secured
> Jän 17, 2018 11:57:25 AM org.apache.cxf.ws.security.
> trust.STSTokenRetriever
> renewToken
> WARNUNG: Error renewing a token
> org.apache.cxf.binding.soap.SoapFault: Implementation for this operation
> not
> found.
>
> ...and afterwards I receive the information from the output of the response
> on the console.
>
> Did anybody have the same problems?
>
> Regrads,
> Patrick
>
>
>
>
> --
> Sent from: http://cxf.547215.n5.nabble.com/cxf-user-f547216.html
>



--
Colm O hEigeartaigh

Talend Community Coder
http://coders.talend.com