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.
- Inn-reach central server sends client key + client secret to the /token endpoint of edge-inn-reach service to initiate the flow.
- Edge-inn-reach service sends the key/secret pair to mod-inn-reach service to get the authentication result.
- 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.
- 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.
- 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:
- OAuth2Controller for generating token (edge-inn-reach).
- AuthenticationController for key/secret pair authentication.
- UserDetailsService implementation to get central server key/secret from the database (mod-inn-reach).
- PasswordEncoder for one-way hashing, salting (mod-inn-reach).
- Domain entities (dto, services) for business logic, validation, etc.(mod-inn-reach/edge-inn-reach).
- JwtTokenAuthorizationFilter to validate JWT access token (edge-inn-reach)
- SecurityConfig to declare security rules, roles, etc. to protect REST API (edge-inn-reach)
Open questions
- What type of JWT token signature do we need?
- One key signature (Same secret key for signing and verification)
- Two key signature (Different keys for signing and verification)
- Where to store the secret that is used to sign JWT access token?
- Property files
- System variables
- External secret storage (Hashicorp Vault, AWS KMS, etc.)
- Database
- Kubernetes secrets
- Something else?
- Something else?