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.
Related
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.
I have already set up a running application having:
an authentication server
several resource servers
a javascript-frontend
For the authentication I am using the oauth2-stack of Spring-Security to hand out JWT-tokens to successfully authenticated user's. The login-information is collected in the javascript-fronted which then asks the authentication-server for an auth-token and stores it. This all works well for my application.
What I want to do now is integrate third-party-login-services like Google or Facebook. Currently I am at a point where the process can be started from the javascript-frontend, then the authentication-server does it's magic and communication with the third-party-login-provider. I've gotten so far that the login process is successful and I get the needed information which actually is only the e-mail-address.
But now I'm stuck. I have the authentication information on the server but now I need to construct one of my own authentication-JWT-tokens and hand it to my javascript-frontend. Can anybody give me a hint on how to achieve that?
The JWT Login Sample in Spring Security Samples demonstrates how to create JWT tokens for your own purposes. The key is to ensure that authentication has already occurred, prior to provisioning said token (which in your example is already the case).
Note that the sample uses the com.nimbusds:nimbus-jose-jwt dependency as Spring Security already depends on this library internally. You may also consider using io.jsonwebtoken:jjwt-api or another library instead. jwt.io has a useful list of libraries that support creation of JWTs, and you can filter by Java and click through to the repository to get more information about any of them.
In any case, the sample should be easily adapted to your choice of library, and the out-of-the-box support for verifying JWTs in Spring Security should work.
I have a Java Application running on tomcat server. I am storing the user information in mysql table and for authentication using Java Rest service.
Now when I land on customer.myapp.com I want to check if there is an active session in the browser for customer.com, if so login to my app using that session internally . If no session then redirect the user to customer.com login portal and after login land in customer.myapp.com home page.
How can I implement this using SAML . I have gone through the theory parts and got an idea about SP(in this case customer.myapp.com) and IdP(I assume it will the the customer's login portal customer.com) . I even downloaded the OpenSAML jar. I have no idea how the configuration is to be done. In my case I don't have any access to the IDP.
public class EMSAMLObjectBuilder {
// Get the builder factory
XMLObjectBuilderFactory builderFactory = Configuration.getBuilderFactory();
// Get the assertion builder based on the assertion element name
#SuppressWarnings("unchecked")
SAMLObjectBuilder<Assertion> builder = (SAMLObjectBuilder<Assertion>) builderFactory.getBuilder(Assertion.DEFAULT_ELEMENT_NAME);
// Create the assertion
Assertion assertion = builder.buildObject();
}
This is the only piece of code I could find. Any help ?
Sound like a standard use case for the SAML Web Browser Profile. I would suggest reading up on in it. There is a lot of information on the Internet.
Basically the process goes like this.
The SP and the IDP exchange metadataXML. This can be done by any means for example email or by publishing the xml on a webserver. This is only done once between a SP and IDP.
When the SP wants to authenticate the user, it sends it to the IDP using for example redirect together with a SAML Authentication Request.
The IDP authenticates the user.
The IDP send the user back to the SP together with a SAML Authentication Response
SAML is a very flexible protocol so the flow above can vary. How the communication is doen is generally closer specified in the metadata.
There are several ways this could be implemented, OpenSAML is one of them. The OpenSAML official website have some helpful examples.
I write a blog on OpenSAML with lots of helpful post on the subject. I have also written a book, A Guide to OpenSAML, that details step by step the implementation of a SAML Web Browser Profile service provider.
Coincidently the sample application in the book runs on embedded tomcat.
My feeling is that you should never directly use libraries like OpenSAML which are really low-level and complicated to master.
If you want to secure your web application with a SAML login process, you should certainly use a security library for that.
Disclaimer: I'm the creator of pac4j, so I can recommend using one of the pac4j implementations: http://www.pac4j.org/implementations.html for SAML: http://www.pac4j.org/docs/clients/saml.html
I have a Java Web Application and I want to serve it as a Service Provider and implement SAML. I am not sure about the workflow of how to do it.
I have read this SO question and still not able to understand completely.
In the question they are saying they need to send request to IDP, called as Assertion if I am right.
How do I create assertion? I saw the sample there. But where to pass the login credentials with that?
Also how do I register my application with IDP and do I need to install some certificate given by IDP for that? what is the workflow?
Thanks
Typically you use some kind of third party software to provide SAML integration. Examples of this is OpenAM and Shibboleth. It is a good idea to use software like this becaouse SAML is a complex protocol and it is easy to make mistakes, leaving your solution vulnerable.
I have a blog post on SAML and the work flow you can have a look at.
This one about SAML and this one about the SAML Web profile flow that you want
If you insist on doing the whole integration yourself in code. OpneSAML is one library you can use. This will require you to have a good understanding of SAML.
My book, A Guide to OpenSAML, gives a good introduction to SAML and the OpenSAML library.
I also have some blog posts on OpenSAML
About your questions. The Assertion is something that is sent to you from the IDP, this is the proof of an authentication of a user. What you need to do is to send a AuthnRequest to the IDP to start and authentication.
The registration on the IDP depends completely on what software is used to implment SAML in the IDP side. Usually it involves you sending a SAML Metadata XML to the IDP. This is a configuration file containing certificates, endpoint and more. Here is a post on SAML Metadata
In return the IDP send you metadata the you use to communicate with it.
i am stumped on this.
I wish to ask how do i really know that an authentic client is connecting to my web service.
I have successfully set up an HTTPs protocol on my web service and also my apache tomcat server.
However , how do i really authenticate a client dynamically without him giving me a username and password. Example, google authenticates its clients by giving them an api key , with that key they are allowed to use its web services.
I wish to do something similar to that, how do i do it?
Hope you guys can help me out on this.
Thanks in advance!
Probably you should look into The Apache Santuario project which is aimed at providing implementation of the primary security standards for XML.
-> This library includes a mature Digital Signature and Encryption implementation. It also includes the standard JSR 105 (Java XML Digital Signature) API. Applications can use the standard JSR 105 API or the Apache Santuario API to create and validate XML Signatures.
You can find more info at the following url
http://santuario.apache.org/index.html
You can also find an example here :
https://svn.apache.org/repos/asf/santuario/xml-security-java/trunk/samples/org/apache/xml/security/samples/signature/
specifically look into the KeyResolver feature
The Apache Santuario project is recommended project by Apache Axis.
http://axis.apache.org/axis/java/security.html#Authenticating_the_caller
What we tried in this situation is to go really Service Oriented .
i.e. We have an Authentication Service which takes input as User Credentials and return a session id . For all other Service calls the session id is added in the soapheader block.
soapHeader.addAttribute()
Using this approach
We avoided user credentials details to be used every time in service calls.
Also the signature of the service is devoid of any authentication data.
In this approach the client application has to authenticate first and use the output , session id for other service calls.
Request : We still haven't completely analyzed the security threat for this approach. Any suggestions / criticisms would be highly appreciated