-
Notifications
You must be signed in to change notification settings - Fork 112
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
LG-7434: Allow cross origin for POST OIDC Logout #10697
LG-7434: Allow cross origin for POST OIDC Logout #10697
Conversation
Context: the original implementation of this did not handle the CSRF logic correctly, this fixes that. |
if result.success? && redirect_uri | ||
apply_logout_secure_headers_override(redirect_uri, @logout_form.service_provider) | ||
if require_logout_confirmation? | ||
handle_successful_logout_request(result, redirect_uri, status: :temporary_redirect) |
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.
I see that the status: :temporary_redirect
is to preserve the method and body of the request, but what makes that necessary?
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.
In effect, when testing with 302
(the default response for POST
and PUT
requests) and 303
, I found Chrome (in particular) would cache the action chosen on the logout confirmation page, so subsequent logout requests would convert the request to a GET
of the redirect URI, skipping the confirmation page altogether sometimes, which we don't want.
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.
My understanding is we always want a GET for the redirect back, the POST support is only needed for the incoming request from SPs.
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.
The subsequent GET
request of the redirect URI always happens, but do we always want to let the browser skip the confirmation page if the user selected a particular option previously?
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.
Updated this to not use a different status code. The routing behavior I described was misinformed by a previous implementation that used match
to send both POST
and GET
to the same action.
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.
@zachmargolis - we would probably need either a new event field (i.e., original_method
) or a new event type that could be logged in the #create
action. As far as I can see in my local logs, we don't populate event_properties.method
in the analytics event.
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.
New event field makes sense to me!
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.
We'd still have the generic web request logs and I don't know if those are bundled into analytics some other way.
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.
those are a separate log file (production.log
) which doesn't always have SP available, so if we want to analyze HTTP method in events.log
(by SP it sounds like), then we need to augment analytics events
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.
Added the new field. method
and original_method
only get populated for the OIDC Logout Requested
event.
GET
only:
{
"name": "OIDC Logout Requested",
"properties": {
"event_properties": {
"success": true,
"client_id": "urn:gov:gsa:openidconnect:sp:sinatra",
"client_id_parameter_present": true,
"id_token_hint_parameter_present": false,
"errors": {},
"error_details": null,
"sp_initiated": true,
"oidc": true,
"saml_request_valid": null,
"method": "GET",
"original_method": null
},
"new_event": true,
"path": "/openid_connect/logout",
"session_duration": 20.555755
// ...
},
// ...
"log_filename": "events.log"
}
POST
redirected to GET
:
{
"name": "OIDC Logout Requested",
"properties": {
"event_properties": {
"success": true,
"client_id": "urn:gov:gsa:openidconnect:sp:sinatra",
"client_id_parameter_present": true,
"id_token_hint_parameter_present": false,
"errors": {},
"error_details": null,
"sp_initiated": true,
"oidc": true,
"saml_request_valid": null,
"method": "GET",
"original_method": "POST"
},
"new_event": false,
"path": "/openid_connect/logout",
"session_duration": 781.444997,
// ...
},
// ...
"log_filename": "events.log"
}
a0e2fb9
to
02a8de6
Compare
e2be881
to
19966cb
Compare
Converting to draft since the analytics changes have broken the tests. |
**Why**: - It is expected that requests will be made by relying parties on external domains - The specification for OpenID Connect RP-Initiated Logout 1.0 requires both HTTP `GET` and `POST` methods to be supported. See: https://openid.net/specs/openid-connect-rpinitiated-1_0.html#RPLogout - Data sent using the `POST` method remains encrypted during transport in the browser and in web application logs, preventing leakage of sensitive information **How**: - The same endpoint shall be used, `/openid_connect/logout`, but the request data must be sent as part of the body and use form serialization as required for HTTP `POST` requests (RFC 9110, sec. 9.3.3). - Disables Rail's CSRF token verification for the POST route only resolves https://gitlab.login.gov/lg-people/lg-people-appdev/protocols/openid-connect/-/issues/3 changelog: Bug Fixes, Security, Fix CORS stopping POST for OIDC RP-Initiated Logout 1.0
…ACHE_MISS on navigation
fe13ea9
to
1844136
Compare
Fixing the tests was pretty straightforward. This is ready for review again. |
* LG-7434: Allow cross origin for POST OIDC Logout **Why**: - It is expected that requests will be made by relying parties on external domains - The specification for OpenID Connect RP-Initiated Logout 1.0 requires both HTTP `GET` and `POST` methods to be supported. See: https://openid.net/specs/openid-connect-rpinitiated-1_0.html#RPLogout **How**: - The same OpenID Provider endpoint shall be used, `/openid_connect/logout`, but the request data must be sent as part of the body and use form serialization as required for HTTP `POST` requests (RFC 9110, sec. 9.3.3). - Disables Rail's CSRF token verification for the POST route only - `POST` requests will redirect to the `GET` endpoint on the OpenID Provider's API for consistent behavior and handling. resolves https://gitlab.login.gov/lg-people/lg-people-appdev/protocols/openid-connect/-/issues/3 changelog: Bug Fixes, Security, Fix CORS stopping POST for OIDC RP-Initiated Logout 1.0
🎫 Ticket
Link to the relevant ticket:
LG-7434: Add support for POST OIDC logout requests (this ticket has been superseded by this GitLab issue).
🛠 Summary of changes
GET
andPOST
POST
route redirects to theGET
route for better UX when using browser navigationoriginal_method
to capture redirected method forOIDC Logout Requested
event. See LG-7434: Allow cross origin for POST OIDC Logout #10697 (comment) for details📜 Testing Plan
Requires:
identity-idp
app to havereject_id_token_hint_in_logout: true
inapplication.yml
OR the partner app must not send anid_token_hint
Steps
Sign out
Do you want to sign out of Login.gov?
, ensure you are redirected to the sample app home page (or other configured redirect URI).Why:
It is expected that requests will be made by relying parties on verified external domains
The specification for OpenID Connect RP-Initiated Logout 1.0 requires both HTTP
GET
andPOST
methods to be supported. See: https://openid.net/specs/openid-connect-rpinitiated-1_0.html#RPLogoutData sent using the
POST
method remains encrypted during transport in the browser and in web application logs, preventing leakage of sensitive informationHow:
The same endpoint shall be used,
/openid_connect/logout
, but the request data must be sent as part of the body and use form serialization as required for HTTPPOST
requests (RFC 9110, sec. 9.3.3).Disables Rail's CSRF token verification for the POST route only
resolves https://gitlab.login.gov/lg-people/lg-people-appdev/protocols/backlog-fy24/-/issues/20
changelog: Bug Fixes, Security, Fix CORS stopping POST for OIDC RP-Initiated Logout 1.0