OpenIDConnectOpenIDConnect简介OpenIDConnect是一种基于OAuth2.0规范系列的可互操作的身份验证协议。它使用简单的REST/JSON消息流实现,与之前的任何身份验证协议相比,开发人员可以轻松集成它。OpenIDConnect允许开发人员跨网站和应用程序对用户进行身份验证,而无需拥有和管理密码文件。OpenIDConnect允许所有类型的客户端(包括基于浏览器的JavaScript和本机移动应用程序)启动登录流程并接收有关登录用户身份的可验证断言。OpenID的历史是怎样的?OpenIDConnect是OpenID的第三代技术。首先是最初的OpenID,它不是商业应用,而是让行业领导者思考什么是可能的。OpenID2.0设计更加完善,提供了良好的安全保障。但是它在设计上有一定的局限性,最致命的是依赖方必须是网页,不能是原生应用程序;此外,它还依赖于XML,这会导致一些应用问题。OpenIDConnect的目标是让更多的开发者可以使用它,扩大它的使用范围。幸运的是,这个目标并不遥远,现在有很好的商业和开源库来帮助实现身份验证机制。OIDC基础简单来说,OIDC是一种安全机制,应用程序连接身份认证服务器(IdentityService)获取用户信息,并将这些信息以安全可靠的方式返回给应用程序。一开始,因为OpenID1/2经常和OAuth协议(一种授权协议)一起提到,所以经常把两者混淆。OpenID即Authentication,即认证。对用户身份进行认证,判断其身份是否有效,即让网站知道“您就是您所声称的用户”;OAuth是Authorization,即授权。在某些情况下,某些操作是用户授权允许的,即让网站知道“你被允许做那些事情”。由此可见,授权必须在认证之后进行,只有确认了用户的身份才能进行授权。(Authentication)+OAuth2.0=OpenIDConnectOpenIDConnect是“认证”和“授权”的组合。由于基于OAuth协议,OpenID-Connect协议还包括client_id、client_secret、redirect_uri等字段标识。这些信息存储在“身份认证服务器”中,以确保特定客户端接收到的信息只来自合法的应用平台。这样做是为了防止因client_id泄露导致恶意网站发起的OIDC进程。在OAuth中,这些授权称为范围。OpenID-Connect也有自己的特殊作用域——openid,它必须在第一次请求“IdentityProvider”(简称IDP)时发送。OpenIDConnect实现我们的代码实现了基于PHP的Oauth2.0尝试-授权码授予(AuthorizationCodeGrant)文章根据代码调整证书#生成私钥privatekey$opensslgenrsa-outprivkey.pem2048#privatekey生成公钥publickey$opensslrsa-inprivkey.pem-pubout-outpubkey.pemadjustserverprivatefunctionserver(){$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');//添加授权码授权类型$server->addGrantType(new\OAuth2\GrantType\AuthorizationCode($storage));//AddClientCredentialsgranttype一般三方应用直接通过client_id&client_secret请求access_token$server->addGrantType(new\OAuth2\GrantType\ClientCredentials($storage));返回$server;}私有函数getKeyStorage(){$rootCache=目录名(APP_PATH).“/cert/oauth/”;$publicKey=file_get_contents($rootCache.'pubkey.pem');$privateKey=file_get_contents($rootCache.'privkey.pem');//创建存储$keyStorage=new\OAuth2\Storage\Memory(array('keys'=>array('public_key'=>$publicKey,'private_key'=>$privateKey,)));return$keyStorage;}Authorizationpublicfunctionauthorize(){//添加openid到scope//这个页面的请求地址类似://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=$this->server();$request=\OAuth2\Request::createFromGlobals();$response=new\OAuth2\Response();//验证授权请求//这将验证参数,例如client_id、redirect_uri以及客户端是否具有作用域if(!$server->validateAuthorizeRequest($request,$response)){$响应->发送();死;}//显示授权登录页面if(empty($_POST)){//获取client类型的storage//但是这里我们设置的storage在server中,其实是一样的storage->pdo.mysql$pdo=$server->getStorage('客户端');//获取oauth_clients表中对应客户端应用的数据$clientInfo=$pdo->getClientDetails($request->query('client_id'));$this->assign('clientInfo',$clientInfo);$this->display('授权');死();}$is_authorized=true;//当然这部分套路是根据你已有的Account系统验证的if(!$uid=$this->checkLogin($request)){$is_authorized=false;}//这里是获取code的授权,拼接Location地址返回对应的//Location地址类似:http://sxx.qkl.local/v2/oauth/cb?code=69d78ea06b5ee41acbb9dfb90500823c8ac0241d&state=xyz$服务器->handleAuthorizeRequest($request,$response,$is_authorized,$uid);if($is_authorized){//这里会创建一个Location跳转,可以直接获取相关跳转url进行debug$parts=parse_url($response->getHttpHeader('Location'));变量转储($部分);parse_str($parts['query'],$query);//拉取oauth_authorization_codes中记录的信息,包括id_token$code=$server->getStorage('authorization_code')->getAuthorizationCode($query['code']);变量转储($代码);}//$response->send();}curlget#使用HTTP基本认证$curl-utestclient:123456http://sxx.qkl.local/v2/oauth/token-d'grant_type=client_credentials'#使用POSTBodyrequest$curlhttp://sxx.qkl.local/v2/oauth/token-d'grant_type=client_credentials&client_id=testclient&client_secret=123456'postmangetaccess_tokensummaryaccess_token用于授权id_token(一般为JWT)进行认证通常我们首先需要使用id_token登录后会得到一个access_token最后使用access_token访问授权相关接口
