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

Unable to execute SAML Assertion AttributeQuery for users stored in secondary user datastores. #294

Open
Kktheoch opened this issue Apr 2, 2020 · 1 comment

Comments

@Kktheoch
Copy link

Kktheoch commented Apr 2, 2020

Description:
After a succesful login with SAML for a user stored in a seconday user store I am trying to query the attributes of the user from the IdP since there is a dynamic attribute that may change.

Although the validation of the query partially succeeds in SAMLSubjectQueryValidator.validateSubject() the user store that is loaded is the primary userstore, so UserStoreManager.isExistingUser() returns false since the user is unknown in the primary datastore of a tenant, causing the entire query to fail with Unknown subject.

Suggested Labels:

Suggested Assignees:

Affected Product Version: 5.9.0

OS, DB, other environment details and versions:
org.wso2.carbon.identity.inbound.auth.saml2 running version is 5.6.14

Steps to reproduce:

  1. Create a secondary user datastore with appropriate connections. In my example the secondary datastore is connecting to a MySQL instance.
  2. Create a Service Provider
  3. Login to the service provider using a user stored in a secondary datastore.
  4. Retrieve nameId from the assertion response and try to execute an AttributeQuery for that nameId

Related Issues:
The org.wso2.carbon.identity.query.saml bundle seems to be completely unaware of any secondary user datastores. The primary datastore is used for every operation. This applies to both tenants and super tenant.

The AttributeQuery is executed using SAMLAttributeQueryRequestClient from saml-query-profile-client from samples-is version 4.2.1.

Complete SAML response - request can be provided in case they are needed.

SAML Assertion query doc

@Kktheoch Kktheoch changed the title Unable to execute AttributeQuery for users stored in secondary user datastores. Unable to execute SAML Assertion AttributeQuery for users stored in secondary user datastores. Apr 2, 2020
@Kktheoch
Copy link
Author

Kktheoch commented Apr 6, 2020

A possible workaround until a proper fix is added (only works when the one issuing the query already knows which userstore domain the useris stored in)

On every method that needs to access user properties stored on a secondary userstore by accesing the UserStoreManager you can get the proper UserStoreManager

public static UserStoreManager getUserStoreFromUsername(String username) throws UserStoreException {
        int tenantId = CarbonContext.getThreadLocalCarbonContext().getTenantId();
        RealmService realmservice = SAMLQueryServiceComponent.getRealmservice();
        UserRealm userRealm = realmservice.getTenantUserRealm(tenantId);
        UserStoreManager primaryUserStoreManager = userRealm.getUserStoreManager();
        UserStoreManager selectedManager = primaryUserStoreManager;
        // This extracts the userstore domain from the username
        // This means that the one issuing the query should already know the domain of the userstore...
        // Example : MYDOMAIN.COM/username
        String userstoreDomain = getUserstoreDomainFromUsername(username);
        // Primary datastore detected in case there is no userstore domain.
        if (StringUtils.isBlank(userstoreDomain)) {
           return selectedManager;
        }
        try {
            AbstractUserStoreManager abstrastUserMngr = (AbstractUserStoreManager) primaryUserStoreManager;
            UserStoreManager secondaryManager = abstrastUserMngr.getSecondaryUserStoreManager(userstoreDomain);
            // Ensure null-safety, do not return a null user store manager
            if (secondaryManager != null) {
                selectedManager = secondaryManager;
            }
        } catch (Exception ex) {
            log.error("Exception caused while trying to retrieve secondary userstore manager from username, defaulting to primary for user " + username, ex);
            selectedManager = primaryUserStoreManager;
        }
        return selectedManager;
}

In this case you need to remove the userstore domain from the username afterwards.

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

1 participant