Skip to content

Commit f3db4d0

Browse files
committed
Store NameID as subject_id from authn-requests
The Subject/NameID text value is stored in the internal data structure as subject_id. It can be used to forward an authn-request with the same Subject element. The Subject/NameID format is also available, but it remains to be discussed how it should be handle in relation to the specified (name_id) policy or the metadata settings. Signed-off-by: Ivan Kanakarakis <[email protected]>
1 parent 13e3b5d commit f3db4d0

File tree

3 files changed

+40
-8
lines changed

3 files changed

+40
-8
lines changed

src/satosa/frontends/saml2.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -208,11 +208,14 @@ def _handle_authn_request(self, context, binding_in, idp):
208208
else:
209209
name_format = NAMEID_FORMAT_TRANSIENT
210210

211-
# XXX TODO support nameid on request
212-
# subject = authn_req.subject
213-
# identifier = subject.text if subject else None
211+
subject = authn_req.subject
212+
subject_id = subject.name_id.text if subject else None
213+
# XXX TODO how should type be handled in relation to name_format above?
214+
# subject_type = subject.name_id.format if subject else None
215+
214216
requester_name = self._get_sp_display_name(idp, requester)
215217
internal_req = InternalData(
218+
subject_id=subject_id,
216219
subject_type=name_format,
217220
requester=requester,
218221
requester_name=requester_name,

tests/satosa/frontends/test_saml2.py

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
from saml2.saml import NAMEID_FORMAT_PERSISTENT
1919
from saml2.saml import NAMEID_FORMAT_EMAILADDRESS
2020
from saml2.saml import NAMEID_FORMAT_UNSPECIFIED
21+
from saml2.saml import NameID, Subject
2122
from saml2.samlp import NameIDPolicy
2223

2324
from satosa.attribute_mapping import AttributeMapper
@@ -57,7 +58,8 @@ def construct_base_url_from_entity_id(self, entity_id):
5758
return "{parsed.scheme}://{parsed.netloc}".format(parsed=urlparse(entity_id))
5859

5960
def setup_for_authn_req(self, context, idp_conf, sp_conf, nameid_format=None, relay_state="relay_state",
60-
internal_attributes=INTERNAL_ATTRIBUTES, extra_config={}):
61+
internal_attributes=INTERNAL_ATTRIBUTES, extra_config={},
62+
subject=None):
6163
config = {"idp_config": idp_conf, "endpoints": ENDPOINTS}
6264
config.update(extra_config)
6365
sp_metadata_str = create_metadata_from_config_dict(sp_conf)
@@ -72,7 +74,12 @@ def setup_for_authn_req(self, context, idp_conf, sp_conf, nameid_format=None, re
7274
sp_conf["metadata"]["inline"].append(idp_metadata_str)
7375

7476
fakesp = FakeSP(SPConfig().load(sp_conf, metadata_construction=False))
75-
destination, auth_req = fakesp.make_auth_req(samlfrontend.idp_config["entityid"], nameid_format, relay_state)
77+
destination, auth_req = fakesp.make_auth_req(
78+
samlfrontend.idp_config["entityid"],
79+
nameid_format,
80+
relay_state,
81+
subject=subject,
82+
)
7683
context.request = auth_req
7784
tmp_dict = {}
7885
for val in context.request:
@@ -147,6 +154,18 @@ def test_handle_authn_request(self, context, idp_conf, sp_conf, internal_respons
147154
for key in resp.ava:
148155
assert USERS["testuser1"][key] == resp.ava[key]
149156

157+
def test_create_authn_request_with_subject(self, context, idp_conf, sp_conf, internal_response):
158+
name_id_value = 'somenameid'
159+
name_id = NameID(format=NAMEID_FORMAT_UNSPECIFIED, text=name_id_value)
160+
subject = Subject(name_id=name_id)
161+
samlfrontend = self.setup_for_authn_req(
162+
context, idp_conf, sp_conf, subject=subject
163+
)
164+
_, internal_req = samlfrontend.handle_authn_request(context, BINDING_HTTP_REDIRECT)
165+
assert internal_req.subject_id == name_id_value
166+
# XXX TODO how should type be handled?
167+
# assert internal_req.subject_type == NAMEID_FORMAT_UNSPECIFIED
168+
150169
def test_handle_authn_request_without_name_id_policy_default_to_name_id_format_from_metadata(
151170
self, context, idp_conf, sp_conf):
152171
samlfrontend = self.setup_for_authn_req(context, idp_conf, sp_conf, nameid_format="")

tests/util.py

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,8 @@ def __init__(self, config):
3838
Saml2Client.__init__(self, config)
3939

4040
def make_auth_req(self, entity_id, nameid_format=None, relay_state="relay_state",
41-
request_binding=BINDING_HTTP_REDIRECT, response_binding=BINDING_HTTP_REDIRECT):
41+
request_binding=BINDING_HTTP_REDIRECT, response_binding=BINDING_HTTP_REDIRECT,
42+
subject=None):
4243
"""
4344
:type entity_id: str
4445
:rtype: str
@@ -52,8 +53,17 @@ def make_auth_req(self, entity_id, nameid_format=None, relay_state="relay_state"
5253
[request_binding], 'idpsso',
5354
entity_id=entity_id)
5455

55-
req_id, req = self.create_authn_request(destination,
56-
binding=response_binding, nameid_format=nameid_format)
56+
kwargs = {}
57+
if subject:
58+
kwargs['subject'] = subject
59+
60+
req_id, req = self.create_authn_request(
61+
destination,
62+
binding=response_binding,
63+
nameid_format=nameid_format,
64+
**kwargs
65+
)
66+
5767
ht_args = self.apply_binding(_binding, '%s' % req, destination,
5868
relay_state=relay_state)
5969

0 commit comments

Comments
 (0)