You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@cxf.apache.org by Jason Pell <ja...@pellcorp.com> on 2010/11/05 15:21:15 UTC

Authentication in cxf and getting the full DN into the Principal

Hi,

I am struggling with configuring CXF and spring security.  I am running the
2.3.1-SNAPSHOT which has some improvements to the WSS4JInInterceptor.  So
basically what I have is a JAX-WS service using ws-security to authenticate
using username password token.  The username is the uid= of the DN of a user
record in LDAP.

What I want is for the Principal saved into teh CXF SecurityContext to have
the Full DN of the user.

So what I have setup by way of interceptors are:

org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor
(ws-security.ut.no-callbacks = true)
I have a custom class which extends
org.apache.cxf.interceptor.security.AbstractUsernameTokenInInterceptor to
use spring security to create the Subject.  I am creating a subject with the
full DN of the user.

However the
org.apache.cxf.interceptor.security.AbstractSecurityContextInInterceptor
ignores this and recreates the SecurityContext with the original username

SecurityContext sc = createSecurityContext(context.getUserPrincipal(),
subject);

So I am kind of up the creek without any kind of paddle :-)

Any suggestions for how I might proceed.  I guess I can always create my own
interceptor from scratch to do this.  I already did the same thing to
populate the full DN of groups.

Re: Authentication in cxf and getting the full DN into the Principal

Posted by Jason Pell <ja...@pellcorp.com>.
Also since subject.getPrincipals returns a set, would have to do something like:

List<Principal> principals = new ArrayList<Principal>(subject.getPrincipals());



On Sat, Nov 6, 2010 at 8:48 AM, Jason Pell <ja...@pellcorp.com> wrote:
> Hi,
>
> I think that sounds ok.  My experience is that often the final
> principal will differ from the original which is why ldap has a user
> dn search attribute to find the actual user principal based on the
> initial one.
>
> Also while I have your attention.  I was confused as to why the
> changes to WSS4JInInterceptor for ws-security.ut.no-callbacks do not
> support direct configuration of the interceptor (I noted this perhaps
> incorrectly on the CXF-3063 patch).
>
> I updated locally to be:
>
>        //boolean utWithCallbacks =
>        //    !MessageUtils.getContextualBoolean(msg,
> SecurityConstants.USERNAME_TOKEN_NO_CALLBACKS, false);
>
>        // allows it to be set from a spring bean interceptor or jaxws:property
>        boolean utWithCallbacks =
> !MessageUtils.isTrue(getProperty(msg,
> SecurityConstants.USERNAME_TOKEN_NO_CALLBACKS));
>
> Which allowed me to create an interceptor like so:
>
> <bean id="WSS4JInInterceptor"
>                class="org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor">
>                <constructor-arg>
>                        <map>
>                                <entry key="action" value="UsernameToken" />
>                                <entry key="passwordType" value="PasswordText" />
>                                <entry key="ws-security.ut.no-callbacks" value="true" />
>                        </map>
>                </constructor-arg>
>        </bean>
>
> Would love to know if this change can be formalised before 2.3.1 is released.
>
> By the way, love the abstraction of the WSS4J from the rest of the
> authorisation very neat
>
> Thanks
> Jason
>
>
> On Sat, Nov 6, 2010 at 5:22 AM, Sergey Beryozkin <sb...@gmail.com> wrote:
>>
>> Hi
>>
>> On Fri, Nov 5, 2010 at 2:21 PM, Jason Pell <ja...@pellcorp.com> wrote:
>>
>> > Hi,
>> >
>> > I am struggling with configuring CXF and spring security.  I am running the
>> > 2.3.1-SNAPSHOT which has some improvements to the WSS4JInInterceptor.  So
>> > basically what I have is a JAX-WS service using ws-security to authenticate
>> > using username password token.  The username is the uid= of the DN of a
>> > user
>> > record in LDAP.
>> >
>> > What I want is for the Principal saved into teh CXF SecurityContext to have
>> > the Full DN of the user.
>> >
>> > So what I have setup by way of interceptors are:
>> >
>> > org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor
>> > (ws-security.ut.no-callbacks = true)
>> > I have a custom class which extends
>> > org.apache.cxf.interceptor.security.AbstractUsernameTokenInInterceptor to
>> > use spring security to create the Subject.  I am creating a subject with
>> > the
>> > full DN of the user.
>> >
>> > However the
>> > org.apache.cxf.interceptor.security.AbstractSecurityContextInInterceptor
>> > ignores this and recreates the SecurityContext with the original username
>> >
>> > SecurityContext sc = createSecurityContext(context.getUserPrincipal(),
>> > subject);
>> >
>> >
>> the assumption was that the Principal created by WSS4J initially does
>> represent the final/correct Principal.
>> So may be the interceptor should be updated like this :
>>
>> List<?> principals = subject.getPrincipals();
>>
>> Principal p = principals.size() > 0 && !(principals.get(0) instanceof Group)
>>
>>                      ? (Principal)principals.get(0) :
>> context.getUserPrincipal();
>>
>> SecurityContext sc = createSecurityContext(p, subject);
>>
>> something like that...
>>
>> What do you think ?
>>
>> cheers, Sergey
>>
>>
>> So I am kind of up the creek without any kind of paddle :-)
>> >
>> > Any suggestions for how I might proceed.  I guess I can always create my
>> > own
>> > interceptor from scratch to do this.  I already did the same thing to
>> > populate the full DN of groups.
>> >
>

