IDP (okta) initiated flow

170 views
Skip to first unread message

Tomer Praizler

unread,
Feb 13, 2017, 11:40:41 AM2/13/17
to pac4j-users
Hey, 

I use pac4j to process the saml messages sent between my application(SP) and okta (IDP).
SP initiated flow works great.

I have the following routes:

POST          /api/saml/callback                                                      org.pac4j.play.CallbackController.callback()
GET          
/api/saml/login                                                         com.app.security.saml.SamlController.login(email: String)

The secured resource is the login end point.

When configuring okta for IDP initiated flow, I need to configure the default relay state url.
I am not sure which url it should be. 
The login end point? (it doesn't work)

Any idea?

Thanks!



Jérôme LELEU

unread,
Feb 14, 2017, 2:09:46 AM2/14/17
to Tomer Praizler, pac4j-users
Hi,

The login URL in the application side is the callback endpoint + the client name. Example: /callback?client_name=SAML2Client

Can you test this URL?

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.

Tomer Praizler

unread,
Feb 14, 2017, 4:53:42 AM2/14/17
to pac4j-users, tomer.p...@gmail.com
Thanks Jérôme, 

My login url: https://app.test.com/api/saml/login (This is the url that is responsible for the SP initiated flow)
This is the end point code

def login() = Secure("okta") { profiles =>
Action.async { implicit request =>
//continue login - put jwt cookie
}
}

I configured okta callback as:

When clicking on the app in okta, I can see it redirect me to https://app.test/com/api/saml/callback?client_name=okta as expected, 
and then it redirect me to "https://app.test.com" (I guess "/" is the default url for the callback)

In order for the user to actually login to my system he need to have the jwt cookie, which is attached to him in the code above. (comment)
But I don't think it goes through this flow when it is IDP initiated.

What am I missing?

Is there a place for me to add this logic (add cookie once the user is authenticated) as part of the callback controller?

Thanks, 
Tomer
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 14, 2017, 5:38:20 AM2/14/17
to Tomer Praizler, pac4j-users
Hi,

Indeed, you are redirected to https://app.test.com because the default URL is / at the CallbackController level.

Normally, the user should be authenticated after passing through the callback endpoint. It's just a matter of generating the JWT then.

In your case, to generate the JWT, you could define /login as the default URL in the CallbackController.

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.

Tomer Praizler

unread,
Feb 14, 2017, 7:35:38 AM2/14/17
to pac4j-users, tomer.p...@gmail.com
Thanks.

My problem is loading the client dynamiclly (as you know:) ).
So my login end point looks like this:

def login(email: String) = samlLogin(email)(parse.anyContent) { (samlClientName, loginMethod) =>
Secure(samlClientName) { profiles =>

Action.async { implicit request =>
//continue login - put jwt cookie
}
}
}

Based on the email, I know to which tenant this email belong to, and which login method is enabled (saml, okta, office365..)
So the SP initiated flow start from here: https://app.test.com/api/saml/login?email=m...@email.com
I fetch the tenant based on m...@email.com -> then the saml client name -> call Secure with this client name -> after the authentication, I get the profiles from okta and continue with the login process.

As you can see the client fetching is dynamic, based on the user email.
So I can't set the callback controller redirect url to that url you suggested, because it is based on the user email.

So I guess I will need to expose another end point for IDP initated flow, but I don't know how to code it.
Should it be wrapped with Secure? let's say the end point is: /api/saml/idplogin.

How does this api will look like? how do I get the profiles extracted from the saml response (the profiles which I have as the result of the Secure method)

Thank you for your help!
Tomer

Tomer Praizler

unread,
Feb 14, 2017, 11:45:21 AM2/14/17
to pac4j-users, tomer.p...@gmail.com
Thanks for the support Jérôme.
I managed to solve my problem by set the redirect url to : /api/saml/idp/login
With the following code (using the playSesstionStore)

def idpLogin = Action.async { implicit request =>
val webContext = new PlayWebContext(request, playSessionStore)
val profileManager = new ProfileManager[CommonProfile](webContext)
toScala(profileManager.get(true)) match {
case Some(profile) => //continue login - put jwt cookie
case None => authenticationFailed(request)
}
}

This is how I got hold of the profile. 
Is this the right way?

Thanks!

Jérôme LELEU

unread,
Feb 15, 2017, 1:42:40 AM2/15/17
to Tomer Praizler, pac4j-users
Hi,

It looks good to me. If you are not authenticated, you may want to redirect to the real default URL (/) instead of returning an authentication failed.

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