Skip to content
This repository was archived by the owner on Jun 23, 2023. It is now read-only.

Commit a2b1353

Browse files
authored
Merge pull request #104 from IdentityPython/acr_claim
acr value in claims parameter was not treated correctly.
2 parents c46919f + 64c4b56 commit a2b1353

2 files changed

Lines changed: 188 additions & 3 deletions

File tree

src/oidcop/user_authn/authn_context.py

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,19 @@ def default(self):
108108
return None
109109

110110

111+
def _acr_claim(request):
112+
_claims = request.get("claims")
113+
if _claims:
114+
_id_token_claim = _claims.get("id_token")
115+
if _id_token_claim:
116+
_acr = _id_token_claim.get("acr")
117+
if 'value' in _acr:
118+
return [_acr["value"]]
119+
elif 'values' in _acr:
120+
return _acr["values"]
121+
return None
122+
123+
111124
def pick_auth(endpoint_context, areq, pick_all=False):
112125
"""
113126
Pick authentication method
@@ -125,9 +138,8 @@ def pick_auth(endpoint_context, areq, pick_all=False):
125138
acrs = areq["acr_values"]
126139

127140
else:
128-
try:
129-
acrs = areq["claims"]["id_token"]["acr"]["values"]
130-
except KeyError:
141+
acrs = _acr_claim(areq)
142+
if not acrs:
131143
_ith = verified_claim_name("id_token_hint")
132144
if areq.get(_ith):
133145
_ith = areq[verified_claim_name("id_token_hint")]

tests/test_24_oidc_authorization_endpoint.py

Lines changed: 173 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
from urllib.parse import parse_qs
55
from urllib.parse import urlparse
66

7+
from cryptojwt.jws.jws import factory
8+
79
from oidcop.configure import OPConfiguration
810
import pytest
911
import responses
@@ -990,6 +992,177 @@ def test_do_request_user(self):
990992
# With login_hint and login_hint_lookup
991993
assert self.endpoint.do_request_user(request) == {"req_user": "diana"}
992994

995+
class TestACR(object):
996+
@pytest.fixture(autouse=True)
997+
def create_endpoint(self):
998+
conf = {
999+
"issuer": "https://example.com/",
1000+
"password": "mycket hemligt zebra",
1001+
"verify_ssl": False,
1002+
"capabilities": CAPABILITIES,
1003+
"keys": {"uri_path": "static/jwks.json", "key_defs": KEYDEFS},
1004+
"token_handler_args": {
1005+
"jwks_file": "private/token_jwks.json",
1006+
"code": {"kwargs": {"lifetime": 600}},
1007+
"token": {
1008+
"class": "oidcop.token.jwt_token.JWTToken",
1009+
"kwargs": {
1010+
"lifetime": 3600,
1011+
"add_claims_by_scope": True,
1012+
"aud": ["https://example.org/appl"],
1013+
},
1014+
},
1015+
"refresh": {
1016+
"class": "oidcop.token.jwt_token.JWTToken",
1017+
"kwargs": {"lifetime": 3600, "aud": ["https://example.org/appl"], },
1018+
},
1019+
"id_token": {
1020+
"class": "oidcop.token.id_token.IDToken",
1021+
"kwargs": {
1022+
"base_claims": {
1023+
"email": {"essential": True},
1024+
"email_verified": {"essential": True},
1025+
"given_name": {"essential": True},
1026+
"nickname": None,
1027+
}
1028+
},
1029+
},
1030+
},
1031+
"endpoint": {
1032+
"provider_config": {
1033+
"path": "{}/.well-known/openid-configuration",
1034+
"class": ProviderConfiguration,
1035+
"kwargs": {},
1036+
},
1037+
"registration": {"path": "{}/registration", "class": Registration,
1038+
"kwargs": {}, },
1039+
"authorization": {
1040+
"path": "{}/authorization",
1041+
"class": Authorization,
1042+
"kwargs": {
1043+
"response_types_supported": [" ".join(x) for x in
1044+
RESPONSE_TYPES_SUPPORTED],
1045+
"response_modes_supported": ["query", "fragment", "form_post"],
1046+
"claims_parameter_supported": True,
1047+
"request_parameter_supported": True,
1048+
"request_uri_parameter_supported": True,
1049+
},
1050+
},
1051+
"token": {
1052+
"path": "token",
1053+
"class": Token,
1054+
"kwargs": {
1055+
"client_authn_method": [
1056+
"client_secret_post",
1057+
"client_secret_basic",
1058+
"client_secret_jwt",
1059+
"private_key_jwt",
1060+
]
1061+
},
1062+
},
1063+
"userinfo": {
1064+
"path": "userinfo",
1065+
"class": userinfo.UserInfo,
1066+
"kwargs": {
1067+
"db_file": "users.json",
1068+
"claim_types_supported": ["normal", "aggregated", "distributed", ],
1069+
},
1070+
},
1071+
},
1072+
"authentication": {
1073+
"anon": {
1074+
"acr": "http://www.swamid.se/policy/assurance/al1",
1075+
"class": "oidcop.user_authn.user.NoAuthn",
1076+
"kwargs": {"user": "diana"},
1077+
},
1078+
"mfa": {
1079+
"acr": "https://refeds.org/profile/mfa",
1080+
"class": "oidcop.user_authn.user.NoAuthn",
1081+
"kwargs": {"user": "diana"},
1082+
}
1083+
},
1084+
"userinfo": {"class": UserInfo, "kwargs": {"db": USERINFO_db}},
1085+
"template_dir": "template",
1086+
"authz": {
1087+
"class": AuthzHandling,
1088+
"kwargs": {
1089+
"grant_config": {
1090+
"usage_rules": {
1091+
"authorization_code": {
1092+
"supports_minting": ["access_token", "refresh_token",
1093+
"id_token", ],
1094+
"max_usage": 1,
1095+
},
1096+
"access_token": {},
1097+
"refresh_token": {
1098+
"supports_minting": ["access_token", "refresh_token"],
1099+
},
1100+
},
1101+
"expires_in": 43200,
1102+
}
1103+
},
1104+
},
1105+
"cookie_handler": {
1106+
"class": CookieHandler,
1107+
"kwargs": {
1108+
"sign_key": "ghsNKDDLshZTPn974nOsIGhedULrsqnsGoBFBLwUKuJhE2ch",
1109+
"name": {
1110+
"session": "oidc_op",
1111+
"register": "oidc_op_reg",
1112+
"session_management": "oidc_op_sman",
1113+
},
1114+
},
1115+
},
1116+
"login_hint2acrs": {
1117+
"class": LoginHint2Acrs,
1118+
"kwargs": {"scheme_map": {"email": [INTERNETPROTOCOLPASSWORD]}},
1119+
},
1120+
}
1121+
server = Server(OPConfiguration(conf=conf, base_path=BASEDIR), cwd=BASEDIR)
1122+
1123+
endpoint_context = server.endpoint_context
1124+
1125+
_clients = yaml.safe_load(io.StringIO(client_yaml))
1126+
endpoint_context.cdb = _clients["oidc_clients"]
1127+
endpoint_context.keyjar.import_jwks(
1128+
endpoint_context.keyjar.export_jwks(True, ""), conf["issuer"]
1129+
)
1130+
self.endpoint = server.server_get("endpoint", "authorization")
1131+
self.session_manager = endpoint_context.session_manager
1132+
self.user_id = "diana"
1133+
1134+
self.rp_keyjar = KeyJar()
1135+
self.rp_keyjar.add_symmetric("client_1", "hemligtkodord1234567890")
1136+
endpoint_context.keyjar.add_symmetric("client_1", "hemligtkodord1234567890")
1137+
1138+
def test_setup_acr_claim(self):
1139+
request = AuthorizationRequest(
1140+
client_id="client_1",
1141+
redirect_uri="https://example.com/cb",
1142+
response_type=["id_token"],
1143+
state="state",
1144+
nonce="nonce",
1145+
scope="openid",
1146+
claims={"id_token": {"acr": {"value": "https://refeds.org/profile/mfa"}}}
1147+
)
1148+
1149+
redirect_uri = request["redirect_uri"]
1150+
_context = self.endpoint.server_get("endpoint_context")
1151+
cinfo = _context.cdb["client_1"]
1152+
1153+
res = self.endpoint.setup_auth(request, redirect_uri, cinfo, None)
1154+
_session_info = self.session_manager.get_session_info(session_id=res["session_id"],
1155+
grant=True)
1156+
_grant = _session_info["grant"]
1157+
assert _grant.authentication_event["authn_info"] == "https://refeds.org/profile/mfa"
1158+
1159+
id_token = self.endpoint.mint_token("id_token", _grant, res["session_id"])
1160+
assert id_token
1161+
_jws = factory(id_token.value)
1162+
_payload = _jws.jwt.payload()
1163+
assert 'acr' in _payload
1164+
assert _payload["acr"] == "https://refeds.org/profile/mfa"
1165+
9931166

9941167
def test_authn_args_gather_message():
9951168
request = AuthorizationRequest(

0 commit comments

Comments
 (0)