Re: Authentication in cxf and getting the full DN into the Principal

Posted by Jason Pell <ja...@pellcorp.com>.
Hi,

Thought I should post an update.  Now that I have a little more
experience I have realised I can set a jaxws:property directly on a
JaxWsServerFactoryBean like so:


		JaxWsServerFactoryBean serverFactory = new JaxWsServerFactoryBean();
		Map<String, Object> properties = new HashMap<String, Object>();
		properties.put("ws-security.ut.no-callbacks", "true");
		serverFactory.setProperties(properties);

I have now deleted my hack.

Might be helpful for someone else trying to use this directly.  Bit of
a D'oh moment for me actually :-)

On Mon, Nov 8, 2010 at 10:20 PM, Sergey Beryozkin <sb...@gmail.com> wrote:
> Hi
>
> On Fri, Nov 5, 2010 at 9:48 PM, Jason Pell <ja...@pellcorp.com> wrote:
>
>> Hi,
>>
>> ...
>> Also while I have your attention.  I was confused as to why the
>> changes to WSS4JInInterceptor for ws-security.ut.no-callbacks do not
>> support direct configuration of the interceptor (I noted this perhaps
>> incorrectly on the CXF-3063 patch).
>>
>> I updated locally to be:
>>
>>        //boolean utWithCallbacks =
>>        //    !MessageUtils.getContextualBoolean(msg,
>> SecurityConstants.USERNAME_TOKEN_NO_CALLBACKS, false);
>>
>>        // allows it to be set from a spring bean interceptor or
>> jaxws:property
>>        boolean utWithCallbacks =
>> !MessageUtils.isTrue(getProperty(msg,
>> SecurityConstants.USERNAME_TOKEN_NO_CALLBACKS));
>>
>> Which allowed me to create an interceptor like so:
>>
>> <bean id="WSS4JInInterceptor"
>>                class="org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor">
>>                <constructor-arg>
>>                        <map>
>>                                <entry key="action" value="UsernameToken" />
>>                                <entry key="passwordType"
>> value="PasswordText" />
>>                                <entry key="ws-security.ut.no-callbacks"
>> value="true" />
>>                        </map>
>>                </constructor-arg>
>>        </bean>
>>
>> Would love to know if this change can be formalised before 2.3.1 is
>> released.
>>
>>
> I started working on this issue after it was reported that extending
> WSS4JInInterceptor does not work in wsdl/policy-first cases, where no
> explicit configuration of  WSS4JInInterceptor is done. Thus I had to go with
> the contextual properties approach... May be we can just combine two boolean
> checks ?
>
>
>> By the way, love the abstraction of the WSS4J from the rest of the
>> authorisation very neat
>>
>> thanks
> Sergey
>
>
>> Thanks
>> Jason
>>
>>
>> On Sat, Nov 6, 2010 at 5:22 AM, Sergey Beryozkin <sb...@gmail.com>
>> wrote:
>> >
>> > Hi
>> >
>> > On Fri, Nov 5, 2010 at 2:21 PM, Jason Pell <ja...@pellcorp.com> wrote:
>> >
>> > > Hi,
>> > >
>> > > I am struggling with configuring CXF and spring security.  I am running
>> the
>> > > 2.3.1-SNAPSHOT which has some improvements to the WSS4JInInterceptor.
>>  So
>> > > basically what I have is a JAX-WS service using ws-security to
>> authenticate
>> > > using username password token.  The username is the uid= of the DN of a
>> > > user
>> > > record in LDAP.
>> > >
>> > > What I want is for the Principal saved into teh CXF SecurityContext to
>> have
>> > > the Full DN of the user.
>> > >
>> > > So what I have setup by way of interceptors are:
>> > >
>> > > org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor
>> > > (ws-security.ut.no-callbacks = true)
>> > > I have a custom class which extends
>> > > org.apache.cxf.interceptor.security.AbstractUsernameTokenInInterceptor
>> to
>> > > use spring security to create the Subject.  I am creating a subject
>> with
>> > > the
>> > > full DN of the user.
>> > >
>> > > However the
>> > >
>> org.apache.cxf.interceptor.security.AbstractSecurityContextInInterceptor
>> > > ignores this and recreates the SecurityContext with the original
>> username
>> > >
>> > > SecurityContext sc = createSecurityContext(context.getUserPrincipal(),
>> > > subject);
>> > >
>> > >
>> > the assumption was that the Principal created by WSS4J initially does
>> > represent the final/correct Principal.
>> > So may be the interceptor should be updated like this :
>> >
>> > List<?> principals = subject.getPrincipals();
>> >
>> > Principal p = principals.size() > 0 && !(principals.get(0) instanceof
>> Group)
>> >
>> >                      ? (Principal)principals.get(0) :
>> > context.getUserPrincipal();
>> >
>> > SecurityContext sc = createSecurityContext(p, subject);
>> >
>> > something like that...
>> >
>> > What do you think ?
>> >
>> > cheers, Sergey
>> >
>> >
>> > So I am kind of up the creek without any kind of paddle :-)
>> > >
>> > > Any suggestions for how I might proceed.  I guess I can always create
>> my
>> > > own
>> > > interceptor from scratch to do this.  I already did the same thing to
>> > > populate the full DN of groups.
>> > >
>>
>

Re: Authentication in cxf and getting the full DN into the Principal

Posted by Sergey Beryozkin <sb...@gmail.com>.
Hi

On Fri, Nov 5, 2010 at 9:48 PM, Jason Pell <ja...@pellcorp.com> wrote:

