Skip to content

Commit a2c2a3e

Browse files
committed
Update doc with info related to the demos
1 parent 3dad583 commit a2c2a3e

1 file changed

Lines changed: 107 additions & 34 deletions

File tree

README.md

Lines changed: 107 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ Installation
6565

6666
* python 2.7
6767
* M2Crypto A Python crypto and SSL toolkit (depends on swig)
68-
* dm.xmlsec.binding Cython/lxml based binding for the XML security library (depends on libxmlsec1-dev)
68+
* dm.xmlsec.binding Cython/lxml based binding for the XML security library (depends on python-dev libxml2-dev libxmlsec1-dev)
6969
* isodate An ISO 8601 date/time/duration parser and formater
7070
* defusedxml XML bomb protection for Python stdlib modules
7171

@@ -110,7 +110,7 @@ the classes and methods that are described in a later section.
110110

111111
#### demo-django ####
112112

113-
This folder contains a Django project that will be used as demo to show how to add SAML support to the Django Framework. 'demo' is the main folder of the django project (with its settings.py, views.py, urls.py), 'templates' is the django templates of the project and 'saml' is a folder that contains the 'certs' folder with the x509 public and private key, and the saml toolkit settings (settings.json and advanced_settings.json).
113+
This folder contains a Django project that will be used as demo to show how to add SAML support to the Django Framework. 'demo' is the main folder of the django project (with its settings.py, views.py, urls.py), 'templates' is the django templates of the project and 'saml' is a folder that contains the 'certs' folder that could be used to store the x509 public and private key, and the saml toolkit settings (settings.json and advanced_settings.json).
114114

115115
***Notice about certs***
116116

@@ -125,6 +125,12 @@ Or also we can provide those data in the setting file at the 'x509cert' and the
125125

126126
Sometimes we could need a signature on the metadata published by the SP, in this case we could use the x.509 cert previously mentioned or use a new x.509 cert: metadata.crt and metadata.key.
127127

128+
If you want to create self-signed certs, you can do it at the https://www.samltool.com/self_signed_certs.php service, or using the command:
129+
130+
```bash
131+
openssl req -new -x509 -days 3652 -nodes -out sp.crt -keyout saml.key
132+
```
133+
128134
#### demo-flask ####
129135

130136
This folder contains a Flask project that will be used as demo to show how to add SAML support to the Flask Framework. 'index.py' is the main flask file that has all the code, this file uses the templates stored at the 'templates' folder. In the 'saml' folder we found the 'certs' folder to store the x509 public and private key, and the saml toolkit settings (settings.json and advanced_settings.json).
@@ -167,7 +173,7 @@ This is the settings.json file:
167173

168174
```javascript
169175
{
170-
// If strict is True, then the PHP Toolkit will reject unsigned
176+
// If strict is True, then the Python Toolkit will reject unsigned
171177
// or unencrypted messages if it expects them to be signed or encrypted.
172178
// Also it will reject the messages if the SAML standard is not strictly
173179
// followed. Destination, NameId, Conditions ... are validated too.
@@ -202,7 +208,7 @@ This is the settings.json file:
202208
},
203209
// Specifies the constraints on the name identifier to be used to
204210
// represent the requested subject.
205-
// Take a look on lib/Saml2/Constants.php to see the NameIdFormat supported.
211+
// Take a look on src/onelogin/saml2/constants.py to see the NameIdFormat that are supported.
206212
"NameIDFormat": "urn:oasis:names:tc:SAML:2.0:nameid-format:unspecified",
207213
// Usually x509cert and privateKey of the SP are provided by files placed at
208214
// the certs folder. But we can also provide them with the following parameters
@@ -612,35 +618,38 @@ We can code a unique file that initiates the SSO process, handle the response, g
612618
Note: Review the demos, in a later section we explain the demo use case further in detail.
613619

614620
```python
615-
req = prepare_request_for_toolkit(request)
616-
auth = OneLogin_Saml2_Auth(req)
621+
req = prepare_request_for_toolkit(request) # Process the request and build the request dict that
622+
# the toolkit expects
617623

