Skip to content

Commit 4be5cf2

Browse files
authored
Merge pull request #417 from magento-performance/CABPI-290-revoke-admin-session
CABPI-290: prolong admin session if access token is valid
2 parents 59aaca7 + 617566d commit 4be5cf2

9 files changed

+146
-19
lines changed

app/code/Magento/AdminAdobeIms/Model/ImsConnection.php

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
namespace Magento\AdminAdobeIms\Model;
1010

1111
use Magento\AdminAdobeIms\Exception\AdobeImsTokenAuthorizationException;
12+
use Magento\AdminAdobeIms\Logger\AdminAdobeImsLogger;
1213
use Magento\AdminAdobeIms\Service\ImsConfig;
1314
use Magento\AdobeIms\Model\GetToken;
1415
use Magento\AdobeImsApi\Api\Data\TokenResponseInterface;
@@ -42,22 +43,30 @@ class ImsConnection
4243
*/
4344
private GetToken $token;
4445

46+
/**
47+
* @var AdminAdobeImsLogger
48+
*/
49+
private AdminAdobeImsLogger $adminAdobeImsLogger;
50+
4551
/**
4652
* @param CurlFactory $curlFactory
4753
* @param ImsConfig $imsConfig
4854
* @param Json $json
4955
* @param GetToken $token
56+
* @param AdminAdobeImsLogger $adminAdobeImsLogger
5057
*/
5158
public function __construct(
5259
CurlFactory $curlFactory,
5360
ImsConfig $imsConfig,
5461
Json $json,
55-
GetToken $token
62+
GetToken $token,
63+
AdminAdobeImsLogger $adminAdobeImsLogger
5664
) {
5765
$this->curlFactory = $curlFactory;
5866
$this->imsConfig = $imsConfig;
5967
$this->json = $json;
6068
$this->token = $token;
69+
$this->adminAdobeImsLogger = $adminAdobeImsLogger;
6170
}
6271

6372
/**
@@ -140,19 +149,20 @@ private function validateResponse(Curl $curl): void
140149
* Verify if access_token is valid
141150
*
142151
* @param string $code
152+
* @param string $tokenType
143153
* @return bool
144154
* @throws AuthorizationException
145155
*/
146-
public function verifyToken(string $code): bool
156+
public function validateToken(string $code, string $tokenType = 'access_token'): bool
147157
{
158+
$isTokenValid = false;
148159
$curl = $this->curlFactory->create();
149160

150161
$curl->addHeader('Content-Type', 'application/x-www-form-urlencoded');
151162
$curl->addHeader('cache-control', 'no-cache');
152-
$curl->addHeader('Authorization', 'Bearer ' . $code);
153163

154164
$curl->post(
155-
$this->imsConfig->getVerifyUrl($code),
165+
$this->imsConfig->getValidateTokenUrl($code, $tokenType),
156166
[]
157167
);
158168

@@ -164,7 +174,15 @@ public function verifyToken(string $code): bool
164174

165175
$body = $this->json->unserialize($curl->getBody());
166176

167-
return isset($body['valid']) && $body['valid'] === true;
177+
if (isset($body['valid'])) {
178+
$isTokenValid = (bool)$body['valid'];
179+
}
180+
181+
if (!$isTokenValid && isset($body['reason'])) {
182+
$this->adminAdobeImsLogger->info($tokenType . ' is not valid. Reason: ' . $body['reason']);
183+
}
184+
185+
return $isTokenValid;
168186
}
169187

170188
/**
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
7+
declare(strict_types=1);
8+
9+
namespace Magento\AdminAdobeIms\Plugin;
10+
11+
use Magento\AdminAdobeIms\Model\ImsConnection;
12+
use Magento\AdminAdobeIms\Service\ImsConfig;
13+
use Magento\Backend\Model\Auth\Session;
14+
use Magento\Framework\Stdlib\DateTime\DateTime;
15+
16+
class BackendAuthSessionPlugin
17+
{
18+
/**
19+
* How often access_token has to be validated
20+
*/
21+
public const ACCESS_TOKEN_INTERVAL_CHECK = 600;
22+
23+
/**
24+
* @var ImsConnection
25+
*/
26+
private ImsConnection $imsConnection;
27+
28+
/**
29+
* @var DateTime
30+
*/
31+
private DateTime $dateTime;
32+
33+
/**
34+
* @var ImsConfig
35+
*/
36+
private ImsConfig $imsConfig;
37+
38+
/**
39+
* @param ImsConnection $imsConnection
40+
* @param DateTime $dateTime
41+
* @param ImsConfig $imsConfig
42+
*/
43+
public function __construct(
44+
ImsConnection $imsConnection,
45+
DateTime $dateTime,
46+
ImsConfig $imsConfig
47+
) {
48+
$this->imsConnection = $imsConnection;
49+
$this->dateTime = $dateTime;
50+
$this->imsConfig = $imsConfig;
51+
}
52+
53+
/**
54+
* Check if access token still valid
55+
*
56+
* @param Session $subject
57+
* @param callable $proceed
58+
* @return void
59+
* @throws \Magento\Framework\Exception\AuthorizationException
60+
*/
61+
public function aroundProlong(Session $subject, callable $proceed): void
62+
{
63+
if ($this->imsConfig->enabled()) {
64+
$lastCheckTime = $subject->getTokenLastCheckTime();
65+
if ($lastCheckTime + self::ACCESS_TOKEN_INTERVAL_CHECK <= $this->dateTime->gmtTimestamp()) {
66+
$accessToken = $subject->getAdobeAccessToken();
67+
if ($this->imsConnection->validateToken($accessToken)) {
68+
$subject->setTokenLastCheckTime($this->dateTime->gmtTimestamp());
69+
} else {
70+
$subject->destroy();
71+
return;
72+
}
73+
}
74+
}
75+
76+
$proceed();
77+
}
78+
}

