使用UAA OAuth2授权服务器–客户端和资源
在上一篇文章中,我介紹了如何使用Cloud Foundry UAA項(xiàng)目啟動OAuth2授權(quán)服務(wù)器,以及如何使用OAuth2授權(quán)代碼流程中涉及的一些參與者來填充它。
我已經(jīng)在Digital Ocean網(wǎng)站上找到了這篇文章,在描述OAuth2授權(quán)代碼流方面做得非常好,因此,與其重新哈希該流中涉及的內(nèi)容,我不如直接使用Spring Boot / Spring Security來實(shí)現(xiàn)該流。
下圖受此處的啟發(fā),顯示了授權(quán)碼授予類型的高級流程:
我將有兩個應(yīng)用程序-一個資源服務(wù)器公開用戶的一些資源,以及一個客戶端應(yīng)用程序代表用戶訪問這些資源。 如前面的博客文章所述,可以啟動授權(quán)服務(wù)器本身。
文章的其余部分可以更輕松地跟隨我的github存儲庫中的代碼
授權(quán)服務(wù)器
可以使用我之前的博客文章中描述的步驟輕松啟動Cloud Foundry UAA服務(wù)器。 一旦完成,可以使用以下uaac命令來填充運(yùn)行樣本所需的不同憑據(jù)。
這些腳本將為客戶端應(yīng)用程序創(chuàng)建客戶端證書,并添加一個名為“ user1”的用戶,其范圍為“ resource.read”和“ resource.write”。
# Login as a canned client uaac token client get admin -s adminsecret# Add a client credential with client_id of client1 and client_secret of client1 uaac client add client1 \--name client1 \--scope resource.read,resource.write \-s client1 \--authorized_grant_types authorization_code,refresh_token,client_credentials \--authorities uaa.resource# Another client credential resource1/resource1 uaac client add resource1 \--name resource1 \-s resource1 \--authorized_grant_types client_credentials \--authorities uaa.resource# Add a user called user1/user1 uaac user add user1 -p user1 --emails user1@user1.com# Add two scopes resource.read, resource.write uaac group add resource.read uaac group add resource.write# Assign user1 both resource.read, resource.write scopes.. uaac member add resource.read user1 uaac member add resource.write user1資源服務(wù)器
資源服務(wù)器通過以下方式公開了一些端點(diǎn),這些端點(diǎn)使用Spring MVC表示并使用Spring Security進(jìn)行保護(hù):
@RestController public class GreetingsController {@PreAuthorize("#oauth2.hasScope('resource.read')")@RequestMapping(method = RequestMethod.GET, value = "/secured/read")@ResponseBodypublic String read(Authentication authentication) {return String.format("Read Called: Hello %s", authentication.getCredentials());}@PreAuthorize("#oauth2.hasScope('resource.write')")@RequestMapping(method = RequestMethod.GET, value = "/secured/write")@ResponseBodypublic String write(Authentication authentication) {return String.format("Write Called: Hello %s", authentication.getCredentials());} }公開了兩個端點(diǎn)uri –授權(quán)用于范圍“ resource.read”的“ /安全/讀取”和授權(quán)用于范圍“ resource.write”的“ /安全/寫入”
保護(hù)這些端點(diǎn)并將應(yīng)用程序標(biāo)記為資源服務(wù)器的配置如下:
@Configuration @EnableResourceServer @EnableWebSecurity @EnableGlobalMethodSecurity(securedEnabled = true, prePostEnabled = true) public class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {@Overridepublic void configure(ResourceServerSecurityConfigurer resources) throws Exception {resources.resourceId("resource");}@Overridepublic void configure(HttpSecurity http) throws Exception {http.antMatcher("/secured/**").authorizeRequests().anyRequest().authenticated();} }該配置以及描述如何驗(yàn)證令牌的屬性是使資源服務(wù)器運(yùn)行所需的全部。
客戶
使用Spring Security OAuth2的OAuth2的客戶端配置也非常簡單,@ EnableAuth2SSO批注提取所有必需的配置以為OAuth2流連接Spring安全過濾器:
@EnableOAuth2Sso @Configuration public class OAuth2SecurityConfig extends WebSecurityConfigurerAdapter {@Overridepublic void configure(WebSecurity web) throws Exception {super.configure(web);}@Overrideprotected void configure(HttpSecurity http) throws Exception {http.csrf().disable();//@formatter:offhttp.authorizeRequests().antMatchers("/secured/**").authenticated().antMatchers("/").permitAll().anyRequest().authenticated();//@formatter:on}}要調(diào)用下游系統(tǒng),客戶端必須將OAuth令牌作為標(biāo)頭傳遞到下游調(diào)用中,方法是通過掛接一個稱為OAuth2RestTemplate的專用RestTemplate來完成,該模板可以從上下文中獲取訪問令牌并將其傳遞到下游連接了一個安全的下游呼叫,如下所示:
public class DownstreamServiceHandler {private final OAuth2RestTemplate oAuth2RestTemplate;private final String resourceUrl;public DownstreamServiceHandler(OAuth2RestTemplate oAuth2RestTemplate, String resourceUrl) {this.oAuth2RestTemplate = oAuth2RestTemplate;this.resourceUrl = resourceUrl;}public String callRead() {return callDownstream(String.format("%s/secured/read", resourceUrl));}public String callWrite() {return callDownstream(String.format("%s/secured/write", resourceUrl));}public String callInvalidScope() {return callDownstream(String.format("%s/secured/invalid", resourceUrl));}private String callDownstream(String uri) {try {ResponseEntity<String> responseEntity = this.oAuth2RestTemplate.getForEntity(uri, String.class);return responseEntity.getBody();} catch(HttpStatusCodeException statusCodeException) {return statusCodeException.getResponseBodyAsString();}} }示范
可以使用此處的說明啟動客戶端和資源服務(wù)器。 一旦所有系統(tǒng)啟動,訪問客戶端將向用戶顯示一個頁面,如下所示:
訪問安全頁面將導(dǎo)致授權(quán)服務(wù)器顯示登錄頁面:
客戶端正在向用戶請求“ resource.read”和“ resource.write”范圍,提示用戶授權(quán)這些范圍:
假設(shè)用戶已授權(quán)“ resource.read”但未授權(quán)“ resource.write”,則令牌將呈現(xiàn)給用戶:
在這一點(diǎn)上,如果請求的下游資源要求范圍為“ resource.read”,則應(yīng)檢索它:
并且,如果請求的下游資源具有用戶未授權(quán)的范圍,在這種情況下為“ resource.write”:
參考
- 大多數(shù)代碼基于此處提供的Cloud Foundry UAA應(yīng)用程序示例– https://github.com/pivotal-cf/identity-sample-apps
- 帖子中的代碼在這里 :https://github.com/bijukunjummen/oauth-uaa-sample
翻譯自: https://www.javacodegeeks.com/2017/03/using-uaa-oauth2-authorization-server-client-resource.html
總結(jié)
以上是生活随笔為你收集整理的使用UAA OAuth2授权服务器–客户端和资源的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: javaee和javaee_JavaEE
- 下一篇: 使用RESTful Client API