众所周知 oauth2 有四种 验证方式 授权码是其中一种
流程 基本上就是 假设我是个用户 我手里有着访问某网站的凭证 (这里指用户名和密码)
我想访问这个网站 当我直接点击网站的相关链接 结果你因为没有登录 浏览器会把你的访问url保存
并重定向到一个登录页 当你登录成功的时候 说明你认证成功 这时候 spring security 会从保存的请求中
把你的url取出来 并重定向到目标页 进行授权操作 当你授权成功 spring security oauth2 会在代码内部进行重定向
这时候你到了一个你可以随意定义的自定义页 观察浏览器 url 框 中会有一个code的标识
这时候你拿着这个授权码即code 发送到 token 端点 获取 token 拿到token 证明你已经在授权服务器上获取到了令牌
接下来的操作 就是你拿着令牌 访问你的资源服务器 它会验证你的token 如果有效 你会正常访问到你的controller
大致就是这个流程 很简易的说个大概
道理一大堆 上代码
我说一下
CustomerUser 这个类呢 主要是在你进行登录验证的时候提供的凭证 当然 我这是最简易的 就没连数据库 你可以在
loadUserByUsername 这个方法里添加 查询数据库的操作 你可以用mybatis jpa jooq 啥都行 查出来用户往构造里一塞
你看到的那一串 是我用的
BCryptPasswordEncoder类加密的 明文就是1 登录的时候密码就是1
OAuth2AuthorizationServer这个类看图就知道 是授权服务器
configure(ClientDetailsServiceConfigurer clients) 这个方法主要作用是配置一个客户端 这里我采取在内存中创建
client_id : xiong client_secret : 1 (那一长串也是用的上面的加密方法 明文就是1)
redirect_uri : http://www.baidu.com (自定义嘛 嘿嘿) 这个是授权无论成功失败都走这个页面
authority : ROLE_USER 这个客户端权限
authorizedGrantTypes 这个我这里 指定了两个
authorization_code 和 refresh_token 分别是 授权码模式 和 刷新token (官方把它也划入授权模式了,没办法)
scope : all
configure(AuthorizationServerEndpointsConfigurer endpoints) 这个方法是对端点进行配置
我在这个方法中 配置了两行
endpoints.allowedTokenEndpointRequestMethods(HttpMethod.GET, HttpMethod.POST); 这行表明 获取token的时候是可以
使用 get 或者 post 请求 默认只有 post 请求 加入get请求 我可以直接在浏览器里发送 就不用postman了
endpoints.userDetailsService(userDetailsService); 这一行 是为了 refreshtoken 刷新 access_token 用的
没有这行 刷新 会报 服务器错误
configure(AuthorizationServerSecurityConfigurer security) 这个方法 是对安全的一些设置 这么说有点牵强 不过我也只能先这样解释 见谅哈 毕竟 接触 到 完成 这个demo 花了两天 虽然之前尝试过 但都失败了 这次我采用的是最新版的springboot 2.2.4.RELEASE 继续说方法
security.passwordEncoder(new BCryptPasswordEncoder());这个方法 就是配置客户端密码加密的 在内部代码中会调用
BCryptPasswordEncoder 的 match 方法 比较 浏览器传过来的密码 和 内存中创建的密文 做匹配 匹配成功 代表着你可以认证成功
或者获取access_token
security.allowFormAuthenticationForClients(); 这个方法 是为了 使用表单提交 取消这行 你会发现一个有趣的现象
会弹出一个http Basic 的认证框 当然 客户端 xiong 密码 是 1 但是为什么我都认证了 为什么又认证一回 这个往下看
ResourceServer 这个类充当 资源服务器 里面配置一个url 那是我的controller 路径相匹配的ant 写法
只有你获取token成功并且在你访问的时候携带access_token才能从资源服务器中认证成功 访问到controller
SecurityConfig 这个类 真相了 哈哈哈 明文就是1
configure(AuthenticationManagerBuilder auth) 这个类 就是自定义认证用户 认证的是你登录页的那个
controller 没啥说的 全程没有 一点配置 没有一个自己写的页面 所以是最简易的
main 方法
pom.xml 就不放了 一会把 代码放上 自己看吧 本来想着把jwt 用上再写博客 结果忍不住了 水个积分哈哈哈 后期我会加上的
这个时候看一下 代码运行效果
http://localhost:8080/oauth/authorize?response_type=code&client_id=xiong&client_secret=1&redirect_uri=http://www.baidu.com
你访问 这个网址 它会跳到 这个是人家默认的 可不是我写的 我前端和后端一样菜 都是痛啊
看到没
当我点 Approve 时候 跳到
看 这code 授权码 不就有了 9B019J 这个就是授权码
然后获取token
http://localhost:8080/oauth/token?grant_type=authorization_code&code=9B019J&client_id=xiong&client_secret=1&redirect_uri=http://www.baidu.com
当你 粘贴到url 框中小心空格每个参数之间都是相连的
上图
access_token 有了 refresh_token也有了 现在 我该访问资源服务器了
http://localhost:8080/user/ok?access_token=c4d37cc5-e560-4d38-a484-840d75226399
到这 还没完 我们还有 refresh_token呢 access_token失效了 咋办
http://localhost:8080/oauth/token?grant_type=refresh_token&refresh_token=3e9a9e34-8950-4678-9039-df0cad1668c6&client_id=xiong&client_secret=1
看 这回新的 access_token又获取到了 有人说 那你的refresh_token过期了咋办 重新登录吧 哈哈哈哈
拿着新的token 访问controller
http://localhost:8080/user/ok?access_token=93201376-1f47-4f88-915c-345aad8cc39a
这回还剩下 一个问题 关于认证两次的问题
其实啊 这是因为 你在 security 中配置的用户在内部代码认证中涉及的不是一个
第一次认证走的是 CustomerUser认证
第二次认证走的是 ClientDetailsUserDetailsService 认证
把 security.allowFormAuthenticationForClients(); 这句话注释掉 说明当时你提交的请求中 没用到orm表单 自然而然 即使你的输入框里有用户密码 他还是让你输入身份信息 当你输入完成 又会走到那个内部代码的断点 自己看吧 哈哈哈哈
当然我觉得可以走一个验证 不过得我现在还没拓展 等过段时间的 加上jwt 和 jwk 就完美了
下载工程后 如果没反应 多点击 那个左上角的刷新
生于平凡 遇见不凡 超脱平凡 尚为自然
https://github.com/luanmaxiansheng/springOauth2.git 欢迎来访