Search code examples
c#asp.net-mvcauthenticationcookiesowin

ASP.NET MVC - Refresh Auth Cookie on Anonymous Ajax Requests


I'm trying to refresh a session after an ajax request to a controller that has the [AllowAnonymous] attribute. For some reasons removing this attribute is not a possibility right now. The authentication is being made via OWIN (Microsoft.Owin v4.1.0).

Here is how the authentication is made:

public class Startup_Auth
{
    public void Configuration(IAppBuilder app)
    {
        try
        {
            MyAuthenticationProvider provider = new MyAuthenticationProvider() { OnValidateIdentity = MyValidation };
            app.SetDefaultSignInAsAuthenticationType("ExternalCookie");
            app.UseCookieAuthentication(new CookieAuthenticationOptions
            {
                AuthenticationType = "ExternalCookie",
                AuthenticationMode = AuthenticationMode.Active,
                CookieName = "MyCookie",
                CookieSecure = CookieSecureOption.Always,
                LoginPath = new PathString(PATH),
                ExpireTimeSpan = TimeSpan.FromMinutes(EXPIRATION),
                Provider = provider,
                TicketDataFormat = new MyTicketDataFormat()
            });
        }
        ...
    }

    private static Task MyValidation(CookieValidateIdentityContext context)
    {
        ...
    }
}

I have also tried by the controller's OnActionExecuting:

[AllowAnonymous]
public class MyController : Controller
{
    protected override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        // can't access cookies here
    }
}

Any suggestions will be very welcome.


Solution

  • You need to create a claims identity and call SignIn on the AuthenticationManager (SignInManager.SignInAsync) this way, the Claims are updated:

    // Get User and a claims-based identity
    ApplicationUser user = await UserManager.FindByIdAsync(User.Identity.GetUserId());
    var Identity = new ClaimsIdentity(User.Identity);
    
    // Remove existing claim and replace with a new value
    await UserManager.RemoveClaimAsync(user.Id, Identity.FindFirst("AccountNo"));
    await UserManager.AddClaimAsync(user.Id, new Claim("AccountNo", value));
    
    // Re-Signin User to reflect the change in the Identity cookie
    await SignInManager.SignInAsync(user, isPersistent: false, rememberBrowser: false);
    
    // [optional] remove claims from claims table dbo.AspNetUserClaims, if not needed
    var userClaims = UserManager.GetClaims(user.Id);
    if (userClaims.Any())
    {
        foreach (var item in userClaims)
        {
            UserManager.RemoveClaim(user.Id, item);
        }
    }