app/code/Magento/AdminAdobeIms/Plugin/ReplaceVerifyIdentityWithImsPlugin.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,6 @@ private function verifyImsToken(User $user): bool
109109
}
110110

111111
$accessToken = $this->encryptor->decrypt($userProfile->getAccessToken());
112-
return $this->imsConnection->verifyToken($accessToken);
112+
return $this->imsConnection->validateToken($accessToken);
113113
}
114114
}

app/code/Magento/AdminAdobeIms/README.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,3 +177,14 @@ This authentication mechanism enabled for REST and SOAP web API areas.
177177
Examples, how developers can test functionality:
178178
curl -X GET "{domain}/rest/V1/customers/2" -H "Authorization: Bearer AddAdobeImsAccessToken"
179179
curl -X GET "{domain}/rest/V1/products/24-MB01" -H "Authorization: Bearer AddAdobeImsAccessToken"
180+
181+
# ACCESS_TOKEN saving in session and validation
182+
When AdminAdomeIms module is enabled, we check each 10 minutes if ACCESS_TOKEN is still valid.
183+
For this when admin user login and when session is started, we add 2 extra varibles to the session:
184+
token_last_check_time is current time
185+
adobe_access_token is ACCESS_TOKEN that we recieve during autorization
186+
187+
There is a plugin \Magento\AdminAdobeIms\Plugin\BackendAuthSessionPlugin where we check if token_last_check_time was updated 10 min ago.
188+
If yes, then we make call to IMS to validate access_token.
189+
If token is valid, value token_last_check_time will be updated to current time and session prolong.
190+
If token is not valid, session will be destroyed.

app/code/Magento/AdminAdobeIms/Service/AdminLoginProcessService.php

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,17 +16,20 @@
1616
use Magento\AdminAdobeIms\Model\User;
1717
use Magento\AdobeIms\Model\LogIn;
1818
use Magento\AdobeImsApi\Api\Data\TokenResponseInterface;
19+
use Magento\Framework\Stdlib\DateTime\DateTime;
1920

2021
class AdminLoginProcessService
2122
{
2223
/**
2324
* @var User
2425
*/
2526
private User $adminUser;
27+
2628
/**
2729
* @var Auth
2830
*/
2931
private Auth $auth;
32+
3033
/**
3134
* @var LogIn
3235
*/
@@ -37,22 +40,30 @@ class AdminLoginProcessService
3740
*/
3841
private LogOut $logOut;
3942

43+
/**
44+
* @var DateTime
45+
*/
46+
private DateTime $dateTime;
47+
4048
/**
4149
* @param User $adminUser
4250
* @param Auth $auth
4351
* @param LogIn $logIn
4452
* @param LogOut $logOut
53+
* @param DateTime $dateTime
4554
*/
4655
public function __construct(
4756
User $adminUser,
4857
Auth $auth,
4958
LogIn $logIn,
50-
LogOut $logOut
59+
LogOut $logOut,
60+
DateTime $dateTime
5161
) {
5262
$this->adminUser = $adminUser;
5363
$this->auth = $auth;
5464
$this->logIn = $logIn;
5565
$this->logOut = $logOut;
66+
$this->dateTime = $dateTime;
5667
}
5768

5869
/**
@@ -76,6 +87,9 @@ public function execute(array $profile, TokenResponseInterface $tokenResponse):
7687
try {
7788
$this->logIn->execute((int)$adminUser['user_id'], $tokenResponse);
7889
$this->auth->loginByUsername($adminUser['username']);
90+
$session = $this->auth->getAuthStorage();
91+
$session->setAdobeAccessToken($tokenResponse->getAccessToken());
92+
$session->setTokenLastCheckTime($this->dateTime->gmtTimestamp());
7993
} catch (Exception $exception) {
8094
$this->externalLogout($tokenResponse->getAccessToken());
8195
throw new AdobeImsTokenAuthorizationException(

app/code/Magento/AdminAdobeIms/Service/ImsConfig.php

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,12 @@ class ImsConfig extends Config
2727
public const XML_PATH_AUTH_URL_PATTERN = 'adobe_ims/integration/auth_url_pattern';
2828
public const XML_PATH_PROFILE_URL = 'adobe_ims/integration/profile_url';
2929
public const XML_PATH_NEW_ADMIN_EMAIL_TEMPLATE = 'adobe_ims/email/content_template';
30-
public const XML_PATH_VERIFY_URL = 'adobe_ims/integration/verify_url';
31-
32-
private const OAUTH_CALLBACK_URL = 'adobe_ims_auth/oauth/';
30+
public const XML_PATH_VALIDATE_TOKEN_URL = 'adobe_ims/integration/validate_token_url';
3331
public const XML_PATH_LOGOUT_URL = 'adobe_ims/integration/logout_url';
3432
public const XML_PATH_CERTIFICATE_PATH = 'adobe_ims/integration/certificate_path';
3533

34+
private const OAUTH_CALLBACK_URL = 'adobe_ims_auth/oauth/';
35+
3636
/**
3737
* @var ScopeConfigInterface
3838
*/
@@ -164,17 +164,18 @@ public function getProfileUrl(): string
164164
}
165165

