miércoles, 26 de septiembre de 2018

Microservices security with Spring Cloud and how to integrate oauth2 with spring security roles

There is many ways to secure our microservices application depending of architecture. In this case we will have one front-end service and four back-end services behind of a proxy. We also will use oauth2 that allow to obtain limited access to an HTTP service, either on behalf of a resource owner by orchestrating an approval interaction between the resource owner and the HTTP service.


The interesting thing about oauth2 is that allows access to the resources of services using a security token. This token (JWT) contain all information necessary for working with the services. The token allow refresh when has expired. Using JWT we have the advantage that the resource server don't need checking the authorization with the ouath2 authorization server, because this information is found into token.

OAuth2 defines severals roles that we will see latter how to implement it with spring cloud

  • Resource Server: Services hosting protected data. Backend services.
  • Client: application requesting access to a resource server. Web 
  • Authorization Server: server issuing access token to the client. This token will be used for the client to request the resource server.
We will use authorization code grant to allow to the web layer to obtain a long-lived access token since it can be renewed with a refresh token. This token will be propagated throught ZuulProxy to the all backend services. We will see how configure ZuulProxy to allow authorization header.

Another aspect important is how to integrate oauth2 with spring security roles, since in a spring application it is easier use  spring security roles. We will see latter.

The authorization dance can be seen in the figure below:



Implementation


Authorization service

The authorization service is composed of two parts:

Oauth2 authorization server configuration. In this section we configure the ouath2 features as  the authorize grant type (authorization code) and the token type (jwt).


Web security configuration. Oauth2 has severals endpoint for authorization (/oauth/authorize) and for access token. This endpoint must be protected. To do this, we going to use web spring security. When a client tries access to /oauth/authorize endpoint, srping redirect the request to login page. 


Is important configure security.oauth2.resource.filter-order=5 to prioritize web security configuration over oauth2 configuration.

Client service (web)

We will use  spring oauth client. With Spring Security 5 is support for writing applications that integrate with services that are secured with OAuth 2. This includes the ability to sign into an application by way of an external service such as Facebook or GitHub or in our case with our own authorization service.

With Spring Security 5 is very easy configure the client service. The first step will be configure the autorization server as we can see in the figure below. In our case we configure a customer provider call school-provider The most important is define the security endpoints (authorization-url, toke-uri, etc). This endpoints are created  by spring oauth2 security.



When we request a token to the authorization service into this token comes the spring roles information. The problem is that spring oauth client doesen't inject this information (roles) into security context. We have that inject the roles into security context as we can see in the figure below.


From any service we need inject the authorization header with the barer token to communicate with others services, in our case using feign. Hence we must create a request interceptor and add the token in the requesttemplate, as we can see in the figure below.


The last step we need tell to spring all of the above in the configuration file.


In this point we already can use all features for securizing our web application.



Proxy service (zuul)

If we use a proxy service we must configure the proxy Zuul send all headers. To do this, we can define ignoreSecurityHeaders = true


Resource service (ClassroomSchool, etc)

The configuration is direct. It's configure of similar way that any application configurated with spring security. Adding @EnableResouceServer and we configure security roles for each endpoint. As we are using jwt token the spring oauth2 doesn't need connect with the authorization server to autorize the resource and get the security roles, because the information is into jwt token.


View code: Here