Skip to Content

Introduction

When your project is moving from a monolith architecture to microservices architecture security can be an important aspect. Microservices architectures are highly distributed by nature and characterized by an increased amount of network traffic. Usually the business data are  accessible via REST APIs and can  easily be stolen if you don’t protect them properly. These calls should be protected against man-in-the-middle-attacks by using the HTTPS protocol, but the API endpoints have to be secured as well. The effort for the  security checks should be well balanced with the effort to call a microservice API otherwise your architecture will never perform well. To protect the endpoint each microservice should get an identity and a set of permissions so that the API endpoint security component is able to verify both. An identity can be provided with several methods:

  • Digital X.509 certificates provides a high level of security but the maintenance effort is relatively high to generate and sign all those certificates for each individual microservice. This can be also a costly variant if you don’t have an in-house certificate authority. If you have a higher security demand this might be the right option for you.
  • Service accounts are an cheaper alternative but you send always the password in a basic authentication header which isn’t encrypted. If the transport protocol is encrypted with SSL this might be an option for you. The endpoint needs a component which checks the security of incoming requests and let only pass those which have a valid authentication and the requires permissions. In a distributed architecture the security component needs a central security service for checking the authentication and authorization which could be a critical performance overhead.
  • Since some years exist an alternative with the OAuth specification which is finalized in version 2 in 2012. OAuth 2 is lightweight authentication framework with a central authorization server from which a client needs to acquire an access token to access a protected resource on a resource server. The resource server could be a web server which hosts the REST API and the client could be a user interface component or another microservice. This entire setup seems to be a lot of overhead but with a special twist this variant can be a viable alternative for securing your microservices.

 

In this first part I want to describe the last variant only because the others are well known and you can find easily information in the internet. The second part I’ll go deeper into an implementation part based on Spring Cloud Security.

JSON Web Tokens

In OAuth the access to a resource is only allowed if you present a valid access token. The specification doesn’t define how an access token has to look like. The authorization server can issue access tokens in the form of JSON web token (JWT). A JWT are basically a signed JSON documents which can optionally be encrypted. These JWT are send in the HTTP header as bearer tokens to the resource server so that it can verify the authentication and authorization of the client request. This is possible because the resource server and the authorization server have established a trust relationship before via a shared secret or a public key. In that way the resource server can validate the signature of the JSON web token. The content of the JWT contains other important information to be verified like:

  • client
  • lifetime
  • scopes
  • roles

Because of this information the resource server doesn’t have to call back to the central security service but can check the authentication and authorization by itself. The JWT content can be extended with other information but should be limited to the necessary information because it can become very large otherwise.

You can look into the web token for instance with the help of http://jwt.io. The header defines with signature algorithm is used:


{
  "alg": "RS256"
}




The payload contains all necessary information:


{
  "exp": 2309614822,
  "scope": [
    "read_user",
    "send_mail"
  ],
  "authorities": [
    "ROLE_TRUSTED_CLIENT"
  ],
  "jti": "9ec15927-80db-49eb-825f-0a7b01525906",
  "client_id": "TestClient"
}



Client Credentials Grant

OAuth 2 defines four authorization grants for different login scenarios with web or browser based user interfaces. In our scenario we are more interested in the fourth grant called client credential grant which allowed clients to get access tokens by providing the client id and a secret. With this grant each microservice gets its own client identity and credential which has to be sent along with the access token request to the authorization server. This has the advantage that you have control over all microservice credentials at the authorization server and you can withdraw access for a microservice if the password is compromised. Also the scopes and roles can be controlled as discussed in the next section. The following diagram shows the flow in detail:

Client Credential Grant.png

The returned access tokens are usually valid for 12 hours. When the token is expired the microservice has to come back with the credentials to get a new one. Any change to the access privileges are then reflected in the new token.

Authorization

As mentioned above the JWT can contain authorization information like scopes or roles. The OAuth 2 specification defines scopes as a list of case-sensitive strings. These scopes can be used to define access to certain microservices. For instance the user microservice could define scopes read_user and write_user. Any client which wants to access user resources has to have at least the read_user scope. For user modification the write_user scope is required. It is up to the microservice to define those scopes. The scope configuration for each microservice is done centrally in the authorization server. This makes it easy to get an complete overview which microservice can call which other service.

Roles or authorities aren’t defined by OAuth 2 but can be used as an additional authorization dimension on the resource server side. Roles can be defined by the Spring Cloud Security implementation I’ll use in the next part of this blog to demonstrate how JSON web tokens can be used in practice.

References

To report this post you need to login first.

Be the first to leave a comment

You must be Logged on to comment or reply to a post.

Leave a Reply