1

We have a Gateway (implemented using Ocelot), which performs both Authentication & Authorization of the calls before it reaches the APIs

For Authentication, the gateway uses JwtBearer like below

services.AddAuthentication(Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerDefaults.AuthenticationScheme)
        .AddJwtBearer(options =>
                        {
                            options.Events = JwtBeaerEvents();
                            options.TokenValidationParameters = TokenValidationParameters(tokenConfig);
                        });

And, this validates the token correctly.

Apart from this, the Gateway is implemented with Custom Authorization, to which it reads the permission related settings using a custom configuration file. And, this Custom Authorization is added as a middleware

We try to add this Authorization middleware after Authentication middleware, like

app.UseAuthentication().UseAuthorizationMiddleware();

This works for a valid token. However, for an invalid token, irrespective of Authentication got failed, the call is being routed to AuthorizationMiddleware as well. And, based on these findings, looks like we need to go with DI, rather than middleware. But, what we want is a custom implementation for Authorization which accepts the permissions/policy/scope via config file (in the gateway) along with JwtBearer scheme, rather than decorating them in the API attribute. Could anyone throw some light on how to achieve the same?

Your help is much appreciated

Athi S
  • 117
  • 1
  • 11

1 Answers1

0

The issue is due to the behaviour of .net core. When the Identity's IsAuthenticated flag is false, Http StatusCode is not set to 401 by the framework in case of Token validation failure during Authentication and also it proceeds to the next call. If only we used the Policy based Authorization, it would have been automatically taken care by RequireAuthenticatedUser() while building the Authorization Policy. However, since we are using a custom middleware, introduced one another middleware which replicates what DenyAnonymousAuthorizationRequirement does, like below

        var user = httpContext.User;
        var userIsAnonymous =
            user?.Identity == null ||
            !user.Identities.Any(i => i.IsAuthenticated);

        if (userIsAnonymous)
        {
            httpContext.Response.StatusCode = 401;
            return Task.CompletedTask;
        }

        return _next(httpContext);

We placed this middleware in between Authentication & Authorization middlewares and the issue has been resolved

Athi S
  • 117
  • 1
  • 11