Skip to content

Commit

Permalink
Merge pull request #103 from skoranda/user_id_from_attrs
Browse files Browse the repository at this point in the history
NameID input from attributes for LDAP attribute store
  • Loading branch information
johanlundberg authored Jun 8, 2017
2 parents 2daaaa0 + e9ba69d commit 86c5eae
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 2 deletions.
3 changes: 2 additions & 1 deletion doc/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -527,7 +527,8 @@ correct functionality.
An identifier such as eduPersonPrincipalName asserted by an IdP can be used to look up a person record
in an LDAP directory to find attributes to assert about the authenticated user to the SP. The identifier
to consume from the IdP, the LDAP directory details, and the mapping of attributes found in the
directory may all be confingured on a per-SP basis. To use the
directory may all be confingured on a per-SP basis. The input to use when hashing to create a
persistent NameID may also be obtained from attributes returned from the LDAP directory. To use the
LDAP microservice install the extra necessary dependencies with `pip install satosa[ldap]` and then see the
[example config](../example/plugins/microservices/ldap_attribute_store.yaml.example).

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ config:
# Whether to clear values for attributes incoming
# to this microservice. Default is no or false.
clear_input_attributes: no
# List of LDAP attributes to use as input to hashing to create
# NameID.
user_id_from_attrs:
- employeeNumber
# Configuration may also be done per-SP with any
# missing parameters taken from the default if any.
# The configuration key is the entityID of the SP.
Expand All @@ -26,3 +30,5 @@ config:
https://sp.myserver.edu/shibboleth-sp
search_base: ou=People,o=MyVO,dc=example,dc=org
eduPersonPrincipalName: employeenumber
user_id_from_attrs:
- uid
34 changes: 33 additions & 1 deletion src/satosa/micro_services/ldap_attribute_store.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,12 @@ def process(self, context, data):
clear_input_attributes = self.config['clear_input_attributes']
else:
clear_input_attributes = False
if 'user_id_from_attrs' in config:
user_id_from_attrs = config['user_id_from_attrs']
elif 'user_id_from_attrs' in self.config:
user_id_from_attrs = self.config['user_id_from_attrs']
else:
user_id_from_attrs = []

except KeyError as err:
satosa_logging(logger, logging.ERROR, "{} Configuration '{}' is missing".format(logprefix, err), context.state)
Expand Down Expand Up @@ -153,15 +159,41 @@ def process(self, context, data):
satosa_logging(logger, logging.DEBUG, "{} Clearing values for these input attributes: {}".format(logprefix, data.attributes), context.state)
data.attributes = {}

# Use a found record, if any, to populate attributes
# Use a found record, if any, to populate attributes and input for NameID
if record:
satosa_logging(logger, logging.DEBUG, "{} Using record with DN {}".format(logprefix, record["dn"]), context.state)
satosa_logging(logger, logging.DEBUG, "{} Record with DN {} has attributes {}".format(logprefix, record["dn"], record["attributes"]), context.state)

# Populate attributes as configured.
for attr in search_return_attributes.keys():
if attr in record["attributes"]:
data.attributes[search_return_attributes[attr]] = record["attributes"][attr]
satosa_logging(logger, logging.DEBUG, "{} Setting internal attribute {} with values {}".format(logprefix, search_return_attributes[attr], record["attributes"][attr]), context.state)

# Populate input for NameID if configured. SATOSA core does the hashing of input
# to create a persistent NameID.
if user_id_from_attrs:
userId = ""
for attr in user_id_from_attrs:
if attr in record["attributes"]:
value = record["attributes"][attr]
if isinstance(value, list):
# Use a default sort to ensure some predictability since the
# LDAP directory server may return multi-valued attributes
# in any order.
value.sort()
for v in value:
userId += v
satosa_logging(logger, logging.DEBUG, "{} Added attribute {} with value {} to input for NameID".format(logprefix, attr, v), context.state)
else:
userId += value
satosa_logging(logger, logging.DEBUG, "{} Added attribute {} with value {} to input for NameID".format(logprefix, attr, value), context.state)
if not userId:
satosa_logging(logger, logging.WARNING, "{} Input for NameID is empty so not overriding default".format(logprefix), context.state)
else:
data.user_id = userId
satosa_logging(logger, logging.DEBUG, "{} Input for NameID is {}".format(logprefix, data.user_id), context.state)

else:
satosa_logging(logger, logging.WARN, "{} No record found in LDAP so no attributes will be added".format(logprefix), context.state)

Expand Down

0 comments on commit 86c5eae

Please # to comment.