-
Notifications
You must be signed in to change notification settings - Fork 8
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[#375] Add optional strict check to aud
member of introspection endpoint response
#378
Conversation
hmmm....
let's also consider/discuss...
and it occurs to me... is it just the presence of the
|
And to dog-pile onto that... are there other members which we might want to make required? In addition to Maybe this is a naive suggestion, so please shoot down as appropriate. |
Yes, more naming suggestions please!
While this was lower down, going to group with the rest up here. Quick wording suggestion (JSON vs. JWT): - require_aud_claim_from_introspection_endpoint
+ require_aud_member_from_introspection_endpoint
In this PR for the introspection endpoint, by requiring the The checks we do are as follows: irods_client_http_api/core/src/openid.cpp Lines 133 to 157 in 3824a09
Don't think this name is a good fit. While the introspection endpoint does use an access token, we should narrow the name to the endpoint. It may be confusing, as it implies we don't require The standard for the introspection endpoint and the standard for JWT Access Tokens (and ID Tokens) are different. Both the JWT Access Tokens and the ID Tokens are required to have an |
See the "Additional context for the Introspection Endpoint" in my response: #375 (comment) This might be relevant too, not sure: #358 (comment) I'm not too sure we should make the other fields "opt-in require". The authorization server should be doing these checks. Requiring these would mean you need to make sure these members are returned. This means you would need to change the server configuration appropriately. Partial quote of myself from the issue:
|
Thanks everybody for looking into this.
and a successive call to the token introspection endpoint. Clearly, if an access token does not present an aud claim, then the token introspection json response will follow suit.
If this is the case, I am not sure that adding a new configuration parameter (
In my opinion, if the decision taken is the addition of this extra configuration parameter, I would rather choose for a generic
and apply it to both the local JWT validation and the introspection json response. This would make the story more consistent, but it is just an idea. PS: keycloak offers huge flexibility with aud claims. It is possible to exclude an aud claim altogether (not setting it up), add it only to access tokens, to both access tokens and json introspection responses, or to add it only to json introspection responses. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
From discussion in standup.
Yes, the HTTP API does fall through to using the introspection endpoint if local validation fails. Perhaps this should be changed too? See #380.
While it may make the story more consistent to have a generic If there is interest in having strict enforcement of this member, then it may make sense to have strict enforcement of the other members (see #381). Later on, these options may be enforced by default.
This seems like a test case we should include, thank you for letting us know. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
looks pretty good. a few kory comments still in here too.
awaiting another response from @ll4strw
It is fine for me. Thanks |
Please rebase your work on top of the main branch. No squashing. All review comments have been resolved. What's left for this PR other than testing? |
Ignore the rebase comment. |
It should just be testing at this point. |
Ok. Will wait for your signal that testing is complete and working. |
What's the status of this PR? |
Need to wrap up tests, should be done by today. |
Writing down jic for automation later. Other default cases where Option is present and strict checking is enabledJWT Access Token: $ echo "${token}" | jwt decode -
Token header
------------
{
"typ": "JWT",
"alg": "HS512",
"kid": "fad9b835-e899-4195-8203-86075fc06006"
}
Token claims
------------
{
"acr": "0",
"allowed-origins": [
"*"
],
"auth_time": 1734030516,
"azp": "other_web",
"email": "[email protected]",
"email_verified": true,
"exp": 1734030890,
"family_name": "NotAlice",
"given_name": "Bob",
"iat": 1734030590,
"irods_username": "rods",
"iss": "http://172.18.0.4:8080/realms/example",
"jti": "a38ef820-c8fb-41ab-a8c4-02c262137a5e",
"name": "Bob NotAlice",
"nonce": "C7QFUrSHw90xtP6p0Xrw",
"preferred_username": "bob",
"scope": "openid email irods profile",
"session_state": "e5b913fe-122a-47ce-ae8f-dbba7de20f78",
"sid": "e5b913fe-122a-47ce-ae8f-dbba7de20f78",
"sub": "687e72a5-4813-44dc-95c3-84329c406ff5",
"typ": "Bearer"
}
Logs: ...
[2024-12-12 19:11:48.186] [P:38431] [debug] [T:38453] hit_introspection_endpoint: Received the following response: [{"exp":1734030890,"iat":1734030590,"auth_time":1734030516,"jti":"a38ef820-c8fb-41ab-a8c4-02c262137a5e","iss":"http://172.18.0.4:8080/realms/example","sub":"687e72a5-4813-44dc-95c3-84329c406ff5","typ":"Bearer","azp":"other_web","nonce":"C7QFUrSHw90xtP6p0Xrw","session_state":"e5b913fe-122a-47ce-ae8f-dbba7de20f78","acr":"0","allowed-origins":["*"],"scope":"openid email irods profile","sid":"e5b913fe-122a-47ce-ae8f-dbba7de20f78","email_verified":true,"name":"Bob NotAlice","irods_username":"rods","preferred_username":"bob","given_name":"Bob","family_name":"NotAlice","email":"[email protected]","client_id":"other_web","username":"bob","token_type":"Bearer","active":true}]
[2024-12-12 19:11:48.186] [P:38431] [warning] [T:38453] validate_using_introspection_endpoint: Bearer token payload is missing [aud]. Validation failed.
... Option is present and strict checking is disabledJWT Access Token: Token header
------------
{
"typ": "JWT",
"alg": "HS512",
"kid": "fad9b835-e899-4195-8203-86075fc06006"
}
Token claims
------------
{
"acr": "0",
"allowed-origins": [
"*"
],
"auth_time": 1734030516,
"azp": "other_web",
"email": "[email protected]",
"email_verified": true,
"exp": 1734031365,
"family_name": "NotAlice",
"given_name": "Bob",
"iat": 1734031065,
"irods_username": "rods",
"iss": "http://172.18.0.4:8080/realms/example",
"jti": "b86c529b-44ab-4c7c-af5c-af4465b76893",
"name": "Bob NotAlice",
"nonce": "vxIw6c4EE1pWSgFBQrOL",
"preferred_username": "bob",
"scope": "openid email irods profile",
"session_state": "e5b913fe-122a-47ce-ae8f-dbba7de20f78",
"sid": "e5b913fe-122a-47ce-ae8f-dbba7de20f78",
"sub": "687e72a5-4813-44dc-95c3-84329c406ff5",
"typ": "Bearer"
} Logs: ...
[2024-12-12 19:18:58.899] [P:38678] [debug] [T:38699] hit_introspection_endpoint: Received the following response: [{"exp":1734031365,"iat":1734031065,"auth_time":1734030516,"jti":"b86c529b-44ab-4c7c-af5c-af4465b76893","iss":"http://172.18.0.4:8080/realms/example","sub":"687e72a5-4813-44dc-95c3-84329c406ff5","typ":"Bearer","azp":"other_web","nonce":"vxIw6c4EE1pWSgFBQrOL","session_state":"e5b913fe-122a-47ce-ae8f-dbba7de20f78","acr":"0","allowed-origins":["*"],"scope":"openid email irods profile","sid":"e5b913fe-122a-47ce-ae8f-dbba7de20f78","email_verified":true,"name":"Bob NotAlice","irods_username":"rods","preferred_username":"bob","given_name":"Bob","family_name":"NotAlice","email":"[email protected]","client_id":"other_web","username":"bob","token_type":"Bearer","active":true}]
[2024-12-12 19:18:58.899] [P:38678] [trace] [T:38699] validate_using_introspection_endpoint: Attempting [iss] validation.
[2024-12-12 19:18:58.899] [P:38678] [debug] [T:38699] user_mapper_match: Attempting match of _param [{"acr":"0","active":true,"allowed-origins":["*"],"auth_time":1734030516,"azp":"other_web","client_id":"other_web","email":"[email protected]","email_verified":true,"exp":1734031365,"family_name":"NotAlice","given_name":"Bob","iat":1734031065,"irods_username":"rods","iss":"http://172.18.0.4:8080/realms/example","jti":"b86c529b-44ab-4c7c-af5c-af4465b76893","name":"Bob NotAlice","nonce":"vxIw6c4EE1pWSgFBQrOL","preferred_username":"bob","scope":"openid email irods profile","session_state":"e5b913fe-122a-47ce-ae8f-dbba7de20f78","sid":"e5b913fe-122a-47ce-ae8f-dbba7de20f78","sub":"687e72a5-4813-44dc-95c3-84329c406ff5","token_type":"Bearer","typ":"Bearer","username":"bob"}].
... Using default schema, Option is not present$ irods_http_api config.json
Validating configuration file ...
No JSON schema file provided. Using default.
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "/usr/lib/python3/dist-packages/jsonschema/validators.py", line 934, in validate
raise error
jsonschema.exceptions.ValidationError: 'require_aud_member_from_introspection_endpoint' is a required property
Failed validating 'required' in schema['properties']['http_server']['properties']['authentication']['properties']['openid_connect']:
{'anyOf': [{'not': {'properties': {'mode': {'const': 'protected_resource'}}}},
{'required': ['client_secret']}],
'properties': {'access_token_secret': {'type': 'string'},
'client_id': {'type': 'string'},
'client_secret': {'type': 'string'},
'mode': {'enum': ['client', 'protected_resource']},
'nonstandard_id_token_secret': {'type': 'string'},
'provider_url': {'format': 'uri', 'type': 'string'},
'redirect_uri': {'format': 'uri', 'type': 'string'},
'require_aud_member_from_introspection_endpoint': {'type': 'boolean'},
'state_timeout_in_seconds': {'minimum': 1,
'type': 'integer'},
'timeout_in_seconds': {'minimum': 1, 'type': 'integer'},
'tls_certificates_directory': {'type': 'string'},
'user_mapping': {'properties': {'configuration': {'type': 'object'},
'plugin_path': {'type': 'string'}},
'required': ['plugin_path',
'configuration'],
'type': 'object'}},
'required': ['timeout_in_seconds',
'state_timeout_in_seconds',
'provider_url',
'mode',
'client_id',
'require_aud_member_from_introspection_endpoint',
'redirect_uri',
'tls_certificates_directory',
'user_mapping'],
'type': 'object'}
On instance['http_server']['authentication']['openid_connect']:
{'client_id': 'irods_http_api',
'client_secret': '**********',
'mode': 'protected_resource',
'provider_url': 'http://172.18.0.4:8080/realms/example',
'redirect_uri': 'http://172.18.0.3:9000/irods-http-api/0.5.0/authenticate',
'state_timeout_in_seconds': 3600,
'timeout_in_seconds': 3600,
'tls_certificates_directory': '/etc/ssl/certs',
'user_mapping': {'configuration': {'file_path': '/u.json'},
'plugin_path': '/usr/lib/irods_http_api/plugins/user_mapping/libirods_http_api_plugin-local_file.so'}}
Configuration failed validation. Using empty schema, Option is not presentJWT: $ echo "${token}" | jwt decode -
Token header
------------
{
"typ": "JWT",
"alg": "HS512",
"kid": "fad9b835-e899-4195-8203-86075fc06006"
}
Token claims
------------
{
"acr": "1",
"allowed-origins": [
"*"
],
"auth_time": 1734032122,
"azp": "other_web",
"email": "[email protected]",
"email_verified": true,
"exp": 1734032422,
"family_name": "NotAlice",
"given_name": "Bob",
"iat": 1734032122,
"irods_username": "rods",
"iss": "http://172.18.0.4:8080/realms/example",
"jti": "547fe2a4-9c3f-4bab-ba2d-6b3b682b343f",
"name": "Bob NotAlice",
"nonce": "LITJVT35t3vuOprhU42a",
"preferred_username": "bob",
"scope": "openid email irods profile",
"session_state": "ece96ad4-f262-4f4d-bee9-6e4d4f9d2ee9",
"sid": "ece96ad4-f262-4f4d-bee9-6e4d4f9d2ee9",
"sub": "687e72a5-4813-44dc-95c3-84329c406ff5",
"typ": "Bearer"
} Logs: ...
[2024-12-12 19:36:22.908] [P:39026] [debug] [T:39048] hit_introspection_endpoint: Received the following response: [{"exp":1734032422,"iat":1734032122,"auth_time":1734032122,"jti":"547fe2a4-9c3f-4bab-ba2d-6b3b682b343f","iss":"http://172.18.0.4:8080/realms/example","sub":"687e72a5-4813-44dc-95c3-84329c406ff5","typ":"Bearer","azp":"other_web","nonce":"LITJVT35t3vuOprhU42a","session_state":"ece96ad4-f262-4f4d-bee9-6e4d4f9d2ee9","acr":"1","allowed-origins":["*"],"scope":"openid email irods profile","sid":"ece96ad4-f262-4f4d-bee9-6e4d4f9d2ee9","email_verified":true,"name":"Bob NotAlice","irods_username":"rods","preferred_username":"bob","given_name":"Bob","family_name":"NotAlice","email":"[email protected]","client_id":"other_web","username":"bob","token_type":"Bearer","active":true}]
[2024-12-12 19:36:22.908] [P:39026] [trace] [T:39048] validate_using_introspection_endpoint: Attempting [iss] validation.
[2024-12-12 19:36:22.908] [P:39026] [debug] [T:39048] user_mapper_match: Attempting match of _param [{"acr":"1","active":true,"allowed-origins":["*"],"auth_time":1734032122,"azp":"other_web","client_id":"other_web","email":"[email protected]","email_verified":true,"exp":1734032422,"family_name":"NotAlice","given_name":"Bob","iat":1734032122,"irods_username":"rods","iss":"http://172.18.0.4:8080/realms/example","jti":"547fe2a4-9c3f-4bab-ba2d-6b3b682b343f","name":"Bob NotAlice","nonce":"LITJVT35t3vuOprhU42a","preferred_username":"bob","scope":"openid email irods profile","session_state":"ece96ad4-f262-4f4d-bee9-6e4d4f9d2ee9","sid":"ece96ad4-f262-4f4d-bee9-6e4d4f9d2ee9","sub":"687e72a5-4813-44dc-95c3-84329c406ff5","token_type":"Bearer","typ":"Bearer","username":"bob"}].
... |
Behaves as expected, all tests passed. |
Open an issue to automate this later. It can link to the comment. Add some context to the issue so we know what it's about. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pound it.
Wait, squash to taste. No pounds. |
6eafe1a
to
eb6511e
Compare
Squashed. |
Add some words to the body of the commit message so developers have some idea as to why this work was done. I take it we're all set to merge @ll4strw's PR? |
Yep, all set. Will add words to this commit shortly. |
eb6511e
to
283b8a2
Compare
More words added. |
Good. Next steps are:
Sound good? |
Sounds good. |
#376 has been merged. Please rebase on top of main. |
283b8a2
to
aba4b76
Compare
Rebased. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pound it!
This commit makes the strict `aud` check for the introspection endpoint optional. This is due to the fact that some OpenID Providers may be configured to not provide an `aud` in the endpoint response, even if the given access token contains the information. Additionally, documentation of this feature is added, along with relevant schema checks.
aba4b76
to
b060106
Compare
Pounded. |
Merging. |
This has the changes made from #376, with the suggestions of that PR applied in this PR.