Skip to content

Commit 883ebcf

Browse files
authored
Merge pull request #151 from sbc100/doc_fixes
Doc fixes
2 parents 3ade98c + 543f2af commit 883ebcf

2 files changed

Lines changed: 51 additions & 51 deletions

File tree

README.md

Lines changed: 50 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -7,31 +7,30 @@
77
![Python versions](https://img.shields.io/pypi/pyversions/python-saml.svg)
88

99
Add SAML support to your Python software using this library.
10-
Forget those complicated libraries and use that open source library provided
10+
Forget those complicated libraries and use the open source library provided
1111
and supported by OneLogin Inc.
1212

13-
This version supports Python2, exists an alternative version compatible with Python 3: [python3-saml](https://github.com/onelogin/python3-saml)
13+
This version supports Python2. There is a separate version that supports
14+
Python3: [python3-saml](https://github.com/onelogin/python3-saml).
1415

1516
#### Warning ####
1617

1718
Update python-saml to 2.1.9, this version includes a security patch that contains extra validations that will prevent signature wrapping attacks.
1819

1920
python-saml < v2.1.6 is vulnerable and allows signature wrapping!
2021

21-
2222
#### Security Guidelines ####
2323

2424
If you believe you have discovered a security vulnerability in this toolkit, please report it at https://www.onelogin.com/security with a description. We follow responsible disclosure guidelines, and will work with you to quickly find a resolution.
2525

26-
2726
Why add SAML support to my software?
2827
------------------------------------
2928

3029
SAML is an XML-based standard for web browser single sign-on and is defined by
31-
the OASIS Security Services Technical Committee. The standard has been around
30+
the OASIS Security Services Technical Committee. The standard has been around
3231
since 2002, but lately it is becoming popular due its advantages:
3332

34-
* **Usability** - One-click access from portals or intranets, deep linking,
33+
* **Usability** - One-click access from portals or intranets, deep linking,
3534
password elimination and automatically renewing sessions make life
3635
easier for the user.
3736
* **Security** - Based on strong digital signatures for authentication and
@@ -44,21 +43,21 @@ since 2002, but lately it is becoming popular due its advantages:
4443
* **IT Friendly** - SAML simplifies life for IT because it centralizes
4544
authentication, provides greater visibility and makes directory
4645
integration easier.
47-
* **Opportunity** - B2B cloud vendor should support SAML to facilitate the
46+
* **Opportunity** - B2B cloud vendor should support SAML to facilitate the
4847
integration of their product.
4948

5049
General description
5150
-------------------
5251

53-
OneLogin's SAML Python toolkit let you build a SP (Service Provider) over
54-
your Python application and connect it to any IdP (Identity Provider).
52+
OneLogin's SAML Python toolkit lets you turn you Python application into an SP
53+
(Service Provider) that can connect to a IdP (Identity Provider).
5554

5655
Supports:
5756

5857
* SSO and SLO (SP-Initiated and IdP-Initiated).
5958
* Assertion and nameId encryption.
60-
* Assertion signature.
61-
* Message signature: AuthNRequest, LogoutRequest, LogoutResponses.
59+
* Assertion signatures.
60+
* Message signatures: AuthNRequest, LogoutRequest, LogoutResponses.
6261
* Enable an Assertion Consumer Service endpoint.
6362
* Enable a Single Logout Service endpoint.
6463
* Publish the SP metadata (which can be signed).
@@ -68,7 +67,7 @@ Key features:
6867
* **saml2int** - Implements the SAML 2.0 Web Browser SSO Profile.
6968
* **Session-less** - Forget those common conflicts between the SP and
7069
the final app, the toolkit delegate session in the final app.
71-
* **Easy to use** - Programmer will be allowed to code high-level and
70+
* **Easy to use** - Programmer will be allowed to code high-level and
7271
low-level programming, 2 easy to use APIs are available.
7372
* **Tested** - Thoroughly tested.
7473
* **Popular** - OneLogin's customers use it. Add easy support to your django/flask/bottle web projects.
@@ -77,7 +76,7 @@ Key features:
7776
Installation
7877
------------
7978

80-
### Dependences ###
79+
### Dependencies ###
8180

8281
* python 2.7
8382
* [dm.xmlsec.binding](https://pypi.python.org/pypi/dm.xmlsec.binding) Cython/lxml based binding for the XML security library (depends on python-dev libxml2-dev libxmlsec1-dev)
@@ -87,13 +86,14 @@ Installation
8786

8887
Review the setup.py file to know the version of the library that python-saml is using
8988

90-
### OSX Dependences ###
89+
### OSX Dependencies ###
90+
9191
* python 2.7
9292
* libxmlsec1
93-
93+
9494
```sh
95-
# using brew
96-
brew install libxmlsec1
95+
# using brew
96+
$ brew install libxmlsec1
9797
```
9898

9999

@@ -106,15 +106,15 @@ The toolkit is hosted on github. You can download it from:
106106
* Lastest release: https://github.com/onelogin/python-saml/releases/latest
107107
* Master repo: https://github.com/onelogin/python-saml/tree/master
108108

109-
Copy the core of the library (src/onelogin/saml2 folder) and merge the setup.py inside the python application. (each application has its structure so take your time to locate the Python SAML toolkit in the best place).
109+
Copy the core of the library (src/onelogin/saml2 folder) and merge the setup.py inside the python application. (each application has its structure so take your time to locate the Python SAML toolkit in the best place).
110110

111111
#### Option 2. Download from pypi ####
112112

113113
The toolkit is hosted in pypi, you can find the python-saml package at https://pypi.python.org/pypi/python-saml
114114

115115
You can install it executing:
116116
```
117-
pip install python-saml
117+
$ pip install python-saml
118118
```
119119

120120
If you want to know how a project can handle python packages review this [guide](https://packaging.python.org/en/latest/tutorial.html) and review this [sampleproject](https://github.com/pypa/sampleproject)
@@ -123,7 +123,7 @@ If you want to know how a project can handle python packages review this [guide]
123123
Security warning
124124
----------------
125125

126-
In production, the **strict** parameter MUST be set as **"true"**. Otherwise
126+
In production, the **strict** parameter MUST be set as **"true"**. Otherwise
127127
your environment is not secure and will be exposed to attacks.
128128

129129

@@ -217,7 +217,7 @@ This is the settings.json file:
217217

218218
```javascript
219219
{
220-
// If strict is True, then the Python Toolkit will reject unsigned
220+
// If strict is True, then the Python Toolkit will reject unsigned
221221
// or unencrypted messages if it expects them to be signed or encrypted.
222222
// Also it will reject the messages if the SAML standard is not strictly
223223
// followed. Destination, NameId, Conditions ... are validated too.
@@ -236,11 +236,11 @@ This is the settings.json file:
236236
// URL Location where the <Response> from the IdP will be returned
237237
"url": "https://<sp_domain>/?acs",
238238
// SAML protocol binding to be used when returning the <Response>
239-
// message. OneLogin Toolkit supports this endpoint for the
239+
// message. OneLogin Toolkit supports this endpoint for the
240240
// HTTP-POST binding only.
241241
"binding": "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
242242
},
243-
// If you need to specify requested attributes, set a
243+
// If you need to specify requested attributes, set a
244244
// attributeConsumingService. nameFormat, attributeValue and
245245
// friendlyName can be omitted
246246
"attributeConsumingService": {
@@ -257,7 +257,7 @@ This is the settings.json file:
257257
]
258258
},
259259
// Specifies info about where and how the <Logout Response> message MUST be
260-
// returned to the requester, in this case our SP.
260+
// returned to the requester, in this case our SP.
261261
"singleLogoutService": {
262262
// URL Location where the <Response> from the IdP will be returned
263263
"url": "https://<sp_domain>/?sls",
@@ -282,7 +282,7 @@ This is the settings.json file:
282282
"entityId": "https://app.onelogin.com/saml/metadata/<onelogin_connector_id>",
283283
// SSO endpoint info of the IdP. (Authentication Request protocol)
284284
"singleSignOnService": {
285-
// URL Target of the IdP where the Authentication Request Message
285+
// URL Target of the IdP where the Authentication Request Message
286286
// will be sent.
287287
"url": "https://app.onelogin.com/trust/saml2/http-post/sso/<onelogin_connector_id>",
288288
// SAML protocol binding to be used when returning the <Response>
@@ -302,16 +302,16 @@ This is the settings.json file:
302302
// Public x509 certificate of the IdP
303303
"x509cert": "<onelogin_connector_cert>"
304304
/*
305-
* Instead of use the whole x509cert you can use a fingerprint in order to
305+
* Instead of using the whole x509cert you can use a fingerprint in order to
306306
* validate a SAMLResponse, but you will need it to validate LogoutRequest and LogoutResponse using the HTTP-Redirect binding.
307-
*
307+
*
308308
* (openssl x509 -noout -fingerprint -in "idp.crt" to generate it,
309309
* or add for example the -sha256 , -sha384 or -sha512 parameter)
310310
*
311311
* If a fingerprint is provided, then the certFingerprintAlgorithm is required in order to
312312
* let the toolkit know which algorithm was used. Possible values: sha1, sha256, sha384 or sha512
313313
* 'sha1' is the default value.
314-
*
314+
*
315315
* Notice that if you want to validate any SAML Message sent by the HTTP-Redirect binding, you
316316
* will need to provide the whole x509cert.
317317
*/
@@ -321,7 +321,7 @@ This is the settings.json file:
321321
}
322322
```
323323

324-
In addition to the required settings data (idp, sp), there is extra information that could be defined at advanced_settings.json
324+
In addition to the required settings data (idp, sp), extra settings can be defined in `advanced_settings.json`:
325325

326326
```javascript
327327
{
@@ -334,15 +334,15 @@ In addition to the required settings data (idp, sp), there is extra information
334334
// will be encrypted.
335335
"nameIdEncrypted": false,
336336

337-
// Indicates whether the <samlp:AuthnRequest> messages sent by this SP
337+
// Indicates whether the <samlp:AuthnRequest> messages sent by this SP
338338
// will be signed. [Metadata of the SP will offer this info]
339339
"authnRequestsSigned": false,
340340

341-
// Indicates whether the <samlp:logoutRequest> messages sent by this SP
341+
// Indicates whether the <samlp:logoutRequest> messages sent by this SP
342342
// will be signed.
343343
"logoutRequestSigned": false,
344344

345-
// Indicates whether the <samlp:logoutResponse> messages sent by this SP
345+
// Indicates whether the <samlp:logoutResponse> messages sent by this SP
346346
// will be signed.
347347
"logoutResponseSigned": false,
348348

@@ -368,7 +368,7 @@ In addition to the required settings data (idp, sp), there is extra information
368368
// elements received by this SP to be encrypted.
369369
'wantAssertionsEncrypted' => false,
370370

371-
// Indicates a requirement for the NameID element on the SAMLResponse
371+
// Indicates a requirement for the NameID element on the SAMLResponse
372372
// received by this SP to be present.
373373
"wantNameId": true,
374374

@@ -428,7 +428,7 @@ In addition to the required settings data (idp, sp), there is extra information
428428
}
429429
```
430430

431-
In the security section, you can set the way that the SP will handle the messages and assertions. Contact the admin of the IdP and ask him what the IdP expects, and decide what validations will handle the SP and what requirements the SP will have and communicate them to the IdP's admin too.
431+
In the security section, you can set the way that the SP will handle the messages and assertions. Contact the admin of the IdP and ask them what the IdP expects, and decide what validations will handle the SP and what requirements the SP will have and communicate them to the IdP's admin too.
432432

433433
Once we know what kind of data could be configured, let's talk about the way settings are handled within the toolkit.
434434

@@ -557,7 +557,7 @@ auth.get_last_request_id()
557557

558558
#### The SP Endpoints ####
559559

560-
Related to the SP there are 3 important endpoints: The metadata view, the ACS view and the SLS view.
560+
Related to the SP there are 3 important endpoints: The metadata view, the ACS view and the SLS view.
561561
The toolkit provides examples of those views in the demos, but lets see an example.
562562

563563
***SP Metadata***
@@ -580,7 +580,7 @@ The get_sp_metadata will return the metadata signed or not based on the security
580580

581581
Before the XML metadata is exposed, a check takes place to ensure that the info to be provided is valid.
582582

583-
Instead of use the Auth object, you can directly use
583+
Instead of using the Auth object, you can directly use
584584
```
585585
saml_settings = OneLogin_Saml2_Settings(settings=None, custom_base_path=None, sp_validation_only=True)
586586
```
@@ -598,7 +598,7 @@ errors = auth.get_errors()
598598
if not errors:
599599
if auth.is_authenticated():
600600
request.session['samlUserdata'] = auth.get_attributes()
601-
if 'RelayState' in req['post_data'] and
601+
if 'RelayState' in req['post_data'] and
602602
OneLogin_Saml2_Utils.get_self_url(req) != req['post_data']['RelayState']:
603603
auth.redirect_to(req['post_data']['RelayState'])
604604
else:
@@ -636,7 +636,7 @@ If we execute print attributes we could get:
636636
"mail": ["Doe"],
637637
"groups": ["users", "members"]
638638
}
639-
```
639+
```
640640

641641
Each attribute name can be used as a key to obtain the value. Every attribute is a list of values. A single-valued attribute is a listy of a single element.
642642

@@ -679,7 +679,7 @@ if not logout_response.is_valid(self.__request_data, request_id):
679679
elif logout_response.get_status() != OneLogin_Saml2_Constants.STATUS_SUCCESS:
680680
self.__errors.append('logout_not_success')
681681
elif not keep_local_session:
682-
OneLogin_Saml2_Utils.delete_local_session(delete_session_cb)
682+
OneLogin_Saml2_Utils.delete_local_session(delete_session_cb)
683683
```
684684

685685
If the SLS endpoints receives an Logout Request, the request is validated, the session is closed and a Logout Response is sent to the SLS endpoint of the IdP.
@@ -723,7 +723,7 @@ In order to send a Logout Request to the IdP:
723723

724724
The Logout Request will be sent signed or unsigned based on the security info of the advanced_settings.json ('logoutRequestSigned').
725725

726-
The IdP will return the Logout Response through the user's client to the Single Logout Service of the SP.
726+
The IdP will return the Logout Response through the user's client to the Single Logout Service of the SP.
727727

728728
We can set a 'return_to' url parameter to the logout function and that will be converted as a 'RelayState' parameter:
729729

@@ -734,7 +734,7 @@ auth.logout(return_to=target_url)
734734

735735
Also there are 2 optional parameters that can be set:
736736

737-
* name_id. That will be used to build the LogoutRequest. If not name_id parameter is set and the auth object processed a
737+
* name_id. That will be used to build the LogoutRequest. If not name_id parameter is set and the auth object processed a
738738
SAML Response with a NameId, then this NameId will be used.
739739
* session_index. SessionIndex that identifies the session of the user.
740740

@@ -758,21 +758,21 @@ auth = OneLogin_Saml2_Auth(req) # Initialize the SP SAML instance
758758

759759
if 'sso' in request.args: # SSO action (SP-SSO initited). Will send an AuthNRequest to the IdP
760760
return redirect(auth.login())
761-
elif 'sso2' in request.args: # Another SSO init action
761+
elif 'sso2' in request.args: # Another SSO init action
762762
return_to = '%sattrs/' % request.host_url # but set a custom RelayState URL
763763
return redirect(auth.login(return_to))
764764
elif 'slo' in request.args: # SLO action. Will sent a Logout Request to IdP
765765
return redirect(auth.logout())
766766
elif 'acs' in request.args: # Assertion Consumer Service
767767
auth.process_response() # Process the Response of the IdP
768768
errors = auth.get_errors() # This method receives an array with the errors
769-
if len(errors) == 0: # that could took place during the process
769+
if len(errors) == 0: # that could took place during the process
770770
if not auth.is_authenticated(): # This check if the response was ok and the user
771771
msg = "Not authenticated" # data retrieved or not (user authenticated)
772772
else:
773773
request.session['samlUserdata'] = auth.get_attributes() # Retrieves user data
774774
self_url = OneLogin_Saml2_Utils.get_self_url(req)
775-
if 'RelayState' in request.form and self_url != request.form['RelayState']:
775+
if 'RelayState' in request.form and self_url != request.form['RelayState']:
776776
return redirect(auth.redirect_to(request.form['RelayState'])) # Redirect if there is a relayState
777777
else: # If there is user data we save that to print it later.
778778
msg = ''
@@ -875,7 +875,7 @@ SAML 2 Logout Response class
875875
* ***get_status*** Gets the Status of the Logout Response.
876876
* ***is_valid*** Determines if the SAML LogoutResponse is valid
877877
* ***build*** Creates a Logout Response object.
878-
* ***get_response*** Returns a Logout Response object.
878+
* ***get_response*** Returns a Logout Response object.
879879
* ***get_error*** After execute a validation process, if fails this method returns the cause.
880880

881881

@@ -915,7 +915,7 @@ Configuration of the OneLogin Python Toolkit
915915

916916
A class that contains functionality related to the metadata of the SP
917917

918-
* ***builder*** Generates the metadata of the SP based on the settings.
918+
* ***builder*** Generates the metadata of the SP based on the settings.
919919
* ***sign_metadata*** Signs the metadata with the key/cert provided.
920920
* ***add_x509_key_descriptors*** Adds the x509 descriptors (sign/encriptation) to the metadata
921921

@@ -1039,7 +1039,7 @@ The flask project contains:
10391039

10401040
####SP setup####
10411041

1042-
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.
1042+
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.
10431043

10441044
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.
10451045

@@ -1079,7 +1079,7 @@ To run the demo you need to install the requirements first. Load your
10791079
virtualenv and execute:
10801080
```
10811081
pip install -r demo-django/requirements.txt
1082-
```
1082+
```
10831083
This will install django and its dependences. Once it has finished, you have to complete the configuration of the toolkit.
10841084

10851085
Later, with the virtualenv loaded, you can run the demo like this:
@@ -1112,9 +1112,9 @@ The django project contains:
11121112

11131113
####SP setup####
11141114

1115-
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.
1115+
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.
11161116

1117-
After set the SAML_FOLDER in the demo/settings.py, the settings of the python toolkit will be loaded on the django web.
1117+
After set the SAML_FOLDER in the demo/settings.py, the settings of the python toolkit will be loaded on the django web.
11181118

11191119
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.
11201120

demo-flask/index.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ def metadata():
121121
resp = make_response(metadata, 200)
122122
resp.headers['Content-Type'] = 'text/xml'
123123
else:
124-
resp = make_response(errors.join(', '), 500)
124+
resp = make_response(', '.join(errors), 500)
125125
return resp
126126

127127

0 commit comments

Comments
 (0)