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?