Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Security for Microservices with Spring

Dave Syer
September 09, 2014

Security for Microservices with Spring

This presentation explores a range of options for securing microservices, ranging from physical network security to token-based authentication with OAuth2. It shows how the combination of rapid development and production-ready features in the modern Spring stack are a perfect mixture for developing secure components in a system composed of microservices. We explore the new features in Spring OAuth2, guide you through the choice of which to use and when, and show how easy they are to enable quickly. Also available (with clickable links) at http://presos.dsyer.com/decks/microservice-security.html.

Dave Syer

September 09, 2014
Tweet

More Decks by Dave Syer

Other Decks in Technology

Transcript

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

    View Slide

  2. 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

    View Slide

  3. 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

    View Slide

  4. 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

    View Slide

  5. 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

    View Slide

  6. 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:[email protected]/resource"
    http://localhost:4000/decks/microservice-security.html
    6 of 47 10/09/14 06:47

    View Slide

  7. 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

    View Slide

  8. 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

    View Slide

  9. 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

    View Slide

  10. 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

    View Slide

  11. 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

    View Slide

  12. 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

    View Slide

  13. 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

    View Slide

  14. 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

    View Slide

  15. 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

    View Slide

  16. 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

    View Slide

  17. 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

    View Slide

  18. 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

    View Slide

  19. 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

    View Slide

  20. 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

    View Slide

  21. 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

    View Slide

  22. 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":"[email protected]",
    "user_id":"52147673-9d60-4674-a6d9-225b94d7a64e",
    "email":"[email protected]",
    "jti":"f724ae9a-7c6f-41f2-9c4a-526cea84e614" }
    http://localhost:4000/decks/microservice-security.html
    22 of 47 10/09/14 06:47

    View Slide

  23. 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

    View Slide

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

    View Slide

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

    View Slide

  26. 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

    View Slide

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

    View Slide

  28. 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

    View Slide

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

    View Slide

  30. 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

    View Slide

  31. 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

    View Slide

  32. 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

    View Slide

  33. 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

    View Slide

  34. 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

    View Slide

  35. 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

    View Slide

  36. 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

    View Slide

  37. 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

    View Slide

  38. 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

    View Slide

  39. 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

    View Slide

  40. 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

    View Slide

  41. 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

    View Slide

  42. 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

    View Slide

  43. 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

    View Slide

  44. 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

    View Slide

  45. 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

    View Slide

  46. 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

    View Slide

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

    View Slide