You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@cxf.apache.org by geecxf <am...@ge.com> on 2013/04/04 16:44:29 UTC

DefaultSecurityTokenServiceProvider does not use CXF UsernameTokenValidator

I'm copying/pasting this from a blog posting where I first reported this
issue. You can find the original problem description and interaction with
the blogger here:

http://coheigea.blogspot.com/2011/11/apache-cxf-sts-documentation-part-viii_10.html?showComment=1365017694507#c377579003061518755

Here is the problem statement:

<begin quote>
Is there a way to configure the CXF/Talend STS to use a custom
UsernameTokenValidator?

The reason I ask is that I would like to call an external identity store to
validate the username/password. The identity store has an interface which
accepts a username and password and returns true of false depending on
whether the password is correct or not.

So far the only way I know to affect the behavior of the
UsernameTokenValidtor is to specify a callback handler. Unfortunately, the
default UsernameTokenValidator does not explicitly pass the password
received from the username token to the callback handler and the identity
store I am trying to work with will not return the password associated with
the id (it only validates a username/password pair).

While I can create a solution using the username callback handler, it is not
very pretty. The solution takes advantage of the fact that while the default
UsernameTokenValidator does not explicitly pass the password in the username
token, it does pass the entire contents of the soap message as part of the
"data" property. From that data, I can extract the SOAP message, then the
WSSecurity header, then the username token, and finally the password.

What I don't like about this solution is that the process of extracting the
username and password is already performed by the code that invokes the
callback handler. I'm doing it a second time in the callback handler, which
seems wasteful.

Thus, I'm wondering if I can create my own UsernameTokenValidtor and
overrride the one that the CXF STS uses by default?
<end quote>

The original response from Colm:

<begin quote>
Yes, you can inject your custom WSS4J Validator implementation into the
STS's UsernameTokenValidator via the "setValidator" method. See here:

http://svn.apache.org/viewvc/cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/validator/UsernameTokenValidator.java?view=markup
<end quote>

The response seemed like a plausible solution. However, while trying to
implement a solution along those lines I discovered the following:

<begin quote>
In fact, in the debugger it looks like the only validator ever called when
submitting an RST with a username token is
org.apache.ws.security.validate.UsernameTokenValidtor. This despite the fact
that I am using the CXF DefaultSecurityTokenProvider class.
<end quote>

So to summarize it would seem that the while the
DefaultSecurityTokenProvider registers a validator of type
org.apache.cxf.sts.token.validator.UsernameTokenValidator this never gets
used. Instead, org.apache.ws.security.validate.UsernameTokenValidtor is
used. This seems strange to me. Is it expected behavior?

My configuration is Talend v5.2.2. Specifically, I am hosting the STS in a
bundle on Karaf version 2.2.9, I am using CXF version 2.7.3, Camel 2.10.2,
and Jetty version 7.6.7v20120910



--
View this message in context: http://cxf.547215.n5.nabble.com/DefaultSecurityTokenServiceProvider-does-not-use-CXF-UsernameTokenValidator-tp5725849.html
Sent from the cxf-user mailing list archive at Nabble.com.

Re: DefaultSecurityTokenServiceProvider does not use CXF UsernameTokenValidator

Posted by geecxf <am...@ge.com>.
Thanks for pointing that out Colm. Once I started debugging from that entry
point I realized there was a subtle bug in my validator. Everything works
now. Once again many thanks for the help. I truly appreciate it.



--
View this message in context: http://cxf.547215.n5.nabble.com/DefaultSecurityTokenServiceProvider-does-not-use-CXF-UsernameTokenValidator-tp5725849p5725920.html
Sent from the cxf-user mailing list archive at Nabble.com.

Re: DefaultSecurityTokenServiceProvider does not use CXF UsernameTokenValidator

Posted by Colm O hEigeartaigh <co...@apache.org>.
Your endpoint configuration looks fine to me. For example, here is a
(non-STS) endpoint with a custom UsernameToken Validator:

http://svn.apache.org/viewvc/cxf/trunk/services/sts/systests/advanced/src/test/resources/org/apache/cxf/systest/sts/usernametoken/cxf-service.xml?view=markup

Could you check what is happening when WSS4J hits the UsernameToken in the
security header (UsernameTokenProcessor). What Validator instance is it
loading to validate the token?

Colm.



On Thu, Apr 4, 2013 at 5:03 PM, geecxf <am...@ge.com> wrote:

> Well I must be doing something wrong but I don't know what it is. Here is
> what I have:
>
>     <jaxws:endpoint id="transportSTS"
>         implementor="#transportSTSProviderBean"
>         address="https://localhost:${port}/SecurityTokenService/Transport"
>         wsdlLocation="wsdl/ws-trust-1.4-service.wsdl"
>         xmlns:ns1="http://docs.oasis-open.org/ws-sx/ws-trust/200512/"
>         serviceName="ns1:SecurityTokenService"
> endpointName="ns1:Transport_Port">
>         <jaxws:properties>
>             <entry key="ws-security.ut.validator">
>                 <bean class="abc.def.CustomUsernameTokenValidator" />
>             </entry>
>         </jaxws:properties>
>     </jaxws:endpoint>
>
> But this does not work. In fact when the STSClient calls the STS it
> complains about there not being a CallbackHandler. If I add the callback
> handler entry back to the properties in the debugger I can see that it is
> not touching the CustomUsernameTokenValidator. Perhaps my endpoint
> configuration is incorrect? Once again, I'm stuck.
>
>
>
> --
> View this message in context:
> http://cxf.547215.n5.nabble.com/DefaultSecurityTokenServiceProvider-does-not-use-CXF-UsernameTokenValidator-tp5725849p5725862.html
> Sent from the cxf-user mailing list archive at Nabble.com.
>