166166
/**
167-
* Get Token verification url
167+
* Get Token validation url
168168
*
169169
* @param string $code
170+
* @param string $tokenType
170171
* @return string
171172
*/
172-
public function getVerifyUrl(string $code): string
173+
public function getValidateTokenUrl(string $code, string $tokenType): string
173174
{
174175
return str_replace(
175-
['#{token}', '#{client_id}'],
176-
[$code, $this->getApiKey()],
177-
$this->scopeConfig->getValue(self::XML_PATH_VERIFY_URL)
176+
['#{token}', '#{client_id}', '#{token_type}'],
177+
[$code, $this->getApiKey(), $tokenType],
178+
$this->scopeConfig->getValue(self::XML_PATH_VALIDATE_TOKEN_URL)
178179
);
179180
}
180181

app/code/Magento/AdminAdobeIms/Test/Unit/Plugin/ReplaceVerifyIdentityWithImsPluginTest.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ public function testAroundVerifyIdentityCallsProceedWhenModuleIsDisabled(): void
9595

9696
$this->imsConnectionMock
9797
->expects($this->never())
98-
->method('verifyToken');
98+
->method('validateToken');
9999

100100
$this->assertEquals($expectedResult, $this->plugin->aroundVerifyIdentity($subject, $proceed, ''));
101101
}
@@ -124,7 +124,7 @@ public function testAroundVerifyIdentityVerifiesAccessTokenWhenModuleIsEnabled()
124124

125125
$this->imsConnectionMock
126126
->expects($this->once())
127-
->method('verifyToken')
127+
->method('validateToken')
128128
->willReturn(true);
129129

130130
$expectedResult = true;
@@ -160,7 +160,7 @@ public function testAroundVerifyIdentityThrowsExceptionOnInvalidToken(): void
160160

161161
$this->imsConnectionMock
162162
->expects($this->once())
163-
->method('verifyToken')
163+
->method('validateToken')
164164
->willReturn(false);
165165

166166
$this->expectException(AuthenticationException::class);

app/code/Magento/AdminAdobeIms/etc/config.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
<profile_url><![CDATA[https://ims-na1-stg1.adobelogin.com/ims/profile/v1?client_id=#{client_id}]]></profile_url>
1818
<logout_url><![CDATA[https://ims-na1-stg1.adobelogin.com/ims/logout/v1?access_token=#{access_token}&amp;client_id=#{client_id}&amp;client_secret=#{client_secret}]]></logout_url>
1919
<certificate_path><![CDATA[https://static.adobelogin.com/keys/prod/]]></certificate_path>
20-
<verify_url><![CDATA[https://ims-na1-stg1.adobelogin.com/ims/validate_token/v1?token=#{token}&client_id=#{client_id}&type=access_token]]></verify_url>
20+
<validate_token_url><![CDATA[https://ims-na1-stg1.adobelogin.com/ims/validate_token/v1?token=#{token}&client_id=#{client_id}&type=#{token_type}]]></validate_token_url>
2121
</integration>
2222
<email>
2323
<header_template>admin_adobe_ims_email_header_template</header_template>

app/code/Magento/AdminAdobeIms/etc/di.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,4 +66,9 @@
6666
<plugin name="admin_adobe_ims_admin_token_plugin"
6767
type="Magento\AdminAdobeIms\Plugin\AdminTokenPlugin" />
6868
</type>
69+
70+
<type name="Magento\Backend\Model\Auth\Session">
71+
<plugin name="admin_adobe_ims_backend_auth_session"
72+
type="Magento\AdminAdobeIms\Plugin\BackendAuthSessionPlugin"/>
73+
</type>
6974
</config>

0 commit comments

Comments
 (0)