I'm using Spring Security's SAML 2.0 to connect my service provider to multiple identity providers.
Everything in Spring's SAML 2.0 documentation makes sense. I have read many helpful tutorials including this one, which are similar to my existing code.
However, I am missing where and how to select an identity provider for a given user.
I understand SAMLDiscovery can be used to delegate the identity provider selection to a third party service. I also understand how to configure multiple identity providers. But I'm looking for a way to run my own code (i.e. check a database) and then trigger a SAML request for the chosen identity provider (not a third party service). I would expect this around the time SAMLEntryPoint is hit. I have seen mention of specifying EntityID in the initial request. Is this related?
I am attempting to perform SP-initiated SAML 2.0 SSO. Can someone please point me toward where I can manually specify an IdP based on the current user?
As far as I know, SAML doesn't offer any mechanism for what you want.
SAML discovery is used to find out which IdP exist for your application.
Your problem is that you don't know who the user is before it tries to log in and when he does, it means that he already know which IdP he wants to use.
So you have these options:
Most common. Use a landing page that lets the user select which IdP to use. For example, Epic games lets you select the IdP from a list of 8. Once the user selects it, then you are good to go, by directing his request to the correct IdP.
If you know in advance which user belongs to which IdP then you can have a page that lets the user enter his username only. Once he does this, you can check in your DB to which IdP this user belongs to and send a redirect message back to the browser. While this works, it will not allow the user to select which IdP it wants to use, putting this job on the shoulders of the backend.
Do step 2 once and save a cookie in the user's browser. Then, when the user tries to log again in another session from the same machine, you can automatically redirect him to the right IdP. Using this option, everything is done automatically and except for the first time.
One thing to consider. From a security standpoint giving a hacker any info is a bad practice and so option 2,3 do reveal to a hacker which IdP belongs to which user. IMO this is not such a big breach and can be implemented.
This is not really a SAML question, since any solution would happen outside of standards and involve identifying the user before asking them to authenticate.
GENERAL PATTERN
App redirects to Service Provider using Technology A, eg SAML, OpenID Connect
For this app, the Service Provider is configured to run an action, eg present a screen, to identify the user - you may have seen this in systems such as Office365
Service Provider then uses some kind of data lookup to identify the IDPs for the next step
If there is more than one then the user is prompted to select one, otherwise the default option is invoked automatically
The Service Provider then redirects to the IDP using Technology B - could be SAML / OIDC / Other
EXTENSIBILITY
Hopefully my comments above show that an IAM system is a toolbox and should be extensible. I work at Curity where we use a concept of authenticators and actions which can be combined - eg for MFA, but a common option is as follows:
Capture the user name
Run some custom logic - eg JavaScript that invokes a data lookup to set the next authenticator
Here is a recent article to show how this works - the Username Authenticator is the interesting part.
PROVIDERS
Unfortunately Spring may not provide the options you would like. This should clarify your requirements a little though.
Related
Good day community:
I am currently developing projects with MyBatis, Spring Security and JSF 2.2.
I've done with these frameworks, 3 projects. These projects have three different database developed in SQL Server 2008.
Then, users of each database are the same, but they are in a Users table each, ie there is a table users per database.
What we have asked is that there can be only one single sign, and thus a user only has a single username and password.
How could make for these three systems are unified into single login?
My current solution in which also I have problems is:
Create a view in SQL Server 2008 users to bring me a central database and from there access is obtained.
Create an authentication module, which at login, can see only those systems where the user has access; in this case, clicking on one of these systems, automatically enter without again login. I was thinking to login to web services.
I hope I can help with ideas or ways of solutions.
All users are retrieved from a database and systems can continue to increase, but henceforth depend on the database.
Greetings and thanks.
Have you come across the Spring SAML module before? This is Spring's implementation of SAML 2.0 authentication, designed specifically with single sign-on in mind.
One of your servers can act as the identity provider, which you can think of as the main system that the users access. They will enter their username and password into this system. The other two systems will need to be setup as service providers - when a user tries to access one of them, they do not enter their username and password. Instead, a request gets sent to your identity provider (main system), which receives and validates the request, and will then allow access if the user is signed in to the identity provider already. If they are not signed in already, it will re-direct them to the login page for the identity provider from which they can login, and will then be re-directed to the system they were attempting to access.
Sorry if that is confusing at all. Head over to here for more information about the Spring SAML module. I implemented SSO for one of my clients using this, and I can highly recommend it for ease of configuration and implementation.
I have two Java wepapps potentially on different domains/servers using Spring Security for authentication. The first is handling authentication locally storing users in the application database. For the second, I would like to authenticate users using the same users accounts than the first webapp with single sign on (if a user is authenticated in the first webapp, it shouldn't have to enter his info again in the second).
I identified three potential ways to do this but it doesn't seem very straightforward:
Shared cookies: Using a shared session cookie and the same database for the two applications. It seem relatively easy to do but the two webapps need to be on the same domain which isn't necessarily the case for my applications.
Directory service: Using a central directory service (LDAP) which would be used by the two webapps to handle authentication. It seem pretty heavy to implement and the users can't be stored in the first webapp database anymore. The existing users accounts would need to be migrated into the LDAP and it would not be possible to create new users using the first webapp.
OAuth: It seem to be be possible to make the first webapp handle external authentications requests by providing an OAuth api (like Google sign on kind of service). That would allow the second webapp to use this api to authenticate the users, but I'm not sure that the signin process would be totally transparent to handle single sign on. It doesn't seem very easy to implement either, as it would necessitate the development of a complete OAuth api in the first webapp.
I also looked at this service https://auth0.com that seem to provide an authentication api that can be interfaced with an external database, but I'm not sure that it can be interfaced with Spring Security and it also mandate the use of an online solution which isn't ideal. I'm not sure that it would handle single sign on either, only shared accounts.
Is there any other way to handle this use case that would be more straightforward?
CAS is a good candidate indeed as a SSO system for your need and it has several CAS clients for Spring Security. You can try for free a CAS server v4.0 at CAS in the cloud: http://www.casinthecloud.com...
As you mentioned, a shared cookie won't work across domains.
LDAP would give you shared credentials (single name/pw works for both systems), but not single sign on, and you notice you'll have provisioning issues.
Not knowing anything about Spring Security, odds are high you won't find a painless solution to this. Integrating SSO is fraught with workflow issues (user provisioning, password recovery, user profile maintenance, etc.)
We had a classic DB managed authentication scheme. Later, when we added LDAP support, we added the capability for "auto-provisioning". This basically consisted of having the application pull down the relevant demographics from the LDAP store during login, and simply updating fields each time user logged in. If the user didn't exist, we'd create one on the fly.
This worked well, because the rest of the application had no awareness of LDAP. It simply worked with the user profile we managed already and if it needed something from the DB, the data was there.
Later, when we integrated SSO, we just leveraged the existing LDAP logic to pull from the SSO server and do the same thing.
This workflow helped a lot with provisioning and management. We could maintained the authoritative source (LDAP, SSO), and the app just kept up. What it hindered was local editing of the user profile, so we simply disabled that. Let them view the profile, but they could go to the other systems portal for management. Inelegant, but it's a rare use case anyway, so we just muddled through it. We eventually worked out two way pushing and replication, etc. but it's a real pain if you don't need it.
You can look here if you want an overview of how to do cross domain SSO: Cross Domain Login - How to login a user automatically when transferred from one domain to another
For our SSO, we use SAML v2 Web Profile, but we ended up writing our most of our own code to pull it off.
But, bottom line, no matter what the web sites say, integrating this is non-trivial. The edge cases and workflow/help desk issues that surround it are legion. And it can be a bear to debug.
I'm designing an SSO solution for my company using CAS. One requirement I'm facing that I'm not sure how to deal with is that one of the apps being fronted by CAS has a few pages considered "Highly Sensitive". While all apps should use CAS, when a user wants to access these particular pages, depending on business rules, they may be required to log in again.
I've seen something similar done in spring security using the "Remember Me" functionality to represent the broader idea of being logged in, but I would expect things to be different with CAS. For instance, assuming I've detected that reauthentication is required, forwarding a user back to the CAS login would simply allow the user to auto-login again. Or am I asking too much of CAS in this case and should I just write my own secondary login?
I have a customer who wants to implement SSO using SAML2 assertion based approach. The customer will be the Identity Provider (IDP) and my application will effectively be the Service Provider (SP).
In the past I've implemented SSO solutions where the IDP was Oracle Access Manager and therefore we were provided with the idp.xml file which allowed us to configure our SP environment using the supplied Fedlet. This conveniently created a relevant WAR file which, when deployed, allowed me to distribute the sp.xml file to the customer who imported it into their IDP. This all worked fine and I understand the concepts i.e. We receive the initial request, the fedlet handles this and takes the user to the IDP where they authenticate, then they're passed back to our SP with a SAML response which the Fedlet allows us to parse and extract some data identifying the user. I then do what's required to sign them into our application.
However the current requirement is not using any backend framework to provide the IDP, they've stated that it's custom built one. They've given me the IDP URL and a cert file and are asking for our "AssertionConsumerServiceURL" and "AudienceURI".
The application which I'm enabling SSO for is largely Java based. My investigation so far has led me to Forgerock's OpenAM solution as well as Shibboleth's OpenSAML. However I'm struggling with the first step, essentially where do what I start building a custom SP application connecting to a third party IDP using OpenAM/Shibboleth/AnotherFramework.
Any pointers would be very useful.
Thanks,
Lee
Depends on what what you requirements are. OpenAM feldlet or Shibboleth i probably the best approach since you don't have to do so much coding on your own.
OpenSAML is a very low level toolkit for handling SAML messages. I would not recommend it if, not really needed.
As for the things they are asking for, the AssertionConsumerServiceURL is the service endpoint where you recieve your SSO SAML messages.
Defenition of AudienceURI is quite gray. Basically you send them an identifier, they include this in their messages and you validate that identifier is the same you gave them. I my self do not understand the difference between this and Destination...
I'm a bit surprised that they ask you for this. The standard way to do this first exchange of information is by SAML metadata documents.
As you may know OpenAM also provides the FedLet, which is a lightweight SAML2.0 SP implementation. If you want to do it all yourself you have to build an SAML2.0 SP yourself.
If you want to mess around with Spring you could also use Spring Security SAML2 extension ..'http://static.springsource.org/spring-security/site/extensions/saml/index.html'
Why roll out those heavy SAML solutions? Have you taken a look at PingOne APS (Application Provider Services) or PingFederate from Ping Identity? You can implement APS in less than a day and you first customer config is free. Includes dashboard reporting, IDP self service functionality for config and a dead simple REST API integration for your application. [Note: I work for Ping.]
You can setup the Spring Security SAML Extension. The extension creates an AssertionConsumerServiceURL and if they want to access your metadata just as you are accessing theirs, they would just need to go to www.yourwebsite.com/saml/metadata and your SP metadata will be downloaded by them.
I'm trying to understand the concept and benefits of implementing OpenID in your project. And, since I'm a Java developer, I'm more or less equally interested in understanding its main Java implementation, openid4java.
My understanding is that OpenID is a standard for provisioning decentralized IDs in a uniform way. Now, if that is totally (or even slightly) incorrect, please correct me!
Assuming I'm still on track, I see that all sorts or organizations have been using OpenID, such as MySpace, who identifies each of their users with a URL matching http://www.myspace.com/username.
So how does OpenID work as a system? Does it just manifest itself as a network of "OpenID Servers" that, like DNS machines, coordinate and make sure all IDs in their system are unique and match a certain pattern? Or, is it just an algorithm to be used which, like GUID, produces globally-unique IDs for each client domain (such as MySpace).
I'm just not understanding how OpenID actually manifests itself, and how frameworks like openid4java ineract with that "manifestation". (What their uses are).
First, there are two sides of the OpenID communication - the provider and the consumer. The consumer is the application that tries to authenticate using OpenID, and the provider is the server to which the authentication request is sent.
Each provider has a so-called Endpoint - url that accepts authentication requests. You should know that URL in advance when supporting an OpenID provider. First you have to discover what is the endpoint for a given openId, and then exchange messages with that provider. This is all wrapped in openid4java ConsumerManager.
Then happens the authentication - you redirect the user to a provider url, where the user confirms he wants to login using his account (should be logged in), then the provider redirects back to you, and then you can get the requested information about the user (through another request)