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

原文地址:https://www.cnblogs.com/lalalagq/p/9969846.html

时间: 2024-11-02 00:55:13

PHP下的Oauth2.0尝试 - OpenID Connect的相关文章

ASP.NET 中OAUTH 2.0 及OPENID CONNECT的介绍

    了解以下内容对ASP.NET 5中的验证中间件应用有很大帮助! OAUTH2是目前很多大型网站都使用的对外提供开放资源接口的应用标准,比入taobao\alipay\腾讯\豆瓣等.它和目前的另外一种OPENID标准是不同的两个概念,OPENID是提供用户验证的,而OAUTH是提供授权的,是OPENID的一个升级版本,由两个机构负责维护的.OPENID的最新标准OpenID Connect[(Identity, Authentication) + OAuth 2.0 = OpenID Co

投票:OAuth2.0 技术选型你会怎么选

1. 前言 在使用 OAuth2.0 中 Authorization Server (授权服务器)是一个回避不了的设施,在大多数情况下我们调用的是一些知名的.可靠的.可信任的第三方平台,比如 QQ.微信.微博.github 等.我们的应用只作为 Client 进行注册接入即可.也就是说我们只需要实现 OAuth2.0 客户端的逻辑就可以了,无须关心授权服务器的实现.然而有时候我们依然希望构建自己的 Authorization Server.我们应该如何实现?今天不会讨论具体的技术细节,来谈谈 O

OAuth2、OpenID Connect、IdentityServer建立Authorization Server简介

当我们在登录一些网站的时候,需要第三方的登录.比如,现在我们要登录简书https://www.jianshu.com/sign_in,我们使用微博登录,点击下方的一个微博的小按钮,就会出现这么一个地址https://api.weibo.com/oauth2/authorize?client_id=1881139527&redirect_uri=http%3A%2F%2Fwww.jianshu.com%2Fusers%2Fauth%2Fweibo%2Fcallback&response_ty

微信公众平台开发—利用OAuth2.0获取微信用户基本信息

1.首先在某微信平台下配置OAuth2.0授权回调页面: 2.通过appid构造url获取微信回传code值(appid可在微信平台下找到) 1).微信不弹出授权页面url: A.code回传到页面wxProcess2.aspx,不带参数 [csharp] view plain copy Response.Redirect("https://open.weixin.qq.com/connect/oauth2/authorize?appid=" + appid + "&

使用微服务架构思想,设计部署OAuth2.0授权认证框架

1,授权认证与微服务架构 1.1,由不同团队合作引发的授权认证问题 去年的时候,公司开发一款新产品,但人手不够,将B/S系统的Web开发外包,外包团队使用Vue.js框架,调用我们的WebAPI,但是这些WebAPI并不在一台服务器上,甚至可能是第三方提供的WebAPI.同时处于系统安全的架构设计,后端WebAPI是不能直接暴露在外面的:另一方面,我们这个新产品还有一个C/S系统,C端登录的时候,要求统一到B/S端登录,可以从C端无障碍的访问任意B/S端的页面,也可以调用B/S系统的一些API,

OpenID Connect常见问题

什么是OpenID Connect?它是如何工作的? OpenID Connect是一种基于OAuth 2.0系列规范的可互操作的身份验证协议.它使用简单的REST / JSON消息流,其设计目标是“使简单的事情变得简单和复杂”.与任何先前的身份协议相比,开发人员可以非常轻松地进行集成. OpenID Connect允许开发人员跨网站和应用程序对用户进行身份验证,而无需拥有和管理密码文件.对于应用程序构建器,它提供了一个安全可验证的问题答案:“当前使用浏览器或连接到我的本机应用程序的人的身份是什

一个功能完备的.NET开源OpenID Connect/OAuth 2.0框架——IdentityServer3

今天推荐的是我一直以来都在关注的一个开源的OpenID Connect/OAuth 2.0服务框架--IdentityServer3.其支持完整的OpenID Connect/OAuth 2.0标准,使用它就可以轻易地搭建一个单点登录服务器. 说是一直关注,是因为1年前,要为一个平台搭建一个OAuth 2.0服务器,当时由于IdentityServer3还处于开发阶段,核心还不稳定,扩展功能也不完备.无奈只好熟读OAuth 2.0的规范,并根据www.asp.net网站上的一个简单示例自己实现了

OpenID Connect Core 1.0(四)使用授权码流验证(上)

3.1 使用授权码流验证(Authentication using the Authorization Code Flow) 本节描述如何使用授权码流执行验证.当使用授权码流时,会从令牌终结点返回的所有令牌. 授权码流返回授权码给客户端,这个授权码可以直接交换一个ID Token和一个Access Token.这给User Agent提供了不暴露任何令牌的好处,因为可能还有其他恶意的应用程序访问User Agent.授权服务器也可以在验证客户端之前通过Access Token交换的授权码.授权码

OpenID Connect Core 1.0(九)声明(Claims)

5 声明(Claims) 这一节说明客户端如何获取关于终端用户声明和验证事件.它还定义了一组标准的基本声明配置.预定义一组可请求的声明,使用特定的scope值或能用于请求参数中的个人声明.声明可以直接来自OpenID提供者或分布式来源. 5.1 标准声明(Standard Claims) 这个规范定义了一组标准的声明.他们可以请求的返回或用户信息的响应,此在 5.3.2节或在第二节中的ID Token. sub string 在发行人终端用户的主体标识符. name  string 终端用户的全