[openstack-dev] [Keystone] - Cloud federation on top of the Apache

Marek Denis marek.denis at cern.ch
Mon Jan 27 17:26:41 UTC 2014


Dear all,

We have Identity Provider and mapping CRUD operations already merged, so 
it's a good point to prepare Keystone and Apache to handle SAML (as a 
starter) requests/responses.
For the next OpenStack release it'd be the Apache that handles SAML 
communication. In order to force SAML authentication, an admin defines 
so called 'protected resources', hidden behind certain URLs. In order to 
get access to aforementioned resources a SAML authenticated session is 
required. In terms of Keystone and federation this 'resource' would be 
just a token, ready to be later used against other OpenStack services. 
For obvious reasons we cannot make mod_shib watch all the Keystone URLs 
clients can access, so I think a dedicated URL should be used. That's 
right, a client who'd want to grab a token upon SAML authn would need to 
hit 
https://keystone:5000/v3/OS-FEDERATION/tokens/identity_provider/<idp>/protocol/<protocol> 
.Such a URL would albo be kind of dynamic, because this would later let 
Keystone distinguish* what (already registered) IdP and federation 
protocol (SAML, OpenID, etc) is going to be used .

A simplified workflow could look like this:


Pre-req: Apache frontend is  configured to protect URLs matching regex 
/OS-FEDERATION/tokens/identity_provider/(.*?)/protocol/(.*?)

1) In order to get a valid token upon federated authentication a client 
enters protected resource, for instance 
https://keystone:5000/v3/OS-FEDERATION/tokens/identity_provider/{idp}/protocol/{protocol}
2) After the client is authenticated (with ECP/similar extension) the 
request enters Keystone public pipeline.
3) Apache modules  store parsed parameters from a SAML assertion in a 
wsgi environment,
4) A class inheriting from wsgi.Middleware checks whether the 
REQUEST_URL (or similar) environment variable matches aforementioned 
regexp (e.g. /OS-FEDERATION/tokens/identity_provider/.*?/protocol/.*?) 
and if the match is positive, fetches env parameters starting with 
certain value (a prefix configurable in the keystone.conf, say 'ADFS_' 
). The parameters are stored as a dictionary and passed in a structure, 
later available to other filters/middleware objects in the pipeline (TO 
BE CONFIRMED, MAYBE REWRITING PARAMS IS NOT REQUIRED).
5) keystone/contrib/federation/routers.py has defined URL routes and 
fires keystone/contrib/federation/controllers.py methods that fetch IdP, 
protocol entities as well as the corresponding mapping entity with the 
mapping rules included. The rules are applied  on the assertion 
parameters and list of local users/groups is issued. The OpenStack token 
is generated, stored in the DB and returned to the user (formed as a 
valid JSON response).
6) The token can now be used for next operations on the OpenStack cloud.


*)
At first I though the dynamic URLs 
(OS-FEDERATION/tokens/identity_provider/(.*?)/protocol/(.*?)) could be 
replaced with a one static, and information about the IdP and protocol 
could be sent as a HTTP POST input, but from what I have already noticed 
after the client is redirected to the IdP (and to the SP again) the 
initial input is lost.


I am looking forward to hear feedback from you.

Thanks,

-- 
Marek Denis
[marek.denis at cern.ch]



More information about the OpenStack-dev mailing list