> Hi,
>
> ...
> Also while I have your attention.  I was confused as to why the
> changes to WSS4JInInterceptor for ws-security.ut.no-callbacks do not
> support direct configuration of the interceptor (I noted this perhaps
> incorrectly on the CXF-3063 patch).
>
> I updated locally to be:
>
>        //boolean utWithCallbacks =
>        //    !MessageUtils.getContextualBoolean(msg,
> SecurityConstants.USERNAME_TOKEN_NO_CALLBACKS, false);
>
>        // allows it to be set from a spring bean interceptor or
> jaxws:property
>        boolean utWithCallbacks =
> !MessageUtils.isTrue(getProperty(msg,
> SecurityConstants.USERNAME_TOKEN_NO_CALLBACKS));
>
> Which allowed me to create an interceptor like so:
>
> <bean id="WSS4JInInterceptor"
>                class="org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor">
>                <constructor-arg>
>                        <map>
>                                <entry key="action" value="UsernameToken" />
>                                <entry key="passwordType"
> value="PasswordText" />
>                                <entry key="ws-security.ut.no-callbacks"
> value="true" />
>                        </map>
>                </constructor-arg>
>        </bean>
>
> Would love to know if this change can be formalised before 2.3.1 is
> released.
>
>
I started working on this issue after it was reported that extending
WSS4JInInterceptor does not work in wsdl/policy-first cases, where no
explicit configuration of  WSS4JInInterceptor is done. Thus I had to go with
the contextual properties approach... May be we can just combine two boolean
checks ?


> By the way, love the abstraction of the WSS4J from the rest of the
> authorisation very neat
>
> thanks
Sergey


> Thanks
> Jason
>
>
> On Sat, Nov 6, 2010 at 5:22 AM, Sergey Beryozkin <sb...@gmail.com>
> wrote:
> >
> > Hi
> >
> > On Fri, Nov 5, 2010 at 2:21 PM, Jason Pell <ja...@pellcorp.com> wrote:
> >
> > > Hi,
> > >
> > > I am struggling with configuring CXF and spring security.  I am running
> the
> > > 2.3.1-SNAPSHOT which has some improvements to the WSS4JInInterceptor.
>  So
> > > basically what I have is a JAX-WS service using ws-security to
> authenticate
> > > using username password token.  The username is the uid= of the DN of a
> > > user
> > > record in LDAP.
> > >
> > > What I want is for the Principal saved into teh CXF SecurityContext to
> have
> > > the Full DN of the user.
> > >
> > > So what I have setup by way of interceptors are:
> > >
> > > org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor
> > > (ws-security.ut.no-callbacks = true)
> > > I have a custom class which extends
> > > org.apache.cxf.interceptor.security.AbstractUsernameTokenInInterceptor
> to
> > > use spring security to create the Subject.  I am creating a subject
> with
> > > the
> > > full DN of the user.
> > >
> > > However the
> > >
> org.apache.cxf.interceptor.security.AbstractSecurityContextInInterceptor
> > > ignores this and recreates the SecurityContext with the original
> username
> > >
> > > SecurityContext sc = createSecurityContext(context.getUserPrincipal(),
> > > subject);
> > >
> > >
> > the assumption was that the Principal created by WSS4J initially does
> > represent the final/correct Principal.
> > So may be the interceptor should be updated like this :
> >
> > List<?> principals = subject.getPrincipals();
> >
> > Principal p = principals.size() > 0 && !(principals.get(0) instanceof
> Group)
> >
> >                      ? (Principal)principals.get(0) :
> > context.getUserPrincipal();
> >
> > SecurityContext sc = createSecurityContext(p, subject);
> >
> > something like that...
> >
> > What do you think ?
> >
> > cheers, Sergey
> >
> >
> > So I am kind of up the creek without any kind of paddle :-)
> > >
> > > Any suggestions for how I might proceed.  I guess I can always create
> my
> > > own
> > > interceptor from scratch to do this.  I already did the same thing to
> > > populate the full DN of groups.
> > >
>

Re: Authentication in cxf and getting the full DN into the Principal

Posted by Jason Pell <ja...@pellcorp.com>.
Hi,

I think that sounds ok.  My experience is that often the final
principal will differ from the original which is why ldap has a user
dn search attribute to find the actual user principal based on the
initial one.

Also while I have your attention.  I was confused as to why the
changes to WSS4JInInterceptor for ws-security.ut.no-callbacks do not
support direct configuration of the interceptor (I noted this perhaps
incorrectly on the CXF-3063 patch).

I updated locally to be:

        //boolean utWithCallbacks =
        //    !MessageUtils.getContextualBoolean(msg,
SecurityConstants.USERNAME_TOKEN_NO_CALLBACKS, false);

        // allows it to be set from a spring bean interceptor or jaxws:property
        boolean utWithCallbacks =
!MessageUtils.isTrue(getProperty(msg,
SecurityConstants.USERNAME_TOKEN_NO_CALLBACKS));

Which allowed me to create an interceptor like so:

<bean id="WSS4JInInterceptor"
		class="org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor">
		<constructor-arg>
			<map>
				<entry key="action" value="UsernameToken" />
				<entry key="passwordType" value="PasswordText" />
				<entry key="ws-security.ut.no-callbacks" value="true" />
			</map>
		</constructor-arg>
	</bean>

Would love to know if this change can be formalised before 2.3.1 is released.

By the way, love the abstraction of the WSS4J from the rest of the
authorisation very neat

Thanks
Jason


On Sat, Nov 6, 2010 at 5:22 AM, Sergey Beryozkin <sb...@gmail.com> wrote:
>
> Hi
>
> On Fri, Nov 5, 2010 at 2:21 PM, Jason Pell <ja...@pellcorp.com> wrote:
>
> > Hi,
> >
> > I am struggling with configuring CXF and spring security.  I am running the
> > 2.3.1-SNAPSHOT which has some improvements to the WSS4JInInterceptor.  So
> > basically what I have is a JAX-WS service using ws-security to authenticate
> > using username password token.  The username is the uid= of the DN of a
> > user
> > record in LDAP.
> >
> > What I want is for the Principal saved into teh CXF SecurityContext to have
> > the Full DN of the user.
> >
> > So what I have setup by way of interceptors are:
> >
> > org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor
> > (ws-security.ut.no-callbacks = true)
> > I have a custom class which extends
> > org.apache.cxf.interceptor.security.AbstractUsernameTokenInInterceptor to
> > use spring security to create the Subject.  I am creating a subject with
> > the
> > full DN of the user.
> >
> > However the
> > org.apache.cxf.interceptor.security.AbstractSecurityContextInInterceptor
> > ignores this and recreates the SecurityContext with the original username
> >
> > SecurityContext sc = createSecurityContext(context.getUserPrincipal(),
> > subject);
> >
> >
> the assumption was that the Principal created by WSS4J initially does
> represent the final/correct Principal.
> So may be the interceptor should be updated like this :
>
> List<?> principals = subject.getPrincipals();
>
> Principal p = principals.size() > 0 && !(principals.get(0) instanceof Group)
>
>                      ? (Principal)principals.get(0) :
> context.getUserPrincipal();
>
> SecurityContext sc = createSecurityContext(p, subject);
>
> something like that...
>
> What do you think ?
>
> cheers, Sergey
>
>
> So I am kind of up the creek without any kind of paddle :-)
> >
> > Any suggestions for how I might proceed.  I guess I can always create my
> > own
> > interceptor from scratch to do this.  I already did the same thing to
> > populate the full DN of groups.
> >

Re: Authentication in cxf and getting the full DN into the Principal

Posted by Jason Pell <ja...@pellcorp.com>.
>> Do you know what the expected release date of 2.3.1 is?  Whats the
>> normal dev cycle?
>
> I'm thinking the end of Nov or first week in Dec.   Normally, it's about every
> 8 weeks.   However, with 2.3.0 being a ".0", I'm likely to shorten it a couple
> weeks just to get the ".1" out there.   I've had several people not look at
> 2.3.0 just cause of the ".0".
>
> I think next time we'll skip 2.4.0 and go straight to 2.4.1.     :-)
>

Rxcellent timing!  Right when I need it not to be a snapshot - cool.

Re: Authentication in cxf and getting the full DN into the Principal

Posted by Daniel Kulp <dk...@apache.org>.
On Monday 08 November 2010 7:50:10 am Jason Pell wrote:
> Hi,
> 
> The changes look good - Arrays no problem.  I will wait for the maven
> snapshot to come down and clean up my code.  I don't use
> SimplePrincipal myself.  The Spring Framework
> UsernamePasswordAuthenticationToken class implements principal and I
> am using spring security for authentication so I just stick that token
> in as the first token.  I just erase the credentials before putting
> back into the subject.
> 
> For now I only have the time and need for Username password.  In a
> couple of months I will be looking at x.509 certs so might have a look
> then.
> 
> Do you know what the expected release date of 2.3.1 is?  Whats the
> normal dev cycle?

I'm thinking the end of Nov or first week in Dec.   Normally, it's about every 
8 weeks.   However, with 2.3.0 being a ".0", I'm likely to shorten it a couple 
weeks just to get the ".1" out there.   I've had several people not look at 
2.3.0 just cause of the ".0".      

I think next time we'll skip 2.4.0 and go straight to 2.4.1.     :-)     

Dan



