Spring Security学习之OAuth介绍

OAuth概念

OAuth:解决了在用户不提供密码给第三方应用的情况下,让第三方应用有权获取用户数据及基本信息的难题

    Open Authorization 开放授权,是一种资源提供商用于授权第三方应用代表资源所有者获得有限访问权限的授权机制。由于整个授权过程中,第三方应用无需触及用户的密码即可取得部分资源的使用权限,所有OAuth是安全开放的。

    例如登录CSDN的时候支持QQ、新浪微博、百度、开源中国和GitHub:

  1. 在选择QQ作为第三方登录的时候,会跳转到QQ站点(避免在CSDN中直接提交QQ密码)进行用户名和密码/二维码扫描登录验证

  2. 验证成功后进行授权管理,权限主要包括:自定义选择后CSDN网站之鞥能获取这一部分权限,其他隐私数据则是完全不可见

    1. 获取您的头像、昵称、性别

    2. 获取移动支付相关信息

  3. 确认授权后,跳回CSDN页面,此时用户已是登录状态

Spring Security学习之OAuth介绍_第1张图片

 

OAuth的运行流程

  1. 四个重要角色:

    1. Resource Owner:资源所有者,通常指用户。例如每个QQ用户

    2. Resource Server:资源服务器,指存放用户受保护资源的服务器,童涵春那个需要通过Access Token(访问令牌)才能进行访问。例如存储QQ用户基本信息的服务器,充当的就是资源服务器的角色

    3. Client:客户端,指需要获取用户资源的第三方应用。例如CSDN

    4. Authorization Server:授权服务器,用于验证资源所有者,并在验证成功后向客户端发放相关访问令牌。例如QQ授权登录页面

  2. 角色间交互:

    1. 客户端要求用户提供授权许可

    2. 用户同意向客户端提供授权许可(最关键的一步,OAuth提供四种授权模式,用于将用户的授权许可提供给客户端)

      1. Authorization Code授权码模式

      2. Implicit隐式授权模式

      3. Password Credentials密码授权模式

      4. Client Authorization客户端授权模式

    3. 客户端携带用户提供的授权许可向授权服务器申请资源服务器的访问令牌

    4. 授权服务器验证客户端及其携带的授权许可,确认有效后发放访问令牌

    5. 客户端使用访问令牌向资源服务器申请资源

    6. 资源服务器验证访问令牌,确认无误后向客户端提供资源

Spring Security学习之OAuth介绍_第2张图片

授权码模式

功能最完整、流程最严密的授权模式,将用户引导到授权服务器进行身份验证,授权服务器将发放的访问令牌传递给客户端。例如CSDN中的QQ登录方式就是由CSDN网站引导到QQ授权服务器进行身份验证的。

// 一个典型的QQ登录页面URL
https://graph.qq.com/oauth2.0/show?which=Login&display=pc& client_id=100270989& response_type=code& redirect_uri=https://passport.csdn.net/account/login?pcAuthType=qq& state=test
 
  • response_type:授权类型,必填项,固定为code

  • client_id:客户端id,必填项

  • state:客户端的状态,通常在授权服务器重定向时原样返回(以确保返回的code是当前客户端需要的code)一般state为随机生成的六位字符串

  • scope:申请的授权范围,例如获取用户信息、用户相册等,由授权服务器抽象为具体的条目(权限表中存储权限,方法头带上权限限制,可基于RBAC用户根据角色与权限绑定)

  • redirect_uri:授权通过后的重定向URL,授权服务器将用户登录完成之后重定向到客户端对应的地址

  • code:申请访问令牌必备的授权码(有效期较短)。客户端拿到code之后需要向授权服务器申请访问令牌access_token(仅可用一次,用完即作废)

    • 申请访问令牌的关键参数:

      • grant_type:授权类型,授权码模式中为authorization_code

      • client_id:客户端id

      • code:获取的授权码

      • redirect_uri:重定向URL

    • 通过构建一个HTTP请求发起访问令牌的申请,如果成功则客户端得到访问令牌,以及刷新令牌时的参数

    • 客户端:接入OAuth的第三方应用,例如CSDN即为一个第三方应用

Spring Security学习之OAuth介绍_第3张图片

 

隐式授权模式

客户端一般为用户浏览器。访问令牌通过重定向的方式传递到用户浏览器中,再通过浏览器的JavaSrcript底阿妈来获取访问令牌

  • 由于访问令牌直接暴露在浏览器端,所有隐式授权码方式可能会导致访问令牌被黑客获取

  • 仅适用于临时访问的场景

  • 例如QQ的OAuth对于移动端采用的就是隐式授权码模式

  • 与授权码模式相比,用户登录环节一致(客户端要求用户提供授权许可;用户登录后提供授权许可给客户端)

    • 在授权成功的重定向上,授权码模式携带一个认证码,由客户端(第三方应用的后端程序)通过认证码code申请访问令牌

    • 隐式授权模式中则是直接将访问令牌作为URL的散列部分传递给浏览器

  • 重定向中携带若干参数:

    • access_token

    • expire_in:令牌在多少秒后过期

    • state:客户端的状态参数

  • 客户端页面可使用JavaScript获取该散列值,最好可利用浏览器的cookie存储访问令牌

