Congiurer
- ClientDetailsServiceConfigurer
- AuthorizationServerSecurityConfigure
- AuthorizationServerEndpointsConfigurer
- ResourceServerSecurityConfigurer
- HttpSecurity
Authorization Server
- ClientDetailsServiceConfigurer:定义ClientDetailsService
- AuthorizationServerSecurityConfigurer:定义token endpoint的安全限制
- AuthorizationServerEndpointsConfigurer:自定义authorization 和 token endpoint和TokenService
Configuring Client Details
提供了in-memory和JDBC两种实现。
ClientDetails的重要属性如下:
- clientId: (required) the client id.
- secret: (required for trusted clients) the client secret, if any.
- scope: The scope to which the client is limited. If scope is undefined or empty (the default) the client is not limited by 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).
Managing Tokens
- TokenStore:存储
- ResourceServerTokenServices:定义了管理OAuth 2.0 token的必要操作
- ConsumerTokenServices:消费一个token,删除一个token,先删除refresh_token,在删除token
三种TokenStore的实现:
- InMemoryTokenStore
- JdbcTokenStore
- JwtTokenStore:jwt是吧用户信息放在了token里,所有这个tokenstore并没有后端的存储
- JwkTokenStore:
- RedisTokenStore:redis版本的token存储
oauth_access_token和oauth_refresh_token的结构
create table oauth_access_token (
token_id VARCHAR(256),
token LONGVARBINARY,
authentication_id VARCHAR(256) PRIMARY KEY,
user_name VARCHAR(256),
client_id VARCHAR(256),
authentication LONGVARBINARY,
refresh_token VARCHAR(256)
);
create table oauth_refresh_token (
token_id VARCHAR(256),
token LONGVARBINARY,
authentication LONGVARBINARY
);
JWT Tokens
在Authorization Server配置JwtTokenStore。Authorization Server需要编码token,Resource Server需要解码token,所以Authorization Server和Resource Server都需要配置JwtAccessTokenConverter。token默认要被签名,所以Resource Server需要能够验证签名,所以Resource Server需要一个跟Authorization Server用来加密用户key对称的key。Resource Server需要的公钥可以通过Authorization Server的/oauth/token_key endpoint获取到,这个endpoint默认是denyAll()的,可以通过AuthorizationServerSecurityConfigurer来覆盖默认的安全配置(因为是公钥,所有改成permitAll()就行了)。
JwtTokenStore 需要引入spring-security-jwt模块。
Grant Types
通过AuthorizationServerEndpointsConfigurer可以配置AuthorizationEndpoint 支持不同的认证方式。OAuth2四种认证方式,默认只禁用了password 模式,其他三种都支持,具体配置看下面:
- authenticationManager: 给AuthorizationServerEndpointsConfigurer注入一个AuthenticationManager对象可以开启password grants;
- userDetailsService: 给AuthorizationServerEndpointsConfigurer注入一个UserDetailsService对象,或者在全局配置一个UserDetailsService对象可以开启refresh token grant ;
- authorizationCodeServices: 往ioc容器中注入一个AuthorizationCodeServices接口的实现的实例,可以开启auth code grant.
- implicitGrantService: 如果IOC容器中有这个对象,imlpicit grant启用.
- tokenGranter: 如果IOC容器中有TokenGranter接口的实现的对象实例,上边那些都不管用;
Configuring the Endpoint URLs
自定义endpoint url地址。
AuthorizationServerEndpointsConfigurer 有个pathMapping()方法,可以自定义的endpoint代替默认的endpoint。
默认的endpoint包括:
- /oauth/authorize
- /oauth/token
- /oauth/confirm_access
- /oauth/error
- /oauth/check_token
- /oauth/token_key
Customizing the UI
Authorization Server 的大部分endpoint是程序内部使用的,不需要UI界面,但是/oauth/confirm_access和/oauth/error是需要Ui界面。这两个UI界面,开发者可以自己定制,只需要使用@RequestMappings实现一个Spring MVC Controller来覆盖默认的URL地址即可。
Mapping User Roles to Scopes
有时候,通过分配给client的scope和用户自己的角色权限来确认token的权限是非常常用的。如果你通过AuthorizationServerEndpointsConfigurer给AuthorizationEndpoint配置一个DefaultOAuth2RequestFactory ,你可以设置checkUserScopes=true来根据用户的角色限制用户的权限。如果你在BasicAuthenticationFilter之后配置了TokenEndpointAuthenticationFilter ,你也可以给TokenEndpoint注入一个OAuth2RequestFactory ,但是这种范式只在password grants方式下工作。
当然,也可以自己实现OAuth2RequestFactory接口,来自定义scope和role的对应关系。
如果使用@EnableAuthorizationServer注解应用,可以使用AuthorizationServerEndpointsConfigurer 给应用注入一个自定义的OAuth2RequestFactory。
Resource Server
ResourceServerSecurityConfigurer、HttpSecurity
Resource Server使用OAuth2 token来保护服务器上资源。spring oauth提供了一系列认证相关的Filter来实现保护功能。使用@EnableResourceServer注解可以启用这些Filter,使用ResourceServerConfigurer可以更进一步的控制资源服务器的行为。下面是可以配置的特性:
- tokenServices: ResourceServerTokenServices接口的实现,RemoteTokenServices用在Resource Server和Authorization Server分离的情况.
- resourceId: the id for the resource (optional, but recommended and will be validated by the auth server if present).
- other extension points for the resourecs server (e.g. tokenExtractor for extracting the tokens from incoming requests)
- 受保护的资源的请求匹配策略(默认是全部可以访问)
- 受保护资源的访问规则(defaults to plain “authenticated”)
- other customizations for the protected resources permitted by the HttpSecurity configurer in Spring Security
@EnableResourceServer会自动添加一个OAuth2AuthenticationProcessingFilter 类型的Filter到Spring Security filter chain中。
ResourceServerTokenServices接口的实现里需要与Authorization Server通信。
Configuring An OAuth-Aware Expression Handler
OAuth2SecurityExpressionMethods 、
@EnableResourceServer默认会注册一个expression 处理器,你可以利用这个处理器来充分利用Spring Security的权限表达式强大的功能。表达式包括#oauth2.clientHasRole, #oauth2.clientHasAnyRole, 和 #oath2.denyClient ,用户对oauth client基于角色进行权限控制(请看OAuth2SecurityExpressionMethods)。
OAuth 2.0 Client
OAuth 2.0 client负责访问其他服务器上受OAuth 2.0 协议保护的资源。client需要提供存储用户的authorization codes 和 access tokens机制。
Protected Resource Configuration
受保护的资源或者说远程资源可以使用一个OAuth2ProtectedResourceDetails类型的对象来定义(跟UserDetails类似)。一个受保护的资源会有下列属性:
- id: The id of the resource. The id is only used by the client to lookup the resource; it’s never used in the OAuth protocol. It’s also used as the id of the bean.
- clientId: The 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: Comma-separted list of strings specifying the scope of the access to the resource. By default, no scope will be specified.
- 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.
- 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.
Client Configuration
使用@EnableOAuth2Client注解即可轻松启用OAuth2Client。此注解会做下列两件事情:
- 创建一个id为oauth2ClientContextFilter的Filter,用户存储当前请求的request对象和context。如果在请求期间需要认证权限,这个Filter还会管理重定向到认证界面,和认证之后重定向回之前请求的界面的功能。
- 在request scope内创建一个AccessTokenRequest 对象,这个类型的bean可以在将每个用户和authorization code 关联起来,避免冲突。
OAuth2ClientContext 存储在session中,用来保持不同用户的授权状态。
上边两个oauth2ClientContextFilter和AccessTokenRequest作用是,可以为每个用户创建一个OAuth2ClientContext对象实例,将请求与用户关联起来。
Accessing Protected Resources
使用@EnableOAuth2Client,Spring Security OAuth已经提供了一个扩展的RestTemplate,只需要提供一个OAuth2ProtectedResourceDetails的实例就可以使用。
Persisting Tokens in a Client
客户端不需要持久化token,但是每次业务请求之前都先去请求一个新的token太费劲了。ClientTokenServices定义了client持久化OAuth 2.0 Token的必要的操作。提供了一个基于JDBC的实现JdbcClientTokenServices,但是你完全可以去自定义ClientTokenServices接口。
create table oauth_client_token (
token_id VARCHAR(256),
token LONGVARBINARY,
authentication_id VARCHAR(256) PRIMARY KEY,
user_name VARCHAR(256),
client_id VARCHAR(256)
);
Enable*
- EnableAuthorizationServer
- EnableResourceServer
- EnableOAuth2Client