gRPC 服务的 ASP.NET Core MVC 过滤器模拟

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

我有一个在 ASP.NET Core 3.0 上运行的现有 REST API。它使用 MVC 过滤器根据标头值执行授权检查,并在授权失败时返回错误,以便请求不会传递到控制器。

现在,我正在尝试 gRPC 并尝试将此 API 移植到 gRPC 服务。但是,我没有看到任何明显的解决方案可以替代 MVC 过滤器。

是否有某种方法可以实现类似的授权检查功能,也许使用元数据

c# asp.net-core grpc asp.net-core-middleware
2个回答
3
投票

对于MVC和gRpc来说,它们是不同的。 gRpc 下不存在 ActionFilter。

如果您想对所有操作应用检查请求标头,您可以尝试在

app.UseEndpoints
之前实现自定义中间件并检查请求标头。

对于另一种方式,您可以尝试

Policy
,如下所示:

  1. GrpcRequireemnt
    GrpcHandler

    public class GrpcRequirement : IAuthorizationRequirement
    { 
    
    }
    public class GrpcHandler : AuthorizationHandler<GrpcRequirement>
    {
        private readonly IHttpContextAccessor _httpContextAccessor;
    
        public GrpcHandler(IHttpContextAccessor httpContextAccessor)
        {
            _httpContextAccessor = httpContextAccessor;
        }
        protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, GrpcRequirement requirement)
        {
    
            var headers = _httpContextAccessor.HttpContext.Request.Headers;
            StringValues token;
            if (!headers.TryGetValue("token", out token))
            {
                context.Fail();
                return Task.CompletedTask;
            }
            context.Succeed(requirement);
            return Task.CompletedTask;
    
        }
    }
    
  2. 注册所需服务

    services.AddAuthorization(options =>
    {
        options.AddPolicy("TokenAuthorize", policy =>
        {                   
            policy.AddRequirements(new GrpcRequirement());
        });
    });
    services.AddHttpContextAccessor();
    services.AddSingleton<IAuthorizationHandler, GrpcHandler>();
    
  3. 用例

    [Authorize("TokenAuthorize")]
    public override Task<BuyTicketsResponse> BuyTickets(BuyTicketsRequest request, ServerCallContext context)
    {
        var user = context.GetHttpContext().User;
    
        return Task.FromResult(new BuyTicketsResponse
        {
            Success = _ticketRepository.BuyTickets(user.Identity.Name!, request.Count)
        });
    }
    

3
投票

这将有稍微不同的答案,具体取决于您是否使用 Grpc.Core,它是最初在 Google 开发的 C GRPC 库的包装器,它已经可用了一段时间并支持各种 .Net 目标(包括 Framework),或者如果您使用的是新的 Grpc.AspNetCore,它随 .Net Core 3.0 一起启动,并且基于 Kestrel 和 ASP.NET Core 内部构建。

Grpc.Core

对于 Grpc.Core,您需要将标头值作为元数据传递,然后创建一个 服务器端拦截器 来处理元数据和请求。您还可以考虑使用 AsyncAuthInterceptor,但是客户端的核心 Grpc 实现不会通过不安全(非 TLS)连接发送凭据。

Grpc.AspNetCore

Grpc.AspNetCore 构建于 ASP.NET 之上,可以使用 ASP.NET 中间件,包括默认的 ASP.NET 身份验证。如果您可以将过滤器转换为中间件,您将能够在两个实现之间共享身份验证。

© www.soinside.com 2019 - 2024. All rights reserved.