简体   繁体   中英

Logout from ASP.NET MVC client app and a .NET 5 openiddict server. Post logout redirect url invalid

I'm using OWIN 4.2 with .NET Framework 4.7.2 for my ASP.NET MVC client app. Login works completely fine but logout will fail.

On my client's startup.cs

app.UseOpenIdConnectAuthentication(
            new OpenIdConnectAuthenticationOptions
            {
                ClientId = "MVC",
                ClientSecret = "MVC-Secret",

                Authority = "https://localhost:44305/",
                RedirectUri = "https://localhost:44347/",
                CallbackPath = new PathString("/"),
                
                Scope = "openid api",

                SignInAsAuthenticationType = "cookie",
                RequireHttpsMetadata = false,
                UseTokenLifetime = false,

                RedeemCode = true,
                SaveTokens = true,

                ResponseType = OpenIdConnectResponseType.Code,
                ResponseMode = OpenIdConnectResponseMode.Query,

                // OpenIdConnectAuthenticationNotifications configures OWIN to send notification of failed authentications to the OnAuthenticationFailed method
                Notifications = new OpenIdConnectAuthenticationNotifications
                {
                    AuthenticationFailed = OnAuthenticationFailed,

                    RedirectToIdentityProvider = n =>
                    {
                        if (n.ProtocolMessage.RequestType == OpenIdConnectRequestType.Authentication)
                        {
                            // generate code verifier and code challenge
                            var codeVerifier = CryptoRandom.CreateUniqueId(32);
                            
                            string codeChallenge;
                            using (var sha256 = SHA256.Create())
                            {
                                var challengeBytes = sha256.ComputeHash(Encoding.UTF8.GetBytes(codeVerifier));
                                codeChallenge = Base64Url.Encode(challengeBytes);
                            }

                            // set code_challenge parameter on authorization request
                            n.ProtocolMessage.SetParameter("code_challenge", codeChallenge);
                            n.ProtocolMessage.SetParameter("code_challenge_method", "S256");

                            // remember code verifier in cookie (adapted from OWIN nonce cookie)
                            // see: https://github.com/scottbrady91/Blog-Example-Classes/blob/master/AspNetFrameworkPkce/ScottBrady91.BlogExampleCode.AspNetPkce/Startup.cs#L85
                            RememberCodeVerifier(n, codeVerifier);
                        }

                        if (n.ProtocolMessage.RequestType == OpenIdConnectRequestType.Logout)
                        {
                            var idTokenHint = n.OwinContext.Authentication.User.FindFirst("id_token").Value;

                            if (idTokenHint != null)
                            {
                                n.ProtocolMessage.IdTokenHint = idTokenHint;
                            }
                        }

                        return Task.CompletedTask;
                    },

                    AuthorizationCodeReceived = n =>
                    {
                        // get code verifier from cookie
                        // see: https://github.com/scottbrady91/Blog-Example-Classes/blob/master/AspNetFrameworkPkce/ScottBrady91.BlogExampleCode.AspNetPkce/Startup.cs#L102
                        var codeVerifier = RetrieveCodeVerifier(n);

                        // attach code_verifier on token request
                        n.TokenEndpointRequest.SetParameter("code_verifier", codeVerifier);

                        return Task.CompletedTask;
                    },

                    SecurityTokenValidated = n =>
                    {
                        var id = n.AuthenticationTicket.Identity;

                        id.AddClaim(new Claim("id_token", n.ProtocolMessage.IdToken));
                        n.AuthenticationTicket = new AuthenticationTicket(
                               id,
                               n.AuthenticationTicket.Properties);
                        return Task.FromResult(0);
                    },

                }
            }
        );

I also tried

...
                Authority = "https://localhost:44305/",
                RedirectUri = "https://localhost:44347/",
                PostLogoutRedirectUri = "https://localhost:44347/signout-callback-oidc",
...

And also

...
                Authority = "https://localhost:44305/",
                RedirectUri = "https://localhost:44347/",
                PostLogoutRedirectUri = "https://localhost:44347/",
...

However, all these results in the response

error:invalid_request error_description:The specified 'post_logout_redirect_uri' is invalid. error_uri: https://documentation.openiddict.com/errors/ID2052

On my server, the configuration is as follows

await manager.CreateAsync(new OpenIddictApplicationDescriptor
            {
                ClientId = clientId,
                ClientSecret = clientSecret,
                DisplayName = displayName,
                RedirectUris =
                {
                    new Uri("https://localhost:44347/")
                },
                Permissions =
                {
                    ...
                },
                PostLogoutRedirectUris =
                {
                    new Uri("https://localhost:44347/")
                }

            }, cancellationToken);
        }

I have also tried changing Server config to

PostLogoutRedirectUris =
                {
                    new Uri("https://localhost:44347/signout-callback-oidc")
                }

I encountered the same issue, what solved it for me was to add the logout permission in the application - OpenIddictConstants.Permissions.Endpoints.Logout

await _applicationManager.CreateAsync(new OpenIddictApplicationDescriptor
{
    ClientId = "mvc",
    ClientSecret = "901564A5-E7FE-42CB-B10D-61EF6A8F3654",
    DisplayName = "MVC client application",
    PostLogoutRedirectUris = { new Uri("http://localhost:53507/signout-callback-oidc") },
    RedirectUris = { new Uri("http://localhost:53507/signin-oidc") },
    Permissions =
    {
        OpenIddictConstants.Permissions.Endpoints.Authorization,
        OpenIddictConstants.Permissions.Endpoints.Logout,
        OpenIddictConstants.Permissions.Endpoints.Token,
        OpenIddictConstants.Permissions.GrantTypes.AuthorizationCode
    }
});

正如此处的应用程序所回答的https://stackoverflow.com/a/69671657/6477254 ,我可以确认您必须允许注销端点的权限,使用OpenIddictConstants.Permissions.Endpoints.Logout的常量值,其中包含"ept:logout"创建 OpenIddict 数据时的字符串值。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM