【问题标题】:Cookie with claims not being set on "production" server未在“生产”服务器上设置声明的 Cookie
【发布时间】:2017-02-17 01:50:49
【问题描述】:

我在 webforms 应用程序中使用 IdentityServer3,我能够按照 MVC No Library Client 在我的本地计算机上复制 id_token 检索。我的完整源代码在 GitHub 上发布为 IdServer3-WebFormsAppDemo

但是,当移动到实际生产服务器时,该应用似乎无法设置声明。这是处理 cookie 登录的回调(在用户验证并同意之后):

// AuthorizationCallback.aspx
private async Task ProcessRequest () {
    var idToken = Request.Form["id_token"];
    var state = Request.Form["state"];

    if (idToken == null) {
        throw new InvalidOperationException("invalid id_token");
    }

    var claims = await ValidateIdentityTokenAsync(idToken, state);
    var claimsIdentity = new ClaimsIdentity(claims, DefaultAuthenticationTypes.ApplicationCookie);
    claimsIdentity.AddClaim(new Claim("id_token", idToken));
    Request.GetOwinContext().Authentication.SignIn(claimsIdentity);

    Response.Redirect("/");
}

在令牌验证和 cookie 登录后,应用重定向到另一个表单并显示 id_token 声明:

// Default.aspx
protected void Page_Load (object sender, EventArgs e) {
    heading.InnerText = Page.User.Identity.IsAuthenticated ? "User Is Authenticated" : "User Is Not Authenticated";
    foreach (var claim in Request.GetOwinContext().Authentication.User.Claims) {
    AddListElement(claim.Type, claim.Value);
    }
}

我可以确认令牌已在 AuthorizationCallback.aspx 上成功验证,并且正在获取声明,当重定向到 Default.aspx 时,声明正在测试时显示在本地,但从生产服务器测试时没有。

Page.User.Identity.IsAuthenticated 总是返回 false,并且没有存储 User 对象的声明。从我的浏览器检查时,我可以在响应标头上看到这 2 个 cookie:

set-cookie:.AspNet.TempCookie=; path=/; expires=Thu, 01-Jan-1970 00:00:00 GMT
set-cookie:.AspNet.ApplicationCookie=fyMP9H ... Gt-7VlTA; path=/; secure; HttpOnly

但仅当从 localhost 测试应用程序时,在生产服务器中这些 cookie 不存在。什么可能导致这种行为?任何帮助或线索将不胜感激。

【问题讨论】:

    标签: c# identityserver3


    【解决方案1】:

    看来我刚刚发现了导致问题的原因。我的 AuthorizationCallback.aspx 表单已配置为可以处理异步方法:

    // AuthorizationCallback.aspx.cs
    protected void Page_Load (object sender, EventArgs e) {
        // Needed in order to process ValidateIdentityTokenAsync below
        RegisterAsyncTask(new PageAsyncTask(ProcessRequest));
    }
    
    private async Task ProcessRequest () {
        var idToken = Request.Form["id_token"];
        ...
        var claims = await ValidateIdentityTokenAsync(idToken, state);
        ...
    }
    

    通过修改表单使其不处理异步请求,我能够让声明为我工作:

    protected void Page_Load (object sender, EventArgs e) {
        var idToken = Request.Form["id_token"];
        ...
        var task = Task.Run(async () =>
            await ValidateIdentityTokenAsync(idToken, state)
        );
        var claims = task.Result;
        ....
    }
    

    我仍然不确定为什么此更改解决了我的问题,但我猜这与登录之前退出的异步方法有关?现在我有了一个阻塞例程,问题就不再存在了。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-02-07
      • 2022-01-18
      • 2015-10-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-02-14
      相关资源
      最近更新 更多