Spring Security OAuth2.0

Spring Security OAuth2.0,第1张

什么是 OAuth 2

OAuth 是一个开放标准,该标准允许用户让第三方应用访问该用户在某一网站上存储的私密资源 (如头像、照片、视频等),而在这个过程中无须将用户名和密码提供给第三方应用。实现这功能是通过提供令牌(token),而不是用户名和密码来访问他们存放在特定服务提供者的数据。

这样,OAuth 让用户可以授权 第三方网站灵活地访问存储在另外一些资源服务器的特定信息,而非所有内容。目前主流的 qq, 微信等第三方授权登录方式都是基于 OAuth2 实现的

传统的 Web 开发登录认证一般都是基于 Session 的,但是在前后端分离的架构中继续使用 Session 会有许多不便,因为移动端(Android、iOS、微信小程序等)要么不支持Cookie(微 信小程序),要么使用非常不便,对于这些问题,使用 OAuth 2 认证都能解决

OAuth 2 授权流程

  • 步骤1:客户端(第三方应用)向用户请求授权。

  • 步骤2:用户单击客户端所呈现的服务授权页面上的同意授权按钮后,服务端返回一个授权许可凭 证给客户端。

  • 步骤3:客户端拿着授权许可凭证去授权服务器申请令牌。

  • 步骤4:授权服务器验证信息无误后,发放令牌给客户端。

  • 步骤5:客户端拿着令牌去资源服务器访问资源。

  • 步骤6:资源服务器验证令牌无误后开放资源。

OAuth 2 授权模式

OAuth 协议的授权模式共分为 4 种,分别说明如下:

  • 授权码模式:授权码模式(authorization code)是功能最完整、流程最严谨的授权模式。它的 特点就是通过客户端的服务器与授权服务器进行交互,国内常见的第三方平台登录功能基本 都是 使用这种模式。

  • 简化模式:简化模式不需要客户端服务器参与,直接在浏览器中向授权服务器中请令牌,一般若网 站是纯静态页面,则可以采用这种方式。

  • 密码模式:密码模式是用户把用户名密码直接告诉客户端,客户端使用这些信息向授权服务器中请 令牌。这需要用户对客户端高度信任,例如客户端应用和服务提供商是同一家公司。

  • 客户端模式:客户端模式是指客户端使用自己的名义而不是用户的名义向服务提供者申请授权。严 格来说,客户端模式并不能算作 OAuth 协议要解决的问题的一种解决方案,但是,对于开发者而 言,在一些前后端分离应用或者为移动端提供的认证授权服务器上使用这种模式还是非常方便的。

授权码模式案例
  • 授权码模式授权流程--简化

    • 客户端向授权服务器申请授权码(授权服务器先判断是否登录,没有则需要先登录认证后,才会生成授权码code携带在direct_uri后面)

    • 客户端拿着授权码code向授权服务器申请令牌

    • 客户端拿着令牌向资源服务器申请资源

  • 授权码模式授权流程--详细

    • 1.客户端(第三方应用京东)携带client_id、redirect_uri,中间通过代理者(浏览器)访问授权服务器,授权服务器使用SpringSecurity认证,如果已经登录过则直接返回redirect_uri,没有登录则跳转到(授权服务)登录页登录

    • 2.授权服务器对客户端进行身份验证(通过用户代理,让用户输入用户名和密码)

    • 3.授权成功(身份认证),会重定向到redirect_uri并携带授权码code作为uri参数

    • 4.客户端(京东服务)携带授权码访问授权服务器申请令牌

    • 5.授权服务器验证授权码,返回令牌access_token

  • 授权服务器职责

    • 生成授权码、生成令牌、存储令牌、发放令牌、校验令牌

