背景
OAuth2的概念这里不在赘述,有兴趣的同学可以看看我其他相关文章,这里直接干货 演示 OAuth2的 四种授权方式,使用姿势
1 授权码(authorization-code)
1.1 访问获取认证服务器获取授权码code api 如:
localhost:7777/oauth/authorize?client_id=cms&response_type=code
然后我们会跳转到认证服务器 登陆地址
这里通过认证服务器 预先颁发的账号/密匙,登陆进入授权页面
点击授权之后/ 认证服务器会重定向地址,这里可以取到我们的授权码,如图code=taApM1
1.2 通过授权码 code=taApM1 访问获取token api 获取access_token 如图
1.3 我们也可以通过认证服务器的access_token 校验api 来校验一下我们获取到的access_token 是否有效 http://localhost:7777/oauth/check_token?token=474f802c-d65c-4e64-aaf2-dfdf034c807c
PS: 这里返回的access_token里面有一个refresh_token信息,有兴趣的同学可以见我的另一篇文章,里面有对refresh_token的作用意义做了讲解 [OAuth2源码分析之 常见面试问题总结回答二 access_token 与 refresh_token](https://juejin.cn/post/7056614367747375118)
1.4 通过拿到的access_token 访问我们需要访问的资源地址demo url
2 隐藏式(implicit)
2.1 在授权码模式的基础,直接去掉了获取授权码的过程,相当于直接获取access_token 并且访问目标地址 先在 认证服务器配置重定向url:
public class OAuth2Configuration extends AuthorizationServerConfigurerAdapter {
```
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
// 使用内存存储
clients.inMemory()
.withClient(CLIENT_ID) //标记客户端id
.secret(passwordEncoder.encode(SECRET_CHAR_SEQUENCE)) //客户端安全码
.autoApprove(false) //为true 直接自动授权成功返回code
.redirectUris("http://localhost:7778/resource_server") //重定向uri,uri中携带的必须为这里面填写的之一
.scopes("app", "file", "zone") //允许授权范围,ALL就不会出现授权页
// .accessTokenValiditySeconds(ACCESS_TOKEN_VALIDITY_SECONDS) //token 时间秒
// .refreshTokenValiditySeconds(REFRESH_TOKEN_VALIDITY_SECONDS) //刷新token 时间 秒
.authorizedGrantTypes(GRANT_TYPE_PASSWORD, AUTHORIZATION_CODE, REFRESH_TOKEN, IMPLICIT); //允许授权类型
}
}
2.2 直接访问获取access_token api地址
localhost:7777/oauth/authorize?response_type=token&client_id=cms&redirect_uri=http://localhost:7778/resource_server
这里的redirect_uri 指的就是你的资源目标访问地址
大家可以看下访问流程
还是会先跳到认证服务器登陆页,进行登陆
登陆之后进行授权
授权之后 会直接跳转到我们的redirect_uri=http://localhost:7778/resource_server 这个地址,并且携带了获取的access_token,如图
2.3 验证刚才步骤2.2获取的access_token 是否有效
3 密码式(password)
如果你高度信任某个应用,允许用户把用户名和密码,直接告诉该应用。
该应用就使用你的密码,申请令牌,这种方式称为 密码式(password)/ 例如自家认证的服务器
3.1 前期准备 认证中心配置支持密码式授权
public class OAuth2Configuration extendsAuthorizationServerConfigurerAdapter {
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
// 配置密码授权模式
.and()
.withClient("cms1")
.authorizedGrantTypes("password", "refresh_token")
.scopes("select")
.authorities("oauth2")
// user ---> BCryptPasswordEncoder 加密算法生成
.secret("$2a$10$vrRjc8vlDwv6gBHlv/me8eeRsHO7P3I7ge0F03sr4C3hh/SmS/lMC");
}
public static void main(String[] args) {
String pass = "user";
BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
final String passHash = encoder.encode(pass);
System.out.println(passHash);
final boolean matches = encoder.matches(pass, passHash);
System.out.println(matches);
}
// $2a$10$jbVRxqHjW8QIYw7.UFVD/Ocf.7TSKLhZrGJRouTKq/PyTNTQ6TVIa
// true
请注意我这里配置的secret("$2a$10$vrRjc8vlDwv6gBHlv/me8eeRsHO7P3I7ge0F03sr4C3hh/SmS/lMC") 因为我选用的是 BCryptPasswordEncoder加密方式
即原密码user 对应加密之后是$2a$10$vrRjc8vlDwv6gBHlv/me8eeRsHO7P3I7ge0F03sr4C3hh/SmS/lMC
3.2 访问认证中心密码模式获取access_token api 地址http://localhost:7777/oauth/token?username=user&password=user&grant_type=password&scope=select&client_id=cms1&client_secret=user 得到access_token
3.3 最后校验一下我们通过密码模式获取的access_token看下是否有效
http://localhost:7777/oauth/check_token?token=5691ce5f-686b-40a6-9832-88810792be7f 有效/成功
4 客户端凭证(client credentials)
客户端模式(Client Credentials Grant)指客户端以自己的名义,而不是以用户的名义,向"服务提供商"进行认证。
严格地说,客户端模式并不属于OAuth框架所要解决的问题。在这种模式中,用户直接向客户端注册,客户端以自己的名义要求"服务提供商"提供服务,其实不存在授权问题。
4.1 前期准备 认证中心配置支持客户端凭证
public class OAuth2Configuration extendsAuthorizationServerConfigurerAdapter {
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
// 配置客户端授权模式
.and()
.withClient("client_1")
.authorizedGrantTypes("client_credentials", "refresh_token")
.scopes("select")
.authorities("oauth2")
.secret("$2a$10$vrRjc8vlDwv6gBHlv/me8eeRsHO7P3I7ge0F03sr4C3hh/SmS/lMC");
// 这里的secret和步骤3.1一样 是user加密而来的
}
4.2 访问认证中心获取access_token api地址 http://localhost:7777/oauth/token?grant_type=client_credentials&scope=select&client_id=client_1&client_secret=user
4.3 验证一下我们获取的access_token 是否有效 http://localhost:7777/oauth/check_token?token=2ab79cbf-4809-4d90-a68d-fd78de17cb4d 有效/成功