SPIKE: [MODINREACH-20] Investigate possible methods to implement OAuth2

Context

Jira Story

https://folio-org.atlassian.net/browse/MODINREACH-20

Spike goals

Investigate possible methods (ways) to implement OAuth2 authorization


Terminologies

Protected resource – some data that needs to be accessed, it needs to be secured and only accessible to requests with a valid JWT access token. In our case it’s mod-inn-reach or inn-reach-edge REST endpoints.

Resource server – application/server hosting the protected resources. In our case these are mod-inn-reach or inn-reach-edge, it’s module that exposes REST endpoints (protected resources).

Client – application that needs access to protected recourse. In our case it’s external inn-reach central servers that call our API REST endpoints (protected resources).

Authorization server – application/server that issues JWT access tokens to the client. In our case it’s -inn-reach-each service.


OAuth2 protocol provides several authentication flows.

In our case we have machine-to-machine communication (M2M) in this Client Credentials Flow is the most appropriated flow.

  1. Inn-reach central server sends client key + client secret to the /token endpoint of edge-inn-reach service to initiate the flow.
  2. Edge-inn-reach service sends the key/secret pair to mod-inn-reach service to get the authentication result.
  3. If the key/secret pair is successfully authenticated, edge-inn-reach service generates a JWT access token and returns it to the inn-reach central server.
  4. Inn-reach central server calls edge-inn-reach REST API using the JWT access token
    • The JWT token is validated in edge-inn-reach service, since all requests go through the edge-inn-reach REST API.
  5. Inn-reach central server receives a response from the edge-inn-reach REST API.

 

Proposed solutions

Custom Spring based solution

Since we have a simple flow, we could implement a simple JWT access token issue/verification. Spring security provides all the necessary mechanisms, basically the result implementation may depend on the requirements and Spring framework knowledge, in general, a basic implementation may look like this:

  1. OAuth2Controller for generating token (edge-inn-reach).
  2. AuthenticationController for key/secret pair authentication.
  3. UserDetailsService implementation to get central server key/secret from the database (mod-inn-reach).
  4. PasswordEncoder for one-way hashing, salting (mod-inn-reach).
  5. Domain entities (dto, services) for business logic, validation, etc.(mod-inn-reach/edge-inn-reach).
  6. JwtTokenAuthorizationFilter to validate JWT access token (edge-inn-reach)
  7. SecurityConfig to declare security rules, roles, etc. to protect REST API (edge-inn-reach)

Open questions

  1. What type of JWT token signature do we need?
    1. One key signature (Same secret key for signing and verification)
    2. Two key signature (Different keys for signing and verification)
  2. Where to store the secret that is used to sign JWT access token?
    1. Property files
    2. System variables
    3. External secret storage (Hashicorp Vault, AWS KMS, etc.)
    4. Database
    5. Kubernetes secrets
    6. Something else?
  3. Something else?