base64 encoding NameID value

297 views
Skip to first unread message

Jon D Rodder

unread,
Sep 22, 2017, 3:51:16 PM9/22/17
to SimpleSAMLphp
What's the proper way to base64 encode an attribute being used as NameID for an SP (n saml20-sp-remote.php)?

I came up with this, and it works, but it seems like there ought to be a better way:

  'authproc' => array(
    20 => array(
      'class' => 'core:PHP',
      'code' => '
        $guid = $attributes["mS-DS-ConsistencyGuid"][0];
        $attributes["NameID"] = array(base64_encode($guid));
      ',
    ),
    30 => array(
      'class' => 'saml:AttributeNameID',
      'attribute' => 'NameID',
      'Format' => 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent',
    ),

Any suggestions? 

Jaime Perez Crespo

unread,
Sep 25, 2017, 10:59:05 AM9/25/17
to simple...@googlegroups.com
Hi Jon,
I’d say it’s a rather unusual requirement, so your solution looks actually quite good. I would recommend you though to add proper checks to make sure that “mS-DS-ConsistencyGuid” is there, is an array, and has exactly one value. Other than that, provided that attribute is indeed persistent, it looks good.

--
Jaime Pérez
UNINETT / Feide

jaime...@uninett.no
jaime...@protonmail.com
9A08 EA20 E062 70B4 616B 43E3 562A FE3A 6293 62C2

"Two roads diverged in a wood, and I, I took the one less traveled by, and that has made all the difference."
- Robert Frost

Peter Schober

unread,
Sep 25, 2017, 12:59:09 PM9/25/17
to Jon D Rodder
* Jon D Rodder <jlu...@gmail.com> [2017-09-22 21:51]:
> What's the proper way to base64 encode an attribute being used as NameID
> for an SP (n saml20-sp-remote.php)?

Usually you don't. Unless the value you're using must be encoded
(e.g. because it's binary), as is the case with your attribute, it
seems.

> 'authproc' => array(
> 20 => array(
> 'class' => 'core:PHP',
> 'code' => '
> $guid = $attributes["mS-DS-ConsistencyGuid"][0];
> $attributes["NameID"] = array(base64_encode($guid));
> ',
> ),
> 30 => array(
> 'class' => 'saml:AttributeNameID',
> 'attribute' => 'NameID',
> 'Format' => 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent',
> ),


It it works it works. But note the first sentence from the SAML spec
about persistent NameIDs:

"Indicates that the content of the element is a persistent opaque
identifier for a principal that is specific to an identity provider
and a service provider or affiliation of service providers. "
SAML core, 8.3.7, https://www.oasis-open.org/committees/download.php/56776/sstc-saml-core-errata-2.0-wd-07.pdf

I.e., the value should be different for each SP accesses, from the
same IDP and for the same subject. So the above is not really an
appropriate value for SAML2.0 persistent NameIDs.

The Shibboleth wiki also has this to say on the matter:

"It should also be technology-neutral; using a GUID generated by an
Active Directory is a very bad choice that will lead to problems if
you ever change directories."
https://wiki.shibboleth.net/confluence/display/IDP30/PersistentNameIDGenerationConfiguration
All directory-maintained values have this issue, incl. e.g. entryUUID,
which will be recreated (with a different value) when the object is
deleted and created again (e.g. because of a mistake in the IDM system,
or human error).

-peter

Jon D Rodder

unread,
Sep 25, 2017, 9:07:00 PM9/25/17
to SimpleSAMLphp
Thanks for catching that.  Looks like I should be urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress according to the SP's metadata.  

Jon D Rodder

unread,
Sep 25, 2017, 11:19:09 PM9/25/17
to SimpleSAMLphp
Thanks! I added a check to make sure it it exists.  mS-DS-ConsistencyGuid is actually a single value in the Active Directory schema, but the attribute returned by the LDAP module is an array with one value.

I'm surprised this base64 encoding question hasn't come up already--Microsoft is now pushing the use of AD mS-DS-ConsistencyGuid for sync to Azure AD (Office 365) ImmutableID, and requires NameID sent by a SAML IdP to match the AAD ImmutableID.  I guess everyone else uses ADFS for this, or hasn't done a fresh install with a newer Azure AD Connect that uses mS-DS-ConsistencyGuid for its sourceAnchor.

  'authproc' => array(
    20 => array(
      'class' => 'core:PHP',
      'code' => '
        if (empty($attributes["mS-DS-ConsistencyGuid"])) {
            throw new Exception("Missing mS-DS-ConsistencyGuid attribute.");
        }
        $guid = $attributes["mS-DS-ConsistencyGuid"][0];
        $attributes["NameID"] = array(base64_encode($guid));
      ',
    ),
    30 => array(
      'class' => 'saml:AttributeNameID',
      'attribute' => 'NameID',
      'Format' => 'urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress',
    ),

Peter Schober

unread,
Sep 26, 2017, 4:15:34 AM9/26/17
to SimpleSAMLphp
* Jon D Rodder <jlu...@gmail.com> [2017-09-26 05:19]:
> mS-DS-ConsistencyGuid is actually a single value in the Active
> Directory schema, but the attribute returned by the LDAP module is
> an array with one value.

JFYI, attributes within SSP are always processed as arrays, even if the
underlying data is of scalar type.
-peter

Jon D Rodder

unread,
Oct 17, 2018, 11:35:32 AM10/17/18
to SimpleSAMLphp
For anyone who who happens to stumble across this thread in a future Google search, something changed somewhere between SSP 1.15.4 and 1.16.2.  The manual base64 encoding of mS-DS-ConsistencyGuid is no longer needed--it's now already base64 encoded in the attribute array.

  'authproc' => array(
    20 => array(
      'class' => 'core:PHP',
      'code' => '
        if (empty($attributes["mS-DS-ConsistencyGuid"])) {
            throw new Exception("Missing mS-DS-ConsistencyGuid attribute.");
        }
      ',
    ),
    30 => array(
      'class' => 'saml:AttributeNameID',
      'attribute' => 'mS-DS-ConsistencyGuid',
      'Format' => 'urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress',
    ),
    40 => array(
      'class' => 'core:AttributeMap',
      'userPrincipalName' => 'IDPEmail',
    ),
    50 => array(
      'class' => 'core:AttributeLimit',
      'userPrincipalName',
      'IDPEmail',
    ),
  ),

Peter Schober

unread,
Oct 17, 2018, 12:02:45 PM10/17/18
to SimpleSAMLphp
Thanks for sharing. But note that the example you posted is misleading
(to say the least) as the values of the mS-DS-ConsistencyGuid
attribute are not email addresses, and as such shouldn't be used as
values of NameIDs with format emailAddress (d'oh).
If it's not an email address don't claim it is.
-peter

* Jon D Rodder <jlu...@gmail.com> [2018-10-17 17:35]:

Jon D Rodder

unread,
Oct 17, 2018, 1:34:36 PM10/17/18
to SimpleSAMLphp
Thanks for the correction.  This better?

<?php

$metadata['urn:federation:MicrosoftOnline'] = array (
  'entityid' => 'urn:federation:MicrosoftOnline',
  'contacts' => 
  array (
  ),
  'metadata-set' => 'saml20-sp-remote',
  'AssertionConsumerService' => 
  array (
    0 => 
    array (
      'Binding' => 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST',
      'index' => 0,
      'isDefault' => true,
    ),
    1 => 
    array (
      'Binding' => 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST-SimpleSign',
      'index' => 1,
    ),
    2 => 
    array (
      'Binding' => 'urn:oasis:names:tc:SAML:2.0:bindings:PAOS',
      'index' => 2,
    ),
  ),
  'SingleLogoutService' => 
  array (
    0 => 
    array (
      'Binding' => 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST',
    ),
  ),
  'NameIDFormat' => 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent',
  'keys' => 
  array (
    0 => 
    array (
      'encryption' => false,
      'signing' => true,
      'type' => 'X509Certificate',
      'X509Certificate' => 'insert
first cert
here',
    ),
    1 => 
    array (
      'encryption' => false,
      'signing' => true,
      'type' => 'X509Certificate',
      'X509Certificate' => 'insert
second cert
here',
    ),
  ),
  'saml20.sign.assertion' => true,
  'simplesaml.attributes' => true,
  'authproc' => array(
    20 => array(
      'class' => 'core:PHP',
      'code' => '
        if (empty($attributes["mS-DS-ConsistencyGuid"])) {
            throw new Exception("Missing mS-DS-ConsistencyGuid attribute.");
        }
      ',
    ),
    30 => array(
      'class' => 'saml:AttributeNameID',
      'attribute' => 'mS-DS-ConsistencyGuid',
      'Format' => 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent',
    ),
    40 => array(
      'class' => 'core:AttributeMap',
      'userPrincipalName' => 'IDPEmail',
    ),
    50 => array(
      'class' => 'core:AttributeLimit',
      'userPrincipalName',
      'IDPEmail',
    ),
  ),
);
Reply all
Reply to author
Forward
0 new messages