我正在使用 ASP.NET Core 6 构建一个 Web 应用程序。
我有:
- Frontend.Client - 带有 UI 的 Blazor WebAssembly
- Frontend.Server - ASP.NET Core,托管 Blazor WebAssembly
- Web Api - 远程 REST 服务
- gRpc 服务- 远程 gRpc 服务
- Identity Provider - 一个使用 Duende.Bff.Yarp 的 Duende 项目
我的 Frontend.Client 配置为调用它自己的 BFF(Frontend.Server),而服务器使用Duende.Bff.YARP将调用转发到 REST 和 gRpc 服务。
对 REST 服务的调用按预期工作:客户端按照文档自动传递令牌。
我的问题是对 gRpc 的调用,它似乎没有使用正确的 HttpClient 和 AntiForgeryToken 和访问令牌。
我知道我在某处遗漏了一些设置,但我找不到任何关于如何将 Duende 与 gRpcWebClient 一起使用的示例。
我的Frontend.Client配置包含:
builder.Services.AddScoped<AuthenticationStateProvider, BffAuthenticationStateProvider>();
builder.Services.AddTransient<AntiforgeryHandler>();
builder.Services.AddHttpClient("backend", client => client.BaseAddress = new Uri(builder.HostEnvironment.BaseAddress))
.AddHttpMessageHandler<AntiforgeryHandler>();
builder.Services.AddTransient(sp => sp.GetRequiredService<IHttpClientFactory>().CreateClient("backend"));
builder.Services.AddSingleton(services => {
var backendUrl = new Uri(builder.HostEnvironment.BaseAddress);
var channel = GrpcChannel.ForAddress(backendUrl, new GrpcChannelOptions {
HttpHandler = new GrpcWebHandler(new HttpClientHandler()),
});
return new Commenter.CommenterClient(channel);
});
我的Frontend.Server配置包含:
builder.Services.AddBff();
var proxyBuilder = builder.Services.AddReverseProxy().AddTransforms<AccessTokenTransformProvider>();
// Initialize the reverse proxy from the "ReverseProxy" section of configuration
proxyBuilder.LoadFromConfig(builder.Configuration.GetSection("ReverseProxy"));
builder.Services.AddAuthentication(options => {
options.DefaultScheme = "cookie";
options.DefaultChallengeScheme = "oidc";
options.DefaultSignOutScheme = "oidc";
})
.AddCookie("cookie", options => {
options.Cookie.Name = "__Host-blazor";
options.Cookie.SameSite = SameSiteMode.Strict;
})
.AddOpenIdConnect("oidc", options => {
options.Authority = "https://localhost:5007";
options.ClientId = "photosharing.bff";
options.ClientSecret = "A9B27D26-E71C-4C53-89A8-3DAB53CE1854";
options.ResponseType = "code";
options.ResponseMode = "query";
options.Scope.Clear();
options.Scope.Add("openid");
options.Scope.Add("profile");
options.Scope.Add("photosrest");
options.Scope.Add("commentsgrpc");
options.Scope.Add("offline_access");
options.MapInboundClaims = false;
options.GetClaimsFromUserInfoEndpoint = true;
options.SaveTokens = true;
});
//code omitted for brevity
app.UseAuthentication();
app.UseBff();
app.UseAuthorization();
app.MapBffManagementEndpoints();
app.MapReverseProxy().AsBffApiEndpoint();
用于读取配置的 appsettings.json 文件包含:
"ReverseProxy": {
"Routes": {
"photosrestroute": {
"ClusterId": "photosrestcluster",
"Match": {
"Path": "/photos/{*any}"
},
"Metadata": {
"Duende.Bff.Yarp.TokenType": "User"
}
},
"commentsgrpcroute": {
"ClusterId": "commentsgrpccluster",
"Match": {
"Path": "/comments.Commenter/{*any}"
},
"Metadata": {
"Duende.Bff.Yarp.TokenType": "User"
}
}
},
"Clusters": {
"photosrestcluster": {
"Destinations": {
"photosrestdestination": {
"Address": "https://localhost:5003/"
}
}
},
"commentsgrpccluster": {
"Destinations": {
"commentsgrpdestination": {
"Address": "https://localhost:5005/"
}
}
}
}
}
当我的客户端调用 gRpc 时,我收到 401 Unauthorized 响应和 Duende.Bff 日志表明 AntiForgery 检查未通过,实际上该请求没有带有 X-CSRF 1 的标头(而对 REST Api 的调用确实)。这表明 gRpc 客户端没有使用 Duende 使用的 HTTP 客户端。
如何将我的 gRpc 客户端连接到 Duende?
注意:在引入身份验证/授权位之前,我直接使用 YARP 并且对 gRpc 的调用工作正常。当我添加 Duende 时,它就坏了。