Programatically refresh user roles
Greetings,
var roleManager = RoleManager.GetManager("MyProvider");
roleManager.Provider.SuppressSecurityChecks = true;
var userManager = UserManager.GetManager("MyProvider");
userManager.Provider.SuppressSecurityChecks = true;
var roleMembers = roleManager.GetRole("Members");
var roleMembersNoProfile = roleManager.GetRole("MembersNoProfile");
roleManager.AddUserToRole(userManager.GetUser(userId), roleMembers);
roleManager.RemoveUserFromRole(userId, roleMembersNoProfile);
Hi Daniel,
In your code I do not see where you commit the transaction by calling roleManagerInstance.SaveChanges().
You can make application restart by using RestartApplication(bool rest) static method of SystemManager. When you pass true to the parameter this will make a full restart, but this requires that you should run the project under full trust environment.
All the best,
Ivan Dimitrov
the Telerik team
Is there another way to force a refresh of the current user's roles after programmatically updating them? I am working on a sso implementation using STS and hooking into the LoginCompleted event to update the user's roles based on information from the sso identity server.
I got it so that the user's roles do get updated, but they have to do a full logout and log back in cycle before they get "applied." It also appears that during this event the user is not really logged in yet, so I can't try to fire any of the claims manager "refresh" functions.
Hello Michael,
First problem, that after applying the roles, they are not updated is because RoleManager manages the CRUD operations of the roles, which means managing them in the database. In order for the user to have those roles "applied" for the current request, they need to be inserted as claims when the actual request is authenticated.
LoginCompleted event is not the right place to do, since the user at that point is verified (his credentials are verified) but the request is still not authenticated.
What you need to do in order to achieve the scenario you want is to inherit SFClaimsAuthenticationManager and override its Authenticated method. In the overridden method you call the base.Authenticate and you will get the user principal, which contains all the claims about the current request. There you can manipulate the roles (add/remove) and they will be applied immediately for the current request. Note that you go through this method only once, after the user has been verified and while the request is being authenticated. See the an example of how to implement it:
using
Microsoft.IdentityModel.Claims;
using
System;
using
System.Linq;
using
Telerik.Sitefinity.Security;
using
Telerik.Sitefinity.Security.Claims;
using
Telerik.Sitefinity.Security.Configuration;
namespace
SitefinityWebApp
public
class
CustomSFClaimsAuthenticationManager : SFClaimsAuthenticationManager
public
override
Microsoft.IdentityModel.Claims.IClaimsPrincipal Authenticate(
string
resourceName, Microsoft.IdentityModel.Claims.IClaimsPrincipal incomingPrincipal)
var principal =
base
.Authenticate(resourceName, incomingPrincipal);
var value = String.Concat(roleId,
";"
, roleName,
";"
, roleProvider);
string
issuer =
"http://localhost"
;
principal.Identities[0].Claims.Add(
new
Claim(SitefinityClaimTypes.Role, value, ClaimValueTypes.String, issuer, issuer));
return
principal;
<
microsoft.identityModel
>
<
service
>
<
claimsAuthenticationManager
type
=
"SitefinityWebApp.CustomSFClaimsAuthenticationManager, SitefinityWebApp"
/>
Ivan, your code gave me the results I needed as well. The only minor issue is on the backend, when checking roles of a user, the new role isn't listed (but I do gain access to pages). I'm guessing it's using a cached copy. Again, for my purposes it doesn't matter but someone else might need it. It would still be nice to know how to clear the role cache for a particular user w/o restarting the whole site. Thanks
Any alternatives yet to clear the role cache maybe?
Hello Njabulo,
Please check the below KB article for more details on this:
www.sitefinity.com/.../roles-assigned-to-user-while-logged-in-do-not-take-effect-before-the-user-logs-out-and-logs-in-again
Regards,
Sabrie Nedzhip
Telerik