appserver-io /
authenticator
| 1 | <?php |
||||||
| 2 | |||||||
| 3 | /** |
||||||
| 4 | * AppserverIo\Authenticator\BearerAuthenticator |
||||||
| 5 | * |
||||||
| 6 | * NOTICE OF LICENSE |
||||||
| 7 | * |
||||||
| 8 | * This source file is subject to the Open Software License (OSL 3.0) |
||||||
| 9 | * that is available through the world-wide-web at this URL: |
||||||
| 10 | * http://opensource.org/licenses/osl-3.0.php |
||||||
| 11 | * |
||||||
| 12 | * PHP version 5 |
||||||
| 13 | * |
||||||
| 14 | * @author Tim Wagner <[email protected]> |
||||||
| 15 | * @copyright 2016 TechDivision GmbH <[email protected]> |
||||||
| 16 | * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) |
||||||
| 17 | * @link https://github.com/appserver-io/authenticator |
||||||
| 18 | * @link http://www.appserver.io |
||||||
| 19 | */ |
||||||
| 20 | |||||||
| 21 | namespace AppserverIo\Authenticator; |
||||||
| 22 | |||||||
| 23 | use AppserverIo\Lang\String; |
||||||
| 24 | use AppserverIo\Psr\Auth\RealmInterface; |
||||||
| 25 | use AppserverIo\Psr\HttpMessage\Protocol; |
||||||
| 26 | use AppserverIo\Psr\Security\PrincipalInterface; |
||||||
| 27 | use AppserverIo\Psr\Servlet\ServletException; |
||||||
| 28 | use AppserverIo\Psr\Servlet\Utils\RequestHandlerKeys; |
||||||
| 29 | use AppserverIo\Psr\Servlet\Http\HttpServletRequestInterface; |
||||||
| 30 | use AppserverIo\Psr\Servlet\Http\HttpServletResponseInterface; |
||||||
| 31 | |||||||
| 32 | /** |
||||||
| 33 | * A bearer token based authenticator implementation. |
||||||
| 34 | * |
||||||
| 35 | * @author Tim Wagner <[email protected]> |
||||||
| 36 | * @copyright 2016 TechDivision GmbH <[email protected]> |
||||||
| 37 | * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) |
||||||
| 38 | * @link https://github.com/appserver-io/authenticator |
||||||
| 39 | * @link http://www.appserver.io |
||||||
| 40 | */ |
||||||
| 41 | class BearerAuthenticator extends AbstractAuthenticator |
||||||
| 42 | { |
||||||
| 43 | |||||||
| 44 | /** |
||||||
| 45 | * Defines the auth type which should match the client request type definition |
||||||
| 46 | * |
||||||
| 47 | * @var string AUTH_TYPE |
||||||
| 48 | */ |
||||||
| 49 | const AUTH_TYPE = 'Bearer'; |
||||||
| 50 | |||||||
| 51 | /** |
||||||
| 52 | * Returns the parsed password. |
||||||
| 53 | * |
||||||
| 54 | * @return \AppserverIo\Lang\String The password |
||||||
| 55 | */ |
||||||
| 56 | public function getPassword() |
||||||
| 57 | { |
||||||
| 58 | return new String(); |
||||||
| 59 | } |
||||||
| 60 | |||||||
| 61 | /** |
||||||
| 62 | * Return's the array with the login credentials. |
||||||
| 63 | * |
||||||
| 64 | * @return \AppserverIo\Lang\String[] The array with the login credentials |
||||||
| 65 | */ |
||||||
| 66 | protected function getCredentials() |
||||||
| 67 | { |
||||||
| 68 | return array($this->getUsername(), $this->getPassword()); |
||||||
|
0 ignored issues
–
show
Bug
Best Practice
introduced
by
Loading history...
|
|||||||
| 69 | } |
||||||
| 70 | |||||||
| 71 | /** |
||||||
| 72 | * Try to authenticate the user making this request, based on the specified login configuration. |
||||||
| 73 | * |
||||||
| 74 | * Return TRUE if any specified constraint has been satisfied, or FALSE if we have created a response |
||||||
| 75 | * challenge already. |
||||||
| 76 | * |
||||||
| 77 | * @param \AppserverIo\Psr\Servlet\Http\HttpServletRequestInterface $servletRequest The servlet request instance |
||||||
| 78 | * @param \AppserverIo\Psr\Servlet\Http\HttpServletResponseInterface $servletResponse The servlet response instance |
||||||
| 79 | * |
||||||
| 80 | * @return boolean TRUE if authentication has already been processed on a request before, else FALSE |
||||||
| 81 | * @throws \AppserverIo\Http\Authentication\AuthenticationException Is thrown if the request can't be authenticated |
||||||
| 82 | */ |
||||||
| 83 | public function authenticate(HttpServletRequestInterface $servletRequest, HttpServletResponseInterface $servletResponse) |
||||||
| 84 | { |
||||||
| 85 | |||||||
| 86 | // invoke the onCredentials callback to load the credentials from the request |
||||||
| 87 | $this->onCredentials($servletRequest, $servletResponse); |
||||||
| 88 | |||||||
| 89 | // load the realm to authenticate this request for |
||||||
| 90 | /** @var AppserverIo\Appserver\ServletEngine\Security\RealmInterface $realm */ |
||||||
| 91 | $realm = $this->getAuthenticationManager()->getRealm($this->getRealmName()); |
||||||
| 92 | |||||||
| 93 | // authenticate the request and initialize the user principal |
||||||
| 94 | $userPrincipal = call_user_func_array(array($realm, 'authenticate'), $this->getCredentials()); |
||||||
| 95 | |||||||
| 96 | // query whether or not the realm returned an authenticated user principal |
||||||
| 97 | if ($userPrincipal == null) { |
||||||
| 98 | // invoke the onFailure callback and forward the user to the error page |
||||||
| 99 | $this->onFailure($realm, $servletRequest, $servletResponse); |
||||||
| 100 | return false; |
||||||
| 101 | } |
||||||
| 102 | |||||||
| 103 | // invoke the onSuccess callback and redirect the user to the original page |
||||||
| 104 | $this->onSuccess($userPrincipal, $servletRequest, $servletResponse); |
||||||
| 105 | return false; |
||||||
| 106 | } |
||||||
| 107 | |||||||
| 108 | /** |
||||||
| 109 | * Will be invoked to load the credentials from the request. |
||||||
| 110 | * |
||||||
| 111 | * @param \AppserverIo\Psr\Servlet\Http\HttpServletRequestInterface $servletRequest The servlet request instance |
||||||
| 112 | * @param \AppserverIo\Psr\Servlet\Http\HttpServletResponseInterface $servletResponse The servlet response instance |
||||||
| 113 | * |
||||||
| 114 | * @return void |
||||||
| 115 | */ |
||||||
| 116 | protected function onCredentials( |
||||||
| 117 | HttpServletRequestInterface $servletRequest, |
||||||
| 118 | HttpServletResponseInterface $servletResponse |
||||||
| 119 | ) { |
||||||
| 120 | |||||||
| 121 | // try to load the access token from the request instead |
||||||
| 122 | if ($servletRequest->hasHeader(Protocol::HEADER_AUTHORIZATION)) { |
||||||
| 123 | // extract the access token from the authorization header |
||||||
| 124 | sscanf($servletRequest->getHeader(Protocol::HEADER_AUTHORIZATION), 'Bearer %s', $accessToken); |
||||||
|
0 ignored issues
–
show
It seems like
$servletRequest->getHead...::HEADER_AUTHORIZATION) can also be of type null; however, parameter $string of sscanf() does only seem to accept string, maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
Loading history...
|
|||||||
| 125 | $this->username = new String($accessToken); |
||||||
| 126 | } |
||||||
| 127 | } |
||||||
| 128 | |||||||
| 129 | /** |
||||||
| 130 | * Will be invoked when login fails for some reasons. |
||||||
| 131 | * |
||||||
| 132 | * @param \AppserverIo\Appserver\ServletEngine\Security\RealmInterface $realm The realm instance containing the exception stack |
||||||
|
0 ignored issues
–
show
The type
AppserverIo\Appserver\Se...Security\RealmInterface was not found. Maybe you did not declare it correctly or list all dependencies?
The issue could also be caused by a filter entry in the build configuration.
If the path has been excluded in your configuration, e.g. filter:
dependency_paths: ["lib/*"]
For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths Loading history...
|
|||||||
| 133 | * @param \AppserverIo\Psr\Servlet\Http\HttpServletRequestInterface $servletRequest The servlet request instance |
||||||
| 134 | * @param \AppserverIo\Psr\Servlet\Http\HttpServletResponseInterface $servletResponse The servlet response instance |
||||||
| 135 | * |
||||||
| 136 | * @return void |
||||||
| 137 | */ |
||||||
| 138 | protected function onFailure( |
||||||
| 139 | RealmInterface $realm, |
||||||
| 140 | HttpServletRequestInterface $servletRequest, |
||||||
| 141 | HttpServletResponseInterface $servletResponse |
||||||
| 142 | ) { |
||||||
| 143 | $this->forwardToErrorPage($servletRequest, $servletResponse); |
||||||
| 144 | } |
||||||
| 145 | |||||||
| 146 | /** |
||||||
| 147 | * Will be invoked on a successfull login. |
||||||
| 148 | * |
||||||
| 149 | * @param \AppserverIo\Psr\Security\PrincipalInterface $userPrincipal The user principal logged into the system |
||||||
| 150 | * @param \AppserverIo\Psr\Servlet\Http\HttpServletRequestInterface $servletRequest The servlet request instance |
||||||
| 151 | * @param \AppserverIo\Psr\Servlet\Http\HttpServletResponseInterface $servletResponse The servlet response instance |
||||||
| 152 | * |
||||||
| 153 | * @return void |
||||||
| 154 | */ |
||||||
| 155 | protected function onSuccess( |
||||||
| 156 | PrincipalInterface $userPrincipal, |
||||||
| 157 | HttpServletRequestInterface $servletRequest, |
||||||
| 158 | HttpServletResponseInterface $servletResponse |
||||||
| 159 | ) { |
||||||
| 160 | |||||||
| 161 | // add the user principal and the authentication type to the request |
||||||
| 162 | $this->register($servletRequest, $servletResponse, $userPrincipal); |
||||||
| 163 | } |
||||||
| 164 | |||||||
| 165 | /** |
||||||
| 166 | * Register's the user principal and the authenticytion in the request and session. |
||||||
| 167 | * |
||||||
| 168 | * @param \AppserverIo\Psr\Servlet\Http\HttpServletRequestInterface $servletRequest The servlet request instance |
||||||
| 169 | * @param \AppserverIo\Psr\Servlet\Http\HttpServletResponseInterface $servletResponse The servlet response instance |
||||||
| 170 | * @param \AppserverIo\Psr\Security\PrincipalInterface $userPrincipal The actual user principal |
||||||
| 171 | * |
||||||
| 172 | * @return void |
||||||
| 173 | */ |
||||||
| 174 | protected function register( |
||||||
| 175 | HttpServletRequestInterface $servletRequest, |
||||||
| 176 | HttpServletResponseInterface $servletResponse, |
||||||
| 177 | PrincipalInterface $userPrincipal |
||||||
| 178 | ) { |
||||||
| 179 | |||||||
| 180 | // add the user principal and the authentication type to the request |
||||||
| 181 | $servletRequest->setUserPrincipal($userPrincipal); |
||||||
|
0 ignored issues
–
show
The method
setUserPrincipal() does not exist on AppserverIo\Psr\Servlet\...ServletRequestInterface. It seems like you code against a sub-type of AppserverIo\Psr\Servlet\...ServletRequestInterface such as AppserverIo\Authenticato...ServletRequestInterface.
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
Loading history...
|
|||||||
| 182 | $servletRequest->setAuthType($this->getAuthType()); |
||||||
|
0 ignored issues
–
show
The method
setAuthType() does not exist on AppserverIo\Psr\Servlet\...ServletRequestInterface.
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces. This is most likely a typographical error or the method has been renamed. Loading history...
|
|||||||
| 183 | } |
||||||
| 184 | |||||||
| 185 | /** |
||||||
| 186 | * Forward's the request to the configured login page. |
||||||
| 187 | * |
||||||
| 188 | * @param \AppserverIo\Psr\Servlet\Http\HttpServletRequestInterface $servletRequest The servlet request instance |
||||||
| 189 | * @param \AppserverIo\Psr\Servlet\Http\HttpServletResponseInterface $servletResponse The servlet response instance |
||||||
| 190 | * |
||||||
| 191 | * @return void |
||||||
| 192 | */ |
||||||
| 193 | protected function forwardToLoginPage( |
||||||
| 194 | HttpServletRequestInterface $servletRequest, |
||||||
| 195 | HttpServletResponseInterface $servletResponse |
||||||
| 196 | ) { |
||||||
| 197 | $servletRequest->setDispatched(true); |
||||||
| 198 | $servletResponse->setHeaders($this->getDefaultHeaders()); |
||||||
| 199 | $servletResponse->appendBodyStream($this->serialize(array('error' => 'Use SSO server to aquire a valid access token'))); |
||||||
| 200 | $servletResponse->setStatusCode(500); |
||||||
| 201 | } |
||||||
| 202 | |||||||
| 203 | /** |
||||||
| 204 | * Forward's the request to the configured error page. |
||||||
| 205 | * |
||||||
| 206 | * @param \AppserverIo\Psr\Servlet\Http\HttpServletRequestInterface $servletRequest The servlet request instance |
||||||
| 207 | * @param \AppserverIo\Psr\Servlet\Http\HttpServletResponseInterface $servletResponse The servlet response instance |
||||||
| 208 | * |
||||||
| 209 | * @return void |
||||||
| 210 | */ |
||||||
| 211 | protected function forwardToErrorPage( |
||||||
| 212 | HttpServletRequestInterface $servletRequest, |
||||||
| 213 | HttpServletResponseInterface $servletResponse |
||||||
| 214 | ) { |
||||||
| 215 | $servletRequest->setDispatched(true); |
||||||
| 216 | $servletResponse->setHeaders($this->getDefaultHeaders()); |
||||||
| 217 | $servletResponse->appendBodyStream($this->serialize(array('error' => 'You need an valid access token to use the API'))); |
||||||
| 218 | $servletResponse->setStatusCode(401); |
||||||
| 219 | } |
||||||
| 220 | |||||||
| 221 | /** |
||||||
| 222 | * Return's the default headers to set. |
||||||
| 223 | * |
||||||
| 224 | * @return string[] The array with the headers |
||||||
| 225 | */ |
||||||
| 226 | protected function getDefaultHeaders() |
||||||
| 227 | { |
||||||
| 228 | return array(Protocol::HEADER_CONTENT_TYPE => 'application/json'); |
||||||
|
0 ignored issues
–
show
|
|||||||
| 229 | } |
||||||
| 230 | |||||||
| 231 | /** |
||||||
| 232 | * Serialize's the passed value an return's it. |
||||||
| 233 | * |
||||||
| 234 | * @param mixed $value The value that has to be serialized |
||||||
| 235 | * |
||||||
| 236 | * @return string The serialized value |
||||||
| 237 | */ |
||||||
| 238 | protected function serialize($value) |
||||||
| 239 | { |
||||||
| 240 | return json_encode($value); |
||||||
|
0 ignored issues
–
show
|
|||||||
| 241 | } |
||||||
| 242 | |||||||
| 243 | /** |
||||||
| 244 | * Tries the login the passed username/password combination for the login configuration. |
||||||
| 245 | * |
||||||
| 246 | * @param \AppserverIo\Lang\String $username The username used to login |
||||||
| 247 | * @param \AppserverIo\Lang\String $password The password used to authenticate the user |
||||||
| 248 | * @param \AppserverIo\Psr\Servlet\Http\HttpServletRequestInterface $servletRequest The servlet request instance |
||||||
| 249 | * |
||||||
| 250 | * @return \AppserverIo\Psr\Security\PrincipalInterface The authenticated user principal |
||||||
| 251 | */ |
||||||
| 252 | public function login( |
||||||
| 253 | String $username, |
||||||
| 254 | String $password, |
||||||
| 255 | HttpServletRequestInterface $servletRequest |
||||||
| 256 | ) { |
||||||
| 257 | |||||||
| 258 | // load the realm to authenticate this request for |
||||||
| 259 | /** @var AppserverIo\Appserver\ServletEngine\Security\RealmInterface $realm */ |
||||||
| 260 | $realm = $this->getAuthenticationManager()->getRealm($this->getRealmName()); |
||||||
| 261 | |||||||
| 262 | // authenticate the request and initialize the user principal |
||||||
| 263 | $userPrincipal = call_user_func_array(array($realm, 'authenticate'), array($username, $password)); |
||||||
| 264 | |||||||
| 265 | // query whether or not we can authenticate the user |
||||||
| 266 | if ($userPrincipal == null) { |
||||||
| 267 | throw new ServletException(sprintf('Can\'t authenticate user %s', $username)); |
||||||
| 268 | } |
||||||
| 269 | |||||||
| 270 | // add the user principal and the authentication type to the request |
||||||
| 271 | $servletRequest->setUserPrincipal($userPrincipal); |
||||||
| 272 | $servletRequest->setAuthType($this->getAuthType()); |
||||||
| 273 | |||||||
| 274 | // return's the user principal |
||||||
| 275 | return $userPrincipal; |
||||||
| 276 | } |
||||||
| 277 | |||||||
| 278 | /** |
||||||
| 279 | * Logout the actual user from the session. |
||||||
| 280 | * |
||||||
| 281 | * @param \AppserverIo\Psr\Servlet\Http\HttpServletRequestInterface $servletRequest The servlet request instance |
||||||
| 282 | * |
||||||
| 283 | * @return void |
||||||
| 284 | */ |
||||||
| 285 | public function logout(HttpServletRequestInterface $servletRequest) |
||||||
| 286 | { |
||||||
| 287 | } |
||||||
| 288 | } |
||||||
| 289 |