This commit is contained in:
Dave Syer
2015-05-21 14:44:15 +01:00
parent 1a55cc1c71
commit 1c862dab2b
15 changed files with 127 additions and 159 deletions

View File

@@ -1,4 +1,4 @@
// Do not edit this file (e.g. go instead to src/main/asciidoc)
// Do not edit this file (e.g. go instead to docs/src/main/asciidoc)
Spring Cloud for Cloudfoundry makes it easy to run
https://github.com/spring-cloud[Spring Cloud] apps in
@@ -11,7 +11,7 @@ username to use for the service).
Add this project as a dependency to any Spring Cloud UI app or REST
service and deploy to Cloudfoundry. If you use Spring Cloud Security
OAuth2 features this will make them bindable to Cloud Foundry services
instead of enironment properties in `oauth2.*`. For a UI app you can
instead of enironment properties in `spring.oauth2.*`. For a UI app you can
declare `@EnableOAuth2Sso` and bind to a service called "sso", and for
a service you can add `@EnableOAuth2Resource` and bind to a service
called "resource" (see below for how to change the names).

54
docs/pom.xml Normal file
View File

@@ -0,0 +1,54 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-build</artifactId>
<version>1.0.2.BUILD-SNAPSHOT</version>
<relativePath />
</parent>
<artifactId>spring-cloud-cloudfoundry-docs</artifactId>
<packaging>pom</packaging>
<name>Spring Cloud for Cloud Foundry Docs</name>
<version>1.0.0.BUILD-SNAPSHOT</version>
<description>Spring Cloud Docs</description>
<properties>
<docs.main>spring-cloud-cloudfoundry</docs.main>
<main.basedir>${basedir}/..</main.basedir>
</properties>
<build>
<plugins>
<plugin>
<artifactId>maven-deploy-plugin</artifactId>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>docs</id>
<build>
<plugins>
<plugin>
<groupId>org.asciidoctor</groupId>
<artifactId>asciidoctor-maven-plugin</artifactId>
<inherited>false</inherited>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<inherited>false</inherited>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<inherited>false</inherited>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>

View File

