mirror of
https://github.com/elyby/oauth2-server.git
synced 2025-05-31 14:12:07 +05:30
Compare commits
40 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
26889abdd3 | ||
|
0f19a6f41c | ||
|
4e996ab3f1 | ||
|
55f93f9400 | ||
|
aee1779432 | ||
|
09c167ac43 | ||
|
765a01021b | ||
|
0706d66c76 | ||
|
e123fe82d0 | ||
|
107cfc3678 | ||
|
1954120c3d | ||
|
dd5eee150d | ||
|
76c1349181 | ||
|
1af4012df4 | ||
|
4a717104fa | ||
|
63530443fe | ||
|
2f8de3d230 | ||
|
57d199b889 | ||
|
6bdd108145 | ||
|
bf7084a147 | ||
|
13c608b849 | ||
|
ded7c1ed47 | ||
|
0da70c916a | ||
|
90cb1bf012 | ||
|
b32204bd91 | ||
|
518c1fcec5 | ||
|
6946592553 | ||
|
25580b98b7 | ||
|
f78dc2eca0 | ||
|
105b3116dc | ||
|
01677a564e | ||
|
4c4b0633b1 | ||
|
c4a75b2880 | ||
|
e091d48127 | ||
|
a798cfdc5d | ||
|
56e8d374fb | ||
|
b1bfff7325 | ||
|
32cde01ab2 | ||
|
11ccc305d0 | ||
|
d7df2f7e24 |
@@ -11,7 +11,7 @@ php:
|
|||||||
- 5.5
|
- 5.5
|
||||||
- 5.6
|
- 5.6
|
||||||
- 7.0
|
- 7.0
|
||||||
- hhvm
|
- 7.1
|
||||||
|
|
||||||
install:
|
install:
|
||||||
- travis_retry composer install --no-interaction --prefer-source
|
- travis_retry composer install --no-interaction --prefer-source
|
||||||
@@ -21,4 +21,4 @@ script:
|
|||||||
|
|
||||||
branches:
|
branches:
|
||||||
only:
|
only:
|
||||||
- master
|
- master
|
||||||
|
18
CHANGELOG.md
18
CHANGELOG.md
@@ -1,5 +1,23 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## 5.1.4 (released 2017-07-01)
|
||||||
|
|
||||||
|
* Fixed multiple security vulnerabilities as a result of a security audit paid for by the [Mozilla Secure Open Source Fund](https://wiki.mozilla.org/MOSS/Secure_Open_Source). All users of this library are encouraged to update as soon as possible to this version or version 6.0 or greater.
|
||||||
|
* It is recommended on each `AuthorizationServer` instance you set the `setEncryptionKey()`. This will result in stronger encryption being used. If this method is not set messages will be sent to the defined error handling routines (using `error_log`). Please see the examples and documentation for examples.
|
||||||
|
* TravisCI now tests PHP 7.1 (Issue #671)
|
||||||
|
* Fix middleware example fatal error (Issue #682)
|
||||||
|
* Fix typo in the first README sentence (Issue #690)
|
||||||
|
* Corrected DateInterval from 1 min to 1 month (Issue #709)
|
||||||
|
|
||||||
|
## 5.1.3 (released 2016-10-12)
|
||||||
|
|
||||||
|
* Fixed WWW-Authenticate header (Issue #669)
|
||||||
|
* Increase the recommended RSA key length from 1024 to 2048 bits (Issue #668)
|
||||||
|
|
||||||
|
## 5.1.2 (released 2016-09-19)
|
||||||
|
|
||||||
|
* Fixed `finalizeScopes` call (Issue #650)
|
||||||
|
|
||||||
## 5.1.1 (released 2016-07-26)
|
## 5.1.1 (released 2016-07-26)
|
||||||
|
|
||||||
* Improved test suite (Issue #614)
|
* Improved test suite (Issue #614)
|
||||||
|
13
README.md
13
README.md
@@ -1,5 +1,11 @@
|
|||||||
# PHP OAuth 2.0 Server
|
# PHP OAuth 2.0 Server
|
||||||
|
|
||||||
|
### :warning::warning::warning::warning::warning::warning::warning::warning::warning::warning::warning::warning::warning::warning::warning::warning::warning::warning::warning::warning::warning::warning::warning::warning::warning::warning::warning::warning::warning::warning::warning::warning::warning::warning::warning::warning::warning::warning::warning::warning::warning::warning:
|
||||||
|
### Security Notice
|
||||||
|
|
||||||
|
### Please upgrade to version `>=5.1.4` (backwards compatible) or `6.x` (one tiny breaking change) to fix some potential security vulnerabilities
|
||||||
|
### :warning::warning::warning::warning::warning::warning::warning::warning::warning::warning::warning::warning::warning::warning::warning::warning::warning::warning::warning::warning::warning::warning::warning::warning::warning::warning::warning::warning::warning::warning::warning::warning::warning::warning::warning::warning::warning::warning::warning::warning::warning::warning:
|
||||||
|
|
||||||
[](https://github.com/thephpleague/oauth2-server/releases)
|
[](https://github.com/thephpleague/oauth2-server/releases)
|
||||||
[](LICENSE.md)
|
[](LICENSE.md)
|
||||||
[](https://travis-ci.org/thephpleague/oauth2-server)
|
[](https://travis-ci.org/thephpleague/oauth2-server)
|
||||||
@@ -7,7 +13,7 @@
|
|||||||
[](https://scrutinizer-ci.com/g/thephpleague/oauth2-server)
|
[](https://scrutinizer-ci.com/g/thephpleague/oauth2-server)
|
||||||
[](https://packagist.org/packages/league/oauth2-server)
|
[](https://packagist.org/packages/league/oauth2-server)
|
||||||
|
|
||||||
`league/oauth2-server` is a a standards compliant implementation of an [OAuth 2.0](https://tools.ietf.org/html/rfc6749) authorization server written in PHP which makes working with OAuth 2.0 trivial. You can easily configure an OAuth 2.0 server to protect your API with access tokens, or allow clients to request new access tokens and refresh them.
|
`league/oauth2-server` is a standards compliant implementation of an [OAuth 2.0](https://tools.ietf.org/html/rfc6749) authorization server written in PHP which makes working with OAuth 2.0 trivial. You can easily configure an OAuth 2.0 server to protect your API with access tokens, or allow clients to request new access tokens and refresh them.
|
||||||
|
|
||||||
It supports out of the box the following grants:
|
It supports out of the box the following grants:
|
||||||
|
|
||||||
@@ -33,6 +39,7 @@ The following versions of PHP are supported:
|
|||||||
* PHP 5.5 (>=5.5.9)
|
* PHP 5.5 (>=5.5.9)
|
||||||
* PHP 5.6
|
* PHP 5.6
|
||||||
* PHP 7.0
|
* PHP 7.0
|
||||||
|
* PHP 7.1
|
||||||
* HHVM
|
* HHVM
|
||||||
|
|
||||||
The `openssl` extension is also required.
|
The `openssl` extension is also required.
|
||||||
@@ -72,6 +79,8 @@ This package is released under the MIT License. See the bundled [LICENSE](https:
|
|||||||
|
|
||||||
This code is principally developed and maintained by [Alex Bilbie](https://twitter.com/alexbilbie).
|
This code is principally developed and maintained by [Alex Bilbie](https://twitter.com/alexbilbie).
|
||||||
|
|
||||||
Special thanks to [all of these awesome contributors](https://github.com/thephpleague/oauth2-server/contributors)
|
Special thanks to [all of these awesome contributors](https://github.com/thephpleague/oauth2-server/contributors).
|
||||||
|
|
||||||
|
Additional thanks go to the [Mozilla Secure Open Source Fund](https://wiki.mozilla.org/MOSS/Secure_Open_Source) for funding a security audit of this library.
|
||||||
|
|
||||||
The initial code was developed as part of the [Linkey](http://linkey.blogs.lincoln.ac.uk) project which was funded by [JISC](http://jisc.ac.uk) under the Access and Identity Management programme.
|
The initial code was developed as part of the [Linkey](http://linkey.blogs.lincoln.ac.uk) project which was funded by [JISC](http://jisc.ac.uk) under the Access and Identity Management programme.
|
||||||
|
@@ -8,8 +8,9 @@
|
|||||||
"ext-openssl": "*",
|
"ext-openssl": "*",
|
||||||
"league/event": "^2.1",
|
"league/event": "^2.1",
|
||||||
"lcobucci/jwt": "^3.1",
|
"lcobucci/jwt": "^3.1",
|
||||||
"paragonie/random_compat": "^1.1 || ^2.0",
|
"paragonie/random_compat": "^2.0",
|
||||||
"psr/http-message": "^1.0"
|
"psr/http-message": "^1.0",
|
||||||
|
"defuse/php-encryption": "^2.1"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"phpunit/phpunit": "^4.8 || ^5.0",
|
"phpunit/phpunit": "^4.8 || ^5.0",
|
||||||
|
@@ -3,7 +3,7 @@
|
|||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
0. Run `composer install` in this directory to install dependencies
|
0. Run `composer install` in this directory to install dependencies
|
||||||
0. Create a private key `openssl genrsa -out private.key 1024`
|
0. Create a private key `openssl genrsa -out private.key 2048`
|
||||||
0. Create a public key `openssl rsa -in private.key -pubout > public.key`
|
0. Create a public key `openssl rsa -in private.key -pubout > public.key`
|
||||||
0. `cd` into the public directory
|
0. `cd` into the public directory
|
||||||
0. Start a PHP server `php -S localhost:4444`
|
0. Start a PHP server `php -S localhost:4444`
|
||||||
|
@@ -5,8 +5,9 @@
|
|||||||
"require-dev": {
|
"require-dev": {
|
||||||
"league/event": "^2.1",
|
"league/event": "^2.1",
|
||||||
"lcobucci/jwt": "^3.1",
|
"lcobucci/jwt": "^3.1",
|
||||||
"paragonie/random_compat": "^1.1",
|
"paragonie/random_compat": "^2.0",
|
||||||
"psr/http-message": "^1.0"
|
"psr/http-message": "^1.0",
|
||||||
|
"defuse/php-encryption": "^2.1"
|
||||||
},
|
},
|
||||||
"autoload": {
|
"autoload": {
|
||||||
"psr-4": {
|
"psr-4": {
|
||||||
|
178
examples/composer.lock
generated
178
examples/composer.lock
generated
@@ -4,23 +4,25 @@
|
|||||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
|
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
|
||||||
"This file is @generated automatically"
|
"This file is @generated automatically"
|
||||||
],
|
],
|
||||||
"hash": "48bcb7a3514d7c7f271c554ba1440124",
|
"content-hash": "9813ed7c3b6dcf107f44df9392935b8f",
|
||||||
"content-hash": "e41be75973527cb9d63f27ad14ac8624",
|
|
||||||
"packages": [
|
"packages": [
|
||||||
{
|
{
|
||||||
"name": "container-interop/container-interop",
|
"name": "container-interop/container-interop",
|
||||||
"version": "1.1.0",
|
"version": "1.2.0",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/container-interop/container-interop.git",
|
"url": "https://github.com/container-interop/container-interop.git",
|
||||||
"reference": "fc08354828f8fd3245f77a66b9e23a6bca48297e"
|
"reference": "79cbf1341c22ec75643d841642dd5d6acd83bdb8"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/container-interop/container-interop/zipball/fc08354828f8fd3245f77a66b9e23a6bca48297e",
|
"url": "https://api.github.com/repos/container-interop/container-interop/zipball/79cbf1341c22ec75643d841642dd5d6acd83bdb8",
|
||||||
"reference": "fc08354828f8fd3245f77a66b9e23a6bca48297e",
|
"reference": "79cbf1341c22ec75643d841642dd5d6acd83bdb8",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
|
"require": {
|
||||||
|
"psr/container": "^1.0"
|
||||||
|
},
|
||||||
"type": "library",
|
"type": "library",
|
||||||
"autoload": {
|
"autoload": {
|
||||||
"psr-4": {
|
"psr-4": {
|
||||||
@@ -32,7 +34,8 @@
|
|||||||
"MIT"
|
"MIT"
|
||||||
],
|
],
|
||||||
"description": "Promoting the interoperability of container objects (DIC, SL, etc.)",
|
"description": "Promoting the interoperability of container objects (DIC, SL, etc.)",
|
||||||
"time": "2014-12-30 15:22:37"
|
"homepage": "https://github.com/container-interop/container-interop",
|
||||||
|
"time": "2017-02-14T19:40:03+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "nikic/fast-route",
|
"name": "nikic/fast-route",
|
||||||
@@ -75,7 +78,7 @@
|
|||||||
"router",
|
"router",
|
||||||
"routing"
|
"routing"
|
||||||
],
|
],
|
||||||
"time": "2015-06-18 19:15:47"
|
"time": "2015-06-18T19:15:47+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "pimple/pimple",
|
"name": "pimple/pimple",
|
||||||
@@ -121,20 +124,69 @@
|
|||||||
"container",
|
"container",
|
||||||
"dependency injection"
|
"dependency injection"
|
||||||
],
|
],
|
||||||
"time": "2015-09-11 15:10:35"
|
"time": "2015-09-11T15:10:35+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "psr/http-message",
|
"name": "psr/container",
|
||||||
"version": "1.0",
|
"version": "1.0.0",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/php-fig/http-message.git",
|
"url": "https://github.com/php-fig/container.git",
|
||||||
"reference": "85d63699f0dbedb190bbd4b0d2b9dc707ea4c298"
|
"reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/php-fig/http-message/zipball/85d63699f0dbedb190bbd4b0d2b9dc707ea4c298",
|
"url": "https://api.github.com/repos/php-fig/container/zipball/b7ce3b176482dbbc1245ebf52b181af44c2cf55f",
|
||||||
"reference": "85d63699f0dbedb190bbd4b0d2b9dc707ea4c298",
|
"reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"php": ">=5.3.0"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"extra": {
|
||||||
|
"branch-alias": {
|
||||||
|
"dev-master": "1.0.x-dev"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"Psr\\Container\\": "src/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "PHP-FIG",
|
||||||
|
"homepage": "http://www.php-fig.org/"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Common Container Interface (PHP FIG PSR-11)",
|
||||||
|
"homepage": "https://github.com/php-fig/container",
|
||||||
|
"keywords": [
|
||||||
|
"PSR-11",
|
||||||
|
"container",
|
||||||
|
"container-interface",
|
||||||
|
"container-interop",
|
||||||
|
"psr"
|
||||||
|
],
|
||||||
|
"time": "2017-02-14T16:28:37+00:00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "psr/http-message",
|
||||||
|
"version": "1.0.1",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/php-fig/http-message.git",
|
||||||
|
"reference": "f6561bf28d520154e4b0ec72be95418abe6d9363"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/php-fig/http-message/zipball/f6561bf28d520154e4b0ec72be95418abe6d9363",
|
||||||
|
"reference": "f6561bf28d520154e4b0ec72be95418abe6d9363",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
@@ -162,6 +214,7 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"description": "Common interface for HTTP messages",
|
"description": "Common interface for HTTP messages",
|
||||||
|
"homepage": "https://github.com/php-fig/http-message",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"http",
|
"http",
|
||||||
"http-message",
|
"http-message",
|
||||||
@@ -170,7 +223,7 @@
|
|||||||
"request",
|
"request",
|
||||||
"response"
|
"response"
|
||||||
],
|
],
|
||||||
"time": "2015-05-04 20:22:00"
|
"time": "2016-08-06T14:39:51+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "slim/slim",
|
"name": "slim/slim",
|
||||||
@@ -236,22 +289,85 @@
|
|||||||
"micro",
|
"micro",
|
||||||
"router"
|
"router"
|
||||||
],
|
],
|
||||||
"time": "2015-12-07 14:11:09"
|
"time": "2015-12-07T14:11:09+00:00"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"packages-dev": [
|
"packages-dev": [
|
||||||
{
|
{
|
||||||
"name": "lcobucci/jwt",
|
"name": "defuse/php-encryption",
|
||||||
"version": "3.1.1",
|
"version": "v2.1.0",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/lcobucci/jwt.git",
|
"url": "https://github.com/defuse/php-encryption.git",
|
||||||
"reference": "afea8e682e911a21574fd8519321b32522fa25b5"
|
"reference": "5176f5abb38d3ea8a6e3ac6cd3bbb54d8185a689"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/lcobucci/jwt/zipball/afea8e682e911a21574fd8519321b32522fa25b5",
|
"url": "https://api.github.com/repos/defuse/php-encryption/zipball/5176f5abb38d3ea8a6e3ac6cd3bbb54d8185a689",
|
||||||
"reference": "afea8e682e911a21574fd8519321b32522fa25b5",
|
"reference": "5176f5abb38d3ea8a6e3ac6cd3bbb54d8185a689",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"ext-openssl": "*",
|
||||||
|
"paragonie/random_compat": "~2.0",
|
||||||
|
"php": ">=5.4.0"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"nikic/php-parser": "^2.0|^3.0",
|
||||||
|
"phpunit/phpunit": "^4|^5"
|
||||||
|
},
|
||||||
|
"bin": [
|
||||||
|
"bin/generate-defuse-key"
|
||||||
|
],
|
||||||
|
"type": "library",
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"Defuse\\Crypto\\": "src"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Taylor Hornby",
|
||||||
|
"email": "taylor@defuse.ca",
|
||||||
|
"homepage": "https://defuse.ca/"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Scott Arciszewski",
|
||||||
|
"email": "info@paragonie.com",
|
||||||
|
"homepage": "https://paragonie.com"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Secure PHP Encryption Library",
|
||||||
|
"keywords": [
|
||||||
|
"aes",
|
||||||
|
"authenticated encryption",
|
||||||
|
"cipher",
|
||||||
|
"crypto",
|
||||||
|
"cryptography",
|
||||||
|
"encrypt",
|
||||||
|
"encryption",
|
||||||
|
"openssl",
|
||||||
|
"security",
|
||||||
|
"symmetric key cryptography"
|
||||||
|
],
|
||||||
|
"time": "2017-05-18T21:28:48+00:00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "lcobucci/jwt",
|
||||||
|
"version": "3.2.1",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/lcobucci/jwt.git",
|
||||||
|
"reference": "ddce703826f9c5229781933b1a39069e38e6a0f3"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/lcobucci/jwt/zipball/ddce703826f9c5229781933b1a39069e38e6a0f3",
|
||||||
|
"reference": "ddce703826f9c5229781933b1a39069e38e6a0f3",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
@@ -259,7 +375,7 @@
|
|||||||
"php": ">=5.5"
|
"php": ">=5.5"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"mdanter/ecc": "~0.3",
|
"mdanter/ecc": "~0.3.1",
|
||||||
"mikey179/vfsstream": "~1.5",
|
"mikey179/vfsstream": "~1.5",
|
||||||
"phpmd/phpmd": "~2.2",
|
"phpmd/phpmd": "~2.2",
|
||||||
"phpunit/php-invoker": "~1.1",
|
"phpunit/php-invoker": "~1.1",
|
||||||
@@ -296,7 +412,7 @@
|
|||||||
"JWS",
|
"JWS",
|
||||||
"jwt"
|
"jwt"
|
||||||
],
|
],
|
||||||
"time": "2016-03-24 22:46:13"
|
"time": "2016-10-31T20:09:32+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "league/event",
|
"name": "league/event",
|
||||||
@@ -346,20 +462,20 @@
|
|||||||
"event",
|
"event",
|
||||||
"listener"
|
"listener"
|
||||||
],
|
],
|
||||||
"time": "2015-05-21 12:24:47"
|
"time": "2015-05-21T12:24:47+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "paragonie/random_compat",
|
"name": "paragonie/random_compat",
|
||||||
"version": "v1.4.1",
|
"version": "v2.0.10",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/paragonie/random_compat.git",
|
"url": "https://github.com/paragonie/random_compat.git",
|
||||||
"reference": "c7e26a21ba357863de030f0b9e701c7d04593774"
|
"reference": "634bae8e911eefa89c1abfbf1b66da679ac8f54d"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/paragonie/random_compat/zipball/c7e26a21ba357863de030f0b9e701c7d04593774",
|
"url": "https://api.github.com/repos/paragonie/random_compat/zipball/634bae8e911eefa89c1abfbf1b66da679ac8f54d",
|
||||||
"reference": "c7e26a21ba357863de030f0b9e701c7d04593774",
|
"reference": "634bae8e911eefa89c1abfbf1b66da679ac8f54d",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
@@ -394,7 +510,7 @@
|
|||||||
"pseudorandom",
|
"pseudorandom",
|
||||||
"random"
|
"random"
|
||||||
],
|
],
|
||||||
"time": "2016-03-18 20:34:03"
|
"time": "2017-03-13T16:27:32+00:00"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"aliases": [],
|
"aliases": [],
|
||||||
|
@@ -31,7 +31,6 @@ $app->add(
|
|||||||
$app->get(
|
$app->get(
|
||||||
'/users',
|
'/users',
|
||||||
function (ServerRequestInterface $request, ResponseInterface $response) use ($app) {
|
function (ServerRequestInterface $request, ResponseInterface $response) use ($app) {
|
||||||
|
|
||||||
$users = [
|
$users = [
|
||||||
[
|
[
|
||||||
'id' => 123,
|
'id' => 123,
|
||||||
@@ -70,4 +69,4 @@ $app->get(
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
$app->run();
|
$app->run();
|
||||||
|
@@ -46,6 +46,7 @@ $app = new App([
|
|||||||
$privateKeyPath,
|
$privateKeyPath,
|
||||||
$publicKeyPath
|
$publicKeyPath
|
||||||
);
|
);
|
||||||
|
$server->setEncryptionKey('lxZFUEsBCJ2Yb14IF2ygAHI5N4+ZAUXXaSeeJm6+twsUmIen');
|
||||||
|
|
||||||
// Enable the authentication code grant on the server with a token TTL of 1 hour
|
// Enable the authentication code grant on the server with a token TTL of 1 hour
|
||||||
$server->enableGrantType(
|
$server->enableGrantType(
|
||||||
|
@@ -30,9 +30,9 @@ $app = new App([
|
|||||||
$accessTokenRepository = new AccessTokenRepository(); // instance of AccessTokenRepositoryInterface
|
$accessTokenRepository = new AccessTokenRepository(); // instance of AccessTokenRepositoryInterface
|
||||||
|
|
||||||
// Path to public and private keys
|
// Path to public and private keys
|
||||||
$privateKey = 'file://'.__DIR__.'/../private.key';
|
$privateKey = 'file://' . __DIR__ . '/../private.key';
|
||||||
//$privateKey = new CryptKey('file://path/to/private.key', 'passphrase'); // if private key has a pass phrase
|
//$privateKey = new CryptKey('file://path/to/private.key', 'passphrase'); // if private key has a pass phrase
|
||||||
$publicKey = 'file://'.__DIR__.'/../public.key';
|
$publicKey = 'file://' . __DIR__ . '/../public.key';
|
||||||
|
|
||||||
// Setup the authorization server
|
// Setup the authorization server
|
||||||
$server = new AuthorizationServer(
|
$server = new AuthorizationServer(
|
||||||
@@ -42,6 +42,7 @@ $app = new App([
|
|||||||
$privateKey,
|
$privateKey,
|
||||||
$publicKey
|
$publicKey
|
||||||
);
|
);
|
||||||
|
$server->setEncryptionKey('lxZFUEsBCJ2Yb14IF2ygAHI5N4+ZAUXXaSeeJm6+twsUmIen');
|
||||||
|
|
||||||
// Enable the client credentials grant on the server
|
// Enable the client credentials grant on the server
|
||||||
$server->enableGrantType(
|
$server->enableGrantType(
|
||||||
|
@@ -42,6 +42,7 @@ $app = new App([
|
|||||||
$privateKeyPath,
|
$privateKeyPath,
|
||||||
$publicKeyPath
|
$publicKeyPath
|
||||||
);
|
);
|
||||||
|
$server->setEncryptionKey('lxZFUEsBCJ2Yb14IF2ygAHI5N4+ZAUXXaSeeJm6+twsUmIen');
|
||||||
|
|
||||||
// Enable the implicit grant on the server with a token TTL of 1 hour
|
// Enable the implicit grant on the server with a token TTL of 1 hour
|
||||||
$server->enableGrantType(new ImplicitGrant(new \DateInterval('PT1H')));
|
$server->enableGrantType(new ImplicitGrant(new \DateInterval('PT1H')));
|
||||||
|
@@ -12,6 +12,7 @@ use League\OAuth2\Server\Grant\AuthCodeGrant;
|
|||||||
use League\OAuth2\Server\Grant\RefreshTokenGrant;
|
use League\OAuth2\Server\Grant\RefreshTokenGrant;
|
||||||
use League\OAuth2\Server\Middleware\AuthorizationServerMiddleware;
|
use League\OAuth2\Server\Middleware\AuthorizationServerMiddleware;
|
||||||
use League\OAuth2\Server\Middleware\ResourceServerMiddleware;
|
use League\OAuth2\Server\Middleware\ResourceServerMiddleware;
|
||||||
|
use League\OAuth2\Server\ResourceServer;
|
||||||
use OAuth2ServerExamples\Repositories\AccessTokenRepository;
|
use OAuth2ServerExamples\Repositories\AccessTokenRepository;
|
||||||
use OAuth2ServerExamples\Repositories\AuthCodeRepository;
|
use OAuth2ServerExamples\Repositories\AuthCodeRepository;
|
||||||
use OAuth2ServerExamples\Repositories\ClientRepository;
|
use OAuth2ServerExamples\Repositories\ClientRepository;
|
||||||
@@ -47,6 +48,7 @@ $app = new App([
|
|||||||
$privateKeyPath,
|
$privateKeyPath,
|
||||||
$publicKeyPath
|
$publicKeyPath
|
||||||
);
|
);
|
||||||
|
$server->setEncryptionKey('lxZFUEsBCJ2Yb14IF2ygAHI5N4+ZAUXXaSeeJm6+twsUmIen');
|
||||||
|
|
||||||
// Enable the authentication code grant on the server with a token TTL of 1 hour
|
// Enable the authentication code grant on the server with a token TTL of 1 hour
|
||||||
$server->enableGrantType(
|
$server->enableGrantType(
|
||||||
@@ -61,7 +63,17 @@ $app = new App([
|
|||||||
// Enable the refresh token grant on the server with a token TTL of 1 month
|
// Enable the refresh token grant on the server with a token TTL of 1 month
|
||||||
$server->enableGrantType(
|
$server->enableGrantType(
|
||||||
new RefreshTokenGrant($refreshTokenRepository),
|
new RefreshTokenGrant($refreshTokenRepository),
|
||||||
new \DateInterval('PT1M')
|
new \DateInterval('P1M')
|
||||||
|
);
|
||||||
|
|
||||||
|
return $server;
|
||||||
|
},
|
||||||
|
ResourceServer::class => function () {
|
||||||
|
$publicKeyPath = 'file://' . __DIR__ . '/../public.key';
|
||||||
|
|
||||||
|
$server = new ResourceServer(
|
||||||
|
new AccessTokenRepository(),
|
||||||
|
$publicKeyPath
|
||||||
);
|
);
|
||||||
|
|
||||||
return $server;
|
return $server;
|
||||||
@@ -94,6 +106,6 @@ $app->group('/api', function () {
|
|||||||
|
|
||||||
return $response->withBody($body);
|
return $response->withBody($body);
|
||||||
});
|
});
|
||||||
})->add(new ResourceServerMiddleware($app->getContainer()->get(AuthorizationServer::class)));
|
})->add(new ResourceServerMiddleware($app->getContainer()->get(ResourceServer::class)));
|
||||||
|
|
||||||
$app->run();
|
$app->run();
|
||||||
|
@@ -23,9 +23,10 @@ $app = new App([
|
|||||||
new ClientRepository(), // instance of ClientRepositoryInterface
|
new ClientRepository(), // instance of ClientRepositoryInterface
|
||||||
new AccessTokenRepository(), // instance of AccessTokenRepositoryInterface
|
new AccessTokenRepository(), // instance of AccessTokenRepositoryInterface
|
||||||
new ScopeRepository(), // instance of ScopeRepositoryInterface
|
new ScopeRepository(), // instance of ScopeRepositoryInterface
|
||||||
'file://'.__DIR__.'/../private.key', // path to private key
|
'file://' . __DIR__ . '/../private.key', // path to private key
|
||||||
'file://'.__DIR__.'/../public.key' // path to public key
|
'file://' . __DIR__ . '/../public.key' // path to public key
|
||||||
);
|
);
|
||||||
|
$server->setEncryptionKey('lxZFUEsBCJ2Yb14IF2ygAHI5N4+ZAUXXaSeeJm6+twsUmIen');
|
||||||
|
|
||||||
$grant = new PasswordGrant(
|
$grant = new PasswordGrant(
|
||||||
new UserRepository(), // instance of UserRepositoryInterface
|
new UserRepository(), // instance of UserRepositoryInterface
|
||||||
@@ -54,19 +55,17 @@ $app->post(
|
|||||||
|
|
||||||
// Try to respond to the access token request
|
// Try to respond to the access token request
|
||||||
return $server->respondToAccessTokenRequest($request, $response);
|
return $server->respondToAccessTokenRequest($request, $response);
|
||||||
|
|
||||||
} catch (OAuthServerException $exception) {
|
} catch (OAuthServerException $exception) {
|
||||||
|
|
||||||
// All instances of OAuthServerException can be converted to a PSR-7 response
|
// All instances of OAuthServerException can be converted to a PSR-7 response
|
||||||
return $exception->generateHttpResponse($response);
|
return $exception->generateHttpResponse($response);
|
||||||
|
|
||||||
} catch (\Exception $exception) {
|
} catch (\Exception $exception) {
|
||||||
|
|
||||||
// Catch unexpected exceptions
|
// Catch unexpected exceptions
|
||||||
$body = $response->getBody();
|
$body = $response->getBody();
|
||||||
$body->write($exception->getMessage());
|
$body->write($exception->getMessage());
|
||||||
return $response->withStatus(500)->withBody($body);
|
|
||||||
|
|
||||||
|
return $response->withStatus(500)->withBody($body);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
@@ -17,7 +17,6 @@ use OAuth2ServerExamples\Repositories\ScopeRepository;
|
|||||||
use Psr\Http\Message\ResponseInterface;
|
use Psr\Http\Message\ResponseInterface;
|
||||||
use Psr\Http\Message\ServerRequestInterface;
|
use Psr\Http\Message\ServerRequestInterface;
|
||||||
use Slim\App;
|
use Slim\App;
|
||||||
use Zend\Diactoros\Stream;
|
|
||||||
|
|
||||||
include __DIR__ . '/../vendor/autoload.php';
|
include __DIR__ . '/../vendor/autoload.php';
|
||||||
|
|
||||||
@@ -43,6 +42,7 @@ $app = new App([
|
|||||||
$privateKeyPath,
|
$privateKeyPath,
|
||||||
$publicKeyPath
|
$publicKeyPath
|
||||||
);
|
);
|
||||||
|
$server->setEncryptionKey('lxZFUEsBCJ2Yb14IF2ygAHI5N4+ZAUXXaSeeJm6+twsUmIen');
|
||||||
|
|
||||||
// Enable the refresh token grant on the server
|
// Enable the refresh token grant on the server
|
||||||
$grant = new RefreshTokenGrant($refreshTokenRepository);
|
$grant = new RefreshTokenGrant($refreshTokenRepository);
|
||||||
@@ -66,10 +66,9 @@ $app->post('/access_token', function (ServerRequestInterface $request, ResponseI
|
|||||||
} catch (OAuthServerException $exception) {
|
} catch (OAuthServerException $exception) {
|
||||||
return $exception->generateHttpResponse($response);
|
return $exception->generateHttpResponse($response);
|
||||||
} catch (\Exception $exception) {
|
} catch (\Exception $exception) {
|
||||||
$body = new Stream('php://temp', 'r+');
|
$response->getBody()->write($exception->getMessage());
|
||||||
$body->write($exception->getMessage());
|
|
||||||
|
|
||||||
return $response->withStatus(500)->withBody($body);
|
return $response->withStatus(500);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@@ -54,7 +54,7 @@ class ScopeRepository implements ScopeRepositoryInterface
|
|||||||
$scope->setIdentifier('email');
|
$scope->setIdentifier('email');
|
||||||
$scopes[] = $scope;
|
$scopes[] = $scope;
|
||||||
}
|
}
|
||||||
|
|
||||||
return $scopes;
|
return $scopes;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -26,6 +26,8 @@ class AuthorizationServer implements EmitterAwareInterface
|
|||||||
{
|
{
|
||||||
use EmitterAwareTrait;
|
use EmitterAwareTrait;
|
||||||
|
|
||||||
|
const ENCRYPTION_KEY_ERROR = 'You must set the encryption key going forward to improve the security of this library - see this page for more information https://oauth2.thephpleague.com/v5-security-improvements/';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var GrantTypeInterface[]
|
* @var GrantTypeInterface[]
|
||||||
*/
|
*/
|
||||||
@@ -66,6 +68,11 @@ class AuthorizationServer implements EmitterAwareInterface
|
|||||||
*/
|
*/
|
||||||
private $scopeRepository;
|
private $scopeRepository;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
private $encryptionKey;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* New server instance.
|
* New server instance.
|
||||||
*
|
*
|
||||||
@@ -101,6 +108,16 @@ class AuthorizationServer implements EmitterAwareInterface
|
|||||||
$this->responseType = $responseType;
|
$this->responseType = $responseType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the encryption key
|
||||||
|
*
|
||||||
|
* @param string $key
|
||||||
|
*/
|
||||||
|
public function setEncryptionKey($key)
|
||||||
|
{
|
||||||
|
$this->encryptionKey = $key;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enable a grant type on the server.
|
* Enable a grant type on the server.
|
||||||
*
|
*
|
||||||
@@ -120,6 +137,13 @@ class AuthorizationServer implements EmitterAwareInterface
|
|||||||
$grantType->setPublicKey($this->publicKey);
|
$grantType->setPublicKey($this->publicKey);
|
||||||
$grantType->setEmitter($this->getEmitter());
|
$grantType->setEmitter($this->getEmitter());
|
||||||
|
|
||||||
|
if ($this->encryptionKey === null) {
|
||||||
|
// @codeCoverageIgnoreStart
|
||||||
|
error_log(self::ENCRYPTION_KEY_ERROR);
|
||||||
|
// @codeCoverageIgnoreEnd
|
||||||
|
}
|
||||||
|
$grantType->setEncryptionKey($this->encryptionKey);
|
||||||
|
|
||||||
$this->enabledGrantTypes[$grantType->getIdentifier()] = $grantType;
|
$this->enabledGrantTypes[$grantType->getIdentifier()] = $grantType;
|
||||||
$this->grantTypeAccessTokenTTL[$grantType->getIdentifier()] = $accessTokenTTL;
|
$this->grantTypeAccessTokenTTL[$grantType->getIdentifier()] = $accessTokenTTL;
|
||||||
}
|
}
|
||||||
@@ -135,6 +159,12 @@ class AuthorizationServer implements EmitterAwareInterface
|
|||||||
*/
|
*/
|
||||||
public function validateAuthorizationRequest(ServerRequestInterface $request)
|
public function validateAuthorizationRequest(ServerRequestInterface $request)
|
||||||
{
|
{
|
||||||
|
if ($this->encryptionKey === null) {
|
||||||
|
// @codeCoverageIgnoreStart
|
||||||
|
error_log(self::ENCRYPTION_KEY_ERROR);
|
||||||
|
// @codeCoverageIgnoreEnd
|
||||||
|
}
|
||||||
|
|
||||||
foreach ($this->enabledGrantTypes as $grantType) {
|
foreach ($this->enabledGrantTypes as $grantType) {
|
||||||
if ($grantType->canRespondToAuthorizationRequest($request)) {
|
if ($grantType->canRespondToAuthorizationRequest($request)) {
|
||||||
return $grantType->validateAuthorizationRequest($request);
|
return $grantType->validateAuthorizationRequest($request);
|
||||||
@@ -200,6 +230,7 @@ class AuthorizationServer implements EmitterAwareInterface
|
|||||||
}
|
}
|
||||||
|
|
||||||
$this->responseType->setPrivateKey($this->privateKey);
|
$this->responseType->setPrivateKey($this->privateKey);
|
||||||
|
$this->responseType->setEncryptionKey($this->encryptionKey);
|
||||||
|
|
||||||
return $this->responseType;
|
return $this->responseType;
|
||||||
}
|
}
|
||||||
|
@@ -75,7 +75,7 @@ class BearerTokenValidator implements AuthorizationValidatorInterface
|
|||||||
} catch (\InvalidArgumentException $exception) {
|
} catch (\InvalidArgumentException $exception) {
|
||||||
// JWT couldn't be parsed so return the request as is
|
// JWT couldn't be parsed so return the request as is
|
||||||
throw OAuthServerException::accessDenied($exception->getMessage());
|
throw OAuthServerException::accessDenied($exception->getMessage());
|
||||||
} catch(\RuntimeException $exception){
|
} catch (\RuntimeException $exception) {
|
||||||
//JWR couldn't be parsed so return the request as is
|
//JWR couldn't be parsed so return the request as is
|
||||||
throw OAuthServerException::accessDenied('Error while decoding to JSON');
|
throw OAuthServerException::accessDenied('Error while decoding to JSON');
|
||||||
}
|
}
|
||||||
|
@@ -44,6 +44,23 @@ class CryptKey
|
|||||||
throw new \LogicException(sprintf('Key path "%s" does not exist or is not readable', $keyPath));
|
throw new \LogicException(sprintf('Key path "%s" does not exist or is not readable', $keyPath));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Verify the permissions of the key
|
||||||
|
$keyPathPerms = decoct(fileperms($keyPath) & 0777);
|
||||||
|
if ($keyPathPerms !== '600') {
|
||||||
|
// Attempt to correct the permissions
|
||||||
|
if (chmod($keyPath, 0600) === false) {
|
||||||
|
// @codeCoverageIgnoreStart
|
||||||
|
throw new \LogicException(
|
||||||
|
sprintf(
|
||||||
|
'Key file "%s" permissions are not correct, should be 600 instead of %s, unable to automatically resolve the issue',
|
||||||
|
$keyPath,
|
||||||
|
$keyPathPerms
|
||||||
|
)
|
||||||
|
);
|
||||||
|
// @codeCoverageIgnoreEnd
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$this->keyPath = $keyPath;
|
$this->keyPath = $keyPath;
|
||||||
$this->passPhrase = $passPhrase;
|
$this->passPhrase = $passPhrase;
|
||||||
}
|
}
|
||||||
@@ -57,7 +74,8 @@ class CryptKey
|
|||||||
*/
|
*/
|
||||||
private function saveKeyToFile($key)
|
private function saveKeyToFile($key)
|
||||||
{
|
{
|
||||||
$keyPath = sys_get_temp_dir() . '/' . sha1($key) . '.key';
|
$tmpDir = sys_get_temp_dir();
|
||||||
|
$keyPath = $tmpDir . '/' . sha1($key) . '.key';
|
||||||
|
|
||||||
if (!file_exists($keyPath) && !touch($keyPath)) {
|
if (!file_exists($keyPath) && !touch($keyPath)) {
|
||||||
// @codeCoverageIgnoreStart
|
// @codeCoverageIgnoreStart
|
||||||
@@ -65,7 +83,17 @@ class CryptKey
|
|||||||
// @codeCoverageIgnoreEnd
|
// @codeCoverageIgnoreEnd
|
||||||
}
|
}
|
||||||
|
|
||||||
file_put_contents($keyPath, $key);
|
if (file_put_contents($keyPath, $key) === false) {
|
||||||
|
// @codeCoverageIgnoreStart
|
||||||
|
throw new \RuntimeException('Unable to write key file to temporary directory "%s"', $tmpDir);
|
||||||
|
// @codeCoverageIgnoreEnd
|
||||||
|
}
|
||||||
|
|
||||||
|
if (chmod($keyPath, 0600) === false) {
|
||||||
|
// @codeCoverageIgnoreStart
|
||||||
|
throw new \RuntimeException('The key file "%s" file mode could not be changed with chmod to 600', $keyPath);
|
||||||
|
// @codeCoverageIgnoreEnd
|
||||||
|
}
|
||||||
|
|
||||||
return 'file://' . $keyPath;
|
return 'file://' . $keyPath;
|
||||||
}
|
}
|
||||||
|
@@ -11,6 +11,8 @@
|
|||||||
|
|
||||||
namespace League\OAuth2\Server;
|
namespace League\OAuth2\Server;
|
||||||
|
|
||||||
|
use Defuse\Crypto\Crypto;
|
||||||
|
|
||||||
trait CryptTrait
|
trait CryptTrait
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
@@ -23,6 +25,11 @@ trait CryptTrait
|
|||||||
*/
|
*/
|
||||||
protected $publicKey;
|
protected $publicKey;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $encryptionKey;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set path to private key.
|
* Set path to private key.
|
||||||
*
|
*
|
||||||
@@ -54,6 +61,10 @@ trait CryptTrait
|
|||||||
*/
|
*/
|
||||||
protected function encrypt($unencryptedData)
|
protected function encrypt($unencryptedData)
|
||||||
{
|
{
|
||||||
|
if ($this->encryptionKey !== null) {
|
||||||
|
return Crypto::encryptWithPassword($unencryptedData, $this->encryptionKey);
|
||||||
|
}
|
||||||
|
|
||||||
$privateKey = openssl_pkey_get_private($this->privateKey->getKeyPath(), $this->privateKey->getPassPhrase());
|
$privateKey = openssl_pkey_get_private($this->privateKey->getKeyPath(), $this->privateKey->getPassPhrase());
|
||||||
$privateKeyDetails = @openssl_pkey_get_details($privateKey);
|
$privateKeyDetails = @openssl_pkey_get_details($privateKey);
|
||||||
if ($privateKeyDetails === null) {
|
if ($privateKeyDetails === null) {
|
||||||
@@ -91,6 +102,10 @@ trait CryptTrait
|
|||||||
*/
|
*/
|
||||||
protected function decrypt($encryptedData)
|
protected function decrypt($encryptedData)
|
||||||
{
|
{
|
||||||
|
if ($this->encryptionKey !== null) {
|
||||||
|
return Crypto::decryptWithPassword($encryptedData, $this->encryptionKey);
|
||||||
|
}
|
||||||
|
|
||||||
$publicKey = openssl_pkey_get_public($this->publicKey->getKeyPath());
|
$publicKey = openssl_pkey_get_public($this->publicKey->getKeyPath());
|
||||||
$publicKeyDetails = @openssl_pkey_get_details($publicKey);
|
$publicKeyDetails = @openssl_pkey_get_details($publicKey);
|
||||||
if ($publicKeyDetails === null) {
|
if ($publicKeyDetails === null) {
|
||||||
@@ -118,4 +133,14 @@ trait CryptTrait
|
|||||||
|
|
||||||
return $output;
|
return $output;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the encryption key
|
||||||
|
*
|
||||||
|
* @param string $key
|
||||||
|
*/
|
||||||
|
public function setEncryptionKey($key = null)
|
||||||
|
{
|
||||||
|
$this->encryptionKey = $key;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -105,7 +105,10 @@ class OAuthServerException extends \Exception
|
|||||||
public static function invalidScope($scope, $redirectUri = null)
|
public static function invalidScope($scope, $redirectUri = null)
|
||||||
{
|
{
|
||||||
$errorMessage = 'The requested scope is invalid, unknown, or malformed';
|
$errorMessage = 'The requested scope is invalid, unknown, or malformed';
|
||||||
$hint = sprintf('Check the `%s` scope', $scope);
|
$hint = sprintf(
|
||||||
|
'Check the `%s` scope',
|
||||||
|
htmlspecialchars($scope, ENT_QUOTES, 'UTF-8', false)
|
||||||
|
);
|
||||||
|
|
||||||
return new static($errorMessage, 5, 'invalid_scope', 400, $hint, $redirectUri);
|
return new static($errorMessage, 5, 'invalid_scope', 400, $hint, $redirectUri);
|
||||||
}
|
}
|
||||||
@@ -267,7 +270,7 @@ class OAuthServerException extends \Exception
|
|||||||
) {
|
) {
|
||||||
$authScheme = 'Bearer';
|
$authScheme = 'Bearer';
|
||||||
}
|
}
|
||||||
$headers[] = 'WWW-Authenticate: ' . $authScheme . ' realm="OAuth"';
|
$headers['WWW-Authenticate'] = $authScheme . ' realm="OAuth"';
|
||||||
}
|
}
|
||||||
// @codeCoverageIgnoreEnd
|
// @codeCoverageIgnoreEnd
|
||||||
return $headers;
|
return $headers;
|
||||||
|
@@ -9,7 +9,6 @@
|
|||||||
|
|
||||||
namespace League\OAuth2\Server\Exception;
|
namespace League\OAuth2\Server\Exception;
|
||||||
|
|
||||||
|
|
||||||
class UniqueTokenIdentifierConstraintViolationException extends OAuthServerException
|
class UniqueTokenIdentifierConstraintViolationException extends OAuthServerException
|
||||||
{
|
{
|
||||||
public static function create()
|
public static function create()
|
||||||
|
@@ -345,6 +345,7 @@ abstract class AbstractGrant implements GrantTypeInterface
|
|||||||
$accessToken->setIdentifier($this->generateUniqueIdentifier());
|
$accessToken->setIdentifier($this->generateUniqueIdentifier());
|
||||||
try {
|
try {
|
||||||
$this->accessTokenRepository->persistNewAccessToken($accessToken);
|
$this->accessTokenRepository->persistNewAccessToken($accessToken);
|
||||||
|
|
||||||
return $accessToken;
|
return $accessToken;
|
||||||
} catch (UniqueTokenIdentifierConstraintViolationException $e) {
|
} catch (UniqueTokenIdentifierConstraintViolationException $e) {
|
||||||
if ($maxGenerationAttempts === 0) {
|
if ($maxGenerationAttempts === 0) {
|
||||||
@@ -391,6 +392,7 @@ abstract class AbstractGrant implements GrantTypeInterface
|
|||||||
$authCode->setIdentifier($this->generateUniqueIdentifier());
|
$authCode->setIdentifier($this->generateUniqueIdentifier());
|
||||||
try {
|
try {
|
||||||
$this->authCodeRepository->persistNewAuthCode($authCode);
|
$this->authCodeRepository->persistNewAuthCode($authCode);
|
||||||
|
|
||||||
return $authCode;
|
return $authCode;
|
||||||
} catch (UniqueTokenIdentifierConstraintViolationException $e) {
|
} catch (UniqueTokenIdentifierConstraintViolationException $e) {
|
||||||
if ($maxGenerationAttempts === 0) {
|
if ($maxGenerationAttempts === 0) {
|
||||||
@@ -420,6 +422,7 @@ abstract class AbstractGrant implements GrantTypeInterface
|
|||||||
$refreshToken->setIdentifier($this->generateUniqueIdentifier());
|
$refreshToken->setIdentifier($this->generateUniqueIdentifier());
|
||||||
try {
|
try {
|
||||||
$this->refreshTokenRepository->persistNewRefreshToken($refreshToken);
|
$this->refreshTokenRepository->persistNewRefreshToken($refreshToken);
|
||||||
|
|
||||||
return $refreshToken;
|
return $refreshToken;
|
||||||
} catch (UniqueTokenIdentifierConstraintViolationException $e) {
|
} catch (UniqueTokenIdentifierConstraintViolationException $e) {
|
||||||
if ($maxGenerationAttempts === 0) {
|
if ($maxGenerationAttempts === 0) {
|
||||||
|
@@ -264,6 +264,13 @@ class AuthCodeGrant extends AbstractAuthorizeGrant
|
|||||||
throw OAuthServerException::invalidRequest('code_challenge');
|
throw OAuthServerException::invalidRequest('code_challenge');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (preg_match('/^[A-Za-z0-9-._~]{43,128}$/', $codeChallenge) !== 1) {
|
||||||
|
throw OAuthServerException::invalidRequest(
|
||||||
|
'code_challenge',
|
||||||
|
'The code_challenge must be between 43 and 128 characters'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
$codeChallengeMethod = $this->getQueryStringParameter('code_challenge_method', $request, 'plain');
|
$codeChallengeMethod = $this->getQueryStringParameter('code_challenge_method', $request, 'plain');
|
||||||
if (in_array($codeChallengeMethod, ['plain', 'S256']) === false) {
|
if (in_array($codeChallengeMethod, ['plain', 'S256']) === false) {
|
||||||
throw OAuthServerException::invalidRequest(
|
throw OAuthServerException::invalidRequest(
|
||||||
@@ -304,6 +311,31 @@ class AuthCodeGrant extends AbstractAuthorizeGrant
|
|||||||
$authorizationRequest->getScopes()
|
$authorizationRequest->getScopes()
|
||||||
);
|
);
|
||||||
|
|
||||||
|
$payload = [
|
||||||
|
'client_id' => $authCode->getClient()->getIdentifier(),
|
||||||
|
'redirect_uri' => $authCode->getRedirectUri(),
|
||||||
|
'auth_code_id' => $authCode->getIdentifier(),
|
||||||
|
'scopes' => $authCode->getScopes(),
|
||||||
|
'user_id' => $authCode->getUserIdentifier(),
|
||||||
|
'expire_time' => (new \DateTime())->add($this->authCodeTTL)->format('U'),
|
||||||
|
'code_challenge' => $authorizationRequest->getCodeChallenge(),
|
||||||
|
'code_challenge_method ' => $authorizationRequest->getCodeChallengeMethod(),
|
||||||
|
];
|
||||||
|
|
||||||
|
if ($this->encryptionKey === null) {
|
||||||
|
// Add padding to vary the length of the payload
|
||||||
|
$payload['_padding'] = base64_encode(random_bytes(mt_rand(8, 256)));
|
||||||
|
// Shuffle the payload so that the structure is no longer know and obvious
|
||||||
|
$keys = array_keys($payload);
|
||||||
|
shuffle($keys);
|
||||||
|
$shuffledPayload = [];
|
||||||
|
foreach ($keys as $key) {
|
||||||
|
$shuffledPayload[$key] = $payload[$key];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$shuffledPayload = $payload;
|
||||||
|
}
|
||||||
|
|
||||||
$response = new RedirectResponse();
|
$response = new RedirectResponse();
|
||||||
$response->setRedirectUri(
|
$response->setRedirectUri(
|
||||||
$this->makeRedirectUri(
|
$this->makeRedirectUri(
|
||||||
@@ -311,16 +343,7 @@ class AuthCodeGrant extends AbstractAuthorizeGrant
|
|||||||
[
|
[
|
||||||
'code' => $this->encrypt(
|
'code' => $this->encrypt(
|
||||||
json_encode(
|
json_encode(
|
||||||
[
|
$shuffledPayload
|
||||||
'client_id' => $authCode->getClient()->getIdentifier(),
|
|
||||||
'redirect_uri' => $authCode->getRedirectUri(),
|
|
||||||
'auth_code_id' => $authCode->getIdentifier(),
|
|
||||||
'scopes' => $authCode->getScopes(),
|
|
||||||
'user_id' => $authCode->getUserIdentifier(),
|
|
||||||
'expire_time' => (new \DateTime())->add($this->authCodeTTL)->format('U'),
|
|
||||||
'code_challenge' => $authorizationRequest->getCodeChallenge(),
|
|
||||||
'code_challenge_method ' => $authorizationRequest->getCodeChallengeMethod(),
|
|
||||||
]
|
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
'state' => $authorizationRequest->getState(),
|
'state' => $authorizationRequest->getState(),
|
||||||
|
@@ -132,4 +132,11 @@ interface GrantTypeInterface extends EmitterAwareInterface
|
|||||||
* @param CryptKey $publicKey
|
* @param CryptKey $publicKey
|
||||||
*/
|
*/
|
||||||
public function setPublicKey(CryptKey $publicKey);
|
public function setPublicKey(CryptKey $publicKey);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the encryption key
|
||||||
|
*
|
||||||
|
* @param string|null $key
|
||||||
|
*/
|
||||||
|
public function setEncryptionKey($key = null);
|
||||||
}
|
}
|
||||||
|
@@ -151,6 +151,13 @@ class ImplicitGrant extends AbstractAuthorizeGrant
|
|||||||
: $client->getRedirectUri()
|
: $client->getRedirectUri()
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Finalize the requested scopes
|
||||||
|
$scopes = $this->scopeRepository->finalizeScopes(
|
||||||
|
$scopes,
|
||||||
|
$this->getIdentifier(),
|
||||||
|
$client
|
||||||
|
);
|
||||||
|
|
||||||
$stateParameter = $this->getQueryStringParameter('state', $request);
|
$stateParameter = $this->getQueryStringParameter('state', $request);
|
||||||
|
|
||||||
$authorizationRequest = new AuthorizationRequest();
|
$authorizationRequest = new AuthorizationRequest();
|
||||||
|
@@ -102,7 +102,7 @@ class RefreshTokenGrant extends AbstractGrant
|
|||||||
// Validate refresh token
|
// Validate refresh token
|
||||||
try {
|
try {
|
||||||
$refreshToken = $this->decrypt($encryptedRefreshToken);
|
$refreshToken = $this->decrypt($encryptedRefreshToken);
|
||||||
} catch (\LogicException $e) {
|
} catch (\Exception $e) {
|
||||||
throw OAuthServerException::invalidRefreshToken('Cannot decrypt the refresh token');
|
throw OAuthServerException::invalidRefreshToken('Cannot decrypt the refresh token');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -66,12 +66,14 @@ class AuthorizationRequest
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* The code challenge (if provided)
|
* The code challenge (if provided)
|
||||||
|
*
|
||||||
* @var string
|
* @var string
|
||||||
*/
|
*/
|
||||||
protected $codeChallenge;
|
protected $codeChallenge;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The code challenge method (if provided)
|
* The code challenge method (if provided)
|
||||||
|
*
|
||||||
* @var string
|
* @var string
|
||||||
*/
|
*/
|
||||||
protected $codeChallengeMethod;
|
protected $codeChallengeMethod;
|
||||||
|
@@ -68,6 +68,7 @@ class BearerTokenResponse extends AbstractResponseType
|
|||||||
* this class rather than the default.
|
* this class rather than the default.
|
||||||
*
|
*
|
||||||
* @param AccessTokenEntityInterface $accessToken
|
* @param AccessTokenEntityInterface $accessToken
|
||||||
|
*
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
protected function getExtraParams(AccessTokenEntityInterface $accessToken)
|
protected function getExtraParams(AccessTokenEntityInterface $accessToken)
|
||||||
|
@@ -33,4 +33,11 @@ interface ResponseTypeInterface
|
|||||||
* @return ResponseInterface
|
* @return ResponseInterface
|
||||||
*/
|
*/
|
||||||
public function generateHttpResponse(ResponseInterface $response);
|
public function generateHttpResponse(ResponseInterface $response);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the encryption key
|
||||||
|
*
|
||||||
|
* @param string|null $key
|
||||||
|
*/
|
||||||
|
public function setEncryptionKey($key = null);
|
||||||
}
|
}
|
||||||
|
@@ -36,6 +36,7 @@ class AuthorizationServerTest extends \PHPUnit_Framework_TestCase
|
|||||||
'file://' . __DIR__ . '/Stubs/public.key',
|
'file://' . __DIR__ . '/Stubs/public.key',
|
||||||
new StubResponseType()
|
new StubResponseType()
|
||||||
);
|
);
|
||||||
|
$server->setEncryptionKey(base64_encode(random_bytes(36)));
|
||||||
|
|
||||||
$server->enableGrantType(new ClientCredentialsGrant(), new \DateInterval('PT1M'));
|
$server->enableGrantType(new ClientCredentialsGrant(), new \DateInterval('PT1M'));
|
||||||
|
|
||||||
@@ -66,6 +67,7 @@ class AuthorizationServerTest extends \PHPUnit_Framework_TestCase
|
|||||||
'file://' . __DIR__ . '/Stubs/public.key',
|
'file://' . __DIR__ . '/Stubs/public.key',
|
||||||
new StubResponseType()
|
new StubResponseType()
|
||||||
);
|
);
|
||||||
|
$server->setEncryptionKey(base64_encode(random_bytes(36)));
|
||||||
|
|
||||||
$server->enableGrantType(new ClientCredentialsGrant(), new \DateInterval('PT1M'));
|
$server->enableGrantType(new ClientCredentialsGrant(), new \DateInterval('PT1M'));
|
||||||
|
|
||||||
@@ -87,6 +89,7 @@ class AuthorizationServerTest extends \PHPUnit_Framework_TestCase
|
|||||||
'file://' . __DIR__ . '/Stubs/private.key',
|
'file://' . __DIR__ . '/Stubs/private.key',
|
||||||
'file://' . __DIR__ . '/Stubs/public.key'
|
'file://' . __DIR__ . '/Stubs/public.key'
|
||||||
);
|
);
|
||||||
|
$server->setEncryptionKey(base64_encode(random_bytes(36)));
|
||||||
|
|
||||||
$abstractGrantReflection = new \ReflectionClass($server);
|
$abstractGrantReflection = new \ReflectionClass($server);
|
||||||
$method = $abstractGrantReflection->getMethod('getResponseType');
|
$method = $abstractGrantReflection->getMethod('getResponseType');
|
||||||
@@ -106,6 +109,7 @@ class AuthorizationServerTest extends \PHPUnit_Framework_TestCase
|
|||||||
'file://' . __DIR__ . '/Stubs/private.key',
|
'file://' . __DIR__ . '/Stubs/private.key',
|
||||||
'file://' . __DIR__ . '/Stubs/public.key'
|
'file://' . __DIR__ . '/Stubs/public.key'
|
||||||
);
|
);
|
||||||
|
$server->setEncryptionKey(base64_encode(random_bytes(36)));
|
||||||
|
|
||||||
$authCodeRepository = $this->getMockBuilder(AuthCodeRepositoryInterface::class)->getMock();
|
$authCodeRepository = $this->getMockBuilder(AuthCodeRepositoryInterface::class)->getMock();
|
||||||
$authCodeRepository->method('getNewAuthCode')->willReturn(new AuthCodeEntity());
|
$authCodeRepository->method('getNewAuthCode')->willReturn(new AuthCodeEntity());
|
||||||
@@ -152,6 +156,7 @@ class AuthorizationServerTest extends \PHPUnit_Framework_TestCase
|
|||||||
'file://' . __DIR__ . '/Stubs/private.key',
|
'file://' . __DIR__ . '/Stubs/private.key',
|
||||||
'file://' . __DIR__ . '/Stubs/public.key'
|
'file://' . __DIR__ . '/Stubs/public.key'
|
||||||
);
|
);
|
||||||
|
$server->setEncryptionKey(base64_encode(random_bytes(36)));
|
||||||
$server->enableGrantType($grant);
|
$server->enableGrantType($grant);
|
||||||
|
|
||||||
$request = new ServerRequest(
|
$request = new ServerRequest(
|
||||||
@@ -184,6 +189,7 @@ class AuthorizationServerTest extends \PHPUnit_Framework_TestCase
|
|||||||
'file://' . __DIR__ . '/Stubs/private.key',
|
'file://' . __DIR__ . '/Stubs/private.key',
|
||||||
'file://' . __DIR__ . '/Stubs/public.key'
|
'file://' . __DIR__ . '/Stubs/public.key'
|
||||||
);
|
);
|
||||||
|
$server->setEncryptionKey(base64_encode(random_bytes(36)));
|
||||||
|
|
||||||
$request = new ServerRequest(
|
$request = new ServerRequest(
|
||||||
[],
|
[],
|
||||||
|
@@ -137,7 +137,6 @@ class AuthCodeGrantTest extends \PHPUnit_Framework_TestCase
|
|||||||
$this->assertTrue($grant->validateAuthorizationRequest($request) instanceof AuthorizationRequest);
|
$this->assertTrue($grant->validateAuthorizationRequest($request) instanceof AuthorizationRequest);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public function testValidateAuthorizationRequestCodeChallenge()
|
public function testValidateAuthorizationRequestCodeChallenge()
|
||||||
{
|
{
|
||||||
$client = new ClientEntity();
|
$client = new ClientEntity();
|
||||||
@@ -165,13 +164,124 @@ class AuthCodeGrantTest extends \PHPUnit_Framework_TestCase
|
|||||||
'response_type' => 'code',
|
'response_type' => 'code',
|
||||||
'client_id' => 'foo',
|
'client_id' => 'foo',
|
||||||
'redirect_uri' => 'http://foo/bar',
|
'redirect_uri' => 'http://foo/bar',
|
||||||
'code_challenge' => 'FOOBAR',
|
'code_challenge' => str_repeat('A', 43),
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
|
|
||||||
$this->assertTrue($grant->validateAuthorizationRequest($request) instanceof AuthorizationRequest);
|
$this->assertTrue($grant->validateAuthorizationRequest($request) instanceof AuthorizationRequest);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @expectedException \League\OAuth2\Server\Exception\OAuthServerException
|
||||||
|
*/
|
||||||
|
public function testValidateAuthorizationRequestCodeChallengeInvalidLengthTooShort()
|
||||||
|
{
|
||||||
|
$client = new ClientEntity();
|
||||||
|
$client->setRedirectUri('http://foo/bar');
|
||||||
|
$clientRepositoryMock = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock();
|
||||||
|
$clientRepositoryMock->method('getClientEntity')->willReturn($client);
|
||||||
|
|
||||||
|
$grant = new AuthCodeGrant(
|
||||||
|
$this->getMockBuilder(AuthCodeRepositoryInterface::class)->getMock(),
|
||||||
|
$this->getMockBuilder(RefreshTokenRepositoryInterface::class)->getMock(),
|
||||||
|
new \DateInterval('PT10M')
|
||||||
|
);
|
||||||
|
$grant->enableCodeExchangeProof();
|
||||||
|
$grant->setClientRepository($clientRepositoryMock);
|
||||||
|
|
||||||
|
$request = new ServerRequest(
|
||||||
|
[],
|
||||||
|
[],
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
'php://input',
|
||||||
|
[],
|
||||||
|
[],
|
||||||
|
[
|
||||||
|
'response_type' => 'code',
|
||||||
|
'client_id' => 'foo',
|
||||||
|
'redirect_uri' => 'http://foo/bar',
|
||||||
|
'code_challenge' => str_repeat('A', 42),
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
|
$grant->validateAuthorizationRequest($request);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @expectedException \League\OAuth2\Server\Exception\OAuthServerException
|
||||||
|
*/
|
||||||
|
public function testValidateAuthorizationRequestCodeChallengeInvalidLengthTooLong()
|
||||||
|
{
|
||||||
|
$client = new ClientEntity();
|
||||||
|
$client->setRedirectUri('http://foo/bar');
|
||||||
|
$clientRepositoryMock = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock();
|
||||||
|
$clientRepositoryMock->method('getClientEntity')->willReturn($client);
|
||||||
|
|
||||||
|
$grant = new AuthCodeGrant(
|
||||||
|
$this->getMockBuilder(AuthCodeRepositoryInterface::class)->getMock(),
|
||||||
|
$this->getMockBuilder(RefreshTokenRepositoryInterface::class)->getMock(),
|
||||||
|
new \DateInterval('PT10M')
|
||||||
|
);
|
||||||
|
$grant->enableCodeExchangeProof();
|
||||||
|
$grant->setClientRepository($clientRepositoryMock);
|
||||||
|
|
||||||
|
$request = new ServerRequest(
|
||||||
|
[],
|
||||||
|
[],
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
'php://input',
|
||||||
|
[],
|
||||||
|
[],
|
||||||
|
[
|
||||||
|
'response_type' => 'code',
|
||||||
|
'client_id' => 'foo',
|
||||||
|
'redirect_uri' => 'http://foo/bar',
|
||||||
|
'code_challenge' => str_repeat('A', 129),
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
|
$grant->validateAuthorizationRequest($request);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @expectedException \League\OAuth2\Server\Exception\OAuthServerException
|
||||||
|
*/
|
||||||
|
public function testValidateAuthorizationRequestCodeChallengeInvalidCharacters()
|
||||||
|
{
|
||||||
|
$client = new ClientEntity();
|
||||||
|
$client->setRedirectUri('http://foo/bar');
|
||||||
|
$clientRepositoryMock = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock();
|
||||||
|
$clientRepositoryMock->method('getClientEntity')->willReturn($client);
|
||||||
|
|
||||||
|
$grant = new AuthCodeGrant(
|
||||||
|
$this->getMockBuilder(AuthCodeRepositoryInterface::class)->getMock(),
|
||||||
|
$this->getMockBuilder(RefreshTokenRepositoryInterface::class)->getMock(),
|
||||||
|
new \DateInterval('PT10M')
|
||||||
|
);
|
||||||
|
$grant->enableCodeExchangeProof();
|
||||||
|
$grant->setClientRepository($clientRepositoryMock);
|
||||||
|
|
||||||
|
$request = new ServerRequest(
|
||||||
|
[],
|
||||||
|
[],
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
'php://input',
|
||||||
|
[],
|
||||||
|
[],
|
||||||
|
[
|
||||||
|
'response_type' => 'code',
|
||||||
|
'client_id' => 'foo',
|
||||||
|
'redirect_uri' => 'http://foo/bar',
|
||||||
|
'code_challenge' => str_repeat('A', 42) . '!',
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
|
$grant->validateAuthorizationRequest($request);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @expectedException \League\OAuth2\Server\Exception\OAuthServerException
|
* @expectedException \League\OAuth2\Server\Exception\OAuthServerException
|
||||||
* @expectedExceptionCode 3
|
* @expectedExceptionCode 3
|
||||||
|
@@ -9,11 +9,13 @@ use League\OAuth2\Server\Grant\ImplicitGrant;
|
|||||||
use League\OAuth2\Server\Repositories\AccessTokenRepositoryInterface;
|
use League\OAuth2\Server\Repositories\AccessTokenRepositoryInterface;
|
||||||
use League\OAuth2\Server\Repositories\ClientRepositoryInterface;
|
use League\OAuth2\Server\Repositories\ClientRepositoryInterface;
|
||||||
use League\OAuth2\Server\Repositories\RefreshTokenRepositoryInterface;
|
use League\OAuth2\Server\Repositories\RefreshTokenRepositoryInterface;
|
||||||
|
use League\OAuth2\Server\Repositories\ScopeRepositoryInterface;
|
||||||
use League\OAuth2\Server\RequestTypes\AuthorizationRequest;
|
use League\OAuth2\Server\RequestTypes\AuthorizationRequest;
|
||||||
use League\OAuth2\Server\ResponseTypes\RedirectResponse;
|
use League\OAuth2\Server\ResponseTypes\RedirectResponse;
|
||||||
use LeagueTests\Stubs\AccessTokenEntity;
|
use LeagueTests\Stubs\AccessTokenEntity;
|
||||||
use LeagueTests\Stubs\ClientEntity;
|
use LeagueTests\Stubs\ClientEntity;
|
||||||
use LeagueTests\Stubs\CryptTraitStub;
|
use LeagueTests\Stubs\CryptTraitStub;
|
||||||
|
use LeagueTests\Stubs\ScopeEntity;
|
||||||
use LeagueTests\Stubs\StubResponseType;
|
use LeagueTests\Stubs\StubResponseType;
|
||||||
use LeagueTests\Stubs\UserEntity;
|
use LeagueTests\Stubs\UserEntity;
|
||||||
use Zend\Diactoros\ServerRequest;
|
use Zend\Diactoros\ServerRequest;
|
||||||
@@ -86,8 +88,14 @@ class ImplicitGrantTest extends \PHPUnit_Framework_TestCase
|
|||||||
$clientRepositoryMock = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock();
|
$clientRepositoryMock = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock();
|
||||||
$clientRepositoryMock->method('getClientEntity')->willReturn($client);
|
$clientRepositoryMock->method('getClientEntity')->willReturn($client);
|
||||||
|
|
||||||
|
$scopeRepositoryMock = $this->getMockBuilder(ScopeRepositoryInterface::class)->getMock();
|
||||||
|
$scopeEntity = new ScopeEntity();
|
||||||
|
$scopeRepositoryMock->method('getScopeEntityByIdentifier')->willReturn($scopeEntity);
|
||||||
|
$scopeRepositoryMock->method('finalizeScopes')->willReturnArgument(0);
|
||||||
|
|
||||||
$grant = new ImplicitGrant(new \DateInterval('PT10M'));
|
$grant = new ImplicitGrant(new \DateInterval('PT10M'));
|
||||||
$grant->setClientRepository($clientRepositoryMock);
|
$grant->setClientRepository($clientRepositoryMock);
|
||||||
|
$grant->setScopeRepository($scopeRepositoryMock);
|
||||||
|
|
||||||
$request = new ServerRequest(
|
$request = new ServerRequest(
|
||||||
[],
|
[],
|
||||||
@@ -114,8 +122,14 @@ class ImplicitGrantTest extends \PHPUnit_Framework_TestCase
|
|||||||
$clientRepositoryMock = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock();
|
$clientRepositoryMock = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock();
|
||||||
$clientRepositoryMock->method('getClientEntity')->willReturn($client);
|
$clientRepositoryMock->method('getClientEntity')->willReturn($client);
|
||||||
|
|
||||||
|
$scopeRepositoryMock = $this->getMockBuilder(ScopeRepositoryInterface::class)->getMock();
|
||||||
|
$scopeEntity = new ScopeEntity();
|
||||||
|
$scopeRepositoryMock->method('getScopeEntityByIdentifier')->willReturn($scopeEntity);
|
||||||
|
$scopeRepositoryMock->method('finalizeScopes')->willReturnArgument(0);
|
||||||
|
|
||||||
$grant = new ImplicitGrant(new \DateInterval('PT10M'));
|
$grant = new ImplicitGrant(new \DateInterval('PT10M'));
|
||||||
$grant->setClientRepository($clientRepositoryMock);
|
$grant->setClientRepository($clientRepositoryMock);
|
||||||
|
$grant->setScopeRepository($scopeRepositoryMock);
|
||||||
|
|
||||||
$request = new ServerRequest(
|
$request = new ServerRequest(
|
||||||
[],
|
[],
|
||||||
|
@@ -36,6 +36,7 @@ class AuthorizationServerMiddlewareTest extends \PHPUnit_Framework_TestCase
|
|||||||
'file://' . __DIR__ . '/../Stubs/public.key',
|
'file://' . __DIR__ . '/../Stubs/public.key',
|
||||||
new StubResponseType()
|
new StubResponseType()
|
||||||
);
|
);
|
||||||
|
$server->setEncryptionKey(base64_encode(random_bytes(36)));
|
||||||
|
|
||||||
$server->enableGrantType(new ClientCredentialsGrant());
|
$server->enableGrantType(new ClientCredentialsGrant());
|
||||||
|
|
||||||
@@ -69,6 +70,7 @@ class AuthorizationServerMiddlewareTest extends \PHPUnit_Framework_TestCase
|
|||||||
'file://' . __DIR__ . '/../Stubs/public.key',
|
'file://' . __DIR__ . '/../Stubs/public.key',
|
||||||
new StubResponseType()
|
new StubResponseType()
|
||||||
);
|
);
|
||||||
|
$server->setEncryptionKey(base64_encode(random_bytes(36)));
|
||||||
|
|
||||||
$server->enableGrantType(new ClientCredentialsGrant(), new \DateInterval('PT1M'));
|
$server->enableGrantType(new ClientCredentialsGrant(), new \DateInterval('PT1M'));
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user