0

Setup:

  • Sitecore 9.0.1 (rev. 171219)
  • Azure B2C External Identity Provider

I am using Azure B2C federated authentication provider to authenticate users. Once a user is authenticated via AzureB2C the user identity is transformed, a virtual Sitecore user is created and given a Sitecore role "domain\TempRole" via transformation:

<transformation name="Profile name" type="Sitecore.Owin.Authentication.Services.DefaultTransformation, Sitecore.Owin.Authentication">
  <sources hint="raw:AddSource">
    <claim name="aud" value="$(Ad.B2C.IdentityProvider.ClientId)" />
      </sources>
    <targets hint="raw:AddTarget">
      <claim name="http://schemas.microsoft.com/ws/2008/06/identity/claims/role" value="domain\TempRole" />
    </targets>
<keepSource>true</keepSource>
</transformation>
.
.
.
<externalUserBuilder type="Sitecore.Owin.Authentication.Services.DefaultExternalUserBuilder, Sitecore.Owin.Authentication">
  <param desc="isPersistentUser">false</param>
</externalUserBuilder>

All this works fine and there are no issues with authentication etc. There are items in Sitecore which grant access to members of this role. The authenticated user is currently only able to browse items that he/she has access to.

Problem:

The problem is that when a user visits another section of the site, they need to perform an action (i.e. accept terms and conditions) before being granted access.

If the user accepted T & Cs, I am trying to:

  • Remove Sitecore role "domain\TempRole" from current Virtual User
  • Add user to Sitecore role "domain\TermsAccepted"
  • Redirect user to items that have this role assigned

The simplified code is:

/terms-page

public ActionResult AcceptTermsAndConditions(TermsAndConditionsResponseModel response)
{
    if (_repository.AcceptTermsAndConditions(HttpContext.GetOwinContext(), Session))
    {
        // Remove Sitecore Roles
        Sitecore.Security.Accounts.User.Current.Roles.RemoveAll();

        // Add user to role
        Sitecore.Security.Accounts.User.Current.Roles.Add(
           Sitecore.Security.Accounts.Role.FromName("domain\\TermsAccepted"));

        return Redirect("/user/check-access");
    }
}

/user/check-access

[Authorize]
public ActionResult Authenticate() {

    // Just inspecting the user's roles
    // the "Roles" returns "domain\TempRole" and has no other roles, 
    // so the Roles.RemoveAll() and Add() did not work
    var sitecoreUserRoles = Sitecore.Security.Accounts.User.Current.Roles;

    return Sitecore.Security.Accounts.User.Current.IsInRole("domain\TermsAccepted") 
        ? new RedirectResult("/pending-terms") : new RedirectResult("/user/access-granted");
}

When the user is redirected to /user/check-access page, the Authenticate() Action Method should direct to /user/access-granted if the user has role "domain\TermsAccepted", however, user's Sitecore roles have not changed.

It still shows "domain\TempRole", therefore, user is redirected back to /terms-page

I do not understand is why I cannot change Sitecore user's roles. As this is a virutal Sitecore user (the isPersistentUser flag is set to "false"), I should be able to add/remove Sitecore Roles.

Just as a test I also tried to update the Virtual user's Profile and added a test custom property in AcceptTermsAndConditions(), however, this also gets lost on page redirect.

How can I change Virtual user's Roles AFTER the user has been authenticated via external ID provider?

  • Try to save your changes -> Sitecore.Security.Accounts.User.Current.Profile.Save(); – Peter Procházka Oct 29 at 11:46
  • I've already tried this already and it doesnt change anything. As I said, I've tried adding custom properties to the Profile and before the existing the AcceptTermsAndConditions() Action Method, I can observe the addition of new property, however, upon redirection to another controller action method, it gets lots. – Sohail Siddiqi Oct 29 at 12:13
  • Have you seen this? sitecore.stackexchange.com/a/8758/88 – josedbaez Oct 29 at 15:38
  • @josedbaez, i just read that - thanks. I seems to be similar issue where the authenticated user has a Virtual User but properties are not being saved. In our case, its user roles. I raised a ticket with Sitecore Support a few days ago. Awaiting response. – Sohail Siddiqi Oct 30 at 8:51
0

Response from Sitecore Support suggests that it is not possible to manipulate the Sitecore Virtual User roles or profile when using Federated Authentication. I have been advised that:

This is expected as the concept of the Federated Authentication means that you delegate authentication to a trusted identity provider and all the users and their roles are managed on the side of this provider. Once the authentication process is finished, the authentication cookie is set. It contains role claims which were applied during the claim transformation mechanism. The user roles are read from the cookie on each request so updating the collection of user roles programmatically will not work.

Interesting to note that "user roles are read from the cookie on each request".

After the user "Accept" term I've been advised to:

  • Add the necessary role to the ClaimsIdentity object
  • Sign out the user
  • Then sign in using the updated ClaimsIdentity.Claims collection to refresh the authentication cookie. You can try using Microsoft.Owin.Security.AuthenticationManager type methods for this purpose
  • Sign in user again

In the end I was able to update the roles by following this: https://stackoverflow.com/questions/24587414/how-to-update-a-claim-in-asp-net-identity

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.