> On Mon, Nov 8, 2010 at 10:14 PM, Sergey Beryozkin <sb...@gmail.com> 
wrote:
> > Hi Jason
> > 
> > thanks for experimenting with the new code, there's a chance some
> > signatures and even packages might change before 2.3.1 as it is still a
> > work in progress but hopefully we won't do many more changes...
> > 
> > See more comments inline...
> > 
> > On Fri, Nov 5, 2010 at 10:58 PM, Jason Pell <ja...@pellcorp.com> wrote:
> >> Hi,
> >> 
> >> To test your approach I overrode the
> >> protected SecurityContext createSecurityContext(final Principal p,
> >> final Subject subject) {
> >> 
> >> in my interceptor that extends AbstractUsernameTokenInInterceptor
> >> 
> >> @Override
> >>        protected SecurityContext createSecurityContext(final Principal
> >> p, final Subject subject) {
> >>                 List<Principal> principals = new
> >> ArrayList<Principal>(subject.getPrincipals());
> >> 
> >>                 Principal principal =
> >>                         principals.size() > 0 && !(principals.get(0)
> >> instanceof Group) ?
> >> (Principal) principals.get(0) : p;
> >> 
> >>                return new DefaultSecurityContext(principal, subject);
> >>        }
> >> 
> >> Works very nicely.  In my createSubject method I actually insert the
> >> Authentication class as the first principal and now I can get access
> >> to this class in the WebServiceContext getUserPrincipal() method.
> >> 
> >> Would be great to see this code added to the
> >> AbstractSecurityContextInInterceptor
> > 
> > I committed some changes yesterday :
> > 
> > http://svn.apache.org/viewvc?rev=1032296&view=rev
> > 
> > The only difference I used set.toArray(T[] array), hope you're ok with
> > that
> > 
> > :-). By default, a (1st) principal associated with Subject will be used
> > :in
> > 
> > the SecurityContext, but the original Principal (created by WSS4J) can
> > easily be chosen by overriding a newly introduced
> > AbstractSecurityContextInterceptor.getPrincipal. This default selection
> > will probably make sense in most cases.
> > 
> > While I was committing that change, I thought that in case of
> > UsernameTokens, a (CXF) UsernameToken has all the information for
> > concrete subclasses of
> > AbstractSecurityContextInterceptor/AbstractUsernameTokenInterceptor to
> > easily (re)create a Principal, when creating a Subject. CXF even ships a
> > SimplePrincipal helper which can be used in simple cases.
> > 
> > What I'm not sure about is how it will work with more complex tokens.
> > Basically, I'm thinking that may be
> > 
> > AbstractSecurityContextInterceptor.createSubject(SecurityToken token)
> > 
> > should be changed to
> > 
> > AbstractSecurityContextInterceptor.createSubject(SecurityToken token,
> > Principal originalPrincipal) ?
> > 
> > I don't quite like this change, given that in case of UsernameTokens
> > "Principal originalPrincipal", but may be in case of more complex tokens
> > it would not be easy to 'recreate' a Principal ? So having this 2nd
> > parameter will just let subclasses to ensure Subject has all the right
> > Groups added in but just add the original Principal as a Subject
> > identity ?
> > Not sure, may be I'm just over-complicating things a bit. If we could
> > have one more token added, certificates or binary based, then we'd
> > clearly see what else needs to be updated. If you have cases where other
> > tokens can be used then it would be good if you could try the new
> > approach with those tokens as well...May be David V or Glen can help as
> > well...
> > 
> > Thoughts ?
> > 
> > thanks, Sergey
> > 
> >> Thanks
> >> Jason
> >> 
> >> On Sat, Nov 6, 2010 at 5:22 AM, Sergey Beryozkin <sb...@gmail.com>
> >> 
> >> wrote:
> >> > Hi
> >> > 
> >> > On Fri, Nov 5, 2010 at 2:21 PM, Jason Pell <ja...@pellcorp.com> wrote:
> >> >> Hi,
> >> >> 
> >> >> I am struggling with configuring CXF and spring security.  I am
> >> >> running
> >> 
> >> the
> >> 
> >> >> 2.3.1-SNAPSHOT which has some improvements to the WSS4JInInterceptor.
> >> 
> >>  So
> >> 
> >> >> basically what I have is a JAX-WS service using ws-security to
> >> 
> >> authenticate
> >> 
> >> >> using username password token.  The username is the uid= of the DN of
> >> >> a user
> >> >> record in LDAP.
> >> >> 
> >> >> What I want is for the Principal saved into teh CXF SecurityContext
> >> >> to
> >> 
> >> have
> >> 
> >> >> the Full DN of the user.
> >> >> 
> >> >> So what I have setup by way of interceptors are:
> >> >> 
> >> >> org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor
> >> >> (ws-security.ut.no-callbacks = true)
> >> >> I have a custom class which extends
> >> >> org.apache.cxf.interceptor.security.AbstractUsernameTokenInIntercepto
> >> >> r
> >> 
> >> to
> >> 
> >> >> use spring security to create the Subject.  I am creating a subject
> >> >> with the
> >> >> full DN of the user.
> >> >> 
> >> >> However the
> >> >> org.apache.cxf.interceptor.security.AbstractSecurityContextInIntercep
> >> >> tor ignores this and recreates the SecurityContext with the original
> >> 
> >> username
> >> 
> >> >> SecurityContext sc =
> >> >> createSecurityContext(context.getUserPrincipal(), subject);
> >> > 
> >> > the assumption was that the Principal created by WSS4J initially does
> >> > represent the final/correct Principal.
> >> > So may be the interceptor should be updated like this :
> >> > 
> >> > List<?> principals = subject.getPrincipals();
> >> > 
> >> > Principal p = principals.size() > 0 && !(principals.get(0) instanceof
> >> 
> >> Group)
> >> 
> >> >                      ? (Principal)principals.get(0) :
> >> > context.getUserPrincipal();
> >> > 
> >> > SecurityContext sc = createSecurityContext(p, subject);
> >> > 
> >> > something like that...
> >> > 
> >> > What do you think ?
> >> > 
> >> > cheers, Sergey
> >> > 
> >> > 
> >> > So I am kind of up the creek without any kind of paddle :-)
> >> > 
> >> >> Any suggestions for how I might proceed.  I guess I can always create
> >> >> my own
> >> >> interceptor from scratch to do this.  I already did the same thing to
> >> >> populate the full DN of groups.

-- 
Daniel Kulp
dkulp@apache.org
http://dankulp.com/blog

Re: Authentication in cxf and getting the full DN into the Principal

Posted by Jason Pell <ja...@pellcorp.com>.
Hi,

The changes look good - Arrays no problem.  I will wait for the maven
snapshot to come down and clean up my code.  I don't use
SimplePrincipal myself.  The Spring Framework
UsernamePasswordAuthenticationToken class implements principal and I
am using spring security for authentication so I just stick that token
in as the first token.  I just erase the credentials before putting
back into the subject.

