84 lines
11 KiB
HTML
84 lines
11 KiB
HTML
<html><head>
|
|
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
|
<title>74. More Detail</title><link rel="stylesheet" type="text/css" href="css/manual-multipage.css"><meta name="generator" content="DocBook XSL Stylesheets V1.78.1"><link rel="home" href="multi_spring-cloud.html" title="Spring Cloud"><link rel="up" href="multi__spring_cloud_security.html" title="Part X. Spring Cloud Security"><link rel="prev" href="multi__quickstart.html" title="73. Quickstart"><link rel="next" href="multi__configuring_authentication_downstream_of_a_zuul_proxy.html" title="75. Configuring Authentication Downstream of a Zuul Proxy"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">74. More Detail</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="multi__quickstart.html">Prev</a> </td><th width="60%" align="center">Part X. Spring Cloud Security</th><td width="20%" align="right"> <a accesskey="n" href="multi__configuring_authentication_downstream_of_a_zuul_proxy.html">Next</a></td></tr></table><hr></div><div class="chapter"><div class="titlepage"><div><div><h2 class="title"><a name="_more_detail" href="#_more_detail"></a>74. More Detail</h2></div></div></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="_single_sign_on" href="#_single_sign_on"></a>74.1 Single Sign On</h2></div></div></div><div class="note" style="margin-left: 0.5in; margin-right: 0.5in;"><table border="0" summary="Note"><tr><td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="images/note.png"></td><th align="left">Note</th></tr><tr><td align="left" valign="top"><p>All of the OAuth2 SSO and resource server features moved to Spring Boot
|
|
in version 1.3. You can find documentation in the
|
|
<a class="link" href="http://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/" target="_top">Spring Boot user guide</a>.</p></td></tr></table></div></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="_token_relay" href="#_token_relay"></a>74.2 Token Relay</h2></div></div></div><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 class="section"><div class="titlepage"><div><div><h3 class="title"><a name="_client_token_relay" href="#_client_token_relay"></a>74.2.1 Client Token Relay</h3></div></div></div><p>If your app is a user facing OAuth2 client (i.e. has declared
|
|
<code class="literal">@EnableOAuth2Sso</code> or <code class="literal">@EnableOAuth2Client</code>) then it has an
|
|
<code class="literal">OAuth2ClientContext</code> in request scope from Spring Boot. You can
|
|
create your own <code class="literal">OAuth2RestTemplate</code> from this context and an
|
|
autowired <code class="literal">OAuth2ProtectedResourceDetails</code>, and then the context will
|
|
always forward the access token downstream, also refreshing the access
|
|
token automatically if it expires. (These are features of Spring
|
|
Security and Spring Boot.)</p><div class="note" style="margin-left: 0.5in; margin-right: 0.5in;"><table border="0" summary="Note"><tr><td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="images/note.png"></td><th align="left">Note</th></tr><tr><td align="left" valign="top"><p>Spring Boot (1.4.1) does not create an
|
|
<code class="literal">OAuth2ProtectedResourceDetails</code> automatically if you are using
|
|
<code class="literal">client_credentials</code> tokens. In that case you need to create your own
|
|
<code class="literal">ClientCredentialsResourceDetails</code> and configure it with
|
|
<code class="literal">@ConfigurationProperties("security.oauth2.client")</code>.</p></td></tr></table></div></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a name="_client_token_relay_in_zuul_proxy" href="#_client_token_relay_in_zuul_proxy"></a>74.2.2 Client Token Relay in Zuul Proxy</h3></div></div></div><p>If your app also has a
|
|
<a class="link" href="http://cloud.spring.io/spring-cloud.html#netflix-zuul-reverse-proxy" target="_top">Spring
|
|
Cloud Zuul</a> embedded reverse proxy (using <code class="literal">@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><p><b>app.groovy. </b>
|
|
</p><pre class="programlisting"><em><span class="hl-annotation" style="color: gray">@Controller</span></em>
|
|
<em><span class="hl-annotation" style="color: gray">@EnableOAuth2Sso</span></em>
|
|
<em><span class="hl-annotation" style="color: gray">@EnableZuulProxy</span></em>
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">class</span> Application {
|
|
|
|
}</pre><p>
|
|
</p><p>and it will (in addition to logging the user in and grabbing a token)
|
|
pass the authentication token downstream to the <code class="literal">/proxy/*</code>
|
|
services. If those services are implemented with
|
|
<code class="literal">@EnableResourceServer</code> then they will get a valid token in the
|
|
correct header.</p><p>How does it work? The <code class="literal">@EnableOAuth2Sso</code> annotation pulls in
|
|
<code class="literal">spring-cloud-starter-security</code> (which you could do manually in a
|
|
traditional app), and that in turn triggers some autoconfiguration for
|
|
a <code class="literal">ZuulFilter</code>, which itself is activated because Zuul is on the
|
|
classpath (via <code class="literal">@EnableZuulProxy</code>). The
|
|
<a class="link" href="https://github.com/spring-cloud/spring-cloud-security/tree/master/src/main/java/org/springframework/cloud/security/oauth2/proxy/OAuth2TokenRelayFilter.java" target="_top">filter</a>
|
|
just extracts an access token from the currently authenticated user,
|
|
and puts it in a request header for the downstream requests.</p></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a name="_resource_server_token_relay" href="#_resource_server_token_relay"></a>74.2.3 Resource Server Token Relay</h3></div></div></div><p>If your app has <code class="literal">@EnableResourceServer</code> you might want to relay the
|
|
incoming token downstream to other services. If you use a
|
|
<code class="literal">RestTemplate</code> to contact the downstream services then this is just a
|
|
matter of how to create the template with the right context.</p><p>If your service uses <code class="literal">UserInfoTokenServices</code> to authenticate incoming
|
|
tokens (i.e. it is using the <code class="literal">security.oauth2.user-info-uri</code>
|
|
configuration), then you can simply create an <code class="literal">OAuth2RestTemplate</code>
|
|
using an autowired <code class="literal">OAuth2ClientContext</code> (it will be populated by the
|
|
authentication process before it hits the backend code). Equivalently
|
|
(with Spring Boot 1.4), you could inject a
|
|
<code class="literal">UserInfoRestTemplateFactory</code> and grab its <code class="literal">OAuth2RestTemplate</code> in
|
|
your configuration. For example:</p><p><b>MyConfiguration.java. </b>
|
|
</p><pre class="programlisting"><em><span class="hl-annotation" style="color: gray">@Bean</span></em>
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">public</span> OAuth2RestTemplate restTemplate(UserInfoRestTemplateFactory factory) {
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">return</span> factory.getUserInfoRestTemplate();
|
|
}</pre><p>
|
|
</p><p>This rest template will then have the same <code class="literal">OAuth2ClientContext</code>
|
|
(request-scoped) that is used by the authentication filter, so you can
|
|
use it to send requests with the same access token.</p><p>If your app is not using <code class="literal">UserInfoTokenServices</code> but is still a client
|
|
(i.e. it declares <code class="literal">@EnableOAuth2Client</code> or <code class="literal">@EnableOAuth2Sso</code>), then
|
|
with Spring Security Cloud any <code class="literal">OAuth2RestOperations</code> that the user
|
|
creates from an <code class="literal">@Autowired</code> <code class="literal">@OAuth2Context</code> will also forward
|
|
tokens. This feature is implemented by default as an MVC handler
|
|
interceptor, so it only works in Spring MVC. If you are not using MVC
|
|
you could use a custom filter or AOP interceptor wrapping an
|
|
<code class="literal">AccessTokenContextRelay</code> to provide the same feature.</p><p>Here’s a basic
|
|
example showing the use of an autowired rest template created
|
|
elsewhere ("foo.com" is a Resource Server accepting the same tokens as
|
|
the surrounding app):</p><p><b>MyController.java. </b>
|
|
</p><pre class="programlisting"><em><span class="hl-annotation" style="color: gray">@Autowired</span></em>
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">private</span> OAuth2RestOperations restTemplate;
|
|
|
|
<em><span class="hl-annotation" style="color: gray">@RequestMapping("/relay")</span></em>
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">public</span> String relay() {
|
|
ResponseEntity<String> response =
|
|
restTemplate.getForEntity(<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"https://foo.com/bar"</span>, String.<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">class</span>);
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">return</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"Success! ("</span> + response.getBody() + <span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">")"</span>;
|
|
}</pre><p>
|
|
</p><p>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 class="literal">OAuth2Context</code> instead of autowiring the default one.</p><p>Feign clients will also pick up an interceptor that uses the
|
|
<code class="literal">OAuth2ClientContext</code> if it is available, so they should also do a
|
|
token relay anywhere where a <code class="literal">RestTemplate</code> would.</p></div></div></div><div class="navfooter"><hr><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="multi__quickstart.html">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="multi__spring_cloud_security.html">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="multi__configuring_authentication_downstream_of_a_zuul_proxy.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">73. Quickstart </td><td width="20%" align="center"><a accesskey="h" href="multi_spring-cloud.html">Home</a></td><td width="40%" align="right" valign="top"> 75. Configuring Authentication Downstream of a Zuul Proxy</td></tr></table></div></body></html> |