Skip to content
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

9531 - Add a Log Out endpoint available when the session API auth feature flag is enabled #9533

Merged
merged 5 commits into from
May 10, 2023

Conversation

GPortas
Copy link
Contributor

@GPortas GPortas commented Apr 18, 2023

What this PR does / why we need it

New Log Out endpoint

Only available when the Session Auth feature flag is enabled

Initially, to emulate the JSF Log Out feature in the SPA, we considered the option of removing the JSESSIONID session cookie from the React application code, by accessing the browser cookies using a cookie management library. This solution would have the trade-off of not terminating the session in the backend, as JSF does when clicking log out, but considering the temporary lifetime of the session based API authentication, and that it will be executed on a closed and small beta testing environment, we did not find it a bad solution.

The problem with the previous solution and what makes it unfeasible is that the JSESSIONID cookie is HttpOnly, which means that it cannot be read or managed from javascript code. This has forced us to have to enable an endpoint to perform the Log Out.

Although the endpoint is publicly exposed, it only works when the feature flag is enabled, returning a server error otherwise. When the API evolves towards the final authentication mechanism, the logic of this endpoint will be modified to make it standard for all authentication mechanisms subject to Log Out (API Key is not subject to Log Out).

Which issue(s) this PR closes

Special notes for your reviewer

This PR is part of an end-to-end flow that covers three PRs from three different repositories:

Suggestions on how to test this

Feature flag disabled curl test

  1. Deploy Dataverse with this branch without modifying the MicroProfile Config properties
  2. Once deployed, log in and get the associated session cookie from the browser
  3. Try to log out from the API by sending the cookie manually curl --cookie "JSESSIONID=<YOUR_COOKIE>" -X POST http://localhost:8080/api/v1/logout
  4. The operation should return an error indicating that the feature flag is disabled

Feature flag enabled curl test

  1. Enable the feature flag: dataverse.feature.api-session-auth=true
  2. Re-deploy Dataverse
  3. Once deployed, log in and get the associated session cookie from the browser
  4. Try to log out from the API by sending the cookie manually curl --cookie "JSESSIONID=<YOUR_COOKIE>" -X POST http://localhost:8080/api/v1/logout
  5. The operation should indicate that the user is logged out.
  6. Refresh JSF page, and check that the user is logged out.

Real end-to-end test

Test the end-to-end flow following the frontend repository PR instructions:

Does this PR introduce a user interface change? If mockups are available, please link/include them here

No

Is there a release notes update needed for this change?

Not sure

Additional documentation

@GPortas GPortas self-assigned this Apr 18, 2023
@GPortas GPortas marked this pull request as ready for review April 24, 2023 14:57
@GPortas GPortas removed their assignment Apr 24, 2023
@GPortas GPortas changed the title 9531 - Adds new CORS headers and frontend URL config for the session API auth feature flag 9531 - Add new CORS headers and frontend URL config for the session API auth feature flag and Log Out endpoint Apr 24, 2023
@pdurbin pdurbin self-assigned this Apr 25, 2023
Copy link
Member

