Skip to content

Commit 343a387

Browse files
committed
add regexp mechanism to parse user IDs from tokens
Signed-off-by: Julien Veyssier <julien-nc@posteo.net>
1 parent 09e373b commit 343a387

File tree

4 files changed

+40
-0
lines changed

4 files changed

+40
-0
lines changed

README.md

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,28 @@ The OpenID Connect backend will ensure that user ids are unique even when multip
7979
id to ensure that a user cannot identify for the same Nextcloud account through different providers.
8080
Therefore, a hash of the provider id and the user id is used. This behaviour can be turned off in the provider options.
8181

82+
### Parsing user IDs from claims
83+
84+
If your ID tokens do not contain the user ID directly in an attribute/claim,
85+
you can configure user_oidc to apply a regular expression to extract the user ID from the claim.
86+
87+
```php
88+
'user_oidc' => [
89+
'user_id_regexp' => 'u=([^,]+)'
90+
]
91+
```
92+
93+
This regular expression may or may not contain parenthesis. If it does, only the selected block will be extracted.
94+
Examples:
95+
96+
* `'[a-zA-Z]+'`
97+
* `'123-abc-123'` will give `'abc'`
98+
* `'123-abc-345-def'` will give `'abc'`
99+
* `'u=([^,]+)'`
100+
* `'u=123'` will give `'123'`
101+
* `'anything,u=123,anything'` will give `'123'`
102+
* `'anything,u=123,anything,u=345'` will give `'123'`
103+
82104
## Commandline settings
83105
The app could also be configured by commandline.
84106

lib/Controller/LoginController.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -562,6 +562,8 @@ public function code(string $state = '', string $code = '', string $scope = '',
562562
return $this->build403TemplateResponse($message, Http::STATUS_BAD_REQUEST, ['reason' => 'failed to provision user']);
563563
}
564564

565+
$userId = $this->settingsService->parseUserId($userId);
566+
565567
// prevent login of users that are not in a whitelisted group (if activated)
566568
$restrictLoginToGroups = $this->providerService->getSetting($providerId, ProviderService::SETTING_RESTRICT_LOGIN_TO_GROUPS, '0');
567569
if ($restrictLoginToGroups === '1') {

lib/Service/SettingsService.php

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,14 @@
1313
use OCA\UserOIDC\AppInfo\Application;
1414
use OCP\Exceptions\AppConfigTypeConflictException;
1515
use OCP\IAppConfig;
16+
use OCP\IConfig;
1617
use Psr\Log\LoggerInterface;
1718

1819
class SettingsService {
1920

2021
public function __construct(
2122
private IAppConfig $appConfig,
23+
private IConfig $config,
2224
private LoggerInterface $logger,
2325
) {
2426
}
@@ -41,4 +43,14 @@ public function setAllowMultipleUserBackEnds(bool $value): void {
4143
$this->appConfig->setValueString(Application::APP_ID, 'allow_multiple_user_backends', $value ? '1' : '0', lazy: true);
4244
}
4345
}
46+
47+
public function parseUserId(string $userId): string {
48+
$oidcSystemConfig = $this->config->getSystemValue('user_oidc', []);
49+
if (isset($oidcSystemConfig['user_id_regexp']) && $oidcSystemConfig['user_id_regexp'] !== '') {
50+
if (preg_match('/' . $oidcSystemConfig['user_id_regexp'] . '/', $userId, $matches) === 1) {
51+
return $matches[1] ?? $matches[0];
52+
}
53+
}
54+
return $userId;
55+
}
4456
}

lib/User/Backend.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
use OCA\UserOIDC\Service\LdapService;
1919
use OCA\UserOIDC\Service\ProviderService;
2020
use OCA\UserOIDC\Service\ProvisioningService;
21+
use OCA\UserOIDC\Service\SettingsService;
2122
use OCA\UserOIDC\User\Validator\SelfEncodedValidator;
2223
use OCA\UserOIDC\User\Validator\UserInfoValidator;
2324
use OCP\AppFramework\Db\DoesNotExistException;
@@ -59,6 +60,7 @@ public function __construct(
5960
private ProviderService $providerService,
6061
private ProvisioningService $provisioningService,
6162
private LdapService $ldapService,
63+
private SettingsService $settingsService,
6264
private IUserManager $userManager,
6365
) {
6466
}
@@ -289,6 +291,8 @@ public function getCurrentUserId(): string {
289291
$discovery = $this->discoveryService->obtainDiscovery($provider);
290292
$this->eventDispatcher->dispatchTyped(new TokenValidatedEvent(['token' => $headerToken], $provider, $discovery));
291293

294+
$tokenUserId = $this->settingsService->parseUserId($tokenUserId);
295+
292296
if ($autoProvisionAllowed) {
293297
// look for user in other backends
294298
if (!$this->userManager->userExists($tokenUserId)) {

0 commit comments

Comments
 (0)