Spring Security学习之OAuth介绍_第4张图片

 

密码授权模式

客户端直接携带用户的密码向授权服务器申请令牌,不再像前两种授权模式一样跳转到授权服务器进行,而是由客户端提供专用页面。如果用户信任该客户端(通常为信誉度高的公司),用户可直接提供密码,客户端不存储用户密码的前提下完成令牌的申请

Spring Security学习之OAuth介绍_第5张图片

 

客户端授权模式

实际并不属于OAuth范畴,关注点不再是用户的私有信息或数据,而是一些由资源服务器持有但并非完全公开的数据,如微信的公众平台授权等

  • 通常由客户端提前向授权服务器申请应用公钥、私钥(秘钥),并通过这些关键信息向授权服务器申请访问令牌,从而得到资源服务器提供的资源

  • OAuth仅定义一个粗略的流程规范,具体实现细节由实际的授权服务器决定

Spring Security学习之OAuth介绍_第6张图片

 

实现GitHub快捷登录

1.创建oauth项目

// pom.xml


   4.0.0
   
      org.springframework.boot
      spring-boot-starter-parent
      2.3.3.RELEASE
       
   
   com.example
   oauthdemo
   0.0.1-SNAPSHOT
   oauthdemo
   Demo project for Spring Boot

   
      1.8
   

   
      
         org.springframework.boot
         spring-boot-starter-oauth2-client
      
      
         org.springframework.boot
         spring-boot-starter-security
      
      
         org.springframework.boot
         spring-boot-starter-web
      

      
         org.springframework.boot
         spring-boot-starter-test
         test
         
            
               org.junit.vintage
               junit-vintage-engine
            
         
      
      
         org.springframework.security
         spring-security-test
         test
      
   

   
      
         
            org.springframework.boot
            spring-boot-maven-plugin
         
      
   

2.注册GitHub应用 链接:https://github.com/settings/applications/new

Spring Security学习之OAuth介绍_第7张图片

3.注册完毕,获取clientId和clientSecret

Spring Security学习之OAuth介绍_第8张图片

当用户通过浏览器(用户代理)成功登录GitHub,并在批准页(Approva Page)授权允许注册的客户端应用访问自己的用户数据后,GitHub会将授权码code通过重定向的方式传递给客户端应用

Spring Security OAuth默认重定向模板为:{baseUrl}/login/oauth2/code/{registrationId}

(也可用户自定义,创建应用的时候写入自定义的重定向页面即可,重定向方法参数主要为code和state,方法中跟据code去获取access_token)

此处的registrationId为注册客户端服务器(ClientRegistration)的唯一ID,通常以接入的OAuth服务提供商的简称来命名,此处设置为github

4.配置项目配置文件applicaiton.yml/applicaiton.properites

spring.security.oauth2.client.regisration:OAuth客户端所有属性的基础前缀

registration下面的github是ClientRegistration的唯一ID

client-id:GitHub上注册得到的clientId

client-secret:GitHub上注册得到的clientSecret

 

5.新建Controller

Spring Security学习之OAuth介绍_第9张图片

6.启动项目

  • 浏览器访问http://localhost:8080/user/hello后,会重定向到默认生成的登录页

  • 点击GitHub按钮,即可跳转GitHub登录页;

  • 当认证成功后跳转到确认授权页面

  • 点击“Authorize andyzhaodaozhao”按钮,以允许OAuth客户端应用访问GitHub的用户数据,此处OAuth客户端应用会调用用户数据接口(the UseInfo Endpoint),创建认证对象

  • 浏览器最后将自动重定向到原访问地址,并打印字符串

https://github.com/login?client_id=a6e66dd2f170df82efe0&return_to=/login/oauth/authorize?client_id=a6e66dd2f170df82efe0&redirect_uri=http://localhost:8080/login/oauth?code=github&response_type=code&scope=read%253Auser&state=Zx0jGnr6rANlM2dFqdiIP21cq3o75gL2BvFX0cHx_bg%253D

Spring Security学习之OAuth介绍_第10张图片

如果本身GitHub处于登录状态,则如下:

Spring Security学习之OAuth介绍_第11张图片Spring Security学习之OAuth介绍_第12张图片

Spring Security学习之OAuth介绍_第13张图片

总结

不同的服务提供商提供的授权流程在细节上略微不同,主要体现在与授权服务器交互过程中的传参、返回值解析,以及从资源服务器获取资源等几个方面,核心步骤大体相同

  1. 获取code

  2. 使用code获取access_token

  3. 携带access_token请求被保护的用户信息和其他资源

你可能感兴趣的:(后端开发,Spring,Security学习,Java学习)