我在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不存在。什么可能导致这种行为?任何帮助或线索将不胜感激。
答案 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之前退出的异步方法有什么关系?现在,我有一个阻止例程,问题就不复存在了。