@@ -0,0 +1,5 @@
include::intro.adoc[]
> NOTE: if you are looking for a way to bind to services then this is the wrong library. Check out the [Spring Cloud Connectors](https://github.com/spring-cloud/spring-cloud-connectors) instead.

View File

@@ -0,0 +1,12 @@
Spring Cloud for Cloudfoundry makes it easy to run
https://github.com/spring-cloud[Spring Cloud] apps in
https://github.com/cloudfoundry[Cloud Foundry] (the Platform as a
Service). Cloud Foundry has the notion of a "service", which is
middlware that you "bind" to an app, essentially providing it with an
environment variable containing credentials (e.g. the location and
username to use for the service).
This project provides an implementation of Spring Cloud Commons `DiscoveryClient` so you can `@EnableDiscoveryClient`
and provide your credentials as `spring.cloud.cloudfoundry.discovery.[email,password]` and then you can use the
`DiscoveryClient` directly or via a `LoadBalancerClient` (also `*.url` if you are not connecting to [Pivotal Web
Services](https://run.pivotal.io)).

View File

@@ -0,0 +1,30 @@
Here's a Spring Cloud app with Cloud Foundry discovery:
.app.groovy
[source,java]
----
@Grab('org.springframework.cloud:spring-cloud-cloudfoundry')
@RestController
@EnableDiscoveryClient
class Application {
@Autowired
DiscoveryClient client
@RequestMapping('/')
String home() {
'Hello from ' + client.getLocalServiceInstance()
}
}
----
If you run it without any service bindings:
----
$ spring jar app.jar app.groovy
$ cf push -p app.jar
----
it will show it's app name in the home page.

View File

@@ -0,0 +1,11 @@
= Spring Cloud for Cloud Foundry
include::intro.adoc[]
The first time you use it the discovery client might be slow owing to
the fact that it has to get an access token from Cloud Foundry.
== Quickstart
include::quickstart.adoc[]

View File

@@ -17,7 +17,7 @@ end
file = ARGV[0] if ARGV.length>0
srcDir = File.dirname(file)
out = "// Do not edit this file (e.g. go instead to src/main/asciidoc)\n\n"
out = "// Do not edit this file (e.g. go instead to docs/src/main/asciidoc)\n\n"
doc = Asciidoctor.load_file file, safe: :safe, parse: false
out << doc.reader.read

14
pom.xml
View File

@@ -14,6 +14,11 @@
<relativePath/>
</parent>
<properties>
<bintray.package>cloudfoundry</bintray.package>
<main.basedir>${basedir}</main.basedir>
</properties>
<scm>
<url>https://github.com/spring-cloud/spring-cloud-consul</url>
<connection>
@@ -29,13 +34,13 @@
<module>spring-cloud-cloudfoundry-discovery</module>
<module>spring-cloud-cloudfoundry-web</module>
<module>spring-cloud-cloudfoundry-sample</module>
<module>docs</module>
</modules>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
@@ -71,11 +76,4 @@
</dependencies>
</dependencyManagement>
<properties>
<cloudfoundry.version>0.0.1-SNAPSHOT</cloudfoundry.version>
</properties>
</project>

View File

@@ -54,7 +54,7 @@ public class CloudFoundryDiscoveryClientConfiguration {
public CloudFoundryClient cloudFoundryClient(CloudCredentials cc)
throws MalformedURLException {
CloudFoundryClient cloudFoundryClient = new CloudFoundryClient(cc, URI.create(
this.cloudFoundryDiscoveryProperties.getCloudControllerUrl()).toURL());
this.cloudFoundryDiscoveryProperties.getUrl()).toURL());
cloudFoundryClient.login();
return cloudFoundryClient;
}

View File

@@ -24,7 +24,7 @@ import org.springframework.boot.context.properties.ConfigurationProperties;
@ConfigurationProperties(prefix = "spring.cloud.cloudfoundry.discovery")
public class CloudFoundryDiscoveryProperties {
private String cloudControllerUrl = "https://api.run.pivotal.io";
private String url = "https://api.run.pivotal.io";
private String email;
@@ -40,12 +40,12 @@ public class CloudFoundryDiscoveryProperties {
this.enabled = enabled;
}
public String getCloudControllerUrl() {
return cloudControllerUrl;
public String getUrl() {
return url;
}
public void setCloudControllerUrl(String cloudControllerUrl) {
this.cloudControllerUrl = cloudControllerUrl;
public void setUrl(String cloudControllerUrl) {
this.url = cloudControllerUrl;
}
public String getEmail() {

View File

@@ -1,2 +0,0 @@
include::intro.adoc[]

View File

@@ -1,15 +0,0 @@
Spring Cloud for Cloudfoundry makes it easy to run
https://github.com/spring-cloud[Spring Cloud] apps in
https://github.com/cloudfoundry[Cloud Foundry] (the Platform as a
Service). Cloud Foundry has the notion of a "service", which is
middlware that you "bind" to an app, essentially providing it with an
environment variable containing credentials (e.g. the location and
username to use for the service).
Add this project as a dependency to any Spring Cloud UI app or REST
service and deploy to Cloudfoundry. If you use Spring Cloud Security
OAuth2 features this will make them bindable to Cloud Foundry services
instead of enironment properties in `spring.oauth2.*`. For a UI app you can
declare `@EnableOAuth2Sso` and bind to a service called "sso", and for
a service you can add `@EnableOAuth2Resource` and bind to a service
called "resource" (see below for how to change the names).

View File

@@ -1,50 +0,0 @@
Here's a Spring Cloud app with OAuth2 SSO:
.app.groovy
[source,java]
----
@Controller
@EnableOAuth2Sso
class Application {
@RequestMapping('/')
String home() {
'Hello World'
}
}
----
If you run it without any service bindings:
----
$ spring jar app.jar app.groovy
$ cf push -p app.jar
----
it will be secure with (Spring Boot default) Basic authentication,
i.e. the password will be in the logs (or set it with
`security.user.password` as normal). To turn on OAuth2 SSO all you
need to do is bind the app to a service with the right
credentials. For example, a
http://docs.pivotal.io/pivotalcf/devguide/services/user-provided.html[user-provided
service] can be created like this on PWS:
----
$ 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"}
----
Then bind and restart the app:
----
$ cf bind app sso
$ cf restart app
----
and visit it in a browser. It will redirect to the Cloud Foundry (PWS)
login server instead of challenging for Basic authentication. The
`clientId` and `clientSecret` are credentials of a registered client
in Cloud Foundry. To get a Cloud Foundry client registration for
testing please ask your local platform administrator if it's a private
instance).

View File

@@ -1,75 +0,0 @@
= Spring Cloud for Cloud Foundry
include::intro.adoc[]
== Quickstart
include::quickstart.adoc[]
== How Does it Work?
=== OAuth2 Single Sign On
Spring Cloud Security provides the `@EnableOAuth2Sso` annotation and
binds the app to environment properties in `spring.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`,
`tokenUri`, `authorizationUri`, (and from `spring.oauth2.resource.*`)
`userInfoUri`, `tokenInfoUri`, `keyValue`, `keyUri`. Refer to the
Spring Cloud Security documentation for details of which combinations
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.
=== JWT Tokens
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
(`keyValue` or `keyUri`).
For example the `keyUri` in PWS is
"https://uaa.run.pivotal.io/token_key":
----
$ curl https://uaa.run.pivotal.io/token_key
{"alg":"SHA256withRSA","value":"-----BEGIN PUBLIC KEY-----\nMIIBI...\n-----END PUBLIC KEY-----\n"}d
----
=== OAuth2 Resource Server
Similarly, the `@EnableOAuth2Resource` annotation will protect your
API endpoints if you bind to a service instance called "resource".
The "sso" service above will work for a resource server as well (so
just bind to that if it's there). If the OAuth2 tokens are JWTs (as in
Cloud Foundry), it is common to use a separate service for resources
to avoid a network round trip decoding the token on every access. A
user-provided-service for an OAuth2 resource can be created like this
on PWS:
----
$ cf create-user-provided-service resource -p '{keyUri:"https://uaa.run.pivotal.io/token_key"}
----
To use JWT you need to add the verification key as either
`keyValue` or `keyUri` (these could be added to the "sso"
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.
=== Default Environment Keys
The precise mapppings are as follows:
* `spring.oauth2.sso.\*` to `vcap.services.${spring.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.*`
* `spring.oauth2.resource.(jwt).\*` to `vcap.services.${spring.oauth2.resource.serviceId:resource}.credentials.tokenUri:${vcap.services.${spring.oauth2.sso.serviceId:sso}.credentials.*`