Using pac4j to secure a REST server

1,991 views
Skip to first unread message

Thiago Lima

unread,
Oct 25, 2014, 5:27:16 AM10/25/14
to pac4j...@googlegroups.com
Hello all.

I'm new to pac4j (play-pac4j, to be more precise), coming really frustated from some other libraries. pac4j seems really good and adherent to "KISS", not messing with my controllers, views and routes.

I did some small changes to both play-pac4j (java) and the demo, to make it less coupled with my controllers and easing DI. It's working and, when polished, I will be more than happy to send a PR.

But two other features seems a little bit harder to do:

1 - I need to call my endpoints, which are protected by pac4j auth and my own authorization scheme, from another app, through a "REST-like" interface.

One of the most usual ways to do this seems to be adding some HTTP custom header in the requests and handling that. I managed to change the StoreHelper to fetch the pac4j session id from the headers, first, and fallback to the session object, if there is no custom header. I refactored all code to use this StoreHelper static method for every session id querying process. It's working, but I'd like to hear what you guys have to say about my approach.

2 - I need to authenticate through REST as well (and here things get a little bit more complicated)

What I need now is to return the "pac4j session id" to my app, after a successful authentication. I need to do it both for username/password credentials AND OAuth2 (Facebook, mostly). My idea regarding OAuth2 is to fetch the token on the app side and forward that to my server, which should return the session id, but I have no ideas about how to skip the whole code -> token exchange process. Regarding the user/password, I'm even more "lost".


Thanks in advance for any help,

Thiago Lima

Jérôme LELEU

unread,
Oct 26, 2014, 4:40:13 AM10/26/14
to Thiago Lima, pac4j...@googlegroups.com
Hi,

I always like to get feedback from pac4j users. Especially PR ;-)

1) Receiving some custom header is another authentication mechanism, it should be pluggable in pac4j. It seems very close to: https://github.com/leleuj/pac4j/blob/master/pac4j-http/src/main/java/org/pac4j/http/client/BasicAuthClient.java.
However, pac4j is meant to handle web flows: you call a protected url, the protected url is saved in session, the authentication occurs successfully (redirect to and back from the identity provider) and the original url is restored. It relies on the web session to save the original url. It doesn't work very well for REST.
So I guess you do a web flow authentication on one url (based on pac4j) and then on another url make some REST call on your own authentication mechanism.

It's a feasible solution, but I think the real target would be to have a good support of REST in pac4j. And we are maybe not so far from it.

