SAML-Toolkits / wordpress-saml

OneLogin SAML plugin for Wordpress
MIT License
65 stars 74 forks source link

Use NameID when there is no username Attribute #66

Closed kaechele closed 6 years ago

kaechele commented 6 years ago

My IdP (Ipsilon attached to FreeIPA) doesn't provide an attribute for the username. Instead, the username is only transmitted as the NameID.

I'm currently using this hack, and it works for me:

diff --git a/onelogin-saml-sso/php/functions.php b/onelogin-saml-sso/php/functions.php
index 088d571..6fb95c8 100644
--- a/onelogin-saml-sso/php/functions.php
+++ b/onelogin-saml-sso/php/functions.php
@@ -165,9 +165,9 @@ function saml_acs() {
        setcookie(SAML_NAMEID_FORMAT_COOKIE, $auth->getNameIdFormat(), time() + YEAR_IN_SECONDS, SITECOOKIEPATH );

        $attrs = $auth->getAttributes();
+       $nameid = $auth->getNameId();

        if (empty($attrs)) {
-               $nameid = $auth->getNameId();
                if (empty($nameid)) {
                        echo __("The SAMLResponse may contain NameID or AttributeStatement");
                        exit();
@@ -186,6 +186,10 @@ function saml_acs() {
                }
        }

+       if(empty($username) && !empty($nameid)) {
+               $username = $nameid;
+       }
+
        if (empty($username)) {
                echo __("The username could not be retrieved from the IdP and is required");
                exit();

A sample SAML Response from my IdP looks like this:

<saml:Subject>
    <saml:NameID Format="urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified" NameQualifier="https://auth1.foo.de/idp/saml2/metadata">felix</saml:NameID>
    <saml:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer">
        <saml:SubjectConfirmationData NotOnOrAfter="2018-07-21T23:29:03Z" Recipient="https://foo.de/wp-login.php?saml_acs"/>
    </saml:SubjectConfirmation>
</saml:Subject>
<saml:Conditions NotBefore="2018-07-21T23:27:03Z" NotOnOrAfter="2018-07-21T23:29:03Z">
    <saml:AudienceRestriction>
        <saml:Audience>php-saml</saml:Audience>
    </saml:AudienceRestriction>
</saml:Conditions>
<saml:AuthnStatement AuthnInstant="2018-07-21T23:28:03Z" SessionIndex="_175871E9A671BF9518663375DFD78E04">
    <saml:AuthnContext>
        <saml:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:unspecified</saml:AuthnContextClassRef>
    </saml:AuthnContext>
</saml:AuthnStatement>
<saml:AttributeStatement>
    <saml:Attribute Name="surname" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic">
        <saml:AttributeValue>Kaechele</saml:AttributeValue>
    </saml:Attribute>
    <saml:Attribute Name="groups" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic">
        <saml:AttributeValue>ipausers</saml:AttributeValue>
        <saml:AttributeValue>superadmins</saml:AttributeValue>
        <saml:AttributeValue>trust admins</saml:AttributeValue>
        <saml:AttributeValue>admins</saml:AttributeValue>
        <saml:AttributeValue>serveradmins</saml:AttributeValue>
    </saml:Attribute>
    <saml:Attribute Name="givenname" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic">
        <saml:AttributeValue>Felix</saml:AttributeValue>
    </saml:Attribute>
    <saml:Attribute Name="gecos" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic">
        <saml:AttributeValue>Felix Kaechele</saml:AttributeValue>
    </saml:Attribute>
    <saml:Attribute Name="sn" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic">
        <saml:AttributeValue>Kaechele</saml:AttributeValue>
    </saml:Attribute>
    <saml:Attribute Name="mail" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic">
        <saml:AttributeValue>felix@foo.de</saml:AttributeValue>
    </saml:Attribute>
    <saml:Attribute Name="fullname" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic">
        <saml:AttributeValue>Felix Kaechele</saml:AttributeValue>
    </saml:Attribute>
    <saml:Attribute Name="email" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic">
        <saml:AttributeValue>felix@foo.de</saml:AttributeValue>
    </saml:Attribute>
</saml:AttributeStatement>

There is probably a nicer and more correct way of doing this. Maybe someone has an idea?

pitbulk commented 6 years ago

The SAML extension expects to retrieve data from NameId or from attributes, not from both. The patch you shared works for you but will impact other integrations so I can't apply it on next release.

Why IdP is not able to provide username on attributes?

kaechele commented 6 years ago

Thanks for the reply! So with Ipsilon you apparently need version > 2.0 and also you need to map _username to any attribute name you'd like. It's not mapped by default as upstream says (we spoke on IRC) one should really be pulling the username from NamedID instead, but this way it's at least working.