Secure your APIs

January 13 2015

0 comments 0
motif

Securing an API in Anypoint Platform is easy. In a previous post we showed how Anypoint Platform for APIs allows you to fully protect your API. We concluded then that the combination of HTTPS and OAuth 2.0 are a rule-of-thumb best practice for Web API security. In this post, we’ll take a deeper dive into the makeup of a security configuration in Anypoint Platform and explore in more detail the areas of Basic Authentication and 2 Authorization in the context of Identity Management. We’ll also give you some pointers about when and how to use these two standards.

Manager

Central to authentication in Mule is the Security Manager. This is the bridge between standard mule configuration and Spring Security beans. In the example we build in this blog, we will use Spring Security to authenticate credentials against an LDAP server. We suggest you read the Spring Documentation on this topic if you want to delve further.

Configuration Overview

The diagram above illustrates how credentials are passed and validated in the solution. Before we dig deeper, a brief overview of this process will give important context for the rest of this post. The security-manager, as you can see above, delegates to the authentication-manager. The authentication-manager uses the authentication-provider to authenticate the set of credentials. The authentication-provider abstracts away from the details of the system used to do the authentication, whether it be in-memory, LDAP or DB based. The Spring LDAPAuthenticationProvider uses the BindAuthenticator in order to build a DN based on the credential username with which to bind directly to the LDAP server.

Example Configuration

Each of the following elements appears on the diagram above.

You need to write a custom class which extends InetOrgPersonContextMapper and implements the mapUserFromContext() method. This method returns a UserDetails instance upon successful authentication. This instance is subsequently stored in the security context of Mule.

public class UserDetailsContextMapper extends InetOrgPersonContextMapper {

    @Override
    public UserDetails mapUserFromContext(DirContextOperations ctx, String username, Collection<? extends GrantedAuthority> authorities) {
        InetOrgPerson.Essence p = new InetOrgPerson.Essence(ctx);
        p.setUsername(username);
        p.setAuthorities(authorities);
        p.setDisplayName(ctx.getStringAttribute("givenName"));
        return p.createUserDetails();
    }
}

Identity

Core to what we have just seen is the concept of Identity. We can only successfully authenticate and authorize people or systems, if we have some means to verify their identity. It may be we have a record of the user in a database or in LDAP as in the example above. It doesn’t really matter where the identity data lies. We just have to have recourse to a system or a data store where we can identify and match the incoming credentials. There are two aspects to identity which interest us, especially as we enter into the discipline of API Management: Identity of consuming Apps and Identity of end users.

Often, the identity of the consuming app is of prime importance. If you wish to expose your company’s core capabilities as an API and you want to monetize on the use of the API, then it’s vital that you identify each consuming App so you can bill accordingly. You will find among some public APIs that API keys are a means for them to identify and authenticate your software as a consuming App. Every time you make an invocation you have to pass the token in a header or query parameter. We prefer the OAuth approach. Every consuming App should have its own client ID and secret. When you secure your API with OAuth, the consuming App provides these credentials in order to receive an OAuth token which it uses to consume the API just like an API key.

Example Secured API

Let’s take a look at how to implement what we have discussed. We will develop an API facade defined with RAML on top of the OpenWeather API. Just for the fun of it we will add security to this facade. We’ll only proxy a part of the API: get weather forecasts and actual weather in a particular country and city. Also, for the convenience of our learning experience we’ll protect both resources one with Basic Authentication and the other with OAuth 2.0. Anypoint Platform automatically generates from the RAML spec a console which serves as a centralisation of documentation and testing of the API. The console supports consuming APIs protected with Basic Authentication and OAuth 2.0. To faciliate this, we configure the RAML accordingly.

As you can see /current-weather is protected with Basic Authentication and /forecast with OAuth 2.0. Now let’s consider the implementation. We have to place a http-security-filter in the GET:/current-weather flow and a oauth2-validate in the GET:/forecast flow. The security-manager is consumed by the http-security-filter in the case of Basic Authentication and by the oauth2-provider in the case of requests for oauth tokens.

Basic Authentication

You should be very mindful of the weakness of this standard when considering its use. It should only be used in combination with Https as the credentials are sent in plain text over the wire. Also, it is not possible to sign out of an authenticated session with this standard (you have to close the browser). It simply doesn’t compare to the power and security of OAuth 2.0. That said, it could be used for private in-house APIs and is used in such scenarios, so we should consider it here.

