Slide 1

Slide 1 text

Security for Microservices with Spring Dave Syer, 2012 Twitter: @david_syer Email: dsyer@pivotal.io (Security for Microservices with Spring) http://localhost:4000/decks/microservice-security.html 1 of 47 10/09/14 06:47

Slide 2

Slide 2 text

Agenda What is a Microservice? How would it be secure? If I was going to use Spring how would that look? What's the easiest way to get something working? http://localhost:4000/decks/microservice-security.html 2 of 47 10/09/14 06:47

Slide 3

Slide 3 text

Introduction There is a strong trend in distributed systems with lightweight architectures People have started to call them "microservices" So what are people doing about security in such systems? http://localhost:4000/decks/microservice-security.html 3 of 47 10/09/14 06:47

Slide 4

Slide 4 text

What is a Microservice? HTTP transport (usually). Text-based message content, usually JSON. Small, compact messages, and quick responses. REST-ful, or at least inspired by the REST Some degree of statelessness Interoperability. http://localhost:4000/decks/microservice-security.html 4 of 47 10/09/14 06:47

Slide 5

Slide 5 text

What Are the Security Requirements Stop bad guys from accessing your resources Identity and permissions: How is identity and permission information conveyed to a service? How is it decoded and interpreted? What data are needed to make the access decision (user accounts, roles, ACLs etc.)? How is the data managed: who is responsible for storing and retrieving it? How can you verify that the request hasn't been tampered with? http://localhost:4000/decks/microservice-security.html 5 of 47 10/09/14 06:47

Slide 6

Slide 6 text

HTTP Basic Authentication Something of a lowest common denominator Supported on practically all servers natively and out of the box Ubiquitous support on the client side in all languages Good support in Spring Security Spring Boot autoconfigures it out of the box Example: $ curl "https://$username:$password@myhost/resource" http://localhost:4000/decks/microservice-security.html 6 of 47 10/09/14 06:47

Slide 7

Slide 7 text

Simple Service @Grab('spring-boot-starter-security') @RestController class Application { @RequestMapping("/") def home() { [status: 'OK'] } } http://localhost:4000/decks/microservice-security.html 7 of 47 10/09/14 06:47

Slide 8

Slide 8 text

So what's wrong with that? Nothing, but... Where do you get the credentials (the username and password)? Fine for systems where all participants can share secrets securely In practice that means small systems Only supports username/password Only covers authentication No distinction between users and machines http://localhost:4000/decks/microservice-security.html 8 of 47 10/09/14 06:47

Slide 9

Slide 9 text

Network Security Microservice endpoints not visible outside an internal network Very secure Very flexible (e.g. using virtual networks) Suits architecture based on "edge" server http://localhost:4000/decks/microservice-security.html 9 of 47 10/09/14 06:47

Slide 10

Slide 10 text

So what's wrong with that? Nothing, but... Annoying to debug and a little bit fiddly to maintain Configuration is out of the control of developers in many cases for organizational reasons There's no identity or authentication http://localhost:4000/decks/microservice-security.html 10 of 47 10/09/14 06:47

Slide 11

Slide 11 text

Certificate Based Security Set up SSL on server so that request has to contain certificate Spring Security (X.509) can turn that into an Authentication If SSL is in the service layer (i.e. not at the router/loadbalancer) then you have a keystore anyway Example: $ curl -k --cert rod.pem:password https://localhost:8443/hello http://localhost:4000/decks/microservice-security.html 11 of 47 10/09/14 06:47

Slide 12

Slide 12 text

So what's wrong with that? Nothing, but... There's no user identity (only at most the machine) unless browsers have certificates installed Requires keystores and certificates in all applications and services (significantly non-trivial if done properly, but some organizations require it anyway) No fine distinction between users and machines http://localhost:4000/decks/microservice-security.html 12 of 47 10/09/14 06:47

Slide 13

Slide 13 text

