几个月之前我我发了一段时间研究过这个东西,最新想重新温习一下,然后把这个过程记录下来。首先我们先来理解一下auth2是什么,这边我们引用了阮一峰的一篇文章(写的也是很不错),这里我直接附上其链接http://www.ruanyifeng.com/blog/2014/05/oauth_2_0.html
首先要好好的去理解这篇文章,理解好了,才会有对后面的一些东西轻松一点。如果你看过这么我贴出来的这篇文章,相信大家对auth这个东西大致有了一定的了解了,其实文章中说的auth出现的原因以及出现的情景,可以说形容的也是比较恰当。不多说废话了,直接开始项目。先声明一下我这边用的是spring-security-oauth2
首先创建一个spring boot 的项目,向pom文件中增加如下代码
##################oauth2#############################
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security.oauth</groupId>
<artifactId>spring-security-oauth2</artifactId>
</dependency>
################################################################
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- 将token存储在redis中 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
</dependencies>
auth2中又2个最重要的概念:1资源服务器 2授权服务器
针对这两个核心东西有2个相应的配置,大家可以放在一个类里面,也可以各自类中
首先我们来看授权服务器配置:
@Configuration
@EnableAuthorizationServer
public class OAuth2ServerConfig extends AuthorizationServerConfigurerAdapter {
@Autowired
private RedisConnectionFactory redisConnectionFactory;
@Autowired
AuthenticationManager authenticationManager;
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
super.configure(clients);
}
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints.tokenStore(new RedisTokenStore(redisConnectionFactory)).authenticationManager(authenticationManager);
super.configure(endpoints);
}
@Override
public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
super.configure(security);
}
}
上面的代码是继承AuthorizationServerConfigurerAdapter类后使用的三个方法,这三个方法都是没有改过的,默认调用父类。
然后我们直接是使用password的方式去调用auth2的endpoint
上面请求中的username默认是user,password去启动日志中能看到,结果看到报了如下错误。
最后原来是我忘记了clientid,serct。我们在阮一峰的文章中知道有用户,客户端,授权服务器等角色,以及获取token的四种方式。那clientId,serct就是授权服务端给各个客户端的一个凭证,是从授权服务器中获取token的其中一个条件(参数)。其实在那篇文章中的4中方式中都有提及到clientid(都是作为请求的入参)
那怎么加入clientId和serct呢?其实auth2提供了多种方式去存储clientId和serct,比如内存(我们等一下就要这种方式),数据库等。我们只需要将如下代码
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
super.configure(clients);
}
替换成
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
//super.configure(clients);
clients.inMemory()
.withClient("clientId")
.secret("secret") //client_secret
.authorizedGrantTypes("authorization_code","password") //授权类型
.scopes("app"); //授权范围
}
这是直接在授权服务器中的内存里面设置clientId和sercet,简化我自己的步骤,实际情况大家可以放在数据库。
现在我们开始作为客户端去去获取token试试。结果如下
{
"error": "unsupported_grant_type",
"error_description": "Unsupported grant type: password"
}
显然之前那个问题解决掉了,这是新的问题,这个问题也好解决,网上的意思就是要把我们刚才的代码改一下
这里贴一下OAuth2ServerConfig类的最新代码
@Configuration
@EnableAuthorizationServer
public class OAuth2ServerConfig extends AuthorizationServerConfigurerAdapter {
@Autowired
AuthenticationManager authenticationManager;
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
//super.configure(clients);
clients.inMemory()
.withClient("clientId")
.secret("secret") //client_secret
.authorizedGrantTypes("authorization_code","password") //授权类型
.scopes("app"); //授权范围
}
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
//super.configure(endpoints);
endpoints.authenticationManager(authenticationManager);
}
@Override
public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
super.configure(security);
}
}
再一次请求,结果如下
{
"access_token": "37c8c108-f246-4b1b-a737-66d3ad55f7f9",
"token_type": "bearer",
"expires_in": 43199,
"scope": "app"
}
一个密码模式的获取token的请求成功了
然后我也试了一下code模式,也是成功的,那到处一个比较简单的授权服务器完成