Sync docs from master to gh-pages
This commit is contained in:
@@ -541,26 +541,6 @@ 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>
|
||||
@@ -3485,565 +3465,15 @@ 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>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="paragraph">
|
||||
<p><a href="https://raw.githubusercontent.com/spring-cloud/spring-cloud-build/master/docs/src/main/asciidoc/contributing-docs.adoc" class="bare">https://raw.githubusercontent.com/spring-cloud/spring-cloud-build/master/docs/src/main/asciidoc/contributing-docs.adoc</a></p>
|
||||
</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>
|
||||
<p>Unresolved directive in spring-cloud.adoc - include::../../../security/src/main/asciidoc/spring-cloud-security.adoc[]</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="footer">
|
||||
<div id="footer-text">
|
||||
Last updated 2015-06-24 17:02:02 UTC
|
||||
Last updated 2015-06-25 11:40:58 UTC
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
Reference in New Issue
Block a user