From 6c9a11d0e7b5a102c999af4ad4ebe9fbc569abda Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Wed, 8 Oct 2014 09:33:04 +0000 Subject: [PATCH] Sync docs from master to gh-pages --- spring-cloud.html | 248 ++++++++++++++++++++++++++++++++++------------ 1 file changed, 184 insertions(+), 64 deletions(-) diff --git a/spring-cloud.html b/spring-cloud.html index cc83db8..02577bc 100644 --- a/spring-cloud.html +++ b/spring-cloud.html @@ -478,9 +478,15 @@ body.book #toc,body.book #preamble,body.book h1.sect0,body.book .sect1>h2{page-b
  • Installation
  • -
  • Spring Cloud for Cloud Foundry +
  • Spring Cloud Security
  • @@ -507,7 +513,8 @@ centres, and managed platforms such as Cloud Foundry.

    Features

    -

    Spring Cloud focuses on providing good out of box experience for typical use cases and extensibility mechanism to cover others.

    +

    Spring Cloud focuses on providing good out of box experience for typical use cases +and extensibility mechanism to cover others.

      @@ -1612,99 +1619,212 @@ $ spring install org.springframework.cloud:spring-cloud-cli:1.0.0.BUILD-SNAPSHOT
    -

    Spring Cloud for Cloud Foundry

    +

    Spring Cloud Security

    -Integration between Cloud Foundry -and Spring Cloud. +Spring Cloud Security offers a set of primitives for building secure +applications and services with minimum fuss. A declarative model which +can be heavily configured externally (or centrally) lends itself to +the implementation of large systems of co-operating, remote components, +usually with a central indentity management service. It is also extremely +easy to use in a service platform like Cloud Foundry. Building on +Spring Boot and Spring Security OAuth2 we can quickly create systems that +implement common patterns like single sign on, token relay and token +exchange.
    -

    Service Broker Example

    +

    Quickstart

    +
    +

    OAuth Single Sign On

    -

    Example script to deploy and regis#ter a broker:

    +

    Here’s a Spring Cloud "Hello World" app with HTTP Basic +authentication and a single user account:

    +
    +
    +
    app.groovy
    +
    +
    @Grab('spring-boot-starter-security')
    +@Controller
    +class Application {
    +
    +  @RequestMapping('/'
    +  String home() {
    +    'Hello World'
    +  }
    +
    +}
    +
    +
    +
    +

    You can run it with spring run app.groovy and watch the logs for the password (username is "user"). So far this is just the default for a Spring Boot app.

    +
    +
    +

    Here’s a Spring Cloud app with OAuth2 SSO:

    +
    +
    +
    app.groovy
    +
    +
    @Grab('spring-cloud-starter-security')
    +@Controller
    +@EnableOAuth2Sso
    +class Application {
    +
    +  @RequestMapping('/'
    +  String home() {
    +    'Hello World'
    +  }
    +
    +}
    +
    +
    +
    +

    Spot the difference? This app will actually behave exactly the same as +the previous one, because it doesn’t know it’s OAuth2 credentals +yet.

    +
    +
    +

    You can register an app in github quite easily, so try that if you +want a production app on your own domain. If you are happy to test on +localhost:8080, then set up these properties in your application +configuration:

    +
    +
    +
    application.yml
    +
    +
    oauth2:
    +  client:
    +    clientId: bd1c0a783ccdd1c9b9e4
    +    clientSecret: 1a9030fbca47a5b2c28e92f19050bb77824b5ad1
    +    tokenUri: https://github.com/login/oauth/access_token
    +    authorizationUri: https://github.com/login/oauth/authorize
    +    authenticationScheme: form
    +  resource:
    +    userInfoUri: https://api.github.com/user
    +    preferTokenInfo: false
    +
    +
    +
    +

    run the app above and it will redirect to github for authorization. If +you are already signed into github you won’t even notice that it has +authenticated. These credentials will only work if your app is +running on port 8080.

    +
    +
    +

    If you now drop the app into Cloud Foundry:

    -
    DOMAIN=mydomain.net
    -cf push app -p target/*.jar --no-start
    -cf env app | grep SPRING_PROFILES_ACTIVE || cf set-env app SPRING_PROFILES_ACTIVE cloud
    -cf env app | grep APPLICATION_DOMAIN || cf set-env app APPLICATION_DOMAIN ${DOMAIN}
    -
    -cf services | grep configserver && cf bind app configserver
    -
    -cf restart app
    -cf create-service-broker app user secure http://app.${DOMAIN}
    -
    -for f in `cf curl /v2/service_plans | grep '\"guid' | sed -e 's/.*: "//' -e 's/".*//'`; do
    -    cf curl v2/service_plans/$f -X PUT -d '{"public":true}'
    -done
    -
    -cf create-service app free appi
    +
    $ spring jar app.jar app.groovy
    +$ cf push -p app.jar
    -

    At which point you have a service called "app" and a service instance called "appi":

    +

    and bind it to a service called "sso" with the following properties +(e.g. created as a +user-provided +service):

    -
    $ cf marketplace
    -OK
    +
    $ cf create-user-provided-service sso -p '{clientId:"<my-client>",clientSecret:"<my-secret>",userInfoUri:"https://uaa.run.pivotal.io/userinfo",tokenUri: "https://login.run.pivotal.io/oauth/token",authorizationUri:"https://login.run.pivotal.io/oauth/authorize"}
    +$ cf push app -p app.jar
    +
    +
    +
    +

    and then visit it in a browser, then it will redirect to the Cloud +Foundry (PWS) login server instead of challenging for Basic +authentication credentials. The clientId and clientSecret are +credentials of a registered client in Cloud Foundry. It’s quite hard +to get a Cloud Foundry client registration for testing (but please ask +at support@run.pivotal.io if you want one on PWS).

    +
    +
    +
    +

    OAuth Protected Resource

    +
    +

    You want to protect an API resource with an OAuth2 token? Here’s a +simple example (paired with the client above):

    +
    +
    +
    app.groovy
    +
    +
    @Grab('spring-cloud-starter-security')
    +@RestController
    +@EnableOAuth2Resource
    +class Application {
     
    -service        plans   description
    -app            free    Singleton service app
    -$ cf services
    -Getting services in org default / space development as admin...
    -OK
    +  @RequestMapping('/'
    +  def home() {
    +    [message: 'Hello World']
    +  }
     
    -name           service        plan   bound apps
    -appi           app            free
    +}
    -

    Your application can define a configuration property -application.domain (defaults to "cfapps.io") which will be used to -construct the credentials for any app that binds to your service. Or -it can define the URI directly using -cloudfoundry.service.definition.metadata.uri.

    +

    and

    +
    +
    +
    application.yml
    +
    +
    oauth2:
    +  resource:
    +    userInfoUri: https://api.github.com/user
    +    preferTokenInfo: false
    +
    +
    +
    +
    +

    Token Relay

    +
    +

    If your app has a +Spring +Cloud Zuul embedded reverse proxy (using @EnableZuulProxy) then you +can ask it to forward OAuth2 access tokens downstream to the services +it is proxying. Thus the SSO app above can be enhanced simply like this:

    +
    +
    +
    app.groovy
    +
    +
    @Controller
    +@EnableOAuth2Sso
    +@EnableZuulProxy
    +class Application {
    +
    +  @RequestMapping('/'
    +  String home() {
    +    'Hello World'
    +  }
    +
    +}
    +
    -

    You can change some other basic metadata by setting config properties:

    -
    -
    -
      -
    • -

      cloudfoundry.service.definition.* is bound to a -ServiceDefinition (defined in spring-boot-cf-service-broker) which -has optional setters for plans and metadata.

      -
    • -
    • -

      cloudfoundry.service.broker.* is bound to an internal bean. It has -optional setters for "name" (the service name), "description" (user -friendly description) and "prefix" (used to create a unique id from -the name).

      -
    • -
    +

    and it will (in addition to loggin the user in and grabbing a token) +pass the authentication token downstream to the /proxy/* +services. If those services are implemented with +@EnableOAuth2Resource then they will get a valid token in the +correct header.

    -

    An app which binds to your service will get credentials that contain a -"uri" property linking to your service. A Spring Boot app can bind to -that through the vcap.services.[service].credentials.uri environment -property.

    +

    How does it work? The @EnableOAuth2Sso annotation pulls in +spring-cloud-starter-security (which you could do manually in a +traditional app), and that has some autoconfiguration for a +ZuulFilter, which itself is activated because Zuul is on the +classpath (via @EnableZuulProxy). The +filter +just extracts an access token from the currently authenticated user, +and puts it in a request header for the downstream requests.

    -
    -

    If your service also has a -Eureka core dependency, and you -can expose it as a Eureka service, then any service which registers -with Eureka will also become a Cloud Foundry service.