Oauth2.0学习

oauth2 学习

准备工作 :

如果是通过数据库进行授权,需在oauth2 的客户端配置表(oauth_client_details)中配置相关信息 :

设置信息如下 :
客户端编号(client_id) 为 client;
资源编号(resource_ids) 为 * (全部资源);
客户端的访问密匙(Client Secret ) 为 123456 (该值需要加密存储);
客户端申请的权限范围(scope) 为 read(可设置为 read|只读、write|只写、trust);
客户端支持的授权类型(authorized_grant_types)为
client_credentials|客户端凭证,implicit|隐藏式,authorization_code|授权码,refresh_token|可刷新,password密码式;
客户端访问的资源地址(web_server_redirect_uri)为 http://127.0.0.1;
指定spring security的用户(authorities)为 * 所有用户都能访问.

如果是直接在内存中存储,需在oauth2 的配置项中直接设置,如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
//对客户端访问密码通过SpringSecurity 工具类加密
String finalSecret = "{bcrypt}"+new BCryptPasswordEncoder().encode("123456");
clients.inMemory().withClient("client")
.resourceIds("*")
.authorizedGrantTypes("client_credentials","implicit",
"authorization_code",
"refresh_token","password")
.scopes("read")
.redirectUris("http://127.0.0.1")
.authorities("*")
.secret(finalSecret);
}

1、 授权码(authorization-code)

1.1、获取配置的请求地址的授权码:

浏览器访问如下地址 :

1
http://localhost:8823/oauth/authorize?response_type=code&client_id=client&scope=read&redirect_uri=http://127.0.0.1

提示 如下信息 :

选中 Approve 选项

点击 Authorize 按钮 , 系统会响应一会儿 得到如下信息:

得到的地址 后的 code=7GLfrX 就是当前的授权码信息

1.2、通过 code 授权码 获取token信息:

PostMan工具上 创建如下 POST 请求 :

1
http://localhost:8823/oauth/token?grant_type=authorization_code&code=7GLfrX&client_id=client&client_secret=123456&redirect_uri=http://127.0.0.1

得到如下 信息 :

1
2
3
4
5
6
7
{
"access_token": "033a1571-3c7f-476e-8ea7-87a555bbc52b",
"token_type": "bearer",
"refresh_token": "19f0dfa2-b876-4062-abcc-63045896139e",
"expires_in": 43199,
"scope": "read"
}

之后使用 access_token的token值访问资源就行

2、隐藏式(implicit)

在 浏览器地址栏输入如下请求 :

1
http://localhost:8823/oauth/authorize?response_type=token&client_id=client&redirect_uri=http://127.0.0.1

需要用户登录之后得到进入如下页面

设置客户端client的访问权限,这里设置readwrite都是Approve

点击 Authorize 按钮 , 系统会响应一会儿 得到如下信息:

得到的信息 :

1
http://127.0.0.1/#access_token=0820dc62-ae1a-4186-b27c-aea060529631&token_type=bearer&expires_in=1200000&scope=read%20write

之后使用 access_token的token值访问资源就行

3、密码式(password)

PostMan工具上 创建如下 POST 请求 :

1
http://localhost:8823/oauth/token?grant_type=password&client_id=client&client_secret=123456&username=oauth_admin&password=user

得到如下 信息 :

1
2
3
4
5
6
7
{
"access_token": "8e87ba90-6675-4f9d-af79-57120eb479e5",
"token_type": "bearer",
"refresh_token": "c90e6f38-b4d4-474b-be10-95b6e0e93549",
"expires_in": 1199950,
"scope": "read write"
}

之后使用 access_token的token值访问资源就行

4、客户端凭证(client credentials)

PostMan上创建如下 POST请求 :

1
http://localhost:8823/oauth/token?grant_type=client_credentials&scope=read&client_id=client&client_secret=123456

得到如下信息 :

1
2
3
4
5
6
{
"access_token": "ba871070-adb2-493e-91d9-bdb2a73cd167",
"token_type": "bearer",
"expires_in": 1199999,
"scope": "read"
}

之后使用 access_token的token值访问资源就行

5、刷新 token信息 ( refresh token )

一般来说,refresh_token的有效期会比 access_token 的有效期稍长,在 access_token 失效后,

可通过如下 POST 请求刷新token信息 :

1
http://localhost:8823/oauth/token?grant_type=refresh_token&refresh_token=f8dc8c19-6b0f-459c-aee0-8dc1677ec66e&client_id=client&client_secret=123456

得到的信息如下 :

1
2
3
4
5
6
7
{
"access_token": "5b74b001-d247-49a5-a80c-bce45aa560b2",
"token_type": "bearer",
"refresh_token": "f8dc8c19-6b0f-459c-aee0-8dc1677ec66e",
"expires_in": 1200000,
"scope": "read write"
}

可以发现,刷新过后的token 得到的 refresh_token并没有改变,仍然是 f8dc8c19-6b0f-459c-aee0-8dc1677ec66e,因此需要在配置刷新token时 配置 如下信息才能每次生成不同的refresh_token

1
2
3
4
5
6
7
8
9
10
11
12
DefaultTokenServices tokenServices = new DefaultTokenServices();
tokenServices.setTokenStore(endpoints.getTokenStore());
tokenServices.setSupportRefreshToken(true);

// 每次刷新token 都会重新生成新的refresh token(该次修改处)
tokenServices.setReuseRefreshToken(false);

tokenServices.setClientDetailsService(endpoints.getClientDetailsService());
tokenServices.setTokenEnhancer(endpoints.getTokenEnhancer());
tokenServices.setAccessTokenValiditySeconds(60*60*2);//token有效期设置2个小时
tokenServices.setRefreshTokenValiditySeconds(60*60*12);//Refresh_token:12个小时
endpoints.tokenServices(tokenServices);

如果需要了解spring boot中oauth2的相关实现源码,idea中查看spring-security-oauth2包中的OAuth2AuthenticationProcessingFilter类的相关实现