• As part of a possible migration from the Shibboleth plugin to this one (which in turn is part of a possible hosting migration), I’m working on replicating functionality of the old Shibboleth plugin.

    Right now, Shibboleth’s SAML implementation can handle whatever arbitrary data are included in the IdP’s response, and exposes them as elements under $_SERVER. (Example: My IdP’s SAML responses include not only names and email addresses, but some org-specific information like department, sometimes employee ID, sometimes AD group memberships, and so on.) Then I can just query $_SERVER[‘ADGroups’] or $_SERVER[‘PrimaryRole’] or whatever other arbitrary data are coming in.

    (Part of that is the Shib daemon’s attribute map, so if this plugin can only get urn:oid: style field names instead of friendly names, that’s an understandable limitation. Probably depends on whether the IdP sends friendly names in its responses.)

    In at least a few specific cases, this plugin can do that, since that’s what the “Attribute Mappings” settings are — you put in the ID of an element in the SAML response, and it’s used for a WordPress-specific thing (like first name or email address). But I’d like to be able to extend that to other fields that might be received in the response. My ideal would be that every attribute from the SAML response gets populated right into $_SERVER for compatibility, but I could be talked into a different implementation. Any suggestions on how to approach this?

Viewing 5 replies - 1 through 5 (of 5 total)
  • Plugin Author Daniel Bachhuber

    (@danielbachhuber)

    Hey @desmith,

    Have you looked into the wp_saml_auth_new_user_authenticated and the wp_saml_auth_existing_user_authenticated filters? I’d think the second $attributes argument would contain all of the data you’d need.

    Thread Starter David E. Smith

    (@desmith)

    Weird, I was literally about to post about those, and how I’m not sure how they work. ??

    Does new_user_authenticated only trigger on a user’s first logon, and existing_user_authenticated only trigger on subsequent logons? (Is there one that triggers for all successful logons, both new and existing? That’ll help me avoid duplicating code.)

    I’m doing this which covers most of my use cases so far:

    add_action( 'wp_saml_auth_existing_user_authenticated',
      function ( $user, $attributes ) {
        foreach ( $attributes as $k=>$v ) {
          $sname = 'saml_' . strtolower( $k );
          update_user_meta( $user->ID, $sname, $v );
          $sname2 = 'saml_' . $this->get_name_by_oid( $k );
          if ( $sname !== $sname2 ) {
            update_user_meta( $user->ID, $sname2, $v );
          }
        }
      }, 10, 2
    );

    (get_name_by_oid is a function that looks at the OIDs and returns the human-readable versions, a low-budget attribute map if you will)

    Should I just abstract that code into a separate function and call it for both new_user and existing_user events?

    Plugin Author Daniel Bachhuber

    (@danielbachhuber)

    Does new_user_authenticated only trigger on a user’s first logon, and existing_user_authenticated only trigger on subsequent logons?

    Correct.

    Is there one that triggers for all successful logons, both new and existing? That’ll help me avoid duplicating code.

    No. For better or for worse, it’s two separate actions.

    Should I just abstract that code into a separate function and call it for both new_user and existing_user events?

    Yep, that’d work just fine!

    Thread Starter David E. Smith

    (@desmith)

    So far, at least, that approach seems to work. Putting it all together for anyone in the future who might need it… I’ve added actions like this, for both wp_saml_auth_new_user_authenticated and for wp_saml_auth_existing_user_authenticated:

    add_action( 'wp_saml_auth_new_user_authenticated', function ( $user, $attributes ) {
      $this->populate_saml_attrs( $user, $attributes );
      }, 10, 2 );

    The populate_saml_attrs function, in my case, goes through the provided attributes and stores the info in user_meta:

    function populate_saml_attrs( $user, $attributes ) {
      foreach( $attributes as $k=>$v ) {
        $samlname = 'saml_' . strtolower( $k );
        update_user_meta( $user->ID, $samlname, $v );
      }
    }

    This gives you a bunch of user_meta attributes with whatever names or OIDs were provided by the identity provider. In my case it’s something like:

    saml_urn:oid:1.2.840.113556.1.4.221     a:1:{i:0;s:10:"davidsmith";}
    saml_urn:oid:2.16.840.1.113730.3.1.241  a:1:{i:0;s:11:"David Smith";}
    saml_urn:oid:2.5.4.42   a:1:{i:0;s:5:"David";}
    saml_urn:oid:2.5.4.4    a:1:{i:0;s:5:"Smith";}

    Anyone using this is highly recommended to extend how they populate the attributes, and put in some sort of user-friendly names instead of the OIDs if they can, the folks consuming the data will thank you.

    I never tested if you could add this straight to $_SERVER to mimic how the Shibboleth plugin works. More I thought about it, more I thought that modifying a superglobal seemed like a really bad idea. ??

    Thank you!

    Plugin Author Daniel Bachhuber

    (@danielbachhuber)

    You’re welcome! Glad you were able to get it working, and thanks for sharing your findings for future readers ??

Viewing 5 replies - 1 through 5 (of 5 total)
  • The topic ‘How to get other IdP-provided attributes from a SAML response into WP?’ is closed to new replies.