Architecture for Third Party Authorization Server Integration
By Johann Nallathamby
- 25 Sep, 2019
In an API management ecosystem, sometimes there are requirements for components from multiple vendors to work together:
- A common requirement is for API management systems to integrate and work with third party OAuth 2.0 Authorization Servers (AS).
- An extension of the above requirement is for API management systems to integrate and work with more than one OAuth 2.0 Authorization Servers.
Most modern API management systems provide API based integration capabilities between these components to avoid vendor lock-in. For this article, we assume that the necessary APIs are readily available for integration. If not, then you may have to build them before carrying out the integration.
Before deciding on third party AS integration, you need to be sure that an identity federation solution pattern will not work in your case. If your requirement is to simply use existing identities of your resource owners to login and provide consent to OAuth2 clients, then an identity federation solution pattern will be ideal. However, there can be other factors in your case that make this option impossible, such as:
- It could be necessary to build the id_token with claims after the first identity federation flow and to build a response for the /userinfo endpoint for a federated user account.
- Certain authorization servers have just-in-time (JIT) provisioning capabilities that can support provisioning accounts for users on the fly with claims so that it supports building the id_token and userinfo response more than once. However certain claims cannot be JIT provisioned. For example, it does not make sense to JIT provision certain dynamic claims issued by the third party identity providers such as authentication methods, assurance levels, dynamic roles, etc. Also, some claims may be authentication event-specific, session-specific, or service provider-specific, for which JIT provisioning will not work perfectly.
- It might be the policy of the organization to manage identities and access tokens by the same server.
If you can’t follow the identity federation approach due to one of the above reasons, then you may have to consider the below approaches. In this article, let’s look at two common solution architectures that can be employed to satisfy such requirements:
- Authorization Server Replacement
- Authorization Server Proxy
In both of these patterns, since end users will be directly interacting with all the third party AS to provide the requested authorization grant, it may be important to invest additional effort to unify the user experience across all the third party AS.
Authorization Server Replacement
In this solution pattern the existing AS is completely replaced with one or more third party AS. Components such as the API Storefront, API Publisher, and API Gateway all need to directly integrate with all the third party AS
The first thing to be done is to proxy all the API calls that come into the AS from the OAuth2 client, the API Storefront, and the API Publisher through the API Gateway. This basically helps to abstract the complexity of dealing with multiple AS from the callers. Most API Gateways have the capability to include mediation logic in some form of scripting, to dynamically route requests based on context, without changing the core component. This approach immediately provides the advantage of being able to maintain the solution easily without requiring internal knowledge about the API management system.
The next thing is the integration in the API Gateway. APIs such as the OAuth2 resource registration for the API Publisher to consume, OAuth2 dynamic client registration for the API Storefront to consume, OAuth2 authorization, authenticate users and grant access with OAuth2 access tokens, OAuth2 access tokens introspection, OAuth2 access and refresh token revocation, and OIDC userinfo for the OAuth2 clients to consume all need to be exposed over the API Gateway, and a switch case logic needs to be implemented in each of these APIs to decide which AS to route to based on either context parameters, access token format, etc.
The actual APIs which are consumed by the API clients will also need to have a switch case logic to introspect the access token with the correct third party AS.
Figures 1-5 illustrate the authorization server replacement solution in action.
Figure 1: OAuth2 client credentials generation in authorization server replacement
Figure 2: OAuth2 authorization request and OAuth2 token request in authorization server replacement
Figure 3: OIDC userinfo request in authorization server replacement
Figure 4: OAuth2 token introspection in authorization server replacement
Figure 5: OAuth2 token revocation in authorization server replacement
- If an OAuth2 client has to deal with only one AS depending on the business case, then it will be oblivious to the existence of multiple ASs.
- If the OAuth2 client has to deal with multiple ASs depending on the business case, then except for the fact that it needs to maintain one set of client credentials for each AS, the rest of the complexity of interacting with multiple ASs is abstracted from it.
- Since most API Gateways provide support to include mediation logic in some form of scripting to dynamically route requests based on context, the core components are not changed.
- If the OAuth2 client has to deal with multiple ASs depending on the business case, then it will be registered directly with all those third party ASs. This could mean that the same OAuth2 client may have to maintain multiple client credentials from multiple third party ASs.
- There is no single AS to manage all OAuth2 clients, making it harder to manage them. This makes it even harder if the ASs are in different organization domains than the rest of the API management platform.
- The third party ASs cannot be made oblivious to the existence of multiple OAuth2 clients.
Authorization Server Proxy
In this solution pattern the built-in AS forwards all the requests that arrive to relevant third party ASs. The built-in AS (proxy) will be registered as the only OAuth2 client in all of the third party ASs.
- A prerequisite for this solution pattern is that extensibility is built into the design of the built-in AS component
- The OAuth2 consent page must be suppressed in the built-in AS in order to avoid requesting consent from the resource owner twice.
- One of the following options must be available:
a). It must be possible in the third party AS to generate unique access tokens in the token endpoint each time for the same resource owner + OAuth2 client combination, because though the actual OAuth2 clients are different, the third party AS only sees the built-in AS (proxy) as the OAuth2 client.
b). If (a) is not possible the third party AS must support requesting dynamic scopes, and issue unique access tokens for resource owner + client + scope combination. In that case, for each of the actual OAuth2 clients a unique scope will be designated at the third party AS.
If (a) or (b) are not possible, then the built-in AS needs to generate a Base64 encoded, self-contained access token, containing the third party access token and client id as attributes which would also be unique to each client.
The built-in AS is represented as AS0 in the below sequence diagrams. Figures 6-9 illustrate the authorization server proxy solution in action.
Figure 6: OAuth2 authorization request and OAuth2 token request in authorization server proxying
Figure 7: OIDC userinfo request in authorization server proxying
Figure 8: OAuth2 token introspection request in authorization server proxying
Figure 9: OAuth2 token revocation request in authorization server proxying
- OAuth2 clients interact only with built-in authorization servers and don’t directly interact with third party ASs. The OAuth2 clients and the third party ASs are oblivious to the existence of each other. Components such as the API Storefront, API Publisher, and API Gateway all need to directly integrate with only the built-in AS.
- There is one single AS which is the built-in AS, to manage all the OAuth2 clients which makes it easier to manage them. The built-in AS is the only OAuth2 client registered in the third party AS, which makes it easier to manage the connection with the third party.
- Extensions are required in the built-in AS to implement the logic to dynamically route requests to the relevant AS based on context parameters, token format, etc. Extensions are required for OAuth2 authorization grant handling (eg- authorization code flow, client credentials flow), OAuth2 access token issuing, OAuth2 introspection, OAuth2 token revocation, and OIDC userinfo.
Authorization Server Replacement for WSO2 API Manager
Due to particular requirements of WSO2 API Manager, the built-in WSO2 Key Manager component cannot be avoided completely when implementing this pattern. Therefore it supports something that very closely resembles the pattern, which we call the "third-party key manager integration" pattern. The deviation from the standard pattern is not so significant from a deployment perspective, in the all-in-one deployment model. However, it could become significant in a distributed deployment model when you need to add additional nodes to host the WSO2 Key Manager.
There are two deviations from the standard pattern already discussed:
- Two major functionalities of WSO2 API Manager are throttling and analytics. However, throttling and analytics are tied into the OAuth2 client identifier. Moreover, it is expected to have this client identifier in the WSO2 Key Management database for throttling and analytics to work as expected. For this reason, when OAuth2 client identifiers are generated in a third party AS, the client identifier also needs to be stored in the same database, where a WSO2 client identifier would be stored. This customization is generally performed in the API Store itself. Instead of calling the gateway’s client credentials generation proxy API in the “Authorization Server Replacement” pattern [Figure 1], it directly calls the third party AS’s client credentials generation API, gets back the client credentials, stores the client identifier in the Key Management database, and displays the client identifier in the API Store. This is shown in Figure 10.
- WSO2 API Manager has a concept of API subscriptions. During access token introspection at the OAuth2 introspection endpoint, by the API Gateway, during API invocation by a client, one of the things that is validated is the subscription of the API that is being invoked. This generally has to be performed at the WSO2 Key Manager as it is a WSO2 API Manager specific concept. As a best practice, it is not recommended to do this validation in the API Gateway as it requires access to the database. The best component to do this validation is WSO2 Key Manager. Therefore, for the token introspection, we follow the “Authorization Server Proxy” approach. WSO2 Key Manager, in this case, is responsible for introspecting the token with the third party AS, validating subscriptions for the client, and sending back the response. This is illustrated by Figure 11.
Figure 10: Client credentials generation in 3rd party Key Manager Integration
Figure 10: OAuth2 token introspection call in 3rd party key manager integration
Authorization Server Proxying for WSO2 API Manager
There are two minute differences when it comes to WSO2 API Manager compared to the standard pattern for this:
- In WSO2 API Manager all OAuth 2.0 APIs are proxied via the API Gateway, so the OAuth 2.0 clients will consume the proxy APIs on the API Gateway instead of the ones in WSO2 Key Manager directly.
- To implement the proxying of OAuth 2.0 authorization endpoint call, we will use the identity federation capability that comes with WSO2 Key Manager, as this flow already implements most parts required for this proxying call. This proxying capability will be implemented as a federated authenticator. Although we have an OIDC federated authenticator, the existing authenticator is tightly coupled to the authorization code grant flow, and it executes the entire authorization flow as an atomic step within the authenticator which prevents us from proxying the authorization call and token call independently. Therefore we will implement a custom authenticator that will handle proxying only the authorization call and extend the grant handler to proxy the token call. This authenticator is something that could potentially be added to the WSO2 API Manager standard product. The custom authenticator could also handle all the possible response types such as “code id_token”, “id_token token”, “code token”, and “code id_token token”. One exception will be the “code token” response type which needs to be proxied as “code id_token token” because the identity federation feature is implemented expecting the authenticator will return an authenticated subject, and therefore we need to get back an id_token from the third party AS.
This article provides a high-level overview of two common solution architecture patterns that can be employed to solve the third party authorization server integration problem. WSO2 API Manager is an open source API management product, distributed under the Apache 2.0 license. Possessing a powerful API Security framework, WSO2 API Manager consists of multiple components that play the roles of an API Gateway, OAuth 2.0 Authorization Server, API Storefront, API Publisher, API Traffic Manager, and API Analytics. While WSO2 API Manager comes with a built-in OAuth 2.0 Authorization Server component, it can also integrate with multiple third party OAuth 2.0 authorization servers, using either of the two approaches described in this article.