授权服务主要完成以下四个核心功能:
- 客户端授权关系管理;
- 接收用户或客户端登录请求,生成accessToken
- Token存储
- Token校验
本文将从源码层面分析授权服务如何实现上述四个功能。
关于Spring Oauth2的一些基础概念及示例,可参考:http://liumoran.cn/topic/myTopics/1
1. 概述
授权服务包含有以下几个关键类:
- EnableAuthorizationServer
启用授权服务,并引入AuthorizationServerEndpointsConfiguration及AuthorizationServerSecurityConfiguration两个配置类; - AuthorizationServerEndpointsConfiguration/AuthorizationServerEndpointsConfigurer
授权服务Endpoints配置类; - AuthorizationServerSecurityConfiguration/AuthorizationServerSecurityConfigurer
授权服务访问授权配置类; - AuthorizationServerConfigurerAdapter(AuthorizationServerConfigurer)
授权服务配置适配器,开发人员可定义其实现类来完成对授权服务的各项配置; - ClientDetailsServiceConfigurer
客户端配置类;
其中比较费解的是AuthorizationServerEndpointsConfiguration/AuthorizationServerEndpointsConfigurer
与AuthorizationServerSecurityConfiguration/AuthorizationServerSecurityConfigurer。
简单来说Configuration类可以看成是Configurer的代理类和配置类;而Configurer是存储配置项的类。
这几个类之间的关系如下所示:
2. AuthorizationServerEndpointsConfiguration
它完成以下功能:
- 配置AuthorizationServerEndpointsConfigurer:通过init方法完成AuthorizationServerEndpointsConfigurer的创建与配置。
- 创建Endpoint:通过Bean注解,往Spring容器中托管各个Endpoint(如用于处理/oauth/token请求的TokenEndpoint、用于处理/oauth/authorize请求的AuthorizationEndpoint等;
Endpoint可以看成是控制器,即平常我们所定义的Controller。
2.1 AuthorizationServerEndpointsConfigurer的创建与配置
init方法定义如下:
@Autowired
private List<AuthorizationServerConfigurer> configurers = Collections.emptyList();
@PostConstruct
public void init() {
for (AuthorizationServerConfigurer configurer : configurers) {
try {
configurer.configure(endpoints);
} catch (Exception e) {
throw new IllegalStateException("Cannot configure enpdoints", e);
}
}
endpoints.setClientDetailsService(clientDetailsService);
}
看到它就是使用容器中的所有类型为AuthorizationServerConfigurer的Bean,然后调用其configure方法对endpoints进行配置。
因此如果我们在应用中定义了实现AuthorizationServerConfigurer接口或者继承AuthorizationServerConfigurerAdapter的配置类,
并且这个配置类通过Configuration注解或者其它方式被注入到Spring中,那么我们在方法configure(AuthorizationServerEndpointsConfigurer)中
定义的代码将会被执行。
通过这种方式我们可以对授权服务所使用的TokenStore、TokenService等进行配置,见4.3节内容。具体配置项内容可看AuthorizationServerEndpointsConfigurer源码。
2.2 创建Endpoints
AuthorizationServerEndpointsConfiguration通过Bean往Spring容器中注入了多个Endpoint,用于处理OAuth相关的授权请求。主要包含的Endpoint如下:
- AuthorizationEndpoint: 用于处理资源授权请求(/oauth/authorize)
- TokenEndpoint: 用于处理Token申请请求(/oauth/token)
- CheckTokenEndpoint:用于处理Token校验请求(/oauth/check_token)
- 其它:默认的授权页面等Endpoint;
以TokenEndpoint为例,它的托管过程如下:
@Bean
public TokenEndpoint tokenEndpoint() throws Exception {
TokenEndpoint tokenEndpoint = new TokenEndpoint();
tokenEndpoint.setClientDetailsService(clientDetailsService);
tokenEndpoint.setProviderExceptionHandler(exceptionTranslator());
tokenEndpoint.setTokenGranter(tokenGranter());
tokenEndpoint.setOAuth2RequestFactory(oauth2RequestFactory());
tokenEndpoint.setOAuth2RequestValidator(oauth2RequestValidator());
tokenEndpoint.setAllowedRequestMethods(allowedTokenEndpointRequestMethods());
return tokenEndpoint;
}
TokenEndpoint的关键方法如下:
@RequestMapping(value = "/oauth/token", method=RequestMethod.POST)
public ResponseEntity<OAuth2AccessToken> postAccessToken(Principal principal