我正试图在ASP.NET Core 5 web应用程序中使用AWS Cognito实现身份验证。
我可以获得身份验证,但现在我想实现注销功能。
我可以让注销工作,因为ASP.NET认为我没有通过身份验证。
在我的Startup.cs中,我有:
options.SignedOutRedirectUri = Configuration["Authentication:Cognito:SignedOutRedirectUri"];
options.Events = new OpenIdConnectEvents()
{
OnRedirectToIdentityProviderForSignOut = context =>
{
var logoutUri = options.SignedOutRedirectUri;
context.Response.Redirect(logoutUri);
context.HandleResponse();
return Task.CompletedTask;
}
};
在我的appsettings.json中,我有:
"SignedOutRedirectUri": "https://mydomain.auth.us-east-2.amazoncognito.com/logout?client_id=<<clientid>>&response_type=code&redirect_uri=https://localhost:44306/Home/LoggedOut"
在我的注销控制器中,我有:
await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
await HttpContext.SignOutAsync(OpenIdConnectDefaults.AuthenticationScheme);
return Redirect("/Home/LoggedOut");
因此,当我单击注销链接时,我会被重定向到/Home/LogedOut,并且我不再经过身份验证(在User.Identity.IsAuthenticated=false中(。
但是,当我转到任何带有[授权]的页面时,它会自动将我重新身份验证为我登录的同一用户——它从来没有给我以不同用户身份登录的机会。我希望它将我带到Cognito登录对话框,并要求我再次进行身份验证。因此,我想,在AWS Cognito方面,似乎有些事情没有得到澄清。
为什么这不让我回到登录对话框重新进行身份验证?我认为GET到AWS/logout端点应该是这样的。
我认为问题在于您为AWS Logout端点构建的URL的参数。(您尚未设置logout_uri(
https://docs.aws.amazon.com/cognito/latest/developerguide/logout-endpoint.html示例1显示了注销和重定向回客户端所需的参数。
以下是我的做法。
options.Events = new OpenIdConnectEvents()
{
OnRedirectToIdentityProviderForSignOut = context =>
{
context.ProtocolMessage.IssuerAddress =
GetAbsoluteUri(Configuration["Authentication:Cognito:EndSessionEndPoint"], Configuration["Authentication:Cognito:Authority"]);
context.ProtocolMessage.SetParameter("client_id", Configuration["Authentication:Cognito:ClientId"]);
context.ProtocolMessage.SetParameter("logout_uri", "https://localhost:5001");
return Task.CompletedTask;
}
};
logout_uri必须与AWS应用程序客户端设置上配置的注销url完全匹配。
辅助方法
private string GetAbsoluteUri(string signoutUri, string authority)
{
var signOutUri = new Uri(signoutUri, UriKind.RelativeOrAbsolute);
var authorityUri = new Uri(authority, UriKind.Absolute);
var uri = signOutUri.IsAbsoluteUri ? signOutUri : new Uri(authorityUri, signOutUri);
return uri.AbsoluteUri;
}
注销是用下面的两行完成的。正如你所做的,第一行是通过清除本地身份验证cookie来将你从本地注销,第二行通常会调用IDP上的end_session端点来注销IDP,但是由于cognito没有end_session终结点,当你通过OnRedirectToIdentityProviderForSignOut事件配置中间件时,你会覆盖它,指示它调用cognito所拥有的注销端点,而这正是使用该URL的地方。由于你没有正确地构建它,它永远不会退出cognito。
public async Task Logout()
{
await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
await HttpContext.SignOutAsync(OpenIdConnectDefaults.AuthenticationScheme);
}
以及配置值
...
"EndSessionEndPoint": "logout",
"ClientId": "<your client id>",
"Authority": "https://<your domain>.auth.<your region>.amazoncognito.com"
...
希望这会有所帮助。