Let's dive deeper in details (for play-pac4j):
- we have protected urls and a callback url:
@RequiresAuthentication(clientName = "TwitterClient")
public static Result twitterIndex() {
...

@RequiresAuthentication(clientName = "BasicAuthClient")
public static Result basicauthIndex() {
...
and the associated routes:
GET     /twitter/index.html         controllers.Application.twitterIndex()
GET     /basicauth/index.html       controllers.Application.basicauthIndex()
GET     /callback                   org.pac4j.play.CallbackController.callback()
POST    /callback                   org.pac4j.play.CallbackController.callback()

When a request comes for a protected url (@RequiresAuthentication annotation), the url is saved into session and a redirection happens to the identity provider. Then, after a successful authentication, the user is redirected back to the callback url with a parameter client_name (pac4j client) and specific credentials from the identity provider. The authentication is finished by the callback controller.
For a basic auth authentication, the same occurs except that the redirection to the identity provider is replaced by a direct redirection to the callback url which returns a 401 if no basic auth header is found and otherwise plays the authentication if a basic auth header is found.
The callback controller finishes the authentication and redirects to the original url. It's perfect for a web flow, but for a REST call, we just want the callback controller to finish the authentication and pass to the application logic.
Somehow, we could already have:

@CallbackController
public static Result callback() {
  return redirectToOriginalUrl();

Which would become for a REST endpoint:

@CallbackController
public static Result restEndpoint() {
  // application continues logic 
  ...
}

With this change, REST calls would be supported out of the box. Just add the @CallbackController annotation (or function in Scala) to enable a REST endpoint. Maybe it should be renamed as @AuthenticationEndpoint.

2) If you want to expose a REST API, I think I already answered above. You already have the access token as part of the FacebookProfile (as well as the other OAuth profiles).


I hope these long explanations make things clearer.

Thanks.
Best regards,





Jérôme LELEU
Founder of CAS in the cloud: www.casinthecloud.com | Twitter: @leleuj
Chairman of CAS: www.jasig.org/cas | Creator of pac4j: www.pac4j.org

--
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...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Jérôme LELEU

unread,
Dec 4, 2014, 11:09:59 AM12/4/14
to pac4j...@googlegroups.com, thiag...@beagletech.com.br
Hi,

Just an update on this request to say we are working on it.

It has been done for J2E (j2e-pac4j) and the next library on the roadmap is play-pac4j.

Best regards,
Jérôme

Thiago Lima

unread,
Dec 10, 2014, 7:24:36 AM12/10/14
to pac4j...@googlegroups.com, thiag...@beagletech.com.br
Hello, Jerome.

I don't know how familiar with Play the people working with the play-pac4j are, but I think we should use composition, instead of inheritance. It'd make it much more easy to integrate, including when using some kind of DI.

I made some huge refactoring in most of the play-pac4j classes, which I'm even afraid of share due to my lack of confidence in some aspects and since it'd be 100% backward INcompatible.

If you want to take a look, just ping me back using this thread. Anyway, I'd like ask for some update on this thread, once we have any new commit regarding this subject.


Best regards,

Jérôme LELEU

unread,
Dec 10, 2014, 10:04:39 AM12/10/14
to Thiago Lima, pac4j...@googlegroups.com
Hi,

Any contribution proposal is always welcome. No one should be afraid of proposing something; proposing is always better than nothing.

Would you mind sending a pull request with your changes? Even if we don't merge it, it's a good way to see your changes.

Best regards,


Jérôme LELEU
Founder of CAS in the cloud: www.casinthecloud.com | Twitter: @leleuj
Chairman of CAS: www.jasig.org/cas | Creator of pac4j: www.pac4j.org

--

Gajendra Naidu

unread,
May 22, 2015, 8:43:19 AM5/22/15
to pac4j...@googlegroups.com, thiag...@beagletech.com.br
Is this implemented in play-pac4j?

Jérôme LELEU

unread,
May 22, 2015, 8:46:20 AM5/22/15
to Gajendra Naidu, pac4j...@googlegroups.com, Thiago Lima
Hi,

There is a very small implementation of the basic auth support for REST operations in play-pac4j Java.

The whole REST support is currently under developpement in pac4j (v1.8): https://github.com/pac4j/pac4j/issues/152, before being implemented in all libraries (like play-pac4j).

Best regards,
Jérôme

Gajendra Naidu

unread,
May 22, 2015, 8:54:09 AM5/22/15
to pac4j...@googlegroups.com, thiag...@beagletech.com.br, gajendr...@gmail.com
Hi Jérôme
 
I am trying to secure REST API with play-pac4j using SAML. I am getting SAML Token from ADFS making separate connection to it. I am just wondering on how do I send SAML Token to Play like should I use custom HTTP header or something else.

Gajendra

Jérôme LELEU

unread,
May 22, 2015, 11:23:38 AM5/22/15
to Gajendra Naidu, pac4j...@googlegroups.com, Thiago Lima
Hi,

I don't know know the SAML token authentication works. You should certainly use a custom HTTP header to pass it, though you don't have the appropriate REST client in pac4j yet.
You should create something similar on what is coming in pac4j v1.8 for that: https://github.com/pac4j/pac4j/pull/166.
Best regards,
Jérôme

simin Ghasemi

unread,
Sep 24, 2016, 4:05:48 AM9/24/16
to pac4j-users, gajendr...@gmail.com, thiag...@beagletech.com.br
Hello,
In our project, we need to secure our API (web service URLs) through @Secure in pac4j (v2.5) using CasRestFormClient.
 
We need a scenario for authentication as follow:
1- First web service call, return notAuthentication.
2- In Front-end, the login page is shown and get username and password from user.
3- Front-end calls  /login and pass username and password through form attributes.
4- In pac4j, a TGT is requested and a CasProfile is created and a Service Ticket (ST) is returned.
5- In Front-end, ST is saved in localStorage.
6- From this moment on, any ajax call (for example GET /api/action ) is requested with embedded ST in request header as credential.
7- In pac4j,the passed credential (ST) is validated and without need of re-authentication, grant access to resource and return resource.
8- All other web service calls are validated with ST until session is expired.
9- If call, GET /logout the ST and related TGT is destroyed.

My question is that, CasRestAuthenticator seems to use username and password for every request validation. I found LocalCachingAuthenticator too, but I do not know how does it authenticate second, third and so on web service requests?
Besides, I am not sure that this solution is appropriate for our scenario. Any Suggestion is appreciated ...

Jérôme LELEU

unread,
Sep 24, 2016, 1:53:19 PM9/24/16
to simin Ghasemi, pac4j-users, Gajendra Naidu, Thiago Lima
Hi,


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.

Prabu Raja

unread,
Oct 21, 2016, 10:25:18 AM10/21/16
to pac4j-users, thiag...@beagletech.com.br, gajendr...@gmail.com
Hi Gajendra,

I am trying to do something very similar to what you had outlined. Did you get any solution to this? 

Thanks,
Prabu Raja

Kumar Vikramaditya

unread,
Feb 6, 2018, 1:31:31 PM2/6/18
to Pac4j users mailing list
Hi Jérôme,
Is there any update on this ? I am trying to secure my rest web services on Play 2.6. I want to issue a custom token with authorized grant types and scopes.(and not use JWT). Similar to something like Spring Security (Oauth2), which i had been using till now. Is this on road map/pipeline? Would be great if Play Community had such a library.

Regards,
-Vikram
To unsubscribe from this group and stop receiving emails from it, send an email to pac4j-users...@googlegroups.com.

Jérôme LELEU

unread,
Feb 7, 2018, 8:33:57 AM2/7/18
to Kumar Vikramaditya, Pac4j users mailing list
Hi,

I'm not sure to understand your question: are you trying to secure your app with the CasRestXClient or with the OAuth protocol?
Thanks.
Best regards,
Jérôme


--
You received this message because you are subscribed to the Google Groups "Pac4j users mailing list" group.
To unsubscribe from this group and stop receiving emails from it, send an email to pac4j-users+unsubscribe@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages