How to catch form authorization error in web API in ASP.NET MVC4

ASP.NET/Mono MVC4 Web API v.1 Application.

API controllers use Forms authorization and are decorated with the standard [Authorize] attribute. If authorization fails, standard api error message

<Error> <Message>Authorization has been denied for this request.</Message> </Error> 

going on. Like, for example, this error for writing to a log file. The error message returned to the shoudl caller remains unchanged. how to add to this additional code that can write this error message with a whole http request headers and body in a log file?

I added the code from the question

How to register ALL exceptions worldwide for a C # MVC4 WebAPI application?

and from

How to catch calls to undefined api method in ASP.NET MVC4 web interface

but the mistake of aphorization is not caught.

How to catch all the bugs?

Update

you need to run the code on a Windows 2003 server. I tried the code from the answer, but received compilation errors.

 Predefined type 'System.Runtime.CompilerServices.IAsyncStateMachine' is not defined or imported Cannot find all types required by the 'async' modifier. Are you targeting the wrong framework version, or missing a reference to an assembly? Cannot find all types required by the 'async' modifier. Are you targeting the wrong framework version, or missing a reference to an assembly? 

How to run int on a W2003 server?

0
source share
1 answer

One way to achieve this is to write a DelegatingHandler to intercept the response before it is sent back to the client, and then register information about those requests that return errors.

 public class RepsonseInterceptor : DelegatingHandler { protected async override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) { var response = await base.SendAsync(request, cancellationToken); LogResponse(request, response); return response; } public void LogResponse(HttpRequestMessage request, HttpResponseMessage response) { HttpStatusCode status = response.StatusCode; //Catch the status codes you want to Log if (status == HttpStatusCode.NotFound || status == HttpStatusCode.Unauthorized || status == HttpStatusCode.InternalServerError) { //Do Logging Stuff here //with the Request and Response } } } 

Then add this to Application_Start in the Global.asax.cs file:

 GlobalConfiguration.Configuration.MessageHandlers.Add(new ResponseInterceptor()); 

EDIT:

If you do not want to execute a handler for all routes, you can add it as a message handler on the path to the routes that you want, and not globally:

 config.Routes.MapHttpRoute( name: "DefaultApi", routeTemplate: "api/{controller}/{id}", defaults: new { id = RouteParameter.Optional }, constraints: null, handler: new ResponseInterceptor() ); 

If you are using the .NET Framework 4.0, you need to change the SendAsync method for the handler as follows:

 protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) { return base.SendAsync(request, cancellationToken) .ContinueWith(task => { var response = task.Result; LogResponse(request, response); return response; }); } 

I think it would be wise to just use this MessageHandler if you can get all the information you need to enter from the Request and Response objects, although I have not fully tested it.

+7
source

Source: https://habr.com/ru/post/958843/


All Articles