Re: authn vs. authz


Nguyen, Liem Manh <liem_m_nguyen@...>
 

Hi John,

 

My response in-line below…   

 

Cheers,

Liem

 

-----Original Message-----
From: John Dennis [mailto:jdennis@...]
Sent: Monday, June 16, 2014 3:39 PM
To: Nguyen, Liem Manh; Abhishek Kumar; 'Arash Eghtesadi'; Lakshman Mukkamalla; Lenrow, Dave; Mellquist, Peter; Wojciech Dec; aaa-dev@...; Nathan Kinder
Subject: authn vs. authz

 

Hi Liem:

 

Thank you for sending out the sequence diagrams, they've been very helpful. Also thank you for posting the code to a public git repo. The code looks clean, nicely organized and professionally written. I've been going through the code to get a better understanding of the overarching architecture and I've got a few questions.

 

My first question is an organizational one, I noticed you've been sending your emails with design information to specific individuals instead of the aaa-dev list, is there a reason? FWIW I've sent this mail to both the individuals you've been emailing *and* the aaa-dev list.

Should we be using the aaa-dev list from this point on?

 

>> Yes, I was not sure if everyone has subscribed to the aaa-dev list; so, I sent to individual addresses to make sure that the information does get to our team.  If everyone has got on the aaa-dev list (which I encourage folks to), it will make it simpler next time J

 

The Framework Overview (https://github.com/opendaylight/aaa) is clear that authentication (authn) and authorization (authz) are two independent concepts and derive from independent sources of authority.

This is good, authn and authz should be separate.

 

But when I look at the code it looks to me as if authn and authz have been conflated. I draw this conclusion by looking at the fields in the Claim and Authentication types. An identity claim is something returned by a trusted IdP (Identity Provider) which attests to the identity and attributes bound to that identity by the IdP. It appears as if the Claim type is being used for this purpose in the code. However the Claim type also includes tenant and role information. An independent IdP will not (or should not) have information specific to ODL. This is especially true for roles, only ODL should know what the roles are and which identities possess those roles. [1]

 

>> From a third-party IdP, the incoming assertion is in the form of Map<String, Object> which is a collection of Servlet attributes and HTTP headers, which ODL will not understand.  In order to normalize this into an ODL “Claim” object that ODL can understand, an implementation of the ClaimAuth interface needs to transform the external claim into the ODL Claim object.  This transformation responsibility includes figuring out what roles user Joe has in what domain under ODL, or may be Joe is actually Bob in ODL.  The Authentication object is simply meant to represent the authentication context to be exposed to the service layer and includes an expiration.

 

Perhaps I've misread the code (please correct me) but it looks as if ClaimAuthFilter via the ClaimAuth.transform() method is supposed to map from an IdP identity assertion to a Claim object. What is confusing me is how or why would an external authn assertion know anything about the ODL roles in order to populate the roles in the Claim object? [2]

 

It seems to me there needs to be a separate mapping stage which maps from an identity assertion to ODL specific information such as tenant and roles. As an example you might want to look at how Keystone handles the federated case (https://github.com/openstack/identity-api/blob/master/v3/src/markdown/identity-api-v3-os-federation-ext.md).

In the Keystone federation architecture one binds an (IdP, protocol) 2-tuple to a mapping which maps from IdP attributes to those used internally (i.e. groups, roles, etc.)

 

Going back to the code and the sequence diagrams shouldn't there be an IdentityClaim (does not yet exist) which is passed to a mapping endpoint (does not yet exist) which returns a Claim instead of the ClaimAuthFilter attempting to assign roles and return a Claim?

 

>> You are correct that the ClaimAuth::transform() maps the identity assertion into a Claim object.  While an external AuthN assertion does not know anything about ODL roles, the specific ClaimAuth implementation should know how to extract the external AuthN assertion information and any additional attributes needed to map that particular IdP protocol onto ODL roles/domain.  Sure, it could use a mapping service like you mentioned underneath the hood.  We could even have a generic mapping service like Keystone (thanks for the link, BTW), but to keep it simple for Helium, I am thinking we can just have a mapping service specific to SSSD, since our goal is to support SSSD, unless someone has the bandwidth to implement a generic mapping service/API—which I would be a fan of!

 

Also, I'm not sure why we have the DirectAuth case as a special case code path and flow. Couldn't the code be simplified if DirectAuth was an instance of the federated case? Here the internal DirecAuth "toy" IdP only does username/password authn and the roles are provided by a mapping? Fewer code paths usually means more robust code.

 

>> The internal IdM provides 2 main functions:  authorization (what roles does this user have in what domain?) and identity assertion (is this the user he claims to be with the given credentials?).  Direct AuthN involves both functions of the internal IdM, while the federated case involves only the first one.  Hence, we have 2 separate interfaces to call out these differences.  As you can tell, I am a fan of using separate Java interfaces to enforce/express contracts J.

 

I'm sure I have a slew of misunderstandings about how the actually code works :-) Feel free to set me straight.

 

Thanks again for the great code and excellent diagrams!

 

John

 

 

[1] Allowing an IdP to attach a role to an identity is a security concern. You may trust an IdP to authenticate a user but do you really want to trust that IdP to also claim that user has the admin role in your service? It may be case that you trust *some* IdP's to assign roles but that should be configurable and off by default. I suspect the DirectAuth case is one such example (correct?)

 

[2] It almost looks as if the authz processing is supposed to happen in

TokenEndpoint.createAccessToken() where the else clause says

 

// TODO: Support authorization code later...

 

but if the claim filters are setting the roles (which is my definition of authz) then what authorization code is going to execute here?

--

John

Join z.archive.aaa-dev@lists.opendaylight.org to automatically receive all group messages.