Security for Microservices with Spring

Dave Syer, 2014
Twitter: @david_syer

(Security for Microservices with Spring)




What Are the Security Requirements

Stop bad guys from accessing your resources

Identity and permissions:

HTTP Basic Authentication


    $ curl "https://$username:$password@myhost/resource"

Simple Service

class Application {

   def home() {
      [status: 'OK']


So what's wrong with that?

Certificate Based Security


$ curl -k --cert rod.pem:password https://localhost:8443/hello

So what's wrong with that?

Custom Authentication Token

So what's wrong with that?

OAuth2 Key Features

So what's wrong with that?

OAuth2 and the Microservice

Example command line Client:

$ curl -H "Authorization: Bearer $TOKEN" https://myhost/resource

Simple Resource Server

class ResourceServer {
    JwtTokenStore tokenStore() throws Exception {
        JwtAccessTokenConverter enhancer = 
            new JwtAccessTokenConverter()
        new JwtTokenStore(enhancer)

N.B. in a real system you would have to configure the verifierKey (or use JdbcTokenStore)

Simple Authorization Server

class AuthorizationServer extends AuthorizationServerConfigurerAdapter {

   void configure(ClientDetailsServiceConfigurer clients) throws Exception {


Example token contents

JWT Bearer Tokens

OAuth2 and the Microservice

Spring Cloud Security

A further level of abstraction to make common microservice security use cases really easy to implement

Simple SSO Client

class Demo {
$ spring jar app.jar app.groovy
$ cf push -p app.jar

(That's it.)

How Does that Work?

Answer: configuration conventions. The app was bound to a service

$ cf bind-service app sso

and the service provides credentials.

To create the same bindings manually (e.g. in application.yml):

    clientId: acme
    clientSecret: ${CLIENT_SECRET}
    id: openid
    serviceId: ${PREFIX:}resource

Resource Server with Spring Cloud

class Demo {
  def home() { [id: UUID.randomUUID().toString(), content: "Hello Remote"] }

How does it work? Same as @EnableOAuth2Sso (bind to service providing credentials for conventional external configuration).

Single Page Apps

With backend services CORS restrictions make reverse proxy useful (@EnableZuulProxy). Then you can acquire tokens in the client app and relay them to back end.

With no backend services, don't be shy, use the session (authorization code flow is vastly superior).

Spring Session helps a lot too.

Relaying User Tokens

Front end app sends SSO token with user credentials to authenticate back end requests, back ends just relay it to each other as necessary.

Simple but possibly flawed: the front end only needs access to user details to authenticate, but you need to give it permission to do other things to allow it access to the back ends.

Idea: exchange (with full authentication) the incoming token for an outgoing one with different permissions (client but not scope). Can use password grant (e.g. with the incoming token as a password).

Token Relay with Spring Cloud

class Demo {

Other Options

In Conclusion