如何在ASP.NET Core中从AWS Cognito注销



我正试图在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"
...

希望这会有所帮助。

最新更新