play-pac4j - use of SecureAction with Play's ActionBuilder

199 views
Skip to first unread message

Pete Nattress

unread,
Sep 2, 2016, 11:52:11 AM9/2/16
to pac4j-users
Hi,

First off just to say thank you to everyone involved in creating and maintaining this library - I've found it very well documented and easy to use.

I am adding authentication logic to my Play Java 2.5.4 application using pac4j 1.9.0 and play-pac4j 2.4.0. I have an Authorizer which "needs" to read the request body on every request, to retrieve an ID value which is used in the isAuthorized() check. I initially tried protecting my controllers with the pac4j SecurityFilter - however, the request body is not available at this point because Play has not parsed it yet, so the Authorizer couldn't do its check.

The other option is to use a SecureAction to protect all my actions. With this approach, I have access to the parsed request body when the action is executed. Unfortunately I have quite a lot of actions which need protecting and it would be very tiresome to add the @Secure annotation to every single one (not to mention dangerous, in case one is accidentally missed off). I basically want to apply the security to all my actions and only exclude a handful of whitelisted URLs.

The Play Java API has a way to do this using an ActionCreator. However, the pac4j SecurityAction is clearly not designed to be called in this way - it assumes there is an annotation available to read. To get this working I have had to hackily subclass the SecurityAction and invoke the "internalCall" method manually, to skip over the annotation checks in SecurityAction.call():

public static class MySecureAction extends SecureAction {

   
@Inject
   
public MySecureAction(Config config) {
     
super(config);
   
}

   
@Override
   
public CompletionStage<Result> call(Http.Context ctx) {
     
try {
       
return super.internalCall(ctx, "client", "authorizer", false);
     
} catch (Throwable th) {
       
throw new RuntimeException(th);
     
}
   
}
 
}



My question is basically: is this OK, or is there a better way? I am fairly new to both Play and pac4j so I may be missing something obvious. I am nervous about invoking a method with the word "internal" in it, and although it is public there's nothing to indicate that it's acceptable to use.

Any advice would be most welcome.


Jérôme LELEU

unread,
Sep 4, 2016, 5:11:05 AM9/4/16
to Pete Nattress, pac4j-users
Hi,

Very interesting feedback!

The @Secure annotation (Java) and Secure function (Scala) are really specific to Play (I started creating them following Play security example with basic auth), but generally pac4j implementations have an interception mechanism (J2E filter, Spring MVC interceptor...) to ensure security.

So later on, came the SecurityFilter for Play which is less cumbersome than the Secure annotation / function (I admit).

Yes, the internalCall method can be called from other play-pac4j components (currently: the SecureAction itself, the Security trait and the SecurityFilter).

So it makes sense to have an ActionCreator calling the internalCall. Though, the ActionCreator applies globally. Therefore, I think you'll have the same issue as the SecurityFilter, you'll need to define some patterns to apply clients and authorizers, won't you? Certainly, we should provide the same patterns definitions.

But there is also the HttpRequestHandler. Finally, it seems we have three potential mechanisms: Filter, ActionCreator and HttpRequestHandler.

Which one(s) should we really implement? I opened this Github issue: https://github.com/pac4j/play-pac4j/issues/134 to discuss this deeply. Please join.

Thanks.
Best regards,
Jérôme



--
You received this message because you are subscribed to the Google Groups "pac4j-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to pac4j-users+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply all
Reply to author
Forward
0 new messages