OpenId Connect 中间件未在 WebForms 应用程序中设置身份验证 cookie
OpenId Connect middleware not setting auth cookie in an WebForms app
我正在尝试将 OpenId Connect 集成到长期存在的网络表单应用程序中。我能够迁移应用程序以使用 OWIN,并且我正在使用 OpenIdConnectAuthenticationMiddleware 对我的 IdP 提供商进行身份验证。一切顺利,直到我需要构建从 IdP 获得的新身份并设置 cookie - 我认为这部分没有发生。
我的 Startup.Configure 方法的重要部分:
app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
LoginPath = new PathString("/login.aspx"),
CookieManager = new SystemWebCookieManager() //custom cookie manager
});
app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions
{
Authority = "https://[development_domain]/core",
ClientId = "VDWeb",
ResponseType = "code id_token token",
Scope = "openid profile",
UseTokenLifetime = true,
SignInAsAuthenticationType = "Cookies",
Notifications = new OpenIdConnectAuthenticationNotifications
{
SecurityTokenValidated = async n =>
{
var userInfo = await EndpointAndTokenHelper.CallUserInfoEndpoint(n.ProtocolMessage.AccessToken);
//now store Preferred name :
var prefNameClaim = new Claim(
Thinktecture.IdentityModel.Client.JwtClaimTypes.PreferredUserName,
userInfo.Value<string>("preferred_username"));
var myIdentity = new ClaimsIdentity(
n.AuthenticationTicket.Identity.AuthenticationType,
Thinktecture.IdentityModel.Client.JwtClaimTypes.PreferredUserName,
Thinktecture.IdentityModel.Client.JwtClaimTypes.Role);
myIdentity.AddClaim(prefNameClaim);
//add unique_user_key claim
var subjectClaim = n.AuthenticationTicket.Identity.FindFirst(Thinktecture.IdentityModel.Client.JwtClaimTypes.Subject);
myIdentity.AddClaim(new Claim("unique_user_key", subjectClaim.Value));
myIdentity.AddClaim(new Claim("id_token", n.ProtocolMessage.IdToken));
var ticket = new AuthenticationTicket(myIdentity, n.AuthenticationTicket.Properties);
var currentUtc = new SystemClock().UtcNow;
ticket.Properties.IssuedUtc = currentUtc;
ticket.Properties.ExpiresUtc = currentUtc.Add(TimeSpan.FromHours(12));
n.AuthenticationTicket = ticket;
},
}
});
我可以确认 AuthentocationTicket 已正确填充,但未设置身份验证 cookie。我确实知道这个问题 https://katanaproject.codeplex.com/workitem/197,并且我已经尝试了为这个问题提供的所有解决方法,但 none 有所帮助。有趣的是,当我尝试将自己的 cookie 放入 SecurityTokenValidated 事件中时 - n.Response.Cookies.Append("Test", "Test");
,我可以看到 cookie 设置正确。
解决方法之一建议实施您自己的 CookieManager。让我好奇的是,当我在这个自定义管理器中将断点放入 cookie setter 时,它没有被击中,即中间件似乎甚至没有尝试设置 cookie。所以我的主要问题是 - 中间件究竟会在什么时候尝试设置 cookie?是在我设置 AuthenticationTicket 时吗?
编辑 1: 添加更多信息。我尝试与另一个 Web 应用程序(这次是 MVC)进行比较,我将其配置为使用相同的 IdP,并且按预期工作。两个应用程序的启动代码是相同的。通过 SecurityTokenValidated 事件调试时,我可以看到 MVC 应用程序(工作)创建了 System.Security.Principal.WindowsPrincipal
身份,而 webforms 应用程序(非工作)创建了 System.Security.Principal.GenericIdentity
身份。
我也添加了这个小片段
app.UseStageMarker(PipelineStage.Authenticate);
app.Use((context, next) =>
{
var identity = context.Request.User.Identity;
return next.Invoke();
});
只是为了看看在这个管道阶段填充了什么身份。对于 MVC 应用程序(工作),我看到我通过设置 AuthenticationTicket 添加的身份,对于 webforms 应用程序,我仍然看到未经身份验证的 GenericIdentity。
您能否使用默认的 cookie 管理器并查看是否会导致设置 cookie?
好吧,这很尴尬 - 问题出在 CookieAuthenticationOptions 中,显然 AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie
与 AuthenticationType = "Cookies"
NOT 相同。稍后设置后,它工作正常。
我正在尝试将 OpenId Connect 集成到长期存在的网络表单应用程序中。我能够迁移应用程序以使用 OWIN,并且我正在使用 OpenIdConnectAuthenticationMiddleware 对我的 IdP 提供商进行身份验证。一切顺利,直到我需要构建从 IdP 获得的新身份并设置 cookie - 我认为这部分没有发生。
我的 Startup.Configure 方法的重要部分:
app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
LoginPath = new PathString("/login.aspx"),
CookieManager = new SystemWebCookieManager() //custom cookie manager
});
app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions
{
Authority = "https://[development_domain]/core",
ClientId = "VDWeb",
ResponseType = "code id_token token",
Scope = "openid profile",
UseTokenLifetime = true,
SignInAsAuthenticationType = "Cookies",
Notifications = new OpenIdConnectAuthenticationNotifications
{
SecurityTokenValidated = async n =>
{
var userInfo = await EndpointAndTokenHelper.CallUserInfoEndpoint(n.ProtocolMessage.AccessToken);
//now store Preferred name :
var prefNameClaim = new Claim(
Thinktecture.IdentityModel.Client.JwtClaimTypes.PreferredUserName,
userInfo.Value<string>("preferred_username"));
var myIdentity = new ClaimsIdentity(
n.AuthenticationTicket.Identity.AuthenticationType,
Thinktecture.IdentityModel.Client.JwtClaimTypes.PreferredUserName,
Thinktecture.IdentityModel.Client.JwtClaimTypes.Role);
myIdentity.AddClaim(prefNameClaim);
//add unique_user_key claim
var subjectClaim = n.AuthenticationTicket.Identity.FindFirst(Thinktecture.IdentityModel.Client.JwtClaimTypes.Subject);
myIdentity.AddClaim(new Claim("unique_user_key", subjectClaim.Value));
myIdentity.AddClaim(new Claim("id_token", n.ProtocolMessage.IdToken));
var ticket = new AuthenticationTicket(myIdentity, n.AuthenticationTicket.Properties);
var currentUtc = new SystemClock().UtcNow;
ticket.Properties.IssuedUtc = currentUtc;
ticket.Properties.ExpiresUtc = currentUtc.Add(TimeSpan.FromHours(12));
n.AuthenticationTicket = ticket;
},
}
});
我可以确认 AuthentocationTicket 已正确填充,但未设置身份验证 cookie。我确实知道这个问题 https://katanaproject.codeplex.com/workitem/197,并且我已经尝试了为这个问题提供的所有解决方法,但 none 有所帮助。有趣的是,当我尝试将自己的 cookie 放入 SecurityTokenValidated 事件中时 - n.Response.Cookies.Append("Test", "Test");
,我可以看到 cookie 设置正确。
解决方法之一建议实施您自己的 CookieManager。让我好奇的是,当我在这个自定义管理器中将断点放入 cookie setter 时,它没有被击中,即中间件似乎甚至没有尝试设置 cookie。所以我的主要问题是 - 中间件究竟会在什么时候尝试设置 cookie?是在我设置 AuthenticationTicket 时吗?
编辑 1: 添加更多信息。我尝试与另一个 Web 应用程序(这次是 MVC)进行比较,我将其配置为使用相同的 IdP,并且按预期工作。两个应用程序的启动代码是相同的。通过 SecurityTokenValidated 事件调试时,我可以看到 MVC 应用程序(工作)创建了 System.Security.Principal.WindowsPrincipal
身份,而 webforms 应用程序(非工作)创建了 System.Security.Principal.GenericIdentity
身份。
我也添加了这个小片段
app.UseStageMarker(PipelineStage.Authenticate);
app.Use((context, next) =>
{
var identity = context.Request.User.Identity;
return next.Invoke();
});
只是为了看看在这个管道阶段填充了什么身份。对于 MVC 应用程序(工作),我看到我通过设置 AuthenticationTicket 添加的身份,对于 webforms 应用程序,我仍然看到未经身份验证的 GenericIdentity。
您能否使用默认的 cookie 管理器并查看是否会导致设置 cookie?
好吧,这很尴尬 - 问题出在 CookieAuthenticationOptions 中,显然 AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie
与 AuthenticationType = "Cookies"
NOT 相同。稍后设置后,它工作正常。