618-
if 'sso' in request.args:
624+
auth = OneLogin_Saml2_Auth(req) # Initialize the SP SAML instance
625+
626+
if 'sso' in request.args: # SSO action (SP-SSO initited). Will send an AuthNRequest to the IdP
619627
return redirect(auth.login())
620-
elif 'sso2' in request.args:
628+
elif 'sso2' in request.args: # Another SSO init action
629+
$returnTo = $spBaseUrl.'/demo1/attrs.php'; # but set a custom RelayState URL
621630
return_to = '%sattrs/' % request.host_url
622631
return redirect(auth.login(return_to))
623-
elif 'slo' in request.args:
632+
elif 'slo' in request.args: # SLO action. Will sent a Logout Request to IdP
624633
return redirect(auth.logout())
625-
elif 'acs' in request.args:
626-
auth.process_response()
627-
errors = auth.get_errors()
628-
if len(errors) == 0:
629-
if not auth.is_authenticated():
630-
msg = "Not authenticated"
634+
elif 'acs' in request.args: # Assertion Consumer Service
635+
auth.process_response() # Process the Response of the IdP
636+
errors = auth.get_errors() # This method receives an array with the errors
637+
if len(errors) == 0: # that could took place during the process
638+
if not auth.is_authenticated(): # This check if the response was ok and the user
639+
msg = "Not authenticated" # data retrieved or not (user authenticated)
631640
else:
632-
session['samlUserdata'] = auth.get_attributes()
641+
request.session['samlUserdata'] = auth.get_attributes() # Retrieves user data
633642
self_url = OneLogin_Saml2_Utils.get_self_url(req)
634-
if 'RelayState' in request.form and self_url != request.form['RelayState']:
635-
return redirect(auth.redirect_to(request.form['RelayState']))
636-
else:
643+
if 'RelayState' in request.form and self_url != request.form['RelayState']:
644+
return redirect(auth.redirect_to(request.form['RelayState'])) # Redirect if there is a relayState
645+
else: # If there is user data we save that to print it later.
637646
msg = ''
638647
for attr_name in request.session['samlUserdata'].keys():
639648
msg += '%s ==> %s' % (attr_name, '|| '.join(request.session['samlUserdata'][attr_name]))
640-
elif 'sls' in request.args:
641-
delete_session_callback = lambda: session.clear()
642-
url = auth.process_slo(delete_session_cb=delete_session_callback)
643-
errors = auth.get_errors()
649+
elif 'sls' in request.args: # Single Logout Service
650+
delete_session_callback = lambda: session.clear() # Obtain session clear callback
651+
url = auth.process_slo(delete_session_cb=delete_session_callback) # Process the Logout Request & Logout Response
652+
errors = auth.get_errors() # Retrieves possible validation errors
644653
if len(errors) == 0:
645654
if url is not None:
646655
return redirect(url)
@@ -662,7 +671,7 @@ Described below are the main classes and methods that can be invoked from the SA
662671

663672
Main class of OneLogin Python Toolkit
664673

665-
* ***__init__*** Initializes the SP SAML instance.
674+
* `__init__` Initializes the SP SAML instance.
666675
* ***login*** Initiates the SSO process.
667676
* ***logout*** Initiates the SLO process.
668677
* ***process_response*** Process the SAML Response sent by the IdP.
@@ -685,7 +694,7 @@ Main class of OneLogin Python Toolkit
685694

686695
SAML 2 Authentication Request class
687696

688-
* ***__init__** This class handles an AuthNRequest. It builds an AuthNRequest object.
697+
* `__init__` This class handles an AuthNRequest. It builds an AuthNRequest object.
689698
* ***get_request*** Returns unsigned AuthnRequest.
690699
* ***get_id*** Returns the AuthNRequest ID.
691700

@@ -694,7 +703,7 @@ SAML 2 Authentication Request class
694703

695704
SAML 2 Authentication Response class
696705

