OAuth2.0是一个开放的授权协议,可以用来实现第三方应用对我们API的访问控制,OAuth2.0中定义的角色包括:
-
Resource Owner(资源拥有者)
-
Client (第三方接入平台,请求者)
-
Resource Server (服务器资源: 数据中心)
-
Authorization Server (认证服务器)
授权认证的基本流程包括: 首先Client需要向Resource Owner申请授权凭据,Resource Owner同意之后会发放**授权凭据(code码)给Client,Client然后会将授权凭据和身份信息(AppId)一起发给Authorization Server申请访问令牌,Authorization Server在验证身份信息无误之后,发送访问令牌(Access Token)**给Client,Client最后根据携带Access Token去访问Resource Server中受保护的API资源。
OAuth2.0的认证模式包括四种:授权码模式、密码模式、简化模式、客户端模式。其中授权码模式是功能最完善,流程最严密的授权模式,其基本流程图如下:
-
用户访问客户端,被导向认证服务器
-
用户给予客户端授权,认证服务器将用户导向客户端事先指定的重定向URL,并附上一个授权码
-
客户端收到授权码,附上早先的URL,向认证服务器申请令牌
-
认证服务器核对了授权码和URL,确认无误之后,向客户端发送访问令牌(access token)和更新令牌(refresh token)
SpringBoot对OAuth2.0进行了很好的支持,下面详细说明下SpringBoot中OAuth2.0的基本配置和流程。
首先搭建oauth server和oauth client的框架
在oauth server中首先定义认证服务器:
@Configuration
@EnableAuthorizationServer
public class Oauth2ServerConfig extends AuthorizationServerConfigurerAdapter {
@Resource
private DataSource dataSource;
@Override
public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
super.configure(security);
}
/**
* 配置ClientDetailsService,这里使用jdbc模式
*/
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.jdbc(dataSource);
}
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
super.configure(endpoints);
}
}
这里我们配置从数据库中读取第三方应用的配置,数据表如下:
CREATE TABLE `oauth_client_details` (
`client_id` varchar(48) NOT NULL,
`resource_ids` varchar(256) DEFAULT NULL,
`client_secret` varchar(256) DEFAULT NULL,
`scope` varchar(256) DEFAULT NULL,
`authorized_grant_types` varchar(256) DEFAULT NULL,
`web_server_redirect_uri` varchar(256) DEFAULT NULL,
`authorities` varchar(256) DEFAULT NULL,
`access_token_validity` int(11) DEFAULT NULL,
`refresh_token_validity` int(11) DEFAULT NULL,
`additional_information` varchar(4096) DEFAULT NULL,
`autoapprove` varchar(256) DEFAULT NULL,
PRIMARY KEY (`client_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
接着配置资源服务器:
@Configuration
@EnableResourceServer
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
@Override
public void configure(HttpSecurity http) throws Exception {
http.requestMatchers().antMatchers("/user/**") //对/user的路径进行保护
.and()
.authorizeRequests()
.anyRequest().authenticated();
}
}
然后配置WebSecurity
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private UserServiceImpl userService;
@