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

Java21+Spring6 upgrade, Keycloak removal #503

Merged
merged 21 commits into from
Nov 26, 2024

Conversation

ngeorges-cnrs
Copy link
Contributor

This pull request updates and replaces #496, which basically had VIP-portal building with Java21, but not running in a usable way.

In the present PR :

  • Login/password authentication works and the UI is usable.
  • API key and EGI authentication both work, and have been upgraded to Spring Security 6.3 API.
  • Keycloak API authentication has been temporarily disabled, with the org.keycloak connector fully removed, as it was incompatible with Spring6. It will be replaced by an equivalent OIDC Spring connector in a separate patch.

Known limitations :

  • There are still around 20 build warnings (not related to Spring Security)
  • The menus icons on the homepage have an abnormal size (probably something in gwt related to the upgrade)
  • Overall, things haven't been thoroughly tested in accordance with the magnitude of the java11/java21 change

These limitations along with the Keycloak connector removal make the patch usable for development/testing, but obviously not for production yet. Also do note that Tomcat must be upgraded to v10 or v11 in order to support jakarta.

Ethaniel Billon and others added 9 commits November 4, 2024 15:28
- Upgrade API key and EGI auth to Spring Security 6.3.
  - Add -parameters compilation flag
  - Add @configuration annotation to @EnableWebSecurity classes
  - Move @order annotations to SecurityFilterChain methods
  - Port API key and EGI authentications to use the new Spring6 API,
    removing use of deprecated stuff.
- Fully remove org.keycloak connector: this temporarily drops support
  for Keycloak authentication in VIP API, as this connector is
  deprecated and doesn't supprot Java21/Spring6.
  It will be replaced with a new Spring-based OIDC connector in an
  upcoming patch.
  - Also remove unused keycloak refreshtoken stuff, and the three
    related keycloak parameters in vip-api.conf
Copy link
Contributor

@axlbonnet axlbonnet left a comment

Choose a reason for hiding this comment

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

Thanks for the work.
Seems good globally.
We need to review the way GWT is imported.
Also, the tests are failing on github because it is still configured with java11, we need to update the workflow definition with the new one @ethaaalpha did. Do they run locally ?

vip-datamanagement/pom.xml Outdated Show resolved Hide resolved
vip-publication/pom.xml Outdated Show resolved Hide resolved
pom.xml Show resolved Hide resolved
vip-api/pom.xml Outdated Show resolved Hide resolved
- Add explicit comment on requestmatchers
- Remove useless authmanager bean
- upgrade hibernate validator from 6.1.5.Final to 8.0.1.Final
- remove direct import of jakarta.validation

With this change, rest API objects validation now correctly
happens at runtime, but still not in unit tests.
@ngeorges-cnrs
Copy link
Contributor Author

Summary of today's changes :

  • CI goes further, but there are still 3 failing tests in vip-api (see conversation on jakarta.validation)
  • The apache-fileupload update and related dependencies changes might indeed deserve extra review / testing

Known limitations listed in the first comment all remain, and ongoing conversations have to be sorted out with @axlbonnet.

@ethaaalpha ethaaalpha mentioned this pull request Nov 7, 2024
Was broken since the smartgwt and fileupload upgrades:
- Backend fix: upgrade commons-io to 2.17.0 and pin version in
  top-level pom (needed for commons-fileupload2-jakarta-servlet6)
- Front-end fix: Make gwt form submission synchronous with
  setCheckFileAccessOnSubmit(false), to workaround immediate
  destruction after submit (see smartgwt DynamicForm javadoc)
This was apparently needed along with the spring+hibernate
upgrade, to have proper validator injection in integration tests.
@ngeorges-cnrs
Copy link
Contributor Author

Last two updates :

Remaining issues :

  • Restore Keycloak API authentication support with Spring Security 6
  • Maybe solve build warnings

@axlbonnet
Copy link
Contributor

Excellent.
We'll see about the keycloak support and this will be ready to be merged.

- This provides support for OIDC Bearer token authentication with
  a Keycloak server, in a backwards-compatible way, but using
  Spring Security 6:
  - Support the same keycloak.json file as previously
  - Same network requests to Keycloak server
  - Same decoding of JWT claims for endpoints with role check
- In addition to the backwards-compatible stuff:
  - Fix missing verification of locked account
  - Inner structures are ready to support multiple servers
@ngeorges-cnrs
Copy link
Contributor Author

