ekapusta / oauth2-esia
允许在ESIA中进行身份验证并获取认证的个人个人信息。
Requires
- php: ^5.6 || ^7.0
- lcobucci/jwt: ^3.2.2
- league/oauth2-client: ^2.4.1
- psr/log: ^1.0
- ramsey/uuid: ^3.0 || ^4.0
Requires (Dev)
- bramus/monolog-colored-line-formatter: ^2.0
- monolog/monolog: ^1.24
- phpunit/phpunit: ^6
- satooshi/php-coveralls: ^1.0
README
允许在ESIA中进行身份验证并获取认证的个人个人信息。
作为PHP League的OAuth 2.0 Client的适配器实现。
安装
要安装,请使用composer
composer require ekapusta/oauth2-esia
用法
用法与正常客户端相同,使用Ekapusta\OAuth2Esia\Provider\EsiaProvider
作为提供者
配置提供者
use Ekapusta\OAuth2Esia\Provider\EsiaProvider; use Ekapusta\OAuth2Esia\Security\JWTSigner\OpenSslCliJwtSigner; use Ekapusta\OAuth2Esia\Security\Signer\OpensslPkcs7; $provider = new EsiaProvider([ 'clientId' => 'XXXXXX', 'redirectUri' => 'https://your-system.domain/auth/finish/', 'defaultScopes' => ['openid', 'fullname', '...'], // For work with test portal version // 'remoteUrl' => 'https://esia-portal1.test.gosuslugi.ru', // 'remotePublicKey' => EsiaProvider::RESOURCES.'esia.test.public.key', // For work with GOST3410_2012_256 signatures (instead of default RS256) // 'remoteCertificatePath' => EsiaProvider::RESOURCES.'esia.gost.prod.public.key', ], [ 'signer' => new OpensslPkcs7('/path/to/public/certificate.cer', '/path/to/private.key'), // For work with GOST3410_2012_256 signatures (instead of default RS256) // 'remoteSigner' => new OpenSslCliJwtSigner('/path/to/openssl'), ]);
使用哪个签名者?
- 如果您使用RSA密钥,则
OpensslPkcs7
就足够了。 - 如果您使用GOST密钥并且编译了带有GOST密码的PHP,则
OpensslPkcs7
就足够了。 - 如果您使用GOST密钥并且拥有openssl兼容的工具,则使用
OpensslCli
。它有toolpath
参数。 - 如果您使用GOST密钥并且是docker-addict,则可以使用
'toolpath' => 'docker run --rm -i -v $(pwd):$(pwd) -w $(pwd) rnix/openssl-gost openssl'
。
使用哪个远程签名者?
- 如果您的系统电子签名算法是默认的RS256,则无需操作。底层使用Sha256远程签名者。
- 如果您使用GOST3410_2012_256签名,则使用
OpenSslCliJwtSigner
,并将其传递到openssl
工具的路径。对于docker,传递类似于docker run --rm -i -v $(pwd):$(pwd) -v /tmp/tmp -w $(pwd) rnix/openssl-gost openssl'
的内容。/tmp
卷在那里非常重要!
认证流程
认证流程是标准的。
// https://your-system.domain/auth/start/ $authUrl = $provider->getAuthorizationUrl(); $_SESSION['oauth2.esia.state'] = $provider->getState(); header('Location: '.$authUrl); exit; // https://your-system.domain/auth/finish/?state=...&code=... if ($_SESSION['oauth2.esia.state'] !== $_GET['state']) { exit('The guard unravels the crossword.'); } $accessToken = $provider->getAccessToken('authorization_code', ['code' => $_GET['code']]); $esiaPersonData = $provider->getResourceOwner($accessToken); var_export($esiaPersonData->toArray());
简化外观
如果您不喜欢有大约20个公共方法的类,则存在简化外观类。
use Ekapusta\OAuth2Esia\EsiaService; $service = new EsiaService($provider); // https://your-system.domain/auth/start/ $_SESSION['oauth2.esia.state'] = $service->generateState(); $authUrl = $service->getAuthorizationUrl($_SESSION['oauth2.esia.state']); header('Location: '.$authUrl); exit; // https://your-system.domain/auth/finish/?state=...&code=... $esiaPersonData = $service->getResourceOwner($_SESSION['oauth2.esia.state'], $_GET['state'], $_GET['code']) var_export($esiaPersonData->toArray());
示例 $esiaPersonData
{ "resourceOwnerId": 1000404446, "stateFacts": [ "EntityRoot" ], "firstName": "Имя006", "lastName": "Фамилия006", "middleName": "Отчество006", "birthDate": "26.05.2000", "birthPlace": "Москва", "gender": "F", "trusted": true, "citizenship": "RUS", "snils": "000-000-600 06", "inn": "585204118212", "updatedOn": 1523386683, "contacts": { "stateFacts": [ "hasSize" ], "size": 3, "eTag": "5F535ACCAEB3018D0AAA8C46027E3CF2C4BD0197", "elements": [ { "stateFacts": [ "Identifiable" ], "id": 14216773, "type": "EML", "vrfStu": "VERIFIED", "value": "EsiaTest006@yandex.ru", "verifyingValue": "EsiaTest006@yandex.ru", "vrfValStu": "VERIFYING", "isCfmCodeExpired": true, "eTag": "17DCA3945F1B8B54496F59EB146BDC7DADAD7BC8" }, { "stateFacts": [ "Identifiable" ], "id": 14249750, "type": "PHN", "vrfStu": "NOT_VERIFIED", "value": "+7(840)0000006", "eTag": "943C1145E4973324599CD0E4FF136186502C93C5" }, { "stateFacts": [ "Identifiable" ], "id": 14244504, "type": "MBT", "vrfStu": "VERIFIED", "value": "+7(000)0000006", "verifyingValue": "+7(111)1111111", "vrfValStu": "VERIFYING", "isCfmCodeExpired": true, "eTag": "F3AA3B18B35BC12E53E0B7A7EAF13EC41EBD02AD" } ] }, "addresses": { "stateFacts": [ "hasSize" ], "size": 2, "eTag": "47B43F0210344E272F338073C382C5955651C5E2", "elements": [ { "stateFacts": [ "Identifiable" ], "id": 530, "type": "PLV", "addressStr": "г Чебоксары, пр-кт Мира", "fiasCode": "bb5f4fab-64ea-4042-a61b-9b2bdb55442d", "flat": "1", "countryId": "RUS", "house": "1", "zipCode": "428022", "city": "Чебоксары", "street": "Мира", "region": "Чувашская Республика", "eTag": "3553085EBBC08CEBFD73957B7D5BAFDFDA096CCA" }, { "stateFacts": [ "Identifiable" ], "id": 15893, "type": "PRG", "addressStr": "г Чебоксары, пр-кт Мира", "fiasCode": "bb5f4fab-64ea-4042-a61b-9b2bdb55442d", "flat": "1", "countryId": "RUS", "house": "1", "zipCode": "428022", "city": "Чебоксары", "street": "Мира", "region": "Чувашская Республика", "eTag": "C90BE244DC0650255C9D3078C7C7EDEA8013BB6E" } ] }, "documents": { "stateFacts": [ "hasSize" ], "size": 2, "eTag": "E752C6CFC8CBAE112527BF2AA07CB0A173143065", "elements": [ { "stateFacts": [ "EntityRoot" ], "id": 3571, "type": "RF_PASSPORT", "vrfStu": "VERIFIED", "series": "5303", "number": "925695", "issueDate": "01.01.2006", "issueId": "006006", "issuedBy": "УФМС006", "eTag": "2E1F79E93B9DF6F5A579F95069630742D41C6AFB" }, { "stateFacts": [ "EntityRoot" ], "id": 21213, "type": "RF_DRIVING_LICENSE", "vrfStu": "NOT_VERIFIED", "series": "1222", "number": "884455", "issueDate": "01.09.2014", "expiryDate": "01.08.2024", "eTag": "E9D14F10321D0021A1267B8D363B22B102387735" } ] }, "vehicles": { "stateFacts": [ "hasSize" ], "size": 1, "eTag": "9D0855F880F882EBCFD93C329C4720D5DB4058D9", "elements": [ { "stateFacts": [ "Identifiable" ], "id": 17743, "name": "Моя птичка", "numberPlate": "А123АА111", "regCertificate": { "series": "1231", "number": "231231" }, "eTag": "A99823275D311CB97A371A420A59AA6BB08B42B7" } ] }, "status": "REGISTERED", "verifying": false, "rIdDoc": 3571, "containsUpCfmCode": false, "eTag": "61F2A6BF9D17B97E6B56F8B10EB28A7C814FF0B4" }
测试
Node用于交互式无头chrome认证机器人。
vendor/bin/phpunit --debug
关于ESIA
ESIA有三个用户识别级别
- 简单
- 标准
- 已确认
信息系统可以请求个人信息注册中的用户信息。
ESIA用户可以是
- 个人
- 个人企业家(个人 + 标记“is entrepreneur”)
- 与法人实体账户关联的个人
- 与公共当局账户关联的个人
个人之后的用户只能是已确认的识别级别。
用户信息
在用户的许可后,可以通过REST读取其信息。
作用域
要获取有关用户的一些信息,系统应通过“作用域”参数请求它。与连接到ESIA的纸质应用程序中输入的参数相同。
作用域类似于移动应用程序中的权限,但针对用户数据。
以下是可能的范围列表:fullname、birthdate、gender、snils、inn、id_doc、birthplace、medical_doc、military_doc、foreign_passport_doc、drivers_licence_doc、vehicles、email、mobile、contacts、kid_fullname。
安全算法
ESIA REST支持RSA2048+SHA256和GOST3410-2001+GOST341194算法。
认证方法
有两种方法可以认证用户:SAML 2.0和OpenID Connect 1.0(OAuth 2.0扩展)。SAML 2.0仅适用于公共当局。
对于法人实体,使用OpenID Connect。
条款
ESIA是俄语的“ЕСИА”,代表“Единая система идентификации и аутентификации”。翻译为“统一身份认证系统”。