@pdurbin pdurbin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have questions. Here's some initial feedback.

}
else {
((HttpServletResponse) sr1).addHeader(accessControlAllowOriginHeader, "*");
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we keep...

((HttpServletResponse) sr1).addHeader("Access-Control-Allow-Origin", "*");

... everywhere instead of changing it from * to frontendOrigin in some cases? I fear something will break.

:AllowCors is "true" by default, which means * - https://guides.dataverse.org/en/5.13/installation/config.html#allowcors

I'm wondering if we can do something like this (untested) instead:

if (settingsSvc.isTrueForKey(SettingsServiceBean.Key.AllowCors, true )) {
    ((HttpServletResponse) sr1).addHeader("Access-Control-Allow-Credentials", "*");
    ((HttpServletResponse) sr1).addHeader("Access-Control-Allow-Methods", "PUT, GET, POST, DELETE, OPTIONS");
    ((HttpServletResponse) sr1).addHeader("Access-Control-Allow-Headers", "Accept, Content-Type, X-Dataverse-Key, Range");
    ((HttpServletResponse) sr1).addHeader("Access-Control-Expose-Headers", "Accept-Ranges, Content-Range, Content-Encoding");
}
if (FeatureFlags.API_SESSION_AUTH.enabled()) {
    ((HttpServletResponse) sr1).addHeader("Access-Control-Allow-Credentials", "true");
}

Now that I look at the PR description, I see this:

"On the other hand, a specific URL value for "Access-Control-Allow-Origin" is established (Loaded from a MicroProfile property), replacing the wildcard "*", which is not supported when Access-Control-Allow-Credentials is enabled."

So I guess it was done this way for a reason. I still worry something will break though, since * is the out of the box default. 🤔

The new header really doesn't work with *?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FWIW: Here's the discussion about CORS on the bucket for previewers to use direct download: https://github.com/gdcc/dataverse-previewers/wiki/Using-Previewers-with-download-redirects-from-S3 . For the buckets, we found that dropping AllowedOrigin from '*' causes trouble - https://github.com/gdcc/dataverse-previewers/wiki/Using-Previewers-with-download-redirects-from-S3#if-you-are-interested-in-restricting-the-allowedorigins-and-allowedheaders is as far as I got towards a solution.

The previewer info may be out of date or irrelevant but I'd ask/say:

  • do you need to worry about bucket rules as well?
  • if the change is on all the time, please check to see that hosted previewers work with your fix, and
  • if you find a better solution, perhaps we can update the previewer docs as well.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, remote previewers need CORS. I started a Slack thread to discuss this further: https://iqss.slack.com/archives/C04EE66HW2Y/p1682524744005719

Comment on lines 110 to 111
SCOPE_FRONTEND(PREFIX, "frontend"),
FRONTEND_URL(SCOPE_FRONTEND, "url"),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Question: is it necessary to create another scope and do you expect more settings to be added here? From the docs and descriptions I understand this URL is only used for CORS so far, so maybe we could move this to the API scope?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this setting be front-end-specific at all? If someone creates another client, would this need to be more than one url? I.e. should this be named something like ALLOWED_CORS_ORIGINS with a value that is a list of urls, defaulting perhaps to just the front end url?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This sounds reasonable (and is easy to apprehend with the lookup function, just give it the String[].class as parameter...)

Should this include migrating :AllowCors to a or this JvmSetting? The list could default to "*" as was discussed above. (And probably there is no need for backward compatibility for a DB setting that defaulted to true.)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@qqmyers I prefer to make it front-end specific, just for the Dataverse Frontend SPA. Making it configurable using that list of allowed origins may end up with someone turning on the feature flag to add their own clients and authenticate them via session cookie, while the only intended use case for the feature flag is SPA development. Remember the security risks and the temporary lifetime of the feature flag (It will be removed when we have a final auth mechanism).

@poikilotherm Personally I have no preference in one scope or another. I can move it to the API scope if it is clearer in that way. Ideally, I would have liked to add it to the same scope as the feature flag, because they depend on each other. But the current feature flag mechanism does not support that kind of "subproperties" (If I am not wrong.)

@GPortas GPortas changed the title 9531 - Add new CORS headers and frontend URL config for the session API auth feature flag and Log Out endpoint 9531 - Add a Log Out endpoint available when the session API auth feature flag is enabled Apr 26, 2023
@mreekie
Copy link

mreekie commented Apr 26, 2023

sprint kickoff

  • There are three pull requests all in a row for a total of 10.

@mreekie mreekie added the Size: 3 A percentage of a sprint. 2.1 hours. label Apr 26, 2023
@GPortas GPortas removed their assignment May 2, 2023
Conflicts:
src/main/java/edu/harvard/iq/dataverse/settings/JvmSettings.java

Just a whitespace change vs mail settings being added.
@pdurbin
Copy link
Member

pdurbin commented May 8, 2023

@GPortas just a heads up that I went ahead and resolved merged conflicts in 25e081d

It was just a whitespace change vs some mail settings being added:

Screen Shot 2023-05-08 at 3 37 32 PM

Copy link
Member

@pdurbin pdurbin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approved. I've been testing this with the frontend PR.

@pdurbin pdurbin removed their assignment May 8, 2023
@kcondon kcondon merged commit b561d3c into IQSS:develop May 10, 2023
@kcondon kcondon self-assigned this May 10, 2023
@pdurbin pdurbin added this to the 5.14 milestone May 11, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Size: 3 A percentage of a sprint. 2.1 hours.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add a Log Out endpoint available when the session API auth feature flag is enabled
6 participants