We have two custom directives responsible for authentication and authorization of users, when something is wrong the directives are rejecting the request with two custom rejections (UnauthorizedRejection and ForbiddenRejection). We do have a custom rejection handler which maps those two rejections to a StatusCode.Unauthorized and a StatusCodes.Forbidden accordingly.
In our tests, everything works perfectly, when we wrap a route with our directives and send an unauthenticated or unauthorized request we can properly assert that the status code is either Unauthorized or Forbidden.
When we wrap the routes in our main API with one of our directives, we end up having a StatusCodes.MethodNotAllowed in place of the expected Unauthorized or Forbidden status codes.
I think it’s related to how akka-http handles route evaluation using the ~ operator.
After having been rejected by a route the request will continue to flow through the routing structure and possibly find another route that can complete it. If there are more rejections all of them will be picked up and collected. Rejections • Akka HTTP
My question is, is there a way to stop the request to flow through the routing structure after some specific rejection are encountered? Or to customize the default rejection handler to send the proper status codes when the rejection list contains either a ForbiddenRejection or an UnauthorizedRejection ?
Yes, the reason is that at concat / ~ when a rejection is returned from a branch, the next branch is tried. After trying all the branches you might have ended up with a list of rejections, one for each branch, and then some response needs to be created which may choose a seemingly arbitrary rejection from one of the branches.
As a mitigation, you can seal the route at any point in the routing structure to convert rejections into final responses. You can either use the handleRejections directive for that and pass your custom rejection handler, or use Route.seal which uses implicit RejectionHandler / ExceptionHandler for the same purpose.
i am having the same problem i have two routes i am channing them route1 ~ route2
the problem is when i am hitting the route2 ,then route1 hanldeNotFoubd rejection got called how can i stop this please help