views:

282

answers:

4

Hi all, simple question...

Given I have an ASP.NET site, which uses a [custom] RoleProvider,
Is there any way in which I can somehow "refresh" the provider without forcing the user to log out of the site and log back in?

I'm looking for something that would be akin to a fictional method

Roles.Refresh()

Specifically, I am looking at this for if an administrator changes a user's roles, the user sessions could maybe refresh themselves every 10 minutes or something.

A: 

depend on the custom role provider used.

Just call a "update my role" function on every request? (bad way but at least your sure to update it)

Fredou
Yes, that's what I want (though I wouldn't call it on EVERY request). How would I go about implementing this then in my custom RoleProvider? There is nothing in the RoleProvider interface that seems to hook in to [how/where]ever ASP.NET caches the roles.
eidylon
+1  A: 

I assume you have something like this in your web.config:

<roleManager enabled="true" defaultProvider="..." 
             cacheRolesInCookie="true">

The roles are cached in a cookie , so you can force them to refresh by deleting the cookie. This method worked for me. I added the cookieName attribute so that I don't rely on asp.net's default. For your scenario, though, you may be able to just set the cookieTimeout attribute to something reasonable and be done with it.

This method won't update the roles immediately, of course. They will be updated on the next page load after you delete the cookie.

Gabe Moothart
Found the method, thank you. This can be done by calling: Roles.DeleteCookie();
eidylon
A: 

If you don't want to use cookies you can use Session object to cache the roles. like this:

        public override string[] GetRolesForUser(string username)
    {
        System.Web.SessionState.HttpSessionState Session = HttpContext.Current.Session;
        if (Session["roles"] == null)
                Session["roles"] = MyDataProvider.Security.GetRolesForUser(username);
        return (string[])Session["roles"];
    }

When you need to update the roles for this user you can do

Session["roles"] = null
TheManAtTheOrgansiation
By default you can't use the Session object in the GetRolesForUser() method. The Session isn't yet initialized in this phase.Don't know if there's a work-around for it though.
Jan_V
A: 

The roles are cached in a cookie (encrypted of course). The simplest solution will be to disable caching in the web.config file. You will loose some performance.

Else you must somehow resend the auth cookie. One major problem is that many browsers will not accept cookies on redirects with method post.

The other solution that worked for me:

1) In a aspx methodod log the user out and store the username in the session

//Add User to role reviewer and refresh ticket

Roles.AddUserToRole(User.Identity.Name, Constants.ROLE_REVISOR);
FormsAuthentication.SignOut();
FormsAuthentication.SetAuthCookie(User.Identity.Name, false); //Might work in some browsers
Session["REFRESHROLES"] = User.Identity.Name;
Response.Redirect("someprotectedurl?someid=" + someid);

2) In the loginpage sign the user in again if username is stored in session

protected void Page_Load(object sender, EventArgs e)
{
   string returnUrl = Request.QueryString["ReturnUrl"];
   if(String.IsNullOrEmpty(returnUrl) == false)
   {

         if(Session["REFRESHROLES"] != null)
         {
            if(!string.IsNullOrEmpty(Session["REFRESHROLES"].ToString()))
            {

               FormsAuthentication.SetAuthCookie(Session["REFRESHROLES"].ToString(), false);
               Session.Remove("REFRESHROLES");
               Response.Redirect(returnUrl);  
               return;
            }
         }