Custom Authentication Token Random identifier per authentication Grant them from a central service and/or store in a central database Can be exposed directly via developer UI Re-hydrate authentication in service Spring Security AbstractPreAuthenticatedProcessingFilter and friends Even easier: Spring Session identifier Github example: token is temporary password in HTTP Basic http://localhost:4000/decks/microservice-security.html 13 of 47 10/09/14 06:47

Slide 14

Slide 14 text

So what's wrong with that? Nothing, but... No separation of client app from user authentication Coarse grained authorization (all tokens activate all resources) It's not a "standard" (but there are ready made implementations) For user authentication, need to collect user credentials in app http://localhost:4000/decks/microservice-security.html 14 of 47 10/09/14 06:47

Slide 15

Slide 15 text

OAuth2 Key Features Extremely simple for clients Access tokens carry information (beyond identity) Resources are free to interpret token content http://localhost:4000/decks/microservice-security.html 15 of 47 10/09/14 06:47

Slide 16

Slide 16 text

So what's wrong with that? Nothing, but... No standard (yet) for request signing http://localhost:4000/decks/microservice-security.html 16 of 47 10/09/14 06:47

Slide 17

Slide 17 text

Quick Introduction to OAuth2 A Client application, often web application, acts on behalf of a User, but with the User's approval Authorization Server Resource Server Client application Common examples of Authorization Servers and Resource Servers on the internet: Facebook - Graph API Google - Google APIs Cloud Foundry - Cloud Controller http://localhost:4000/decks/microservice-security.html 17 of 47 10/09/14 06:47

Slide 18

Slide 18 text

OAuth2 Bearer Tokens Centralizing account management and permissions: OAuth 2.0 adds an extra dimension - more information for the access decision Standards always help in security Lightweight - easy to curl Requires HTTPS for secure operation, but you can test with HTTP http://localhost:4000/decks/microservice-security.html 18 of 47 10/09/14 06:47

Slide 19

Slide 19 text

OAuth2 and the Microservice Example command line Client: $ curl -H "Authorization: Bearer $TOKEN" https://myhost/resource https://myhost is a Resource Server TOKEN is a Bearer Token it came from an Authorization Server http://localhost:4000/decks/microservice-security.html 19 of 47 10/09/14 06:47

Slide 20

Slide 20 text

Simple Authorization Server @EnableAuthorizationServer class AuthorizationServer extends AuthorizationServerConfigurerAdapter { @Override void configure(ClientDetailsServiceConfigurer clients) throws Exception { clients.inMemory() .withClient("my-client-with-secret")... } } http://localhost:4000/decks/microservice-security.html 20 of 47 10/09/14 06:47

Slide 21

Slide 21 text

Example token contents Client id Resource id (audience) Issuer User id Role assignments http://localhost:4000/decks/microservice-security.html 21 of 47 10/09/14 06:47

Slide 22

Slide 22 text

JWT Bearer Tokens OAuth 2.0 tokens are opaque to clients But they carry important information to Resource Servers Example of implementation (from Cloud Foundry UAA, JWT = signed, base64-encoded, JSON): { "client_id":"cf", "exp":1346325625, "scope": ["cloud_controller.read","openid","password.write"], "aud":["openid","cloud_controller","password"], "iss": "https://login.run.pivotal.io", "user_name":"tester@vmware.com", "user_id":"52147673-9d60-4674-a6d9-225b94d7a64e", "email":"tester@vmware.com", "jti":"f724ae9a-7c6f-41f2-9c4a-526cea84e614" } http://localhost:4000/decks/microservice-security.html 22 of 47 10/09/14 06:47

Slide 23

Slide 23 text