The http-security-filter knows how to decipher the incoming Base64 encoded username and password before passing them to the security manager. This filter can be present both on the API itself and on the console, though you may consider it convenient to give free access to the console and apply no filter to it. For every invocation of the API, the filter will intercept and authenticate as described. Failure to authenticate will result in a 403 sent back to the client.

OAuth 2.0

The power of Auth 2.0 comes with the price of complexity and the spec can be rather daunting at first sight, but you should read our documentation to see how easy it is to use in Mule.  Of its four grant types, Authorization code is the most secure, but you might consider the following as a rule-of-thumb guide so as to know which grant type to use depending on the nature of your client:

  1. Authorization Code: server-side web application (Spring MVC, Vaadin, Zend, Play, .Net) hosted by a partner or third-party.
  2. Implicit: browser based web application written in Javascript (Angular, Ember, NodeJS) or 3rd party Mobile Apps written for iOS or Android.
  3. Resource Owner Password Credentials: highly trusted web apps and smart phone / desktop Apps written by you as the Service Provider.

Also, you shoud be mindful of the fact that client secrets are not for public consumption. Hence, Resource Owner Password Credentials should never be used for a Javascript application as it has no means to hide the client secret.

The oauth-provider config exposes a url over which it receives requests for a token in exchange for credentials (client id, secret, username and password). It also passes the username and password to the security-manager before proceeding to issue a token.

Every invocation of the API should be protected with an oauth-provider validate message processor. This will check for an incoming token and verify that it is valid, still within its expiration window and allows the client to actually invoke this flow. Tokens are issued based on requested scopes. The validation takes scope into account when making its decision. If validation fails, a 403 is returned to the client. If it succeeds, the flow continues to execute normally.

CORS


Note how we have to place a CORS processor in the main flow of the API. This allows Javascript clients to make calls to the API. The console, which is implemented in Angular,  is an example of this. As it is exposed on a separate endpoint, it is naturally constrained by cross-site restrictions.

End Result

When we expose an API in Gateway we do so on top of a powerful Integration platform. The actual implementation is merely a configuration of generic software developed by MuleSoft’s engineers. The consequence of this declarative mode of solution delivery is the decimation of what would have been a serious development effort. We end up with an integration between OpenWeather’s API, a consuming client and the LDAP server, packaged as a RESTful Web API.

Federated Identity

Things don’t always stay as simple as the example we’ve just created. What if we had multiple instances of LDAP to consult? What if we had not just LDAP, but databases and web-services and file systems? To bring our pondering to its maximum extension: what if our Identity Providers where across multiple organizations as would be the case were we to faciltate access to our partners’ systems?

This is where Identity Federation comes in and the industry has brought about protocols and systems which are focussed on this area alone. To fulfill this need, the Anypoint Platform for APIs allows you to integrate your API Manager organizations with external Identity Providers hosted by you or your partners. One such provider is PingFederate. It acts both as a federated Identity Provider and as an OAuth 2.0 Provider.

Overview of PingFederate Configuration

The following diagram highlights the key elements that must be configured in order for PingFederate to act as OAuth Provider and issue tokens based on requests which it authenticates against our LDAP instance. Take a look at it with two Federation concepts in mind: Service Provider and Identity Provider.

SP Connection

Your organization in the Anypoint Platform is the Service Provider. It must talk to PingFederate through the SP Connection. This is the bridge which facilitates all federated communication between your org and PingFederate as Identity Provider.

IdP Adapter

Adapters are like the Security Manager we have seen above. They do all the heavy lifting and delegation work in order to facilitate authentication against any data store. Composite IdP Adapters allow you to attempt authentication against numerous systems, perhaps multiple instances of LDAP, perhaps also databases. PingFederate allows you to exploit many adapter types as plugins to your server configuration. HtmlForm Adapters allow the OAuth Provider to expose its login page and have that hook into the authentication process.

Password Credential Validator

This also comes in numerous types (LDAP, Database, etc.). We can never escape the need to compare incoming credentials with some system that contains the same username and password pairs.

DataStore

The connection and search configuration of your LDAP servers, databases, etc.

OAuth Configuration

The four main areas of configuration for your PingFederate instance to act as an OAuth Provider are:

  • Authorization Server: the main area of configuration of the grant types you support, etc.
  • IdP Adapter Mapping: This is key if you choose to use the more secure dances in OAuth: Authorization code and Implicit. This facilitates the need to keep track of generated keys and the necessary association of them with their owners.
  • Resource Owner Credentials Mapping: This is only necessary if you decide to implement this grant type (relevant when the client is not mobile or web-based, but rather a trusted server-side system).
  • Access Token Attribute Mapping:the point of configuration of the data that you want stored in the generated tokens.

