OAuth2.0简单介绍

概念说明

       先说OAuth,OAuth是Open Authorization的简写。 OAuth协议为用户资源的授权提供了一个安全的、开放而又简易的标准。与以往的授权方式不同之处是 OAuth的授权不会使第三方触及到用户的帐号信息(如用户名与密码),即第三方无需使用用户的用户名与 密码就可以申请获得该用户资源的授权,因此OAuth是安全的。 OAuth2.0是OAuth协议的延续版本,但不向前兼容(即完全废止了OAuth1.0)。

使用场景

       假设,A网站是一个打印照片的网站,B网站是一个存储照片的网站,二者原本毫无关联。 如果一个用户想使用A网站打印自己存储在B网站的照片,那么A网站就需要使用B网站的照片资源才行。 按照传统的思考模式,我们需要A网站具有登录B网站的用户名和密码才行,但是,现在有了OAuth2,只需要A网 站获取到使用B网站照片资源的一个通行令牌即可!这个令牌无需具备操作B网站所有资源的权限,也无需永久有 效,只要满足A网站打印照片需求即可。 这么听来,是不是有点像单点登录?NONONO!千万不要混淆概念!单点登录是用户一次登录,自己可以操作其 他关联的服务资源。OAuth2则是用户给一个系统授权,可以直接操作其他系统资源的一种方式。 但SpringSecurity的OAuth2也是可以实现单点登录的! 总结一句:SpringSecurity的OAuth2可以做服务之间资源共享,也可以实现单点登录!

OAuth2.0中四种授权方式

为了说明四种模式先准备一张图

授权码模式(authorization code)

流程

说明:【A服务客户端】需要用到【B服务资源服务】中的资源

第一步:【A服务客户端】将用户自动导航到【B服务认证服务】,这一步用户需要提供一个回调地址,以备 【B服务认证服务】返回授权码使用。

第二步:用户点击授权按钮表示让【A服务客户端】使用【B服务资源服务】,这一步需要用户登录B服务,也 就是说用户要事先具有B服务的使用权限。

第三步:【B服务认证服务】生成授权码,授权码将通过第一步提供的回调地址,返回给【A服务客户端】。 注意这个授权码并非通行【B服务资源服务】的通行凭证。

第四步:【A服务认证服务】携带上一步得到的授权码向【B服务认证服务】发送请求,获取通行凭证token。

第五步:【B服务认证服务】给【A服务认证服务】返回令牌token和更新令牌refresh token。

使用场景

授权码模式是OAuth2中最安全最完善的一种模式,应用场景最广泛,可以实现服务之间的调用,常见的微 信,QQ等第三方登录也可采用这种方式实现。

简化模式(implicit)

流程

说明:简化模式中没有【A服务认证服务】这一部分,全部有【A服务客户端】与B服务交互,整个过程不再有 授权码,token直接暴露在浏览器。

第一步:【A服务客户端】将用户自动导航到【B服务认证服务】,这一步用户需要提供一个回调地址,以备 【B服务认证服务】返回token使用,还会携带一个【A服务客户端】的状态标识state。

第二步:用户点击授权按钮表示让【A服务客户端】使用【B服务资源服务】,这一步需要用户登录B服务,也 就是说用户要事先具有B服务的使用权限。

第三步:【B服务认证服务】生成通行令牌token,token将通过第一步提供的回调地址,返回给【A服务客户 端】。

使用场景

适用于A服务没有服务器的情况。比如:纯手机小程序,JavaScript语言实现的网页插件等。

密码模式(resource owner password credentials)

流程

第一步:直接告诉【A服务客户端】自己的【B服务认证服务】的用户名和密码

第二步:【A服务客户端】携带【B服务认证服务】的用户名和密码向【B服务认证服务】发起请求获取 token。

第三步:【B服务认证服务】给【A服务客户端】颁发token。

使用场景

此种模式虽然简单,但是用户将B服务的用户名和密码暴露给了A服务,需要两个服务信任度非常高才能使 用。

客户端模式(client credentials)

流程

说明:这种模式其实已经不太属于OAuth2的范畴了。A服务完全脱离用户,以自己的身份去向B服务索取 token。换言之,用户无需具备B服务的使用权也可以。完全是A服务与B服务内部的交互,与用户无关了。

第一步:A服务向B服务索取token。

第二步:B服务返回token给A服务。

使用场景

A服务本身需要B服务资源,与用户无关。

OAuth2.0中表结构说明

说明

如果只是写个测试案例,完全可以不用连接数据库,直接将用户等信息写在项目中就行。

但是,我们应该把眼光放在企业开发中。试想,我们自己做的一个软件,想使用微信第三方登录。难道你还指望微 信去修改他们的代码,让我们去访问?想都别想!

那么微信会怎么做呢?微信会提供好一个接入的入口,让我们自己去申请访问权限。这些数据自然而然需要保存在 数据库中!

所以,我们将直接讲解数据库版实现方式!

建表语句

官方SQL地址:

https://github.com/spring-projects/spring-security-oauth/blob/master/spring-securityoauth2/src/test/resources/schema.sql

表字段说明