For now I only have the time and need for Username password.  In a
couple of months I will be looking at x.509 certs so might have a look
then.

Do you know what the expected release date of 2.3.1 is?  Whats the
normal dev cycle?

On Mon, Nov 8, 2010 at 10:14 PM, Sergey Beryozkin <sb...@gmail.com> wrote:
> Hi Jason
>
> thanks for experimenting with the new code, there's a chance some signatures
> and even packages might change before 2.3.1 as it is still a work in
> progress but hopefully we won't do many more changes...
>
> See more comments inline...
>
> On Fri, Nov 5, 2010 at 10:58 PM, Jason Pell <ja...@pellcorp.com> wrote:
>
>> Hi,
>>
>> To test your approach I overrode the
>> protected SecurityContext createSecurityContext(final Principal p,
>> final Subject subject) {
>>
>> in my interceptor that extends AbstractUsernameTokenInInterceptor
>>
>> @Override
>>        protected SecurityContext createSecurityContext(final Principal p,
>> final Subject subject) {
>>                 List<Principal> principals = new
>> ArrayList<Principal>(subject.getPrincipals());
>>
>>                 Principal principal =
>>                         principals.size() > 0 && !(principals.get(0)
>> instanceof Group) ?
>> (Principal) principals.get(0) : p;
>>
>>                return new DefaultSecurityContext(principal, subject);
>>        }
>>
>> Works very nicely.  In my createSubject method I actually insert the
>> Authentication class as the first principal and now I can get access
>> to this class in the WebServiceContext getUserPrincipal() method.
>>
>> Would be great to see this code added to the
>> AbstractSecurityContextInInterceptor
>>
>>
> I committed some changes yesterday :
>
> http://svn.apache.org/viewvc?rev=1032296&view=rev
>
> The only difference I used set.toArray(T[] array), hope you're ok with that
> :-). By default, a (1st) principal associated with Subject will be used in
> the SecurityContext, but the original Principal (created by WSS4J) can
> easily be chosen by overriding a newly introduced
> AbstractSecurityContextInterceptor.getPrincipal. This default selection will
> probably make sense in most cases.
>
> While I was committing that change, I thought that in case of
> UsernameTokens, a (CXF) UsernameToken has all the information for concrete
> subclasses of
> AbstractSecurityContextInterceptor/AbstractUsernameTokenInterceptor to
> easily (re)create a Principal, when creating a Subject. CXF even ships a
> SimplePrincipal helper which can be used in simple cases.
>
> What I'm not sure about is how it will work with more complex tokens.
> Basically, I'm thinking that may be
>
> AbstractSecurityContextInterceptor.createSubject(SecurityToken token)
>
> should be changed to
>
> AbstractSecurityContextInterceptor.createSubject(SecurityToken token,
> Principal originalPrincipal) ?
>
> I don't quite like this change, given that in case of UsernameTokens
> "Principal originalPrincipal", but may be in case of more complex tokens it
> would not be easy to 'recreate' a Principal ? So having this 2nd parameter
> will just let subclasses to ensure Subject has all the right Groups added in
> but just add the original Principal as a Subject identity ?
> Not sure, may be I'm just over-complicating things a bit. If we could have
> one more token added, certificates or binary based, then we'd clearly see
> what else needs to be updated. If you have cases where other tokens can be
> used then it would be good if you could try the new approach with those
> tokens as well...May be David V or Glen can help as well...
>
> Thoughts ?
>
> thanks, Sergey
>
>
>
>> Thanks
>> Jason
>>
>> On Sat, Nov 6, 2010 at 5:22 AM, Sergey Beryozkin <sb...@gmail.com>
>> wrote:
>> > Hi
>> >
>> > On Fri, Nov 5, 2010 at 2:21 PM, Jason Pell <ja...@pellcorp.com> wrote:
>> >
>> >> Hi,
>> >>
>> >> I am struggling with configuring CXF and spring security.  I am running
>> the
>> >> 2.3.1-SNAPSHOT which has some improvements to the WSS4JInInterceptor.
>>  So
>> >> basically what I have is a JAX-WS service using ws-security to
>> authenticate
>> >> using username password token.  The username is the uid= of the DN of a
>> >> user
>> >> record in LDAP.
>> >>
>> >> What I want is for the Principal saved into teh CXF SecurityContext to
>> have
>> >> the Full DN of the user.
>> >>
>> >> So what I have setup by way of interceptors are:
>> >>
>> >> org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor
>> >> (ws-security.ut.no-callbacks = true)
>> >> I have a custom class which extends
>> >> org.apache.cxf.interceptor.security.AbstractUsernameTokenInInterceptor
>> to
>> >> use spring security to create the Subject.  I am creating a subject with
>> >> the
>> >> full DN of the user.
>> >>
>> >> However the
>> >> org.apache.cxf.interceptor.security.AbstractSecurityContextInInterceptor
>> >> ignores this and recreates the SecurityContext with the original
>> username
>> >>
>> >> SecurityContext sc = createSecurityContext(context.getUserPrincipal(),
>> >> subject);
>> >>
>> >>
>> > the assumption was that the Principal created by WSS4J initially does
>> > represent the final/correct Principal.
>> > So may be the interceptor should be updated like this :
>> >
>> > List<?> principals = subject.getPrincipals();
>> >
>> > Principal p = principals.size() > 0 && !(principals.get(0) instanceof
>> Group)
>> >
>> >                      ? (Principal)principals.get(0) :
>> > context.getUserPrincipal();
>> >
>> > SecurityContext sc = createSecurityContext(p, subject);
>> >
>> > something like that...
>> >
>> > What do you think ?
>> >
>> > cheers, Sergey
>> >
>> >
>> > So I am kind of up the creek without any kind of paddle :-)
>> >>
>> >> Any suggestions for how I might proceed.  I guess I can always create my
>> >> own
>> >> interceptor from scratch to do this.  I already did the same thing to
>> >> populate the full DN of groups.
>> >>
>> >
>>
>

