Multiple identity providers and stateless authentication w/ Pac4J + JWTs

477 views
Skip to first unread message

Jackson Treeman

unread,
Jan 23, 2017, 2:52:43 PM1/23/17
to pac4j-users
Hi, I would like to create a centralized auth service to handle authentication and authorization between my microservices. I have an AngularJS front-end hosted on a NodeJS server, and an api server hosted on Jetty (Dropwizard framework) as the backend.  I would like to use Pac4J to secure the REST endpoints on my backend, and to handle multiple authentication mechanisms and identity providers (username + password, Facebook, Twitter and LinkedIn), with stateless claim-based authentication based on JWTs . Additionally, I want to store a user’s Facebook access token so I can get Facebook resources on their behalf at a later time. The centralized auth service would expose endpoints to login with different identity providers, to get an access token with which to request resources from a given identity provider, and to refresh a JWT.

From reading the Pac4J documentation, it looks like I would use the dropwizard-pac4j package, and secure all protected endpoints except for the login endpoints with a JWT authorizer. Then I would implement the relevant OAuth client for each of my identity providers at these login endpoints (FacebookClient for the api/authentication/facebook/login , etc). After successfully authenticating with the identity provider and receiving a pac4j profile (like FacebookProfile for example), I could use the JWTGenerator to create a JWT. I would pass this JWT back to the client who would then store it and pass it in the Authorization header on successive calls to protected resources where it would be validated by a JWTAuthenticator.

When the JWT expires, the client could exchange it at my auth service for a new JWT, and if the client needs to access a Facebook resource for example they can likewise use their JWT to authorize a call to the auth service where it will return their long-lived Facebook access token from the database to be used for the client’s request to Facebook. I have crafted a sequence diagram to demonstrate my current understanding of the correct procedure, and would greatly appreciate feedback of whether I am on the right track. Thanks!
Pac4J Stateless Authentication with JWTs - Page 1.png

Jérôme LELEU

unread,
Jan 24, 2017, 3:56:38 AM1/24/17
to Jackson Treeman, pac4j-users
Hi,

"and secure all protected endpoints except for the login endpoints with a JWT authorizer": authorizer != authenticator. Authorizers check authorizations while Authenticators validate credentials (authentication).

It looks good overall, I just have two concerns:
- when calling your REST API (Dropwizard) from your AngularJS app, the HTTP request will be redirected to the identity provider for login, won't it? But it's an AJAX request, how the UI login page will be displayed?
- did you think of using a standard protocol like OpenID Connect?

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.

Jackson Treeman

unread,
Jan 27, 2017, 6:50:40 PM1/27/17
to pac4j-users, jackson...@gmail.com
Hi Jérôme,

Thanks so much for the response. My mistake with authorizers versus authenticators, I imagine I would need to be using an HTTPClient which deals with TokenCredentials and then a JWTAuthenticator to validate credentials for the protected endpoints? I see the point you raise about the AJAX request--so using a FacebookClient or GoogleClient will always require the UI authentication (stateful/indirect) client flow? In which case my REST service would need to host the UI login page? Or is there a way I can get around that?

Thanks again, the library is great!
To unsubscribe from this group and stop receiving emails from it, send an email to pac4j-users...@googlegroups.com.

Jérôme LELEU

unread,
Jan 31, 2017, 4:50:36 AM1/31/17
to Jackson Treeman, pac4j-users
Hi,

Yes, you need a HeaderClient (JWT passed as a header) or a ParameterClient (JWT passed as a parameter) + a JwtAuthenticator to secure your REST API.

On your AngularJS app, you must check if you have a JWT: if not, you must redirect to your login endpoint of your centralized auth server (which will redirect to the login page of Facebook or Google).
Also, you must check the HTTP calls to the REST API: if a 401 error is returned (your JWT has expired), you must redirect back to the login endpoint.

Thanks.
Best regards,
Jérôme


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