Federated mapping doc improvements
The documentation was originally written using imprecise language. This resulted in lots of confusion when read. Change-Id: I9f1af3cee3216c4c10c0bf6d91a6353a28f27dd5
This commit is contained in:
parent
2db574de6d
commit
0015e1a41e
|
@ -20,17 +20,28 @@ Mapping Combinations
|
||||||
Description
|
Description
|
||||||
-----------
|
-----------
|
||||||
|
|
||||||
Mapping adds a set of rules to map federation attributes to Keystone users and/or
|
During the authentication process an identity provider (IdP) will present
|
||||||
groups. An Identity Provider has exactly one mapping specified per protocol.
|
keystone with a set of user attributes about the user that is authenticating.
|
||||||
|
For example, in the SAML2 flow this comes to keystone in the form of a SAML
|
||||||
|
document.
|
||||||
|
|
||||||
Mapping objects can be used multiple times by different combinations of Identity
|
The attributes are typically processed by third-party software and are presented
|
||||||
Provider and Protocol.
|
to keystone as environment variables. The original document from the IdP is
|
||||||
|
generally not available to keystone. This is how the `Shibboleth` and `Mellon`
|
||||||
|
implementations work.
|
||||||
|
|
||||||
|
The mapping format described in this document maps these environment variables
|
||||||
|
to a local keystone user. The mapping may also define group membership for
|
||||||
|
that user and projects the user can access.
|
||||||
|
|
||||||
|
An IdP has exactly one mapping specified per protocol. Mappings themselves can
|
||||||
|
be used multiple times by different combinations of IdP and protocol.
|
||||||
|
|
||||||
-----------
|
-----------
|
||||||
Definitions
|
Definitions
|
||||||
-----------
|
-----------
|
||||||
|
|
||||||
A rule hierarchy looks as follows:
|
A mapping looks as follows:
|
||||||
|
|
||||||
.. code-block:: javascript
|
.. code-block:: javascript
|
||||||
|
|
||||||
|
@ -39,23 +50,127 @@ A rule hierarchy looks as follows:
|
||||||
{
|
{
|
||||||
"local": [
|
"local": [
|
||||||
{
|
{
|
||||||
"<user> or <group>"
|
<user>
|
||||||
|
[<group>]
|
||||||
|
[<project>]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"remote": [
|
"remote": [
|
||||||
{
|
{
|
||||||
"<condition>"
|
<match>
|
||||||
|
[<condition>]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
* `rules`: top-level list of rules.
|
* `mapping`: a JSON object containing a list of rules.
|
||||||
* `local`: a rule containing information on what local attributes will be mapped.
|
* `rules`: a property in the mapping that contains the list of rules.
|
||||||
* `remote`: a rule containing information on what remote attributes will be mapped.
|
* `rule`: a JSON object containing `local` and `remote` properties to define
|
||||||
* `<condition>`: contains information on conditions that allow a rule, can only
|
the rule. There is no explicit `rule` property.
|
||||||
be set in a `remote` rule.
|
* `local`: a JSON object containing information on what local attributes will
|
||||||
|
be mapped. The mapping engine processes this using the `context` (defined
|
||||||
|
below) and the result is a representation of the user from keystone's
|
||||||
|
perspective.
|
||||||
|
|
||||||
|
* `<user>`: the local user that will be mapped to the federated user.
|
||||||
|
* `<group>`: (optional) the local groups the federated user will be placed in.
|
||||||
|
* `<projects>`: (optional) the local projects mapped to the federated user.
|
||||||
|
|
||||||
|
* `remote`: a JSON object containing information on what remote attributes will be mapped.
|
||||||
|
|
||||||
|
* `<match>`: a JSON object that tells the mapping engine what federated attribute
|
||||||
|
to make available for substitution in the local object. There can be one or more
|
||||||
|
of these objects in the `remote` list.
|
||||||
|
* `<condition>`: a JSON object containing conditions that allow a rule. There can be
|
||||||
|
zero or more of these objects in the `remote` list.
|
||||||
|
|
||||||
|
* `direct mapping`: the mapping engine keeps track of each match and makes them
|
||||||
|
available to the local rule for substitution.
|
||||||
|
* `assertion`: data provided to keystone by the IdP to assert facts
|
||||||
|
(name, groups, etc) about the authenticating user. This is an XML document when
|
||||||
|
using the SAML2 protocol.
|
||||||
|
* `mapping context`: the data, represented as key-value pairs, that is used by the
|
||||||
|
mapping engine to turn the `local` object into a representation of the user
|
||||||
|
from keystone's perspective. The mapping context contains the environment of the
|
||||||
|
keystone process and any `direct mapping` values calculated when processing the
|
||||||
|
`remote` list.
|
||||||
|
|
||||||
|
--------------------------
|
||||||
|
How Mappings Are Processed
|
||||||
|
--------------------------
|
||||||
|
|
||||||
|
A mapping is selected by IdP and protocol. Then keystone takes the mapping and
|
||||||
|
processes each rule sequentially stopping after the first matched rule. A rule
|
||||||
|
is matched when all of its conditions are met.
|
||||||
|
|
||||||
|
First keystone evaluates each condition from the rule's remote property to see
|
||||||
|
if the rule is a match. If it is a match, keystone saves the data captured by
|
||||||
|
each of the matches from the rule's remote property in an ordered list. We call
|
||||||
|
these matches `direct mappings` since they can be used in the next step.
|
||||||
|
|
||||||
|
After the rule is found using the rule's conditions and a list of direct mappings is
|
||||||
|
stored, keystone begins processing the rule's `local` property. Each object in
|
||||||
|
the `local` property is collapsed into a single JSON object. For example:
|
||||||
|
|
||||||
|
.. code-block:: javascript
|
||||||
|
|
||||||
|
{
|
||||||
|
"local": [
|
||||||
|
{
|
||||||
|
"user": {...}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"projects": [...]
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
becomes:
|
||||||
|
|
||||||
|
.. code-block:: javascript
|
||||||
|
|
||||||
|
{
|
||||||
|
"local": {
|
||||||
|
"user": {...}
|
||||||
|
"projects": [...]
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
when the same property exists in the local multiple times the first occurrence wins:
|
||||||
|
|
||||||
|
.. code-block:: javascript
|
||||||
|
|
||||||
|
{
|
||||||
|
"local": [
|
||||||
|
{
|
||||||
|
"user": {#first#}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"projects": [...]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"user": {#second#}
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
becomes:
|
||||||
|
|
||||||
|
.. code-block:: javascript
|
||||||
|
|
||||||
|
{
|
||||||
|
"local": {
|
||||||
|
"user": {#first#}
|
||||||
|
"projects": [...]
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
We take this JSON object and then recursively process it in order to apply
|
||||||
|
the direct mappings. This is simply looking for the pattern `{#}` and
|
||||||
|
substituting it with values from the direct mappings list. The index of the
|
||||||
|
direct mapping starts at zero.
|
||||||
|
|
||||||
-------------
|
-------------
|
||||||
Mapping Rules
|
Mapping Rules
|
||||||
|
@ -72,9 +187,9 @@ tested with the ``keystone-manage mapping_engine`` command:
|
||||||
$ keystone-manage mapping_engine --rules <file> --input <file>
|
$ keystone-manage mapping_engine --rules <file> --input <file>
|
||||||
|
|
||||||
.. NOTE::
|
.. NOTE::
|
||||||
Although the rules file is formated as json the input file of assertion
|
Although the rules file is formated as JSON, the input file of assertion
|
||||||
data is formatted as individual lines of key: value pairs,
|
data is formatted as individual lines of key: value pairs, see
|
||||||
see `keystone-manage mapping_engine --help` for details.
|
`keystone-manage mapping_engine --help` for details.
|
||||||
|
|
||||||
|
|
||||||
Mapping Conditions
|
Mapping Conditions
|
||||||
|
@ -668,7 +783,7 @@ between this mapping and the other examples is the addition of a ``projects``
|
||||||
section within the ``local`` rules. The ``projects`` list supplies a list
|
section within the ``local`` rules. The ``projects`` list supplies a list
|
||||||
of projects that the federated user will be given access to. The projects
|
of projects that the federated user will be given access to. The projects
|
||||||
will be automatically created if they don't exist when the user
|
will be automatically created if they don't exist when the user
|
||||||
authenticates and the mapping engine has applied values from the assertion
|
authenticated and the mapping engine has applied values from the assertion
|
||||||
and mapped them into the ``local`` rules.
|
and mapped them into the ``local`` rules.
|
||||||
|
|
||||||
In the above example, an authenticated federated user will be granted the
|
In the above example, an authenticated federated user will be granted the
|
||||||
|
@ -758,21 +873,23 @@ federated user's name. In addition to that, they will also be placed in the
|
||||||
``Finance`` group and receive all role assignments that group has on projects
|
``Finance`` group and receive all role assignments that group has on projects
|
||||||
and domains.
|
and domains.
|
||||||
|
|
||||||
Keystone to Keystone
|
keystone-to-keystone
|
||||||
--------------------
|
--------------------
|
||||||
|
|
||||||
Keystone to Keystone federation also utilizes mappings, but has some
|
keystone-to-keystone federation also utilizes mappings, but has some
|
||||||
differences.
|
differences.
|
||||||
|
|
||||||
An attribute file (``/etc/shibboleth/attribute-map.xml``) is used to add
|
An attribute file (e.g. ``/etc/shibboleth/attribute-map.xml`` in a Shibboleth
|
||||||
attributes to the Keystone Identity Provider. Attributes look as follows:
|
implementation) is used to add attributes to the mapping `context`. Attributes
|
||||||
|
look as follows:
|
||||||
|
|
||||||
.. code-block:: xml
|
.. code-block:: xml
|
||||||
|
|
||||||
|
<!-- example from a K2k Shibboleth implementation -->
|
||||||
<Attribute name="openstack_user" id="openstack_user"/>
|
<Attribute name="openstack_user" id="openstack_user"/>
|
||||||
<Attribute name="openstack_user_domain" id="openstack_user_domain"/>
|
<Attribute name="openstack_user_domain" id="openstack_user_domain"/>
|
||||||
|
|
||||||
The Keystone Service Provider must contain a mapping as shown below.
|
The service provider must contain a mapping as shown below.
|
||||||
``openstack_user``, and ``openstack_user_domain`` match to the attribute
|
``openstack_user``, and ``openstack_user_domain`` match to the attribute
|
||||||
names we have in the Identity Provider. It will map any user with the name
|
names we have in the Identity Provider. It will map any user with the name
|
||||||
``user1`` or ``admin`` in the ``openstack_user`` attribute and
|
``user1`` or ``admin`` in the ``openstack_user`` attribute and
|
||||||
|
|
Loading…
Reference in New Issue