blob: 54c5f9a63002c82f1509c442dc114f295c4fffd5 [file] [log] [blame]
Matthias Andreas Benkardb382b102021-01-02 15:32:21 +01001<?php
2
3namespace OAuth2\OpenID\Controller;
4
5use OAuth2\Controller\AuthorizeController as BaseAuthorizeController;
6use OAuth2\RequestInterface;
7use OAuth2\ResponseInterface;
8
9/**
10 * @see OAuth2\Controller\AuthorizeControllerInterface
11 */
12class AuthorizeController extends BaseAuthorizeController implements AuthorizeControllerInterface
13{
14 /**
15 * @var mixed
16 */
17 private $nonce;
18
19 /**
20 * Set not authorized response
21 *
22 * @param RequestInterface $request
23 * @param ResponseInterface $response
24 * @param string $redirect_uri
25 * @param null $user_id
26 */
27 protected function setNotAuthorizedResponse(RequestInterface $request, ResponseInterface $response, $redirect_uri, $user_id = null)
28 {
29 $prompt = $request->query('prompt', 'consent');
30 if ($prompt == 'none') {
31 if (is_null($user_id)) {
32 $error = 'login_required';
33 $error_message = 'The user must log in';
34 } else {
35 $error = 'interaction_required';
36 $error_message = 'The user must grant access to your application';
37 }
38 } else {
39 $error = 'consent_required';
40 $error_message = 'The user denied access to your application';
41 }
42
43 $response->setRedirect($this->config['redirect_status_code'], $redirect_uri, $this->getState(), $error, $error_message);
44 }
45
46 /**
47 * @TODO: add dependency injection for the parameters in this method
48 *
49 * @param RequestInterface $request
50 * @param ResponseInterface $response
51 * @param mixed $user_id
52 * @return array
53 */
54 protected function buildAuthorizeParameters($request, $response, $user_id)
55 {
56 if (!$params = parent::buildAuthorizeParameters($request, $response, $user_id)) {
57 return;
58 }
59
60 // Generate an id token if needed.
61 if ($this->needsIdToken($this->getScope()) && $this->getResponseType() == self::RESPONSE_TYPE_AUTHORIZATION_CODE) {
62 $params['id_token'] = $this->responseTypes['id_token']->createIdToken($this->getClientId(), $user_id, $this->nonce);
63 }
64
65 // add the nonce to return with the redirect URI
66 $params['nonce'] = $this->nonce;
67
68 return $params;
69 }
70
71 /**
72 * @param RequestInterface $request
73 * @param ResponseInterface $response
74 * @return bool
75 */
76 public function validateAuthorizeRequest(RequestInterface $request, ResponseInterface $response)
77 {
78 if (!parent::validateAuthorizeRequest($request, $response)) {
79 return false;
80 }
81
82 $nonce = $request->query('nonce');
83
84 // Validate required nonce for "id_token" and "id_token token"
85 if (!$nonce && in_array($this->getResponseType(), array(self::RESPONSE_TYPE_ID_TOKEN, self::RESPONSE_TYPE_ID_TOKEN_TOKEN))) {
86 $response->setError(400, 'invalid_nonce', 'This application requires you specify a nonce parameter');
87
88 return false;
89 }
90
91 $this->nonce = $nonce;
92
93 return true;
94 }
95
96 /**
97 * Array of valid response types
98 *
99 * @return array
100 */
101 protected function getValidResponseTypes()
102 {
103 return array(
104 self::RESPONSE_TYPE_ACCESS_TOKEN,
105 self::RESPONSE_TYPE_AUTHORIZATION_CODE,
106 self::RESPONSE_TYPE_ID_TOKEN,
107 self::RESPONSE_TYPE_ID_TOKEN_TOKEN,
108 self::RESPONSE_TYPE_CODE_ID_TOKEN,
109 );
110 }
111
112 /**
113 * Returns whether the current request needs to generate an id token.
114 *
115 * ID Tokens are a part of the OpenID Connect specification, so this
116 * method checks whether OpenID Connect is enabled in the server settings
117 * and whether the openid scope was requested.
118 *
119 * @param string $request_scope - A space-separated string of scopes.
120 * @return boolean - TRUE if an id token is needed, FALSE otherwise.
121 */
122 public function needsIdToken($request_scope)
123 {
124 // see if the "openid" scope exists in the requested scope
125 return $this->scopeUtil->checkScope('openid', $request_scope);
126 }
127
128 /**
129 * @return mixed
130 */
131 public function getNonce()
132 {
133 return $this->nonce;
134 }
135}