697-
* ***__init__*** Constructs the SAML Response object.
706+
* `__init__` Constructs the SAML Response object.
698707
* ***is_valid*** Determines if the SAML Response is valid. Includes checking of the signature by a certificate.
699708
* ***check_status*** Check if the status of the response is success or not
700709
* ***get_audiences*** Gets the audiences
@@ -712,7 +721,7 @@ SAML 2 Authentication Response class
712721

713722
SAML 2 Logout Request class
714723

715-
* ***__init__*** Constructs the Logout Request object.
724+
* `__init__` Constructs the Logout Request object.
716725
* ***get_request*** Returns the Logout Request defated, base64encoded.
717726
* ***get_id*** Returns the ID of the Logout Request.
718727
* ***get_nameid_data*** Gets the NameID Data of the the Logout Request (returns a dict).
@@ -726,7 +735,7 @@ SAML 2 Logout Request class
726735

727736
SAML 2 Logout Response class
728737

729-
* ***__init__*** Constructs a Logout Response object.
738+
* `__init__` Constructs a Logout Response object.
730739
* ***get_issuer*** Gets the Issuer of the Logout Response Message
731740
* ***get_status*** Gets the Status of the Logout Response.
732741
* ***is_valid*** Determines if the SAML LogoutResponse is valid
@@ -737,9 +746,9 @@ SAML 2 Logout Response class
737746

738747
####OneLogin_Saml2_Settings - settings.py####
739748

740-
Configuration of the OneLogin PHP Toolkit
749+
Configuration of the OneLogin Python Toolkit
741750

742-
* ***__init__*** Initializes the settings: Sets the paths of the different folders and Loads settings info from settings file or array/object provided.
751+
* `__init__` Initializes the settings: Sets the paths of the different folders and Loads settings info from settings file or array/object provided.
743752
* ***check_settings*** Checks the settings info.
744753
* ***get_errors*** Returns an array with the errors, the array is empty when the settings is ok.
745754
* ***get_sp_metadata*** Gets the SP metadata. The XML representation.
@@ -870,10 +879,49 @@ You'll have the demo running at http://localhost:8000
870879

871880
####Content####
872881

882+
The flask project contains:
883+
884+
885+
* ***index.py*** Is the main flask file, where or the SAML handle take place.
886+
887+
* ***templates***. Is the folder where flask stores the templates of the project. It was implemented a base.html template that is extended by index.html and attrs.html, the templates of our simple demo that shows messages, user attributes when available and login and logout links.
888+
889+
* ***saml*** Is a folder that contains the 'certs' folder that could be used to store the x509 public and private key, and the saml toolkit settings (settings.json and advanced_settings.json).
890+
891+
892+
####SP setup####
893+
894+
The Onelogin's Python Toolkit allows you to provide the settings info in 2 ways: settings files or define a setting dict. In the demo-flask it used the first method.
895+
896+
In the index.py file we define the app.config['SAML_PATH'], that will target to the 'saml' folder. We require it in order to load the settings files.
897+
898+
First we need to edit the saml/settings.json, configure the SP part and review the metadata of the IdP and complete the IdP info. Later edit the saml/advanced_settings.json files and configure the how the toolkit will work. Check the settings section of this document if you have any doubt.
899+
900+
####IdP setup####
901+
902+
Once the SP is configured, the metadata of the SP is published at the /metadata url. Based on that info, configure the IdP.
873903

874904
####How it works####
875905

906+
1. First time you access to the main view 'http://localhost:8000', you can select to login and return to the same view or login and be redirected to /?attrs (attrs view).
907+
908+
2. When you click:
909+
910+
2.1 in the first link, we access to /?sso (index view). An AuthNRequest is sent to the IdP, we authenticate at the IdP and then a Response is sent to the SP, specifically the Assertion Consumer Service view: /?acs, notice that a RelayState parameter is set to the url that initiated the process, the index view.
876911

