Sync docs from 1.0.x to gh-pages
This commit is contained in:
@@ -542,6 +542,26 @@ body.book #toc,body.book #preamble,body.book h1.sect0,body.book .sect1>h2{page-b
|
||||
<li><a href="#_encryption_and_decryption_3">Encryption and Decryption</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="#_spring_cloud_security">Spring Cloud Security</a>
|
||||
<ul class="sectlevel1">
|
||||
<li><a href="#_quickstart">Quickstart</a>
|
||||
<ul class="sectlevel2">
|
||||
<li><a href="#_oauth2_single_sign_on">OAuth2 Single Sign On</a></li>
|
||||
<li><a href="#_oauth2_protected_resource">OAuth2 Protected Resource</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="#_more_detail">More Detail</a>
|
||||
<ul class="sectlevel2">
|
||||
<li><a href="#_single_sign_on">Single Sign On</a></li>
|
||||
<li><a href="#_token_type_in_user_info">Token Type in User Info</a></li>
|
||||
<li><a href="#_customizing_the_resttemplate">Customizing the RestTemplate</a></li>
|
||||
<li><a href="#_resource_server">Resource Server</a></li>
|
||||
<li><a href="#_token_relay">Token Relay</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="#_configuring_authentication_downstream_of_a_zuul_proxy">Configuring Authentication Downstream of a Zuul Proxy</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1029,7 +1049,7 @@ when RestTemplate is on the classpath and a <code>LoadBalancerClient</code> bean
|
||||
<div class="paragraph">
|
||||
<p>The URI needs to use a virtual host name (ie. service name, not a host name).
|
||||
The Ribbon client is used to create a full physical address. See
|
||||
{github-code}/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonAutoConfiguration.java[RibbonAutoConfiguration]
|
||||
<a href="https://github.com/spring-cloud/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonAutoConfiguration.java">RibbonAutoConfiguration</a>
|
||||
for details of how the <code>RestTemplate</code> is set up.</p>
|
||||
</div>
|
||||
</div>
|
||||
@@ -3574,15 +3594,574 @@ the key value with "@" and provide the file path, e.g.</p>
|
||||
AQAjPgt3eFZQXwt8tsHAVv/QHiY5sI2dRcR+...</pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<h1 id="_spring_cloud_security" class="sect0">Spring Cloud Security</h1>
|
||||
<div class="openblock partintro">
|
||||
<div class="content">
|
||||
<div class="paragraph">
|
||||
<p>Unresolved directive in spring-cloud.adoc - include::../../../security/src/main/asciidoc/spring-cloud-security.adoc[]</p>
|
||||
<p>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.</p>
|
||||
</div>
|
||||
<div class="admonitionblock note">
|
||||
<table>
|
||||
<tr>
|
||||
<td class="icon">
|
||||
<div class="title">Note</div>
|
||||
</td>
|
||||
<td class="content">
|
||||
Spring Cloud is released under the non-restrictive Apache 2.0 license. If you would like to contribute to this section of the documentation or if you find an error, please find the source code and issue trackers in the project at {githubmaster}/src/main/asciidoc[github].
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sect1">
|
||||
<h2 id="_quickstart">Quickstart</h2>
|
||||
<div class="sectionbody">
|
||||
<div class="sect2">
|
||||
<h3 id="_oauth2_single_sign_on">OAuth2 Single Sign On</h3>
|
||||
<div class="paragraph">
|
||||
<p>Here’s a Spring Cloud "Hello World" app with HTTP Basic
|
||||
authentication and a single user account:</p>
|
||||
</div>
|
||||
<div class="listingblock">
|
||||
<div class="title">app.groovy</div>
|
||||
<div class="content">
|
||||
<pre class="highlight"><code class="language-java" data-lang="java">@Grab('spring-boot-starter-security')
|
||||
@Controller
|
||||
class Application {
|
||||
|
||||
@RequestMapping('/')
|
||||
String home() {
|
||||
'Hello World'
|
||||
}
|
||||
|
||||
}</code></pre>
|
||||
</div>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>You can run it with <code>spring run app.groovy</code> and watch the logs for the password (username is "user"). So far this is just the default for a Spring Boot app.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>Here’s a Spring Cloud app with OAuth2 SSO:</p>
|
||||
</div>
|
||||
<div class="listingblock">
|
||||
<div class="title">app.groovy</div>
|
||||
<div class="content">
|
||||
<pre class="highlight"><code class="language-java" data-lang="java">@Controller
|
||||
@EnableOAuth2Sso
|
||||
class Application {
|
||||
|
||||
@RequestMapping('/')
|
||||
String home() {
|
||||
'Hello World'
|
||||
}
|
||||
|
||||
}</code></pre>
|
||||
</div>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>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.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>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:</p>
|
||||
</div>
|
||||
<div class="listingblock">
|
||||
<div class="title">application.yml</div>
|
||||
<div class="content">
|
||||
<pre class="highlight"><code class="language-yaml" data-lang="yaml">spring:
|
||||
oauth2:
|
||||
client:
|
||||
clientId: bd1c0a783ccdd1c9b9e4
|
||||
clientSecret: 1a9030fbca47a5b2c28e92f19050bb77824b5ad1
|
||||
accessTokenUri: https://github.com/login/oauth/access_token
|
||||
userAuthorizationUri: https://github.com/login/oauth/authorize
|
||||
clientAuthenticationScheme: form
|
||||
resource:
|
||||
userInfoUri: https://api.github.com/user
|
||||
preferTokenInfo: false</code></pre>
|
||||
</div>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>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.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>To limit the scope that the client asks for when it obtains an access token
|
||||
you can set <code>spring.oauth2.client.scope</code> (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.</p>
|
||||
</div>
|
||||
<div class="admonitionblock note">
|
||||
<table>
|
||||
<tr>
|
||||
<td class="icon">
|
||||
<div class="title">Note</div>
|
||||
</td>
|
||||
<td class="content">
|
||||
The examples above are all Groovy scripts. If you want to write the
|
||||
same code in Java (or Groovy) you need to add Spring Security OAuth2
|
||||
to the classpath (e.g. see the
|
||||
<a href="https://github.com/spring-cloud-samples/sso">sample here</a>).
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sect2">
|
||||
<h3 id="_oauth2_protected_resource">OAuth2 Protected Resource</h3>
|
||||
<div class="paragraph">
|
||||
<p>You want to protect an API resource with an OAuth2 token? Here’s a
|
||||
simple example (paired with the client above):</p>
|
||||
</div>
|
||||
<div class="listingblock">
|
||||
<div class="title">app.groovy</div>
|
||||
<div class="content">
|
||||
<pre class="highlight"><code class="language-java" data-lang="java">@Grab('spring-cloud-starter-security')
|
||||
@RestController
|
||||
@EnableOAuth2Resource
|
||||
class Application {
|
||||
|
||||
@RequestMapping('/')
|
||||
def home() {
|
||||
[message: 'Hello World']
|
||||
}
|
||||
|
||||
}</code></pre>
|
||||
</div>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>and</p>
|
||||
</div>
|
||||
<div class="listingblock">
|
||||
<div class="title">application.yml</div>
|
||||
<div class="content">
|
||||
<pre class="highlight"><code class="language-yaml" data-lang="yaml">spring:
|
||||
oauth2:
|
||||
resource:
|
||||
userInfoUri: https://api.github.com/user
|
||||
preferTokenInfo: false</code></pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sect1">
|
||||
<h2 id="_more_detail">More Detail</h2>
|
||||
<div class="sectionbody">
|
||||
<div class="sect2">
|
||||
<h3 id="_single_sign_on">Single Sign On</h3>
|
||||
<div class="paragraph">
|
||||
<p>An app will activate <code>@EnableOAuth2Sso</code> if you bind provide the
|
||||
following properties in the <code>Environment</code>:</p>
|
||||
</div>
|
||||
<div class="ulist">
|
||||
<ul>
|
||||
<li>
|
||||
<p><code>spring.oauth2.client.*</code> with <code>*</code> equal to <code>clientId</code>, <code>clientSecret</code>,
|
||||
<code>accessTokenUri</code>, <code>userAuthorizationUri</code> and one of:</p>
|
||||
<div class="ulist">
|
||||
<ul>
|
||||
<li>
|
||||
<p><code>spring.oauth2.resource.userInfoUri</code> to use the "/me" resource
|
||||
(e.g. "https://uaa.run.pivotal.io/userinfo" on PWS), or</p>
|
||||
</li>
|
||||
<li>
|
||||
<p><code>spring.oauth2.resource.tokenInfoUri</code> to use the token decoding endpoint
|
||||
(e.g. "https://uaa.run.pivotal.io/check_token" on PWS).</p>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>If you specify both the <code>userInfoUri</code> and the <code>tokenInfoUri</code> then
|
||||
you can set a flag to say that one is preferred over the other
|
||||
(<code>preferTokenInfo=true</code> is the default). Or</p>
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<p><code>spring.oauth2.resource.jwt.keyValue</code> 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 <code>spring.oauth2.resource.jwt.keyUri</code>. E.g. on PWS:</p>
|
||||
<div class="listingblock">
|
||||
<div class="content">
|
||||
<pre>$ curl https://uaa.run.pivotal.io/token_key
|
||||
{"alg":"SHA256withRSA","value":"-----BEGIN PUBLIC KEY-----\nMIIBI...\n-----END PUBLIC KEY-----\n"}</pre>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="admonitionblock warning">
|
||||
<table>
|
||||
<tr>
|
||||
<td class="icon">
|
||||
<div class="title">Warning</div>
|
||||
</td>
|
||||
<td class="content">
|
||||
If you use the <code>spring.oauth2.resource.jwt.keyUri</code> 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.
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>You can set the preferred scope (as a comma-separated list or YAML
|
||||
array) in <code>spring.oauth2.client.scope</code>. It defaults to empty, in which case
|
||||
most Authorization Servers will ask the user for approval for the
|
||||
maximum allowed scope for the client.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>There is also a setting for <code>spring.oauth2.client.clientAuthenticationScheme</code> 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 <code>spring.oauth2.client.*</code> properties are bound to an instance
|
||||
of <code>AuthorizationCodeResourceDetails</code> so all its properties can be specified.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sect2">
|
||||
<h3 id="_token_type_in_user_info">Token Type in User Info</h3>
|
||||
<div class="paragraph">
|
||||
<p>Google (and certain other 3rd party identity providers) is more strict
|
||||
about the token type name that is sent in the headers to the user info
|
||||
endpoint. The default is "Bearer" which suits most providers and
|
||||
matches the spec, but if you need to change it you can set
|
||||
<code>spring.oauth2.resource.tokenType</code>.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sect2">
|
||||
<h3 id="_customizing_the_resttemplate">Customizing the RestTemplate</h3>
|
||||
<div class="paragraph">
|
||||
<p>The SSO (and Resource Server) features use an <code>OAuth2RestTemplate</code>
|
||||
internally to fetch user details for authentication. This is provided
|
||||
as a qualified <code>@Bean</code> with id "userInfoRestTemplate", but you
|
||||
shouldn’t need to know that to just use it. The default should be fine
|
||||
for most providers, but occasionally you might need to add additional
|
||||
interceptors, or change the request authenticator (which is how the
|
||||
token gets attached to outgoing requests). To add a customization just
|
||||
create a bean of type <code>UserInfoRestTemplateCustomizer</code> - it has a
|
||||
single method that will be called after the bean is created but before
|
||||
it is initialized. The rest template that is being customized here is
|
||||
<em>only</em> used internally to carry out authentication (in the SSO or
|
||||
Resource Server use cases).</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>A second {@link OAuth2RestTemplate} is available for autowiring if you
|
||||
want to use it for back channel calls, and if there is a
|
||||
token-authenticated user (in a web application) it will have the token
|
||||
injected for you.</p>
|
||||
</div>
|
||||
<div class="admonitionblock tip">
|
||||
<table>
|
||||
<tr>
|
||||
<td class="icon">
|
||||
<div class="title">Tip</div>
|
||||
</td>
|
||||
<td class="content">
|
||||
<div class="paragraph">
|
||||
<p>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:</p>
|
||||
</div>
|
||||
<div class="listingblock">
|
||||
<div class="content">
|
||||
<pre class="highlight"><code class="language-yaml" data-lang="yaml">oauth2:
|
||||
resource:
|
||||
jwt:
|
||||
keyValue: |
|
||||
-----BEGIN PUBLIC KEY-----
|
||||
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC...
|
||||
-----END PUBLIC KEY-----</code></pre>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<div class="sect3">
|
||||
<h4 id="_access_decision_rules">Access Decision Rules</h4>
|
||||
<div class="paragraph">
|
||||
<p>By default the whole application will be secured with OAuth2 with the
|
||||
same access rule ("authenticated"). This includes the Actuator
|
||||
endpoints, which you might prefer to be secured differently, so Spring
|
||||
Cloud Security provides a configurer callback that lets you change the
|
||||
matching and access rules for OAuth2 authentication. Any bean of type
|
||||
<code>OAuth2SsoConfigurer</code> (there is a convenient empty base class) will
|
||||
get 2 callbacks, one to set the request matchers for the OAuth2
|
||||
filter, and one with the full <code>HttpSecurity</code> builder (so you can set
|
||||
up all sorts of behaviour, but the main application is to control
|
||||
access rules).</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>The default login path, i.e. the one that triggers the redirect to the
|
||||
OAuth2 Authorization Server, is "/login". It will always be added to
|
||||
the matching patterns for the OAuth2 SSO, even if you have
|
||||
<code>OAuth2SsoConfigurer</code> 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 <code>spring.oauth2.sso.*' (`loginPath</code>, <code>logoutPath</code> and
|
||||
<code>home.path</code>).</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>For example if you want the resources under "/ui/**" to be protected with OAuth2:</p>
|
||||
</div>
|
||||
<div class="listingblock">
|
||||
<div class="content">
|
||||
<pre class="highlight"><code class="language-java" data-lang="java">@Configuration
|
||||
@EnableOAuth2Sso
|
||||
@EnableAutoConfiguration
|
||||
protected static class TestConfiguration extends OAuth2SsoConfigurerAdapter {
|
||||
@Override
|
||||
public void match(RequestMatchers matchers) {
|
||||
matchers.antMatchers("/ui/**");
|
||||
}
|
||||
}</code></pre>
|
||||
</div>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>In this case the rest of the application will default to the normal
|
||||
Spring Boot access control (Basic authentication, or whatever custom
|
||||
filters you put in place).</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sect3">
|
||||
<h4 id="_integrating_with_the_actuator_endpoints">Integrating with the Actuator Endpoints</h4>
|
||||
<div class="paragraph">
|
||||
<p>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.
|
||||
<code>ManagementProperties.BASIC_AUTH_ORDER + 1</code> which is
|
||||
<code>Ordered.LOWEST_PRECEDENCE-9</code> or <code>2147483636</code>). If you want to change
|
||||
the order you can set <code>spring.oauth2.sso.filterOrder</code>. 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
|
||||
<code>management.contextPath=/admin</code> (for instance) and use an
|
||||
<code>OAuth2SsoConfigurer</code> to set the access rules, e.g.</p>
|
||||
</div>
|
||||
<div class="listingblock">
|
||||
<div class="content">
|
||||
<pre class="highlight"><code class="language-java" data-lang="java"> @Configuration
|
||||
@EnableOAuth2Sso
|
||||
@EnableAutoConfiguration
|
||||
protected static class TestConfiguration extends OAuth2SsoConfigurerAdapter {
|
||||
@Override
|
||||
public void configure(HttpSecurity http) {
|
||||
http.authorizeRequests()
|
||||
.antMatchers("/admin/**").role("ADMIN")
|
||||
.anyRequest().authenticated();
|
||||
}
|
||||
}</code></pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sect2">
|
||||
<h3 id="_resource_server">Resource Server</h3>
|
||||
<div class="paragraph">
|
||||
<p>The <code>@EnableOAuth2Resource</code> annotation will protect your API endpoints
|
||||
if you have the same environment settings as the SSO client, except
|
||||
that it doesn’t need a <code>tokenUri</code> or <code>authorizationUri</code>, and it also
|
||||
doesn’t need a <code>clientId</code> and <code>clientSecret</code> if it isn’t using the
|
||||
<code>tokenInfoUri</code> (i.e. if it has <code>jwt.*</code> or <code>userInfoUri</code>).</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>By default <strong>all</strong> your endpoints are protected (i.e. "/**") but you can
|
||||
pick and choose by adding a <code>ResourceServerConfigurerAdapter</code> (standard
|
||||
Spring OAuth feature), e.g. to protect only the "/api/**" resources</p>
|
||||
</div>
|
||||
<div class="listingblock">
|
||||
<div class="title">Application.java</div>
|
||||
<div class="content">
|
||||
<pre class="highlight"><code class="language-java" data-lang="java">@RestController
|
||||
@EnableOAuth2Resource
|
||||
class Application extends ResourceServerConfigurerAdapter {
|
||||
|
||||
@Override
|
||||
public void configure(HttpSecurity http) throws Exception {
|
||||
http.requestMatchers()
|
||||
.antMatchers("/api/**")
|
||||
.and()
|
||||
.authorizeRequests()
|
||||
.anyRequest().authenticated();
|
||||
}
|
||||
|
||||
@RequestMapping("/api")
|
||||
public String home() {
|
||||
return "Hello World";
|
||||
}
|
||||
|
||||
}</code></pre>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sect3">
|
||||
<h4 id="_customizing_the_jwt_token_converter">Customizing the JWT Token Converter</h4>
|
||||
<div class="paragraph">
|
||||
<p>When a resource server accepts an access token as a JWT, it has to
|
||||
convert it to an <code>Authentication</code> so that Spring Security can do its
|
||||
access decisions. Different token providers might support JWT tokens
|
||||
with different contents, so Spring OAuth2 has an abstraction for
|
||||
converting the token into security domain objects
|
||||
(<code>AccessTokenConverter</code>). You can modify the default behaviour easily
|
||||
by providing a <code>@Bean</code> of type <code>JwtAccessTokenConverterConfigurer</code>,
|
||||
e.g.</p>
|
||||
</div>
|
||||
<div class="listingblock">
|
||||
<div class="content">
|
||||
<pre class="highlight"><code class="language-java" data-lang="java">@Component
|
||||
public class JwtCustomization extends DefaultAccessTokenConverter implements
|
||||
JwtAccessTokenConverterConfigurer {
|
||||
|
||||
@Override
|
||||
public void configure(JwtAccessTokenConverter converter) {
|
||||
converter.setAccessTokenConverter(this);
|
||||
}
|
||||
|
||||
... // implement custom AccessTokenConverter here
|
||||
|
||||
}</code></pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sect2">
|
||||
<h3 id="_token_relay">Token Relay</h3>
|
||||
<div class="paragraph">
|
||||
<p>A Token Relay is where an OAuth2 consumer acts as a Client and
|
||||
forwards the incoming token to outgoing resource requests. The
|
||||
consumer can be a pure Client (like an SSO application) or a Resource
|
||||
Server.</p>
|
||||
</div>
|
||||
<div class="sect3">
|
||||
<h4 id="_client_token_relay">Client Token Relay</h4>
|
||||
<div class="paragraph">
|
||||
<p>If your app has a
|
||||
<a href="http://cloud.spring.io/spring-cloud.html#netflix-zuul-reverse-proxy">Spring
|
||||
Cloud Zuul</a> embedded reverse proxy (using <code>@EnableZuulProxy</code>) 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:</p>
|
||||
</div>
|
||||
<div class="listingblock">
|
||||
<div class="title">app.groovy</div>
|
||||
<div class="content">
|
||||
<pre class="highlight"><code class="language-java" data-lang="java">@Controller
|
||||
@EnableOAuth2Sso
|
||||
@EnableZuulProxy
|
||||
class Application {
|
||||
|
||||
}</code></pre>
|
||||
</div>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>and it will (in addition to loggin the user in and grabbing a token)
|
||||
pass the authentication token downstream to the <code>/proxy/*</code>
|
||||
services. If those services are implemented with
|
||||
<code>@EnableOAuth2Resource</code> then they will get a valid token in the
|
||||
correct header.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>How does it work? The <code>@EnableOAuth2Sso</code> annotation pulls in
|
||||
<code>spring-cloud-starter-security</code> (which you could do manually in a
|
||||
traditional app), and that in turn triggers some autoconfiguration for
|
||||
a <code>ZuulFilter</code>, which itself is activated because Zuul is on the
|
||||
classpath (via <code>@EnableZuulProxy</code>). The
|
||||
{github}/tree/master/src/main/java/org/springframework/cloud/security/oauth2/proxy/OAuth2TokenRelayFilter.java[filter]
|
||||
just extracts an access token from the currently authenticated user,
|
||||
and puts it in a request header for the downstream requests.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sect3">
|
||||
<h4 id="_resource_server_token_relay">Resource Server Token Relay</h4>
|
||||
<div class="paragraph">
|
||||
<p>If your app has <code>@EnableOAuth2Resource</code> and also is a Client (i.e. it
|
||||
has a <code>spring.oauth2.client.clientId</code>, even if it doesn’t use it),
|
||||
then the <code>OAuth2RestOperations</code> that is provided for <code>@Autowired</code>
|
||||
users by Spring Cloud (it is declared as <code>@Primary</code>) will also forward
|
||||
tokens. If you don’t want to forward tokens (and that is a valid
|
||||
choice, since you might want to act as yourself, rather than the
|
||||
client that sent you the token), then you only need to create your own
|
||||
<code>OAuth2RestOperations</code> instead of autowiring the default one. Here’s
|
||||
a basic example showing the use of the autowired rest template ("foo.com"
|
||||
is a Resource Server accepting the same tokens as the surrounding app):</p>
|
||||
</div>
|
||||
<div class="listingblock">
|
||||
<div class="title">MyController.java</div>
|
||||
<div class="content">
|
||||
<pre class="highlight"><code class="language-java" data-lang="java">@Autowired
|
||||
private OAuth2RestOperations restTemplate;
|
||||
|
||||
@RequestMapping("/relay")
|
||||
public String relay() {
|
||||
ResponseEntity<String> response =
|
||||
restTemplate.getForEntity("https://foo.com/bar", String.class);
|
||||
return "Success! (" + response.getBody() + ")";
|
||||
}</code></pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sect1">
|
||||
<h2 id="_configuring_authentication_downstream_of_a_zuul_proxy">Configuring Authentication Downstream of a Zuul Proxy</h2>
|
||||
<div class="sectionbody">
|
||||
<div class="paragraph">
|
||||
<p>You can control the authorization behaviour downstream of an
|
||||
<code>@EnableZuulProxy</code> through the <code>proxy.auth.*</code> settings. Example:</p>
|
||||
</div>
|
||||
<div class="listingblock">
|
||||
<div class="title">application.yml</div>
|
||||
<div class="content">
|
||||
<pre class="highlight"><code class="language-yaml" data-lang="yaml">proxy:
|
||||
auth:
|
||||
routes:
|
||||
customers: oauth2
|
||||
stores: passthru
|
||||
recommendations: none</code></pre>
|
||||
</div>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>In this example the "customers" service gets an OAuth2 token relay,
|
||||
the "stores" service gets a passthrough (the authorization header is
|
||||
just passed downstream), and the "recommendations" service has its
|
||||
authorization header removed. The default behaviour is to do a token
|
||||
relay if there is a token available, and passthru otherwise.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>See
|
||||
{github}/tree/master/src/main/java/org/springframework/cloud/security/oauth2/proxy/ProxyAuthenticationProperties[
|
||||
ProxyAuthenticationProperties] for full details.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="footer">
|
||||
<div id="footer-text">
|
||||
Last updated 2016-02-25 10:40:59 UTC
|
||||
Last updated 2016-02-25 11:46:04 UTC
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
Reference in New Issue
Block a user