開発中の電子商取引ソリューションではAspNet Identity 2.2.1を使用しており、ゲスト(匿名)ユーザーは事前にWebサイトに登録しなくてもチェックアウトを完了する必要があります。この要件を満たすために、UserTrackId(文字列GUID)を取得するUserMigrationAttributeという名前のActionFilterが記述されています.SessionTrackId(文字列GUID)はリクエストCookieと共にSessionTrackIdが見つからない場合はすべてのリクエストに対してHttpModuleから設定し、 usernameは[email protected]のようなものです。ASP.NET ID 2と匿名ユーザー
このUserMigration属性でBaseControllerクラスを装飾して、サイト全体でその機能を利用しました。
これまでのすべてのことは、いずれのユーザーに対してもページが初めてロードされている場合、[ValidateAntiForgeryToken]
属性を持つメソッドへのJquery Ajax呼び出しを作成しようとすると、すべてのajax呼び出しで__RequestVerificationToken
パラメータを送信していても、呼び出しは 'The provided anti-forgery token was meant for a different claims-based user than the current user.
'というエラーで失敗します。
しかし、ユーザーがリンクをクリックして別のページを開いたり、現在のページを再読み込み/更新したりすると、その後のすべてのajax呼び出しが正常に完了します。
私たちの理解では、UserMigrationAttributeはOnActionExecutingメソッドでユーザーを作成しますが、@ Html.AntiForgeryToken()が適切な値で更新されていないプロセスでsignInした後にユーザーを作成します。
以下のUserMigrationAttributeコードがあります。
[AttributeUsage(AttributeTargets.Class)]
public class UserMigrationAttribute : ActionFilterAttribute
{
public ApplicationSignInManager SignInManager(ActionExecutingContext filterContext)
{
return filterContext.HttpContext.GetOwinContext().Get<ApplicationSignInManager>();
}
public UserManager UserManager(ActionExecutingContext filterContext)
{
return filterContext.HttpContext.GetOwinContext().GetUserManager<UserManager>();
}
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
CreateMigrateCurrentUser(filterContext);
base.OnActionExecuting(filterContext);
}
private static readonly object LockThis = new object();
private void CreateMigrateCurrentUser(ActionExecutingContext filterContext)
{
lock (LockThis)
{
var signInManager = SignInManager(filterContext);
var userManager = UserManager(filterContext);
var sessionTrackId = GetSessionTrackId(filterContext);
if (!filterContext.HttpContext.Request.IsAuthenticated)
{
if (!string.IsNullOrEmpty(sessionTrackId))
{
var username = string.Format("{0}@mydomain.com", sessionTrackId);
var user = userManager.FindByName(username);
if (user == null)
{
user = new User() {UserName = username, Email = username};
var result = userManager.Create(user);
userManager.AddToRole(user.Id, StringResources.AnonymousVisitorsGroup);
}
signInManager.SignIn(user, true, true);
}
}
else
{
if (!string.IsNullOrEmpty(sessionTrackId))
{
var username = string.Format("{0}@mydomain.com", sessionTrackId);
var user = userManager.FindByName(username);
if (user != null)
{
if (!HttpContext.Current.User.IsInRole(StringResources.AnonymousVisitorsGroup))
{
var targetUserId = HttpContext.Current.User.Identity.GetUserId<int>();
var service = new Service();
service.Users.MigrateUser(user.Id, targetUserId);
}
}
}
}
}
}
private string GetSessionTrackId(ActionExecutingContext filterContext)
{
var retVal = string.Empty;
if (filterContext.HttpContext.Request.Cookies["stid"] != null)
{
retVal = filterContext.HttpContext.Request.Cookies["stid"].Value;
}
return retVal;
}
}
ご意見やご提案は高く評価されます。
は偽造防止トークンが次のリクエストまで更新されませんクッキー、に設定されているので、これが起こっている
ご回答いただきありがとうございます。これはfilterContextにリダイレクトされ、私たちの問題を解決することを示唆しています。 –