WSO2 API Microgateway: Mutual SSL and Open API Security
- Hasunie Adikari
- Associate Technical Lead - WSO2
Introduction
Security is not an afterthought, it is an integral part of any project. Moreover, an API is an interface where internal and external users can expose business information. The information might be medical, financial, business, or sensitive personal data. Allowing users to access APIs helps expand the business and compete with global vendors. But the internet is not a nice place and you might not have the luxury of exposing expensive details in public without any security mechanism or control. Hackers are on the lookout for emerging vulnerable pipes.
A gateway acts as the major point of enforcement for the API traffic and it will allow users to authenticate the traffic as well. WSO2 API Microgateway is a lightweight proxy to the APIs and a significant component for managing microservices architecture from the API perspective. A microservice is a target individual task and a set of microservices is composed to handle multiple tasks in a collaborative manner through network calls among each component. While each component is handling its individual tasks, the microgateway is used to govern individual API calls. If each individual microservice implements its own security mechanisms, it will duplicate and increase the maintainability issues. But WSO2 API Microgateway enforces standard security mechanisms across all microservices.
Security is an evolving concept which has been there for decades and there are two main factors:
- Authentication - validation of credentials and verification of identity
- Authorization - verification of a user’s rights to grant him/her access to resources
Let's see how WSO2 API Microgateway supports the main security factors.
Mutual SSL (Certificate-based Authentication)
From an authentication perspective, a common practice in relatively large organizations is to secure their internal APIs using SSL key pairs issued by their own private CAs. This is where the mutual SSL comes into action. In fact, mutual SSL authenticates two parties through verifying the provided digital certificate so that both parties are assured of the other's identity. WSO2 API Microgateway supports mutual SSL as an authentication mechanism.
Example scenario
Let's see how we can achieve this requirement.
- Create the CoffeeBar using the command given below.
- Add the API to the CoffeeBar project by adding a Swagger file (.yaml or .json) to the CoffeeBar/api_definitions folder. A sample open API definition can be found here.
- Build the microgateway distribution for the project.
- Then we should enable the SSL authentication through the microgateway configuration file, micro-gw.conf.
- Default sslVerifyClient is set to “optional. That said, if the mutual SSL authentication has succeeded, OAuth authentication is skipped. If you set it as “require”, the mutual SSL becomes exclusive. If it fails, you will get an unauthorized(401) error.
- Then, configure the trust store and change “trustStore.path” property and “trustStore.password” property under “[listenerConfig]” instance ID. The truststore should have the certificate which is used to create SSL connections.
- Now, let's run the microgateway docker runtime mounting executable file(coffeebar.balx).
Micro-gw init CoffeeBar
Micro-gw build CoffeeBar
Note: Once the particular build command is executed, an executable file (/CoffeBar/target/coffeebar.balx) is created to expose the API via WSO2 API Microgateway.
Note: If you have been working on kubernetes/docker environment, you should enable the SSL authentication in
A sample configuration in micro-gw.conf is shown below:
Format:
docker run -d -v:/home/exec/ -p 9095:9095 -p 9090:9090 -e project="project-name"
- The path of the target directory created inside the project directory
Sample:
docker run -d -v /wso2am-micro-gw-toolkit/bin/coffeebar/target:/home/exec/ -p 9095:9095 -p 9090:9090 -e project="coffebar" wso2/wso2micro-gw:3.0.1
In order to successfully complete the SSL handshake, the public certificate of the WSO2 API Microgateway has to be imported to the trust store of the client and the public certificate of the client has to be imported to the ballerinaTruststore.p12.ballerina trust store which resides in the Micro-gw-runtime-home/runtime/bre/security folder.
In the example discussed in this blog, a self-signed certificate is added into the already available ballerina trust-store and the same certificate is imported into the client application. Let's see how to import server certs to Navigate to the browser’s certificate management section. On Firefox, navigate to Preferences > Privacy & Security > Certificates.
Figure 2
Add the certificate to the client.
Figure 3
Invoke the REST API using a REST API client from the browser.
Figure 4
The browser will present a user identification request, to select a certificate in order to use for the SSL connection. Select the certificate you added and click OK.
Figure 5
If you don’t import certificates properly, you will see the following error message:
curl: (35) error:1401E412:SSL routines:CONNECT_CR_FINISHED:sslv3 alert bad certificate
Open API Security
When organizations expose business services via an API-driven model, these services are exposed to both internal and external parties. Since an organization cannot expose all the services of an API to the public, they need to restrict access to the most valuable services only to authorized parties.
If revenue is generated by exposing APIs, it’s important to make sure that only authorized parties have access to the respective resources. In this scenario, securing APIs is an important task because unauthorized access to resources will affect revenue and eventually have a negative impact on the organization. Even though it may seem difficult to do, it’s mandatory to have a security solution that can facilitate fine-grained access control to every resource of an API.
WSO2 API Microgateway supports security schemas keyword in OPEN API definition to restrict the authorization per resource and at the API level.
Example scenario
Here is an example that explains the use of scopes via a real-world example. Let's take API called CoffeebarAPI to handle some operations in a coffee stole. This API can be used to add, update orders, and view the menu. Each resource is authorized through the scope and the token which has the particular scope only can invoke the particular API resource.To consume the API, you will need to obtain an access token with relevant scope otherwise you will encounter the unauthorized(401) issue.
The gateway supports the "securitySchemes" keyword in open API specifications. There are four types of security schemas in the open API specification - API key, HTTP, OAuth2, and OpenID Connect.
Most of the users tightly bond with OAuth2 authentication. But you may have several APIs that are exposed by WSO2 API Microgateway. All of them are secured with OAuth2 by default. But there may be a requirement for one API and it must be secured with basic auth. This means you simply use the username and password for authentication.
WSO2 API Microgateway currently supports OAuth2 and basic authentication under HTTP for APIs which can be defined via open API extensions. If none of the security schemes is defined, the gateway by default applies OAuth2 security.
You can refer to a sample configuration for OAuth2 and basic support below. This is how we define the security schema in the Swagger definition.
Figure 6
OAuth Authentication
Let's now see how we can try out the OAuth authentication type. You can refer to a sample configuration which depicts how you can refer the OAuth security schema in the resource level.
Figure 7
You can find a sample Swagger file here. Let's see how to apply the security schemas to our use case. The table below lists the mapping between scopes and resource.
Scope | Resource |
read:menu | GET /menu |
write:order, read:order | POST /order |
write:order, read:order | GET /order/{orderId} |
admin | POST /menu |
The user needs to obtain an access token to consume the respective resource. A scope allows you to specify what type of access is specifically required per resource. The scope of an access token defines what the access token can do and what resources it can access. In other words, the scope will add some limitations for the OAuth tokens.
Then you can move to consuming APIs according to the necessity of the user. Let's try to consume a GET /menu resource by a JWT token which is not contained required scopes.
In the microgateway ecosystem, users can use third-party key managers to obtain an access token. In this sample use case, I used Auth0 as an identity provider and generate 4 types of jwt tokens to depict the scenario.
Token type | Token name |
Token without scopes | TOKEN_A |
Token with write:order, read:order scopes | TOKEN_B |
Token with read: menu scopes | TOKEN_C |
Token with admin scope | TOKEN_D |
TOKEN_A
Try to invoke the POST /order resource from the TOKEN_A. The user can’t access the resource without having the write: order and read: order and he/she will get the following error message.
{"fault":{"code":900910, "message":"The access token does not allow you to access the requested resource", "description":"The access token does not allow you to access the requested resource"}}
TOKEN_B
Try to invoke all the resource but user can only invoke POST /order and GET /order/{orderId}
TOKEN_C
User can only consume the resource GET /menu resource.
TOKEN_D
User can only consume POST /menu resource.
Basic Authentication
Developers can define the basic OAuth under “securitySchemes” as in figure 6 so that he/she can refer to the particular security schema under the resource as shown below.
Figure 10
Now you can access the GET /order/{orderID} resource through basic auth. But where can you define the username and password? You can use micro-gw.conf file to define a username and password.
Note: If your project is deployed in a Kubernetes or docker environment, you should do all the configs in
You can refer to a sample config here:
Username: generalUser1
Password : password
Figure 11
Passwords are sensitive and it should be encoded in sha1 as shown above. Now all the configurations are completed. You can build the project and try out the basic authentication by using the following curl command:
Curl -X GET "https://localhost:9090/coffeebar/v1/order/1" -H "Authorization: Basic"
Summary
API security has come a long way from where it started and it has a long way to go. This blog focused on how the microgateway has been layering security over individual services. We discussed mutual SSL/certificate-based authentication and Open API security schemas. This blog also depicted how scopes can be used when consuming the resources of an API.
Click here to learn more about WSO2 API Microgateway.