Consider a controller endpoint like this:
[HttpGet]
public IActionResult Get()
{
var resource = _myService.GetSomeResource();
return Ok(resource);
}
The GetSomeResource()
method performs validation on the identity of the caller, like this:
public SomeResourceModel GetSomeResource()
{
_securityVerifier.VerifyCallerHasAccess();
// do stuff to get resource
return resource;
}
Within the VerifyCallerHasAccess()
method, let's pretend that the caller does NOT have access to the resource they requested. So, we throw an exception. Something like:
throw new SecurityException($"User does not have access to this resource");
With all that said, what I want is for the ASP.NET controller to automatically return a 403 when an exception of that type is encountered. By default, it's just returning a 500. Is it possible to register http response codes to specific types of exceptions? If so, how?
(Note, I know I can wrap my endpoint code in a try/catch, but I don't want to have to manually do this)
Edit for some clarity: My endpoint is already using .NET's authorization system. The security verification in question deals with getting the user's identity and checking against an external security service that they have the appropriate access rights to a given security resource.
CodePudding user response:
You could use some middleware in the request pipeline:
public class ErrorHandlingMiddleware
{
readonly RequestDelegate _next;
public ErrorHandlingMiddleware(RequestDelegate next)
{
_next = next;
}
public async Task Invoke(HttpContext context)
{
try
{
await _next(context);
}
catch (SecurityException ex)
{
context.Response.StatusCode = 403;
}
catch (Exception ex)
{
context.Response.StatusCode = 500;
await context.Response.WriteAsync(ex.Message);
}
}
}
and then register that in Program.cs:
app.UseMiddleware<ErrorHandlingMiddleware>();
CodePudding user response:
You can write an exception filter (see https://learn.microsoft.com/en-us/aspnet/core/mvc/controllers/filters?view=aspnetcore-7.0) or if you want to standardize your responses as well, take a look at Hellang.Middleware.ProblemDetails