JWT Authorization Server @EnableAuthorizationServer class AuthorizationServer extends AuthorizationServerConfigurerAdapter { @Bean public JwtAccessTokenConverter accessTokenConverter() { return new JwtAccessTokenConverter(); } @Override public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception { endpoints.authenticationManager(authenticationManager) .accessTokenConverter(accessTokenConverter()); } ... // client config } http://localhost:4000/decks/microservice-security.html 23 of 47 10/09/14 06:47

Slide 24

Slide 24 text

User Approvals An access token represents a user approval: http://localhost:4000/decks/microservice-security.html 24 of 47 10/09/14 06:47

Slide 25

Slide 25 text

http://localhost:4000/decks/microservice-security.html 25 of 47 10/09/14 06:47

Slide 26

Slide 26 text

User Approvals as Token An access token represents a user approval: http://localhost:4000/decks/microservice-security.html 26 of 47 10/09/14 06:47

Slide 27

Slide 27 text

http://localhost:4000/decks/microservice-security.html 27 of 47 10/09/14 06:47

Slide 28

Slide 28 text

Formal Model for User Approvals It can be an advantage to store individual approvals independently (e.g. for explicit revokes of individual scopes): http://localhost:4000/decks/microservice-security.html 28 of 47 10/09/14 06:47

Slide 29

Slide 29 text

http://localhost:4000/decks/microservice-security.html 29 of 47 10/09/14 06:47

Slide 30

Slide 30 text

Spring OAuth Support @EnableAuthorizationServer class AuthorizationServer extends AuthorizationServerConfigurerAdapter { @Override public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception { endpoints.tokenStore(tokenStore()); } @Bean public ApprovalStore approvalStore() throws Exception { TokenApprovalStore store = new TokenApprovalStore(); store.setTokenStore(tokenStore()); return store; } ... // client config and tokenStore() defined here } http://localhost:4000/decks/microservice-security.html 30 of 47 10/09/14 06:47

Slide 31

Slide 31 text

Simple Resource Server @EnableResourceServer class ResourceServer { @Bean TokenStore tokenStore() throws Exception { ... } } or @EnableResourceServer class ResourceServer { @Bean ResourceServerTokenServices tokenServices() throws Exception { ... } } http://localhost:4000/decks/microservice-security.html 31 of 47 10/09/14 06:47

Slide 32

Slide 32 text

Simple Client Application @EnableOAuth2Client class ClientApplication { @Autowired // session-scoped private OAuth2ClientContext clientContext @Bean OAuth2RestOperations restTemplate() { new OAuth2RestTemplate(resource, clientContext) } ... } http://localhost:4000/decks/microservice-security.html 32 of 47 10/09/14 06:47

Slide 33

Slide 33 text

Authorization Code Grant Summary Authorization Server authenticates the User 1. Client starts the authorization flow and obtain User's approval 2. Authorization Server issues an authorization code (opaque one-time token) 3. Client exchanges the authorization code for an access token. 4. http://localhost:4000/decks/microservice-security.html 33 of 47 10/09/14 06:47

Slide 34

Slide 34 text

Role of Resource Server Extract token from request and decode it 1. Make access control decision Scope Audience User account information (id, roles etc.) Client information (id, roles etc.) 2. Send 403 (FORBIDDEN) if token not sufficient 3. http://localhost:4000/decks/microservice-security.html 34 of 47 10/09/14 06:47

Slide 35

Slide 35 text

Role of the Authorization Server Grant tokens 1. Interface for users to confirm that they authorize the Client to act on their behalf 2. Authenticate users (/authorize) 3. Authenticate clients (/token) 4. #1 and #4 are covered thoroughly by the spec; #2 and #3 not (for good reasons). http://localhost:4000/decks/microservice-security.html 35 of 47 10/09/14 06:47

Slide 36

Slide 36 text

Client Registration and Scopes For secure channels a client has to authenticate itself to obtain a token, so it has to be known to the Authorization Server. Registration provides at a mimimum: authentication (shared secret) registered redirect URI (optional but essential to prevent attacks) allowed scopes (clients are not permitted access to all resources) Also useful: a way to identify which resources can be accessed ownership information (which user registered the client) http://localhost:4000/decks/microservice-security.html 36 of 47 10/09/14 06:47

Slide 37

Slide 37 text

More on Scopes Per the spec they are arbitrary strings. The Authorization Server and the Resource Servers agree on the content and meanings. Examples: Google: https://www.googleapis.com /auth/userinfo.profile Facebook: email, read_stream, write_stream UAA: cloud_controller.read, cloud_controller.write, scim.read, openid Authorization Server has to decide whether to grant a token to a given client and user based on the requested scope (if any). http://localhost:4000/decks/microservice-security.html 37 of 47 10/09/14 06:47

Slide 38

Slide 38 text

Authentication and the Authorization Server Authentication (checking user credentials) is orthogonal to authorization (granting tokens) They don't have to be handled in the same component of a large system Authentication is often deferred to existing systems (SSO) Authorization Server has to be able to authenticate the OAuth endpoints (/authorize and /token) It does not have to collect credentials (except for grant_type=password) http://localhost:4000/decks/microservice-security.html 38 of 47 10/09/14 06:47

Slide 39

Slide 39 text

OAuth2 and the Microservice Resource Servers might be microservices Web app clients: authorization code grant Browser clients (single page app): authorization code grant (better) or implicit grant Mobile and non-browser clients: password grant (maybe with mods for multifactor etc.) Service clients (intra-system): client credentials or relay user token http://localhost:4000/decks/microservice-security.html 39 of 47 10/09/14 06:47

Slide 40

Slide 40 text

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. http://localhost:4000/decks/microservice-security.html 40 of 47 10/09/14 06:47

Slide 41

Slide 41 text

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). http://localhost:4000/decks/microservice-security.html 41 of 47 10/09/14 06:47

Slide 42

Slide 42 text

OAuth 1.0 Another (slightly older) standard Includes request signing Common in early wave public APIs (e.g. Twitter) Spring Security OAuth is full solution at framework level http://localhost:4000/decks/microservice-security.html 42 of 47 10/09/14 06:47

Slide 43

Slide 43 text

So What's Wrong with That? Nothing but... It's hard work for client app developers (crypto) (Notionally at least) superseded by OAuth2 http://localhost:4000/decks/microservice-security.html 43 of 47 10/09/14 06:47

Slide 44

Slide 44 text

SAML Assertions Another standard with similar features to OAuth2 XML based Common infrastructure in enterprise Spring Security SAML provides SP and Consumer roles (not IDP) Request signing is standadized http://localhost:4000/decks/microservice-security.html 44 of 47 10/09/14 06:47

Slide 45

Slide 45 text

So What's Wrong with That? Nothing but... Painful to set up for servers and client Large amounts of XML data in HTTP headers Huge complexity for developers N.B. exchanging SAML assertion for OAuth2 token is quote normal http://localhost:4000/decks/microservice-security.html 45 of 47 10/09/14 06:47

Slide 46

Slide 46 text

In Conclusion Lightweight services demand lightweight infrastructure Security is important, but should be unobtrusive Spring Security makes it all easier Special mention for Spring Session OAuth 2.0 is a standard, and has a lot of useful features Spring Security OAuth aims to be a complete OAuth2 solution at the framework level Cloudfoundry has an open source, OAuth2 identity service (UAA) http://localhost:4000/decks/microservice-security.html 46 of 47 10/09/14 06:47

Slide 47

Slide 47 text

Links http://github.com/spring-projects/spring-security-oauth http://github.com/spring-projects/spring-security-oauth/tree/master /tests/annotation http://github.com/cloudfoundry/uaa http://blog.spring.io http://blog.cloudfoundry.org http://presos.dsyer.com/decks/microservice-security.html Twitter: @david_syer Email: dsyer@pivotal.io http://localhost:4000/decks/microservice-security.html 47 of 47 10/09/14 06:47