资讯专栏INFORMATION COLUMN

PHP下的Oauth2.0尝试 - OpenID Connect

saucxs / 3490人阅读

摘要:基础简要而言是一种安全机制用于应用连接到身份认证服务器获取用户信息并将这些信息以安全可靠的方法返回给应用。这些信息被保存在身份认证服务器以确保特定的客户端收到的信息只来自于合法的应用平台。

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 OAuth2StoragePdo($pdo);

    $config = [
        "use_openid_connect" => true, //openid 必须设置
        "issuer" => "sxx.qkl.local"
    ];

    $server = new OAuth2Server($storage, $config);

    // 第二个参数,必须设置值为public_key
    $server->addStorage($this->getKeyStorage(), "public_key");

    // 添加 Authorization Code 授予类型
    $server->addGrantType(new OAuth2GrantTypeAuthorizationCode($storage));

    // 添加 Client Credentials 授予类型  一般三方应用都是直接通过client_id & client_secret直接请求获取access_token
    $server->addGrantType(new OAuth2GrantTypeClientCredentials($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 OAuth2StorageMemory(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 = OAuth2Request::createFromGlobals();
    $response = new OAuth2Response();

    // 验证 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://www.ucloud.cn/yun/29447.html

相关文章

  • 微信公众平台OAuth2.0 认证

    摘要:若用户禁止授权,则重定向后不会带上参数,仅会带上参数点击修改第二步封装拉取用户信息类公共账号公众账号接收参数第一步根据获取第二步根据获取的和存放认证的第三步拉取信息返回数据格式郑州河南中国带有用户信息数组微信认证类下载认证下载 第一步:引导用户打开如下链接 (详细介绍见OAuth2.0) $url = urlencode(http://xxx.com/xxx); $newurl = ...

    iflove 评论0 收藏0
  • Django增加QQ第三方登录

    摘要:在授权页面里面,登录并确认授权。从腾讯提供的按钮下载放到你的登录页面即可。腾讯不给得到真实号可能是出于保护隐私的考虑。再回头编辑,添加回调地址的处理方法逆向解析第三方登录,回调函数登录之后,会跳转到这里。 准备工作_OAuth2.0 接入QQ登录前,网站需首先进行申请,获得对应的appid与appkey,以保证后续流程中可正确对网站与用户进行验证与授权。showImg(https://...

    Heier 评论0 收藏0
  • 微信授权和sdk加密算法

    摘要:准备工作申请服务器公众号基本配置这些微信公众平台上都有,就不介绍了,接下来进入正题。随着微信管控越发严厉,像一些最基本的网页转发都需要授权处理才能获取到图片和描述,描述审查也是相当严格。 准备工作: 申请服务器 公众号 基本配置 这些微信公众平台上都有,就不介绍了,接下来进入正题。 ➣ 微信网页授权 node js-sdk 授权公众平台的技术文档目的为了简明扼要的交代接口的使用,语句难...

    gaara 评论0 收藏0
  • PHP下的Oauth2.0尝试 - 授权码授权(Authorization Code Grant)

    摘要:不太熟悉什么是的同学可以参考阮大神的文章,理解阮一峰授权码模式授权代码授予类型用于获得访问权限令牌和刷新令牌,并为机密客户进行了优化。 OAuth 2.0 不太熟悉什么是OAuth2.0的同学可以参考阮大神的文章, 理解OAuth 2.0 - 阮一峰 授权码模式(Authorization Code) # 授权代码授予类型用于获得访问权限令牌和刷新令牌,并为机密客户进行了优化。 # 由...

    zilu 评论0 收藏0
  • 关于网站微博和QQ第三方的登陆

    摘要:近几日由于公司业务需要,要做一个网站的第三方登陆,并且登陆之后并进行验证,只有登陆过我们手机的第三方账号才可以登陆网站。只能百度,发现腾讯对于网站登陆和手机登陆拿到的是不一样的,如果要想一样得写申请信给,简直就是蛋疼。 近几日由于公司业务需要,要做一个网站的第三方登陆,并且登陆之后并进行验证,只有登陆过我们手机app的第三方账号才可以登陆网站。 这边先说下oauth2.0大概的流程吧...

    mist14 评论0 收藏0

发表评论

0条评论

saucxs

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<