[doc] New bits of documentation
|
@ -22,9 +22,9 @@ the user session.
|
|||
Attributes can thus be proxyfied during SSO with Authentic2
|
||||
configured as a SAML2 proxy.
|
||||
|
||||
The namespace of attributes received from another SAML2 IdP or pushed in the
|
||||
assertion given in to service providers can be configured per attribute or per
|
||||
service provider.
|
||||
The namespace of attributes received from another SAML2 IdP and of attributes
|
||||
pushed in the assertion given to service providers can be configured per
|
||||
attribute or per service provider.
|
||||
|
||||
By default, the namespace and format of attributes in assertion is conformant
|
||||
to the SAMLV2.0 X500/LDAP Attribute profile::
|
||||
|
@ -50,8 +50,8 @@ profile can also be used, for instance::
|
|||
Configuration
|
||||
=============
|
||||
|
||||
Configure sources of attributes
|
||||
-------------------------------
|
||||
Configure local sources of attributes
|
||||
-------------------------------------
|
||||
|
||||
The source of attributes for authentic2 are of two kinds. The LDAP sources and
|
||||
the user django profile.
|
||||
|
@ -123,8 +123,8 @@ user alias in source is created for the user:
|
|||
.. image:: pictures/alias_in_source_saved.png
|
||||
:width: 800 px
|
||||
|
||||
Configure attributes pushed to SAML2 service providers in SSO response
|
||||
----------------------------------------------------------------------
|
||||
Configure attributes from local sources pushed to SAML2 service providers in SSO response
|
||||
-----------------------------------------------------------------------------------------
|
||||
|
||||
Reminder:
|
||||
|
||||
|
@ -206,65 +206,188 @@ __________________________________________
|
|||
.. image:: pictures/policy_pull_renamed.png
|
||||
:width: 800 px
|
||||
|
||||
Handle attributes provided by other Identity providers, proxy attributes
|
||||
------------------------------------------------------------------------
|
||||
Handle attributes provided by other Identity providers and pushed to SAML2 service providers in SSO response (proxy attributes)
|
||||
-------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
Link to configure first Authentic as a sp to have attributes in session
|
||||
To have these kind of attributes to forward, authentic must be configured as a
|
||||
SAML2 service provider, see the corresponding administration page
|
||||
:ref:`config_saml2_idp`.
|
||||
|
||||
Add a source if mapping set to true
|
||||
Forward all attributes in session without any modification
|
||||
__________________________________________________________
|
||||
|
||||
Create or modify an attribute policy activating the option 'Forward attributes from push sources' and save.
|
||||
|
||||
**No other option below must be used.**
|
||||
|
||||
.. image:: pictures/attr_policy_forward.png
|
||||
:width: 800 px
|
||||
|
||||
**Attach policy to the service provider if it is not yet the case.**
|
||||
|
||||
**No need to deal with namespace here.**
|
||||
|
||||
Filter attributes from source only
|
||||
__________________________________
|
||||
|
||||
Here, you want to forward **all** attributes of selected source of attributes.
|
||||
|
||||
First of all you need to create objects corresponding to the sources of
|
||||
attributes.
|
||||
|
||||
**The name of the source object must be the entity ID of the SAML2
|
||||
identity provider.**
|
||||
|
||||
1. Go to http[s]://your.domain.com/admin/attribute_aggregator/attributesource/add/
|
||||
|
||||
2. Set the name (No need to change the namespace)
|
||||
|
||||
.. image:: pictures/attr_source_idp.png
|
||||
:width: 800 px
|
||||
|
||||
3. Save
|
||||
|
||||
.. image:: pictures/attr_source_idp_saved.png
|
||||
:width: 800 px
|
||||
|
||||
Then create or modify an attribute policy activating the option **'Forward attributes from push sources'**.
|
||||
You then select the source you want to forward attributes through the selection box and you save.
|
||||
|
||||
.. image:: pictures/attr_policy_filter_source.png
|
||||
:width: 800 px
|
||||
|
||||
**Attach policy to the service provider if it is not yet the case.**
|
||||
|
||||
**No need to deal with namespace here.**
|
||||
|
||||
|
||||
Modify namespace of attributes forwarded when attributes forwarded are not filtered or when filtered according to the source
|
||||
____________________________________________________________________________________________________________________________
|
||||
|
||||
The system needs to 'recognise the attributes' to perform the mapping.
|
||||
For this, you need to indicate the namespace of attributes received per source
|
||||
if the namespace is not the one of Authentic2 (X500/LDAP and extensions edu*
|
||||
and supann).
|
||||
|
||||
In other words if the source provides attributes in a different namespace, you
|
||||
need to create objects corresponding to the sources of attributes and indicate
|
||||
there the right namespace. By default, the only other supported namespace is
|
||||
http://schemas.xmlsoap.org/ws/2005/05/identity/claims.
|
||||
|
||||
.. image:: pictures/attr_source_idp_claims.png
|
||||
:width: 800 px
|
||||
|
||||
Then create or modify an attribute policy activating the options 'Forward attributes from push sources',
|
||||
**'Map attributes from push sources'**. You also choose the output namespace expected with the
|
||||
parameters **'Output name format'** and **'Output namespace'**.
|
||||
|
||||
.. image:: pictures/attr_policy_map_ns.png
|
||||
:width: 800 px
|
||||
|
||||
Remind that the default namespace is X500/LDAP + edu* + supann and the only other supported namespace is
|
||||
http://schemas.xmlsoap.org/ws/2005/05/identity/claims.
|
||||
|
||||
**Attach policy to the service provider if it is not yet the case.**
|
||||
|
||||
Filter attributes with a list of attributes, with or without choosing the source
|
||||
________________________________________________________________________________
|
||||
|
||||
The system needs to 'recognise the attributes' to filter the attributes
|
||||
according to a list of attributes.
|
||||
For this, you need to indicate the namespace of attributes received per source
|
||||
if the namespace is not the one of Authentic2 (X500/LDAP and extensions edu*
|
||||
and supann).
|
||||
|
||||
In other words if the source provides attributes in a different namespace, you
|
||||
need to create objects corresponding to the sources of attributes and indicate
|
||||
there the right namespace. By default, the only other supported namespace is
|
||||
http://schemas.xmlsoap.org/ws/2005/05/identity/claims.
|
||||
|
||||
.. image:: pictures/attr_source_idp_claims.png
|
||||
:width: 800 px
|
||||
|
||||
You then create an attribute list as described in section *'Create a named list of attribute items'*.
|
||||
|
||||
Then create or modify an attribute policy activating the option **'Forward attributes from push sources'**.
|
||||
You then associate the list of attributes.
|
||||
|
||||
.. image:: pictures/attr_policy_filter_attributes.png
|
||||
:width: 800 px
|
||||
|
||||
If you want to also filter according to the source you can configure it as defined in section *'Filter attributes from source only'*. You can also choose to filter
|
||||
with the source indicate per attribute item of the list. For this select the option **'Filter source of filtered attributes'**.
|
||||
|
||||
.. image:: pictures/attr_policy_filter_attributes_source.png
|
||||
:width: 800 px
|
||||
|
||||
.. image:: pictures/attribute_item.png
|
||||
:width: 800 px
|
||||
|
||||
The default name format is BASIC. You can however change the name format and namespace with the option **'Map attributes from push sources'** and the parameters **'Output name format'** and **'Output namespace'**.
|
||||
|
||||
Using the option **'Map attributes of filtered attributes'** the output name format and namespace are the ones indicated per attribute item of the list.
|
||||
|
||||
.. image:: pictures/attr_policy_filter_attributes_map.png
|
||||
:width: 800 px
|
||||
|
||||
.. image:: pictures/attribute_item.png
|
||||
:width: 800 px
|
||||
|
||||
|
||||
Push manually (writing bits of code) attributes to SAML2 service providers in SSO response
|
||||
------------------------------------------------------------------------------------------
|
||||
|
||||
In idp/signals.py connect to the add_attributes_to_response signal::
|
||||
|
||||
add_attributes_to_response.connect(your_function)
|
||||
|
||||
Your function must return an attribute dictionnary as follows::
|
||||
|
||||
dic = {}
|
||||
attributes = {}
|
||||
attributes[name] = (value1, value2, )
|
||||
attributes[(name, format)] = (value1, value2, )
|
||||
attributes[(name, format, nickname)] = (value1, value2, )
|
||||
dic['attributes'] = attributes
|
||||
return dic
|
||||
|
||||
*format* must be in (lasso.SAML2_ATTRIBUTE_NAME_FORMAT_URI,
|
||||
lasso.SAML2_ATTRIBUTE_NAME_FORMAT_BASIC)
|
||||
|
||||
You can use the attributes form the local source and the attributes in the
|
||||
session that are pushed by other identity providers.
|
||||
|
||||
Attributes in the session are in::
|
||||
|
||||
request.session['multisource_attributes']
|
||||
|
||||
See the page :ref:`attributes_in_session`.
|
||||
|
||||
If you want to use local source of attributes and use mapping capabilities
|
||||
of the UserAttributeProfile see the page :ref:`attribute_management_explained`.
|
||||
Use the file idp/attributes.py as an exemple.
|
||||
|
||||
Modifying supported namespaces and attribute name mappings
|
||||
==========================================================
|
||||
|
||||
TBD
|
||||
The mapping is defined in the file attribute_aggregatore/mapping.py
|
||||
|
||||
Explanation (Draft)
|
||||
===================
|
||||
The manual modification of this file is necessary to extend the default schema
|
||||
and mappings.
|
||||
|
||||
Attribute aggegrator module
|
||||
---------------------------
|
||||
Add new namespaces in ATTRIBUTE_NAMESPACES.
|
||||
|
||||
The core attribute management is based on the attribute aggregator module.
|
||||
To extend the default schema add key/value in ATTRIBUTE_MAPPING, for instance::
|
||||
|
||||
Intro
|
||||
_____
|
||||
"displayName": {
|
||||
"oid": "2.16.840.1.113730.3.1.241",
|
||||
"display_name": _("displayName"),
|
||||
"type": "http://www.w3.org/2001/XMLSchema#string",
|
||||
"syntax": "1.3.6.1.4.1.1466.115.121.1.15",
|
||||
},
|
||||
|
||||
Attribute aggregator provides a main Model class called UserAttributeProfile,
|
||||
functions to load attributes and extract attributes.
|
||||
|
||||
The mapping between attribute namespaces is built-in and depends on a unique
|
||||
file (mapping.py).
|
||||
|
||||
A main schema is defined and is based on LDAP/X500 for naming. The support
|
||||
of http://schemas.xmlsoap.org/ws/2005/05/identity/claims is partly complete.
|
||||
|
||||
Source of attributes are connected with attribute loading functions using
|
||||
signals.
|
||||
|
||||
FAQ
|
||||
___
|
||||
|
||||
Why not use the Django User profile?
|
||||
|
||||
The django user profile needs to define attributes as class attributes and
|
||||
then support form filling or mapping with LDAP.
|
||||
|
||||
That is useful and may be used, especially because the profile can be used as
|
||||
a source of attribute to load in the attribute_aggregator profile.
|
||||
|
||||
The attribute_aggregator profile allow to load multivalued attributes from any
|
||||
source supported (LDAP, Django profile and attributes in Django session for
|
||||
now) from any namespace defined in mapping.py (LDAP/X500 and claims for now).
|
||||
|
||||
The profile can be loaded giving a source or a list of attribute, or can be
|
||||
from any known source, or with a dictionnary.
|
||||
|
||||
Attributes can be extracted with many functions in any namespace supported.
|
||||
|
||||
Quick explanation
|
||||
_________________
|
||||
|
||||
The schema is defined in mapping.py and is made of definitions like this::
|
||||
Add mapping of attribute name extending attribute entries in ATTRIBUTE_MAPPING,
|
||||
for instance::
|
||||
|
||||
"sn": {
|
||||
"oid": "2.5.4.4",
|
||||
|
@ -276,7 +399,7 @@ The schema is defined in mapping.py and is made of definitions like this::
|
|||
"http://schemas.xmlsoap.org/ws/2005/05/identity/claims": {
|
||||
"identifiers":
|
||||
[
|
||||
"http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname",
|
||||
"http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname",
|
||||
],
|
||||
"friendly_names":
|
||||
[
|
||||
|
@ -285,379 +408,3 @@ The schema is defined in mapping.py and is made of definitions like this::
|
|||
}
|
||||
}
|
||||
},
|
||||
|
||||
The profile store all the data in a text field taht contains a cPickle list of
|
||||
instances of the class AttributeData.
|
||||
|
||||
The profile is attached to a user and then can be created or loaded with::
|
||||
|
||||
profile = load_or_create_user_profile(user=user)
|
||||
|
||||
User may be None to create a temporary profile for an anonymous user. But
|
||||
that need a DB cleaning function not implemented.
|
||||
|
||||
The model *UserAttributeProfile*
|
||||
________________________________
|
||||
|
||||
The model 'UserAttributeProfile' can be attached to a user and then persist
|
||||
(as a Model).
|
||||
|
||||
When the profile is loaded, all data stored are removed expect if the
|
||||
the data has an expiration date later.
|
||||
|
||||
The profile provide several methods to store and extract attributes.
|
||||
|
||||
All the methods to add attributes are based on a main one accepting a
|
||||
dictionnary of attribute is parameters 'load_by_dic()'. The other methods
|
||||
('load_listed_attributes()', 'load_greedy()') send a signal with a list of
|
||||
attributes (listed_attributes_call) or not (any_attributes_call) to grab a
|
||||
dictionnary. The list is given with the definition name, oid or friendly name
|
||||
of the attribute in the system namespace.
|
||||
|
||||
Into the dictionnary, attributes are given with their name, oid or friendly
|
||||
name in the default namespace or with their name in a namepsace. An expiration
|
||||
date can also be given (ISO8601 format), if none, attribute will be deleted at
|
||||
next profile loading. The dictionnary format is as follows::
|
||||
|
||||
attributes = dict()
|
||||
data_from_source = list()
|
||||
a1 = dict()
|
||||
a1['oid'] = definition_name
|
||||
Or
|
||||
a1['definition'] = definition_name
|
||||
definition may be the definition name like 'gn'
|
||||
or an alias like 'givenName'
|
||||
Or
|
||||
a1['name'] = attribute_name_in_ns
|
||||
a1['namespace'] = ns_name
|
||||
a1['expiration_date'] = date
|
||||
a1['values'] = list_of_values
|
||||
data_from_source.append(a1)
|
||||
...
|
||||
data_from_source.append(a2)
|
||||
attributes[source_name] = data_from_source
|
||||
|
||||
Getters are defined to extract data from a profile. Only AttributeData
|
||||
instances are extracted that assume that any attribute namespace can be used.
|
||||
|
||||
* get_data_of_definition(definition)
|
||||
|
||||
Return a list of AttributeData instances corresponding to the definition
|
||||
given.
|
||||
|
||||
* get_freshest_data_of_definition(definition)
|
||||
|
||||
Return the freshest AttributeData instance. If multiple with no or same exp
|
||||
date, random. Should use the creation date soon.
|
||||
|
||||
* get_data_of_source
|
||||
|
||||
Return a list of AttributeData instances corresponding to the source given.
|
||||
|
||||
* get_data_of_source_by_name
|
||||
|
||||
Idem but source name is given, not a Source instance.
|
||||
|
||||
* get_data_of_definition_and_source
|
||||
|
||||
Return a list of AttributeData instances corresponding to the definition and
|
||||
source given.
|
||||
|
||||
* get_data_of_definition_and_source_by_name
|
||||
|
||||
Idem but source name is given, not a Source instance.
|
||||
|
||||
SAML2 attribute representation in assertions
|
||||
--------------------------------------------
|
||||
|
||||
SAML2 attribute profile (saml-profiles-2.0-os - Section 8) defines two kind of
|
||||
attribute element syntax in the attribute statement of assertions, also
|
||||
called *name format*:
|
||||
|
||||
- BASIC::
|
||||
|
||||
NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic"
|
||||
|
||||
- URI::
|
||||
|
||||
NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"
|
||||
|
||||
*URI should be used when attributes have "universally" known unique names
|
||||
like OID.*
|
||||
|
||||
Example::
|
||||
|
||||
<saml:Attribute NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic"
|
||||
Name="FirstName">
|
||||
<saml:AttributeValue xsi:type="xs:string">By-Tor</saml:AttributeValue>
|
||||
</saml:Attribute>
|
||||
|
||||
<saml:Attribute
|
||||
xmlns:x500="urn:oasis:names:tc:SAML:2.0:profiles:attribute:X500"
|
||||
NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"
|
||||
Name="urn:oid:2.5.4.42" FriendlyName="givenName">
|
||||
<saml:AttributeValue xsi:type="xs:string"
|
||||
x500:Encoding="LDAP">Steven</saml:AttributeValue>
|
||||
</saml:Attribute>
|
||||
|
||||
|
||||
BASIC
|
||||
_____
|
||||
|
||||
|
||||
Two <Attribute> elements refer to the same SAML attribute if and only if the
|
||||
values of their Name XML attributes are equal in the sense of Section 3.3.6 of
|
||||
[Schema2].
|
||||
|
||||
No additional XML attributes are defined for use with the <Attribute> element.
|
||||
|
||||
The schema type of the contents of the <AttributeValue> element MUST be drawn
|
||||
from one of the types defined in Section 3.3 of [Schema2]. The xsi:type
|
||||
attribute MUST be present and be given the appropriate value.
|
||||
|
||||
X.500/LDAP Attribute Profile (URI)
|
||||
__________________________________
|
||||
|
||||
**Extracted from the SAML2 core specifications**
|
||||
|
||||
Two <Attribute> elements refer to the same SAML attribute if and only if their
|
||||
Name XML attribute values are equal in the sense of [RFC3061]. The
|
||||
FriendlyName attribute plays no role in the comparison.
|
||||
|
||||
Directory attribute type definitions for use in native X.500 directories
|
||||
specify the syntax of the attribute using ASN.1 [ASN.1]. For use in LDAP,
|
||||
directory attribute definitions additionally include an LDAP syntax which
|
||||
specifies how attribute or assertion values conforming to the syntax are to be
|
||||
represented when transferred in the LDAP protocol (known as an LDAP-specific
|
||||
encoding). The LDAP-specific encoding commonly produces Unicode characters in
|
||||
UTF-8 form. This SAML attribute profile specifies the form of SAML attribute
|
||||
values only for those directory attributes which have LDAP syntaxes. Future
|
||||
extensions to this profile may define attribute value formats for directory
|
||||
attributes whose syntaxes specify other encodings.
|
||||
|
||||
To represent the encoding rules in use for a particular attribute value, the
|
||||
<AttributeValue> element MUST contain an XML attribute named Encoding defined
|
||||
in the XML namespace urn:oasis:names:tc:SAML:2.0:profiles:attribute:X500.
|
||||
|
||||
For any directory attribute with a syntax whose LDAP-specific encoding
|
||||
exclusively produces UTF-8 character strings as values, the SAML attribute
|
||||
value is encoded as simply the UTF-8 string itself, as the content of the
|
||||
<AttributeValue> element, with no additional whitespace.
|
||||
In such cases, the xsi:type XML attribute MUST be set to xs:string.
|
||||
The profile-specific Encoding XML attribute is provided, with a value of LDAP.
|
||||
|
||||
The AttributeData instances have a field expiration_data. It the profile
|
||||
exists, obsolete data are removed at loading.
|
||||
|
||||
|
||||
When authentic 2 deals with attributes and needs mapping?
|
||||
---------------------------------------------------------
|
||||
|
||||
Authentic2 behaves as an attribute provider:
|
||||
* At the SSO login
|
||||
* When an attribute request is received
|
||||
|
||||
Authentic requests (e.g. by soap) are not yet supported.
|
||||
|
||||
When Authentic2 behaves as an attribute provider at SSO login
|
||||
_____________________________________________________________
|
||||
|
||||
At a SSO request, just before responding to the service provider, the saml2
|
||||
idp module sends the signal 'add_attributes_to_response' giving the SP entity
|
||||
ID.
|
||||
|
||||
The signal is connected to the function 'provide_attributes_at_sso()' in
|
||||
charge of providing the attributes at the SSO for this SP.
|
||||
|
||||
**Attributes sources are of two kinds. The first ones are the sources that can
|
||||
be requested by the IdP with a syncrhonous binding without user intercations.
|
||||
These sources are called pull sources. They are for now limited to LDAP
|
||||
sources. The other ones are sources are asyncrhonous bindings, usually
|
||||
requiring user interactions. These sources are called push sources. They are
|
||||
now limited to the attributes provided at SSO requests when the IdP acts as a
|
||||
SAML2 SP. There attributes are put/found in the Django session.**
|
||||
|
||||
Each source in the system is declared with an instance of the AttributeSource
|
||||
model. We'll see later that to forward attributes of push sources it is not
|
||||
necessary that a source is declared in some circumstances.
|
||||
|
||||
To manage these sources an attribute policy is attached to services providers.
|
||||
Then the service provider model must be extended with a attribute
|
||||
attributes_at_sso_policy. The service provider must send the signal
|
||||
'add_attributes_to_response'.
|
||||
|
||||
The implementation is actually done for SAML2 providers.
|
||||
|
||||
**In such a policy attributes from pull and push sources are treated
|
||||
differently.**
|
||||
|
||||
**For pull sources, a list of attributes is indicated. Either an attribute is
|
||||
searched in all the pull sources and whatever attribute value found is
|
||||
returned. Or each attribute is indicated with a source. With each attribute is
|
||||
indicated the output format and namespace.**
|
||||
|
||||
**The policy may also indicate that all the attributes in the Django session
|
||||
must be forwarded. Then, no AttributeSource instance is required. All the
|
||||
attributes are then forwarded without treating input namespace considerations.
|
||||
When an AttributeSource instance is found, the input namespace of this source
|
||||
is considered. An option can then be set to tell that the output format and
|
||||
namespace must be taken. A list of attribute can also be given.
|
||||
This list can be use to filter attributes to forward without or without taking
|
||||
care of the source. The output namespace and format can also be trated per
|
||||
attribute.**
|
||||
|
||||
If the namespace is default, the attribute names will be taken from the
|
||||
system namespace. In BASIC the name will be the definition name. In URI, the
|
||||
Name will be the OID in urn format and the friendly name will be the
|
||||
definition name. If a namespace is given, the first identifier of this
|
||||
attribute is taken as Name in BASIC. In URI, the same and the first friendly
|
||||
name is taken.
|
||||
|
||||
::
|
||||
|
||||
class LibertyServiceProvider(models.Model):
|
||||
...
|
||||
attribute_policy = models.ForeignKey(AttributePolicy,
|
||||
verbose_name=_("Attribute policy"), null=True, blank=True)
|
||||
|
||||
class AttributePolicy(models.Model):
|
||||
# List of attributes to provide from pull sources at SSO Login.
|
||||
# If an attribute is indicate without a source, from any source.
|
||||
# The output format and namespace is given by each attribute.
|
||||
attribute_list_for_sso_from_pull_sources = \
|
||||
models.ForeignKey(LibertyAttributeMap,
|
||||
related_name = "attributes of pull sources",
|
||||
blank = True, null = True)
|
||||
|
||||
# Set to true for proxying attributes from pull sources at SSO Login.
|
||||
# Attributes are in session.
|
||||
# All attributes are forwarded as is except if the parameter
|
||||
# 'attribute_list_for_sso_from_push_sources' is initialized
|
||||
forward_attributes_from_pull_sources = models.BooleanField(default=False)
|
||||
|
||||
# Map attributes in session
|
||||
# forward_attributes_in_session must be true
|
||||
# At False, all attributes are forwarded as is
|
||||
# At true, look for the namespace of the source for input, If not found,
|
||||
# system namespace. Look for the options attribute_name_format and
|
||||
# output_namespace of the attribute policy for output.
|
||||
map_attributes_from_pull_sources = models.BooleanField(default=False)
|
||||
|
||||
# ATTRIBUTE_VALUE_FORMATS[0] =>
|
||||
# (lasso.SAML2_ATTRIBUTE_NAME_FORMAT_BASIC, 'SAMLv2 BASIC')
|
||||
output_name_format = models.CharField(max_length = 100,
|
||||
choices = ATTRIBUTE_VALUE_FORMATS,
|
||||
default = ATTRIBUTE_VALUE_FORMATS[0])
|
||||
|
||||
#ATTRIBUTES_NS[0] => ('Default', 'Default')
|
||||
output_namespace = models.CharField(max_length = 100,
|
||||
choices = ATTRIBUTES_NS, default = ATTRIBUTES_NS[0])
|
||||
|
||||
# Filter attributes pushed from source.
|
||||
source_filter_for_sso_from_push_sources = \
|
||||
models.ManyToManyField(AttributeSource,
|
||||
related_name = "attributes of pull sources",
|
||||
blank = True, null = True)
|
||||
|
||||
# List of attributes to filter from pull sources at SSO Login.
|
||||
attribute_filter_for_sso_from_push_sources = \
|
||||
models.ForeignKey(LibertyAttributeMap,
|
||||
related_name = "attributes of pull sources",
|
||||
blank = True, null = True)
|
||||
|
||||
# The sources of attributes of the previous list are considered.
|
||||
# May be used conjointly with 'source_filter_for_sso_from_push_sources'
|
||||
filter_source_of_filtered_attributes = models.BooleanField(default=False)
|
||||
|
||||
# To map the attributes of forwarded attributes with the defaut output
|
||||
# format and namespace, use 'map_attributes_from_pull_sources'
|
||||
# Use the following option to use the output format and namespace
|
||||
# indicated for each attribute.
|
||||
map_attributes_of_filtered_attributes = models.BooleanField(default=False)
|
||||
|
||||
|
||||
# Set to true to take in account missing required attributes
|
||||
send_error_and_no_attrs_if_missing_required_attrs = \
|
||||
models.BooleanField(default=False)
|
||||
|
||||
class Meta:
|
||||
verbose_name = _('attribute options policy')
|
||||
verbose_name_plural = _('attribute options policies')
|
||||
|
||||
|
||||
class AttributeList(models.Model):
|
||||
name = models.CharField(max_length = 40, unique = True)
|
||||
attributes = models.ManyToManyField(AttributeItem,
|
||||
related_name = "attributes of the list",
|
||||
blank = True, null = True)
|
||||
|
||||
|
||||
class AttributeItem(models.Model):
|
||||
attribute_name = models.CharField(max_length = 100, choices = ATTRIBUTES,
|
||||
default = ATTRIBUTES[0])
|
||||
# ATTRIBUTE_VALUE_FORMATS[0] =>
|
||||
# (lasso.SAML2_ATTRIBUTE_NAME_FORMAT_BASIC, 'SAMLv2 BASIC')
|
||||
output_attribute_name_format = models.CharField(max_length = 100,
|
||||
choices = ATTRIBUTE_VALUE_FORMATS,
|
||||
default = ATTRIBUTE_VALUE_FORMATS[0])
|
||||
#ATTRIBUTES_NS[0] => ('Default', 'Default')
|
||||
output_namespace = models.CharField(max_length = 100,
|
||||
choices = ATTRIBUTES_NS, default = ATTRIBUTES_NS[0])
|
||||
required = models.BooleanField(default=False)
|
||||
source = models.ForeignKey(AttributeSource, blank = True, null = True)
|
||||
|
||||
|
||||
A list of attributes can also be taken from the service provider metadata and
|
||||
added to 'attribute_list_for_sso_from_pull_sources'. The namespace may be
|
||||
extracted from the metadata. This namespace is then used to look for the
|
||||
corresponding definition and then to provide the attribute in the right
|
||||
namespace. Read attributes from metadata is not yet supported.
|
||||
|
||||
For the attributes of pull sources, once the list of attributes is defined,
|
||||
They are loaded in the user profile.
|
||||
|
||||
As explained before the attribute_aggregator loading function send signals to
|
||||
grab dictionnary of attributes. Up to know, only the ldap loading function are
|
||||
connected to these signals. The namespace of LDAP sources is assumed to be
|
||||
the same as the system namespace. There is here then no mapping needed. Other
|
||||
kind of sources than LDAP can be defined in attribute aggregator.
|
||||
|
||||
To grab attributes from a LDAP the user dn in the LDAP or at least a local
|
||||
identifier in the LDAP is required. For this purpose, each user has alias
|
||||
associated with LDAP source. These aliases must their DN in the LDAP. When
|
||||
the authentication LDAP backend will be taken in account, the dn will be taken
|
||||
direclty from the user Model instance.
|
||||
|
||||
Each LDAP sources are declared with the binding parameters. The LDAP namespace
|
||||
is always 'Default'.
|
||||
|
||||
If an attribute to load is not found and is required the answer should report
|
||||
an error (Not yet implemented).
|
||||
|
||||
Attributes in response can also be provided with other means than from an LDAP
|
||||
source. Attributes can be put in the user Django session and then loaded in
|
||||
the profile. An option of the service provier indicate if attributes in the
|
||||
session must be provided to the service provider.
|
||||
|
||||
To have the attribute loaded from the session, they must be provided in the
|
||||
session as follows:
|
||||
request.session['attributes'][source_name] = list()
|
||||
|
||||
The source_name must be the name of an existing instance of an
|
||||
'AttributeSource'. Such an instance contains a field namespace indicating the
|
||||
namespace of attributes.
|
||||
|
||||
This is currently implemented only for the SAML2 service provider module of
|
||||
authentic2. Authsaml2, the SP module, parse the assertion and put the
|
||||
attributes in the session.
|
||||
|
||||
::
|
||||
|
||||
if not 'multisource_attributes' in request.session:
|
||||
request.session['attributes'] = dict{}
|
||||
request.session['multisource_attributes'] \
|
||||
[login.assertion.issuer.content] = attributes
|
||||
|
||||
Then, Authentic2 can be used as a SAML2 proxy forwarding attributes in
|
||||
assertion, eventually doing a namespace mapping. For this, the option
|
||||
forward attributes in sesion must be set (by default False).
|
||||
|
|
|
@ -0,0 +1,438 @@
|
|||
.. _attribute_management_explained:
|
||||
|
||||
Attribute management machinery explained (attribute_aggregator module)
|
||||
======================================================================
|
||||
|
||||
Attribute aggegrator module
|
||||
---------------------------
|
||||
|
||||
The core attribute management is based on the attribute aggregator module.
|
||||
|
||||
Intro
|
||||
_____
|
||||
|
||||
Attribute aggregator provides a main Model class called UserAttributeProfile,
|
||||
functions to load attributes and extract attributes.
|
||||
|
||||
The mapping between attribute namespaces is built-in and depends on a unique
|
||||
file (mapping.py).
|
||||
|
||||
A main schema is defined and is based on LDAP/X500 for naming. The support
|
||||
of http://schemas.xmlsoap.org/ws/2005/05/identity/claims is partly complete.
|
||||
|
||||
Source of attributes are connected with attribute loading functions using
|
||||
signals.
|
||||
|
||||
FAQ
|
||||
___
|
||||
|
||||
Why not use the Django User profile?
|
||||
|
||||
The django user profile needs to define attributes as class attributes and
|
||||
then support form filling or mapping with LDAP.
|
||||
|
||||
That is useful and may be used, especially because the profile can be used as
|
||||
a source of attribute to load in the attribute_aggregator profile.
|
||||
|
||||
The attribute_aggregator profile allow to load multivalued attributes from any
|
||||
source supported (LDAP, Django profile and attributes in Django session for
|
||||
now) from any namespace defined in mapping.py (LDAP/X500 and claims for now).
|
||||
|
||||
The profile can be loaded giving a source or a list of attribute, or can be
|
||||
from any known source, or with a dictionnary.
|
||||
|
||||
Attributes can be extracted with many functions in any namespace supported.
|
||||
|
||||
Quick explanation
|
||||
_________________
|
||||
|
||||
The schema is defined in mapping.py and is made of definitions like this::
|
||||
|
||||
"sn": {
|
||||
"oid": "2.5.4.4",
|
||||
"display_name": _("sn surname"),
|
||||
"alias": ['surname'],
|
||||
"profile_field_name": 'last_name',
|
||||
"type": "http://www.w3.org/2001/XMLSchema#string",
|
||||
"namespaces": {
|
||||
"http://schemas.xmlsoap.org/ws/2005/05/identity/claims": {
|
||||
"identifiers":
|
||||
[
|
||||
"http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname",
|
||||
],
|
||||
"friendly_names":
|
||||
[
|
||||
"Last Name",
|
||||
],
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
The profile store all the data in a text field taht contains a cPickle list of
|
||||
instances of the class AttributeData.
|
||||
|
||||
The profile is attached to a user and then can be created or loaded with::
|
||||
|
||||
profile = load_or_create_user_profile(user=user)
|
||||
|
||||
User may be None to create a temporary profile for an anonymous user. But
|
||||
that need a DB cleaning function not implemented.
|
||||
|
||||
The model *UserAttributeProfile*
|
||||
________________________________
|
||||
|
||||
The model 'UserAttributeProfile' can be attached to a user and then persist
|
||||
(as a Model).
|
||||
|
||||
When the profile is loaded, all data stored are removed expect if the
|
||||
the data has an expiration date later.
|
||||
|
||||
The profile provide several methods to store and extract attributes.
|
||||
|
||||
All the methods to add attributes are based on a main one accepting a
|
||||
dictionnary of attribute is parameters 'load_by_dic()'. The other methods
|
||||
('load_listed_attributes()', 'load_greedy()') send a signal with a list of
|
||||
attributes (listed_attributes_call) or not (any_attributes_call) to grab a
|
||||
dictionnary. The list is given with the definition name, oid or friendly name
|
||||
of the attribute in the system namespace.
|
||||
|
||||
Into the dictionnary, attributes are given with their name, oid or friendly
|
||||
name in the default namespace or with their name in a namepsace. An expiration
|
||||
date can also be given (ISO8601 format), if none, attribute will be deleted at
|
||||
next profile loading. The dictionnary format is as follows::
|
||||
|
||||
attributes = dict()
|
||||
data_from_source = list()
|
||||
a1 = dict()
|
||||
a1['oid'] = definition_name
|
||||
Or
|
||||
a1['definition'] = definition_name
|
||||
definition may be the definition name like 'gn'
|
||||
or an alias like 'givenName'
|
||||
Or
|
||||
a1['name'] = attribute_name_in_ns
|
||||
a1['namespace'] = ns_name
|
||||
a1['expiration_date'] = date
|
||||
a1['values'] = list_of_values
|
||||
data_from_source.append(a1)
|
||||
...
|
||||
data_from_source.append(a2)
|
||||
attributes[source_name] = data_from_source
|
||||
|
||||
Getters are defined to extract data from a profile. Only AttributeData
|
||||
instances are extracted that assume that any attribute namespace can be used.
|
||||
|
||||
* get_data_of_definition(definition)
|
||||
|
||||
Return a list of AttributeData instances corresponding to the definition
|
||||
given.
|
||||
|
||||
* get_freshest_data_of_definition(definition)
|
||||
|
||||
Return the freshest AttributeData instance. If multiple with no or same exp
|
||||
date, random. Should use the creation date soon.
|
||||
|
||||
* get_data_of_source
|
||||
|
||||
Return a list of AttributeData instances corresponding to the source given.
|
||||
|
||||
* get_data_of_source_by_name
|
||||
|
||||
Idem but source name is given, not a Source instance.
|
||||
|
||||
* get_data_of_definition_and_source
|
||||
|
||||
Return a list of AttributeData instances corresponding to the definition and
|
||||
source given.
|
||||
|
||||
* get_data_of_definition_and_source_by_name
|
||||
|
||||
Idem but source name is given, not a Source instance.
|
||||
|
||||
SAML2 attribute representation in assertions
|
||||
--------------------------------------------
|
||||
|
||||
SAML2 attribute profile (saml-profiles-2.0-os - Section 8) defines two kind of
|
||||
attribute element syntax in the attribute statement of assertions, also
|
||||
called *name format*:
|
||||
|
||||
- BASIC::
|
||||
|
||||
NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic"
|
||||
|
||||
- URI::
|
||||
|
||||
NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"
|
||||
|
||||
*URI should be used when attributes have "universally" known unique names
|
||||
like OID.*
|
||||
|
||||
Example::
|
||||
|
||||
<saml:Attribute NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic"
|
||||
Name="FirstName">
|
||||
<saml:AttributeValue xsi:type="xs:string">By-Tor</saml:AttributeValue>
|
||||
</saml:Attribute>
|
||||
|
||||
<saml:Attribute
|
||||
xmlns:x500="urn:oasis:names:tc:SAML:2.0:profiles:attribute:X500"
|
||||
NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"
|
||||
Name="urn:oid:2.5.4.42" FriendlyName="givenName">
|
||||
<saml:AttributeValue xsi:type="xs:string"
|
||||
x500:Encoding="LDAP">Steven</saml:AttributeValue>
|
||||
</saml:Attribute>
|
||||
|
||||
|
||||
BASIC
|
||||
_____
|
||||
|
||||
|
||||
Two <Attribute> elements refer to the same SAML attribute if and only if the
|
||||
values of their Name XML attributes are equal in the sense of Section 3.3.6 of
|
||||
[Schema2].
|
||||
|
||||
No additional XML attributes are defined for use with the <Attribute> element.
|
||||
|
||||
The schema type of the contents of the <AttributeValue> element MUST be drawn
|
||||
from one of the types defined in Section 3.3 of [Schema2]. The xsi:type
|
||||
attribute MUST be present and be given the appropriate value.
|
||||
|
||||
X.500/LDAP Attribute Profile (URI)
|
||||
__________________________________
|
||||
|
||||
**Extracted from the SAML2 core specifications**
|
||||
|
||||
Two <Attribute> elements refer to the same SAML attribute if and only if their
|
||||
Name XML attribute values are equal in the sense of [RFC3061]. The
|
||||
FriendlyName attribute plays no role in the comparison.
|
||||
|
||||
Directory attribute type definitions for use in native X.500 directories
|
||||
specify the syntax of the attribute using ASN.1 [ASN.1]. For use in LDAP,
|
||||
directory attribute definitions additionally include an LDAP syntax which
|
||||
specifies how attribute or assertion values conforming to the syntax are to be
|
||||
represented when transferred in the LDAP protocol (known as an LDAP-specific
|
||||
encoding). The LDAP-specific encoding commonly produces Unicode characters in
|
||||
UTF-8 form. This SAML attribute profile specifies the form of SAML attribute
|
||||
values only for those directory attributes which have LDAP syntaxes. Future
|
||||
extensions to this profile may define attribute value formats for directory
|
||||
attributes whose syntaxes specify other encodings.
|
||||
|
||||
To represent the encoding rules in use for a particular attribute value, the
|
||||
<AttributeValue> element MUST contain an XML attribute named Encoding defined
|
||||
in the XML namespace urn:oasis:names:tc:SAML:2.0:profiles:attribute:X500.
|
||||
|
||||
For any directory attribute with a syntax whose LDAP-specific encoding
|
||||
exclusively produces UTF-8 character strings as values, the SAML attribute
|
||||
value is encoded as simply the UTF-8 string itself, as the content of the
|
||||
<AttributeValue> element, with no additional whitespace.
|
||||
In such cases, the xsi:type XML attribute MUST be set to xs:string.
|
||||
The profile-specific Encoding XML attribute is provided, with a value of LDAP.
|
||||
|
||||
The AttributeData instances have a field expiration_data. It the profile
|
||||
exists, obsolete data are removed at loading.
|
||||
|
||||
|
||||
When authentic 2 deals with attributes and needs mapping?
|
||||
---------------------------------------------------------
|
||||
|
||||
Authentic2 behaves as an attribute provider:
|
||||
* At the SSO login
|
||||
* When an attribute request is received
|
||||
|
||||
Authentic requests (e.g. by soap) are not yet supported.
|
||||
|
||||
When Authentic2 behaves as an attribute provider at SSO login
|
||||
_____________________________________________________________
|
||||
|
||||
At a SSO request, just before responding to the service provider, the saml2
|
||||
idp module sends the signal 'add_attributes_to_response' giving the SP entity
|
||||
ID.
|
||||
|
||||
The signal is connected to the function 'provide_attributes_at_sso()' in
|
||||
charge of providing the attributes at the SSO for this SP.
|
||||
|
||||
**Attributes sources are of two kinds. The first ones are the sources that can
|
||||
be requested by the IdP with a syncrhonous binding without user intercations.
|
||||
These sources are called pull sources. They are for now limited to LDAP
|
||||
sources. The other ones are sources are asyncrhonous bindings, usually
|
||||
requiring user interactions. These sources are called push sources. They are
|
||||
now limited to the attributes provided at SSO requests when the IdP acts as a
|
||||
SAML2 SP. There attributes are put/found in the Django session.**
|
||||
|
||||
Each source in the system is declared with an instance of the AttributeSource
|
||||
model. We'll see later that to forward attributes of push sources it is not
|
||||
necessary that a source is declared in some circumstances.
|
||||
|
||||
To manage these sources an attribute policy is attached to services providers.
|
||||
Then the service provider model must be extended with a attribute
|
||||
attributes_at_sso_policy. The service provider must send the signal
|
||||
'add_attributes_to_response'.
|
||||
|
||||
The implementation is actually done for SAML2 providers.
|
||||
|
||||
**In such a policy attributes from pull and push sources are treated
|
||||
differently.**
|
||||
|
||||
**For pull sources, a list of attributes is indicated. Either an attribute is
|
||||
searched in all the pull sources and whatever attribute value found is
|
||||
returned. Or each attribute is indicated with a source. With each attribute is
|
||||
indicated the output format and namespace.**
|
||||
|
||||
**The policy may also indicate that all the attributes in the Django session
|
||||
must be forwarded. Then, no AttributeSource instance is required. All the
|
||||
attributes are then forwarded without treating input namespace considerations.
|
||||
When an AttributeSource instance is found, the input namespace of this source
|
||||
is considered. An option can then be set to tell that the output format and
|
||||
namespace must be taken. A list of attribute can also be given.
|
||||
This list can be use to filter attributes to forward without or without taking
|
||||
care of the source. The output namespace and format can also be trated per
|
||||
attribute.**
|
||||
|
||||
If the namespace is default, the attribute names will be taken from the
|
||||
system namespace. In BASIC the name will be the definition name. In URI, the
|
||||
Name will be the OID in urn format and the friendly name will be the
|
||||
definition name. If a namespace is given, the first identifier of this
|
||||
attribute is taken as Name in BASIC. In URI, the same and the first friendly
|
||||
name is taken.
|
||||
|
||||
::
|
||||
|
||||
class LibertyServiceProvider(models.Model):
|
||||
...
|
||||
attribute_policy = models.ForeignKey(AttributePolicy,
|
||||
verbose_name=_("Attribute policy"), null=True, blank=True)
|
||||
|
||||
class AttributePolicy(models.Model):
|
||||
# List of attributes to provide from pull sources at SSO Login.
|
||||
# If an attribute is indicate without a source, from any source.
|
||||
# The output format and namespace is given by each attribute.
|
||||
attribute_list_for_sso_from_pull_sources = \
|
||||
models.ForeignKey(LibertyAttributeMap,
|
||||
related_name = "attributes of pull sources",
|
||||
blank = True, null = True)
|
||||
|
||||
# Set to true for proxying attributes from pull sources at SSO Login.
|
||||
# Attributes are in session.
|
||||
# All attributes are forwarded as is except if the parameter
|
||||
# 'attribute_list_for_sso_from_push_sources' is initialized
|
||||
forward_attributes_from_pull_sources = models.BooleanField(default=False)
|
||||
|
||||
# Map attributes in session
|
||||
# forward_attributes_in_session must be true
|
||||
# At False, all attributes are forwarded as is
|
||||
# At true, look for the namespace of the source for input, If not found,
|
||||
# system namespace. Look for the options attribute_name_format and
|
||||
# output_namespace of the attribute policy for output.
|
||||
map_attributes_from_pull_sources = models.BooleanField(default=False)
|
||||
|
||||
# ATTRIBUTE_VALUE_FORMATS[0] =>
|
||||
# (lasso.SAML2_ATTRIBUTE_NAME_FORMAT_BASIC, 'SAMLv2 BASIC')
|
||||
output_name_format = models.CharField(max_length = 100,
|
||||
choices = ATTRIBUTE_VALUE_FORMATS,
|
||||
default = ATTRIBUTE_VALUE_FORMATS[0])
|
||||
|
||||
#ATTRIBUTES_NS[0] => ('Default', 'Default')
|
||||
output_namespace = models.CharField(max_length = 100,
|
||||
choices = ATTRIBUTES_NS, default = ATTRIBUTES_NS[0])
|
||||
|
||||
# Filter attributes pushed from source.
|
||||
source_filter_for_sso_from_push_sources = \
|
||||
models.ManyToManyField(AttributeSource,
|
||||
related_name = "attributes of pull sources",
|
||||
blank = True, null = True)
|
||||
|
||||
# List of attributes to filter from pull sources at SSO Login.
|
||||
attribute_filter_for_sso_from_push_sources = \
|
||||
models.ForeignKey(LibertyAttributeMap,
|
||||
related_name = "attributes of pull sources",
|
||||
blank = True, null = True)
|
||||
|
||||
# The sources of attributes of the previous list are considered.
|
||||
# May be used conjointly with 'source_filter_for_sso_from_push_sources'
|
||||
filter_source_of_filtered_attributes = models.BooleanField(default=False)
|
||||
|
||||
# To map the attributes of forwarded attributes with the defaut output
|
||||
# format and namespace, use 'map_attributes_from_pull_sources'
|
||||
# Use the following option to use the output format and namespace
|
||||
# indicated for each attribute.
|
||||
map_attributes_of_filtered_attributes = models.BooleanField(default=False)
|
||||
|
||||
|
||||
# Set to true to take in account missing required attributes
|
||||
send_error_and_no_attrs_if_missing_required_attrs = \
|
||||
models.BooleanField(default=False)
|
||||
|
||||
class Meta:
|
||||
verbose_name = _('attribute options policy')
|
||||
verbose_name_plural = _('attribute options policies')
|
||||
|
||||
|
||||
class AttributeList(models.Model):
|
||||
name = models.CharField(max_length = 40, unique = True)
|
||||
attributes = models.ManyToManyField(AttributeItem,
|
||||
related_name = "attributes of the list",
|
||||
blank = True, null = True)
|
||||
|
||||
|
||||
class AttributeItem(models.Model):
|
||||
attribute_name = models.CharField(max_length = 100, choices = ATTRIBUTES,
|
||||
default = ATTRIBUTES[0])
|
||||
# ATTRIBUTE_VALUE_FORMATS[0] =>
|
||||
# (lasso.SAML2_ATTRIBUTE_NAME_FORMAT_BASIC, 'SAMLv2 BASIC')
|
||||
output_attribute_name_format = models.CharField(max_length = 100,
|
||||
choices = ATTRIBUTE_VALUE_FORMATS,
|
||||
default = ATTRIBUTE_VALUE_FORMATS[0])
|
||||
#ATTRIBUTES_NS[0] => ('Default', 'Default')
|
||||
output_namespace = models.CharField(max_length = 100,
|
||||
choices = ATTRIBUTES_NS, default = ATTRIBUTES_NS[0])
|
||||
required = models.BooleanField(default=False)
|
||||
source = models.ForeignKey(AttributeSource, blank = True, null = True)
|
||||
|
||||
|
||||
A list of attributes can also be taken from the service provider metadata and
|
||||
added to 'attribute_list_for_sso_from_pull_sources'. The namespace may be
|
||||
extracted from the metadata. This namespace is then used to look for the
|
||||
corresponding definition and then to provide the attribute in the right
|
||||
namespace. Read attributes from metadata is not yet supported.
|
||||
|
||||
For the attributes of pull sources, once the list of attributes is defined,
|
||||
They are loaded in the user profile.
|
||||
|
||||
As explained before the attribute_aggregator loading function send signals to
|
||||
grab dictionnary of attributes. Up to know, only the ldap loading function are
|
||||
connected to these signals. The namespace of LDAP sources is assumed to be
|
||||
the same as the system namespace. There is here then no mapping needed. Other
|
||||
kind of sources than LDAP can be defined in attribute aggregator.
|
||||
|
||||
To grab attributes from a LDAP the user dn in the LDAP or at least a local
|
||||
identifier in the LDAP is required. For this purpose, each user has alias
|
||||
associated with LDAP source. These aliases must their DN in the LDAP. When
|
||||
the authentication LDAP backend will be taken in account, the dn will be taken
|
||||
direclty from the user Model instance.
|
||||
|
||||
Each LDAP sources are declared with the binding parameters. The LDAP namespace
|
||||
is always 'Default'.
|
||||
|
||||
If an attribute to load is not found and is required the answer should report
|
||||
an error (Not yet implemented).
|
||||
|
||||
Attributes in response can also be provided with other means than from an LDAP
|
||||
source. Attributes can be put in the user Django session and then loaded in
|
||||
the profile. An option of the service provier indicate if attributes in the
|
||||
session must be provided to the service provider.
|
||||
|
||||
To have the attribute loaded from the session, they must be provided in the
|
||||
session as follows:
|
||||
request.session['attributes'][source_name] = list()
|
||||
|
||||
The source_name must be the name of an existing instance of an
|
||||
'AttributeSource'. Such an instance contains a field namespace indicating the
|
||||
namespace of attributes.
|
||||
|
||||
This is currently implemented only for the SAML2 service provider module of
|
||||
authentic2. Authsaml2, the SP module, parse the assertion and put the
|
||||
attributes in the session.
|
||||
|
||||
Then, Authentic2 can be used as a SAML2 proxy forwarding attributes in
|
||||
assertion, eventually doing a namespace mapping. For this, the option
|
||||
forward attributes in sesion must be set (by default False).
|
|
@ -0,0 +1,44 @@
|
|||
.. _attributes_in_session:
|
||||
|
||||
==============================================================
|
||||
Attributes in session pushed by third SAML2 identity providers
|
||||
==============================================================
|
||||
|
||||
When an assertion is received, assertion data, including attributes, are
|
||||
pushed in the Django session dictionnary.
|
||||
|
||||
It leads to the creation of the following dictionnary::
|
||||
|
||||
request.session['multisource_attributes']
|
||||
|
||||
The keys of the dictionnary are the source names, i.e. the entity Id for
|
||||
SAML2 identity providers.
|
||||
|
||||
The values are list of data extracted from assertions. Indeed, this is done
|
||||
to store multiple assertion received from a same source in a same Django
|
||||
session::
|
||||
|
||||
request.session['multisource_attributes'] \
|
||||
[source_name] = list()
|
||||
|
||||
The items of this list are dictionnaries with the keys 'certificate_type' and
|
||||
'attributes'.
|
||||
|
||||
For a saml2 assertion, all the keys are::
|
||||
|
||||
a8n['certificate_type'] = 'SAML2_assertion'
|
||||
a8n['nameid'] = ...
|
||||
a8n['subject_confirmation_method'] = ...
|
||||
a8n['not_before'] = ...
|
||||
a8n['not_on_or_after'] = ...
|
||||
a8n['authn_context'] = ...
|
||||
a8n['authn_instant'] = ...
|
||||
a8n['attributes'] = attrs
|
||||
|
||||
a8n['attributes'] has the following structure::
|
||||
|
||||
attributes = {}
|
||||
attributes[name] = (value1, value2, )
|
||||
attributes[(name, format)] = (value1, value2, )
|
||||
attributes[(name, format, nickname)] = (value1, value2, )
|
||||
a8n['attributes'] = attributes
|
|
@ -55,6 +55,10 @@ Documentation content
|
|||
|
||||
attribute_management
|
||||
|
||||
attribute_management_explained
|
||||
|
||||
attributes_in_session
|
||||
|
||||
Copyright
|
||||
=========
|
||||
|
||||
|
|
After Width: | Height: | Size: 87 KiB |
After Width: | Height: | Size: 88 KiB |
After Width: | Height: | Size: 87 KiB |
After Width: | Height: | Size: 84 KiB |
After Width: | Height: | Size: 78 KiB |
After Width: | Height: | Size: 87 KiB |
After Width: | Height: | Size: 24 KiB |
After Width: | Height: | Size: 30 KiB |
After Width: | Height: | Size: 33 KiB |