SpringBoot 1.9 整合Oauth2.0

本文详细介绍了如何在SpringBoot项目中整合Oauth2.0,包括Oauth2.0的授权模式,如授权码模式、简化模式、密码模式、客户端模式和扩展模式。并逐步讲解了SpringBoot整合Oauth2.0与Spring Security的步骤,涉及创建数据库表、配置POM、数据源、用户验证服务以及密钥编码解码器等关键环节。
摘要由CSDN通过智能技术生成

1.9 整合Oauth2.0

1.9.1 Oauth2.0介绍

在实践之前我们先来了解下oauth2.0,OAuth是一个关于授权(authorization)的开放网络标准,在全世界得到广泛应用,目前的版本是2.0版。OAuth2.0服务提供者实际上分为:“授权服务 Authorization Service ”和“资源服务Resource Service”。Oauth2.0 的运行流程如下图所示:
在这里插入图片描述

*(A)用户打开客户端,客户端要求用户给予授权。
*(B)用户同意给予客户端授权。
*(C)客户端使用上一步获得的授权(一般是Code),向认证服务器申请令牌TOKEN。
*(D)认证服务器对客户端进行认证以后,确认无误,同意发放令牌。
*(E)客户端使用令牌,向资源服务器申请获取资源(用户信息等)。
*(F)资源服务器确认令牌无误,同意向客户端开放资源。
图中服务端的三个组件分别为:

  • Resource Owner:即指需要授权访问的资源,比如用户昵称,头像
  • Authorization Server:鉴权服务,核心鉴权逻辑
  • Resource Server:资源服务
    Oauth2.0 定义了五种授权方式:
  • 授权码模式(authorization code)
  • 简化模式(implicit)
  • 密码模式(resource owner password credentials)
  • 客户端模式(client credentials)
  • 扩展模式(Extension)

1.9.2 Oauth2.0授权模式

1.9.2.1 授权码模式(authorization_code)

授权码模式是功能最完整、流程最严密的授权模式。他的特点是通过客户端的后台服务器,与"服务提供商"的认证服务器进行互动。以微信公众平台公众号网页应用开发流程为例。
在这里插入图片描述

步骤如下:

  • (A)用户访问客户端,客户端将用户导向认证服务器。
  • (B)用户选择是否给予客户端授权。
  • (C)若用户给予授权,认证服务器将用户导向客户端指定的"重定向URI"(redirection URI),同时附上授权码code。
  • (D)客户端收到授权码code,附上早先的"重定向URI",向认证服务器申请token。这一步是在客户端的后台的服务器上完成的,对用户不可见。
  • (E)认证服务器核对了授权码和重定向URI,确认无误后,向客户端发送访问令牌(access token)和更新令牌(refresh token)。

授权码模式的几个重要参数如下:

  • response_type:表示授权类型,必选项,此处的值固定为"code"
  • appid:表示客户端的ID,必选项
  • redirect_uri:表示重定向URI,可选项
  • scope:表示申请的权限范围,可选项
  • state:表示客户端的当前状态,可以指定任意值,认证服务器会原封不动地返回这个值。用于防止恶意攻击

授权码模式的URL以及参数应用步骤如下:

  • (1)引导用户跳转到授权页面:
    http://localhost:8080/oauth/authorize?client_id=client&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect
    参数:
    • client_id 客户唯一标识
    • redirect_uri 授权后重定向的回调链接地址, 请使用 urlEncode 对链接进行处理
    • response_type 返回类型,请填写code
    • scope 应用授权作用域,有snsapi_base 、snsapi_userinfo 两种
    • state 重定向后会带上state参数,开发者可以填写a-zA-Z0-9的参数值,最多128字节
  • (2)通过code获取Token
    http://localhost:8080/oauth/token? client_id=client&secret=secret&code=CODE&grant_type=authorization_code
    参数:
    • client_id 客户唯一标识
    • secret 密钥
    • code 填写获取的code参数(存在有效期,通常设为10分钟,客户端只能使用该码一次,否则会被授权服务器拒绝。该码与客户端ID和重定向URI,是一一对应关系)
    • grant_type 填写为authorization_code

返回结果:

