Do you have Roles configured to cache user roles in a cookie?
This is controlled by <roleManager> section in web.config.
There is a method Roles.DeleteCookie() which will clear this.
/johan
Hi, and thanks for the reply. I have Roles configured, and a Roles.DeleteCookie() clears roles in cache so they are updated. However, I think the problem is related to the
EPiServer.Security.PrincipalInfo.CurrentPrincipal = EPiServer.Security.PrincipalInfo.CreatePrincipal("KNOWNUSERNAME");
CreatePrincipal probably just set current principal to a known (or not known) prinsipal every time, it doesent update the principals roles. But if i run membership.validate(user,pass), the user's groups and rights and roles are updated, and the next time I use the code above, the created principal is updated with the correct rights. So what goes on behind the scene? :) The sites are configured with the multiplexingprovider.
Hi, and thanks for the reply. I have Roles configured, and a Roles.DeleteCookie() clears roles in cache so they are updated after I for example run membership.validate(), (Which I can't do without some pretty ugly hacking:)) However, I think the problem is related to the
EPiServer.Security.PrincipalInfo.CurrentPrincipal = EPiServer.Security.PrincipalInfo.CreatePrincipal("KNOWNUSERNAME");
CreatePrincipal probably just set current principal to a known (or not known) prinsipal every time, it doesent update the principals roles. But if i run membership.validate(user,pass), the user's groups and rights and roles are updated, and the next time I use the code above, the created principal is updated with the correct rights. So what goes on behind the scene? :) The sites are configured with the multiplexingprovider.
Actually, the code in PrincipalInfo.CreatePrincipal() looks like this:
new GenericPrincipal(new GenericIdentity(username), Roles.GetRolesForUser(username));
So, it will make a call to Roles.GetRolesForUser().
Are you using the EPiServer.Security.ActiveDirectoryRoleProvider? If so, then *it* will internally cache the DirectoryData-entry
(including the "memberOf" attribute).
Try (for tests) to make a call to ClearCache() for the ActiveDirectoryFroleProvider before creating the principal and see if that helps:
((ActiveDirectoryRoleProvider)Roles.Providers["MyActiveDirectoryRoleProvider"]).ClearCache();
/johan
HI again! I can't seem to find the clrearcache() function. Actually am using the MultiplexingRoleProvider, and the users are identified as windowsmembership and WindowsRoleProvider. I'm not sure that it's related to caching either, it can be weeks between the user's groups in ad have changed, but still the roles are not changed for the createprincipal-user.
Aha, the WindowsMembershipProvider/WindowsRoleProvider are a little "special" in that they
synchronize groupmembership to local DB (using procedures netWinMembershipGroup-Insert/Delete/List)
When the WindowsRoleProvider.GetRiolesForUser(username) is called, it first tries to cast the Identity of the CurrentPrincipal
into a Windowsidentity, and if that fails, it'll return the (previously synchronized) groups from DB:
WindowsIdentity identity = PrincipalInfo.CurrentPrincipal.Identity as WindowsIdentity;
if ((identity == null) ... )
{
return DB.MemberOfGroups(username);
}
else
... read groups from WindowsIdentity
This is exactly what happens in your case when you call the PrincipalInfo.CreatePrincipal, it'll return a GenericPrincipal/GenericIdentity
and the cast to WindowsIdentity will fail.
You may want to try creating the WindowsIdentity yourself:
WindowsIdentity windowsIdentity = new WindowsIdentity(@"username");
WindowsPrincipal windowsPrincipal = new WindowsPrincipal(windowsIdentity);
EPiServer.Security.PrincipalInfo.CurrentPrincipal = windowsPrincipal;
/johan
Thank you johan! Now things start to make sense to me :) I ended up with the code:
Roles.DeleteCookie();
WindowsIdentity windowsIdentity = new WindowsIdentity(username);
WindowsPrincipal windowsPrincipal = new WindowsPrincipal(windowsIdentity);
string[] groups = WindowsMembershipProvider.GroupNamesFromIdentity(windowsIdentity,WindowsMembershipProvider.GetDeletePrefix());
new WindowsProviderDB().SynchronizeGroups(username, groups);
EPiServer.Security.PrincipalInfo.CurrentPrincipal = windowsPrincipal;
Not sure I need the DB().SynchronizeGroups, but it can't hurt can it?
No I dont think you need the extra call to WindowsProviderDB.SynchronizeGroups(), it will be
called automatically in the WindowsRoleProvider.GetRolesForUser(user).
However, the only thing it may hurt would be performance.
/johan
Hi! I have a little special scenario where a 3rd party solution does the actual user validation. When the user enters different episerver sites, I can check if the user has done the 3rd party validation. Both the episerver and 3rd party solution works within active directory and ad grups controls access rights for pages in episerver. The problem is that when a user gains or loses membership to different groups in AD, I can't synchronize the episerver rights without doing a membership.validate(). I only have access to the username and can not do this. Do someone have a smart solution to this? My code so far :) :