Reply
Explorer
Posts: 14
Registered: ‎06-13-2016

HUE 3.9 saml login.

Hi.
I'm trying to configure HUE for saml login with CDH5.7.1 parcels.

 

First I can't get the user_attribure_mapping directive in hue.ini to work. We use Cloudera Manager so configured it in "hue/config/service-wide/Hue Service Advanced Configuration Snippet (Safety Valve) for hue_safety_valve.ini"

 

[libsaml]
required_attributes=emailAddress,givenName,surname,nameId
username_source=attributes
user_attribute_mapping={'nameId': ('username',), 'emailAddress': ('email',), 'givenName' : ('first_name',), 'surname': ('last_name', )}

 

Here is the error msg from hue.error log in debug. 

[01/Sep/2016 12:08:33 +0000] backends ERROR Session info or attribute mapping are None
[01/Sep/2016 12:08:33 +0000] views ERROR The user is None

 

Session info is not empty, it's the attribute_mapping that's not updated with any value from hue.ini.

 

When hard coding it as the default value in $HUE_HOME/desktop/libs/libsaml/src/libsaml/conf.py it works.

 

USER_ATTRIBUTE_MAPPING = Config(
key="user_attribute_mapping",
#default={'uid': ('username', )},
default={'nameId': ('username',), 'emailAddress': ('email',), 'givenName' : ('first_name',), 'surname': ('last_name', )},
type=dict_list_map,
help=_t("A mapping from attributes in the response from the IdP to django user attributes."))

 

Second problem is that previously when using ldap login the hdfs user folder was created during login, this isn't done when using libsaml.

 

I have added the "create_users_on_login=true" for libsaml in hue.ini but not sure if this directive just creates the users in the hue DB or if it should create the hdfs home folder for the username that login?

 

If not, is there a way to get HUE/libsaml to create the hdfs user folder as when using ldap login for hue?
We could script it but if there is a way to get hue/libsaml to do it I would prefer that.

 

/Jesper

Cloudera Employee
Posts: 701
Registered: ‎07-30-2013

Re: HUE 3.9 saml login.

1.
Have you tried with double quotes around "{'nameId': ('username',),
'emailAddress': ('email',), 'givenName' : ('first_name',), 'surname':
('last_name', )}"?

2.
Created https://issues.cloudera.org/browse/HUE-4790 for creating HDFS
directory (right now create_users_on_login means create the users in Hue)
Explorer
Posts: 14
Registered: ‎06-13-2016

Re: HUE 3.9 saml login.

[ Edited ]

Hi. 

 

Thanks for your reply!

 

Yes, I tried that.

 

When I add user_attribute_mapping="{'nameId': ('username',), 'emailAddress': ('email',), 'givenName' : ('first_name',), 'surname': ('last_name', )}" to hue_safety_valve_server.ini  hue server throws this exemption. 

 

 

