IdP LDAP Configuration Error parsing XML string

918 views
Skip to first unread message

Mike Di Domenico

unread,
May 9, 2016, 6:24:54 AM5/9/16
to SimpleSAMLphp

Good morning, 

I am attempting to setup a SAML server and I am kinda stuck. This is my first time playing with SAML, let alone building and configuring a IdP server so I apologize if the problem I am facing is a simple one. 


My goal is to authenticate a web application against LDAP. I didn't write the web application, I was just told that it only supports SAML for authentication. I would like to map the following LDAP fields to custom names in the response (LDAP => Response):

sAMAccountName => NameID

givenName => first_name

sn => last_name

mail => email

telephoneNumber => phone


I have successfully authenticated the SP to this IdP that I am trying to configure when the IdP is using the exampleauth:UserPass (see configuration below), however when I get to trying to authenticate it against LDAP, I am hitting an unhandled exception. The logs show "Caused by: DOMException: Error parsing XML string."


I know the problem is with my configuration... I just have no clue what the problem could be. See below for configuration and logs. 


Any suggestions?


Thank you very much.



SimpleSAML_Error_Error: UNHANDLEDEXCEPTION

Backtrace:
0 /var/simplesamlphp/www/module.php:170 (N/A)
Caused by: DOMException: Error parsing XML string.
Backtrace:
15 /var/simplesamlphp/lib/SimpleSAML/Utils/XML.php:234 (SimpleSAML\Utils\XML::formatXMLString)
14 /var/simplesamlphp/lib/SimpleSAML/Utils/XML.php:115 (SimpleSAML\Utils\XML::debugSAMLMessage)
13 /var/simplesamlphp/lib/SimpleSAML/Utilities.php:683 (SimpleSAML_Utilities::debugMessage)
12 /var/simplesamlphp/vendor/simplesamlphp/saml2/src/SAML2/Compat/Ssp/Container.php:39 (SAML2_Compat_Ssp_Container::debugMessage)
11 /var/simplesamlphp/vendor/simplesamlphp/saml2/src/SAML2/HTTPPost.php:29 (SAML2_HTTPPost::send)
10 /var/simplesamlphp/modules/saml/lib/IdP/SAML2.php:78 (sspmod_saml_IdP_SAML2::sendResponse)
9 [builtin] (call_user_func)
8 /var/simplesamlphp/lib/SimpleSAML/IdP.php:287 (SimpleSAML_IdP::postAuthProc)
7 /var/simplesamlphp/lib/SimpleSAML/IdP.php:333 (SimpleSAML_IdP::postAuth)
6 [builtin] (call_user_func)
5 /var/simplesamlphp/lib/SimpleSAML/Auth/Source.php:229 (SimpleSAML_Auth_Source::loginCompleted)
4 [builtin] (call_user_func)
3 /var/simplesamlphp/lib/SimpleSAML/Auth/Source.php:145 (SimpleSAML_Auth_Source::completeAuth)
2 /var/simplesamlphp/modules/core/lib/Auth/UserPassBase.php:266 (sspmod_core_Auth_UserPassBase::handleLogin)
1 /var/simplesamlphp/modules/core/www/loginuserpass.php:67 (require)
0 /var/simplesamlphp/www/module.php:127 (N/A)


/var/log/messages

May  9 06:06:53 SAMLServ1 simplesamlphp[56732]: 6 [309acdc86a] SAML2.0 - IdP.SSOService: Accessing SAML 2.0 IdP endpoint SSOService

May  9 06:06:53 SAMLServ1 simplesamlphp[56732]: 6 [309acdc86a] SAML2.0 - IdP.SSOService: incoming authentication request: 'INST0'

