PHP下的Oauth2.0尝试 - OpenID Connect
OpenID Connect
OpenID Connect简介
OpenID Connect是基于OAuth 2.0规范族的可互操作的身份验证协议。它使用简单的REST / JSON消息流来实现,和之前任何一种身份认证协议相比,开发者可以轻松集成。
OpenID Connect允许开发者验证跨网站和应用的用户,而无需拥有和管理密码文件。OpenID Connect允许所有类型的客户,包括基于浏览器的JavaScript和本机移动应用程序,启动登录流动和接收可验证断言对登录用户的身份。
OpenID的历史是什么?
OpenID Connect是OpenID的第三代技术。首先是原始的OpenID,它不是商业应用,但让行业领导者思考什么是可能的。OpenID 2.0设计更为完善,提供良好的安全性保证。然而,其自身存在一些设计上的局限性,最致命的是其中依赖方必须是网页,但不能是本机应用程序;此外它还要依赖XML,这些都会导致一些应用问题。
OpenID Connect的目标是让更多的开发者使用,并扩大其使用范围。幸运的是,这个目标并不遥远,现在有很好的商业和开源库来帮助实现身份验证机制。
OIDC基础
简要而言,OIDC是一种安全机制,用于应用连接到身份认证服务器(Identity Service)获取用户信息,并将这些信息以安全可靠的方法返回给应用。
在最初,因为OpenID1/2经常和OAuth协议(一种授权协议)一起提及,所以二者经常被搞混。
OpenID是Authentication,即认证,对用户的身份进行认证,判断其身份是否有效,也就是让网站知道“你是你所声称的那个用户”;
OAuth是Authorization,即授权,在已知用户身份合法的情况下,经用户授权来允许某些操作,也就是让网站知道“你能被允许做那些事情”。
由此可知,授权要在认证之后进行,只有确定用户身份只有才能授权。
(身份验证)+ OAuth 2.0 = OpenID Connect
OpenID Connect是“认证”和“授权”的结合,因为其基于OAuth协议,所以OpenID-Connect协议中也包含了client_id、client_secret还有redirect_uri等字段标识。这些信息被保存在“身份认证服务器”,以确保特定的客户端收到的信息只来自于合法的应用平台。这样做是目的是为了防止client_id泄露而造成的恶意网站发起的OIDC流程。
在OAuth中,这些授权被称为scope。OpenID-Connect也有自己特殊的scope--openid ,它必须在第一次请求“身份鉴别服务器”(Identity Provider,简称IDP)时发送过去。
OpenID Connect 实现
我们的本代码实现建立在PHP下的Oauth2.0尝试 - 授权码授权(Authorization Code Grant) 文章的代码基础上调整
证书
# 生成私钥 private key
$ openssl genrsa -out privkey.pem 2048
# 私钥生成公钥 public key
$ openssl rsa -in privkey.pem -pubout -out pubkey.pem
调整server
private function server()
{
$pdo = new \PDO('mysql:host=ip;dbname=oauth_test', "user", "123456");
$storage = new \OAuth2\Storage\Pdo($pdo);
$config = [
'use_openid_connect' => true, //openid 必须设置
'issuer' => 'sxx.qkl.local'
];
$server = new \OAuth2\Server($storage, $config);
// 第二个参数,必须设置值为public_key
$server->addStorage($this->getKeyStorage(), 'public_key');
// 添加 Authorization Code 授予类型
$server->addGrantType(new \OAuth2\GrantType\AuthorizationCode($storage));
// 添加 Client Credentials 授予类型 一般三方应用都是直接通过client_id & client_secret直接请求获取access_token
$server->addGrantType(new \OAuth2\GrantType\ClientCredentials($storage));
return $server;
}
private function getKeyStorage()
{
$rootCache = dirname(APP_PATH) . "/cert/oauth/";
$publicKey = file_get_contents($rootCache.'pubkey.pem');
$privateKey = file_get_contents($rootCache.'privkey.pem');
// create storage
$keyStorage = new \OAuth2\Storage\Memory(array('keys' => array(
'public_key' => $publicKey,
'private_key' => $privateKey,
)));
return $keyStorage;
}
授权
public function authorize()
{
// scope增加openid
// 该页面请求地址类似:
// http://sxx.qkl.local/v2/oauth/authorize?response_type=code&client_id=testclient&state=xyz&redirect_uri=http://sxx.qkl.local/v2/oauth/cb&scope=basic%20get_user_info%20upload_pic%20openid
//获取server对象
$server = $this->server();
$request = \OAuth2\Request::createFromGlobals();
$response = new \OAuth2\Response();
// 验证 authorize request
// 这里会验证client_id,redirect_uri等参数和client是否有scope
if (!$server->validateAuthorizeRequest($request, $response)) {
$response->send();
die;
}
// 显示授权登录页面
if (empty($_POST)) {
//获取client类型的storage
//不过这里我们在server里设置了storage,其实都是一样的storage->pdo.mysql
$pdo = $server->getStorage('client');
//获取oauth_clients表的对应的client应用的数据
$clientInfo = $pdo->getClientDetails($request->query('client_id'));
$this->assign('clientInfo', $clientInfo);
$this->display('authorize');
die();
}
$is_authorized = true;
// 当然这部分常规是基于自己现有的帐号系统验证
if (!$uid = $this->checkLogin($request)) {
$is_authorized = false;
}
// 这里是授权获取code,并拼接Location地址返回相应
// Location的地址类似:http://sxx.qkl.local/v2/oauth/cb?code=69d78ea06b5ee41acbb9dfb90500823c8ac0241d&state=xyz
$server->handleAuthorizeRequest($request, $response, $is_authorized, $uid);
if ($is_authorized) {
// 这里会创建Location跳转,你可以直接获取相关的跳转url,用于debug
$parts = parse_url($response->getHttpHeader('Location'));
var_dump($parts);
parse_str($parts['query'], $query);
// 拉取oauth_authorization_codes记录的信息,包含id_token
$code = $server->getStorage('authorization_code')
->getAuthorizationCode($query['code']);
var_dump($code);
}
// $response->send();
}