Re: Authentication in cxf and getting the full DN into the Principal

Posted by Sergey Beryozkin <sb...@gmail.com>.
Hi Jason

thanks for experimenting with the new code, there's a chance some signatures
and even packages might change before 2.3.1 as it is still a work in
progress but hopefully we won't do many more changes...

See more comments inline...

On Fri, Nov 5, 2010 at 10:58 PM, Jason Pell <ja...@pellcorp.com> wrote:

> Hi,
>
> To test your approach I overrode the
> protected SecurityContext createSecurityContext(final Principal p,
> final Subject subject) {
>
> in my interceptor that extends AbstractUsernameTokenInInterceptor
>
> @Override
>        protected SecurityContext createSecurityContext(final Principal p,
> final Subject subject) {
>                 List<Principal> principals = new
> ArrayList<Principal>(subject.getPrincipals());
>
>                 Principal principal =
>                         principals.size() > 0 && !(principals.get(0)
> instanceof Group) ?
> (Principal) principals.get(0) : p;
>
>                return new DefaultSecurityContext(principal, subject);
>        }
>
> Works very nicely.  In my createSubject method I actually insert the
> Authentication class as the first principal and now I can get access
> to this class in the WebServiceContext getUserPrincipal() method.
>
> Would be great to see this code added to the
> AbstractSecurityContextInInterceptor
>
>
I committed some changes yesterday :

http://svn.apache.org/viewvc?rev=1032296&view=rev

The only difference I used set.toArray(T[] array), hope you're ok with that
:-). By default, a (1st) principal associated with Subject will be used in
the SecurityContext, but the original Principal (created by WSS4J) can
easily be chosen by overriding a newly introduced
AbstractSecurityContextInterceptor.getPrincipal. This default selection will
probably make sense in most cases.

While I was committing that change, I thought that in case of
UsernameTokens, a (CXF) UsernameToken has all the information for concrete
subclasses of
AbstractSecurityContextInterceptor/AbstractUsernameTokenInterceptor to
easily (re)create a Principal, when creating a Subject. CXF even ships a
SimplePrincipal helper which can be used in simple cases.

What I'm not sure about is how it will work with more complex tokens.
Basically, I'm thinking that may be

AbstractSecurityContextInterceptor.createSubject(SecurityToken token)

should be changed to

AbstractSecurityContextInterceptor.createSubject(SecurityToken token,
Principal originalPrincipal) ?

I don't quite like this change, given that in case of UsernameTokens
"Principal originalPrincipal", but may be in case of more complex tokens it
would not be easy to 'recreate' a Principal ? So having this 2nd parameter
will just let subclasses to ensure Subject has all the right Groups added in
but just add the original Principal as a Subject identity ?
Not sure, may be I'm just over-complicating things a bit. If we could have
one more token added, certificates or binary based, then we'd clearly see
what else needs to be updated. If you have cases where other tokens can be
used then it would be good if you could try the new approach with those
tokens as well...May be David V or Glen can help as well...

Thoughts ?

thanks, Sergey



> Thanks
> Jason
>
> On Sat, Nov 6, 2010 at 5:22 AM, Sergey Beryozkin <sb...@gmail.com>
> wrote:
> > Hi
> >
> > On Fri, Nov 5, 2010 at 2:21 PM, Jason Pell <ja...@pellcorp.com> wrote:
> >
> >> Hi,
> >>
> >> I am struggling with configuring CXF and spring security.  I am running
> the
> >> 2.3.1-SNAPSHOT which has some improvements to the WSS4JInInterceptor.
>  So
> >> basically what I have is a JAX-WS service using ws-security to
> authenticate
> >> using username password token.  The username is the uid= of the DN of a
> >> user
> >> record in LDAP.
> >>
> >> What I want is for the Principal saved into teh CXF SecurityContext to
> have
> >> the Full DN of the user.
> >>
> >> So what I have setup by way of interceptors are:
> >>
> >> org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor
> >> (ws-security.ut.no-callbacks = true)
> >> I have a custom class which extends
> >> org.apache.cxf.interceptor.security.AbstractUsernameTokenInInterceptor
> to
> >> use spring security to create the Subject.  I am creating a subject with
> >> the
> >> full DN of the user.
> >>
> >> However the
> >> org.apache.cxf.interceptor.security.AbstractSecurityContextInInterceptor
> >> ignores this and recreates the SecurityContext with the original
> username
> >>
> >> SecurityContext sc = createSecurityContext(context.getUserPrincipal(),
> >> subject);
> >>
> >>
> > the assumption was that the Principal created by WSS4J initially does
> > represent the final/correct Principal.
> > So may be the interceptor should be updated like this :
> >
> > List<?> principals = subject.getPrincipals();
> >
> > Principal p = principals.size() > 0 && !(principals.get(0) instanceof
> Group)
> >
> >                      ? (Principal)principals.get(0) :
> > context.getUserPrincipal();
> >
> > SecurityContext sc = createSecurityContext(p, subject);
> >
> > something like that...
> >
> > What do you think ?
> >
> > cheers, Sergey
> >
> >
> > So I am kind of up the creek without any kind of paddle :-)
> >>
> >> Any suggestions for how I might proceed.  I guess I can always create my
> >> own
> >> interceptor from scratch to do this.  I already did the same thing to
> >> populate the full DN of groups.
> >>
> >
>

