我有一个ASP.NET 4.6的web应用程序,我正在尝试使用OWIN添加OpenId Connect。
我添加了我的Owin启动类,一切似乎都配置正确,但是我遇到的问题是ASP Identity/Authenticated用户从未被创建。我最终陷入了无限循环中,其中OpenId回调页面重定向回原始页面,然后重定向到登录页面,依此类推。
这是我的启动类:
public void Configuration(IAppBuilder app)
{
app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
app.UseKentorOwinCookieSaver();
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
LoginPath = new PathString("/Login.aspx"),
ExpireTimeSpan = TimeSpan.FromDays(7)
});
app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions
{
ClientId = _clientId,
ClientSecret = _clientSecret,
Authority = _authority,
RedirectUri = _redirectUri, // LoginCallback
PostLogoutRedirectUri = "http://localhost:60624/Logout.aspx",
ResponseType = OpenIdConnectResponseType.CodeIdToken,
Scope = "openid profile email",
TokenValidationParameters = new TokenValidationParameters
{
NameClaimType = "name"
},
Notifications = new OpenIdConnectAuthenticationNotifications
{
AuthorizationCodeReceived = async n =>
{
// Exchange code for access and ID tokens
var tokenClient = new TokenClient($"{_authority}/as/token.oauth2", _clientId, _clientSecret);
var tokenResponse = await tokenClient.RequestAuthorizationCodeAsync(n.Code, _redirectUri);
if (tokenResponse.IsError)
{
throw new Exception(tokenResponse.Error);
}
var userInfoClient = new UserInfoClient($"{_authority}/idp/userinfo.openid");
var userInfoResponse = await userInfoClient.GetAsync(tokenResponse.AccessToken);
var claims = new List<Claim>(userInfoResponse.Claims)
{
new Claim("id_token", tokenResponse.IdentityToken),
new Claim("access_token", tokenResponse.AccessToken)
};
n.AuthenticationTicket.Identity.AddClaims(claims);
//// create the identity
//var identity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationType);
//System.Web.HttpContext.Current.GetOwinContext().Authentication.SignIn(new AuthenticationProperties
//{
// IsPersistent = true
//}, identity);
}
}
});
}
这是Login.aspx页面:
protected void Page_Load(object sender, EventArgs e)
{
if (!Request.IsAuthenticated)
{
HttpContext.Current.GetOwinContext().Authentication.Challenge(
new AuthenticationProperties { RedirectUri = Request["ReturnUrl"] ?? "Default.aspx" },
OpenIdConnectAuthenticationDefaults.AuthenticationType);
}
}
页面流程如下:
1)请求:http://localhost:60624/Page.aspx,响应:302 - 重定向到 Login.aspx。
2)请求:http://localhost:60624/Login.aspx?ReturnUrl=%2FPage.aspx,响应:302 - 重定向到 https://auth.myprovider.com。一些 cookie 在此处设置在响应头中:
Set-Cookie: OpenIdConnect.nonce.KIsuj4RUmGKJIynLrkEScxBvGrZzkMo6ylZ%2F4lRknPM%3D=xxxxxxxxx; path=/; expires=Mon, 22-Apr-2019 14:12:00 GMT; HttpOnly Set-Cookie: OpenIdConnect.nonce.KIsuj4RUmGKJIynLrkEScxBvGrZzkMo6ylZ%2F4lRknPM%3D=yyyyyyyyy; expires=Mon, 22-Apr-2019 14:12:00 GMT; path=/; HttpOnly
3)认证提供商,登录,它将 302 重定向到 /LoginCallback。4)请求:http://localhost:60624/LoginCallback,响应:302 - 重定向到 /Page.aspx。在这里清除了第 2 步设置的 cookie:
Set-Cookie: OpenIdConnect.nonce.KIsuj4RUmGKJIynLrkEScxBvGrZzkMo6ylZ%2F4lRknPM%3D=; path=/; expires=Thu, 01-Jan-1970 00:00:00 GMT Set-Cookie: OpenIdConnect.nonce.KIsuj4RUmGKJIynLrkEScxBvGrZzkMo6ylZ%2F4lRknPM%3D=; expires=Thu, 01-Jan-1970 00:00:00 GMT; path=/
5)返回到 Page.aspx,用户未经过身份验证;回到步骤 1。我已经进行了一些调试,并且在启动时 AuthorizationCodeReceived 已经触发,后端成功调用了用户信息终结点。我尝试从该通知中调用 System.Web.HttpContext.Current.GetOwinContext().Authentication.SignIn(),但似乎没有任何作用。
此时,我卡住了。为什么用户身份验证的身份验证 cookie 没有被设置?这似乎应该自动发生。我是否应该手动创建它? (如何手动创建身份验证 cookie 而不是默认方法?)
编辑:在查阅了@Zaxxon的回复后,我得以让它正常工作。在AuthorizationCodeReceived通知中有两个问题:
- 我需要创建ClaimsIdentity。在我上面提交的原始代码中,我已经将其注释掉了,但是也是不正确的。
- 我必须用新创建的身份替换AuthenticationTicket。然后将声明添加到这个新身份中。
以下是可正常工作的代码:
ClaimsIdentity identity = new ClaimsIdentity(DefaultAuthenticationTypes.ApplicationCookie, ClaimTypes.GivenName, ClaimTypes.Role);
n.AuthenticationTicket = new AuthenticationTicket(identity, n.AuthenticationTicket.Properties);
n.AuthenticationTicket.Identity.AddClaims(claims);