Say I have a module in my app that can change the username. Since the username is changed, the authcookie should be updated along with the XSRF token.
Upon trying this, I am getting an error saying "The provided anti-forgery token was meant for user...". Well I got a little hint on how to resolve this. Since the current XSRF token was for the old username and not for the updated one, hence this error.
Looking into the Global.asax code, the change of username would only be reflected on Application_AuthenticateRequest
. I also modified the Application_PostAuthenticateRequest
to force create a new XSRF token on the updated username if upon validation, it will encounter the same error.
protected void Application_PostAuthenticateRequest(object sender, EventArgs e)
{
var existingXsrfCookie = Request.Cookies["XSRF-TOKEN"];
// logic for parsing XSRF-TOKEN
try
{
...more logic
AntiForgery.Validate(currentCookieToken, currentFormToken);
return;
}
catch (Exception ex)
{
Logger.ErrorException(ex.Message, ex);
}
// logic for creating new XSRF token
}
Now my real question is, can I trigger Application_AuthenticateRequest
and Application_PostAuthenticateRequest
from other than the Global.asax on server side?
I want to trigger then immediately after the user has updated the username.
We attached an onExecuted action filter on the api call to which the user details was updated. Since XSRF token is generated from HTTPContext.Current, we updated the Thread.CurrentPrincipal to reflect the updated details.
[AntiForgeryUpdate]
[HttpPost]
public async Task<EditUserResponse> editUser (EditUserRequest request)
{
try
{
//code for updating user
var principal = Request.GetRequestContext().Principal;
var identity = principal.Identity;
identity.IdentityInfo = changedUser;
}
catch(Exception ex)
{
throw;
}
}
public class AntiForgeryUpdate: ActionFilterAttribute
{
public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
{
if (actionExecutedContext.Request.Method != HttpMethod.Get)
{
AntiForgery.GetTokens(null, out string cookieToken, out string formToken);
var token = cookieToken + ":" + formToken;
actionExecutedContext.Response.Headers.AddCookies("XSRF-TOKEN", token);
}
base.OnActionExecuted(actionExecutedContext);
}
}