📜 ⬆️ ⬇️

SSL implementation through SAML with an example

Introduction


Good day, dear reader. I have long wanted to write an article on Habré, and finally this moment has come. Of the last topics that I did and about which I have something to tell, it was the implementation of SSO for the realtimeboard.com service — a wonderful product for teamwork of a remote team in one place that I want to constantly develop and improve. I want to clarify right away that, in principle, SSO through Facebook and Google was already in service before I arrived. My task was to implement it through the SAML protocol.


SSO ( Single Sign-On ) is a single sign -on technology that allows users to access many different services using their own account.


SAML is a popular XML protocol for implementing SSO. As a rule, large organizations (enterprise) use it as a proven and reliable option.


The appearance of this feature in our service was just due to frequent requests from enterprise customers for its implementation. Such customers centrally maintain the current user base, introduce their own security policies, etc. Accordingly, access to content in the service becomes more secure and controlled, which in the end they want.


Technical details


At the time of writing, the latest version of the standard is SAML 2.0 . The standard is based on XML, and therefore all the requirements of the w3c standards for XML are also applicable to it, do not forget about it. So, for example at the moment of implementation, I caught one mistake. At the time of the creation of AuthnRequest, I generated a unique string identifier for the ID attribute, so, according to the requirements, it should not begin with a number, and I occasionally had it that way.


Three parties are involved in authentication via SAML SSO:



The interaction scheme itself is shown in the figure below.


image

It produces two main interaction cases, one containing the other.


Option 1. The user accesses the service. The service generates the AuthnRequest message, puts the SAMLRequest parameter in and redirects the browser to the provider on the Login URL where the authentication takes place, then the provider generates a Response message, puts it in the SamlResponse parameter and redirects back to the service on the ACS URL .


Option 2. The user is already authenticated and is in the provider's personal account, from where he can go to the service by clicking on his shortcut. In this situation, the provider immediately generates a Response message, puts it in the SamlResponse parameter and sends it to the service on the ACS URL .


ACS URL (Assertion Consumer Service URL) is an url on the side of our application that accepts requests with the SamlResponse parameter, processes it (pulls out the Response message, checks the signature on the certificate, various rules) and if all is well, it creates a working session for the user in the application.


The IdP Login URL is an URL on the provider’s side that accepts requests with the SAMLRequest parameter and also performs proper validation of this parameter, and if all is well, sends it to the authentication form.


One of the online services such as OneLogin, LastPass, Okta and others can act as an IdP provider. You can also deploy your IdP using Shibboleth or raise AD.


Settings


All parameters for this interaction should be configured and stored on both sides (IdP, SP), that is, trust relationships should be built.


SP must keep a certificate that will be issued by IdP, as well as Saml Login the URL to which SAMLRequest will send.


IdP must be stored in the hosted ACS URL application ...


image

... must generate a certificate , select an encryption algorithm , provide Saml Login with the URL for the service ...


image

... should set up (if necessary) user attributes or some other custom fields for a particular service. Service with the provider must also agree on the format of the Subject NameID . This is essentially a user ID, information about which will be transmitted in messages. In our case, this email.


image

In addition to manual configuration, SP and IdP should be able to generate a metadata file containing all the necessary parameters for a “colleague” so that he can both load and set the settings himself. We had no such task.


In addition, I will also say that in addition to SSO, providers optionally also provide the service SLO (Single Logout) - a mechanism that involves exit from all services at once simultaneously. Two entry points are also possible:



To do this, on the service side, you must support the processing of SP SLO URL requests and sending requests to the IdP SLO URL . I also did not have such a task.


Research


And so, the task is set, I got acquainted with the theory, it’s time to start. First of all I got acquainted with the list of available libraries. The backend of our service is written in Java, I was looking for libraries for it The most complete list of products related to SAML can be found here . I chose the most obvious solutions for myself: Okta SAML Toolkit for Java, SpringSecurity SAML, OIOSAML 2.0 Toolkit, lastpass / saml-sdk-java, OneLogin 2.0, OneLogin 1.1.2, OpenSAML 2.0. Next, it was necessary to determine the criteria by which one or another solution would be chosen. So the following table was made.


To be honest, the source code of the proposed solutions was simply horrified - well-known providers decided to write their own high-level application libraries (not very good), most (thank God) solutions were based on the low-level library for working with SAML OpenSaml 2.0 . Considering that all these libraries would have to be edited in some way, honing the needs of our logic, and it was decided to build in our main code with all unit tests also use the existing base in the form of OpenSaml 2.0 and write our high-level logic on it. Perhaps, if we had Spring , I would use SAMSL SpringSecurity , but we don’t have it.


In general, I set out all my thoughts and solutions in our service for further discussion by the team; you can look at the screen below or switch to a “live” board , which I took part in filling.


image

So, the decision is chosen, the behavior is defined.


Implementation


As an IdP for testing, I chose OneLogin, as can be seen from the screenshots above. It provides a free developer account , with it it was easiest to set up a test application, and it also contains a set of utilities for working with SAML, which can facilitate your work. If you do not need any fully configurable IdP, then you can use this simple utility or its equivalent from Okta . I used them too.


First, I wrote my test local application to test this technology in principle, and I will show you its source code. Then he transferred this decision to an industrial code base. Application logic is simple and applicable to any service. The application prompts the user to enter an email if SAML SSO is not configured for this domain, then the application asks for the user's internal password (in the example, swears that the user cannot SSO). If it is configured, then we look at what IdP the given domain is configured for, form the message and redirect the request there. After successful authentication, we receive the generated message to our ACS URL from IdP, take an email from the message, take a certificate for this domain and validate the message. In case of successful verification, we take the attributes from the message FirstName , LastName . If the user already exists, change the values ​​of these attributes in our service. If there is no user yet, then create it.


This is the so-called Just-in-Time Provisioning . This is the easiest user provisioning (synchronization) implementation to do. The disadvantage of such synchronization is the delay in execution until the next user login. Plus, the inability to delete a user on the service side when deleting a user from IdP. In order to fully launch provisioning in the service, it is necessary to implement the SCIM standard, but I have not done this yet - perhaps this will be the next story.


Hope this article was helpful to you.


')

Source: https://habr.com/ru/post/329022/


All Articles