Re: Authentication in cxf and getting the full DN into the Principal

Posted by Jason Pell <ja...@pellcorp.com>.
Hi,

To test your approach I overrode the
protected SecurityContext createSecurityContext(final Principal p,
final Subject subject) {

in my interceptor that extends AbstractUsernameTokenInInterceptor

@Override
	protected SecurityContext createSecurityContext(final Principal p,
final Subject subject) {
		List<Principal> principals = new
ArrayList<Principal>(subject.getPrincipals());
		
		Principal principal =
			principals.size() > 0 && !(principals.get(0) instanceof Group) ?
(Principal) principals.get(0) : p;

		return new DefaultSecurityContext(principal, subject);
	}

Works very nicely.  In my createSubject method I actually insert the
Authentication class as the first principal and now I can get access
to this class in the WebServiceContext getUserPrincipal() method.

Would be great to see this code added to the
AbstractSecurityContextInInterceptor

Thanks
Jason

On Sat, Nov 6, 2010 at 5:22 AM, Sergey Beryozkin <sb...@gmail.com> wrote:
> Hi
>
> On Fri, Nov 5, 2010 at 2:21 PM, Jason Pell <ja...@pellcorp.com> wrote:
>
>> Hi,
>>
>> I am struggling with configuring CXF and spring security.  I am running the
>> 2.3.1-SNAPSHOT which has some improvements to the WSS4JInInterceptor.  So
>> basically what I have is a JAX-WS service using ws-security to authenticate
>> using username password token.  The username is the uid= of the DN of a
>> user
>> record in LDAP.
>>
>> What I want is for the Principal saved into teh CXF SecurityContext to have
>> the Full DN of the user.
>>
>> So what I have setup by way of interceptors are:
>>
>> org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor
>> (ws-security.ut.no-callbacks = true)
>> I have a custom class which extends
>> org.apache.cxf.interceptor.security.AbstractUsernameTokenInInterceptor to
>> use spring security to create the Subject.  I am creating a subject with
>> the
>> full DN of the user.
>>
>> However the
>> org.apache.cxf.interceptor.security.AbstractSecurityContextInInterceptor
>> ignores this and recreates the SecurityContext with the original username
>>
>> SecurityContext sc = createSecurityContext(context.getUserPrincipal(),
>> subject);
>>
>>
> the assumption was that the Principal created by WSS4J initially does
> represent the final/correct Principal.
> So may be the interceptor should be updated like this :
>
> List<?> principals = subject.getPrincipals();
>
> Principal p = principals.size() > 0 && !(principals.get(0) instanceof Group)
>
>                      ? (Principal)principals.get(0) :
> context.getUserPrincipal();
>
> SecurityContext sc = createSecurityContext(p, subject);
>
> something like that...
>
> What do you think ?
>
> cheers, Sergey
>
>
> So I am kind of up the creek without any kind of paddle :-)
>>
>> Any suggestions for how I might proceed.  I guess I can always create my
>> own
>> interceptor from scratch to do this.  I already did the same thing to
>> populate the full DN of groups.
>>
>

Re: Authentication in cxf and getting the full DN into the Principal

Posted by Sergey Beryozkin <sb...@gmail.com>.
Hi

On Fri, Nov 5, 2010 at 2:21 PM, Jason Pell <ja...@pellcorp.com> wrote:

> Hi,
>
> I am struggling with configuring CXF and spring security.  I am running the
> 2.3.1-SNAPSHOT which has some improvements to the WSS4JInInterceptor.  So
> basically what I have is a JAX-WS service using ws-security to authenticate
> using username password token.  The username is the uid= of the DN of a
> user
> record in LDAP.
>
> What I want is for the Principal saved into teh CXF SecurityContext to have
> the Full DN of the user.
>
> So what I have setup by way of interceptors are:
>
> org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor
> (ws-security.ut.no-callbacks = true)
> I have a custom class which extends
> org.apache.cxf.interceptor.security.AbstractUsernameTokenInInterceptor to
> use spring security to create the Subject.  I am creating a subject with
> the
> full DN of the user.
>
> However the
> org.apache.cxf.interceptor.security.AbstractSecurityContextInInterceptor
> ignores this and recreates the SecurityContext with the original username
>
> SecurityContext sc = createSecurityContext(context.getUserPrincipal(),
> subject);
>
>
the assumption was that the Principal created by WSS4J initially does
represent the final/correct Principal.
So may be the interceptor should be updated like this :

List<?> principals = subject.getPrincipals();

Principal p = principals.size() > 0 && !(principals.get(0) instanceof Group)

                      ? (Principal)principals.get(0) :
context.getUserPrincipal();

SecurityContext sc = createSecurityContext(p, subject);

something like that...

What do you think ?

cheers, Sergey


So I am kind of up the creek without any kind of paddle :-)
>
> Any suggestions for how I might proceed.  I guess I can always create my
> own
> interceptor from scratch to do this.  I already did the same thing to
> populate the full DN of groups.
>