微信授权就是这个原理,Spring Cloud OAuth2 授权码模式
3、点击确定后,来到授权确认页面,页面上有 Authorize 和 Deny (授权和拒绝)两个按钮。可通过将 autoapprove 字段设置为 0 来取消此页面的展示,默认直接同意授权。
4、点击同意授权后,跳转到了回调地址,虽然是 404 ,但是我们只是为了拿到 code 参数,注意地址后面的 code 参数。
5、拿到这个 code 参数是为了向认证服务器 /oauth/token 接口请求 access_token ,继续用 REST Client 发送请求,同样的,你也可以用 postman 等工具测试。
注意 grant_type 参数设置为 authorization_code,code 就是上一步回调地址中加上的,redirect_uri 仍然要带上,回作为验证条件,如果不带或者与前面设置的不一致,会出现错误。
请求头 Authorization ,仍然是 Basic + 空格 + base64(client_id:client_secret),可以通过 https://www.sojson.com/base64.html 网站在线做 base64 编码。
code-client:code-secret-8888 通过 base64 编码后结果为 Y29kZS1jbGllbnQ6Y29kZS1zZWNyZXQtODg4OA==
POST http://localhost:6001/oauth/token?grant_type=authorization_code&client=code-client&code=BbCE34&redirect_uri=http://localhost:6102/client-authcode/login Accept: */* Cache-Control: no-cache Authorization: Basic Y29kZS1jbGllbnQ6Y29kZS1zZWNyZXQtODg4OA==
发送请求后,返回的 json 内容如下:
{ "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX25hbWUiOiJhZG1pbiIsImp3dC1leHQiOiJKV1Qg5omp5bGV5L-h5oGvIiwic2NvcGUiOlsiYWxsIl0sImV4cCI6MTU3MjYwMTMzMiwiYXV0aG9yaXRpZXMiOlsiUk9MRV9BRE1JTiJdLCJqdGkiOiI2OWRmY2M4Yy1iZmZiLTRiNDItYTZhZi1hN2IzZWUyZjI1ZTMiLCJjbGllbnRfaWQiOiJjb2RlLWNsaWVudCJ9.WlgGnBkNdg2PwKqjbZWo6QmUmq0QluZLgIWJXaZahSU", "token_type": "bearer", "refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX25hbWUiOiJhZG1pbiIsImp3dC1leHQiOiJKV1Qg5omp5bGV5L-h5oGvIiwic2NvcGUiOlsiYWxsIl0sImF0aSI6IjY5ZGZjYzhjLWJmZmItNGI0Mi1hNmFmLWE3YjNlZTJmMjVlMyIsImV4cCI6MTU3MjYzMzczMiwiYXV0aG9yaXRpZXMiOlsiUk9MRV9BRE1JTiJdLCJqdGkiOiJkNzk2OWRhMS04NTg4LTQ2YzMtYjdlNS1jMGM5NzcxNTM5Y2YiLCJjbGllbnRfaWQiOiJjb2RlLWNsaWVudCJ9.TEz0pQOhST9-ozdoJWm6cf1SoWvPC6W-5JW9yjZJXek", "expires_in": 3599, "scope": "all", "jwt-ext": "JWT 扩展信息", "jti": "69dfcc8c-bffb-4b42-a6af-a7b3ee2f25e3" }
和上一篇文章 password 模式拿到的 token 内容是一致的,接下来的请求都需要带上 access_token 。
6、把获取到的 access_token 代入到下面的请求中 ${access_token} 的位置,就可以请求微服务中的需要授权访问的接口了。
GET http://localhost:6102/client-authcode/get Accept: */* Cache-Control: no-cache Authorization: bearer ${access_token}
接口内容如下:
@org.springframework.web.bind.annotation.ResponseBody @GetMapping(value = "get") @PreAuthorize("hasAnyRole('ROLE_ADMIN')") public Object get(Authentication authentication) { //Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); authentication.getCredentials(); OAuth2AuthenticationDetails details = (OAuth2AuthenticationDetails) authentication.getDetails(); String token = details.getTokenValue(); return token; }
经过以上的手工测试,证明此过程是通的,但是还没有达到自动化。如果你集成过微信登录,那你一定知道我们在回调地址中做了什么,拿到返回的 code 参数去 token 接口换取 access_token 对不对,没错,思路都是一样的,我们的回调接口中同样要拿 code 去换取 access_token。
为此,我做了一个简单的页面,并且在回调接口中请求获取 token 的接口。
创建简单的登录页面
在 resources 目录下创建 templates 目录,用来存放 thymeleaf 的模板,不做样式,只做最简单的演示,创建 index.html 模板,内容如下:
<!DOCTYPE html>