Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

Context - Spring + OAuth2

...

Current (Keycloak) Auth Flow

Drawio
mVer2
zoom1
simple0
inComment0
custContentId4453236739
pageId4450910534
lbox1
diagramDisplayNameUntitled Diagram-1732880583246.drawio
contentVer1
revision1
baseUrlhttps://hee-tis.atlassian.net/wiki
diagramNameUntitled Diagram-1732880583246.drawio
pCenter0
width1061
links
tbstyle
height610.5

Proposed UserManagement OAuth2 Flow

To implement a more generic OAuth2 flow, the filter chain in the web security config will be changed to use the Spring Security oauth2Login provider as below:

Code Block
    httpSecurity.csrf()
        .and()
        .authorizeRequests()
        .anyRequest().authenticated()
        .and()
        .oauth2Login()
        .successHandler(successHandler);

In order to create a reusable approach, a shared success handler can be created or adapted from an existing class to achieve the following:

  • Retrieve the appropriate claim from the token to be matched with the username in the profile service

  • Verify the user exists, and retrieve the user’s roles and principles for authorization

  • Set the calling service’s security context with the retrieved authorities (do we want to do this?)#

A high level idea of this can be seen below:

Drawio
mVer2
simple0
zoom1
inComment0
pageId4450910534
custContentId44532367394452483155
diagramDisplayNameUntitled Diagram-17328805832461732882607371.drawio
lbox1
contentVer1
revision1
baseUrlhttps://hee-tis.atlassian.net/wiki
diagramNameUntitled Diagram-17328805832461732882607371.drawio
pCenter0
width1061
links
tbstyle
height610.5

...

656.5

A more specific example idea of a real implementation can be split into two parts:

Shared Components

  1. SharedAuthencticationSuccessHandler (implements AuthenticationSuccessHandler) (needs new name)

    • Instantiated with following dependencies/params:

      • SecurityContext(is this bad?) - for setting granted authorities

      • JwtUtil(another shared component, see below) - for decoding token to retrieve user details

      • UserDetailsService - for retrieving user details

    • Does the following in its onAuthenticationSuccessmethod:

      • Decodes token to find username (email) using JwtUtil

      • Fetches user details from UserDetailsService

      • Extracts granted authorities from UserInfo and sets them in SecurityContext

      • Authorization can now be performed on controllers etc within the calling service

  2. JwtUtil class (again, needs a better name)

    • Instantiated with the following dependencies/params:

      • jwkSetUri String configured as an application property

      • jwtIssuer String configured as an application property

      • usernameClaimString configured as an application property (this is because we use email as the username)

      • creates a NimbusJwtDecoder Bean from jwkSetUri and jwtIssuer

    • Does the following:

      • Method to retrieve the username from the token

    • UserDetailsService - Already exists, fetches user infor by user name

Service-Specific Configuration

Given the above, each service would need to be configured with the following application properties:

  • jwkSetUri

  • jwtIssuer

  • usernameClaim

  • & any provider-specific (e.g. cognito) configuration required by spring framework to perform the authentication step

and would need to instantiate the following beans:

  1. SharedAuthencticationSuccessHandler (injected into successHandler)

  2. JwtUtil (injected into the above)

Tickets