AuthTokenSession.php
1 <?php
2 /**
3  * wCMF - wemove Content Management Framework
4  * Copyright (C) 2005-2020 wemove digital solutions GmbH
5  *
6  * Licensed under the terms of the MIT License.
7  *
8  * See the LICENSE file distributed with this work for
9  * additional information.
10  */
11 namespace wcmf\lib\core\impl;
12 
18 
19 /**
20  * AuthTokenSession is a DefaultSession, but additionally requires
21  * clients to send a token in the X-Auth-Token request header (Double Submit Cookie).
22  * The token is created, when the authenticated user is associated
23  * with the session and send to the client in a cookie named
24  * <em>application-title</em>-token.
25  *
26  * @author ingo herwig <ingo@wemove.com>
27  */
29 
30  const TOKEN_HEADER = 'X-Auth-Token';
31 
32  private $tokenName = '';
33  private $isTokenValid = false;
34 
35  /**
36  * Constructor
37  * @param $configuration
38  */
39  public function __construct(Configuration $configuration) {
40  parent::__construct($configuration);
41 
42  $this->tokenName = $this->getCookiePrefix().'-auth-token';
43  }
44 
45  /**
46  * @see TokenBasedSession::getHeaderName()
47  */
48  public function getHeaderName() {
49  return self::TOKEN_HEADER;
50  }
51 
52  /**
53  * @see TokenBasedSession::getCookieName()
54  */
55  public function getCookieName() {
56  return $this->tokenName;
57  }
58 
59  /**
60  * @see Session::setAuthUser()
61  */
62  public function setAuthUser($login) {
63  parent::setAuthUser($login);
64 
65  // set auth-token cookie for authenticated user
66  if ($login !== AnonymousUser::USER_GROUP_NAME) {
67  // generate a token, set it in the session and send it to the client
68  $token = base64_encode(openssl_random_pseudo_bytes(32));
69  $this->isTokenValid = true;
70  // NOTE: prevent "headers already sent" errors in phpunit tests
71  if (!headers_sent()) {
72  // NOTE: this cookie is intentionally not httpOnly to allow the client to read the value
73  // in order to send it via the auth token header (see Double Submit Cookie pattern)
74  // @sonar-ignore-start
75  setcookie($this->tokenName, $token, 0, '/', '', URIUtil::isHttps(), false);
76  // @sonar-ignore-end
77  }
78  $this->set($this->tokenName, $token);
79  }
80  }
81 
82  /**
83  * @see Session::getAuthUser()
84  */
85  public function getAuthUser() {
86  $login = parent::getAuthUser();
87  return $this->isTokenValid() ? $login : AnonymousUser::USER_GROUP_NAME;
88  }
89 
90  /**
91  * Check if the request contains a valid token
92  */
93  protected function isTokenValid() {
94  if ($this->isTokenValid) {
95  // already validated
96  return true;
97  }
98  $request = ObjectFactory::getInstance('request');
99  $token = $request->hasHeader(self::TOKEN_HEADER) ? $request->getHeader(self::TOKEN_HEADER) :
100  $request->getValue(self::TOKEN_HEADER, null);
101  // NOTE: we compare to the cookie value sent by the client and the original value stored in the session
102  $this->isTokenValid = $token != null && $token == $_COOKIE[$this->tokenName] && $token == $this->get($this->tokenName);
103  return $this->isTokenValid;
104  }
105 }
AuthTokenSession is a DefaultSession, but additionally requires clients to send a token in the X-Auth...
A session that requires clients to send a token for authentication.
getCookiePrefix()
Get the cookie prefix.
Implementations of Configuration give access to the application configuration.
__construct(Configuration $configuration)
Constructor.
URIUtil provides support for uri manipulation.
Definition: URIUtil.php:18
static getInstance($name, $dynamicConfiguration=[])
isTokenValid()
Check if the request contains a valid token.
DefaultSession uses the default PHP session implementation:
ObjectFactory implements the service locator pattern by wrapping a Factory instance and providing sta...