首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用gRpc WebAssembly客户端时,Duende纱线不传递令牌

使用gRpc WebAssembly客户端时,Duende纱线不传递令牌
EN

Stack Overflow用户
提问于 2022-02-03 15:24:14
回答 1查看 517关注 0票数 2

我正在用ASP.NET核心6构建一个web应用程序。

我有:

  1. Frontend.Client -一个带有UI
  2. Frontend.Server - ASP.NET核心的Blazor,托管了Blazor WebAssembly
  3. Web Api -一个远程REST Service
  4. gRpc服务-一个远程gRpc Service
  5. Identity提供者-一个使用Duende.Bff.Yarp

的Duende项目

我的Frontend.Client被配置为调用自己的BFF ( Frontend.Server),而服务器则使用Frontend.Client将调用转发给REST和gRpc服务。

对REST服务的调用如出一辙:客户端按照文档自动传递令牌。

我的问题在于对gRpc的调用,它似乎没有按照应有的方式与AntiForgeryToken和访问令牌一起使用正确的HttpClient。

我知道我错过了一些设置,但我找不到关于如何在gRpcWebClient中使用Duende的任何例子。

我的Frontend.Client配置包含:

代码语言:javascript
复制
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配置包含:

代码语言:javascript
复制
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文件包含:

代码语言:javascript
复制
"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个未经授权的响应和Duende.Bff日志,而AntiForgery检查没有通过,实际上请求没有X 1的头(而对REST Api的调用是这样)。这意味着gRpc客户机没有使用Duende使用的HTTP。

如何将我的gRpc客户端连接到Duende?

注意:在介绍身份验证/授权位之前,我直接使用了YARP,对gRpc的调用工作得很好。是我加杜恩德的时候它就坏了。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-02-04 07:27:12

问题是AntiforgeryHandler,因为我没有将它添加到HttpHandlers of my gRpcChannel的链中。我解决这个问题的方法是

  1. 添加构造函数以接受内部处理程序,并将其传递给其基类
  2. ,将my AntiforgeryHandler附加到HttpHandlers图灵链grpc客户端

的构造中。

AntiforgeryHandler变成:

代码语言:javascript
复制
namespace PhotoSharingApplication.Frontend.Client.DuendeAuth;

public class AntiforgeryHandler : DelegatingHandler {
    public AntiforgeryHandler() { }
    public AntiforgeryHandler(HttpClientHandler innerHandler) : base(innerHandler) { }
protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) {
    request.Headers.Add("X-CSRF", "1");
    return base.SendAsync(request, cancellationToken);
  }
}

在我的Frontend.Client项目中,grpc客户端的构造如下:

代码语言:javascript
复制
builder.Services.AddSingleton(services => {
    var backendUrl = new Uri(builder.HostEnvironment.BaseAddress);
    var channel = GrpcChannel.ForAddress(backendUrl, new GrpcChannelOptions {
        HttpHandler = new GrpcWebHandler(new AntiforgeryHandler(new HttpClientHandler())),
    });
    return new Commenter.CommenterClient(channel);
});
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70973903

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档