I have an existing REST API running on ASP.NET Core 3.0. It uses MVC filter to perform an authorization check based on a header value and returns error in case of authorization failure so that the request is not passed to the controller.
Now, I am experimenting with gRPC and trying to port this API to a gRPC service. However, I do not see any obvious solutions that might act as an MVC filter replacement.
Is there some way to achieve similar authorization checking functionality, perhaps using metadata?
For MVC and gRpc, they are different. ActionFilter is not exist under gRpc.
If you want to apply checking request header for all actions, you could try implement your custom middleware before app.UseEndpoints
and check the request header.
For another way, you could try Policy
like below:
GrpcRequireemnt
and 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;
}
}
Register required services
services.AddAuthorization(options =>
{
options.AddPolicy("TokenAuthorize", policy =>
{
policy.AddRequirements(new GrpcRequirement());
});
});
services.AddHttpContextAccessor();
services.AddSingleton<IAuthorizationHandler, GrpcHandler>();
UseCase
[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)
});
}