This commit is contained in:
2022-06-13 23:37:17 +08:00
parent d21608a860
commit 0230cb42a2
153 changed files with 62907 additions and 0 deletions

View File

@@ -0,0 +1,135 @@
<?php
namespace OAuth2\OpenID\Controller;
use OAuth2\Controller\AuthorizeController as BaseAuthorizeController;
use OAuth2\RequestInterface;
use OAuth2\ResponseInterface;
/**
* @see OAuth2\Controller\AuthorizeControllerInterface
*/
class AuthorizeController extends BaseAuthorizeController implements AuthorizeControllerInterface
{
/**
* @var mixed
*/
private $nonce;
/**
* Set not authorized response
*
* @param RequestInterface $request
* @param ResponseInterface $response
* @param string $redirect_uri
* @param null $user_id
*/
protected function setNotAuthorizedResponse(RequestInterface $request, ResponseInterface $response, $redirect_uri, $user_id = null)
{
$prompt = $request->query('prompt', 'consent');
if ($prompt == 'none') {
if (is_null($user_id)) {
$error = 'login_required';
$error_message = 'The user must log in';
} else {
$error = 'interaction_required';
$error_message = 'The user must grant access to your application';
}
} else {
$error = 'consent_required';
$error_message = 'The user denied access to your application';
}
$response->setRedirect($this->config['redirect_status_code'], $redirect_uri, $this->getState(), $error, $error_message);
}
/**
* @TODO: add dependency injection for the parameters in this method
*
* @param RequestInterface $request
* @param ResponseInterface $response
* @param mixed $user_id
* @return array
*/
protected function buildAuthorizeParameters($request, $response, $user_id)
{
if (!$params = parent::buildAuthorizeParameters($request, $response, $user_id)) {
return;
}
// Generate an id token if needed.
if ($this->needsIdToken($this->getScope()) && $this->getResponseType() == self::RESPONSE_TYPE_AUTHORIZATION_CODE) {
$params['id_token'] = $this->responseTypes['id_token']->createIdToken($this->getClientId(), $user_id, $this->nonce);
}
// add the nonce to return with the redirect URI
$params['nonce'] = $this->nonce;
return $params;
}
/**
* @param RequestInterface $request
* @param ResponseInterface $response
* @return bool
*/
public function validateAuthorizeRequest(RequestInterface $request, ResponseInterface $response)
{
if (!parent::validateAuthorizeRequest($request, $response)) {
return false;
}
$nonce = $request->query('nonce');
// Validate required nonce for "id_token" and "id_token token"
if (!$nonce && in_array($this->getResponseType(), array(self::RESPONSE_TYPE_ID_TOKEN, self::RESPONSE_TYPE_ID_TOKEN_TOKEN))) {
$response->setError(400, 'invalid_nonce', 'This application requires you specify a nonce parameter');
return false;
}
$this->nonce = $nonce;
return true;
}
/**
* Array of valid response types
*
* @return array
*/
protected function getValidResponseTypes()
{
return array(
self::RESPONSE_TYPE_ACCESS_TOKEN,
self::RESPONSE_TYPE_AUTHORIZATION_CODE,
self::RESPONSE_TYPE_ID_TOKEN,
self::RESPONSE_TYPE_ID_TOKEN_TOKEN,
self::RESPONSE_TYPE_CODE_ID_TOKEN,
);
}
/**
* Returns whether the current request needs to generate an id token.
*
* ID Tokens are a part of the OpenID Connect specification, so this
* method checks whether OpenID Connect is enabled in the server settings
* and whether the openid scope was requested.
*
* @param string $request_scope - A space-separated string of scopes.
* @return boolean - TRUE if an id token is needed, FALSE otherwise.
*/
public function needsIdToken($request_scope)
{
// see if the "openid" scope exists in the requested scope
return $this->scopeUtil->checkScope('openid', $request_scope);
}
/**
* @return mixed
*/
public function getNonce()
{
return $this->nonce;
}
}

View File

@@ -0,0 +1,12 @@
<?php
namespace OAuth2\OpenID\Controller;
interface AuthorizeControllerInterface
{
const RESPONSE_TYPE_ID_TOKEN = 'id_token';
const RESPONSE_TYPE_ID_TOKEN_TOKEN = 'id_token token';
const RESPONSE_TYPE_CODE_ID_TOKEN = 'code id_token';
}

View File

@@ -0,0 +1,62 @@
<?php
namespace OAuth2\OpenID\Controller;
use OAuth2\Scope;
use OAuth2\TokenType\TokenTypeInterface;
use OAuth2\Storage\AccessTokenInterface;
use OAuth2\OpenID\Storage\UserClaimsInterface;
use OAuth2\Controller\ResourceController;
use OAuth2\ScopeInterface;
use OAuth2\RequestInterface;
use OAuth2\ResponseInterface;
/**
* @see OAuth2\Controller\UserInfoControllerInterface
*/
class UserInfoController extends ResourceController implements UserInfoControllerInterface
{
/**
* @var UserClaimsInterface
*/
protected $userClaimsStorage;
/**
* Constructor
*
* @param TokenTypeInterface $tokenType
* @param AccessTokenInterface $tokenStorage
* @param UserClaimsInterface $userClaimsStorage
* @param array $config
* @param ScopeInterface $scopeUtil
*/
public function __construct(TokenTypeInterface $tokenType, AccessTokenInterface $tokenStorage, UserClaimsInterface $userClaimsStorage, $config = array(), ScopeInterface $scopeUtil = null)
{
parent::__construct($tokenType, $tokenStorage, $config, $scopeUtil);
$this->userClaimsStorage = $userClaimsStorage;
}
/**
* Handle the user info request
*
* @param RequestInterface $request
* @param ResponseInterface $response
* @return void
*/
public function handleUserInfoRequest(RequestInterface $request, ResponseInterface $response)
{
if (!$this->verifyResourceRequest($request, $response, 'openid')) {
return;
}
$token = $this->getToken();
$claims = $this->userClaimsStorage->getUserClaims($token['user_id'], $token['scope']);
// The sub Claim MUST always be returned in the UserInfo Response.
// http://openid.net/specs/openid-connect-core-1_0.html#UserInfoResponse
$claims += array(
'sub' => $token['user_id'],
);
$response->addParameters($claims);
}
}

View File

@@ -0,0 +1,30 @@
<?php
namespace OAuth2\OpenID\Controller;
use OAuth2\RequestInterface;
use OAuth2\ResponseInterface;
/**
* This controller is called when the user claims for OpenID Connect's
* UserInfo endpoint should be returned.
*
* @code
* $response = new OAuth2\Response();
* $userInfoController->handleUserInfoRequest(
* OAuth2\Request::createFromGlobals(),
* $response
* );
* $response->send();
* @endcode
*/
interface UserInfoControllerInterface
{
/**
* Handle user info request
*
* @param RequestInterface $request
* @param ResponseInterface $response
*/
public function handleUserInfoRequest(RequestInterface $request, ResponseInterface $response);
}