Cookie没有设置"生产"服务器

时间:2016-10-08 01:33:34

标签: c# identityserver3

我在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,并且用户对象没有存储声明。从我的浏览器检查时,我可以在响应标题上看到这两个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不存在。什么可能导致这种行为?任何帮助或线索将不胜感激。

1 个答案:

答案 0 :(得分:0)

我似乎刚刚发现了造成这个问题的原因。我的 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;
    ....
}

我仍然不确定为什么这个更改解决了我的问题,但我猜测它与在SignIn之前退出的异步方法有什么关系?现在,我有一个阻止例程,问题就不复存在了。