几个重要平台的authsuccess2登录验证

OAuth2.0简介
OAuth: OAuth(开放授权)是一个开放标准,允许用户授权第三方移动应用访问他们存储在另外的服务提供者上的信息,而不需要将用户名和密码提供给第三方移动应用或分享他们数据的所有内容。
QQ登录OAuth2.0:对于用户相关的OpenAPI(例如获取用户信息,动态同步,照片,日志,分享等),为了保护用户数据的安全和隐私,第三方移动应用访问用户数据前都需要显式的向用户征求授权。
QQ登录OAuth2.0采用OAuth2.0标准协议来进行用户身份验证和获取用户授权,其认证流程简单、安全。
如果您想对OAuth2.0开放标准进行扩展阅读,请参看: |
QQ登录OAuth2.0支持。
移动应用可通过以下两种方式接入:
(1)使用QQ互联提供的SDK包,用户体验统一,只需要修改少量代码,不需要理解验证授权流程,需要快速接入QQ登录的移动应用可选用此方法。
(2)根据QQ登录OAuth2.0协议,自主开发,此方法自定义程度较高,需要与现有系统进行整合的移动应用可选用此方法。
QQ登录OAuth2.0总体处理流程如下:
Step1:接入申请,获取appid和apikey;
Step2:放置QQ登录按钮;
Step3:通过用户登录验证和授权,获取Access Token;
Step4:通过Access Token获取用户的OpenID;
Step5:调用OpenAPI,来请求访问或修改用户授权的资源。
开发者需要根据腾讯提供的UI规范,请求说明,接口说明进行UI和代码的开发。
详细信息请参见。您还可以使用以下方式登录
当前位置:&>&&>&&>& > 几个重要平台的auth2登录验证
几个重要平台的auth2登录验证
根据授权码取得access_token&参数是否必须含义grant_type必须授权类型,此值固定为&authorization_code&。client_id必须网站的appid。client_secret必须网站的appkey。code必须上一步返回的authorization code。注意此code会在10分钟内过期。redirect_uri必须与上面一步中传入的redirect_uri保持一致。成功取码:&access_token=FE04************************CCE2&expires_in=7776000&失败:返回code和msg字段,以url参数对的形式返回,value部分会进行url编码根据access_token获得对应用户身份的openid&参数是否必须含义access_token必须在Step1中获取到的access token。查询成功:[plain] &callback( {&client_id&:&YOUR_APPID&,&openid&:&YOUR_OPENID&} ); &&查询失败:&[plain] &通用错误码 &调用openid并访问资源access_token=&token&& oauth_consumer_key=&appkey&& opened=&user_openid&参数:&YOUR_APP_ID: appid(如222222)YOUR_ACCESS_TOKEN:Step1获取到的access token,必须保证未过期(如EAC709999)YOUR_OPENID:Step2获取到的openid,用户唯一标识(如B9DD537D1C5C98A9999)[plain] &https://graph.qq.com/user/get_user_info? (GET) &access_token=*************& oauth_consumer_key=12345& openid=****************& format=json &&&[plain] &{ && & &ret&:0, // 返回码 && & &msg&:&&, // 错误信息,red&0 && & &nickname&:&Peter&, //呢称 && & &figureurl&:&http://qzapp.qlogo.cn/qzapp/FEA70050EEAFBD4DCE2C1FC775E56/30&, //30x30 && & &figureurl_1&:&http://qzapp.qlogo.cn/qzapp/FEA70050EEAFBD4DCE2C1FC775E56/50&, //50x50 && & &figureurl_2&:&http://qzapp.qlogo.cn/qzapp/FEA70050EEAFBD4DCE2C1FC775E56/100&,//100x100 && & &gender&:&男&,//性别 && & &vip&:&1&, //黄钻用户 && & &level&:&7&,//黄钻等级 && & &is_yellow_year_vip&:&1&//年费黄钻用户 &} &&Weibo后台方式的登录验证&获得授权码&client_id必须stringAppKey。redirect_uri必须string授权回调地址&scope可选string申请scope权限所需参数,可一次申请多个scope权限,用逗号分隔。state可选string防止跨站请求伪造(CSRF)攻击,第三方自定义串display可选string授权页面的终端类型,取值见下面的说明。{default-&web page, &mobile , wap, client, apponweibo -&站内 }forcelogin可选boolean是否强制用户重新登录,true:是,false:否。默认false。language可选string授权页语言,缺省为中文简体版,en为英文版。成功:&&失败:&[plain] &{ &error&:&desc&, &&error_code&:123456, &error_description&:&desc& } &根据授权码获取access_token&&必选类型及范围说明client_idtruestring申请应用时分配的AppKey。client_secrettruestring申请应用时分配的AppSecret。grant_typetruestring请求的类型,填写authorization_codegrant_type为authorization_code时&必选类型及范围说明codetruestring调用authorize获得的code值。redirect_uritruestring回调地址,需需与注册应用里的回调地址一致。成功调用则返回:&[plain] &{&access_token&: &token.. &, &expires_in&: 1234, &remind_in&:&798114&, &uid&:&& } &不成功则:&[sql] &{ &&error&:&desc&, &&error_code&:123456, &error_description&:&desc& } &根据token查询用户的信息及资源&必选类型及范围说明access_tokentruestringaccess_token成功返回值:&[plain]&{ &uid&: , &&appkey&: , &scope&: null,&create_at&: , &expires_in&:
} &失败返回值:&[html] view plaincopy{ &error&:&desc&, &&error_code&:123456, &error_description&:&desc& } &豆瓣后台方式的登录验证&获取授权码&参数名称参数说明client_id必选APIKeyredirect_uri必选回调地址,此地址必须与在应用注册时填写的回调地址一致。response_type必选此值可以为 code 或者 token。scope可选申请权限的范围,缺省的scope。如果申请多个scope,使用逗号分隔。state可选第三方自定义参数。成功:&&不成功:&获取access_token&参数名称参数说明client_id必选APIKeyclient_secret必选对应于豆瓣secretredirect_uri必选回调地址grant_type必选此值可以为 authorization_code 或者 refresh_token 。code必选authorization_code成功:&[plain]&{ &access_token&:&&token&&, &expires_in&:3920, &refresh_token&:&&token2&&, &douban_user_id&:&&user-id&&} &失败: www.2cto.com[plain]&{&msg&:&uri_not_found&, &code&:1001, &request&:&GET \/v2\/photo\/132&} &获取当前用户信息https://api.douban.com/v2/user/~me (GET)重要注意事项:&&必须用GET方法l必须将token放在请求的header里,key = &Authorization&, value=&Bearer token&&的方式放入header.成功:&[plain]&{ &loc_id&:&118281&, &name&:&名称&, &created&:&&创建日期&&, &loc_name&:&地区&, &avatar&:&图标&, &signature&:&签名&, &uid&:&账号&, &alt&:&链接地址&, &id&:&&, &desc&:&&} &失败:&[plain] &{&msg&:&uri_not_found&, &code&:1001, &request&:&GET \/v2\/photo\/132&} &举例方式:&curl &https://api.douban.com/v2/user/~me& -H &Authorization: Bearer a14afef0f66fcffce3e0fcd2e34f6ff4&就爱阅读www.92to.com网友整理上传,为您提供最全的知识大全,期待您的分享,转载请注明出处。
欢迎转载:
推荐:    laravel 搭建oauth2认证服务,可用于app登录等验证 - 简书
laravel 搭建oauth2认证服务,可用于app登录等验证
oauth2是一种验证方式, 这里不加以解释,不明白的小伙伴可以看一看阮一峰的文章-
按github上的教程搭建oauth2认证
先进行composer安装然后配置,数据迁移。
选择一种验证方式
oauth2-server-laravel 支持Client Credentials Grant,password等四种验证方式,可按照教程在config/oauth2.php下配置,例如选择password granttype,就可按照操作。
登录验证(这里使用密码方式)
现在oauth_clients表中新建一条数据,然后每次登录验证时就发送参数client_id和client_secret; 在User.php修改验证的用户表
protected $table="ims_mc_members";
在routes.php新建以下路由
Route::post('oauth/access_token', function() {
return Response::json(Authorizer::issueAccessToken());
表单请求上面的路由,发送表单数据
grant_typ = "password"
client_id = "your_client_id"
client_secret = "your_client_secret"
username = "you_"
password = "your_password",
1.按照自己写的restapi格式发送表单,post或者get的话指定action就好,其他如delete,patch,put等就需要对应的在表单中加上一个隐藏的input如:
_method = 'delete'
2.默认用邮箱登录
以上就搭建完了,等等,如果我登录不用邮箱怎么办,如果我用了salt加密怎么办, 那往下看吧。
自定义验证规则
有时候可能不是用邮箱登录,或者验证方式与上面的不同,比如我的系统使用md5+salt验证,mobile和email都可登录,这时候就要修改默认验证方式了
修改app下PasswordGrantVerifier.php的verify.php方法
public function verify($username, $password)
//harry 修改验证 anasit
$credentials = [
'uniacid' =& $_REQUEST['uniacid'],
'password' =& $password,
if(strpos($username, '@')){
$credentials['email'] = $
$credentials['mobile'] = $
if (Auth::once($credentials)) {
return Auth::user()-&
因为之前会正则验证邮箱和手机号,所以就偷了个懒,用是否含有@来区分邮箱和手机号了。
这样就修改成mobile和email都可登录了
哎,上面的uniacid是什么鬼?
uniacid是因为在做微信开发,识别不同公众号,比如权限管理,管理员和用户都在一个user表中,一个人可以是管理员也可以是用户,他的账号密码可能相同,只是一个的role(角色)是user,一个是admin,这样你就可以在$credentials,加入一个键值对'role'=&'admin'或'role'=&'user'来做验证。
但是接下来还要修改验证方式,
验证方法在/vendor/laravel/frameword/src/Illuminate/Auth/EloquentUserProvider.php里面的validateCredentials方法可以自定义自己的验证逻辑md5,hash或者其他,我的修改为
public function validateCredentials(UserContract $user, array $credentials)
$plain = $credentials['password'];
$salt =$user-&getAuthSalt();
$upwd = md5($plain.$salt.config('app.authkey'));
return $user-&getAuthPassword() == $
getAuthPassword是获取用户表中的password,但是我还要salt验证,就需要新建一个getAuthSalt()方法取得用户表中的salt,需要在\vendor\laravel\framework\src\Illuminate\Auth\Authenticatable.php,\vendor\laravel\framework\src\Illuminate\Auth\GenericUser.php,\vendor\laravel\framework\src\Illuminate\Contracts\Auth\Authenticatable.php,是不是好多文件不好找,其实在vendor文件下搜索一下getAuthPassword就基本知道要修改哪些文件了,
修改好的是这样的
\vendor\laravel\framework\src\Illuminate\Auth\Authenticatable.php
public function getAuthSalt()
return $this-&
\vendor\laravel\framework\src\Illuminate\Auth\GenericUser.php
public function getAuthSalt()
return $this-&attributes['salt'];
\vendor\laravel\framework\src\Illuminate\Contracts\Auth\Authenticatable.php
public function getAuthPassword();
这样就万事大吉了,开心的写代码吧。
定义url获取access_token
在routers.php加入下面代码
Route::post('oauth/access_token', function() {
return Response::json(Authorizer::issueAccessToken());
给需要登录才能看到的资源(控制器)加入oauth2中间件
如routers.php加入下面代码, 访问购物车时需要access_token
Route::put('wechat/{uniacid}/anas_shop/cart', ['middleware' =& 'oauth', 'uses' =& 'Anas_shop\CartController@put']);
提交表单时需要加入
&input type="hidden" name="access_token" value="xxxxxxxxxxxx" &
获取当前access_token的用户id
使用Authorizer::getResourceOwnerId(); 方法即可获取,这里写成model供控制器调用
namespace A
//文件路径
use Illuminate\Support\Facades\A
use Illuminate\Database\Eloquent\M
use LucaDegasperi\OAuth2Server\Facades\A
class Functions extends Model {
protected static function memberinfo(){
$member_id = Authorizer::getResourceOwnerId(); 获取到的id
$member = DB::table('ims_mc_members')-&where('uid', $member_id)-&first();
更多oauth2的使用,去看文档吧
希望这篇文章能帮到你!
最近在和同学参与一个创业项目,用到了laravel,仔细研究了一下,发现laravel封装了很多开箱即用的方法,通过traits实现引入后,就可以使用这些方法,今天我们来分析一下 AuthenticatesAndRegistersUsers ThrottlesLogins ...
补充 Exception 部分改造方案的内容 补充 View 部分改造方案的内容 背景 项目包含若干子站点,不同站点功能各异,但共享底层数据及逻辑。为开发及运维效率期间,决定在一个 Laravel 应用内实现整套系统。 本文基于 L...
Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智能路由,微代理,控制总线)。分布式系统的协调导致了样板模式, 使用Spring Cloud开发人员可以快速地支持实现这些模式的服务和应用程序。他们将在任何分布式...
先说几句废话,调和气氛。事情的起由来自客户需求频繁变更,伟大的师傅决定横刀立马的改革使用新的框架(created by 师傅)。在他老人家为时半小时对其新框架代码目录简要的讲解后,我依然一脸懵逼(准确来讲,他可能最需要只是鄙人快速上手,照猫画虎,知道HOW就行了,迅速完成代...
简介 laravel 使实施认证的变得非常简单,事实上,它提供了非常全面的配置项以适应应用的业务。认证的配置文件存放在 config/auth.php 目录,这里的每个选项都提供了完善的注释文档,你可以从这里调整认证服务的行为。 在 laravel 中,认证服务的核心是由 ...
假期全心在家带娃。 烈日炎炎,两岁多的娃总趴在窗台用特别稚气的声音跟我说,妈妈,下去玩去吧! 楼下就是游泳池,浅蓝底,深蓝鱼纹,水波粼粼,特别清凉的感觉。还有游乐场,儿子最爱荡秋千。哥哥在家时,哥哥会带他玩得很嗨很嗨,哈哈大笑。其实两个男孩也没有别人说的那么不堪。哥哥比弟弟...
应我们湖大的杨老师的要求,他表达了对我的文章的喜爱,按他的原话是,夜读可催眠,我的,咸菜,粉丝团,终于迎来了第一位粉丝,但其实我是一名商人。 我有一篇两年前的社论,一直不敢拿出来,怕吃扳砖,因为我发现: 很多视频,都是对城管一边倒的喊打喊杀,我想说句公道话都不行,今天有了杨...
一个老领导躺在北京一家高级病房里,年轻漂亮的小护士服务周到,体贴入微。 这天,小护士端来了一碗汤圆,准备喂给老领导她小心翼翼的舀了一勺,送向领导口中,领导大张着嘴巴,正欲接纳,却见护士一个手抖,汤圆噗通落入老领导口中。 小护士大惊失色,生怕老领导发怒,但只见老领导面色凝重,...
早兩個周,蔡明亮定下要來廣州辦展覽的時候,書店的朋友盡責地當了內應,早早通報給我風聲。我的答復不置可否,去或不去大抵隨緣。臨近講座日,有朋友說想去,便打聽了是否還有位置。刷臉每次都是人情債,但即使座位爆滿還是成功拿到兩個媒體席位。於是,今晚趕完稿子,幾乎是踩點進場。OIDC–基于 OAuth2 的下一代身份认证授权协议
OIDC(OpenID Connect),下一代的身份认证授权协议;当前发布版本1.0;OIDC是基于OAuth2+OpenID整合的新的认证授权协议;OAuth2是一个授权(authorization)的开放协议, 在全世界得到广泛使用,但在实际使用中,OAuth2只解决了授权问题,没有实现认证部分,往往需要添加额外的API来实现认证;而OpenID呢,是一个认证(authentication )的协议,二者在实际使用过程中都有其局限性;综合二者,即是OIDC;通过OIDC,既能有OAUTH2的功能,也有OpenID的功能;恰到好处…OIDC将是替换(或升级)OAuth2,OpenID的不二选择..OIDC在OAuth2的access_token的基础上增加了身份认证信息;通过公钥私钥配合校验获取身份等其他信息——即idT一个使用JWT生成的idToken(base64):& & &eyJhbGciOiJSUzI1NiIsImtpZCI6IjM3MTc2NjA0OTExODEyNzkwNzgifQ.eyJpc3MiOiIxMTExIiwiYXVkIjoiMTExMSIsImF0X2hhc2giOiI4ZjgxYThjOS1jNWJiLTQwOWMtYjI0Ni1lMzEyZmUwYzM4NWMiLCJyZWdpc3RyYXRpb24iOiIxMjM0NTY3OCIsImV4cCI6MTQ2MzYyMjA4NiwianRpIjoiRnl5aGZOYnQtU0NLR2tpTWRGMVg2dyIsImlhdCI6MTQ2MzU3ODg4NiwibmJmIjoxNDYzNTc4ODI2LCJzdWIiOiJsc3otb2lkYyJ9.hDCcs8PISdwUPp6Eyd-9JCeeTJ2ZtscBeuPITIt43gMYbddiUBLC90uT9bxKe6e3awHels3asEMreFtlnlY09PwdCxXvhjYcEiXO_dnzqu-zQXESHzPEE6d1WsZUcbj6yxoxMh0laba24uu3CbqSRQbOrsYmh2_XA5Q5eP66iOajRUDhNXhmsWEL85jtL9_h0SyfRNPZ9C0mRu2x9YZTHT129O53ggqtjwQxrXLAbCd1dd35DyIztagqQWDpo3gFG7YseNEiQ6Mf2D6nIBU9llAqH4sTThq_ahME06qKENat_sxnmIJN2UHw7u0E08S-59oxtOY9winT78Qj5IfWJw在OIDC协议的实现中, 其底层是基于OAuth2. 一些常用的库如: JWT(), JWS; OAuth2的实现如: Spring Security OAuth,OLTU。更多信息可参考:&拥抱OIDC…
spring-oauth-server 的详细介绍:
spring-oauth-server 的下载地址:
转载请注明:文章转载自 开源中国社区
本文标题:OIDC–基于 OAuth2 的下一代身份认证授权协议
本文地址:
哈哈,是有单独的,不过那是基础
最好标准化
早已在实践中使用了泛义的工具是文明的基础,而确指的工具却是愚人的器物
规范定义了一个授权(delegation)协议,对于使用Web的应用程序和API在网络上传递授权决策非常有用。OAuth被用在各钟各样的应用程序中,包括提供用户认证的机制。这导致许多的开发者和API提供者得出一个OAuth本身是一个认证协议的错误结论,并将其错误的使用于此。让我们再次明确的指出:
OAuth2.0 不是认证协议。OAuth2.0 不是认证协议。OAuth2.0 不是认证协议。
混乱的根源来自于在认证协议的内部实际上使用了OAuth,开发人员看到OAuth组件并与OAuth流程进行交互,并假设通过简单地使用OAuth,他们就可以完成用户认证。这不仅不是事情的真相,而且对服务提供商,开发人员以及最终用户而言都是危险的事情。
本文旨在帮助潜在的身份提供者如何基于OAuth2构建用户身份认证。实际上,如果你说&我有OAuth2,并且我需要身份认证&,那么请继续阅读。
什么是认证(Authentication)?
在用户访问一个应用程序的上下文环境中认证会告诉应用程序当前用户是谁以及其是否存在。一个完整的认证协议可能还会告诉你一些关于此用户的相关属性,比如唯一标识符、电子邮件地址以及应用程序说&早安&时所需要的内容。认证是关于应用程序中存在的用户,而互联网规模的认证协议需要能够跨网络和安全边界来执行此操作。
然而,OAuth没有告诉应用程序上述任何信息。OAuth对用户没有任何说明,也没有说明如何证明他们的存在,即使他们就在那里。对于OAuth的Client而言,它请求一个token,得到一个token,并用这个token访问一些API。但它不知道是谁授权的应用程序,以及甚至还有一个用户在那里。实际上,OAuth的大部分问题在于Client和被访问的资源之间的连接上在用户不存在的情况下使用这种委托访问。这对于Client授权来说是好的,但是对于用户身份认证来说却非常糟糕,因为认证需要确定用户是否存在(以及他们是谁)。
另外一个的混淆的因素,一个OAuth的过程通常包含在一些认证的过程中:资源所有者在授权步骤中向授权服务器进行身份验证,客户端向令牌端点中的授权服务器进行身份验证,可能还有其他的。OAuth协议中的这些认证事件的存在不能够说明OAuth协议本身能够可靠地传送认证。(译注:我觉得可能作者想表达的是虽然OAuth是这些认证事件的消费者,但却不是生产者,所以不能因为使用了认证,就等同于OAuth可以直接提供认证。)
事实证明尽管如此,还有一些事情可以和OAuth一起使用,以便在授权和授权协议之上创建身份认证协议。几乎在所有的这些情况下,OAuth的核心功能都将保持不变,而发生的事件是用户将他们的身份委派给他们正在尝试登录的应用程序。然后,客户端应用程序成为身份API的消费者,从而找出先前授权给客户端的用户。以这种方式建立身份验证的一个主要好处是允许管理最终用户的同意,这在互联网规模的跨域身份联合中是非常重要的。另一个重要的好处是,用户可以同时将访问其他受保护的API委托给他们的身份,使应用程序开发人员和最终用户管理更简单。通过一个调用,应用程序可以找出用户是否登录,应该调用什么用户,下载照片进行打印,并将更新发布到其消息流。这种简单性是非常有吸引力的,但当这两件事情同时进行时,许多开发人员将这两个功能混为一谈。
认证(Authentication) VS 授权(Authorization) : 一个比喻
为了帮助弄清楚这件事情,可以通过一个比喻来思考这个问题:巧克力 VS 软糖。在一开始,这两件事情的本质是截然不同的:巧克力是一种原料,软糖就是糖果。巧克力可以用来做许多不同的事情,甚至可以自己使用。软糖可以由许多不同的东西制成,其中一种可能是巧克力,但是需要多种成分来制造软糖,甚至不会用到巧克力。因此,巧克力等于软糖是错误的,而巧克力等于巧克力软糖肯定是夸大其词的。
在这个比喻中,OAuth是巧克力。这是一个多功能的原料,对许多不同的东西是至关重要的,甚至可以自己使用。认证更像是软糖,至少有一些成分必须以正确的方式汇集在一起,使其成为可能,OAuth也许是这些成分之一(可能是主要原料),但可能也根本不需要参与其中。你需要一个配方来说明说明如何组合它们。
事实上,有一些众所周知的配方可以与特定的供应商进行合作,比如Facebook Connect、使用Twitter登录以及OpenID Connect(为Google的登录系统提供了支持)。这些配方每个都添加了一些项目到OAuth中以创建身份认证协议,比如通用的profile API。可以在没有OAuth的情况下构建身份验证协议吗?当然可以,就像有很多种非巧克力软糖一样。但是我们今天在这里谈论的是专门针对基于OAuth2的身份认证,以及可能出现什么问题,以及如何确保安全和美味。
使用OAuth进行认证的常见误区
即使使用OAuth来构建身份验证协议是非常有可能的,但是在身份提供者或者身份消费者方面,有许多事情可能会让这些人脱节。本文中描述的做法旨在通知身份提供商的潜在的常见风险,并向消费者通报在使用基于OAuth的身份认证系统时可避免的常见错误。
Access Token作为身份认证的证明
由于身份认证通常发生在颁发access token的之前, 因此使用access token作为身份认证的证明是非常诱人的。然而, 仅仅拥有一个access token并没有告诉Client任何东西。在OAuth 中, token被设计为对Client不透明(译注:上一篇中有介绍), 但在用户身份认证的上下文环境中, Client需要能够从token中派生一些信息。
此问题的根源在于Client不是OAuth access token的预期受众。相反, 它是该token的授权提出者, 而受众实际上是受保护的资源。受保护的资源通常不能够仅通过token的单独存在来判断用户是否存在, 因为 oauth 协议的性质和设计, 在客户端和受保护资源之间的连接上用户是不可用的。为了应对这一点, 需要有一个针对客户本身的假象,这可以通过定义一个双重目的(dual-purposing)的Client可以解析和理解的access token来完成。但是由于一般的OAuth没有为access token本身定义特定的格式货结构,因此诸如OpenId Connect的ID Token和Facebook Connect的Signed在响应中提供一个次要的标记,它将和access token一起发送给Client中。这可以使得Client对主要的access token保持不透明,就像常规的OAuth中的那样。
访问受保护的API作为身份认证的证明
由于access token可以用于获取一组用户属性,因此拥有一个有效的access token作为身份认证的证明也是很诱人的。在一些情况下,这种假设是成立的,因为在授权服务器商经过身份认证的用户上下文中,token是刚刚被创建的。但是在OAuth中,这并不是获取access token的唯一方法,Refresh Token和assertions()可以在用户不存在的情况下获取access token。而在某些情况下,用户无需身份验证即可获得access token(译注:比如)。
此外,在用户不存在后,access token通常还会存在很长时间。记住,OAuth是一个授权协议(delegation protocol),这对它的设计至关重要。这意味着,如果一个Client想要确保身份认证是有效的,那么简单的使用token获取用户属性是不够的,因为OAuth保护的是资源,获取用户属性的API(identity API)通常没有办法告诉你用户是否存在。
注入Access Token
另外一个额外的威胁(非常危险)是当Client接受来自token endpoint的token时。这可能会发生在使用implicit流程(这个流程中直接把acces token作为url的hash参数(译注:))中,并且Client不正确的使用state参数的时候。如果应用程序在不同的组件中传递 access token以&共享&访问权限的时候,也会发生此问题。这里的问题在于它开辟了一个注入access token到应用程序外部(并可能在应用程序外部泄露)的地方。如果Client不通过某种机制验证access token,则它无法区分access token是有效的令牌还是攻击的令牌。
可以通过使用Authorization code来缓解这一点,并且只能通过授权服务器的token API(token endpoint)并使用一个state的值来避免被攻击者猜中。
缺乏受众限制
另外一个问题是,通过access token获取一组用户属性的OAuth API通常没有为返回的信息的受众做任何限制。换句话话说,很可能有一个幼稚的(naive)Client,从其他的Client拿到一个有效的token来作为自己的登录事件。毕竟令牌是有效的,对API的访问也会返回有效的用户信息。问题在于没有用户做任何事情来证明用户存在,在这种情况下,用户甚至都没有授权给幼稚的(naive)Client。
通过将Client的认证信息与Client可以识别和验证的标识符一起传递给Client,可以缓解此问题,从而允许客户端区分自身的身份认证与另一应用程序的身份认证。通过在OAuth的过程中直接向Client传递一组身份认证信息,而不是通过受OAuth保护的API这样的辅助机制来缓解它,从而防止Client在稍后的过程中注入未知来源的不可信的信息。
注入无效的用户信息
如果攻击者能够拦截或者替换来自Client的一个调用,它可能会改变返回的用户信息,而客户端却无法感知这一情况。这将允许攻击者通过简单地在正确的调用序列中交换用户标识符来模拟一个幼稚的(naive)Client上的用户。通过在身份认证协议过程中(比如跟随OAuth的Token的颁发过程)直接从身份提供程序中获取身份认证信息,并通过可校验的签名保护身份认证信息,可以缓解这一点问题。
每个潜在的身份提供商的不同协议
基于OAuth 身份(identity)API的最大问题在于,即使使用完全符合OAuth的机制,不同的提供程序不可避免的会使用不同的方式实现身份(identity)API。比如,在一个提供程序中,用户标识符可能是用user_id字段来表示的,但在另外的提供程序中则是用subject字段来表示的。即使这些语义是等效的,也需要两份代码来处理。换句话说,虽然发生在每个提供程序中的授权是相同的,但是身份认证信息的传输可能是不同的。此问题可以在OAuth之上构建标准的身份认证协议来缓解,这样无论身份认证信息来自何处,都可以用通用的方式传输。
这个问题之所以出现,是因为此处讨论的身份认证的机制被明确的排除在OAuth的范围之内。OAuth定义了一个,定义了一个的access token,并且没有解决。
基于OAuth的用户认证的标准:OpenId Connect
OpenID Connect是2014年初发布的开放标准,定义了一种基于OAuth2的可互操作的方式来来提供用户身份认证。实际上,它是众所周知的巧克力软糖的配方,已经被多数的专家们尝试和测试了。应用程序不必为每个潜在的身份提供程序构建不同的协议,而是可以将一个协议提供给多个提供程序。由于OpenId Connect是一个开放标准,所以可以自由的没有任何限制的和知识产权问题的来实现。
OpenId Connect是直接建立在OAuth2之上的,在大多数情况下,部署在一个基于OAuth的基础设施之上。它还使用JOSN签名和加密规范,用来在传递携带签名和加密的信息。OpenId Connect避免了上面讨论的很多误区。
OpenID Connect Id Token是一个签名的JSON Web Token(JWT:RFC7519),它和OAuth access token一起提供给Client应用程序。Id Token包含一组关于身份认证会话的声明(claim),包括用户的标识(sub)、颁发令牌的提供程序的标识符(iss)、以及创建此标识的Client的标识符(aud)。此外,Id Token还包含token的有效生存期(通常非常短)以及其他相关的上下文信息。由于Client知道Id Token的格式,因此它能直接分析出token的内容而无需依赖外部服务。此外,OpenId Connect还颁发access token给Client,允许Client保持对token的不透明,因为这是属于OAuth规范的一部分。最后,token本身是由提供程序的私钥进行签名的,除了在获取token中受TLS的保护之外,还添加了一个额外的保护层,以防止类似的模拟攻击。通过对此token的一些校验检查,Client可以保护自己免受大量常见的攻击。
由于Id token是授权服务器签名的,它还提供了在authorization code(c_hash)和access token(at_hash)上添加分离签名的位置,这些hash可以由Client来验证,同时仍保留authorization code和access token对Client不透明的语义,从而防止这一类的注入攻击。
应该指出的是,Client不再需要使用access token,因为Id token已经包含了处理身份认证所需的所有信息。然而,为了保持和OAuth的兼容性,OpenId Connect会同时提供Id token和acces token。
除了Id token包含的信息之外,还定义了一个包含当前用户信息的标准的受保护的资源。如上所述,这些信息不是身份认证的一部分,而是提供附加的标识信息。比如说应用程序提示说&早上好:Jane Doe&,总比说&早上好:9XE3-JI34-00132A&要友好的多。它提供了一组标准化的属性:比如profile、email、phone和address。OpenId Connect定义了一个特殊的openid scope,可以通过access token来开启Id token的颁发以及对UserInfo Endpoint的访问。它可以和其他scope一起使用而不发生冲突。这允许OpenId Connect和OAuth平滑的共存。
动态服务发现以及客户端注册
OAuth2为了允许各种不同的部署而编写,但是这样的设计并没有指定这些部署如何设置以及组件之间如何互相了解,在OAuth自己的世界中这是没问题的。在使用OpenId Connect时,一个通用的受保护的API部署在各种各样的Client和提供者中,所有这些都需要彼此互相了解才能运行。对于每个Client来说,不可能事先了解有关每个提供程序,并且要求每个提供者了解每个潜在的Client,这将大大削弱扩展性。
为了抵消这种情况,OpenId Connect定义了一个发现协议,它允许Client轻松的获取有关如何和特定的身份认证提供者进行交互的信息。在另一方面,还定义了一个Client注册协议,允许Client引入新的身份提供程序(identity providers)。通过这两种机制和一个通用的身份API,OpenId Connect可以运行在互联网规模上运行良好,在那里没有任何一方事先知道对方的存在。
兼容OAuth2
即使拥有这些强大的身份认证功能,OpenId Connect(通过设计)仍然与纯粹的OAuth2兼容,使其可以在开发人员花费最小代价的情况下部署在在OAuth系统之上。实际上,如果服务已经使用了OAuth和规范(以及JWT),该服务以及可以很好的支持OpenId Connect了。
译注 & 原文
原文成文应该时比较早,一些信息已经过时了,我做了部分的删减,现在OpenId Connect已经成为了一个非常庞大的协议族了,有很多相关的辅助协议来完善认证授权的相关需求。OpenId Connect具体的信息参见这里:。本人翻译水平一般,如有错误之处,欢迎指正!
原作者: 。文章地址:
备注:原文标题是&User Authentication with OAuth 2.0&,觉得有点不妥,本来很多人对于Authentication和Authorization的认知就有一些混淆,而OAuth2是一个Authorization协议,而不是Authentication的协议,故而在翻译的时候调整了原文的名称。同时提了一个Pull Request(,不知道会不会被接受。
阅读(...) 评论()

我要回帖

更多关于 authcode 本地验证 的文章

 

随机推荐