cxf-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Sergey Beryozkin <sberyoz...@gmail.com>
Subject Re: Using WS-Security UsernameToken to authenticate users and populate SecurityContexts
Date Mon, 19 Apr 2010 13:14:09 GMT
By the way, the idea (suggested by Dan) to have WSS4J not doing
UsernameToken processing still works with the proposed patch. But I'd rather
have a NoopProcessor added to CXF and registered with WSS4J when needed to
delegate the processing of token/actions to  interceptors like
UsernameTokenInterceptor...

thanks, Sergey

On Mon, Apr 19, 2010 at 1:46 PM, Sergey Beryozkin <sberyozkin@gmail.com>wrote:

> Hi
>
> I've added an initial patch for addressing a policy-first case, see [1].
> It's a patch because it depends on another one I submitted to WSS4J [2].
> Both patches need more work (tests, etc) but I'd just like to initiate a
> discussion/review.
>
> The idea behind [1] is quite similar to the one used in supporting a
> java-first case, where a custom interceptor extends an
> AbstractWSS4JSecurityContextPr
> oviding interceptor. But is is much simpler in [1] where
> UsernameTokenProcessor may be optionally extended and its createSubject
> method be overridden. Provided [2] gets applied then a subclass will just
> have a property set disabling the (WSS4J) validation of passwords and will
> do its own validation in createSubject method.
>
> This is really all what will be needed in simple cases, where a
> DefaultSecurityContext will do, but optionally, createSecurityContext  can
> be overridden too.
>
> A user would need to set a bus property
> "org.apache.cxf.ws.security.usernametoken.interceptor" referincing a custom
> interceptor which will indicate to the WSSecurityPolicyLoader that a custom
> UsernameTokenProcessor subclass will need to be loaded.
>
> Similar approach can be employed for handling other types of tokens.
>
> cheers, Sergey
>
> [1] https://issues.apache.org/jira/browse/CXF-2754
> [2] https://issues.apache.org/jira/browse/WSS-229
>
>
> On Mon, Apr 19, 2010 at 1:43 PM, Sergey Beryozkin <sberyozkin@gmail.com>wrote:
>
>> Just realized I did not CC tp dev when replying to Dan the other day :
>>
>> Hi Dan
>>
>>
>> On Fri, Apr 9, 2010 at 2:50 PM, Daniel Kulp <dkulp@apache.org> wrote:
>>
>>>
>>> My main "concern" with the implementation of this is that it's done as a
>>> direct subclass of the WSS4JInInterceptor and thus not really usable by
>>> the
>>> policy based endpoints as those interceptors subclass WSS4JInInterceptor
>>> as
>>> well.
>>>
>>> I think the better approach may be to add a flag to wss4j (I can help
>>> commit
>>> changes there if needed) to have it not do any UserName token processing
>>> at
>>> all.   (aside:  this may be doable without changes to wss4j by
>>> registering our
>>> own "do nothing processor")    Then, have another interceptor that runs
>>> after
>>> the WSS4JInInterceptor that would actually handle the UsernameToken and
>>> verify
>>> anything it needs and such.
>>>
>>
>> This sounds like a very good idea, I agree the proposed approach won't do
>> for the cases where policies drive the
>> creation of interceptors.
>>
>> Having said that, I think the abstract utility interceptor extending
>> WSS4JInInterceptor
>> may still be used in cases where users start from manually configuring
>> jaxws endpoints. In these cases they'd need to
>> list up to 3 interceptors (the one which extends
>> AbstractWSS4JSecuriyContextInterceptor, the authorizing interceptor if the
>> authorization is needed plus may be a SAAJ one) but otherwise, when say a
>> clear text password has been encrypted, they'd still need to specify
>> WSS4JInInterceptor (with a flag disabling UsernameToken checks) plus
>> UsernameTokenInterceptor, etc.
>>
>> At the moment AbstractWSS4JSecuriyContextInterceptor is a bit complicated
>> due to the fact it blocks the WSS4J digest checks and thus also creates a
>> security engine per every request, but it all will be gone in due time...
>>
>>
>>>
>>> To be honest, I WANT to do this for the Policy based stuff anyway.
>>> There is
>>> currently some duplicated code between the PolicyBasedWSS4JIinInterceptor
>>> and
>>> the new UsernameTokenInterceptor that could be eliminated by having the
>>> PolicyBasedWSS4JIinInterceptor not do UsernameTokens at all and delegate
>>> that
>>> completely to the UsernameTokenInterceptor.
>>>
>>
>> What I will do is I will experiment with the test you added (thanks :-))
>> and see how UsernameTokenInterceptor can be refactored
>> so that a subclass can get an easy access to password, nonce, etc. I think
>> I will need to come up with a contextual property so that a custom
>> UsernameTokenInterceptor can be installed if needed. Or may be
>> UsernameTokenInterceptor can store the details in a message to be later
>> retrieved and processed for creating SecurityContext - but I'm not sure
>> about it just yet.
>>
>>
>>>
>>> Basically, it would be good if the WSS4JIn* stuff just handled the
>>> encryption/signature stuff and then let the authorization validations
>>> stuff to
>>> later interceptors.   That would include things like key validation
>>> checking
>>> and stuff as well.  Probably SAML token validation as well.
>>>
>>>
>> sounds good
>>
>> cheers, Sergey
>>
>> On Fri, Apr 9, 2010 at 2:50 PM, Daniel Kulp <dkulp@apache.org> wrote:
>>
>>>
>>> My main "concern" with the implementation of this is that it's done as a
>>> direct subclass of the WSS4JInInterceptor and thus not really usable by
>>> the
>>> policy based endpoints as those interceptors subclass WSS4JInInterceptor
>>> as
>>> well.
>>>
>>> I think the better approach may be to add a flag to wss4j (I can help
>>> commit
>>> changes there if needed) to have it not do any UserName token processing
>>> at
>>> all.   (aside:  this may be doable without changes to wss4j by
>>> registering our
>>> own "do nothing processor")    Then, have another interceptor that runs
>>> after
>>> the WSS4JInInterceptor that would actually handle the UsernameToken and
>>> verify
>>> anything it needs and such.
>>>
>>> To be honest, I WANT to do this for the Policy based stuff anyway.
>>> There is
>>> currently some duplicated code between the PolicyBasedWSS4JIinInterceptor
>>> and
>>> the new UsernameTokenInterceptor that could be eliminated by having the
>>> PolicyBasedWSS4JIinInterceptor not do UsernameTokens at all and delegate
>>> that
>>> completely to the UsernameTokenInterceptor.
>>>
>>> Basically, it would be good if the WSS4JIn* stuff just handled the
>>> encryption/signature stuff and then let the authorization validations
>>> stuff to
>>> later interceptors.   That would include things like key validation
>>> checking
>>> and stuff as well.  Probably SAML token validation as well.
>>>
>>> Dan
>>>
>>>
>>> On Thursday 08 April 2010 12:09:24 pm Sergey Beryozkin wrote:
>>> > Hi David
>>> >
>>> > thanks for the comments...
>>> >
>>> > On Wed, Apr 7, 2010 at 9:41 PM, David Valeri <dvaleri@apache.org>
>>> wrote:
>>> > > Sergey,
>>> > >
>>> > > I think this type of functionality would be very useful to a number
>>> of
>>> > > folks.  I have built two similar capabilities for clients very
>>> recently
>>> > > using CXF and Spring Security.  Based on the code provided below, I
>>> have
>>> > > several points that I would like to see addressed in a solution.
>>> > >
>>> > > 1) Architecture to support more than just UsernameTokens.  I have
>>> worked
>>> > > with systems that need to authenticate a user using UsernameTokens,
>>> > > BinarySecurityTokens, SAML Assertions, and a combination of more than
>>> one
>>> > > of
>>> > > these at a time.
>>> >
>>> > Supporting UsernameTokens is the initial requirement. At the moment I
>>> do
>>> > not even know how BinarySecurityTokens or SAML Assertions are
>>> > processed/validated in CXF or WSS4J.
>>> >
>>> > > For the most part, WSS4J simply validates the structural
>>> > > details of security.  That is, signature validity, trust chaining of
>>> > > digital
>>> > > certificates, etc.  As Glen pointed out with his reference to
>>> > > https://issues.apache.org/jira/browse/WSS-183, WSS4J sometimes
>>> performs
>>> > > its
>>> > > own password checking (authentication).  Unfortunately, WSS4J doesn't
>>> > > provide hooks for authenticating other forms of credentials that I
>>> have
>>> > > listed above (I don't consider trust to be equivalent to
>>> authentication).
>>> > > It would be best if the authentication interface supported multiple
>>> > > credential types and allowed for authentication to be performed in
a
>>> > > single location in the same manner every time (not sometimes in the
>>> > > WSS4J callback and sometimes in another interceptor for non-UT based
>>> > > credentials).
>>> >
>>> > Makes sense. Assuming it is WSS4J which validates (the structure of)
>>> > BinarySecurityTokens then
>>>  AbstractWSS4JSecurityContextProvidingInterceptor
>>> > can also implement a processor for BinarySecurityTokens and delegate to
>>> > subclass to authenticate and setup a subject. Some extra methods will
>>> need
>>> > to be added, to be optionally overridden.
>>> >
>>> > If it is not only WSS4J which is involved then perhaps another option
>>> is to
>>> > store (from WSS4J callback handler, etc) relevant details such username
>>> > token details, etc to be acted upon by other interceptors.
>>> >
>>> > > That
>>> > > last bit there means disabling WSS4J's password authentication since
>>> it
>>> > > gets
>>> > > in the way of doing it later in our own interceptor.
>>> >
>>> > AbstractWSS4JSecurityContextProvidingInterceptor does it now by
>>> > implementing a simplified UsernameTokenProcessor
>>> >
>>> > > 2) Allow for end-user flexibility in choosing the credentials they
>>> want
>>> > > to authenticate.  For instance, each user is going to have their own
>>> > > security profiles and authentication requirements.  For instance, a
>>> > > message contains a UT for a portal user and a digital signature from
>>> the
>>> > > portal (I know using
>>> > > a SAML Assertion would be better here, but people still do it this
>>> way).
>>> > > Each organization will have different requirements as to which
>>> > > credentials get authenticated and what needs to end up in the
>>> security
>>> > > context.
>>> >
>>> > I suppose AbstractWSS4JSecurityContextProvidingInterceptor subclasses
>>> > should be able to do it, for username tokens and other tokens later on.
>>> >
>>> > > 3) Decouple the authentication interface from WSS4J.  What is passed
>>> in
>>> > > needs to be abstracted enough that it can work with other WS-Security
>>> > > libraries as well.
>>> >
>>> > the only WSS4J class which is leaked at the moment is
>>> WSSecurityException.
>>> > Perhaps we can come up later on with a different more generic approach
>>> > which does not depend on WSS4J at all. As Dan indicated, in some cases
>>> > WSS4JInInterceptor is not even used, so that case will need to be
>>> > addressed. Experimenting wuth binary tokens might help with identifying
>>> > another solution.
>>> >
>>> > > 4) It would be nice to be able to perform authorization using
>>> something
>>> > > like
>>> > > Spring Security at the service operation level.  With a POJO or
>>> JAX-WS
>>> > > based
>>> > > service, one can just use Spring Security's method interceptor to
>>> provide
>>> > > such security; however, in situations where one only has a WSDL based
>>> > > service or a provider style service, a method interceptor can't be
>>> used.
>>> > >
>>> > >  It
>>> > >
>>> > > would be nice to provide a hook into Spring Security to allow
>>> end-users
>>> > > to specify role based authorization policy based on a combination of
>>> > > interface,
>>> > > instance, and operation names.  It seems like your
>>> > > AbstractAuthorizingInterceptor and SimpleAuthorizingInterceptor are
>>> > > looking in this direction, but I think it would be best if we can
>>> stand
>>> > > on the shoulders of the Spring Security giant as much as possible so
>>> > > that we can take advantage of their rich authorization manager,
>>> voter,
>>> > > XML
>>> > > configuration
>>> > > capabilities.
>>> >
>>> > Not sure what to say here yet. But I think non-Spring users should be
>>> taken
>>> > care of too. Or when simpler cases are dealt with then perhaps there's
>>> no
>>> > need to bring in Spring security. Perhaps the utility authorization
>>> > interceptors should just not be used when Spring Security is preferred
>>> ?
>>> >
>>> > > 5) Try not to leave the ServiceMix CXF-BC out in the cold.  The
>>> CXF-BC
>>> > > currently has a limited capability to select the credentials to
>>> > > authenticate
>>> > > and would benefit from 1 and 2 above.  The CXF-BC ultimately
>>> delegates
>>> > > authentication to the JBI container through a ServiceMix components
>>> > > authentication service abstraction of JAAS.  Whatever solution we
>>> have
>>> > > for 1
>>> > > and 2 would help out the component if the ServiceMix authentication
>>> > > service abstraction could be wired up in lieu of whatever we provide
>>> out
>>> > > of the box.
>>> >
>>> > I'm not planning to contribute to ServiceMix. I agree though that an
>>> ideal
>>> > solution will meet multiple requirements
>>> >
>>> > thanks, Sergey
>>> >
>>> > > -----Original Message-----
>>> > > From: Sergey Beryozkin [mailto:sberyozkin@gmail.com]
>>> > > Sent: Wednesday, April 07, 2010 10:11 AM
>>> > > To: dev@cxf.apache.org
>>> > > Subject: Using WS-Security UsernameToken to authenticate users and
>>> > > populate SecurityContexts
>>> > >
>>> > > Hi
>>> > >
>>> > > I've been looking recently at extending the CXF WS-Security component
>>> > > such that a current UsernameToken could be used by custom
>>> interceptors
>>> > > to authenticate a user with the external security systems and, if
>>> > > possible, provide enough information for CXF to populate a
>>> > > SecurityContext [1] to be used later on for
>>> > > authorization decisions.
>>> > >
>>> > > Here is the approach I've taken so far.
>>> > > A custom interceptor extends
>>> > > AbstractWSS4JSecurityContextProvidingInterceptor [2] and the only
>>> method
>>> > > it overrides is
>>> > >
>>> > > abstract Subject createSubject(String name, String password, boolean
>>> > > isDigest,
>>> > >
>>> > >                                    String nonce,
>>> > >                                    String created) throws
>>> > >
>>> > > WSSecurityException;
>>> > >
>>> > >
>>> > > For example, see [3].
>>> > >
>>> > > The idea here is that a custom interceptor interfaces whichever way
>>> it
>>> > > needs
>>> > > to with the external system and populates a Subject following this
>>> simple
>>> > > rule : first Subject principal is the current user (identified by a
>>> > > 'name' argument), followed by one or more Groups this user is a
>>> member
>>> > > of. AbstractWSS4JSecurityContextProvidingInterceptor will use this
>>> > > Subject to provide a functional SecurityContext instance.
>>> > >
>>> > > This is the first part, next is how to utilize a SecurityContext and
>>> get
>>> > > the
>>> > > expected roles associated one way or the other with a current method
>>> to
>>> > > be invoked. There's a number of usual options available here, perhaps
>>> > > even SpringSecurity can be used now that SecurityContext is
>>> available,
>>> > > or application code or other custom CXF interceptor can check the
>>> known
>>> > > roles against SecurityContext.
>>> > >
>>> > > I've also added AbstractAuthorizingInInterceptor interceptor which
>>> custom
>>> > > interceptors can override and return a list of expected roles given
a
>>> > > (service) Method to be invoked upon, AbstractAuthorizingInInterceptor
>>> > > will then ask available SecurityContext to match the roles; one
>>> concrete
>>> > > implementation is SimpleAuthorizingInterceptor[5], it can be injected
>>> > > with a
>>> > > method specific or class (applying to all methods) roles. Another
>>> > > implementation which I will likely add later on will be injected with
>>> a
>>> > > name
>>> > > of annotation such as RolesAlloved and it will introspect a method
>>> and
>>> > > its class.
>>> > >
>>> > > Note that I haven't looked into the case when a policy runtimes adds
>>> the
>>> > > interceptors yet (as opposed to interceptors being configured form
>>> > > Spring/programmatically). I think an optional contextual property
>>> will
>>> > > need to be setup in such cases for users be able to indicate that say
>>> an
>>> > > interceptor such as [3] has to be used as opposed to
>>> WSS4JInInterceptor,
>>> > > etc.
>>> > >
>>> > > I'm going to validate this approach with JBoss CXF. If you have any
>>> > > comments
>>> > > then please let me know.
>>> > >
>>> > > I think we may have a simpler alternative eventually to the way
>>> > > authorization decisions are made. [1]-[3] is specific to ws-security,
>>> but
>>> > > [4]-[5] is not
>>> > >
>>> > > cheers, Sergey
>>> > >
>>> > > [1] https://issues.apache.org/jira/browse/CXF-2754
>>> > > [2]
>>> > >
>>> > >
>>> http://svn.apache.org/repos/asf/cxf/trunk/rt/ws/security/src/main/java/or
>>> > > g/a
>>> > >
>>> > >
>>> pache/cxf/ws/security/wss4j/AbstractWSS4JSecurityContextProvidingIntercep
>>> > > tor<
>>> http://svn.apache.org/repos/asf/cxf/trunk/rt/ws/security/src/main/jav
>>> > >
>>> a/org/a%0Apache/cxf/ws/security/wss4j/AbstractWSS4JSecurityContextProvidi
>>> > > ngInterceptor> .java
>>> > > [3]
>>> > >
>>> > >
>>> http://svn.apache.org/repos/asf/cxf/trunk/rt/ws/security/src/test/java/or
>>> > > g/a
>>> > >
>>> pache/cxf/ws/security/wss4j/SimpleSubjectCreatingInterceptor.java<http:/
>>> > > /
>>> svn.apache.org/repos/asf/cxf/trunk/rt/ws/security/src/test/java/org/a%0A
>>> > > pache/cxf/ws/security/wss4j/SimpleSubjectCreatingInterceptor.java>
>>> [4]
>>> > >
>>> > >
>>> http://svn.apache.org/repos/asf/cxf/trunk/rt/core/src/main/java/org/apach
>>> > > e/c
>>> > > xf/interceptor/security/AbstractAuthorizingInInterceptor.java<
>>> http://svn
>>> > > .
>>> apache.org/repos/asf/cxf/trunk/rt/core/src/main/java/org/apache/c%0Axf/i
>>> > > nterceptor/security/AbstractAuthorizingInInterceptor.java> [5]
>>> > >
>>> > >
>>> http://svn.apache.org/repos/asf/cxf/trunk/rt/core/src/main/java/org/apach
>>> > > e/c
>>> > > xf/interceptor/security/SimpleAuthorizingInterceptor.java<
>>> http://svn.apa
>>> > >
>>> che.org/repos/asf/cxf/trunk/rt/core/src/main/java/org/apache/c%0Axf/inter
>>> > > ceptor/security/SimpleAuthorizingInterceptor.java>
>>>
>>> --
>>> Daniel Kulp
>>> dkulp@apache.org
>>> http://dankulp.com/blog
>>>
>>
>>
>

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