Single Sign On: SimpleSAMLPhp Service Provider Implementatio - single-sign-on

I am implementing a SSO using SimpleSAMLPhp Service Provider.
I provided my metadata to remote Shibboleth Identity Provider and was provided a test account.
When a user visits a specific page on my SP, they get redirected to the IdP, login, and are redirected back to my web site with a bunch of IdP provided attributes. This part works.
This part I am struggling with.
If the user authenticates with the same IdP through a different Service Provider and then visits my page, how do I know they are already authenticated? Currently I am being asked to login again.
Is there a configuration value somewhere that lets me do this? Or am I using the wrong method? This is what I am doing.
$as = new SimpleSAML_Auth_Simple({REMOTE_AUTHSOURCE});
$as->requireAuth(); // this redirects to remote IdP login
$attributes = $as->getAttributes();
Thanks.

There are two separate authentication sessions to consider. One session is in you app and the other is at the IdP. The requireAuth method can tell if the user already has an authenticated session in your application, and will return immediately in that case.
There is no way for you to tell if a browser has a session at the IdP. You just call requireAuth whichs send the user there and if the IdP decides the user's session is still valid it will respond without prompting for login.
Are you saying that the user has a valid session at the IdP and they are being re-prompted to authenticate when you send the user there? That could be due to IdP policy, or if your app was sending something like 'forceAuth' in its AuthnRequest.

Related

Accepting a JWT token from an external IdP through Keycloak

I have a setup where Keycloak is acting as an identity broker. There are two Oauth2.0 Identity Providers configured in Keycloak.
A user goes to my app, is forwarded to Keycloak and is presented with two buttons. These buttons can be used to either authenticate with IdP 1 or IdP 2. Once the user is authenticated, keycloak will receive the JWT token and will issue its own JWT token to the client, enriched with claims from the JWT token received from the selected IdP. So far so good.
Now I have the usecase where my app will be embedded in another CRM platform. Let's say this CRM platform uses IdP 1. So a user is able to access the CRM and will authenticate through IdP 1. Then, the user can hit a button and get directed to my app. Of course we don't want the user to authenticate again with the same IdP but now first by going through Keycloak.
My question is, is there a way to let Keycloak use the IdP 1 token the user received when accessing the CRM platform in a way that Keycloak will enrich it and issue a JWT token just as it is done when the user would authenticate through Keycloak?
Consider implementing custom Authenticator that will sign on in Keycloak users that come from CRM. Our goal is to initiate SSO session in Keycloak.
Assume that when user hits button in CRM to got to your app, Keycloak will have access to some data provided by IDP1 that could be useful for identifying which user perform such action. So here we go:
User hit button "go to app"
User comes to App
App redirects user to Keycloak for passing the authentication
Your own custom implementation of Keycloak Authenticator will utilize information from IDP1 (you could utilize mentioned JWT token somehow)
Now SSO session in established and Keycloak redirects user back to your application
???
Profit
Also note that your will have to solve potential problem of session idle synchronization between Keycloak and IDP 1.
Keycloak development guide

SAML SSO: keeping users logged in after validating the SAML Assertion

I am implementing front-channel SAML 2.0 SSO golang Service Provider, with Okta as my Identity Provider (this is just a POC and should eventually work with any IdP).
Implementing the sign on process was straightforward with saml2 package. I've created the login endpoint that redirects to the SAML application login URL at the intended IdP, as well as the POST callback endpoint which is properly receiving the SAML assertion and is able to validate it. After that a session with a random cookie is created with the same TTL as the Identity Provider session TTL. So far everything works well (I haven't implemented Single Sign-Out yet, but I'm planning to).
However, when some time passes and the session expires, I'd like to renew it only if the user is still logged in with the Idp and hasn't been removed from the SAML Application. I would like to avoid redirecting the user to perform SSO again with IdP, because it would mean that if they are still logged in, they would be redirected back to the home page of my application. I wasn't able to find great sources on my options to go about it online.
Questions:
1.1 One solution that comes to mind is storing the requested URL in the RelayState parameter, whenever the session has expired, then redirect the user to the IdP SSO URL. When the redirect returns to the SAML callback POST endpoint, check the RelayState parameter and if set, redirect back to that (original) URL. That means that for users that use the system continuously, I would have to request Assertions very often. Does that make sense?
1.2 A second solution that comes to mind is to implement a back-channel of communicating directly from my SP to the IdP. That would allow me to verify a user is still logged in 'behind the users back'. If that's a sound idea:
a. Do I need to have dedicated code for each IdP?
b. Do I need to load an API key to the IdP which would allow secure communication?
c. Do I need to upload a public certificate to the IdP that would be able to verify that my SP signed the requests?
Will using the Assertion to get an OAuth 2.0 Access Token help me in achieving this?
I've chosen SAML 2.0 for now, since the environment is an enterprise oriented one and I thought it fits well with it based on what I read. Would using OpenID Connect instead help achieve my goals easier and fit well with enterprise oriented products?