curl获取
# 使用 HTTP Basic Authentication
$ curl -u testclient:123456 http://sxx.qkl.local/v2/oauth/token -d 'grant_type=client_credentials'
# 使用 POST Body 请求
$ curl http://sxx.qkl.local/v2/oauth/token -d 'grant_type=client_credentials&client_id=testclient&client_secret=123456'
postman获取access_token

总结
access_token 用于授权
id_token(通常为JWT) 用于认证
通常我们
首先,需要使用id_token登录
然后,你会得到一个access_token
最后,使用access_token来访问授权相关接口。
原文地址:https://segmentfault.com/a/1190000016539242
PHP下的Oauth2.0尝试 - OpenID Connect的更多相关文章
- 微服务系列之授权认证(一) OAuth 2.0 和 OpenID Connect
1.传统架构的授权认证 传统应用架构,用户使用账号密码登录后,可以使用前端cookie存储登录状态,也可以使用后端session方式存储登录状态,小应用这么做其实很高效实用,当应用需要横向扩展时,就需 ...
- 使用 IdentityServer4 实现 OAuth 2.0 与 OpenID Connect 服务
IdentityServer4 是 ASP.NET Core 的一个包含 OIDC 和 OAuth 2.0 协议的框架.最近的关注点在 ABP 上,默认 ABP 也集成 IdentityServer4 ...
- ASP.NET 中OAUTH 2.0 及OPENID CONNECT的介绍
了解以下内容对ASP.NET 5中的验证中间件应用有很大帮助! OAUTH2是目前很多大型网站都使用的对外提供开放资源接口的应用标准,比入taobao\alipay\腾讯\豆瓣等.它和目前的另 ...
- [翻译]在asp.net core2.0 OpenID Connect Handler中丢失了声明(CLaims)?
注:这是一篇翻译,来自这里.这篇文章讲述了在asp.net core2.0中使用openid connect handler的过程中解析不到你想要的claim时,你可以参考这篇文章. Missing ...
- Spring Cloud 微服务中搭建 OAuth2.0 认证授权服务
在使用 Spring Cloud 体系来构建微服务的过程中,用户请求是通过网关(ZUUL 或 Spring APIGateway)以 HTTP 协议来传输信息,API 网关将自己注册为 Eureka ...
- 投票:OAuth2.0 技术选型你会怎么选
1. 前言 在使用 OAuth2.0 中 Authorization Server (授权服务器)是一个回避不了的设施,在大多数情况下我们调用的是一些知名的.可靠的.可信任的第三方平台,比如 QQ.微 ...
- OpenID Connect:OAuth 2.0协议之上的简单身份层
OpenID Connect是什么?OpenID Connect(目前版本是1.0)是OAuth 2.0协议(可参考本人此篇:OAuth 2.0 / RCF6749 协议解读)之上的简单身份层,用 A ...
- OAuth2、OpenID Connect简介
当我们在登录一些网站的时候,需要第三方的登录.比如,现在我们要登录简书https://www.jianshu.com/sign_in,我们使用微博登录,点击下方的一个微博的小按钮,就会出现这么一个地址 ...
- 微信公众平台开发—利用OAuth2.0获取微信用户基本信息
在借鉴前两篇获取微信用户基本信息的基础下,本人也总结整理了一些个人笔记:如何通过OAuth2.0获取微信用户信息 1.首先在某微信平台下配置OAuth2.0授权回调页面: 2.通过appid构造url ...
随机推荐
- [BZOJ4916]神犇(Monster_Qi)和蒟蒻(SWHsz)
很久很久以前,有一只神犇叫Monster_Qi; 很久很久之后,有一只蒟蒻叫SWHsz; 1<=N<=1E9,A.B模1E9+7; 求这个. 求μ的话直接输出1就行了因为除了1的平方外都有 ...
- Mybaitis-generator生成数据对象和时间的优化
1.本章涉及到知识点,Mybaitis-generator生成数据对象和时间,xml的引用*.properties 外部文件(在这之前必须导入了mybaitis的核心架包) A.在pom.xml的案例 ...
- JSP中文乱码问题的由来以及解决方法
首先明确一点,在计算机中,只有二进制的数据! 一.java_web乱码问题的由来 1.字符集 1.1 ASCII字符集 在早期的计算机系统中,使用的字符非常少,这些字符包括26个英文字母.数字符号和一 ...
- BA--关于干节点和湿节点
干接点与湿接点知识 通俗定义:有干接点就有湿接点,是对于开关量而言的. 湿接点的定义是:有源开关:具有有电和无电的 2 种状态:2 个接点之间有极性,不能反 接: 常见湿接点 1.如果把以上的干接点信 ...
- 洛谷—— P1120 小木棍 [数据加强版]
https://www.luogu.org/problem/show?pid=1120 题目描述 乔治有一些同样长的小木棍,他把这些木棍随意砍成几段,直到每段的长都不超过50. 现在,他想把小木棍拼接 ...
- Maven错误-Missing artifact com.sun:tools:jar:1.5.0:system 解决方式
1.Missing artifact com.sun:tools:jar:1.5.0:system Could not resolve dependencies for project com.ifl ...
- Eclipse设置jdk相关
2.window->preferences->java->Compiler->设置右侧的Compiler compliance level 3.window->prefe ...
- [SharePoint2010开发入门经典]二、开始SPS2010开发
本章概要: 1.了解SPS2010开发要素(包括工具,平台服务,开发选项) 2.熟悉主要开发工具和部署方案 3.安装.配置.简单开发案例 4.理解网站级别的安全设置
- TT流程随笔
细节: 如果本地可以自动登录, 先实现本地登录,发送事件通知,再请求登录服务器 如果本地不可以登录(第一次或退出后),直接请求登录服务器 登录服务器返回消息服务器ip port / 文件服务器 链接消 ...
- Chrome插件开发新手教程
近期在用百词斩这个站点来学单词,感觉非常不错,就是在回想单词列表的时候仅仅有单词和意思.却没有读音.感觉非常不方便,思来思去,想到了Chrome插件能够胜任这个工作.于是小小的研究了一下. Chrom ...