Security Policies

If you have used APIkit you have already seen how easy it is to expose APIs in Anypoint Platform. All of the power of the integration platform that is Mule is available to you everywhere. That said, things get much easier as we venture into the area of API management. The security configuration in our example is very common. If you use LDAP as Identity store and you want to protect your APIs with OAuth the above configuration snippets will suffice. However, given the common need for such solutions, the industry has come up with the concept of an API Policy to facilitate the encapsulation of the repeating logic. Similar to how Aspect Oriented Programming worked, these logical bundles can be applied to or removed from running APIs without effecting their lifecycle. No need to redeploy! The APIs know nothing of what you are doing! With the flick of a switch you can change the behaviour of your running API! This means that the configuration work we have done for our example above can disappear behind some UI forms which we fill out on API Manager (ldap connection details or OAuth configuration for example). Furthermore, if we use PingFederate for External Identity management we can even eliminate the need to fill out such forms. It would just be a question of applying the PingFederate Access Token Enforcement Policy with a single click!

Let’s revisit our example API and the requirement to secure it in the light of what we currently have in the area of Policies. At this moment Policies must be applied only at the level of the API itself (Resource level Policies are coming very soon!) so we will have to choose either Basic Authentication or OAuth 2.0 for our entire API.

For our two use cases you will see a similarity to the concepts described in our configuration above in the following diagram.

Here, the Http Basic Authentication policy corresponds to the http-security-filter above. The OAuth 2.0 Provider corresponds to the oauth-provider config above and the OAuth 2.0 Access Token Enforcement corresponds to the token validation processor. Both Policies use the security-manager as we have discussed.

End Result

Core to our understanding of the application of Policies is that the Policies themselves are actually snippets of Mule configuration. These configurations are received by Gateway as it regularly consumes API Manager’s own API in order to receive any newly applied or removed Policies. It then proceeds to inject the configurations into the managed API. While we start out with no manual configuration of the LDAP server, CORS protection or OAuth configuration in our API, when we manage it in the Anypoint Platform for APIs and we apply the relevant Policies we end up with the same fully protected API as we developed above.

Identity-based Policies

We must return to our discussion about Identity in the light of what Anypoint has to offer in its suite of Policies. Though not all strictly categorized as security policies, the following ones are inherently dependent on a mechanism to verify incoming Identity tokens:

  • Client ID enforcement: a means to lock-down your API for consumption only by a set of known clients.
  • SLA-based Rate Limiting: a means to provide different quality of service contracts to your known clients, 10 calls a minute for some, 100 calls a second for others, etc.
  • SLA-based Throttling: same as Rate Limiting only exceeded calls are queued for next time window.
  • OAuth 2.0 access token enforcement: a means to validate incoming tokens previously issued by Anypoint OAuth Provider upon receipt of client ID and secret.
  • PingFederate access token enforcement: a means to validate incoming tokens previously issued by PingFederate OAuth Provider upon receipt of client ID and secret.

To achieve this, the client IDs and secrets of consuming Apps must necessarily be stored in a datastore somewhere. By default this is the responsibility of the Anypoint Platform. When you register a new consuming App in the Developer Portal, the platform generates a new Client ID and secret and persists it. Later, when any of the above Policies are applied to your API, Gateway downloads these, as we have seen, and also downloads the Client ID and secret for every consuming App registered to consume your API. Thus, when Gateway injects the Policy configuration into your API, it also provides access to a local embedded database of IDs and secrets which the Policy can consult to verify the identity of the calling client. When you choose to integrate your Anypoint Organization with External Identity Management like PingFederate, then this assumes the role of administering and persisting Client ID and secrets, but the same process takes place for the application of Policies and the actual Identity verification executed by the same.

In Conclusion

What we have shown how extremely easy it is to secure your APIs whether it be through simple Basic Authentication or the more powerful and complex and secure OAuth 2.0. Also we have demonstrated that we can encapsulate such security logic in the form of Policies which can be applied at the flick of a switch and with zero development effort to multiple APIs. Finally, also through Policy application we have shown how you can hook up your organization with an external Identity Provider to bring power and ease to their maximum expression.

You can download the example API from here. There are two branches to the commit. The policy branch elimintates all manual security configuration.


We'd love to hear your opinion on this post