cxf-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Sergey Beryozkin <sberyoz...@gmail.com>
Subject Re: UsernameToken JBoss Integration
Date Wed, 06 Apr 2011 16:39:18 GMT
Hi David

I did a minor update to WSS4JInInterceptor to ensure that the 'best'
principal is wrapped as a SecurityContext principal, when possible. This
update does not change the fact all Principals are still available on the
message for subsequent interceptors to check, it simply attempts not to set
a Principal representing the encryption key which was used to encrypt UT as
the 'main' Principal.

Hope Colm and others will be ok with this update.

Can you please checkout 2.3.4-SNAPSHOT and verify it fixes the problem ?

Thanks, Sergey

On Tue, Apr 5, 2011 at 12:01 PM, David Zhang <zhngdvd@hotmail.com> wrote:

> Hello Sergey,
>
> i think i found the cause of the problem. JBoss 6.0.0.Final comes with CXF
> 2.3.1. However, i checked out the 2.3.3 tag and did a little bug fix.
>
> What do you think of it? Please tell me, if you will make a fix for 2.3.x,
> then i would like to download the update.
>
> Please look at
> org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor.doResults()
>
> At the end of the method is a for-loop over the wssEngineResults. If
> withCallbacks is false then the UsernameToken should be put in the message.
> The Problem is, the first Principal found is not the UsernameTokenPrincipal
> but the DerivedKeyPrincipal. This triggers creation of a security context
> and breakes the for-loop. The second wssEngineResult would have been the
> UsernameTokenPrincipal.
>
> I believe this is the reason why i receive the error message:
> Security Token is not available on the current message
>
> Here is the patch i use. It seems to work for me.
>
> David
>
> protected void doResults(SoapMessage msg, String actor, SOAPMessage doc,
> Vector wsResult,
>        boolean utWithCallbacks) throws SOAPException, XMLStreamException,
> WSSecurityException {
>        /*
>         * All ok up to this point. Now construct and setup the security
> result
>         * structure. The service may fetch this and check it.
>         */
>        List<Object> results =
> CastUtils.cast((List)msg.get(WSHandlerConstants.RECV_RESULTS));
>        if (results == null) {
>            results = new Vector<Object>();
>            msg.put(WSHandlerConstants.RECV_RESULTS, results);
>        }
>        WSHandlerResult rResult = new WSHandlerResult(actor, wsResult);
>        results.add(0, rResult);
>
>        SOAPBody body = doc.getSOAPBody();
>
>        XMLStreamReader reader = StaxUtils.createXMLStreamReader(new
> DOMSource(body));
>        // advance just past body
>        int evt = reader.next();
>        int i = 0;
>        while (reader.hasNext() && i < 1
>               && (evt != XMLStreamConstants.END_ELEMENT || evt !=
> XMLStreamConstants.START_ELEMENT)) {
>            reader.next();
>            i++;
>        }
>        msg.setContent(XMLStreamReader.class, reader);
>        String pwType = (String)getProperty(msg, "passwordType");
>        if ("PasswordDigest".equals(pwType)) {
>            //CXF-2150 - we need to check the UsernameTokens
>            for (WSSecurityEngineResult o : CastUtils.cast(wsResult,
> WSSecurityEngineResult.class)) {
>                Integer actInt =
> (Integer)o.get(WSSecurityEngineResult.TAG_ACTION);
>                if (actInt == WSConstants.UT) {
>                    WSUsernameTokenPrincipal princ
>                        =
> (WSUsernameTokenPrincipal)o.get(WSSecurityEngineResult.TAG_PRINCIPAL);
>                    if (!princ.isPasswordDigest()) {
>                        LOG.warning("Non-digest UsernameToken found, but
> digest required");
>                        throw new
> WSSecurityException(WSSecurityException.INVALID_SECURITY);
>                    }
>                }
>            }
>        }
>
>        if (!utWithCallbacks) {
>            for (WSSecurityEngineResult o : CastUtils.cast(wsResult,
> WSSecurityEngineResult.class)) {
>                final Principal p =
> (Principal)o.get(WSSecurityEngineResult.TAG_PRINCIPAL);
>                if (p instanceof WSUsernameTokenPrincipal) {
>                    msg.put(PRINCIPAL_RESULT, p);
>                    WSS4JTokenConverter.convertToken(msg, p);
>                    SecurityContext sc = msg.get(SecurityContext.class);
>                    if (sc == null || sc.getUserPrincipal() == null) {
>                        msg.put(SecurityContext.class,
> createSecurityContext(p));
>                    }
>                    break;
>                }
>            }
>        } else {
>            for (WSSecurityEngineResult o : CastUtils.cast(wsResult,
> WSSecurityEngineResult.class)) {
>                final Principal p =
> (Principal)o.get(WSSecurityEngineResult.TAG_PRINCIPAL);
>                if (p != null) {
>                    msg.put(PRINCIPAL_RESULT, p);
>                    if (!utWithCallbacks) {
>                        WSS4JTokenConverter.convertToken(msg, p);
>                    }
>                    SecurityContext sc = msg.get(SecurityContext.class);
>                    if (sc == null || sc.getUserPrincipal() == null) {
>                        msg.put(SecurityContext.class,
> createSecurityContext(p));
>                        break;
>                     }
>                }
>            }
>        }
>    }
>
> -----Ursprüngliche Nachricht-----
> From: Sergey Beryozkin
> Sent: Monday, April 04, 2011 1:50 PM
> To: users@cxf.apache.org
> Cc: David Zhang
> Subject: Re: UsernameToken JBoss Integration
>
> Sorry, that one is indeed needed for the encryption itself to succeed.
> Can you try, for the sake of the test, send unencrypted UTs ?
>
> I don't recall if I had the test for the case when the body was also
> encrypted, would have to check.
> In meantime, you may want to try the following:
>
> - if UT passwords are not encrypted then simply register a CXF interceptor,
> after WSS4JInInterceptor, extract a WSS4J token and use it to create the
> Subject and then replace the existing SecurityContext on the message with
> the new one - if you decide to follow this route then I can provide more
> info on how existing CXF SecurityContext impls can be reused
> - if it is not a WSDL-first case then  register an
> AbstractUsernameTokenAuthenticatingInterceptor implementation instead of
> WSS4InInterceptor but configure it as usual, just do not provide a UT
> callback
>
> Let us know how it goes
>
> Sergey
>
> On Mon, Apr 4, 2011 at 12:33 PM, David Zhang <zhngdvd@hotmail.com> wrote:
>
> > Hello,
> >
> > i still cannot get the AuthenticationInterceptor to work.
> >
> > The password callback is needed to retrieve the password for the private
> > key. Otherwise the server cannot decrypt the SOAP Request.
> >
> > However, when the AuthenticationInterceptor is called in the pre-invoke
> > Phase, the security token is null.
> > see AbstractSecurityContextInInterceptor.handleMessage()
> >
> > Any ideas?
> >
> > David
> >
> > From: zhngdvd@hotmail.com
> > Sent: Friday, April 01, 2011 7:38 AM
> > To: users@cxf.apache.org
> > Subject: Re: UsernameToken JBoss Integration
> >
> > Hello Sergey,
> >
> > if i remove the password callback, i get another error message:
> > General security error (WSSecurityEngine: Callback supplied no password
> > for: myAlias)
> >
> > The keystore.properties file contains only the password for the keystore,
> > not for the private key inside the keystore. Also i can not find a way to
> > create a private key without password by the java keytool.
> >
> > Is there another way to provide the password besides the password
> callback?
> > Is there maybe a property in the keystore.properties file? I cannot find
> a
> > suitable property in this list:
> > http://cxf.apache.org/docs/ws-securitypolicy.html
> >
> > This is the content of the keystore.properties. The ${}-parts are
> replaced
> > by maven with actual values:
> >
> >
> >
> >
> org.apache.ws.security.crypto.provider=org.apache.ws.security.components.crypto.Merlin
> > org.apache.ws.security.crypto.merlin.keystore.type=jks
> >
> org.apache.ws.security.crypto.merlin.keystore.password=${keystore.password}
> > org.apache.ws.security.crypto.merlin.keystore.alias=${certificate.alias}
> > org.apache.ws.security.crypto.merlin.file=${keystore.path}
> >
> >
> >
> > Thank you
> > David
> >
> > -----Ursprüngliche Nachricht-----
> > From: Sergey Beryozkin
> > Sent: Thursday, March 31, 2011 10:21 PM
> > To: users@cxf.apache.org
> > Subject: Re: UsernameToken JBoss Integration
> >
> > Hi -
> >
> > You don't need a password callback in this case.
> >
> > Cheers, Sergey
> >
> > On Thu, Mar 31, 2011 at 7:42 PM, David Zhang <zhngdvd@hotmail.com>
> wrote:
> >
> > > Hi Sergey,
> > >
> > > thank you very much for taking the time to help me.
> > > I have set the property you mentioned. Look, this is my configuration:
> > >
> > >
> > > <jaxws:endpoint id="SecureServiceBean"
> > >
> > > address="/example-ejb/SecureService"
> > >
> > > implementor="com.example.SecureServiceBean">
> > >
> > > <jaxws:invoker>
> > >
> > > <bean class="org.jboss.wsf.stack.cxf.InvokerEJB3" />
> > >
> > > </jaxws:invoker>
> > >
> > > <jaxws:inInterceptors>
> > >
> > >
> > > <bean class="com.example.AuthenticationInterceptor1"/>
> > >
> > > </jaxws:inInterceptors>
> > >
> > > <jaxws:properties>
> > >
> > > <entry key="ws-security.ut.no-callbacks" value="true" />
> > >
> > > <!--<entry key="ws-security.validate.token" value="false" />-->
> > >
> > > <entry key="ws-security.signature.properties"
> value="keystore.properties"
> > > />
> > >
> > > <entry key="ws-security.encryption.properties"
> > value="keystore.properties"
> > > />
> > >
> > > <entry key="ws-security.callback-handler"
> > > value="com.example.PasswordCallback" />
> > >
> > > </jaxws:properties>
> > >
> > > </jaxws:endpoint>
> > >
> > > Where com.example.AuthenticationInterceptor1 extends
> > > AbstractUsernameTokenInInterceptor.
> > > This results in:
> > > 12:01:12,770 ERROR
> > >
> >
> [org.apache.cxf.interceptor.security.AbstractSecurityContextInInterceptor]
> > > Security Token is not available on the current message
> > >
> > > Thanks
> > > David
> > >
> > >
> > > -----Ursprüngliche Nachricht-----
> > > From: Sergey Beryozkin
> > > Sent: Thursday, March 31, 2011 11:06 AM
> > > To: users@cxf.apache.org
> > > Subject: Re: UsernameToken JBoss Integration
> > >
> > > Hi
> > >
> > > Please check this section:
> > >
> > >
> > >
> >
> http://cxf.apache.org/docs/security.html#Security-WSSecurityUsernameTokenandCustomAuthentication
> > >
> > > In 2.3.x you have to set a "ws-security.ut.no-callbacks" property and
> > this
> > > will ensure AbstractUserNameTokenInterceptor can be used.
> > >
> > > Setting this property results in WSS4JInInterceptor duplicating WSS4J
> > > specific UT into CXF specific UsernameToken which is what
> > > AbstractUserNameTokenInterceptor is checking.
> > >
> > > Cheers, Sergey
> > >
> > > On Thu, Mar 31, 2011 at 8:42 AM, David Zhang <zhngdvd@hotmail.com>
> > wrote:
> > >
> > > >
> > > > Hello,
> > > >
> > > >
> > > >
> > > > i have a web service with symmetric binding and self-signed server
> > > > certificate.
> > > >
> > > > I implemented a password callbackhandler for the password to the
> > private
> > > > key of the server.
> > > >
> > > > Now i want to add authentication with username token. So i added a
> > > > supporting token to the ws security policy.
> > > >
> > > >
> > > >
> > > > To this point everything works fine. The server gets an encrypted
> > request
> > > > with a username token.
> > > >
> > > > My concern is that i do not want to do the authentication in my
> > > > application. I want to integrate the username token with JBoss
> > Security.
> > > >
> > > >
> > > >
> > > > So i followed these instructions:
> > > >
> > >
> >
> http://community.jboss.org/wiki/JBossWS-StackCXFUserGuide#Authentication_and_authorization
> > > >
> > > > However, it did not work. I used a debugger to check and i saw the
> > > > authentication interceptor was created when my app was deployed but
> it
> > > was
> > > > never called on a client request.
> > > >
> > > >
> > > >
> > > > Later i found this:
> > > >
> > >
> >
> http://svn.apache.org/repos/asf/cxf/tags/cxf-2.3.3/systests/ws-specs/src/test/java/org/apache/cxf/systest/ws/wssec10/server/SimpleSubjectCreatingInterceptor.java
> > > >
> > > > I implemented an interceptor following that example. I put a
> breakpoint
> > > on
> > > > the createSubject method. It was never called.
> > > >
> > > >
> > > >
> > > > Then i followed this example:
> > > >
> > >
> >
> http://svn.apache.org/repos/asf/cxf/tags/cxf-2.3.3/systests/ws-specs/src/test/java/org/apache/cxf/systest/ws/wssec10/server/SimpleUsernameTokenInterceptor.java
> > > >
> > > > At least i know this interceptor was called. But it produced an error
> > > > before the createSubject method was called. The error says: Security
> > > Token
> > > > is not available on the current message
> > > >
> > > >
> > > >
> > > > But this can not be true. Because then i removed the interceptor
> > removed
> > > > the property ws-security.ut.no-callbacks and on the next request my
> > > password
> > > > callbackhandler was called with the username i set on the client.
> > > >
> > > >
> > > >
> > > > Please, can anybody explain me what i am doing wrong?
> > > >
> > > >
> > > >
> > > > Thanks
> > > >
> > > > David
> > > >
> > >
> > >
> > >
> > >
> > > --
> > > Sergey Beryozkin
> > >
> > > Application Integration Division of Talend <http://www.talend.com>
> > > http://sberyozkin.blogspot.com
> >
> >
> >
> >
> > --
> > Sergey Beryozkin
> >
> > Application Integration Division of Talend <http://www.talend.com>
> > http://sberyozkin.blogspot.com
> >
>
>
>
> --
> Sergey Beryozkin
>
> Application Integration Division of Talend <http://www.talend.com>
> http://sberyozkin.blogspot.com
>



-- 
Sergey Beryozkin

Application Integration Division of Talend <http://www.talend.com>
http://sberyozkin.blogspot.com

Mime
  • Unnamed multipart/alternative (inline, None, 0 bytes)
View raw message