申请授权码
  • 访问授权服务器的oauth2的获取授权码端点oauth/authorize (GET)

  • URI:localhost:8888/oauth/authorize?client_id=cms&client_secret=secret&response_type=code

  • response:http://127.0.0.1:8084/cms/login?code=U22eHY

  • 参数:

    • oauth/authorize:授权码端点

    • client_id:客户端id,和授权配置类中设置的客户端id一致

    • client_secret:客户端秘钥,同上

    • response_type:oauth2授权模式,code表示授权码模式

    • redirect_uri:跳转uri,当授权码申请成功后会跳转到此地址,并在uri后面携带授权码code参数

    因为没有登录,所以会返回SpringSecutity默认登录页面,若是自定义登录页面,则Security这样配置
    http.formLogin().loginPage("/login).permitAll()
    当第三方应用京东使用第三方平台qq进行登录时,需要我们输入qq的账号密码,就是因为没有登录
申请令牌
  • 访问授权服务器的oauth2的获取令牌端点oauth/token (POST postman测试)

  • URI:http://localhost:8888/oauth/token?code=U22eHY&grant_type=authorization_code&redirect_uri=http://127.0.0.1:8084/cms/login&scope=all

  • response:{ "access_token": "874ec87e-30da-4e9f-a05f-eacf05e9dc18", "token_type": "bearer", "refresh_token": "b956f881-5fad-42d1-81d5-14bfd9886db3", "expires_in": 1799, "scope": "all" }

  • 请求参数:

    • code:授权码(只能用一次就失效)

    • grant_type:授权类型,值authorization_code表示授权码模式

    • redirect_uri:申请授权码时的跳转url,一定和申请授权码时用的redirect_uri一致

    • scope:允许授权范围,值和授权配置类一致

  • 返回参数:

    • access_token:申请的令牌,携带此令牌访问资源

    • token_type:有MAC Token与Bearer Token两种类型,两种的校验算法不同,RFC 6750建议Oauth2采用 Bearer Token(RFC Reader - An online reader for IETF RFCs)。

    • refresh_token:刷新令牌,使用此令牌可以延长访问令牌的过期时间,授权配置类中授权类型需要包含refresh_token模式

    • expires_in:过期时间,单位为秒。

    • scope:范围,与定义的客户端范围一致。

    • jti:当前token的唯一标识

令牌校验
  • 访问授权服务器的oauth2的校验令牌端点oauth/check_token

  • URI:http://localhost:8888/oauth/check_token?token=874ec87e-30da-4e9f-a05f-eacf05e9dc18

  • response:{ active: true, exp: 1650256367, user_name: "cbw", authorities: [ "ROLE_admin" ], client_id: "cms", scope: [ "all" ] }

使用令牌,访问资源服务
  • 不使用令牌访问资源服务器/index接口

URI:http://localhost:8084/cms/index
response:Full authentication is required to access this resourceunauthorized
  • 使用正确令牌访问资源服务器/index接口

URI:http://localhost:8084/cms/index?access_token=874ec87e-30da-4e9f-a05f-eacf05e9dc18
response:index
  • 使用错误令牌访问

URI:http://localhost:8084/cms/index?access_token=5294b7f9-babf-489-a565-412cb326959
response:5294b7f9-babf-489-a565-412cb3269592 invalid_token
简单模式案例 搭建授权服务器

同授权码模式的授权服务器

主要是授权配置类的设置授权服务器支持的授权模式包含简单模式implicit

搭建资源服务器(同上) 授权码与简化模式区别
  • 授权码模式:

1.浏览器向授权服务器申请授权码交给客户端(第三方应用程序京东服务),客户端拿着授权码向授权服务器申请令牌,
2.浏览器只持有授权码,且授权码使用一次后就失效,这样即使授权码泄露,令牌相对安全,
3.而简化模式由user agent(浏览器),直接持有令牌,相对不安全
  • 简化模式:

不通过第三方应用程序的服务器,直接在浏览器中向授权服务器申请令牌,跳过了"授权码"这个步骤
申请令牌
  • 浏览器向授权服务器申请令牌

    • URI:localhost:8888/oauth/authorize?client_id=cms&client_secret=secret&response_type=token

    • response:http://127.0.0.1:8084/cms/login#access_token=5bb2d401-b90f-46f7-a51d-00208722eef7&token_type=bearer&expires_in=1800&scope=all

    • 如果授权服务器没有登录过,跳转到SringSecurity默认的登录页面先让用户(资源持有者)登录授权服务器

  • 校验令牌

    • URI:http://localhost:8888/oauth/check_token?token=5bb2d401-b90f-46f7-a51d-00208722eef7

    • response:{ active: true, exp: 1650267440, user_name: "cbw", authorities: [ "ROLE_admin" ], client_id: "cms", scope: [ "all" ] }

  • 使用令牌访问资源

    • 正确令牌访问资源服务器:

    URI:http://localhost:8084/cms/index?access_token=5bb2d401-b90f-46f7-a51d-00208722eef7
    response:index
    • 错误令牌访问资源服务器

    URI:http://localhost:8084/cms/index?access_token=5bb2d401-b90f-46f7-a51d-00208722eef
    response:5bb2d401-b90f-46f7-a51d-00208722eefinvalid_token
密码模式
  • 特点

密码模式中,用户向客户端提供自己的用户名和密码,这通常用在用户对客户端高度信任的情况。
一般用户微服务中,各个服务之间高度信任,或者说各个服务都是同一家,
在前后端分离微服务架构中做单点登录最流行的就是使用Spring Oauth2的密码模式实现单点登录。
而像第三方登录这种情况,第三方应用京东和授权服务器(qq)和资源服务器(qq)不是一家的
申请令牌
  • 向授权服务器申请令牌

    • URI:http://localhost:8888/oauth/token?grant_type=password&username=cbw&password=123&scope=all

    • response:{ "access_token": "695af335-e52d-4bb2-a0d6-b28b099656ae", "token_type": "bearer", "refresh_token": "a76a058c-9600-471f-bbce-5f111b296ebb", "expires_in": 1799, "scope": "all" }

    • http Basic认证

    此链接需要使用 http Basic认证,
    header字段Authorization:Basic WGNXZWJBcHA6WGNXZWJBcHA=WGNXZWJBcHA6WGNXZWJBcHA  
    客户端id:客户端秘钥的base64编码
使用令牌
URI:http://localhost:8084/cms/index?access_token=695af335-e52d-4bb2-a0d6-b28b099656ae
response:index
客户端模式
  • 特点

A直接拿客户端id和客户端秘钥去授权服务器B申请令牌,客户端id和客户端秘钥可以由资源服务器C共享,
这种模式其实也是适合微服务,各服务之间共享id和secret,谁要访问其它服务的资源,都拿这俩值去授权服务器取token
流程
  • 1.第一步: 获取token (client_id、client_secret直接作为参数传递,不需要http Basic认证,放入header中)

http://localhost:8888/oauth/token?client_id=cms&client_secret=secret&grant_type=client_credentials&scope=all
  • 2.第二步:拿到acceptToken之后,就可以直接访问资源

获取令牌
  • URI:http://localhost:8888/oauth/token?client_id=cms&client_secret=secret&grant_type=client_credentials&scope=all 【post】

  • response:{ "access_token": "d8b57e92-8bf5-4708-bb7b-76027398ba7a", "token_type": "bearer", "expires_in": 1800, "scope": "all" }

使用令牌访问资源
  • URI:http://localhost:8084/cms/index?access_token=d8b57e92-8bf5-4708-bb7b-76027398ba7a

  • response:index

 

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/741009.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-04-28
下一篇 2022-04-28

发表评论

登录后才能评论

评论列表(0条)

保存