{
   
"access_token":"ACCESS_TOKEN", //网页授权接口调用凭证,注意:此access_token与基础支持的access_token不同
"expires_in":7200,  // access_token接口调用凭证超时时间,单位(秒)
"refresh_token":"REFRESH_TOKEN", //用户刷新access_token
"client_id":"client",  //用户唯一标识
"scope":"all"  //用户授权的作用域,使用逗号(,)分隔
 } 

  • access_token:表示访问令牌,必选项。
  • token_type:表示令牌类型,该值大小写不敏感,必选项,可以是bearer类型或mac类型。
  • expires_in:表示过期时间,单位为秒。如果省略该参数,必须其他方式设置过期时间。
  • refresh_token:表示更新令牌,用来获取下一次的访问令牌,可选项。
  • scope:表示权限范围,如果与客户端申请的范围一致,此项可省略。
1.9.2.2 简化模式(implicit)

简化模式是不通过第三方应用程序的服务器,直接在浏览器中向认证服务器申请令牌,跳过"授权码"步骤。所有步骤在浏览器中完成,令牌对访问者是可见的,且客户端不需要认证。

在这里插入图片描述

步骤如下:

  • (A)客户端将用户导向认证服务器。
  • (B)用户决定是否给于客户端授权。
  • (C)若用户授权,认证服务器将用户导向客户端指定的"重定向URI",并在URI的Hash部分包含了访问令牌。
  • (D)浏览器向资源服务器发出请求,其中不包括上一步收到的Hash值。
  • (E)资源服务器返回一个网页,其中包含的代码可以获取Hash值中的令牌。
  • (F)浏览器执行上一步获得的脚本,提取出令牌。
  • (G)浏览器将令牌发给客户端。

下面是上面这些步骤所需要的参数。

A步骤中,客户端发出的HTTP请求,包含以下参数:

  • response_type:表示授权类型,此处的值固定为"token",必选项。
  • client_id:表示客户端的ID,必选项。
  • redirect_uri:表示重定向的URI,可选项。
  • scope:表示权限范围,可选项。
  • state:表示客户端的当前状态,可以指定任意值,认证服务器会原封不动地返回这个值

例如:


GET /authorize?response_type=token&client_id=s6BhdRkqt3&state=xyz&redirect_uri=http://www.baidu.com 
HTTP/1.1

Host: www.baidu.com

C步骤中,认证服务器回应客户端的URI,包含以下参数:

  • access_token:表示访问令牌,必选项。
  • token_type:表示令牌类型,该值大小写不敏感,必选项。
  • expires_in:表示过期时间,单位为秒。如果省略该参数,必须其他方式设置过期时间。
  • scope:表示权限范围,如果与客户端申请的范围一致,此项可省略。
  • state:如果客户端的请求中包含这个参数,认证服务器的回应也必须一模一样包含这个参数。
    例如:
HTTP/1.1 302 Found
Location: http://www.baidu.com#access_token=9e64da25-105c-4d20-a8b5-606c553c9b33&token_type=bearer&expires_in=829

认证服务器用HTTP头信息的Location栏,指定浏览器重定向的网址。注意,在这个网址的Hash部分包含了令牌。
根据上面的D步骤,下一步浏览器会访问Location指定的网址,但是Hash部分不会发送。接下来的E步骤,服务提供商的资源服务器发送过来的代码,会提取出Hash中的令牌。

1.9.2.3 密码模式(Password)

向客户端提供自己的用户名和密码,客户端使用这些信息,向"服务商提供商"索要授权。在这种模式中,用户必须把自己的密码给客户端,但是客户端不得储存密码。这通常用在用户对客户端高度信任的情况下,比如客户端是操作系统的一部分,或由一个著名公司出品。而认证服务器只有在其他授权模式无法执行的情况下,才能考虑使用这种模式。

步骤如下:

  • (A)用户向客户端提供用户名和密码。
  • (B)客户端将用户名和密码发给认证服务器,向后者请求令牌。
  • (C)认证服务器确认无误后,向客户端提供访问令牌。
    在B步骤中,客户端发出的HTTP请求,包含以下参数:
  • grant_type:表示授权类型,此处的值固定为"password",必选项。
  • username:表示用户名,必选项。
  • password:表示用户的密码,必选项。
  • scope:表示权限范围,可选项。

例如:


     POST /oauth/token HTTP/1.1
     Host: localhost
     Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW
     Content-Type: application/x-www-form-urlencoded
     grant_type=password&username=admin&password=111111
   

