[ 
https://issues.apache.org/jira/browse/CXF-5118?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=14084691#comment-14084691
 ] 

Christian Schneider edited comment on CXF-5118 at 8/4/14 2:18 PM:
------------------------------------------------------------------

I think I understand what you mean that reusing an existing structure like 
AuthorizationPolicy might be error prone. So I propose a solution that avoids 
this.

In any case let us first go back to the requirements. 
We are currently looking at three different methods of authentication:

1. basic auth -> Is handled in the http transport and leads to a populated 
AuthorizationPolicy
2. UserNameToken -> Is handled in ws security and leads to a populated 
UsernameToken
3. certificate based authentication -> Is handled in http transport and leads 
to a populated TLSSessionInfo

So one relevant question is what should happen if several of these tokens are 
present. One possible order is the one below. The first matching token will be 
used.

1. UserNameToken
2. basic auth
3. certificate based authentication

If we are sure this order is universal we can code it in the 
JAASLoginInterceptor. 

If we rather think the order should be user configurable then it is a lot more 
difficult. The main problem I see is that jaas mainly provides the NameCallback 
and PasswordCallback interfaces. Everything else would require to define 
additional interfaces and share them between LoginModule and cxf. As this 
sharing needs a lot of overhead like a separate jar for the shared interfaces I 
would like to avoid this as long as possible.

I personally think that we can not define the one and only list of 
authentication mechanisms and order for these. So we need to enable the user to 
provide this decision. One way to achieve this is to provide an extension 
interface like this:
interface CallbackHandlerProvider {
  CallbackHandler getCallBackHandler(Message message);
}
So the implementor would be responsible to scan the message for tokens and 
decide which one to use to populate the CallBackHandler. In most cases the 
Callbackhandler would be a NamePasswordCallbackHandler but the user could also 
use this to provide something more exotic.

We allow to set an implementation in the JAASLoginInterceptor and provide one 
by default that implements the default order we define.

The advantage of this solution would be that the JAASLoginInterceptor would be 
universal for all kinds of JAAS authentication. It would simply handle calling 
JAAS and populating the SecurityContext from the results. It would not know 
what kind of tokens we know and how to handle them. This would be delegated to 
the CallBackHandlerProvider which only 
concentrates on this part.

If we provide a good default CallBackHandlerProvider then the 
JAASLoginInterceptor should still be easy to use for simple cases while 
providing enough flexibility to implement any authentication mechanism. If we 
later see that the CallbackHandlerProvider is too complex then we still have 
the possibility to split it up into classes for each authentication type and a 
coordinating class that handles the case if mixing different authentications 
like TLS + UserNameToken. Still we could start with one default implementation 
and defer the decision to later if we need to split it up.

WDYT?



was (Author: [email protected]):
I think I understand what you mean that reusing an existing structure like 
AuthorizationPolicy might might be error prone. I do not fully agree though.

In any case let us first go back to the requirements. 
We are currently looking at three different methods of authentication:

1. basic auth -> Is handled in the http transport and leads to a populated 
AuthorizationPolicy
2. UserNameToken -> Is handled in ws security and leads to a populated 
UsernameToken
3. certificate based authentication -> Is handled in http transport and leads 
to a populated TLSSessionInfo

So one relevant question is what should happen if several of these tokens are 
present. One possible order is the one below. The first matching token will be 
used.

1. UserNameToken
2. basic auth
3. certificate based authentication

If we are sure this order is universal we can code it in the 
JAASLoginInterceptor. 

If we rather think the order should be user configurable then it is a lot more 
difficult. The main problem I see is that jaas mainly provides the NameCallback 
and PasswordCallback interfaces. Everything else would require to define 
additional interfaces and share them between LoginModule and cxf. As this 
sharing needs a lot of overhead like a separate jar for the shared interfaces I 
would like to avoid this as long as possible.

I personally think that we can not define the one and only list of 
authentication mechanisms and order for these. So we need to enable the user to 
provide this decision. One way to achieve this is to provide an extension 
interface like this:
interface CallbackHandlerProvider {
  CallbackHandler getCallBackHandler(Message message);
}
So the implementor would be responsible to scan the message for tokens and 
decide which one to use to populate the CallBackHandler. In most cases the 
Callbackhandler would be a NamePasswordCallbackHandler but the user could also 
use this to provide something more exotic.

We allow to set an implementation in the JAASLoginInterceptor and provide one 
by default that implements the default order we define.

The advantage of this solution would be that the JAASLoginInterceptor would be 
universal for all kinds of JAAS authentication. It would simply handle calling 
JAAS and populating the SecurityContext from the results. It would not know 
what kind of tokens we know and how to handle them. This would be delegated to 
the CallBackHandlerProvider which only 
concentrates on this part.

If we provide a good default CallBackHandlerProvider then the 
JAASLoginInterceptor should still be easy to use for simple cases while 
providing enough flexibility to implement any authentication mechanism. If we 
later see that the CallbackHandlerProvider is too complex then we still have 
the possibility to split it up into classes for each authentication type and a 
coordinating class that handles the case if mixing different authentications 
like TLS + UserNameToken. Still we could start with one default implementation 
and defer the decision to later if we need to split it up.

WDYT?


> Create CXF interceptor which will use HTTPS client certificates to create 
> JAAS SecurityContext 
> -----------------------------------------------------------------------------------------------
>
>                 Key: CXF-5118
>                 URL: https://issues.apache.org/jira/browse/CXF-5118
>             Project: CXF
>          Issue Type: New Feature
>          Components: Core
>            Reporter: Sergey Beryozkin
>            Assignee: Christian Schneider
>
> Use case:
> The user authenticates against the webservice using an X509 client 
> certificate. In case of successful authentication the JAAS security context 
> should be populated with a Subject that stores the user name and the roles of 
> the user. This is necessary to support Authorization at a later stage.
> Design ideas
> The SSL transport will be configured to only accept certain client 
> certificates. So we can assume that the interceptor does not have to do a 
> real authentication. Instead it has to map from the subjectDN of the 
> certificate to the user name and then lookup the roles of that user. Both 
> then has to be stored in the subject's principles.
> The mapping could be done inside a JAASLoginModule or before. Inside will 
> give the user more flexibility.
> The next step to retrieve the roles should be done in one of the standard 
> JAASLoginModules as the source of the roles can be quite diverse. So for 
> example the LdapLoginModule allows to retrieve the roles from Ldap. At the 
> moment these modules require the password of the user though which is not 
> available when doing a cert based auth.
> So I see two variants to retrieve the roles:
> 1. Change the loginmodules like the LDAP one to be configureable to use a 
> fixed ldap user for the ldap connect and not require the user password. So 
> the module would have two modes: a) normal authentication and group gathering 
> b) use a fixed user to just retrieve roles for a given user
> 2. Store the user password somewhere (e.g. in the mapping file). In this case 
> the existing LDAPLoginModule could be used but the user password would be 
> openly in a text file
> 3. Create new LoginModules with the desired behaviour (fixed user and only 
> lookup of roles)



--
This message was sent by Atlassian JIRA
(v6.2#6252)

Reply via email to