簡體   English   中英

Identity Server 4 與 ASP.NET 4.6.2 Web API 導致重定向

[英]Identity Server 4 with ASP.NET 4.6.2 Web API causes redirect

我正在嘗試將 Identity Server 4 與用 .NET 框架 4.6.2 編寫的 Web API 一起使用。 我正在使用答案中提到的IdentityServer3.Contrib.AccessTokenValidation庫。 但是,對受保護端點的調用返回 402 重定向。

這是來自 API 的代碼:

private void ConfigureAuth(IAppBuilder app)
        {
            app.Map("/api",
                    apiApp =>
                    {
                        apiApp.UseCors(corsOptions);
                        apiApp.UseIdentityServerBearerTokenAuthentication(new IdentityServerBearerTokenAuthenticationOptions
                        {
                            Authority = apiAuthority,
                            ValidationMode = ValidationMode.ValidationEndpoint,
                            RequiredScopes = new[] { "api" }
                        });
                        SetupOpenIdAuthentication(apiApp);
                    });
        }

        private static void SetupOpenIdAuthentication(IAppBuilder app)
        {
            app.UseCookieAuthentication(new CookieAuthenticationOptions
            {
                AuthenticationType = "Cookies",
                ExpireTimeSpan = new TimeSpan(0, Configuration.SessionTimeoutInMinutes, 0),
                SlidingExpiration = true
            });
            app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions
            {
                Authority = apiAuthority,
                ClientId = "clientId",
                RedirectUri = apiRootUri + "Help",
                PostLogoutRedirectUri = apiRootUri,
                ResponseType = "id_token token",
                Scope = "openid profile roles api all_claims",
                SignInAsAuthenticationType = "Cookies",
                Notifications = new OpenIdConnectAuthenticationNotifications()
                {
                    RedirectToIdentityProvider = n =>
                    {
                        // if signing out, add the id_token_hint
                        if (n.ProtocolMessage.RequestType == Microsoft.IdentityModel.Protocols.OpenIdConnect.OpenIdConnectRequestType.Logout)
                        {
                            var idTokenHint = n.OwinContext.Authentication.User.FindFirst("id_token");
                            if (idTokenHint != null)
                            {
                                n.ProtocolMessage.IdTokenHint = idTokenHint.Value;
                            }
                        }

                        if (n.ProtocolMessage.RequestType == Microsoft.IdentityModel.Protocols.OpenIdConnect.OpenIdConnectRequestType.Authentication)
                        {
                            if (IsAjaxRequest(n.Request) && n.Response.StatusCode == (int)System.Net.HttpStatusCode.Unauthorized)
                            {
                                n.Response.StatusCode = (int)System.Net.HttpStatusCode.Unauthorized;
                                n.HandleResponse();
                                return Task.FromResult(0);
                            }
                        }

                        return Task.FromResult(0);
                    },
                    SecurityTokenValidated = n =>
                    {
                        // keep the id_token for logout
                        n.AuthenticationTicket.Identity.AddClaim(
                            new Claim("id_token", n.ProtocolMessage.IdToken));

                        //Add Role claims as MS claims so Authorize works on API methods when used without the bearer token
                        foreach (var claim in n.AuthenticationTicket.Identity.Claims.Where(x => x.Type == JwtClaimTypes.Role).ToList())
                        {
                            n.AuthenticationTicket.Identity.AddClaim(new Claim(ClaimTypes.Role, claim.Value));
                        }

                        return Task.FromResult(0);
                    },
                    AuthenticationFailed = n =>
                    {
                        // Pass in the context back to the app
                        n.OwinContext.Response.Redirect("/Help/Error");
                        //TODO:  Create authentication failure page
                        n.HandleResponse(); // Suppress the exception
                        return Task.FromResult(0);
                    }
                }
            });
        }

來自身份服務器的代碼:

var builder = services.AddIdentityServer(options =>
            {
                options.Events.RaiseErrorEvents = true;
                options.Events.RaiseInformationEvents = true;
                options.Events.RaiseFailureEvents = true;
                options.Events.RaiseSuccessEvents = true;

                // see https://identityserver4.readthedocs.io/en/latest/topics/resources.html
                options.EmitStaticAudienceClaim = true;
            })
            .AddSigningCredential(rsaCertificate)
            .AddInMemoryIdentityResources(IdentityConfig.IdentityResources)
            .AddInMemoryApiScopes(IdentityConfig.ApiScopes)
            .AddInMemoryClients(IdentityConfig.Clients)
            .AddAspNetIdentity<User>()
            .AddProfileService<CustomProfileService>()
            .AddWsFederationPlugin(options =>
            {
                options.Licensee = "License";
                options.LicenseKey = "Key"
            })
            .AddInMemoryRelyingParties(new List<RelyingParty>());

            services.AddAuthentication(sharedOptions =>
            {
                sharedOptions.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
                sharedOptions.DefaultChallengeScheme = WsFederationDefaults.AuthenticationScheme;
            })
            .AddWsFederation(options =>
            {
                options.Wtrealm = "azureAppId";
                options.MetadataAddress = "metadataAddress";
            });
            builder.Services.ConfigureApplicationCookie(options =>
                {
                    options.Cookie.IsEssential = true;
                    options.Cookie.SameSite = SameSiteMode.None; //SameSiteMode.Unspecified in .NET Core 3.1
                });

以下是Identity Server中為API注冊的客戶端:

new Client
            {
                ClientId = "clientId",
                AllowedGrantTypes = GrantTypes.ImplicitAndClientCredentials,
                ClientSecrets = { new Secret("secret".Sha256()) },
                RedirectUris = { "https://localhost:44302/", $"{apiUrl}/Help" },
                PostLogoutRedirectUris = { $"{apiUrl}" },
                AllowedScopes = new List<string>
                {
                    IdentityServerConstants.StandardScopes.OpenId,
                    IdentityServerConstants.StandardScopes.Profile,
                    "api",
                    "roles",
                    "all_claims"
                },
                RequirePkce = false,
                AllowOfflineAccess = true,
                AllowAccessTokensViaBrowser = true
            }

如果我需要添加更多代碼,請告訴我。 當用於調用受 Identity Server 4 保護的 .NET 核心 API 時,相同的訪問令牌不會導致重定向。 但是,當與 .NET 4.6.2 中的 API 一起使用時,它會導致重定向。

在 API 中,將ValidationMode = ValidationMode.ValidationEndpoint更改為ValidationMode = ValidationMode.Both 這將使 Identity Server 能夠使用 JWT 的本地驗證和引用令牌的驗證端點。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM