> 本博文翻译自[官方文档](https://projects.spring.io/spring-security-oauth/docs/oauth2.html)。 Spring Security 官方已经弃用OAuth2项目了,你知道吗?Spring Security5.2.x版本以上提供了最新的方式。 ## 一、关于授权服务器 ### AuthorizationServerConfigurer的配置 使用注解`@EnableAuthorizationServer`启用授权服务器。授权服务器可以对ClientDetailsService、AuthorizationServerSecurity、AuthorizationServerEndpoints进行配置。 分别对应三个配置类: - ClientDetailsServiceConfigurer: a configurer that defines the client details service. Client details can be initialized, or you can just refer to an existing store. - `AuthorizationServerSecurityConfigurer`: tolen获取的安全性设置。 - `AuthorizationServerEndpointsConfigurer`: 定义了授权、token获取的相关服务。 ### 配置Client Details `ClientDetailsServiceConfigurer`会被`AuthorizationServerConfigurer`回调。Client Details Service可以被设置为基于内存或者是JDBC的实现,关键属性包括: - clientId: (非空)Client编号. - secret: client secret. - scope: 客户端访问范围限制。如果scope设置为空,则不进行限制。 - authorizedGrantTypes: Grant types that are authorized for the client to use. Default value is empty. - authorities: Authorities that are granted to the client (regular Spring Security authorities). ### 管理token `AuthorizationServerTokenServices`用来管理token存储的实现,默认存储是在内存中的。 - InMemoryTokenStore:适合单节点开发环境; - JdbcTokenStore :各个服务之间可以共享token存储; - JWTTokenStore: ### 配置EndPoint URLS > 什么是EndPoint URLS?作为小白的我,经常感到水土不服。 框架自带的路径: - `/oauth/authorize`:认证地址; - `/oauth/token`:token地址; - `/oauth/confirm_access`:用户授权的时候打开的地址; - `/oauth/error`:授权错误时打开的地址; - `/oauth/check_token`:资源服务器解密验证token; - `/oauth/token_key`:使用JWT token时暴露公有key进行token验证; ## 二、资源(Resource)服务器配置 资源服务器是基于token保护资源服务的。Spring Oauth协议提供Security认证Filter(`OAuth2AuthenticationProcessingFilter`的实现)来实现这个功能。 开启方法:在配置类中添加注解:`@EnableResourceServer`。可用配置有: - tokenServices: 定义token services的一个bean (ResourceServerTokenServices的实例). - resourceId: 资源id (可选,但建议使用,如果存在auth服务,将由auth服务器验证). - other extension points for the resourecs server (e.g. tokenExtractor for extracting the tokens from incoming requests) - request matchers for protected resources (defaults to all) - access rules for protected resources (defaults to plain "authenticated") - other customizations for the protected resources permitted by the HttpSecurity configurer in Spring Security ## 三、OAuth2.0 Client > 基本概念: - `OAuth2ProtectedResourceDetails`:被保护的资源bean; ### 被保护资源配置 - `id`: 资源的ID。客户端可以用来查找资源;这个ID在OAuth protocol中是无用的,它也用作bean的ID。 - `clientId`: OAuth client的id. This is the id by which the OAuth provider identifies your client. - `clientSecret`: The secret associated with the resource. By default, no secret is empty. - `accessTokenUri`: The URI of the provider OAuth endpoint that provides the access token. - `scope`: 多个scope之间使用','连接的字符串配置,可以访问资源资源。默认不指定任何的scope。 - `clientAuthenticationScheme`: The scheme used by your client to authenticate to the access token endpoint. Suggested values: "http_basic" and "form". Default: "http_basic". See section 2.1 of the OAuth 2 spec. > Different grant types have different concrete implementations of OAuth2ProtectedResourceDetails (e.g. ClientCredentialsResource for "client_credentials" grant type). For grant types that require user authorization there is a further property: - `userAuthorizationUri`: The uri to which the user will be redirected if the user is ever needed to authorize access to the resource. Note that this is not always required, depending on which OAuth 2 profiles are supported. ### 客户端的配置 使用注解:`@EnableOAuth2Client`,注解的背后做了两件事情: - 创建了一个ID为`oauth2ClientContextFilter`的filter,用来存储当前请求和上下文。在认证请求过程中用于管理OAuth认证url的重定向。 - 请求过程中,创建了一个类型为`AccessTokenRequest`的bean,授权码可以用这个bean来防止客户端与单个用户的状态冲突。 `AccessTokenRequest`在OAuth2RestTemplate是这样的使用的: ```java @Autowired private OAuth2ClientContext oauth2Context; @Bean public OAuth2RestTemplate sparklrRestTemplate() { return new OAuth2RestTemplate(sparklr(), oauth2Context); } ``` ### 资源访问 在Spring3中RestTemplate是访问资源时推荐的方式,Spring Security对其进行了拓展,只需要实例化`OAuth2ProtectedResourceDetails`就好了。 ### 客户端token的保持 客户端不需要持久化token,但是客户端重启时用户不需要获取一个新的token。 `ClientTokenServices` 接口定义了必要的功能用来持久化 OAuth 2.0 tokens以区分用户。系统提供了一种JDBC的实现。想要使用这个特性,需要向OAUthRestTemplate提供额外的`TokenProvider`配置。 ```java @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; } ``` ## 感慨一下 > 之前在网络上搜了不少关于Spring Security Oauth2相关的资料,理解一直不甚透彻。今日官网文档一看,发现Spring Security Oauth2已经是Spring4.x时代的产物了。说明自己学习新知识的习惯还是不太成熟。另外说一点,看英文文档的表述比谷歌的自动翻译要好太多了。