Tobias Moe Thorstensen
Tobias Moe Thorstensen

Reputation: 8981

Modify content of response when using [Authorize]-attribute in dotnet core 3.0

We're using the [Microsoft.AspNetCore.Authorization.Authorize]-attribute to authorize requests to our api. If the JWT is not present or invalid in the HTTP-Header, a 401-error is returned. We want to modify to response body to contain more information, rather than an empty body. We've tried doing the following thing:

 app.Use(async (context, next) =>
 {
     var statusCode = context.Response.StatusCode;
     //write a custom body here       
 });

But the status code is always HTTP.200 which seems to me a bit strange since Postman tells me that it is a HTTP.401

In case of an exception being thrown in our api, we have implemented a filter which implements IActionFilter to return a more detailed error message. This is what we are looking for to do in case of an HTTP.401. Is there any filter I can add to achieve this?

Upvotes: 0

Views: 2585

Answers (3)

Tobias Moe Thorstensen
Tobias Moe Thorstensen

Reputation: 8981

For those of you that is curious on how I solved it:

I created a class that implements the IAsyncAuthorizationFilter

public class AuthorizationFilter : IAsyncAuthorizationFilter
{
   public async Task OnAuthorizationAsync(AuthorizationFilterContext context)
   {
       if(HasAuthorizationAttribute(context))
       {
          var isAuthorized = //Your authorization code
          if(!isAuthorized)
          {
              context.Result = new ObjectResult(..some object to return in response body..)
              {
                        StatusCode = StatusCodes.Status401Unauthorized
              };
          }
       }
   }

    private bool HasAuthorizationAttribute(AuthorizationFilterContext context)
    {
        var controllerActionDescriptor = context.ActionDescriptor as ControllerActionDescriptor;
        return controllerActionDescriptor.MethodInfo.HasAttribute<ClaimsAuthorizeAttribute>();
    }
}

This filter is registered in Startup.cs method ConfigureServices like this:

 public void ConfigureServices(IServiceCollection services)
 {
     services.AddMvc().AddMvcOptions(options => 
     {
         options.Filters.Add(typeof(AuthorizationFilter));
     }
 }

Upvotes: 1

Ryan
Ryan

Reputation: 20116

You could use app.UseStatusCodePages() instead:

app.UseStatusCodePages(async context =>
        {
            var httpContext = context.HttpContext;
            var statusCode = context.HttpContext.Response.StatusCode;
            //write a custom body here       
            //for example
            await context.HttpContext.Response.WriteAsync(
                "Status code page, status code: " +
                statusCode);
        });

Upvotes: 0

Jeremy Lakeman
Jeremy Lakeman

Reputation: 11110

So you need to add your own middleware before JWT, call the next handler, check the result and add your custom response.

    app.Use(async (context, next) =>
        {
            await next.Invoke();
            var statusCode = context.Response.StatusCode;
        });
    app.UseAuthentication();

Upvotes: 2

Related Questions