Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Role Mapping does not work when configured via Active Directory Group-Mappings (CN=xxx / Is-member-Of-DL Attribute) #119

Open
squild-mtinnemeier opened this issue May 12, 2021 · 4 comments

Comments

@squild-mtinnemeier
Copy link

Discussion / Issue

We encountered the following problem when we tried to connect a WordPress Instance to our internal Active Directory using ADFS as IdP in a scenario, where a User's Wordpress-Role(s) should be mapped against a subset of the User's Active Directory Groups.

Expected behavior

Configured "memberOf" Groups should be mapped to Wordpress Roles when using a Common Name as a mapping value.

Actual behavior

Group-Mapping does not work.

Steps to reproduce the behavior

Active Directory Structure

A user object has several groups in an Active Directory. Groups can be structured in different OUs. Only some of there Groups are Wordpress-relevant and will be used for role mapping.

Example User Object:

dn: CN=Example User,OU=Users,OU=xxx,OU=xxx,OU=xxx,DC=domain,DC=local
[...]
memberOf: CN=Group-A-1,OU=xxx,OU=xxx,OU=xxx,OU=xxx,OU=xxx,DC=domain,DC=local
memberOf: CN=Group-A-2,OU=xxx,OU=xxx,OU=xxx,OU=xxx,OU=xxx,DC=domain,DC=local
memberOf: CN=Group-B-1,OU=xxx,OU=xxx,OU=xxx,OU=xxx,DC=domain,DC=local
memberOf: CN=Group-B-2,OU=xxx,OU=xxx,OU=xxx,OU=xxx,DC=domain,DC=local
[...]
memberOf: CN=Wordpress-Administrators,OU=xxx,DC=domain,DC=local
memberOf: CN=Wordpress-Editors,OU=xxx,DC=domain,DC=local
memberOf: CN=Wordpress-Authors,OU=xxx,DC=domain,DC=local
memberOf: CN=Wordpress-Contributors,OU=xxx,DC=domain,DC=local
memberOf: CN=Wordpress-Subscribers,OU=xxx,DC=domain,DC=local
[...]

ADFS - Claim Issuance Policy

We configured a "Send LDAP Attributes as Claims" Rule with some Attributes from our Active Directory Attribute Store. The relevant one for this case is out mapping of the memberOf LDAP Attribute to the http://schemas.microsoft.com/ws/2008/06/identity/claims/role Claim:

LDAP Attribute Outgoing Claim Type
Is-Member-Of-DL Role
c:[Type == "http://schemas.microsoft.com/ws/2008/06/identity/claims/windowsaccountname", Issuer == "AD AUTHORITY"]
 => issue(
    store = "Active Directory", 
    types = (
        "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress", 
        "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name", 
        "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname", 
        "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname", 
        "http://schemas.microsoft.com/ws/2008/06/identity/claims/role"), 
    query = ";mail,sAMAccountName,givenName,sn,memberOf;{0}",    p
    param = c.Value
);

SAML Response

With this configuration, the SAML response looks like this after successful authentication:

<samlp:Response ...>
  [...]
  <Assertion ...>
    <AttributeStatement>
       <Attribute Name="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress">
           <AttributeValue>my@email.com</AttributeValue>
        </Attribute>
        [...]
        <Attribute Name="http://schemas.microsoft.com/ws/2008/06/identity/claims/role">
            <AttributeValue>CN=Group-A-1,OU=xxx,OU=xxx,OU=xxx,OU=xxx,OU=xxx,DC=domain,DC=local</AttributeValue>
            <AttributeValue>CN=Group-A-2,OU=xxx,OU=xxx,OU=xxx,OU=xxx,OU=xxx,DC=domain,DC=local</AttributeValue>
            [...]
            <AttributeValue>CN=Wordpress-Administrators,OU=xxx,DC=domain,DC=local</AttributeValue>
            <AttributeValue>CN=Wordpress-Editors,OU=xxx,DC=domain,DC=local</AttributeValue>
            <AttributeValue>CN=Wordpress-Authors,OU=xxx,DC=domain,DC=local</AttributeValue>
            [...]        
        </Attribute>
    [...]
  </AttributeStatement>
  [...]
  </Assertion>
</samlp:Response>

SSO/SAML Settings - Wordpress Plugin Configuration

Relevant subset of the Plugin's settings page:

Attribute Mapping

Option Value
Username http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name
E-Mail http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress
[...]
Role http://schemas.microsoft.com/ws/2008/06/identity/claims/role

Role Mapping

Because it is contained in this way in the SAML response, we have entered the entire CN string as a value. Since the different roles are delivered in several individual attributes, we didn't checked "Multiple role values in one saml attribute value" and let "Regular expression for multiple role values" empty.

Option Value
Administrator CN=Wordpress-Administrators,OU=xxx,DC=domain,DC=local
Editor CN=Wordpress-Editors,OU=xxx,DC=domain,DC=local
Author CN=Wordpress-Authors,OU=xxx,DC=domain,DC=local
[...]
Multiple role values in one saml attribute value  [ ] (unchecked)
Regular expression for multiple role values [ ] (empty)

Suspected source of error in the code

We suspect the source of the problem is, that the string of the "Role Mapping" value gets splitted by the comma seperator. In cases, where the string itself includes multiple commas, that doesn't work out:

https://github.com/onelogin/wordpress-saml/blob/666380d4b92178a6f08eb502b51b1dface940761/onelogin-saml-sso/php/functions.php#L356

As it is mentioned on the Plugin's Settings Page, there should be the option to map multiple IdP roles to one Wordpress role: "Accepts comma separated values. Example: admin,owner,superuser"

A comma as string seperator may not be the best option here.

We suppose there are lot's of scenarios where another Separator for this purpose would be a better solution, even when it comes to Active Directory based IdP Deployments. One Option could be to provide the possibility to use a user-defined string seperator, in our case, we changed it simply to a semicolon in the explode-Function.

@sandykadam
Copy link

I will be also interested in this feature, we have similar requirement.

@pitbulk
Copy link
Contributor

pitbulk commented Jun 4, 2021

For this specific case, there is already a solution. I think you missed a setting available at the SAML Settings at the Options section: "Regular expression for multiple role values":

Regular expression that extract roles from complex multivalued data (required to active the previous option).
E.g. If the SAMLResponse has a role attribute like: CN=admin;CN=superuser;CN=europe-admin; , use the regular expression /CN=([A-Z0-9\s _-]*);/i to retrieve the values. Or use /CN=([^,;]*)/

So basically at the Role Mapping you may set:

Administrator | Wordpress-Administrators
Editor | Wordpress-Editors
Author | Wordpress-Authors

and set as "Regular expression for multiple role values" the one able to extract those values. https://regex101.com/ can help you to find it

@squild-mtinnemeier
Copy link
Author

@pitbulk Are you really sure about that? As I understood this option, it is usable for the situation where all SAML-Roles are returned as a String separated by a specific separator. An Array of SAML-Roles as SAML-Response is not accepted (see https://github.com/onelogin/wordpress-saml/blob/666380d4b92178a6f08eb502b51b1dface940761/onelogin-saml-sso/php/functions.php#L331). But in my case the SAML-Response is not a String but an Array of SAML-Roles - as it should be usual in an Active Directory Context.

@pitbulk
Copy link
Contributor

pitbulk commented Jun 7, 2021

You are right, the pattern feature was designed to work when all role data is provided in a single string.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants