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: 722
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
Contributor
Posts: 49
Registered: ‎07-05-2018

Re: HUE 3.9 saml login.

@sudhakarv 

 

hello Sudhakar,

 

I need your help for one of my requirement in hue integration with saml?

 

Can you help me to understand the use of proprty user_attribute_mapping in hue config, what it is for and how it works.

 

Actually i am looking for if user getting authenticated with name vijay and if idp returns values as vijay, 1123(uid), Email addess,  how can i map this attributes with Hue attributes?

 

In cloudera documentation it mention user_attribute_mapping used to map IDP attributes with Hue django attributes, what is Hue Django attributes?

 

Can you show me working example of ur Hue + saml and when user tried to access hue web ui what happens?

 

- Vijay M

Posts: 1,028
Topics: 1
Kudos: 257
Solutions: 127
Registered: ‎04-22-2014

Re: HUE 3.9 saml login.

@VijayM,

 

user_attribute_mapping is used to map an attribute returned by your IDP to the "username" attribute used by Django as the user that will log into Hue.  If, for instance, your IDP returns an attribute with the name "uid" that you want to use as the value for your Hue username, then you could use the following:

 

user_attribute_mapping='{"uid":"username"}'

 

I am almost certain that Hue does not use any other attribute values from the SAML response.

 

Do you have an example of what your IDP emits in terms of the "uid" attribute?  If you can share the XML it might be easier to guide toward configuration.

Contributor
Posts: 49
Registered: ‎07-05-2018

Re: HUE 3.9 saml login.

@bgooley 

 

Let me check and get back to you.

 

My requirement is if idp return uid as "Vijay" then i want by someway this get converted into "Ajay" and on Hue UI username logged in shows as "Ajay".

 

Is there any way i can achieve it?

 

- Vijay M

Posts: 1,028
Topics: 1
Kudos: 257
Solutions: 127
Registered: ‎04-22-2014

Re: HUE 3.9 saml login.

@VijayM,

 

Hue doesn't do name translation, so you would have to find another way to achieve this.  Is there an IDP attribute that you could have returned in the SAML response that Hue could use to pull the value "Ajay"?

 

Basically, you would want to do anything like this with names at the IDP side so that Hue can get the attribute/value from your IDP response.

Highlighted
Contributor
Posts: 49
Registered: ‎07-05-2018

Re: HUE 3.9 saml login.

@bgooley 

 

idp only returns Name of user but it is not similar to Unix Username due to which sentry authorization will not work becuase authorization provided on Unix user group.

 

Can you suggest for any method/way or sample example through which i can perform name translation?

 

- VIjay M