Enforce IDP to ask for credentials

What I have right now?
I have a working SP-initiated flow where users can authenticate against their IDP. If they return after some time and click on SP-initiated authentication link, IDP lets them bypass entering credentials.
Question
Why does IDP decide to allow the user to jump over entering credentials? I have discovered if I delete my cookies this does not happen. Is this then IDP set cookie and IDP controlled session? Can I control this via SAML Request?
Can I enforce IDP to always ask for credentials by setting a FOO SAML Request flag? Is this even possible?
Most of the times the point of introducing SAML-based federated SSO is that users don't have to enter their credentials over and over again. So not having to type their credentials is a feature of the IDP.
But the behavior is completely up to the IDP who controls how and when the user authenticates. The SP can ask for forced authentication but it is still the IDP that decides if that request is honored (by following the spec).
An IDP may skip asking for credentials explicitly if the user has logged in explicitly within a short timeframe before the current authentication request. That's still relatively secure and convenient for the user.
you can force IdP to always prompt user for re-authentication by passing ForceAuthn=true attribute in authentication request.

SAML: is it possible to force user to go through login process even when user has an IDP session

In SAML, is it possible to force the user to go through idp's login process everytime even when the user has an active idp session?
To make a concrete example here:
Let's call my application "SP"
I use SSOCirecle as idp and I use POST and redirect (SP initiated).
To test, I will first login to SSOCircle to get an active idp session. Then when I try going to SP, I should be redirected to idp.
Normally, since I already have an active idp session, the idp will see "oh, you already being authenticated before, you can go directly to SP!"
But I don't want that, I want idp to force the user to enter credential everytime, maybe by either (I guess)
ignore active idp session
don't create an idp session
I want to knwo whether this is doable.
Yes, the SP can send a flag ForceAuthn to the Idp in the AuthnRequest to require a new authentication instead of reusing an existing session.
As always with SAML2, you can't expect all Idps to support everything. Yyou have to test if your Idp supports the ForceAuthn flag.

Is this SAML SSO implementation correct?

I have a site say www.e1.com. www.e1.com is Service Provider. Whenever I click a service in it, I am redirected to a Identity provider, say www.e2.com. Before that,In service provider(www.e1.com) I will check if any cookie is set for the user. For the first time there will be no cookie so it will send empty SessionId value. Thus, I am sending a SAML Request to www.e2.com along with with no id(as no cookie is set. Cookie contains Id)
Now in www.e2.com i.e.In identity provider,I will check whether www.e1.com has sent any Id value. If it is null I will create a session Id and store it in database(In www.e2.com). Then I will redirect browser to my Authentication page where User's Name and password will be asked and accordingly he will be authenticated. If the authentication is successfull, I will redirect browser to Service provider(www.e1.com) with SAML Response which contains session Id.
Now in Service provider the SessionId value will be stored in Cookie and browser will be redirected to consumer service page(service page the user wants to access).
Now if the same user wants to access some other service from same Service provider
(within the session), the browser will obviously send the SessionId in Cookie along with the request SAML. Identity Provider will check the SessionId value in his database, If its there in its database then it will give direct access to service to user without entering login credential as the user is already authenticated for the session.
Is this the right way to achieve Single Sign On with SAML? or
If this method has flaws, Can you explain those flaws?
Thanks in advance :)
Your understanding is not quite correct :)
Here is the flow:
User tries to access a protected resource on the SP. SP checks if the
user has a local (and authenticated session). If not it generates a
SAML <AuthRequest> which includes a random id. The SP then redirects
the user to the IDP with this AuthnRequest.
The IDP will check if the user has a local authenticated session. If
not it will authenticate the user The IDP will send an AuthResponse
back to the SP with an inReplyTo attribute which matches the id sent by
the SP in it's AuthnRequest
The SP will then create a local session. Subsequent requests to the
SP will not involve the IDP unless a) The session expires or b) the SP
receives a SingleLogout message from the IDP