oauth_client_details【核心表】

字段名字段说明
access_token_validity设定客户端的access_token的有效时间值(单位:秒),可选, 若不设定值则使用默认的有效时间 值(60 * 60 * 12, 12小时). 在服务端获取的access_token JSON数据中的expires_in字段的值 即为当前access_token的有效时间值. 在项目中, 可具体参考DefaultTokenServices.java中属 性accessTokenValiditySeconds. 在实际应用中, 该值一般是由服务端处理的, 不需要客户端 自定义.refresh_token_validity 设定客户端的refresh_token的有效时间值(单位:秒),可选, 若不设定值则使用默认的有效时间值(60 * 60 * 24 * 30, 30天). 若客户端的grant_type不包 括refresh_token,则不用关心该字段 在项目中, 可具体参考DefaultTokenServices.java中属 性refreshTokenValiditySeconds. 在实际应用中, 该值一般是由服务端处理的, 不需要客户端 自定义.
additional_information这是一个预留的字段,在Oauth的流程中没有实际的使用,可选,但若设置值,必须是JSON格式的 数据,如:{“country”:“CN”,“country_code”:“086”}按照spring-security-oauth项目中对该字段 的描述 Additional information for this client, not need by the vanilla OAuth protocol but might be useful, for example,for storing descriptive information. (详见 ClientDetails.java的getAdditionalInformation()方法的注释)在实际应用中, 可以用该字段来 存储关于客户端的一些其他信息,如客户端的国家,地区,注册时的IP地址等等.create_time 数据的创建时间,精确到秒,由数据库在插入数据时取当前系统时间自动生成(扩展字段)
archived用于标识客户端是否已存档(即实现逻辑删除),默认值为’0’(即未存档). 对该字段的具体使用请 参考CustomJdbcClientDetailsService.java,在该类中,扩展了在查询client_details的SQL加上 archived = 0条件 (扩展字段)
trusted设置客户端是否为受信任的,默认为’0’(即不受信任的,1为受信任的). 该字段只适用于 grant_type="authorization_code"的情况,当用户登录成功后,若该值为0,则会跳转到让用户 Approve的页面让用户同意授权, 若该字段为1,则在登录后不需要再让用户Approve同意授权 (因为是受信任的). 对该字段的具体使用请参考OauthUserApprovalHandler.java. (扩展字 段)
autoapprove设置用户是否自动Approval操作, 默认值为 ‘false’, 可选值包括 ‘true’,‘false’, ‘read’,‘write’. 该 字段只适用于grant_type="authorization_code"的情况,当用户登录成功后,若该值为’true’或 支持的scope值,则会跳过用户Approve的页面, 直接授权. 该字段与 trusted 有类似的功能, 是 spring-security-oauth2 的 2.0 版本后添加的新属性. 在项目中,主要操作 oauth_client_details表的类是JdbcClientDetailsService.java, 更多的细节请参考该类. 也可 以根据实际的需要,去扩展或修改该类的实现.

 

oauth_client_token

字段名字段说明
create_time数据的创建时间,精确到秒,由数据库在插入数据时取当前系统时间自动生成(扩展字段)
token_id从服务器端获取到的access_token的值.
token这是一个二进制的字段, 存储的数据是OAuth2AccessToken.java对象序列化后的二进 制数据.
authentication_id该字段具有唯一性, 是根据当前的username(如果有),client_id与scope通过MD5加密 生成的. 具体实现请参考DefaultClientKeyGenerator.java类.
user_name登录时的用户名
client_id 

oauth_access_token

字段名字段说明
create_time数据的创建时间,精确到秒,由数据库在插入数据时取当前系统时间自动生成(扩展字段)
token_id该字段的值是将access_token的值通过MD5加密后存储的.
token存储将OAuth2AccessToken.java对象序列化后的二进制数据, 是真实的AccessToken 的数据值.
authentication_id该字段具有唯一性, 其值是根据当前的username(如果有),client_id与scope通过MD5 加密生成的.具体实现请参考DefaultAuthenticationKeyGenerator.java类.
user_name登录时的用户名, 若客户端没有用户名(如grant_type=“client_credentials”),则该值等于client_id
refresh_token该字段的值是将refresh_token的值通过MD5加密后存储的. 在项目中,主要操作 oauth_access_token表的对象是JdbcTokenStore.java. 更多的细节请参考该类.
client_id 
authentication存储将OAuth2Authentication.java对象序列化后的二进制数据.

 

oauth_refresh_token

字段名字段说明
create_time数据的创建时间,精确到秒,由数据库在插入数据时取当前系统时间自动生成(扩展字段)
token_id该字段的值是将refresh_token的值通过MD5加密后存储的.
token存储将OAuth2RefreshToken.java对象序列化后的二进制数据.
authentication存储将OAuth2Authentication.java对象序列化后的二进制数据.

 

oauth_code

 

字段名字段说明
create_time数据的创建时间,精确到秒,由数据库在插入数据时取当前系统时间自动生成(扩展字段)
code存储服务端系统生成的code的值(未加密).
authentication存储将AuthorizationRequestHolder.java对象序列化后的二进制数据.

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值