首页 > 解决方案 > 指定的“redirect_uri”对此客户端应用程序无效

问题描述

我正在使用 OIDC 客户端,我在下面的行中调用 siginin,

await this.userManager.signinRedirect(this.createArguments(state));
            return this.redirect();

在此之后,我在网络选项卡中看到它被导航到:

https://localhost:5001/connect/authorize?client_id=WebPriorTrainingAuth&redirect_uri=https%3A%2F%2Flocalhost%3A5001%2Fauthentication%2Flogin-callback&response_type=code&scope=openid%20profile&state=9a061d073a424b76bfee25c9bad535d4&code_challenge=ElP_Qtwl8skk13ZyhkzWbnQqU04Y_xYAQXN09cyLY_E&code_challenge_method=S256&response_mode=query

带有错误消息:

error:invalid_request
error_description:The specified 'redirect_uri' is not valid for this client application.
error_uri:https://documentation.openiddict.com/errors/ID2043

我猜这应该重定向到 /Account/Login 页面(https://localhost:5001/Account/Login?ReturnUrl=%2Fconnect%2),但这并没有发生。有人可以帮忙吗?

在授权控制器中,客户端参数将设置以下值。

var result = new Dictionary<string, string>();

            var application = await applicationManager.FindByClientIdAsync(clientId, cancellationToken);
            if (application != null)
            {
                result.Add("authority", httpContext.GetBaseUrl());
                result.Add("client_id", application.ClientId);
                result.Add("redirect_uri", "https://localhost:5001/authentication/login-callback");
                result.Add("post_logout_redirect_uri", "https://localhost:5001/authentication/logout-callback");
                result.Add("response_type", "code");
                result.Add("scope", $"openid profile");
                //result.Add("response_mode", "query");
            }

            return result;

在 startup.cs 中,OpenIddict 设置的以下代码,

services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
                .AddCookie(CookieAuthenticationDefaults.AuthenticationScheme, options => 
                {
                    options.LoginPath = "/Identity/Account/Login";
                    options.LogoutPath = "/Identity/Account/Logout";
                })
                .AddOpenIdConnect(options =>
                {
                    options.SignInScheme = "Cookies";
                    options.ForwardSignIn = "Cookies";

                    options.Authority = baseUrl;
                    options.SignedOutRedirectUri = baseUrl;

                    options.ClientId = AuthenticationClient.WebClientId;

                    options.RequireHttpsMetadata = true;
                    options.GetClaimsFromUserInfoEndpoint = true;
                    options.SaveTokens = true;
                    options.UsePkce = true;

                    /// Use the authorization code flow.
                    options.ResponseType = OpenIdConnectResponseType.CodeIdToken;
                    options.AuthenticationMethod = OpenIdConnectRedirectBehavior.RedirectGet;

                    options.Scope.Add(Scopes.OpenId);
                    options.Scope.Add(Scopes.Profile);
                    options.Scope.Add(AuthenticationClient.WebClientApiScope);

                    options.SecurityTokenValidator = new JwtSecurityTokenHandler
                    {
                        /// Disable the built-in JWT claims mapping feature.
                        InboundClaimTypeMap = new Dictionary<string, string>()
                    };

                    options.TokenValidationParameters.NameClaimType = "name";
                    options.TokenValidationParameters.RoleClaimType = "role";


                    options.Events = new OpenIdConnectEvents
                    {

                        /// Add Code Challange
                        OnRedirectToIdentityProvider = context =>
                        {
                            /// Set ProjectId
                            context.ProtocolMessage.SetParameter("project_id", context.HttpContext.User.Identity.Name);
                            
                            /// Only modify requests to the authorization endpoint
                            if (context.ProtocolMessage.RequestType == OpenIdConnectRequestType.Authentication)
                            {
                                /// Generate code_verifier
                                var codeVerifier = CryptoRandom.CreateUniqueId(32);

                                /// Store codeVerifier for later use
                                context.Properties.Items.Add("code_verifier", codeVerifier);

                                /// Create code_challenge
                                string codeChallenge;
                                using (var sha256 = SHA256.Create())
                                {
                                    var challengeBytes = sha256.ComputeHash(Encoding.UTF8.GetBytes(codeVerifier));
                                    codeChallenge = Base64Url.Encode(challengeBytes);
                                }

                                /// Add code_challenge and code_challenge_method to request
                                context.ProtocolMessage.Parameters.Add("code_challenge", codeChallenge);
                                context.ProtocolMessage.Parameters.Add("code_challenge_method", "S256");
                            }

                            return Task.CompletedTask;
                        },

有人可以告诉我为什么 signinredirect 调用没有重定向到 /Account/Login 页面吗?

标签: reactjsidentityserver4openiddictoidc-client-js

解决方案


redirect_uri当OpenIddict 无法识别指定时返回此错误。

您确定已将其添加到客户的https://localhost:5001/authentication/login-callback允许列表中吗?redirect_uriWebPriorTrainingAuth


推荐阅读