Why does "authorize" directive cancel AuthorizationFailedRejection?

99 views
Skip to first unread message

Drew Kutcharian

unread,
Oct 8, 2014, 2:48:50 AM10/8/14
to spray...@googlegroups.com
Hi Guys,

I was just looking at the Spray’s source code and I came across:

https://github.com/spray/spray/blob/master/spray-routing/src/main/scala/spray/routing/directives/SecurityDirectives.scala#L48

I wanted to see what’s the reason that authorize directive cancels AuthorizationFailedRejection?

Best,

Drew

Mathias Doenitz

unread,
Oct 8, 2014, 4:25:37 AM10/8/14
to spray...@googlegroups.com
Drew,

suppose you have a construct like this:


get {
authorize(checkA) {

} ~
authorize(checkB) {

}
}

If `checkA` fails an `AuthorizationFailedRejection` will be gathered up.
If `checkB` then succeeds it needs to cancel the `AuthorizationFailedRejection` that was produced earlier, since now the request has indeed been authorised successfully.

Cheers,
Mathias

---
mat...@spray.io
http://spray.io
> --
> You received this message because you are subscribed to the Google Groups "spray.io User List" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to spray-user+...@googlegroups.com.
> Visit this group at http://groups.google.com/group/spray-user.
> To view this discussion on the web visit https://groups.google.com/d/msgid/spray-user/67FD21EA-2097-44D1-BEA0-F2BFA8AAEAAF%40venarc.com.
> For more options, visit https://groups.google.com/d/optout.

Drew Kutcharian

unread,
Oct 8, 2014, 9:02:39 PM10/8/14
to spray...@googlegroups.com
I see, thanks.

On Oct 8, 2014, at 1:25 AM, Mathias Doenitz <mat...@spray.io> wrote:

> Drew,
>
> suppose you have a construct like this:
>
>
> get {
> authorize(checkA) {
> ...
> } ~
> authorize(checkB) {
> ...
> To view this discussion on the web visit https://groups.google.com/d/msgid/spray-user/A7F397BF-A814-4B11-A198-69D910EAD1AF%40spray.io.

Emrys Ingersoll

unread,
Jun 23, 2015, 12:48:19 PM6/23/15
to spray...@googlegroups.com
Mathias,

What about the following scenario?

get {
  authorize(true) {
    authorize(false) {
      ...
    }
  }
}

In this case, I'd expect the request to be rejected with an `AuthorizationFailedRejection` but the successful outer `authorize` cancels the rejection from the inner `authorize`.

To make this a bit less hypothetical, I ran into this issue by having some independent routes, each using their own fine-grained `authorize` checks, that were later composed together and wrapped with an outer route guarded by a single coarse-grained `authorize` check. Using the default rejection handler, I was surprised to see `404 Not Found` responses when a request was rejected due to an `authorize` failure in one of the wrapped routes.

I went as far as attempting a PR to fix the issue, but I wasn't sure how to satisfy both the constraint that successful `authorize` checks cancel rejections from any sibling `authorize` failures (your example) while also permitting rejections from descendant `authorize` directives to persist (my example).

There is also the possibility I'm just doing it wrong. Nesting `authorize` directives seems to me like reasonable usage, but is there a better way to go about this that I've overlooked?

Cheers,

Emrys

Akos Vandra

unread,
May 29, 2016, 4:50:14 PM5/29/16
to spray.io User List
Hello,

I just stumbled into this.
This email thread explains why the cancel rejection transformation is there, however I wonder if there is an actual solution to the nested authorize routes, as portrayed by Drew (I have the exact same use-case).


Thanks,
  Akos Vandra
Reply all
Reply to author
Forward
0 new messages