Add OAuth state to session

Signed-off-by: Lukas Reschke <lukas@statuscode.ch>
This commit is contained in:
Lukas Reschke 2017-05-18 15:43:14 +02:00
parent 88afd8b224
commit b07a0f51ba
No known key found for this signature in database
GPG Key ID: B9F6980CF6E759B1
2 changed files with 27 additions and 32 deletions

View File

@ -25,6 +25,7 @@ use OCA\OAuth2\Db\ClientMapper;
use OCP\AppFramework\Controller; use OCP\AppFramework\Controller;
use OCP\AppFramework\Http\RedirectResponse; use OCP\AppFramework\Http\RedirectResponse;
use OCP\IRequest; use OCP\IRequest;
use OCP\ISession;
use OCP\IURLGenerator; use OCP\IURLGenerator;
class LoginRedirectorController extends Controller { class LoginRedirectorController extends Controller {
@ -32,45 +33,45 @@ class LoginRedirectorController extends Controller {
private $urlGenerator; private $urlGenerator;
/** @var ClientMapper */ /** @var ClientMapper */
private $clientMapper; private $clientMapper;
/** @var ISession */
private $session;
/** /**
* @param string $appName * @param string $appName
* @param IRequest $request * @param IRequest $request
* @param IURLGenerator $urlGenerator * @param IURLGenerator $urlGenerator
* @param ClientMapper $clientMapper * @param ClientMapper $clientMapper
* @param ISession $session
*/ */
public function __construct($appName, public function __construct($appName,
IRequest $request, IRequest $request,
IURLGenerator $urlGenerator, IURLGenerator $urlGenerator,
ClientMapper $clientMapper) { ClientMapper $clientMapper,
ISession $session) {
parent::__construct($appName, $request); parent::__construct($appName, $request);
$this->urlGenerator = $urlGenerator; $this->urlGenerator = $urlGenerator;
$this->clientMapper = $clientMapper; $this->clientMapper = $clientMapper;
$this->session = $session;
} }
/** /**
* @PublicPage * @PublicPage
* @NoCSRFRequired * @NoCSRFRequired
* @UseSession
* *
* @param string $client_id * @param string $client_id
* @param string $redirect_uri
* @param string $state * @param string $state
* @return RedirectResponse * @return RedirectResponse
*/ */
public function authorize($client_id, public function authorize($client_id,
$redirect_uri,
$state) { $state) {
$client = $this->clientMapper->getByIdentifier($client_id); $client = $this->clientMapper->getByIdentifier($client_id);
$this->session->set('oauth.state', $state);
if($client->getRedirectUri() !== $redirect_uri) {
throw new \Exception('Redirect URI does not match');
}
$targetUrl = $this->urlGenerator->linkToRouteAbsolute( $targetUrl = $this->urlGenerator->linkToRouteAbsolute(
'core.ClientFlowLogin.showAuthPickerPage', 'core.ClientFlowLogin.showAuthPickerPage',
[ [
'clientIdentifier' => $client->getClientIdentifier(), 'clientIdentifier' => $client->getClientIdentifier(),
'oauthState' => $state,
] ]
); );
return new RedirectResponse($targetUrl); return new RedirectResponse($targetUrl);

View File

@ -149,10 +149,7 @@ class ClientFlowLoginController extends Controller {
* *
* @return TemplateResponse * @return TemplateResponse
*/ */
public function showAuthPickerPage($clientIdentifier = '', public function showAuthPickerPage($clientIdentifier = '') {
$oauthState = '') {
$clientName = $this->getClientName(); $clientName = $this->getClientName();
$client = null; $client = null;
if($clientIdentifier !== '') { if($clientIdentifier !== '') {
@ -160,19 +157,22 @@ class ClientFlowLoginController extends Controller {
$clientName = $client->getName(); $clientName = $client->getName();
} }
$validClient = $client !== null && $client->getClientIdentifier() !== null; // No valid clientIdentifier given and no valid API Request (APIRequest header not set)
$cookieCheckSuccessful = $this->request->passesStrictCookieCheck(); $clientRequest = $this->request->getHeader('OCS-APIREQUEST');
if ($clientRequest !== 'true' && $client === null) {
// no valid clientIdentifier given and no valid API Request (APIRequest header not set)
if ($cookieCheckSuccessful === false && $validClient === false) {
return new TemplateResponse( return new TemplateResponse(
$this->appName, $this->appName,
'error', 'error',
['errors' => [
'errors' =>
[ [
['error' => 'Access Forbidden', 'hint' => 'Invalid request'] [
] 'error' => 'Access Forbidden',
] 'hint' => 'Invalid request',
],
],
],
'guest'
); );
} }
@ -188,7 +188,6 @@ class ClientFlowLoginController extends Controller {
[ [
'client' => $clientName, 'client' => $clientName,
'clientIdentifier' => $clientIdentifier, 'clientIdentifier' => $clientIdentifier,
'oauthState' => $oauthState,
'instanceName' => $this->defaults->getName(), 'instanceName' => $this->defaults->getName(),
'urlGenerator' => $this->urlGenerator, 'urlGenerator' => $this->urlGenerator,
'stateToken' => $stateToken, 'stateToken' => $stateToken,
@ -205,12 +204,10 @@ class ClientFlowLoginController extends Controller {
* *
* @param string $stateToken * @param string $stateToken
* @param string $clientIdentifier * @param string $clientIdentifier
* @param string $oauthState
* @return TemplateResponse * @return TemplateResponse
*/ */
public function redirectPage($stateToken = '', public function redirectPage($stateToken = '',
$clientIdentifier = '', $clientIdentifier = '') {
$oauthState = '') {
if(!$this->isValidToken($stateToken)) { if(!$this->isValidToken($stateToken)) {
return $this->stateTokenForbiddenResponse(); return $this->stateTokenForbiddenResponse();
} }
@ -222,7 +219,7 @@ class ClientFlowLoginController extends Controller {
'urlGenerator' => $this->urlGenerator, 'urlGenerator' => $this->urlGenerator,
'stateToken' => $stateToken, 'stateToken' => $stateToken,
'clientIdentifier' => $clientIdentifier, 'clientIdentifier' => $clientIdentifier,
'oauthState' => $oauthState, 'oauthState' => $this->session->get('oauth.state'),
], ],
'empty' 'empty'
); );
@ -234,14 +231,10 @@ class ClientFlowLoginController extends Controller {
* *
* @param string $stateToken * @param string $stateToken
* @param string $clientIdentifier * @param string $clientIdentifier
* @param string $state
* @param string $oauthState
* @return Http\RedirectResponse|Response * @return Http\RedirectResponse|Response
*/ */
public function generateAppPassword($stateToken, public function generateAppPassword($stateToken,
$clientIdentifier = '', $clientIdentifier = '') {
$state = '',
$oauthState = '') {
if(!$this->isValidToken($stateToken)) { if(!$this->isValidToken($stateToken)) {
$this->session->remove(self::stateName); $this->session->remove(self::stateName);
return $this->stateTokenForbiddenResponse(); return $this->stateTokenForbiddenResponse();
@ -305,9 +298,10 @@ class ClientFlowLoginController extends Controller {
$redirectUri = sprintf( $redirectUri = sprintf(
'%s?state=%s&code=%s', '%s?state=%s&code=%s',
$client->getRedirectUri(), $client->getRedirectUri(),
urlencode($oauthState), urlencode($this->session->get('oauth.state')),
urlencode($code) urlencode($code)
); );
$this->session->remove('oauth.state');
} else { } else {
$redirectUri = 'nc://login/server:' . $this->request->getServerHost() . '&user:' . urlencode($loginName) . '&password:' . urlencode($token); $redirectUri = 'nc://login/server:' . $this->request->getServerHost() . '&user:' . urlencode($loginName) . '&password:' . urlencode($token);
} }