.net表单身份验证 - 手动设置HttpContext.Current.User在自定义AuthorizeAttribute中不起作用

Tsa*_*mba 12 .net asp.net-mvc forms-authentication httpcontext

我已经打了好几个小时了,我很难过.我正在向MVC 5控制器发出ajax post请求,试图自动登录特定的预定义"超级"用户.在控制器方法中,我正在尝试以编程方式设置HttpContext.Current.User并进行身份验证,因此超级用户可以跳过手动登录的过程.对此的共识似乎就在这里,我实现了:

设置HttpContext.Current.User

这似乎有效,直到我尝试使用自定义AuthorizeAttribute查看任何其他控制器方法.

控制器方法:

[HttpPost]
[AllowAnonymous]
public ActionResult Login(string username)
{
    string password = ConfigurationManager.AppSettings["Pass"];

    User user = service.Login(username, password);

    var name = FormsAuthentication.FormsCookieName;
    var cookie = Response.Cookies[name]; 
    if (cookie != null)
    {   
        var ticket = FormsAuthentication.Decrypt(cookie.Value);
        if (ticket != null && !ticket.Expired)
        {
            string[] roles = (ticket.UserData as string ?? "").Split(',');
            System.Web.HttpContext.Current.User = new GenericPrincipal(new FormsIdentity(ticket), roles);
        }
    }

    //...processing result

    return Json(result);
}
Run Code Online (Sandbox Code Playgroud)

上面的service.Login方法创建cookie:

FormsAuthentication.SetAuthCookie(cookieValue, false);
Run Code Online (Sandbox Code Playgroud)

虽然我正在设置具有Identity和IsAuthenticated的User,但下面的filterContext.HttpContext.User不是同一个用户.它本质上是空的,好像从未分配过,并且未经过身份验证.

public override void OnAuthorization(AuthorizationContext filterContext) 
{
    string[] userDetails = filterContext.HttpContext.User.Identity.Name.Split(char.Parse("|"));
}
Run Code Online (Sandbox Code Playgroud)

我能找到的最近的帖子是:IsAuthenticated适用于浏览器 - 但不适用于Air客户端!

但是,对我来说已经有了解决方法:

<authentication mode="Forms">
  <forms cookieless="UseCookies" timeout="60" loginUrl="~/Account/Login" />
</authentication>
Run Code Online (Sandbox Code Playgroud)

我缺少什么使AuthorizationContext.User匹配我在控制器中进行身份验证的HttpContext.Current.User?

更新:

我意识到我需要一个重定向来正确设置cookie,我只是无法通过ajax调用远程工作.这是在站点B上执行控制器方法时站点A中的脚本的样子.此重定向不会设置会话.在下一个控制器方法上验证用户时,它仍然不存在.它只是将我重定向回登录视图.

function remoteLogin(id) {
    $.ajax({
        url: "/MyController/RemoteLogin",
        type: "POST",
        dataType: "json",
        data: { "id": id }
    }).done(function (data) {
        if (data) {
            if (data.user) {
                var user = data.user;
                $.ajax({
                    url: "http://siteB.xyz/Account/Login",
                    type: "POST",
                    dataType: "json",
                    data: { "username": user.username, "password": user.password }
                }).done(function (data) {
                    if (data) {
                        window.location.href = "http://siteB.xyz/Next"
                    } else {
                        alert("Fail.");
                    }
                }).fail(function (data) {
                    alert("Fail.");
                });
            } else {
                alert("Fail.");
            }
        }
    }).fail(function (data) {
        alert("Fail.");
    });
}
Run Code Online (Sandbox Code Playgroud)

yaz*_*ati 3

您遇到的问题是,此时您仅设置身份验证 cookie,在表单身份验证模块内创建的 IPrincipal 在有新请求之前不会发生 - 所以此时 HttpContext.User 处于奇怪的状态。一旦发生重定向,因为这是来自浏览器的新请求,所以在到达您的页面并创建正确的用户对象之前,将读取 cookie。

Cookie 仅在请求完成后才会在浏览器上设置。