When an organization migrates existing applications and services to the light-gateway from a monolithic gateway without changing the code for all consumer applications, we need to provide a dummy OAuth 2.0 server on the light-gateway to simulate how other gateway works.
Most monolithic gateways will have a built-in OAuth 2.0 server to issue tokens to the consumer and verify the tokens for subsequent requests. Consumer applications might cache a token and go to the gateway to get a new token when the cached token is about expired. When migrating to the light-proxy-client, getting a token from the OAuth 2.0 server is taken care of by the light-proxy-client automatically. There is no need to issue a gateway token anymore; however, this getting token from gateway logic might be built-in already. To ensure that there is no code change for the consumer applications, we need to provide a dummy OAuth 2.0 server on the light-proxy-client and light-gateway to return a dummy token or a real token from an OAuth 2.0 provider for the existing application to complete the invocation flow.
The current implementation is designed based on the SAG gateway, and only the client_credentials token is supported. However, we are trying to implement it as generic as possible and leave the door open for future enhancements.
The OAuthServerHandler is located in the egress-router module in the light-4j repository. The handler accepts the request body with the following data elements in a JSON format or FormData.
client_id, client_secret and grant_type. The grant_type should always be client_credentials, and the client_id and client_secret should be configured in the oauthServer.yml client_credentials section, separated with a colon.
You must have a content type header with the value “application/json”, “multipart/form-data” or “application/x-www-form-urlencoded”.
If content type is missing, you will receive the following error.
description: Content type header is missing and it is required.
If the content type is not one of the above allowed content types, you will receive the following error.
# indicate if the handler is enabled or not in the handler chain.
# A list of client_id and client_secret concat with a colon.
# An indicator to for path through to an OAuth 2.0 server to get a real token.
# If pathThrough is set to true, this is the serviceId that is used in the client.yml configuration as the key
# to get all the properties to connect to the target OAuth 2.0 provider to get client_credentials access token.
# The client.yml must be set to true for multipleAuthServers and the token will be verified on the same LPC.
This handler is expecting that the RequestBodyInterceptor is used so that we can get the request body in a map structure in the handler.
When using values.yml to configure the OAuth Server, add the following section in YAML format to use a dummy token without verification.
If you want to have a real token to be retrieved from an OAuth 2.0 provider, you need to change the passThrough flag to true and provide a serviceId as the key for the client credentials token retrieval configuration in the client.yml section. If you don’t want to name the serviceId, you can use the light-proxy-client as the serviceId by default.
# set to true if the oauth2 provider supports HTTP/2
# token endpoint for client credentials grant for LPC
# client_id for client credentials grant flow for LPC
This handler should only be used in the light-gateway to issue dummy tokens.
In the handler.yml file in src/resources/config folder, we have the following endpoint defined.
When using this handler in the light-client-proxy to integrate a legacy consumer application into the ecosystem, we usually allow the consumer to send to the LCP the dummy token or real token returned from the LCP in the Authorization request header.
Suppose there is only one consumer application on the host; you can choose the dummy token as there are no security concerns between the consumer application and the LPC, and the LPC is dedicated to the consumer application.
Suppose there are several consumer applications on the same host. We need to ensure that only the authorized consumer applications can connect to the LPC to send a request to access downstream APIs. In that case, we can set the passThrough to true and allow the LPC to get a real token from an OAuth 2.0 provider.
When a dummy token is used, we don’t want to send it to the downstream API as they expect a real JWT token from its OAuth 2.0 provider. This means the LCP should enable the TokenHandler to grab the token and replace the dummy token in the Authorization header.
As the light-4j application supports two tokens, with primary in the Authorization header and secondary in the X-Scope-Token header, we have to remove the dummy token in order to allow the TokenHandler to put the real token into the same Authorization header. Otherwise, the LCP will put the real token into the X-Scope-Token header because the dummy token occupies the Authorization header.
To remove the Authorization header, we can config the header.yml section in the values.yml file.
This will allow the HeaderHandler to remove the Authorization header if the request path is “/v3/BankingServices/GetNightlyRefreshStatus”.
When a real token is used, we can send it to the downstream API in the Authorization header; however, we also need to get another token that contains the right scope to access the downstream API and put it in the X-Scope-Token header. LPC will verify the token in the Authorization header, and the downstream API will verify both to allow the request to access.
Also, you need to setup the client.yml, token.yml sections to get an access token for the request.
# set to true if the oauth2 provider supports HTTP/2
# token endpoint for client credentials grant for Mras
# client_id for client credentials grant flow for Mras.
Note: The above OAuth credentials are fake and you need to replace them with your own server_url, uri, client_id, client_secret and scope.