How to replace a value of NameId with attribute in

2019-08-02 09:26发布

I'm trying to setup SimpleSAMLphp IdP to send a SAML response to my local dev server (SP-initiated flow in this case) . This IdP is based on a Docker image from https://hub.docker.com/r/kristophjunge/test-saml-idp/ (ver. 1.15 I believe).

The whole setup is to emulate a similar environment that I have whereby G Suite IdP is used against the same local dev SP - trying to eventually eliminate the cloud dependency from my local dev environment and replace it with an equivalent SimpleSAMLphp one.

The problem I'm experiencing is Google sends NameId in its SAML response as this:

<saml2:Subject> 
    <saml2:NameID Format="urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified">a.b@c.com</saml2:NameID> 
                  <saml2:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer"> 
                     <saml2:SubjectConfirmationData InResponseTo="ONELOGIN_88ebd953f02c07d01b19714cd70133827ff1228e" NotOnOrAfter="2018-05-07T20:21:25.433Z" .                         Recipient="https://ee0138c4.ngrok.io/saml/?acs" /> 
</saml2:SubjectConfirmation>
</saml2:Subject>

but SimpleSAMLphp one instead sends it in this format:

<saml:Subject> 
<saml:NameID SPNameQualifier="https://ee0138c4.ngrok.io/saml/metadata" Format="urn:oasis:names:tc:SAML:2.0:nameid-format:transient">_69d05500bd6e797de3674df0165facbfa0af699589</saml:NameID> 
<saml:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer"> <saml:SubjectConfirmationData NotOnOrAfter="2018-05-09T17:47:57Z" Recipient="https://ee0138c4.ngrok.io/saml/?acs" InResponseTo="ONELOGIN_170bb7a0ff82100318ba498583e8e59cdae8607b" /> 
</saml:SubjectConfirmation> 
</saml:Subject>

I need it to be an attribute value

(a.b@c.com instead of _69d05500bd6e797de3674df0165facbfa0af699589)

which I can then grab in my SP's logic, instead it sends some random number, I'm assuming it's a transientId.

Here are my configurations:

To start the Docker container:

docker run --name=testsamlidp_idp \
-p 8080:8080 \
-p 8443:8443 \
-e SIMPLESAMLPHP_SP_ENTITY_ID=https://ee0138c4.ngrok.io/saml/metadata \
-e SIMPLESAMLPHP_SP_ASSERTION_CONSUMER_SERVICE=https://ee0138c4.ngrok.io/saml/?acs  \
-e SIMPLESAMLPHP_SP_SINGLE_LOGOUT_SERVICE=http://localhost/simplesaml/module.php/saml/sp/saml2-logout.php/test-sp \
-v $(pwd)/users.php:/var/www/simplesamlphp/config/authsources.php \
-v $(pwd)/_saml20-sp-remote.php:/var/www/simplesamlphp/config/saml20-sp-remote.php \
-d kristophjunge/test-saml-idp

where users.php contains:

<?php
$config = array(
    'admin' => array(
        'core:AdminPassword',
    ),
    'example-userpass' => array(
        'exampleauth:UserPass',
        'user1:user1pass' => array(
            'uid' => array('1'),
            'Groups' => array('group1','group2', 'group3'),
            'email' => 'user1@example.com',
        ),
        'user2:user2pass' => array(
            'uid' => array('2'),
            'Groups' => array('group2', 'group4', 'group5'),
            'email' => 'user2@example.com',
        ),
    ),
);

and _saml20-sp-remote.php is:

<?php
/**
 * SAML 2.0 remote SP metadata for SimpleSAMLphp.
 *
 * See: https://simplesamlphp.org/docs/stable/simplesamlphp-reference-sp-remote
 */
$metadata[getenv('SIMPLESAMLPHP_SP_ENTITY_ID')] = array(

    'AssertionConsumerService' => getenv('SIMPLESAMLPHP_SP_ASSERTION_CONSUMER_SERVICE'),
    'SingleLogoutService' => getenv('SIMPLESAMLPHP_SP_SINGLE_LOGOUT_SERVICE'),

    #'NameIDFormat' => 'urn:oasis:names:tc:SAML:1.1:nameid-format:persistent',
      #'simplesaml.nameidattribute' => 'email',
      #'simplesaml.attributes' => FALSE,

    'authproc.idp' => array(
            /* Filter to create a NameID with the "unspecified" format. */
            3 => array(
                'class' => 'saml:AtrributeNameID',
                'attribute' => 'email',
                'Format' => 'urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress',
            ),
        ),
        /* Select the unspecified NameID format by default. */
        'NameIDFormat' => 'urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified',

);

I'm assuming it's some kind of a misconfiguration in the latter file, perhaps someone could lend me a hand in getting to the bottom of it.

Thank you in advance.

1条回答
老娘就宠你
2楼-- · 2019-08-02 10:04

The following setup worked for me:

Docker startup script:

docker run --name=testsamlidp_idp \
-p 8080:8080 \
-p 8443:8443 \
-e SIMPLESAMLPHP_SP_ENTITY_ID=https://ee0138c4.ngrok.io/saml/metadata \
-e SIMPLESAMLPHP_SP_ASSERTION_CONSUMER_SERVICE=https://ee0138c4.ngrok.io/saml/?acs  \
-e SIMPLESAMLPHP_SP_SINGLE_LOGOUT_SERVICE=http://localhost/simplesaml/module.php/saml/sp/saml2-logout.php/test-sp \
-v $(pwd)/users.php:/var/www/simplesamlphp/config/authsources.php \
-v $(pwd)/saml20-idp-hosted.php:/var/www/simplesamlphp/metadata/saml20-idp-hosted.php \
-d kristophjunge/test-saml-idp

saml20-idp-hosted.php in /var/www/simplesamlphp/metadata/saml20-idp-hosted.php in Docker container

<?php

$metadata['__DYNAMIC:1__'] = array(
    /*
     * The hostname of the server (VHOST) that will use this SAML entity.
     *
     * Can be '__DEFAULT__', to use this entry by default.
     */
    'host' => '__DEFAULT__',
    // X.509 key and certificate. Relative to the cert directory.
    'privatekey' => 'server.pem',
    'certificate' => 'server.crt',
    /*
     * Authentication source to use. Must be one that is configured in
     * 'config/authsources.php'.
     */
    'auth' => 'example-userpass',

  'NameIDFormat' => 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent',


// refer to https://simplesamlphp.org/docs/stable/saml:nameid
'authproc' => array(
  3 => array(
          'class' => 'saml:AttributeNameID',
          'attribute' => 'email',
          'Format' => 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent',
      ),
  ),

);

Both NameIDFormat and Format are necessary. email should correspond to the attribute specified in

authsources.php in /var/www/simplesamlphp/config of Docker container:

<?php
$config = array(
    'admin' => array(
        'core:AdminPassword',
    ),
    'example-userpass' => array(
        'exampleauth:UserPass',
        'user1:user1pass' => array(
            'uid' => array('1'),
            'Groups' => array('group1','group2', 'group3'),
            'email' => 'user1@example.com',
        ),
        'user2:user2pass' => array(
            'uid' => array('2'),
            'Groups' => array('group2', 'group4', 'group5'),
            'email' => 'user2@example.com',
        ),
    ),
);

The general idea on how to get to it is somewhat documented but the documentation is not for the faint of heart and certainly welcomes sections on rationale of why things are the way they are.

查看更多
登录 后发表回答