I recently had a customer wanting to build a simple UI to maintain additional filtering data associated to a defined “Contract” contained within API Manager. This code would have to run outside of the MuleSoft eco-system, as a service, within a JAVA Data Layer container environment.
My goal was to develop a very simple JAVA API Manager Client Access Example, whose concept prototype could be used as a basis to construct a necessary Mashup of API Manager Resources and Custom Client oriented resources. A primary emphasis is to understand the OAUTH2 Authentication exchange requirements.
- API Manager Account
- JAVA Development Environment
To begin you can review the API Manager Console located at https://anypoint.mulesoft.com/api-platform/api/console/#
Here we can see all of the available protected resources available from API Manager’s REST API.
You can drill down as well as request Authentication using your API Manager account credentials to perform the related resource queries.
But our goal is to provide a programmatic way of accessing API Manager resources. Any programming language can be used. In this demonstration, I am using JAVA. The whole idea around RESTful API’s is to eliminate lock in and be language agnostic. So API’s are our bridges to the world around. Hmm, sounds like another blog…
One major requirement is that where ever your client will be running, it must be able to access API Manager via SSL and the default port of 443. This is a hardened requirement and facility to provide secure access to API Manager, as it is one of the components within the MuleSoft Anypoint eco-system of products.
First, I wanted to refresh myself on OAUTH2 and the handshake performed among the parties involved. Reviewing the OAUTH V2 specification located at: http://tools.ietf.org/html/draft-ietf-oauth-v2-31, provided me with the necessary information. Always good to review the specification, but in the end there can be nuances distinctive to the provider. In summary of the specification, upon sending our credentials and being authenticated on the provider side, we shall receive an “access_token” contained within the Location header of the HTTP Resource to our authentication request.
However, the most important part of developing a correct Authorize request is to specify the proper parameters, per the provider, to send on our HTTP POST request to API Manager’s Authorize resource, “/authorize“.
The Authorize request parameters we must use are as follows:
Required OAUTH2 grant Type, to indicate a user name and password will be supplied.
Required, Provides Client Identifier, specific to API Manager to indicate client context, if not specified, you will receive an error indicating “invalid_request No client identification nor authentication found”.
Required, Indicate our Request and Response Type.
Required and encoded, Indicate the Redirect URI, which will be received in our Location Header upon redirect response.
Required and encoded, The authorization and token endpoints allow the client to specify the scope of the access request using the “scope” request parameter. In turn, the authorization server uses the encoded “scope” response parameter to inform the client of the scope of the access token issued.API Manager will determine access right based upon the scope setting. In our example, we are requesting full access.
Value(s): Specified as a concatenated String Value separated using an encoded space character of “%20“, as in “READ_SERVICES%20CONSUME_SERVICES…”
Required API Manager Account Principal
Value: Your API Manager Account Principal
Required API Manager Account Credentials
Value: Your API Manager Account Credentials
The current JAVA Source code for this project can be found publicly on Github at: https://github.com/mulesoft-consulting/apimanager-oauth2-client.
Class Diagram of our Classes in project
Very simple JAVA Class organization where we have an Interface, which contains all of our necessary constants defined. A Main class, to demonstrate the Authentication and then subsequent access of a protected resource. A Static Tool class, to provide the “Authentication” and “GetResource” methods called by our Main class. And finally two POJOs, which will represent our Authentication and Resource Result objects respectfully.
This JAVA gist, provides details on the client side Authorize request:
Upon receiving the response from the “/authorize” Post request, you should receive a status code of 302. Which indicates a redirection. You now interrogate the “Location” HTTP Header to obtain our access_token upon successful authentication or obtain an error condition. Ensure you specify the “client_id” parameter with a value of “CONSOLE“, one of those undocumented gotchas. If you do not specify, you will receive an error condition. And you will possibly be left scratching/banging your head for an hour and a day or so, trying to understand what is wrong with the request.
Once you have the access_token, in this example, we use the JAVA constructor for APIManagerAuthenticationResult to parse the Location Header returned from our “/authorize” request and instantiate the POJO for use in upstream layers to easily access the access_token for use in subsequent API Manager REST API calls.
This JAVA gist, provides details on the client side Get Resource request:
You should receive a status code of 200 from a resource Get Request. You may however, receive, a 403, indicating a Forbidden request. Depending upon your request, the 403 will indicate that based upon the specified authorization scopes present and specified, the current user principal does not have access to the requested resource. You should review API Manager user your are using as well as the scope specified to resource requested.
Once you have all the required items and have built the source code, you will be able to run the demonstration.
Running the example will perform:
- Authentication of supplied credentials to API Manager
- Obtain an access_token
- Using the acquired access_token, Perform rudimentary get requests for each of the authenticated principal’s API Manager resources.
To run from command line using Maven perform the following command substituting your Credentials:
- arg0 is your API Manager Account Principal
- arg1 is your API Manager Account Credentials
Here is abridged example log of a run:
Using this very simple example, you should be able to evolve your own Client specific to your needs, in your preferred Lingua Franca, to incorporate and Mash-In API Manager resources with your existing Enterprise Application Processed and Resources providing seamless integration.