Duende BFF 框架 - 缺少访问令牌

问题描述 投票:0回答:1

我正在尝试对用户进行身份验证以访问我的 React SPA。我正在尝试使用 IdentityServer6 和 Duende 的 BFF 框架来完成此任务。我在调试环境中本地工作。

我已按照他们的 documentation 进行操作,并且登录似乎可以正常工作,但当我尝试调用本地和远程端点(包括 /bff/user (用户信息)端点)时,我不断收到来自 BFF 主机的 401 错误消息。 BFF 主机日志显示找不到访问令牌。

这是来自BFF Host的日志信息:

[23:19:05 Warning] Duende.Bff.Yarp.AccessTokenRequestTransform
Access token is missing. token type: 'Unknown token type', local path: 'Unknown Route', detail: 'Missing access token'

[23:19:05 Information] Yarp.ReverseProxy.Forwarder.HttpForwarder
Not Proxying, a 401 response was set by the transforms.

来自身份服务器的日志,我相信它在登录时正确发出访问令牌:

[23:19:04 Information] Duende.IdentityServer.Hosting.IdentityServerMiddleware
Invoking IdentityServer endpoint: Duende.IdentityServer.Endpoints.AuthorizeEndpoint for /connect/authorize

[23:19:04 Information] Duende.IdentityServer.Events.DefaultEventService
{"ClientId": "interactive", "ClientName": null, "RedirectUri": "https://localhost:5002/", "Endpoint": "Authorize", "SubjectId": "1", "Scopes": "openid profile scope2 offline_access", "GrantType": "authorization_code", "Tokens": [{"TokenType": "code", "TokenValue": "****1D-1", "$type": "Token"}], "Category": "Token", "Name": "Token Issued Success", "EventType": "Success", "Id": 2000, "Message": null, "ActivityId": "0HMSBUIP9547T:00000011", "TimeStamp": "2023-07-24T03:19:04.9717252Z", "ProcessId": 49004, "LocalIpAddress": "::1:5001", "RemoteIpAddress": "::1", "$type": "TokenIssuedSuccessEvent"}

[23:19:04 Information] Serilog.AspNetCore.RequestLoggingMiddleware
HTTP GET /connect/authorize responded 302 in 18.3209 ms

[23:19:04 Information] Microsoft.AspNetCore.Hosting.Diagnostics
Request finished HTTP/2 GET https://localhost:5001/connect/authorize?client_id=interactive&redirect_uri=https%3A%2F%2Flocalhost%3A5002%2F&response_type=code&scope=openid%20profile%20scope2%20offline_access&code_challenge=7FjRcNdlHDeguDpLb2CmMSQrFZULfi46FaxRKds-KhY&code_challenge_method=S256&nonce=638257655449622490.ZWVjOGJmYjMtZjdlOC00NjQ1LTgxNTYtM2UxZjdiYjAwMTM0NjNmMjFjYWYtNTA4MC00Yjg4LTgyOWEtMTY5YWIxNDFhMjM4&state=CfDJ8GNxzlZXLyNLt0KDaVzK8HYWEXpzhCOxx2CvvAYf7lImUYvaqSqPOt92ipDF1BQM23yjJ58NcKo7W5m0eftvl3H042zOGJ6mmoBDLjFfjg1o01tH4Y6cE6YxonHxAmr-pkhtas4D0IP-_iRtYqLSPDgquJHpYVqTRAa9HJz6_crmBy0P_0cLHnaU8PmltBADJVH9lF7HWzvkjjbT6MeO8YM92R_mLwhr7uE5UfKqeYV2PxArkamdRKigVBO-gsASJlHSbWa2do2VGhM5itYvKAHJ__IHRAdfoU3CXLSY5ALkUa0Kq9IdP9RANriImkaIfCFaEJHJ3QfvVDAuP529pdIuINXLVi3OHQYZS1O3_bpG&x-client-SKU=ID_NET6_0&x-client-ver=6.21.0.0 - - - 302 0 - 22.6862ms

我的BFF主机身份验证配置:

public static WebApplication ConfigureServices(this WebApplicationBuilder builder)
        {
            // add BFF services and server-side session management
            builder.Services.AddBff()
                .AddRemoteApis()
                .AddServerSideSessions();

            builder.Services.AddAuthentication(options =>
                {
                    options.DefaultScheme = "cookie";
                    options.DefaultChallengeScheme = "oidc";
                    options.DefaultSignOutScheme = "oidc";
                })
                .AddCookie("cookie", options =>
                {
                    options.Cookie.Name = "__Host-bff";
                    options.Cookie.SameSite = SameSiteMode.Strict;
                })
                .AddOpenIdConnect("oidc", options =>
                {
                    options.Authority = "https://localhost:5001";
                    options.ClientId = "interactive";
                    options.ClientSecret = "49C1A7E1-0C79-4A89-A3D6-A37998FB86B0";
                    options.CallbackPath = "/";
                    options.SignedOutCallbackPath = "/";
                    options.ResponseType = "code";
                    options.ResponseMode = "query";

                    options.UsePkce = true;
                    options.GetClaimsFromUserInfoEndpoint = true;
                    options.SaveTokens = true;
                    options.MapInboundClaims = false;

                    options.Scope.Clear();
                    options.Scope.Add("openid");
                    options.Scope.Add("profile");
                    options.Scope.Add("scope2");
                    options.Scope.Add("offline_access");

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

            return builder.Build();
        }

        public static WebApplication ConfigurePipeline(this WebApplication app)
        {
            app.UseHttpsRedirection();
            app.UseDefaultFiles();
            app.UseStaticFiles();

            app.UseRouting();

            // add CSRF protection and status code handling for API endpoints
            app.UseAuthentication();
            app.UseBff();
            app.UseAuthorization();

            // local API endpoints
            app.MapControllers()
                .RequireAuthorization()
                .AsBffApiEndpoint();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapBffManagementEndpoints();
                endpoints.MapRemoteBffApiEndpoint("/api", "https://localhost:7011")
                    .RequireAccessToken(TokenType.User);
            });

            return app;
        }

我的身份服务器配置

public static WebApplication ConfigureServices(this WebApplicationBuilder builder)
        {
            builder.Services.AddRazorPages();

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

                    // see https://docs.duendesoftware.com/identityserver/v6/fundamentals/resources/
                    options.EmitStaticAudienceClaim = true;
                })
                .AddTestUsers(TestUsers.Users);

            // in-memory, code config
            isBuilder.AddInMemoryIdentityResources(Config.IdentityResources);
            isBuilder.AddInMemoryApiScopes(Config.ApiScopes);
            isBuilder.AddInMemoryClients(Config.Clients);


            // if you want to use server-side sessions: https://blog.duendesoftware.com/posts/20220406_session_management/
            // then enable it
            isBuilder.AddServerSideSessions();

            builder.Services.AddAuthentication();

            return builder.Build();
        }

        public static WebApplication ConfigurePipeline(this WebApplication app)
        {
            app.UseStaticFiles();
            app.UseRouting();
            app.UseIdentityServer();
            app.UseAuthorization();

            app.MapRazorPages()
                .RequireAuthorization();

            return app;
        }

以及我的 IdentityServer

的客户端配置
        public static IEnumerable<Client> Clients =>
            new Client[]
            {
                // interactive client using code flow + pkce
                new Client
                {
                    ClientId = "interactive",
                    ClientSecrets = { new Secret("49C1A7E1-0C79-4A89-A3D6-A37998FB86B0".Sha256()) },

                    AllowedGrantTypes = GrantTypes.Code,

                    RedirectUris = { "https://localhost:5002/" },
                    FrontChannelLogoutUri = "https://localhost:5002/signout-oidc",
                    PostLogoutRedirectUris = { "https://localhost:5002/signout-callback-oidc" },

                    AllowOfflineAccess = true,
                    AllowedScopes = { "openid", "profile", "scope2", "offline_access" }
                },
            };

如有任何帮助,我们将不胜感激!

identityserver4 openid-connect ms-yarp identityserver6
1个回答
0
投票

问题出在我的重定向 URI 上。 Identity Server 正在重定向到我的应用程序的根目录,而不是管理令牌所需的端点。

我通过在 BFF 主机配置中设置以下内容修复了此问题:

options.CallbackPath = "/signin-oidc";
options.SignedOutCallbackPath = "/signout-oidc";

并在我的 IdentityServer 客户端配置中执行相同的操作:

RedirectUris = { "https://localhost:5002/signin-oidc" }
FrontChannelLogoutUri = "https://localhost:5002/signout-oidc",
PostLogoutRedirectUris = { "https://localhost:5002/signout-callback-oidc" },
© www.soinside.com 2019 - 2024. All rights reserved.