+ /opt/cloudera/parcels/CDH-5.7.1-1.cdh5.7.1.p0.11/lib/hue/build/env/bin/hue migrate --merge
[08/Sep/2016 12:26:08 +0000] settings     DEBUG    DESKTOP_DB_TEST_NAME SET: /opt/cloudera/parcels/CDH-5.7.1-1.cdh5.7.1.p0.11/lib/hue/desktop/desktop-test.db
[08/Sep/2016 12:26:08 +0000] settings     DEBUG    DESKTOP_DB_TEST_USER SET: hue_test
Traceback (most recent call last):
  File "/opt/cloudera/parcels/CDH-5.7.1-1.cdh5.7.1.p0.11/lib/hue/build/env/bin/hue", line 12, in <module>
    load_entry_point('desktop==3.9.0', 'console_scripts', 'hue')()
  File "/opt/cloudera/parcels/CDH-5.7.1-1.cdh5.7.1.p0.11/lib/hue/desktop/core/src/desktop/manage_entry.py", line 57, in entry
    execute_from_command_line(sys.argv)
  File "/opt/cloudera/parcels/CDH-5.7.1-1.cdh5.7.1.p0.11/lib/hue/build/env/lib/python2.7/site-packages/Django-1.6.10-py2.7.egg/django/core/management/__init__.py", line 399, in execute_from_command_line
    utility.execute()
  File "/opt/cloudera/parcels/CDH-5.7.1-1.cdh5.7.1.p0.11/lib/hue/build/env/lib/python2.7/site-packages/Django-1.6.10-py2.7.egg/django/core/management/__init__.py", line 392, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "/opt/cloudera/parcels/CDH-5.7.1-1.cdh5.7.1.p0.11/lib/hue/build/env/lib/python2.7/site-packages/Django-1.6.10-py2.7.egg/django/core/management/__init__.py", line 261, in fetch_command
    commands = get_commands()
  File "/opt/cloudera/parcels/CDH-5.7.1-1.cdh5.7.1.p0.11/lib/hue/build/env/lib/python2.7/site-packages/Django-1.6.10-py2.7.egg/django/core/management/__init__.py", line 107, in get_commands
    apps = settings.INSTALLED_APPS
  File "/opt/cloudera/parcels/CDH-5.7.1-1.cdh5.7.1.p0.11/lib/hue/build/env/lib/python2.7/site-packages/Django-1.6.10-py2.7.egg/django/conf/__init__.py", line 54, in __getattr__
    self._setup(name)
  File "/opt/cloudera/parcels/CDH-5.7.1-1.cdh5.7.1.p0.11/lib/hue/build/env/lib/python2.7/site-packages/Django-1.6.10-py2.7.egg/django/conf/__init__.py", line 49, in _setup
    self._wrapped = Settings(settings_module)
  File "/opt/cloudera/parcels/CDH-5.7.1-1.cdh5.7.1.p0.11/lib/hue/build/env/lib/python2.7/site-packages/Django-1.6.10-py2.7.egg/django/conf/__init__.py", line 128, in __init__
    mod = importlib.import_module(self.SETTINGS_MODULE)
  File "/opt/cloudera/parcels/CDH-5.7.1-1.cdh5.7.1.p0.11/lib/hue/build/env/lib/python2.7/site-packages/Django-1.6.10-py2.7.egg/django/utils/importlib.py", line 40, in import_module
    __import__(name)
  File "/opt/cloudera/parcels/CDH-5.7.1-1.cdh5.7.1.p0.11/lib/hue/desktop/core/src/desktop/settings.py", line 391, in <module>
    from libsaml.saml_settings import *
  File "/opt/cloudera/parcels/CDH-5.7.1-1.cdh5.7.1.p0.11/lib/hue/desktop/libs/libsaml/src/libsaml/saml_settings.py", line 105, in <module>
    SAML_ATTRIBUTE_MAPPING = libsaml.conf.USER_ATTRIBUTE_MAPPING.get()
  File "/opt/cloudera/parcels/CDH-5.7.1-1.cdh5.7.1.p0.11/lib/hue/desktop/core/src/desktop/lib/conf.py", line 147, in get
    return self.config.get_value(data, present=present, prefix=self.prefix, coerce_type=True)
  File "/opt/cloudera/parcels/CDH-5.7.1-1.cdh5.7.1.p0.11/lib/hue/desktop/core/src/desktop/lib/conf.py", line 263, in get_value
    return self._coerce_type(raw_val, prefix)
  File "/opt/cloudera/parcels/CDH-5.7.1-1.cdh5.7.1.p0.11/lib/hue/desktop/core/src/desktop/lib/conf.py", line 283, in _coerce_type
    return self.type(raw)
  File "/opt/cloudera/parcels/CDH-5.7.1-1.cdh5.7.1.p0.11/lib/hue/desktop/libs/libsaml/src/libsaml/conf.py", line 46, in dict_list_map
    for k, v in json.loads(value).iteritems():
  File "/usr/lib64/python2.7/json/__init__.py", line 338, in loads
    return _default_decoder.decode(s)
  File "/usr/lib64/python2.7/json/decoder.py", line 365, in decode
    obj, end = self.raw_decode(s, idx=_w(s, 0).end())
  File "/usr/lib64/python2.7/json/decoder.py", line 381, in raw_decode
    obj, end = self.scan_once(s, idx)
ValueError: Expecting property name: line 1 column 2 (char 1)
+ '[' dumpdata = runcpserver ']'
+ '[' syncdb = runcpserver ']'
+ exec /opt/cloudera/parcels/CDH-5.7.1-1.cdh5.7.1.p0.11/lib/hue/build/env/bin/hue runcpserver
[08/Sep/2016 12:26:09 +0000] settings     DEBUG    DESKTOP_DB_TEST_NAME SET: /opt/cloudera/parcels/CDH-5.7.1-1.cdh5.7.1.p0.11/lib/hue/desktop/desktop-test.db
[08/Sep/2016 12:26:09 +0000] settings     DEBUG    DESKTOP_DB_TEST_USER SET: hue_test
Traceback (most recent call last):
  File "/opt/cloudera/parcels/CDH-5.7.1-1.cdh5.7.1.p0.11/lib/hue/build/env/bin/hue", line 12, in <module>
    load_entry_point('desktop==3.9.0', 'console_scripts', 'hue')()
  File "/opt/cloudera/parcels/CDH-5.7.1-1.cdh5.7.1.p0.11/lib/hue/desktop/core/src/desktop/manage_entry.py", line 57, in entry
    execute_from_command_line(sys.argv)
  File "/opt/cloudera/parcels/CDH-5.7.1-1.cdh5.7.1.p0.11/lib/hue/build/env/lib/python2.7/site-packages/Django-1.6.10-py2.7.egg/django/core/management/__init__.py", line 399, in execute_from_command_line
    utility.execute()
  File "/opt/cloudera/parcels/CDH-5.7.1-1.cdh5.7.1.p0.11/lib/hue/build/env/lib/python2.7/site-packages/Django-1.6.10-py2.7.egg/django/core/management/__init__.py", line 392, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "/opt/cloudera/parcels/CDH-5.7.1-1.cdh5.7.1.p0.11/lib/hue/build/env/lib/python2.7/site-packages/Django-1.6.10-py2.7.egg/django/core/management/__init__.py", line 261, in fetch_command
    commands = get_commands()
  File "/opt/cloudera/parcels/CDH-5.7.1-1.cdh5.7.1.p0.11/lib/hue/build/env/lib/python2.7/site-packages/Django-1.6.10-py2.7.egg/django/core/management/__init__.py", line 107, in get_commands
    apps = settings.INSTALLED_APPS
  File "/opt/cloudera/parcels/CDH-5.7.1-1.cdh5.7.1.p0.11/lib/hue/build/env/lib/python2.7/site-packages/Django-1.6.10-py2.7.egg/django/conf/__init__.py", line 54, in __getattr__
    self._setup(name)
  File "/opt/cloudera/parcels/CDH-5.7.1-1.cdh5.7.1.p0.11/lib/hue/build/env/lib/python2.7/site-packages/Django-1.6.10-py2.7.egg/django/conf/__init__.py", line 49, in _setup
    self._wrapped = Settings(settings_module)
  File "/opt/cloudera/parcels/CDH-5.7.1-1.cdh5.7.1.p0.11/lib/hue/build/env/lib/python2.7/site-packages/Django-1.6.10-py2.7.egg/django/conf/__init__.py", line 128, in __init__
    mod = importlib.import_module(self.SETTINGS_MODULE)
  File "/opt/cloudera/parcels/CDH-5.7.1-1.cdh5.7.1.p0.11/lib/hue/build/env/lib/python2.7/site-packages/Django-1.6.10-py2.7.egg/django/utils/importlib.py", line 40, in import_module
    __import__(name)
  File "/opt/cloudera/parcels/CDH-5.7.1-1.cdh5.7.1.p0.11/lib/hue/desktop/core/src/desktop/settings.py", line 391, in <module>
    from libsaml.saml_settings import *
  File "/opt/cloudera/parcels/CDH-5.7.1-1.cdh5.7.1.p0.11/lib/hue/desktop/libs/libsaml/src/libsaml/saml_settings.py", line 105, in <module>
    SAML_ATTRIBUTE_MAPPING = libsaml.conf.USER_ATTRIBUTE_MAPPING.get()
  File "/opt/cloudera/parcels/CDH-5.7.1-1.cdh5.7.1.p0.11/lib/hue/desktop/core/src/desktop/lib/conf.py", line 147, in get
    return self.config.get_value(data, present=present, prefix=self.prefix, coerce_type=True)
  File "/opt/cloudera/parcels/CDH-5.7.1-1.cdh5.7.1.p0.11/lib/hue/desktop/core/src/desktop/lib/conf.py", line 263, in get_value
    return self._coerce_type(raw_val, prefix)
  File "/opt/cloudera/parcels/CDH-5.7.1-1.cdh5.7.1.p0.11/lib/hue/desktop/core/src/desktop/lib/conf.py", line 283, in _coerce_type
    return self.type(raw)
  File "/opt/cloudera/parcels/CDH-5.7.1-1.cdh5.7.1.p0.11/lib/hue/desktop/libs/libsaml/src/libsaml/conf.py", line 46, in dict_list_map
    for k, v in json.loads(value).iteritems():
  File "/usr/lib64/python2.7/json/__init__.py", line 338, in loads
    return _default_decoder.decode(s)
  File "/usr/lib64/python2.7/json/decoder.py", line 365, in decode
    obj, end = self.raw_decode(s, idx=_w(s, 0).end())
  File "/usr/lib64/python2.7/json/decoder.py", line 381, in raw_decode
    obj, end = self.scan_once(s, idx)
ValueError: Expecting property name: line 1 column 2 (char 1)

 

Here is my complete saftey valve for [libsam] in hue.ini.

 

[libsaml]
xmlsec_binary=/usr/bin/xmlsec1
create_users_on_login=true
metadata_file=/opt/hue/saml/metadata.xml
key_file=/opt/hue/saml/my_key.pem
cert_file=/opt/hue/saml/my_cert.pem
logout_requests_signed=true
required_attributes=emailAddress,givenName,surname,nameId
username_source=attributes
logout_enabled=true
user_attribute_mapping="{'nameId': ('username',), 'emailAddress': ('email',), 'givenName' : ('first_name',), 'surname': ('last_name', )}"
authn_requests_signed=false

 

Thank you for the issue report on the create users!

 

/Jesper

 

 

New Contributor
Posts: 4
Registered: ‎10-03-2017

Re: HUE 3.9 saml login.

[ Edited ]

You might have already figured out the solution, but it might be useful for someone else if I post the solution here.

 

Removing “user_attribute_mapping=” from config file solved same issue for me. It will use following default value from conf.py file.

default={'uid': ('username', )}

Looks like following code in libsaml/conf.py is creating problem.

def dict_list_map(value):
  if isinstance(value, str):
    d = {}
    for k, v in json.loads(value).iteritems():
      d[k] = (v,)
    return d
  elif isinstance(value, dict):
    return value
  return None

USER_ATTRIBUTE_MAPPING = Config(
  key="user_attribute_mapping",
  default={'uid': ('username', )},
  type=dict_list_map,
  help=_t("A mapping from attributes in the response from the IdP to django user attributes."))

It is returning attribute map value as None and  because of this is None, djangosaml2/backends.py is throwing exception at 

if session_info is None or attribute_mapping is None:
            logger.error('Session info or attribute mapping are None')
            return None
Announcements