# Spring-security-oauth2 **Repository Path**: sixdog/Spring-security-oauth2 ## Basic Information - **Project Name**: Spring-security-oauth2 - **Description**: Spring security整合oauth2实现token认证 - **Primary Language**: Java - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 21 - **Created**: 2020-07-29 - **Last Updated**: 2020-12-19 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # Spring-security整合OAuth2授权认证协议 1. 使用@EnableAuthorizationServer配置授权服务器,开启授权认证服务的端点/oauth/authorize、/oauth/token 2. 使用@EnableResourceServer配置资源服务器,配置需要传token才能调用的接口路径 3. 使用@EnableGlobalMethodSecurity配置spring security放行所有认证服务端点/oauth/** 4. token写入redis缓存,过期会自动失效.运行前请先开启redis并导入SQL脚本 5. 由于使用了password认证,前端发请求时需要先申请token,代码在auth.js中: ``` function fetchToken(){ var name = token_storage.getItem('username'); var pwd = token_storage.getItem('password'); var data={ 'scope':'server', 'grant_type':'password', 'username':"java", "password":"1234" }; $.ajax({ url: "/oauth/token", type:"post", data:data, async: false, contentType: 'application/x-www-form-urlencoded', beforeSend:function(xhr){ xhr.setRequestHeader("Authorization", 'Basic ' + BASE64.encode(client_id+':'+client_secret)); }, success: function (sResponse) { saveAuth(sResponse); console.log('fetch_token ok: ' + sResponse.access_token+' expires_in:'+sResponse.expires_in); }, error:function(a,b,c){ console.log(a, b, c); } }); } ``` 如果要刷新token,则: ``` function refreshToken(){ var auth = getAuth(); var data={ 'client_id': client_id, 'client_secret': client_secret, 'grant_type':'refresh_token', 'refresh_token':auth.refresh_token }; $.ajax({ url: "/oauth/token", type:"post", data:data, async: false, contentType: 'application/x-www-form-urlencoded', success: function (sResponse) { saveAuth(sResponse); console.log('refresh_token ok: ' + sResponse.access_token+' expires_in:'+sResponse.expires_in); }, error:function(a,b,c){ if (a.status==400 && a.responseJSON.error=='invalid_grant'){ console.log('refresh token invalid'); clearAuth(); } } }); } ``` 发送请求前,在登录页面使用ajaxSetup()对ajax请求的token初始化并写入localStorage。登录用户名java,密码1234 ![输入图片说明](https://images.gitee.com/uploads/images/2020/0717/093426_d7fbf619_1110335.png "165717_a8d350ef_1110335.png") 如此,则所有请求头都自带token: ![输入图片说明](https://images.gitee.com/uploads/images/2020/0717/091529_3c2b9ec2_1110335.png "微信截图_20200717091502.png") ### 测试password认证,前端需要先发送请求获取token: ![输入图片说明](https://images.gitee.com/uploads/images/2020/0716/111856_f9d381b6_1110335.png "14.png") ![输入图片说明](https://images.gitee.com/uploads/images/2020/0716/111907_2d4ecf6b_1110335.png "11741.png") 然后拿着token去拉接口: ![输入图片说明](https://images.gitee.com/uploads/images/2020/0618/141539_7fc4793d_1110335.jpeg "2.jpg") 如果token过期就刷新token: ![输入图片说明](https://images.gitee.com/uploads/images/2020/0618/141600_e81f82bc_1110335.jpeg "3.jpg") ### oauth2的认证流程 ![输入图片说明](https://images.gitee.com/uploads/images/2020/0717/094118_fd947e6f_1110335.png "085436_1dac6cc3_1110335.png") OAauth2.0包括以下角色: - 客户端 本身不存储资源,需要通过资源拥有者的授权去请求资源服务器的资源,比如:Android客户端、Web客户端(浏览器端)、微信客户端等。 - 资源拥有者 通常为用户,也可以是应用程序,即该资源的拥有者。 - 授权服务器(也称认证服务器)用于服务提供商对资源拥有的身份进行认证、对访问资源进行授权,认证成功后会给客户端发放令牌 (access_token),作为客户端访问资源服务器的凭据。 - 资源服务器 存储资源的服务器,服务提供商会给准入的接入方一个身份,用于接入时的凭据: client_id:客户端标识 client_secret:客户端秘钥 因此,准确来说,授权服务器对两种OAuth2.0中的两个角色进行认证授权,分别是资源拥有者、客户端。 总之,对于授权码模式,先申请授权码,然后用授权码申请token令牌,然后把token令牌放在请求头拉取其他接口。如果是密码模式,则可以跳过授权码,直接走后面两步。 ### 测试授权码模式 需要先申请授权code:http://localhost:8080/oauth/authorize?response_type=code&client_id=web ![输入图片说明](https://images.gitee.com/uploads/images/2020/0619/100056_4c799f0d_1110335.png "1.png") - 同意授权后,页面地址会返回一个code: ![输入图片说明](https://images.gitee.com/uploads/images/2020/0619/100210_105489f4_1110335.png "微信截图_20200619100155.png") - 再拿着code请求token: ![输入图片说明](https://images.gitee.com/uploads/images/2020/0619/100502_0ad6cf44_1110335.png "微信截图_20200619100438.png") - 再拿着token去拉接口: ![输入图片说明](https://images.gitee.com/uploads/images/2020/0619/100626_b1306b1d_1110335.png "微信截图_20200619100610.png") ### 测试客户端模式 直接取申请token: ![输入图片说明](https://images.gitee.com/uploads/images/2020/0619/101444_3532b747_1110335.png "微信截图_20200619100610.png") - 再用token拉接口 ![输入图片说明](https://images.gitee.com/uploads/images/2020/0619/101538_6fa0fbd5_1110335.png "微信截图_20200619100610.png")