Grpc-dotnet: Authorization does not reject invalid access tokens

Created on 7 Mar 2019  路  6Comments  路  Source: grpc/grpc-dotnet

I have tried to implement and client/server gRPC with Bearer token authorization. When I send an invalid token, the token itself is rejected, but the business part of the gRPC executes anyway. Once the token is rejected, the pipeline should return with a 401/403 status code with no further execution.

Here is an example with the problem.

https://github.com/damienbod/Secure_gRpc

If you replace these 2 lines, and send a invalid access token, you can reproduce the problem on the server.

https://github.com/damienbod/Secure_gRpc/blob/master/Secure_gRpc/Secure_gRpc.Client/Program.cs#L24-L25

Greetings Damien

All 6 comments

Thanks for trying it out. I'll look into.

I ran your sample and I get into GreeterService.SayHello.

Is it possible that Authorization/Authentication has not been configured correctly to reject the token? I'm not an expert in that area so I can't say with certainty.

We have some function tests that use authorization and it returns a 401 error: https://github.com/grpc/grpc-dotnet/blob/24ecde24012ba2c475368e297463c4b8fea82932/test/FunctionalTests/AuthorizationTests.cs

Related Startup.cs configuration code:

services.AddAuthorization(options =>
{
    options.AddPolicy(JwtBearerDefaults.AuthenticationScheme, policy =>
    {
        policy.AddAuthenticationSchemes(JwtBearerDefaults.AuthenticationScheme);
        policy.RequireClaim(ClaimTypes.NameIdentifier);
    });
});
services.AddAuthorizationPolicyEvaluator();
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
    .AddJwtBearer(options =>
    {
        options.TokenValidationParameters =
            new TokenValidationParameters
            {
                ValidateAudience = false,
                ValidateIssuer = false,
                ValidateActor = false,
                ValidateLifetime = true,
                IssuerSigningKey = SecurityKey
            };

        options.Events = new JwtBearerEvents
        {
            OnMessageReceived = context =>
            {
                var token = context.Request.Headers["access_token"];
                if (!string.IsNullOrEmpty(token))
                {
                    context.Token = token;
                }
                return Task.CompletedTask;
            }
        };
    });

I tried the test example and it works, so I switched the server code to use AddJwtBearer and it still did not work with my client.

I do not set the context.Token in the JwtBearerEvents, because I believe the Authorization header should be used. The token gets validated and is logged in the console as invalid, but the pipeline continues to execute.

I figured it out. The code that shipped in preview 3 does not support attributes on the service or methods. This isn't doing anything: [Authorize(Policy = "protectedScope")]

Change your Startup.cs code to this and you're good to go:

app.UseRouting(routes =>
{
    routes.MapGrpcService<GreeterService>().RequireAuthorization("protectedScope");
});

This is already fixed and will be in the next preview.

excellent, this works
routes.MapGrpcService().RequireAuthorization("protectedScope");

Thanks

@davidfowl Yes the authorization middleware is configured.https://github.com/damienbod/Secure_gRpc/blob/master/Secure_gRpc/Secure_gRpc.Server/Startup.cs#L64-L65

So once the Attributes are supported, this will work.

Was this page helpful?
0 / 5 - 0 ratings