-- 
Colm O hEigeartaigh

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

Re: DefaultSecurityTokenServiceProvider does not use CXF UsernameTokenValidator

Posted by geecxf <am...@ge.com>.
Well I must be doing something wrong but I don't know what it is. Here is
what I have:

    <jaxws:endpoint id="transportSTS"
        implementor="#transportSTSProviderBean"
        address="https://localhost:${port}/SecurityTokenService/Transport"
        wsdlLocation="wsdl/ws-trust-1.4-service.wsdl"
        xmlns:ns1="http://docs.oasis-open.org/ws-sx/ws-trust/200512/"
        serviceName="ns1:SecurityTokenService"
endpointName="ns1:Transport_Port">
        <jaxws:properties>
            <entry key="ws-security.ut.validator">
                <bean class="abc.def.CustomUsernameTokenValidator" />
            </entry>
        </jaxws:properties>
    </jaxws:endpoint>

But this does not work. In fact when the STSClient calls the STS it
complains about there not being a CallbackHandler. If I add the callback
handler entry back to the properties in the debugger I can see that it is
not touching the CustomUsernameTokenValidator. Perhaps my endpoint
configuration is incorrect? Once again, I'm stuck.



--
View this message in context: http://cxf.547215.n5.nabble.com/DefaultSecurityTokenServiceProvider-does-not-use-CXF-UsernameTokenValidator-tp5725849p5725862.html
Sent from the cxf-user mailing list archive at Nabble.com.

Re: DefaultSecurityTokenServiceProvider does not use CXF UsernameTokenValidator

Posted by Colm O hEigeartaigh <co...@apache.org>.
Hi,

If the UsernameToken is in the security header of the STS request, then it
will get handled by WSS4J before the STS implementation sees it. So you
will need to plug your custom UsernameTokenValidator in to the endpoint via
a jaxws:property, e.g:

 <jaxws:properties>
           <entry key="ws-security.ut.validator">
              <bean class="XXX.YYY"/>
           </entry>
</jaxws:properties>

Colm.



On Thu, Apr 4, 2013 at 3:44 PM, geecxf <am...@ge.com> wrote:

> I'm copying/pasting this from a blog posting where I first reported this
> issue. You can find the original problem description and interaction with
> the blogger here:
>
>
> http://coheigea.blogspot.com/2011/11/apache-cxf-sts-documentation-part-viii_10.html?showComment=1365017694507#c377579003061518755
>
> Here is the problem statement:
>
> <begin quote>
> Is there a way to configure the CXF/Talend STS to use a custom
> UsernameTokenValidator?
>
> The reason I ask is that I would like to call an external identity store to
> validate the username/password. The identity store has an interface which
> accepts a username and password and returns true of false depending on
> whether the password is correct or not.
>
> So far the only way I know to affect the behavior of the
> UsernameTokenValidtor is to specify a callback handler. Unfortunately, the
> default UsernameTokenValidator does not explicitly pass the password
> received from the username token to the callback handler and the identity
> store I am trying to work with will not return the password associated with
> the id (it only validates a username/password pair).
>
> While I can create a solution using the username callback handler, it is
> not
> very pretty. The solution takes advantage of the fact that while the
> default
> UsernameTokenValidator does not explicitly pass the password in the
> username
> token, it does pass the entire contents of the soap message as part of the
> "data" property. From that data, I can extract the SOAP message, then the
> WSSecurity header, then the username token, and finally the password.
>
> What I don't like about this solution is that the process of extracting the
> username and password is already performed by the code that invokes the
> callback handler. I'm doing it a second time in the callback handler, which
> seems wasteful.
>
> Thus, I'm wondering if I can create my own UsernameTokenValidtor and
> overrride the one that the CXF STS uses by default?
> <end quote>
>
> The original response from Colm:
>
> <begin quote>
> Yes, you can inject your custom WSS4J Validator implementation into the
> STS's UsernameTokenValidator via the "setValidator" method. See here:
>
>
> http://svn.apache.org/viewvc/cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/validator/UsernameTokenValidator.java?view=markup
> <end quote>
>
> The response seemed like a plausible solution. However, while trying to
> implement a solution along those lines I discovered the following:
>
> <begin quote>
> In fact, in the debugger it looks like the only validator ever called when
> submitting an RST with a username token is
> org.apache.ws.security.validate.UsernameTokenValidtor. This despite the
> fact
> that I am using the CXF DefaultSecurityTokenProvider class.
> <end quote>
>
> So to summarize it would seem that the while the
> DefaultSecurityTokenProvider registers a validator of type
> org.apache.cxf.sts.token.validator.UsernameTokenValidator this never gets
> used. Instead, org.apache.ws.security.validate.UsernameTokenValidtor is
> used. This seems strange to me. Is it expected behavior?
>
> My configuration is Talend v5.2.2. Specifically, I am hosting the STS in a
> bundle on Karaf version 2.2.9, I am using CXF version 2.7.3, Camel 2.10.2,
> and Jetty version 7.6.7v20120910
>
>
>
> --
> View this message in context:
> http://cxf.547215.n5.nabble.com/DefaultSecurityTokenServiceProvider-does-not-use-CXF-UsernameTokenValidator-tp5725849.html
> Sent from the cxf-user mailing list archive at Nabble.com.
>



-- 
Colm O hEigeartaigh

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