Платформа Duende BFF – отсутствует токен доступа
Я пытаюсь аутентифицировать пользователей для доступа к моему React SPA. Для этого я пытаюсь использовать IdentityServer6 и платформу BFF Duende. Я работаю локально в среде отладки.
Я проследил за их документацией до T, и вход в систему, похоже, работает, но я продолжаю получать сообщения об ошибках 401 от хоста BFF, когда пытаюсь вызвать как локальные, так и удаленные конечные точки, включая конечную точку /bff/user (информация о пользователе). В журналах хоста BFF указано, что токен доступа не найден.
Вот информация журнала с хоста BFF:
[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.
Журналы с Identity Server , который, как я полагаю, правильно выдает токен доступа при входе в систему:
[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" }
},
};
Любая помощь приветствуется!
1 ответ
Проблема была в моем 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" },