May  9 06:06:53 SAMLServ1 simplesamlphp[56187]: 6 [309acdc86a] Template: Looking up [{login:processing]: not translated at all.

May  9 06:07:02 SAMLServ1 simplesamlphp[56682]: 5 STAT [309acdc86a] User 'admin1' has been successfully authenticated.

May  9 06:07:02 SAMLServ1 simplesamlphp[56682]: 5 STAT [309acdc86a] saml20-idp-SSO-first INST0 http://192.168.152.10/sso/saml2/idp/metadata.php NA

May  9 06:07:02 SAMLServ1 simplesamlphp[56682]: 5 STAT [309acdc86a] saml20-idp-SSO INST0 http://192.168.152.10/sso/saml2/idp/metadata.php NA

May  9 06:07:02 SAMLServ1 simplesamlphp[56682]: 6 [309acdc86a] Sending SAML 2.0 Response to 'INST0'

May  9 06:07:02 SAMLServ1 simplesamlphp[56682]: 3 [309acdc86a] SimpleSAML_Error_Error: UNHANDLEDEXCEPTION

May  9 06:07:02 SAMLServ1 simplesamlphp[56682]: 3 [309acdc86a] Backtrace:

May  9 06:07:02 SAMLServ1 simplesamlphp[56682]: 3 [309acdc86a] 0 /var/simplesamlphp/www/module.php:170 (N/A)

May  9 06:07:02 SAMLServ1 simplesamlphp[56682]: 3 [309acdc86a] Caused by: DOMException: Error parsing XML string.

May  9 06:07:02 SAMLServ1 simplesamlphp[56682]: 3 [309acdc86a] Backtrace:

May  9 06:07:02 SAMLServ1 simplesamlphp[56682]: 3 [309acdc86a] 15 /var/simplesamlphp/lib/SimpleSAML/Utils/XML.php:234 (SimpleSAML\Utils\XML::formatXMLString)

May  9 06:07:02 SAMLServ1 simplesamlphp[56682]: 3 [309acdc86a] 14 /var/simplesamlphp/lib/SimpleSAML/Utils/XML.php:115 (SimpleSAML\Utils\XML::debugSAMLMessage)

May  9 06:07:02 SAMLServ1 simplesamlphp[56682]: 3 [309acdc86a] 13 /var/simplesamlphp/lib/SimpleSAML/Utilities.php:683 (SimpleSAML_Utilities::debugMessage)

May  9 06:07:02 SAMLServ1 simplesamlphp[56682]: 3 [309acdc86a] 12 /var/simplesamlphp/vendor/simplesamlphp/saml2/src/SAML2/Compat/Ssp/Container.php:39 (SAML2_Compat_Ssp_Container::debugMessage)

May  9 06:07:02 SAMLServ1 simplesamlphp[56682]: 3 [309acdc86a] 11 /var/simplesamlphp/vendor/simplesamlphp/saml2/src/SAML2/HTTPPost.php:29 (SAML2_HTTPPost::send)

May  9 06:07:02 SAMLServ1 simplesamlphp[56682]: 3 [309acdc86a] 10 /var/simplesamlphp/modules/saml/lib/IdP/SAML2.php:78 (sspmod_saml_IdP_SAML2::sendResponse)

May  9 06:07:02 SAMLServ1 simplesamlphp[56682]: 3 [309acdc86a] 9 [builtin] (call_user_func)

May  9 06:07:02 SAMLServ1 simplesamlphp[56682]: 3 [309acdc86a] 8 /var/simplesamlphp/lib/SimpleSAML/IdP.php:287 (SimpleSAML_IdP::postAuthProc)

May  9 06:07:02 SAMLServ1 simplesamlphp[56682]: 3 [309acdc86a] 7 /var/simplesamlphp/lib/SimpleSAML/IdP.php:333 (SimpleSAML_IdP::postAuth)

May  9 06:07:02 SAMLServ1 simplesamlphp[56682]: 3 [309acdc86a] 6 [builtin] (call_user_func)

May  9 06:07:02 SAMLServ1 simplesamlphp[56682]: 3 [309acdc86a] 5 /var/simplesamlphp/lib/SimpleSAML/Auth/Source.php:229 (SimpleSAML_Auth_Source::loginCompleted)

May  9 06:07:02 SAMLServ1 simplesamlphp[56682]: 3 [309acdc86a] 4 [builtin] (call_user_func)

May  9 06:07:02 SAMLServ1 simplesamlphp[56682]: 3 [309acdc86a] 3 /var/simplesamlphp/lib/SimpleSAML/Auth/Source.php:145 (SimpleSAML_Auth_Source::completeAuth)

May  9 06:07:02 SAMLServ1 simplesamlphp[56682]: 3 [309acdc86a] 2 /var/simplesamlphp/modules/core/lib/Auth/UserPassBase.php:266 (sspmod_core_Auth_UserPassBase::handleLogin)

May  9 06:07:02 SAMLServ1 simplesamlphp[56682]: 3 [309acdc86a] 1 /var/simplesamlphp/modules/core/www/loginuserpass.php:67 (require)

May  9 06:07:02 SAMLServ1 simplesamlphp[56682]: 3 [309acdc86a] 0 /var/simplesamlphp/www/module.php:127 (N/A)

May  9 06:07:02 SAMLServ1 simplesamlphp[56682]: 3 [309acdc86a] Error report with id b0781dee generated.


metadata/saml20-idp-hosted.php

$metadata['__DYNAMIC:1__'] = array(

        'host' => '__DEFAULT__',


        'privatekey' => 'simplesamlphp.pem',

        'certificate' => 'simplesamlphp.crt',


        'auth' => 'domain-ldap',

//      'auth' => 'example-userpass',

);


metadata/saml20-sp-remote.php

$metadata['INST0'] = array(

        'AssertionConsumerService' => 'http://portal.domain.com/login.php',

        'SingleLogoutService'      => 'http://portal.domain.com/logout.php',


        'NameIDFormat' => 'urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified',


        'authproc' => array(

                3 => array(

                        'class' => 'saml:AttributeNameID',

                        'attribute' => 'sAMAccountName',

                        'Format' => 'urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified',

                ),

        ),

);


config/authsources.php

    'example-userpass' => array(

        'exampleauth:UserPass',


       'admin1:P4ss30rd' => array(

            'NameID' => array('admin1'),

            'first_name' => array('My'),

            'last_name' => array('Admin 1'),

            'name' => array('My Admin 1'),

            'email=> array('some...@example.org'),

            'phone=> array('1234567890'),

        ),

    ),

    'domain-ldap' => array(

        'ldap:LDAP',


        // Give the user an option to save their username for future login attempts

        // And when enabled, what should the default be, to save the username or not

        //'remember.username.enabled' => FALSE,

        //'remember.username.checked' => FALSE,


        // The hostname of the LDAP server.

        'hostname' => '192.168.152.11',


        // Whether SSL/TLS should be used when contacting the LDAP server.

        'enable_tls' => FALSE,


        // Whether debug output from the LDAP library should be enabled.

        // Default is FALSE.

        'debug' => TRUE,


        // The timeout for accessing the LDAP server, in seconds.

        // The default is 0, which means no timeout.

        'timeout' => 30,


        // The port used when accessing the LDAP server.

        // The default is 389.

        'port' => 389,


        // Set whether to follow referrals. AD Controllers may require FALSE to function.

        'referrals' => FALSE,


        // Which attributes should be retrieved from the LDAP server.

        // This can be an array of attribute names, or NULL, in which case

        // all attributes are fetched.

        'attributes' => NULL,


        // The pattern which should be used to create the users DN given the username.

        // %username% in this pattern will be replaced with the users username.

        //

        // This option is not used if the search.enable option is set to TRUE.

        'dnpattern' => 'uid=%username%,DC=my,DC=domain,DC=com',


        // As an alternative to specifying a pattern for the users DN, it is possible to

        // search for the username in a set of attributes. This is enabled by this option.

        'search.enable' => TRUE,


        // The DN which will be used as a base for the search.

        // This can be a single string, in which case only that DN is searched, or an

        // array of strings, in which case they will be searched in the order given.

        'search.base' => 'DC=my,DC=domain,DC=com',

        // The attribute(s) the username should match against.

        //

        // This is an array with one or more attribute names. Any of the attributes in

        // the array may match the value the username.

        'search.attributes' => array('uid', 'mail', 'sAMAccountName'),


        // The username & password the SimpleSAMLphp should bind to before searching. If

        // this is left as NULL, no bind will be performed before searching.

        'search.username' => 'admin1',

        'search.password' => '<password>',


        // If the directory uses privilege separation,

        // the authenticated user may not be able to retrieve

        // all required attribures, a privileged entity is required

        // to get them. This is enabled with this option.

        'priv.read' => FALSE,


        // The DN & password the SimpleSAMLphp should bind to before

        // retrieving attributes. These options are required if

        // 'priv.read' is set to TRUE.

        'priv.username' => NULL,

        'priv.password' => NULL,

Peter Schober

unread,
May 9, 2016, 8:39:59 PM5/9/16
to SimpleSAMLphp
* Mike Di Domenico <didomeni...@gmail.com> [2016-05-09 12:25]:
> Backtrace:
> 0 /var/simplesamlphp/www/module.php:170 (N/A)
> Caused by: DOMException: Error parsing XML string.
> Backtrace:
> 15 /var/simplesamlphp/lib/SimpleSAML/Utils/XML.php:234 (SimpleSAML\Utils\XML::formatXMLString)
> 14 /var/simplesamlphp/lib/SimpleSAML/Utils/XML.php:115 (SimpleSAML\Utils\XML::debugSAMLMessage)
> 13 /var/simplesamlphp/lib/SimpleSAML/Utilities.php:683 (SimpleSAML_Utilities::debugMessage)
> 12 /var/simplesamlphp/vendor/simplesamlphp/saml2/src/SAML2/Compat/Ssp/Container.php:39 (SAML2_Compat_Ssp_Container::debugMessage)
> 11 /var/simplesamlphp/vendor/simplesamlphp/saml2/src/SAML2/HTTPPost.php:29 (SAML2_HTTPPost::send)
> 10 /var/simplesamlphp/modules/saml/lib/IdP/SAML2.php:78 (sspmod_saml_IdP_SAML2::sendResponse)
> 9 [builtin] (call_user_func)
> 8 /var/simplesamlphp/lib/SimpleSAML/IdP.php:287 (SimpleSAML_IdP::postAuthProc)
> 7 /var/simplesamlphp/lib/SimpleSAML/IdP.php:333 (SimpleSAML_IdP::postAuth)
> 6 [builtin] (call_user_func)
> 5 /var/simplesamlphp/lib/SimpleSAML/Auth/Source.php:229 (SimpleSAML_Auth_Source::loginCompleted)
> 4 [builtin] (call_user_func)
> 3 /var/simplesamlphp/lib/SimpleSAML/Auth/Source.php:145 (SimpleSAML_Auth_Source::completeAuth)
> 2 /var/simplesamlphp/modules/core/lib/Auth/UserPassBase.php:266 (sspmod_core_Auth_UserPassBase::handleLogin)
> 1 /var/simplesamlphp/modules/core/www/loginuserpass.php:67 (require)
> 0 /var/simplesamlphp/www/module.php:127 (N/A)

That's strange. Looks like the XML it falls over is generated by the
IDP itself, earlier, after completing login and before ultimately
HTTP-POST'ing the response to the SP.

No idea what would cause the IDP to generate XML it fails to parse
itself later. Maybe add a log (or print) statement to
formatXMLString() in lib/SimpleSAML/Utils/XML.php, or add the $xml
itself to the DOMException thrown there, to get an idea of what's the
XML that's tripping the code up here.

How did you install SSP and its SAML2 library on that system?
-peter

Mike Di Domenico

unread,
May 11, 2016, 5:24:30 AM5/11/16
to SimpleSAMLphp, peter....@univie.ac.at
I spent some time debugging and it was passing XML.php an XML variable that contained "0". I suspect something is returning false and that is being passed along. I did not dig into it to find out where. 

I installed SimpleSamlPHP by going through the install guide on the website (clean install). 

After a bunch more Googling, I just got everything working with the following config settings... 
saml20-idp-hosted.php

        'authproc' => array(

                2 => array(

                        'class' => 'saml:PersistentNameID',

                        'attribute' => 'sAMAccountName',

                ),

                10 => array(

                        'class' => 'core:AttributeMap',

                        'givenName' => 'first_name',

                        'sn' => 'last_name',

                        'cn' => 'name',

                        'mail' => 'mail',

                        'telephoneNumber' => 'phone',

                ),

                100 => array(

                        'class' => 'core:PHP',

                        'code' => '

        if(!empty($attributes["sAMAccountName"])) {

              $employeeID = $attributes["sAMAccountName"][0];

              $attributes["employeeID"] = array($employeeID);

        }


        if(!empty($attributes["givenName"])){

                $firstName = $attributes["givenName"][0];

                $attributes["first_name"] = array($firstName);

        }

                        ',

                ),

        ),


Since it is working I have been afraid to remove the PHP code so I plan to just leave it. I don't think it is doing anything useful though. 


saml20-sp-remote.php

        'simplesaml.attributes' => true,

        'attributes' => array('first_name', 'last_name', 'name', 'email', 'phone'),


        'NameIDFormat' => 'urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified',

        'authproc' => array(

                3 => array(

                        'class' => 'saml:AttributeNameID',

                        'attribute' => 'sAMAccountName',

                        'Format' => 'urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified',

                ),

        ),


Thanks,
Mike

face.al...@gmail.com

unread,
May 16, 2017, 8:37:01 AM5/16/17
to SimpleSAMLphp, peter....@univie.ac.at
Hi Mike,

I have the same problem. But I can't use the solution you proposed.
Could you help me?
I think the problem is the release of the attributes. But I don't know how to solve it and which way to go.

Mike Di Domenico

unread,
May 23, 2017, 8:36:48 AM5/23/17
to SimpleSAMLphp, peter....@univie.ac.at, face.al...@gmail.com
Sure, I can try to help. What seems to be the problem? If you want to email me directly, my email address is Michael dot DiDomenico at Unisys dot com.
Reply all
Reply to author
Forward
0 new messages