Skip to content

Commit 45ef435

Browse files
readme
1 parent a630f70 commit 45ef435

File tree

1 file changed

+25
-0
lines changed

1 file changed

+25
-0
lines changed

docs/source/contents/setup.rst

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,31 @@ setting::
214214

215215
SAML_CONFIG_LOADER = 'python.path.to.your.callable'
216216

217+
Bearer Assertion Replay Attack Prevention
218+
==================================
219+
In SAML standard doc, section 4.1.4.5 it states
220+
221+
The service provider MUST ensure that bearer assertions are not replayed, by maintaining the set of used ID values for the length of time for which the assertion would be considered valid based on the NotOnOrAfter attribute in the <SubjectConfirmationData>
222+
223+
djangosaml2 provides a hook 'is_authorized' for the SP to store assertion IDs and implement replay prevention with your choice of storage.
224+
::
225+
226+
def is_authorized(self, attributes: dict, attribute_mapping: dict, idp_entityid: str, assertion: object, **kwargs) -> bool:
227+
if not assertion:
228+
return True
229+
230+
# Get your choice of storage
231+
cache_storage = storage.get_cache()
232+
assertion_id = assertion.get('assertion_id')
233+
234+
if cache.get(assertion_id):
235+
logger.warn("Received SAMLResponse assertion has been already used.")
236+
return False
237+
238+
expiration_time = assertion.get('not_on_or_after')
239+
time_delta = isoparse(expiration_time) - datetime.now(timezone.utc)
240+
cache_storage.set(assertion_id, 'True', ex=time_delta)
241+
return True
217242

218243
Users, attributes and account linking
219244
-------------------------------------

0 commit comments

Comments
 (0)