@@ -138,6 +138,13 @@ For example::
138138
139139 import saml2
140140 SAML_LOGOUT_REQUEST_PREFERRED_BINDING = saml2.BINDING_HTTP_POST
141+
142+ Signed Logout Request
143+ ------------------------
144+ Idp's like Okta require a signed logout response to validate and logout a user. Here's a sample config with all required SP/IDP settings::
145+
146+ "logout_requests_signed": True,
147+
141148
142149Changes in the urls.py file
143150---------------------------
@@ -169,6 +176,75 @@ the path to that file.
169176In djangosaml2 you just put the same information in the Django
170177settings.py file under the SAML_CONFIG option.
171178
179+ Okta settings to configure on your Idp's SAML app advanced settings::
180+
181+ Single Logout URL: http://localhost:8000/saml2/ls/post/
182+ SP Issuer : http://localhost:8000/saml2/metadata/
183+
184+ Okta sample configuration for setting up an Okta SSO with Django::
185+
186+ 'service': {
187+ # we are just a lonely SP
188+ 'sp': {
189+ 'name': 'XXX',
190+ 'allow_unsolicited': True,
191+ 'want_assertions_signed': True, # assertion signing (default=True)
192+ 'want_response_signed': True,
193+ "want_assertions_or_response_signed": True, # is response signing required
194+ 'name_id_format': NAMEID_FORMAT_UNSPECIFIED,
195+
196+ # Must for signed logout requests
197+ "logout_requests_signed": True,
198+ 'endpoints': {
199+ # url and binding to the assetion consumer service view
200+ # do not change the binding or service name
201+ 'assertion_consumer_service': [
202+ ('http://localhost:8000/saml2/acs/',
203+ saml2.BINDING_HTTP_POST),
204+ ],
205+ # url and binding to the single logout service view
206+ # do not change the binding or service name
207+ 'single_logout_service': [
208+ # ('http://localhost:8000/saml2/ls/',
209+ # saml2.BINDING_HTTP_REDIRECT),
210+ ('http://localhost:8000/saml2/ls/post/',
211+ saml2.BINDING_HTTP_POST),
212+ ],
213+ },
214+ # Mandates that the identity provider MUST authenticate the
215+ # presenter directly rather than rely on a previous security context.
216+ 'force_authn': False,
217+
218+ "allow_unsolicited": True,
219+
220+ # Enable AllowCreate in NameIDPolicy.
221+ 'name_id_format_allow_create': False,
222+
223+ # attributes that this project need to identify a user
224+ 'required_attributes': ['email'],
225+
226+ # in this section the list of IdPs we talk to are defined
227+ 'idp': {
228+ # we do not need a WAYF service since there is
229+ # only an IdP defined here. This IdP should be
230+ # present in our metadata
231+
232+ # the keys of this dictionary are entity ids
233+ 'https://xxx.okta.com/app/XXXXXXXXXX/sso/saml/metadata': {
234+ # Okta only uses HTTP_POST disable this
235+ # 'single_sign_on_service': {
236+ # saml2.BINDING_HTTP_REDIRECT: 'https://xxx.okta.com/app/APPNAME/xxxxxxxxx/sso/saml',
237+ # },
238+ 'single_logout_service': {
239+ saml2.BINDING_HTTP_POST: 'https://xxx.okta.com/app/APPNAME/xxxxxxxxxx/slo/saml',
240+ },
241+ },
242+ },
243+
244+ },
245+ },
246+
247+
172248We will see a typical configuration for protecting a Django project::
173249
174250 from os import path
@@ -191,6 +267,10 @@ We will see a typical configuration for protecting a Django project::
191267 'sp' : {
192268 'name': 'Federated Django sample SP',
193269 'name_id_format': saml2.saml.NAMEID_FORMAT_PERSISTENT,
270+
271+ # For Okta add signed logout requets. Enable this:
272+ # "logout_requests_signed": True,
273+
194274 'endpoints': {
195275 # url and binding to the assetion consumer service view
196276 # do not change the binding or service name
@@ -201,6 +281,7 @@ We will see a typical configuration for protecting a Django project::
201281 # url and binding to the single logout service view
202282 # do not change the binding or service name
203283 'single_logout_service': [
284+ # Disable next two lines for HTTP_REDIRECT for IDP's that only support HTTP_POST. Ex. Okta:
204285 ('http://localhost:8000/saml2/ls/',
205286 saml2.BINDING_HTTP_REDIRECT),
206287 ('http://localhost:8000/saml2/ls/post',
0 commit comments