In my .NET Core Web API, I have a method that gets called after they AD/Okta login to the app. Then certain data based tests fail about a user (stuff not stored in ad or okta, like this user is not a student), I'm throwing an AuthorizationException
, to indicate this person is not allowed to log in.
The client gets a 500 error, is there a good way to make it return a 401 unauthorized instead?
I'm using a global exception filter, for another use, this seems like a good place to do it.
public void OnActionExecuted(ActionExecutedContext context)
{
if (context.Exception is ApiErrorException ex)
{
var bdo = new BaseReturnDataObject(ex.Message, ex.Type);
context.Result = new JsonResult( bdo ) { };
context.ExceptionHandled = true;
}
// do it about here
}
Except that I only have access to the response, not the request on the context object.
My issue is the client is going to treat a 500 from calling the specific API method as a "you are not authorized" and there is no way to differentiate it from a "your service is broken" , as it's the first method called on each login.
I kind of half way remember reading a post on SO about someone doing this because it offended them that the return type was 500 and not 401, and it being a bad idea, but I can't find it when I search for it. Is there a good reason not to change the error type?
If I don't change the return type is there a good way to embed the exception.message into the 500 result sent to the client so I can differentiate between the reasons for the 500?
I guess what I'm asking for is what is the best practice to tell the 2 types of error apart at the client end? Returning a 401 seems on the face like the right answer.
Edit: I guess what I'm asking here is what is the best practice and why is it the best practice in this situation?