diff --git a/spring-cloud.html b/spring-cloud.html index 910de1e..6f83d16 100644 --- a/spring-cloud.html +++ b/spring-cloud.html @@ -477,18 +477,8 @@ body.book #toc,body.book #preamble,body.book h1.sect0,body.book .sect1>h2{page-b
  • Turbine
  • -
  • Declarative REST Client: Feign - -
  • -
  • Client Side Load Balancer: Ribbon - -
  • +
  • Declarative REST Client: Feign
  • +
  • Client Side Load Balancer: Ribbon
  • External Configuration: Archaius
  • Router and Filter: Zuul
  • -
  • Configuring Downstream Authentication
  • Spring Cloud for Cloud Foundry @@ -636,10 +625,7 @@ repository. Then try it out as a client:

    repository (at "spring.cloud.config.server.git.uri") and use it to initialize a mini SpringApplication. The mini-application’s Environment is used to enumerate property sources and publish them -via a JSON endpoint.

    - -
    -

    The HTTP service has resources in the form:

    +via a JSON endpoint. The service has resources in the form:

    @@ -655,10 +641,7 @@ via a JSON endpoint.

    SpringApplication (i.e. what is normally "application" in a regular Spring Boot app), "profile" is an active profile (or comma-separated list of properties), and "label" is an optional git label (defaults to -"master".)

    -
    -
    -

    The YAML and properties forms are coalesced into a single +"master".) The YAML and properties forms are coalesced into a single map, even if the origin of the values (reflected in the "propertySources" of the "standard" form) has multiple sources.

    @@ -689,7 +672,7 @@ users. Example Maven configuration:

    <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-parent</artifactId> - <version>1.0.0.BUILD-SNAPSHOT</version> + <version>1.0.0.RC1</version> <type>pom</type> <scope>import</scope> </dependency> @@ -795,66 +778,10 @@ Server? The strategy that governs this behaviour is the EnvironmentRepository, serving Environment objects. This Environment is a shallow copy of the domain from the Spring Environment (including propertySources as the main feature). The -Environment resources are parametrized by three variables:

    -
    -
    - -
    -
    -

    Repository implementations generally behave just like a Spring Boot -application loading configuration files from a "spring.config.name" -equal to the {application} parameter, and "spring.profiles.active" -equal to the {profiles} parameter. Precedence rules for profiles are -also the same as in a regular Boot application: active profiles take -precedence over defaults, and if there are multiple profiles the last -one wins (like adding entries to a Map).

    -
    -
    -

    Example: a client application has this bootstrap configuration:

    -
    -
    -
    bootstrap.yml
    -
    -
    spring:
    -  application:
    -    name: foo
    -  profiles:
    -    active: dev,mysql
    -
    -
    -
    -

    (as usual with a Spring Boot application, these properties could also -be set as environment variables or command line arguments).

    -
    -
    -

    If the repository is file-based, the server will create an -Environment from application.yml (shared between all clients), and -foo.yml (with foo.yml taking precedence). If the YAML files have -documents inside them that point to Spring profiles, those are applied -with higher precendence (in order of the profiles listed), and if -there are profile-specific YAML (or properties) files these are also -applied with higher precedence than the defaults. Higher precendence -translates to a PropertySource listed earlier in the -Environment. (These are the same rules as apply in a standalone -Spring Boot application.)

    -
    -
    -

    Git Backend

    -
    -

    The default implementation of EnvironmentRepository uses a Git -backend, which is very convenient for managing upgrades and physical +default implementation of EnvironmentRepository uses a Git backend, +which is very convenient for managing upgrades and physical environments, and also for auditing changes. To change the location of -the repository you can set the "spring.cloud.config.server.git.uri" +the repository you can set the "spring.cloud.config.server.uri" configuration property in the Config Server (e.g. in application.yml). If you set it with a file: prefix it should work from a local repository so you can get started quickly and easily @@ -865,29 +792,18 @@ would need to have all instances of the server pointing to the same repository, so only a shared file system would work.

    -

    This repository implementation maps the {label} parameter of the -HTTP resource to a git label (commit id, branch name or tag).

    -
    -
    -
    -

    File System Backend

    -

    There is also a "native" profile in the Config Server that doesn’t use -Git, but just loads the config files from the local classpath or file -system (any static URL you want to point to with -"spring.cloud.config.server.native.locations"). To use the native -profile just launch the Config Server with -"spring.profiles.active=native".

    -
    -
    -

    This repository implementation maps the {label} parameter of the -HTTP resource to a suffix on the search path, so properties files are +Git, but just loads the config files from the local classpath (or +anywhere else you want to point to with +"spring.cloud.config.server.locations"). To use the native profile +just launch the Config Server with "spring.profiles.active=native". In +the native profile the repository the "label" specification in the +HTTP resources is added to the search path, so properties files are loaded from each search location and a subdirectory with the same name as the label (the labelled properties take precedence in the Spring Environment).

    -

    Security

    @@ -1692,10 +1608,7 @@ is more convenient to use it behind a wrapper of some sort. Spring Cloud has support for Feign (a REST client builder) and also Spring RestTemplate using the logical Eureka service identifiers (VIPs) instead of physical -URLs. To configure Ribbon with a fixed list of physical servers you -can simply set <client>.ribbon.listOfServers to a comma-separated -list of physical addresses (or hostnames), where <client> is the ID -of the client.

    +URLs.

    @@ -2040,9 +1953,6 @@ for details on the properties available.

    The cluster parameter must match an entry in turbine.aggregator.clusterConfig.

    -
    -

    Value returned from eureka are uppercase, thus the examples of all uppercase CUSTOMERS

    -
    turbine:
    @@ -2095,86 +2005,13 @@ public interface StoreClient {
     }
    -
    -

    In the @FeignClient annotation the String value ("stores" above) is -the arbitrary name of the client, used to create a configuration -prefix (see below for details of Ribbon -support).

    -
    -
    -

    Example: How to Use Feign Without Eureka

    -
    -

    Eureka is a convenient way to abstract the discovery of remote servers -so you don’t have to hard code their URLs in clients, but if you -prefer not to use it, Ribbon and Feign are still quite -amenable. Suppose you have declared a Feign client as above for -"stores", and Eureka is not in use (and not even on the -classpath). You should find that the Ribbon client defaults to a -configured server list, and you can supply the configuration like this

    -
    -
    -
    application.yml
    -
    -
    stores:
    -  ribbon:
    -    listOfClients: example.com,google.com
    -
    -
    -

    Client Side Load Balancer: Ribbon

    -

    Ribbon is a client side load balancer which gives you a lot of control -over the behaviour of HTTP and TCP clients. Feign already uses Ribbon, -so if you are using @FeignClient then this section also applies.

    -
    -
    -

    A central concept in Ribbon is that of the named client. Each load -balancer is part of an ensemble of components that work together to -contact a remote server on demend, and the ensemble has a name that -you give it as an application developer (e.g. using the @FeignClient -annotation). Spring Cloud creates a new ensemble as an -ApplicationContext on demand for each named client using -RibbonClientConfiguration. This contains (amongst other things) an -ILoadBalancer, a RestClient, and a ServerListFilter.

    -
    -
    -

    Customizing the Ribbon Client

    -
    -

    You can configure some bits of a Ribbon client using external -properties in <client>.ribbon.*, which is no different than using -the Netflix APIs natively, except that you can use Spring Boot -configuration files (example -above). The native options can -be inspected as static fields in CommonClientConfigKey (part of -ribbon-core).

    -
    -
    -

    Spring Cloud also lets you take full control of the client by -declaring additional configuration (on top of the -RibbonClientConfiguration) using @RibbonClient. Example:

    -
    -
    -
    -
    @Configuration
    -@RibbonClient(name = "foo", configuration = FooConfiguration.class)
    -public class TestConfiguration {
    -}
    -
    -
    -
    -

    In this case the client is composed from the components already in -RibbonClientConfiguration together with any in FooConfiguration -(where the latter generally will override the former).

    -
    -
    -
    -

    Using the Ribbon API Directly

    -
    -

    You can also use the LoadBalancerClient directly. Example:

    +

    Usage of LoadBalancerClient directly:

    @@ -2190,12 +2027,8 @@ public class TestConfiguration { }
    -
    -
    -

    Spring RestTemplate as a Ribbon Client

    -

    You can use Ribbon indirectly via an autoconfigured RestTemplate -(provided Spring Cloud and Ribbon are both on the classpath):

    +

    Indirect usage via RestTemplate.

    @@ -2210,14 +2043,6 @@ public class TestConfiguration { }
    -
    -

    The URI is inspected to see if it has a full host name, or a virtual -one. If it is virtual the Ribbon client is used to create a full -physical address. See -RibbonAutoConfiguration -for details of how the RestTemplate is set up.

    -
    -
    @@ -2469,7 +2294,7 @@ sure you have
    $ spring version
    -Spring CLI v1.2.0.RELEASE
    +Spring CLI v1.2.0.RC1
    @@ -2477,8 +2302,8 @@ Spring CLI v1.2.0.RELEASE
    -
    $ gvm install springboot 1.2.0.RELEASE
    -$ gvm use springboot 1.2.0.RELEASE
    +
    $ gvm install springboot 1.2.0.RC1
    +$ gvm use springboot 1.2.0.RC1
    @@ -2487,7 +2312,7 @@ $ gvm use springboot 1.2.0.RELEASE
    $ mvn install
    -$ spring install org.springframework.cloud:spring-cloud-cli:1.0.0.BUILD-SNAPSHOT
    +$ spring install org.springframework.cloud:spring-cloud-cli:1.0.0.RC1
    @@ -2585,7 +2410,7 @@ running on port 8080.

    To limit the scope that the client asks for when it obtains an access token -you can set spring.oauth2.client.scope (comma separated or an array in YAML). By +you can set oauth2.client.scope (comma separated or an array in YAML). By default the scope is empty and it is up to to Authorization Server to decide what the defaults should be, usually depending on the settings in the client registration that it holds.

    @@ -2655,96 +2480,46 @@ following properties in the Environment:

    • -

      spring.oauth2.client.* with * equal to clientId, clientSecret, -accessTokenUri, userAuthorizationUri and one of:

      -
      -
        +

        oauth2.client.* with * equal to clientId, clientSecret, +tokenUri, authorizationUri and one of:

        +
      • -

        spring.oauth2.resource.userInfoUri to use the "/me" resource +

        oauth2.resource.preferTokenInfo=false and +oauth2.resource.userInfoUri to use the "/me" resource (e.g. "https://uaa.run.pivotal.io/userinfo" on PWS), or

      • -

        spring.oauth2.resource.tokenInfoUri to use the token decoding endpoint -(e.g. "https://uaa.run.pivotal.io/check_token" on PWS).

        -
      • -
      -
      -
      -

      If you specify both the userInfoUri and the tokenInfoUri then -you can set a flag to say that one is preferred over the other -(preferTokenInfo=true is the default). Or

      -
      +

      oauth2.resource.tokenInfoUri to use the token decoding endpoint +(e.g. "https://uaa.run.pivotal.io/check_token" on PWS), or

    • -

      spring.oauth2.resource.jwt.keyValue to +

      oauth2.resource.jwt.keyValue or oauth2.resource.jwt.keyUri to decode a JWT token locally, where the key is a verification key. The verification key value is either a symmetric secret or PEM-encoded RSA public key. If you don’t have the key and it’s public you can provide a URI where it can be downloaded (as a JSON object with a -"value" field) with spring.oauth2.resource.jwt.keyUri. E.g. on PWS:

      +"value" field). E.g. on PWS: ++

      +
    • +
    +
    $ curl https://uaa.run.pivotal.io/token_key
     {"alg":"SHA256withRSA","value":"-----BEGIN PUBLIC KEY-----\nMIIBI...\n-----END PUBLIC KEY-----\n"}
    -
  • - - -
    - - - - - -
    -
    Warning
    -
    -If you use the spring.oauth2.resource.jwt.keyUri the authorization -server needs to be running when your application starts up. It will -log a warning if it can’t find the key, and tell you what to do to fix -it. -
    -

    You can set the preferred scope (as a comma-separated list or YAML -array) in spring.oauth2.client.scope. It defaults to empty, in which case +array) in oauth2.client.scope. It defaults to empty, in which case most Authorization Servers will ask the user for approval for the maximum allowed scope for the client.

    -

    There is also a setting for spring.oauth2.client.clientAuthenticationScheme which +

    There is also a setting for oauth2.client.authenticationScheme which defaults to "header" (but you might need to set it to "form" if, like Github for instance, your OAuth2 provider doesn’t like header -authentication). The spring.oauth2.client.* properties are bound to an instance -of AuthorizationCodeResourceDetails so all its properties can be specified.

    -
    -
    - - - - - -
    -
    Tip
    -
    -
    -

    To set an RSA key value in YAML use the "pipe" continuation -marker to split it over multiple lines ("|") and remember to indent -the key value (it’s a standard YAML language feature). Example:

    -
    -
    -
    -
    oauth2:
    -  resource:
    -    jwt:
    -      keyValue: |
    -        -----BEGIN PUBLIC KEY-----
    -        MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC...
    -        -----END PUBLIC KEY-----
    -
    -
    -
    +authentication).

    Access Decision Rules

    @@ -2767,7 +2542,7 @@ the matching patterns for the OAuth2 SSO, even if you have OAuth2SsoConfigurer beans as well. The default logout path is "/logout" and it gets similar treatment, as does the "home" page (which is the logout success page, defaults to "/"). Those paths can -be overriden by setting spring.oauth2.sso.*' (`loginPath, logoutPath and +be overriden by setting oauth2.sso.\*' (`loginPath, logoutPath and home.path).

    @@ -2792,40 +2567,6 @@ Spring Boot access control (Basic authentication, or whatever custom filters you put in place).

    -
    -

    Integrating with the Actuator Endpoints

    -
    -

    The Spring Boot Actuator endpoints ("/env", "/metrics", etc.) if -present will, by default, be protected by the standard Spring Boot -basic authentication. The SSO authentication filter is added in a -position directly behind the filter that intercepts requests to the -Actuator endpoints by default (i.e. -ManagementProperties.BASIC_AUTH_ORDER + 1 which is -Ordered.LOWEST_PRECEDENCE-9 or 2147483636). If you want to change -the order you can set spring.oauth2.sso.filterOrder. If you do that -and the value is less than the default, then you will need to consider -setting the access rules for the Actuator, since they will become -accessible to all authenticated users who sign on with the external -provider. One way to do that would be to set -management.contextPath=/admin (for instance) and use an -OAuth2SsoConfigurer to set the access rules, e.g.

    -
    -
    -
    -
    	@Configuration
    -	@EnableOAuth2Sso
    -	@EnableAutoConfiguration
    -	protected static class TestConfiguration extends OAuth2SsoConfigurerAdapter {
    -		@Override
    -		public void configure(HttpSecurity http) {
    -	         http.authorizeRequests()
    -                 .antMatchers("/admin/**").role("ADMIN")
    -                 .anyRequest().authenticated();
    -		}
    -	}
    -
    -
    -

    Resource Server

    @@ -2837,9 +2578,9 @@ doesn’t need a clientId and clientSecret if it i tokenInfoUri (i.e. if it has jwt.* or userInfoUri).

    -

    By default all your endpoints are protected (i.e. "/**") but you can +

    By default all your endpoints are protected (i.e. "/") but you can pick and choose by adding a ResourceServerConfigurerAdapter (standard -Spring OAuth feature), e.g. to protect only the "/api/**" resources

    +Spring OAuth feature), e.g. to protect only the "/api/" resources

    Application.java
    @@ -2857,9 +2598,9 @@ class Application extends ResourceServerConfigurerAdapter { .anyRequest().authenticated(); } - @RequestMapping("/api") - public String home() { - return "Hello World"; + @RequestMapping('/api') + String home() { + 'Hello World' } } @@ -2883,6 +2624,12 @@ it is proxying. Thus the SSO app above can be enhanced simply like this:

    @EnableZuulProxy class Application { + @RequestMapping('/') + @ResponseBody + String home() { + 'Hello World' + } + }
    @@ -2903,12 +2650,6 @@ classpath (via @EnableZuulProxy). The just extracts an access token from the currently authenticated user, and puts it in a request header for the downstream requests.

    - - - -
    -

    Configuring Downstream Authentication

    -

    You can control the authorization behaviour downstream of an @EnableZuulProxy through the proxy.auth.* settings. Example:

    @@ -2938,6 +2679,7 @@ ProxyAuthenticationProperties for full details.

    +

    Spring Cloud for Cloud Foundry

    @@ -3031,11 +2773,11 @@ instance).

    OAuth2 Single Sign On

    Spring Cloud Security provides the @EnableOAuth2Sso annotation and -binds the app to environment properties in spring.oauth2.*. Spring Cloud +binds the app to environment properties in oauth2.*. Spring Cloud for Cloud Foundry just sets up default environment properties so that it all just works if you bind to a Cloud Foundry service instance called "sso". The service credentials are mapped to the SSO -properties, i.e. (from spring.oauth2.client.*) clientId, clientSecret, +properties, i.e. (from oauth2.client.*) clientId, clientSecret, tokenUri, authorizationUri, (and from oauth2.resource.*) userInfoUri, tokenInfoUri, keyValue, keyUri. Refer to the Spring Cloud Security documentation for details of which combinations @@ -3043,8 +2785,8 @@ will work together. The main thing is that in Cloud Foundry you only need one service to cover all the necessary credentials.

    -

    To use a different service instance name (i.e. not "sso") just set -spring.oauth2.sso.serviceId to your custom name.

    +

    To use a different sercice instance name (i.e. not "sso") just set +oauth2.sso.serviceId to your custom name.

    @@ -3052,7 +2794,7 @@ need one service to cover all the necessary credentials.

    Spring Cloud Security already has support for decoding JWT tokens if you just provide the verification key (as an environment property). In -Cloud Foundry you can pick that property up from a service binding +Cloud Foundry you can pick that property up from a servcice binding (keyValue or keyUri).

    @@ -3090,7 +2832,7 @@ service or the "resource" service if you have one).

    To use a different sercice instance name (i.e. not "resource" or -"sso") just set spring.oauth2.resource.serviceId to your custom name.

    +"sso") just set oauth2.resource.serviceId to your custom name.

    @@ -3101,13 +2843,13 @@ service or the "resource" service if you have one).

    • -

      spring.oauth2.sso.* to vcap.services.${spring.oauth2.sso.serviceId:sso}.credentials.*

      +

      oauth2.sso.* to vcap.services.${oauth2.sso.serviceId:sso}.credentials.*

    • -

      spring.oauth2.client.* to vcap.services.${spring.oauth2.sso.serviceId:sso}.credentials.tokenUri:${vcap.services.${spring.oauth2.resource.serviceId:resource}.credentials.*

      +

      oauth2.client.* to vcap.services.${oauth2.sso.serviceId:sso}.credentials.tokenUri:${vcap.services.${oauth2.resource.serviceId:resource}.credentials.*

    • -

      spring.oauth2.resource.(jwt).* to vcap.services.${spring.oauth2.resource.serviceId:resource}.credentials.tokenUri:${vcap.services.${spring.oauth2.sso.serviceId:sso}.credentials.*

      +

      oauth2.resource.(jwt).* to vcap.services.${oauth2.resource.serviceId:resource}.credentials.tokenUri:${vcap.services.${oauth2.sso.serviceId:sso}.credentials.*

    @@ -3117,7 +2859,7 @@ service or the "resource" service if you have one).