912+
2.2 in the second link we access to /?attrs (attrs view), we will expetience have the same process described at 2.1 with the diference that as RelayState is set the attrs url.
913+
914+
3. The SAML Response is processed in the ACS /?acs, if the Response is not valid, the process stops here and a message is shown. Otherwise we are redirected to the RelayState view. a) / or b) /?attrs
915+
916+
4. We are logged in the app and the user attributes are showed. At this point, we can test the single log out functionality.
917+
918+
The single log out funcionality could be tested by 2 ways.
919+
920+
5.1 SLO Initiated by SP. Click on the "logout" link at the SP, after that a Logout Request is sent to the IdP, the session at the IdP is closed and replies to the SP a Logout Response (sent to the Single Logout Service endpoint). The SLS endpoint /?sls of the SP process the Logout Response and if is valid, close the user session of the local app. Notice that the SLO Workflow starts and ends at the SP.
921+
922+
5.2 SLO Initiated by IdP. In this case, the action takes place on the IdP side, the logout process is initiated at the idP, sends a Logout Request to the SP (SLS endpoint, /?sls). The SLS endpoint of the SP process the Logout Request and if is valid, close the session of the user at the local app and send a Logout Response to the IdP (to the SLS endpoint of the IdP). The IdP receives the Logout Response, process it and close the session at of the IdP. Notice that the SLO Workflow starts and ends at the IdP.
923+
924+
Notice that all the SAML Requests and Responses are handled at a unique view (index) and how GET paramters are used to know the action that must be done.
877925

878926
### Demo Django ###
879927

@@ -884,10 +932,9 @@ virtualenv and execute:
884932
```
885933
pip install -r demo-django/requirements.txt
886934
```
887-
This will install django and its dependences. Once it has finished, you have to complete
888-
the configuration of the toolkit. You'll find it at `demo-django/settings.json`
935+
This will install django and its dependences. Once it has finished, you have to complete the configuration of the toolkit.
889936

890-
Now, with the virtualenv loaded, you can run the demo like this:
937+
Later, with the virtualenv loaded, you can run the demo like this:
891938
```
892939
cd demo-django
893940
python manage.py runserver 0.0.0.0:8000
@@ -897,6 +944,32 @@ You'll have the demo running at http://localhost:8000
897944

898945
####Content####
899946

900-
####How it works####
947+
The django project contains:
948+
949+
* ***manage.py***. A file that is automatically created in each Django project. Is a thin wrapper around django-admin.py that takes care of putting the project’s package on sys.path and sets the DJANGO_SETTINGS_MODULE environment variable.
950+
951+
* ***saml*** Is a folder that contains the 'certs' folder that could be used to store the x509 public and private key, and the saml toolkit settings (settings.json and advanced_settings.json).
901952

953+
* ***demo*** Is the main folder of the django project, that contains the typical files:
954+
* ***settings.py*** Contains the default parameters of a django project except the SAML_FOLDER parameter, that may contain the path where is located the 'saml' folder.
955+
* ***urls.py*** A file that define url routes. In the demo we defined '/' that is related to the index view, '/attrs' that is related with the attrs view and '/metadata', related to th metadata view.
956+
* ***views.py*** This file contains the views of the django project and some aux methods.
957+
* ***wsgi.py*** A file that let as deploy django using WSGI, the Python standard for web servers and applications.
958+
959+
* ***templates***. Is the folder where django stores the templates of the project. It was implemented a base.html template that is extended by index.html and attrs.html, the templates of our simple demo that shows messages, user attributes when available and login and logout links.
960+
961+
####SP setup####
962+
963+
The Onelogin's Python Toolkit allows you to provide the settings info in 2 ways: settings files or define a setting dict. In the demo-django it used the first method.
964+
965+
After set the SAML_FOLDER in the demo/settings.py, the settings of the python toolkit will be loaded on the django web.
966+
967+
First we need to edit the saml/settings.json, configure the SP part and review the metadata of the IdP and complete the IdP info. Later edit the saml/advanced_settings.json files and configure the how the toolkit will work. Check the settings section of this document if you have any doubt.
968+
969+
####IdP setup####
970+
971+
Once the SP is configured, the metadata of the SP is published at the /metadata url. Based on that info, configure the IdP.
972+
973+
####How it works####
902974

975+
This demo works very similar to the flask-demo (We did it intentionally).

0 commit comments

Comments
 (0)