C步骤中,认证服务器向客户端发送访问令牌,例子:


     HTTP/1.1 200 OK
     Content-Type: application/json;charset=UTF-8
     Cache-Control: no-store
     Pragma: no-cache
     {
       "access_token":"2YotnFZFEjr1zCsicMWpAA",
       "token_type":"example",
       "expires_in":3600,
       "refresh_token":"tGzv3JOkF0XG5Qx2TlKWIA",
       "example_parameter":"example_value"
     }
     

整个过程中,客户端不得保存用户的密码。

1.9.2.4 客户端模式(client_credentials)

客户端模式下,并不存在对个体用户授权的行为,被授权的主体为client。因此,该模式可用于对某类用户进行集体授权。
在这里插入图片描述

申请该模式时,需要在HTTP request entity-body中提交以下信息。

POST /oauth/token
content-type: application/x-www-form-urlencoded
user-agent: PostmanRuntime/7.1.1
accept: */*
host: localhost:8080
accept-encoding: gzip, deflate
content-length: 74
grant_type=client_credentialsscope=allclient_id=zgqclient_secret=secret

若申请成功,服务器将返回access token和token有效时间。


HTTP/1.1 200
status: 200
cache-control: no-store
pragma: no-cache
x-content-type-options: nosniff
x-xss-protection: 1; mode=block
x-frame-options: DENY
content-type: application/json;charset=UTF-8
transfer-encoding: chunked
date: Thu, 20 Jun 2019 09:01:58 GMT
{"access_token":"43f856cb-2976-4a73-85f3-75638c32f8d7","token_type":"bearer","expires_in":1199,"scope":"all"}


1.9.2.5 扩展模式

扩展模式也叫自定义模式。Oauth2.0的规范中要求 “grant type”参数必须为URI。对于其他申请数据,可以根据需求进行自定义。这里不对这个部分做深入讨论,如果需要可以进一步查看Oauth2.0 相关文档。

1.9.2.6 令牌更新

在用户访问的时候,客户端的"访问令牌"如果已经过期,则需要使用"更新令牌"申请一个新的访问令牌。客户端可以发出更新令牌的HTTP请求进行令牌更新。
令牌更新请求包含以下参数:

  • grant_type:表示使用的授权模式,此处的值固定为"refresh_token",必选项。
  • refresh_token:表示早前收到的更新令牌,必选项。
  • scope:表示申请的授权范围,不可以超出上一次申请的范围,如果省略该参数,则表示与上一次一致。
  • client_id: 客户唯一标识
  • client_secret:密钥

例如:
请求内容:

POST /oauth/token
refresh_token=67ced428-1011-4da5-ae54-f3b98cb46b01&grant_type=refresh_token&scope=all&client_id=zgq&token_type=bearer&client_secret=secret

返回内容:

HTTP/1.1 200
{"access_token":"ab827d16-0a6b-4cdd-abaa-ad6535de9881","token_type":"bearer","refresh_token":"67ced428-1011-4da5-ae54-f3b98cb46b01","expires_in":11999,"scope":"all"}

1.9.3 SpringBoot整合Oauth2.0 和Spring Security

1.9.3.1 Step1:创建Oauth2.0所需要的三个表

Mysql脚本如下:

-- ----------------------------
-- Table structure for oauth_access_token
-- ----------------------------
DROP TABLE IF EXISTS `oauth_access_token`;
CREATE TABLE `oauth_access_token`  (
  `token_id` varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `token` blob NULL,
  `authentication_id` varchar(250) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
  `user_name` varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `client_id` varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `authentication` blob NULL,
  `refresh_token` varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  PRIMARY KEY (`authentication_id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;

-- ----------------------------
-- Table structure for oauth_client_details
-- ----------------------------
DROP TABLE IF EXISTS `oauth_client_details`;
CREATE TABLE `oauth_client_details`  (
  `client_id` varchar(250) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
  `resource_ids` varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `client_secret` varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `scope` varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `authorized_grant_types` varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `web_server_redirect_uri` varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `authorities` varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `access_token_validity` int(11) NULL DEFAULT NULL,
  `refresh_token_validity` int(11) NULL DEFAULT NULL,
  `additional_information` varchar(4096) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `autoapprove` varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  PRIMARY 
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Zone 7

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值