OAuth2开发者指南—客户端

来源:互联网 发布:安卓 平板 软件 编辑:程序博客网 时间:2024/06/05 03:04

引言

OAuth2.0客户端机制负责访问其他服务器的OAuth2.0保护资源,配置包括建立相关受保护资源。客户端也需要实现存储用户的授权代码和访问令牌的功能。

受保护资源配置

受保护的资源(或称为远程资源)可以使用OAuth2ProtectedResourceDetails类型的实体bean定义。一个受保护的资源有以下属性:
- id:资源id。它仅在客户端搜索资源的时候使用;在OAuth协议中它从未被用到。它也被用作bean的id。
- clientId:OAuth客户端id。OAuth提供端依赖这个id来识别客户端。
- clientSecret:与资源有关的客户端密钥,默认情况下其值不为空。
- accessTokenUri:提供访问令牌的提供者OAuth端点的URI。
- scope:以逗号分隔的字符串列表,标识可访问资源的范围。默认情况下,该值为空。
- clientAuthenticationScheme:客户端对访问令牌端点进行身份验证使用的方案,建议的值:httpbasicform。默认值:http_basic。参见OAuth 2规范的2.1节。。

不同的授权类型有不同的OAuth2ProtectedResourceDetails接口的实现(对于client_credentials授权类型,使用ClientCredentialsResource )。对于需要进行用户身份验证的授权类型,还有一个属性:
- userAuthorizationUri:用户访问资源需要身份验证时跳转页面的URI。 注意这个字段不是必填的,它依赖于被支持的OAuth 2的配置文件类型。

在XML中,可以使用<resource/>元素创建一个OAuth2ProtectedResourceDetails类型的实体bean。它有上面提到的所有的属性。

客户端配置

对于OAuth 2.0客户端,使用@EnableOAuth2Client简化了配置。主要做了两件事:
- 创建一个过滤器bean(ID为oauth2ClientContextFilter)来存储当前请求和上下文。在请求期间需要进行身份验证的情况下,它管理对OAuth身份验证uri的重定向。
- 在请求作用域内创建AccessTokenRequest类型的bean。这可以由使用授权代码(或隐式)授权模式的客户端使用,以防止与个别用户发生冲突。

这个过滤器需要能够连接到应用(例如,使用Servlet初始化程序或者web.xml配置文件配置一个和DelegatingFilterProxy相同名称的代理)。

这个AccessTokenRequest可以在OAuth2RestTemplate中使用:

@Autowiredprivate OAuth2ClientContext oauth2Context;@Beanpublic OAuth2RestTemplate sparklrRestTemplate() {    return new OAuth2RestTemplate(sparklr(), oauth2Context);}

实例OAuth2ClientContext可以在Session的作用域中保持不同用户不同的状态。否则,您将不得不在服务器上管理相同的数据结构,将传入的请求映射到用户,并将每个用户与OAuth2ClientContext的单独实例关联起来。

在XML中有一个带有id属性的<client/>标签用于表示servlet的Filter的bean id素——这是servlet Filter的bean id,它必须被映射到一个DelegatingFilterProxy(具有相同的名称)的@Configuration注解。

访问受保护资源

一旦您为这些资源提供了所有配置,现在就可以访问这些资源了。访问这些资源的建议方法是使用在Spring 3中引入的RestTemplate。Spring Security OAuth 已经提供了一个扩展的RestTemplate只需要提供OAuth2ProtectedResourceDetails的实例。
要将它与user-tokens(授权码模式)一起使用,您应该考虑使用@EnableOAuth2Client配置(或者是XML配置<oauth:rest-template/>),它创建了一些请求和会话范围的上下文对象,以便不同用户的请求在运行时不会发生冲突。

一般来说,一个web应用程序不应该使用密码模式,所以如果你能支持AuthorizationCodeResourceDetails的话,尽量避免使用ResourceOwnerPasswordResourceDetails。如果您非常需要在Java客户端中使用密码模式,那么使用相同的机制来配置您的OAuth2RestTemplate并将凭据添加到AccessTokenRequest(短暂的Map)而不是ResourceOwnerPasswordResourceDetails(在所有访问令牌之间共享)。

客户端持久化访问令牌

客户端不需要持久化令牌,但对于用户来说,每次重新启动客户端应用程序时都不需要批准新的令牌授权,这是一项很人性化的功能。ClientTokenServices接口定义了为特定用户持久化OAuth 2.0令牌所必需的操作。这里提供了一个JDBC实现,但是如果您喜欢的话,也可以自己实现一个服务,将访问令牌和相关的身份验证实例存储在持久化数据库中。如果您想要使用这个功能,您需要为OAuth2RestTemplate提供一个特殊配置的TokenProvider。eg:

@Bean@Scope(value = "session", proxyMode = ScopedProxyMode.INTERFACES)public OAuth2RestOperations restTemplate() {    OAuth2RestTemplate template = new OAuth2RestTemplate(resource(), new DefaultOAuth2ClientContext(accessTokenRequest));    AccessTokenProviderChain provider = new AccessTokenProviderChain(Arrays.asList(new AuthorizationCodeAccessTokenProvider()));    provider.setClientTokenServices(clientTokenServices());    return template;}

为外部 OAuth2 提供者定制客户端

一些外部的OAuth2提供者(例如facebook)并没有正确地实现规范,或者他们只是停留在一个较老版本的规范上,而不是Spring Security OAuth。要在客户端应用程序中使用这些外部提供者,您可能需要调整客户端基础结构的各个部分。

如果要使用Facebook作为例子,在tonr2应用程序中有一个Facebook的例子作为参考(您需要更改配置来添加您自己的、有效的、client idsecret——它们很容易在Facebook网站上生成)。

Facebook响应令牌也包含一个不一致的、有失效时间的JSON实体(他们使用expires而不是expires_in),所以如果你想在应用程序中使用超时时间你将不得不使用一个自定义OAuth2SerializationService手动解码。