ngeorges-cnrs@7970495 : restore Keycloak support, ready for review and candidate to merge.

Notes for the review :

  • This SpringSecurity 6 implementation should be fully backwards-compatible with the previous Keycloak connector one : same config file, same network requests, etc.
  • There is normally only one visible and intentional change, a bugfix : locked user accounts were not checked by previous version when using OIDC bearer tokens, they now are correctly denied.
  • Keycloak-specific mapping of JWT claims into roles is now explicit in OidcResolver.parseAuthorities, this was previously done by the Keycloak connector implementation. Same thing for keycloak.json file parsing.
  • Preparing support for multiple OIDC servers, while also caching the authenticated principal to avoid multiple getVipUser() DB lookups per request, as well as mapping JWT claims, requires some extensive configuration compared to the simpler cases in SpringSecurity docs. This is done in OidcResolver.getAuthenticationManagerResolver and its dependencies. This is a bit verbose, but still the most concise way I've found so far.

@ngeorges-cnrs
Copy link
Contributor Author

ngeorges-cnrs commented Nov 20, 2024

During some extra testing today, I found an issue with Keycloak support in the present PR, which has to do with how JWT claims get mapped to authorities ("roles") : the current PR assumed that roles were extracted from the resource_access.<resource>.roles JWT field, where <resource> is the string defined in keycloak.json. But this was an incorrect assumption : actual tests on role-restricted endpoints with VIP-portal 2.7 show that authorities are in fact extracted from realm_access.roles.

This means that the resource name in keycloak.json is probably useless : I'll do some review of the existing Keycloak connector code to confirm that, if I can find it. And we can then decide whether to drop that configuration field.
The resulting patch should be relatively simple.

Edit: Keycloak adapter behaviour is confirmed (we were using 15.0.1) :

So depending on current and planned prod usage, we can either remove support for resource roles entirely, or keep a similar configuration possibility with a boolean flag + resource name.

- Change default authorities parsing to realm_access, as in previous
  implementation
- Add support for use-resource-role-mapping parameter in keycloak.json,
  to allow resource_access authorities to be configured
@ngeorges-cnrs
Copy link
Contributor Author

ngeorges-cnrs@79e825c : adjusted how roles are parsed from JWT to exactly match previous implementation (cf previous comment).

As seen with Axel, use-resource-role-mappings is currently unused in prod, so the resource parameter is effectively unused as well. As this was simple to implement, I've kept optional support for both realm roles (default) and resource roles (if use-resource-role-mappings + resource fields are set).

All tests done on my side, so this PR is finally ready for review and merge.

Copy link
Contributor

@axlbonnet axlbonnet left a comment

Choose a reason for hiding this comment

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

Excellent and elegant work.
I just have short remarks mainly about exception handling.

Copy link
Member

@camarasu camarasu left a comment

Choose a reason for hiding this comment

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

Excellent work @ngeorges-cnrs!
I'm OK with merging the PR after taking into account Axel's suggestions.

- Improve keycloak.json file reading
- Change OidcConfig from @configuration to @service
- Shorten AntPathRequestMatcher.antMatcher with a static import
- In OidcConfig: let exceptions bubble up and rely on default logging,
  throw explicit BusinessException instead of implicit
  NullPointerException on missing mandatory fields in keycloak.json.
- In OidcResolver.parseAuthorities: handle unknown resource name
  gracefully with logging, let other errors bubble up as they normally
  shouldn't happen with a Keycloak-generated JWT.
- Also adjust some logs of abnormal cases to warning-level.
@ngeorges-cnrs
Copy link
Contributor Author

All comments above were addressed in today's commits :

  • ngeorges-cnrs@d8adb42 for exceptions handling. See commit message for what changed. Most of the diff is just reindentation because of try/catch blocks removal.
  • ngeorges-cnrs@702d30e for the rest. For the record, the code snippet with MvcRequestMatcher mentionned here does work, but it's indeed not shorter than antMatcher() so I've kept the latter.

Hopefully everything is now ready for merging.

@axlbonnet
Copy link
Contributor

Great work, thanks @ngeorges-cnrs

@axlbonnet axlbonnet merged commit f3b8c9b into virtual-imaging-platform:develop Nov 26, 2024
3 checks passed
@ngeorges-cnrs ngeorges-cnrs deleted the java21 branch December 5, 2024 08:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants