Skip to content

Commit dda608f

Browse files
committed
add new boolean setting to enable private key jwt auth
Signed-off-by: Julien Veyssier <julien-nc@posteo.net>
1 parent 093cd98 commit dda608f

6 files changed

Lines changed: 31 additions & 5 deletions

File tree

lib/Command/UpsertProvider.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,10 @@ class UpsertProvider extends Base {
2727
'shortcut' => null, 'mode' => InputOption::VALUE_REQUIRED, 'setting_key' => ProviderService::SETTING_UNIQUE_UID,
2828
'description' => 'Determines if unique user ids shall be used or not. 1 to enable, 0 to disable',
2929
],
30+
'use-private-key-jwt' => [
31+
'shortcut' => null, 'mode' => InputOption::VALUE_REQUIRED, 'setting_key' => ProviderService::SETTING_USE_PRIVATE_KEY_JWT,
32+
'description' => 'If enabled, user_oidc will use the private key JWT authentication method instead of using the client secret. 1 to enable, 0 to disable (default when creating a new provider)',
33+
],
3034
'check-bearer' => [
3135
'shortcut' => null, 'mode' => InputOption::VALUE_REQUIRED, 'setting_key' => ProviderService::SETTING_CHECK_BEARER,
3236
'description' => 'Determines if Nextcloud API/WebDav calls should check the Bearer token against this provider or not. 1 to enable, 0 to disable (default when creating a new provider)',

lib/Service/JwkService.php

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -128,10 +128,8 @@ public function getJwkFromSslKey(array $sslKeyDetails, bool $isEncryptionKey = f
128128
'crv' => 'P-384',
129129
'x' => \rtrim(\strtr(\base64_encode($sslKeyDetails['ec']['x']), '+/', '-_'), '='),
130130
'y' => \rtrim(\strtr(\base64_encode($sslKeyDetails['ec']['y']), '+/', '-_'), '='),
131+
'alg' => $isEncryptionKey ? 'ECDH-ES+A192KW' : 'ES384',
131132
];
132-
if ($isEncryptionKey) {
133-
$jwk['alg'] = 'ECDH-ES+A192KW';
134-
}
135133
return $jwk;
136134
}
137135

lib/Service/ProviderService.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
class ProviderService {
2020
public const SETTING_CHECK_BEARER = 'checkBearer';
21+
public const SETTING_USE_PRIVATE_KEY_JWT = 'usePrivateKeyJwt';
2122
public const SETTING_SEND_ID_TOKEN_HINT = 'sendIdTokenHint';
2223
public const SETTING_BEARER_PROVISIONING = 'bearerProvisioning';
2324
public const SETTING_UNIQUE_UID = 'uniqueUid';
@@ -62,6 +63,7 @@ class ProviderService {
6263
self::SETTING_BEARER_PROVISIONING => false,
6364
self::SETTING_UNIQUE_UID => true,
6465
self::SETTING_CHECK_BEARER => false,
66+
self::SETTING_USE_PRIVATE_KEY_JWT => false,
6567
self::SETTING_SEND_ID_TOKEN_HINT => false,
6668
self::SETTING_RESTRICT_LOGIN_TO_GROUPS => false,
6769
self::SETTING_RESOLVE_NESTED_AND_FALLBACK_CLAIMS_MAPPING => false,
@@ -169,6 +171,7 @@ private function getSupportedSettings(): array {
169171
self::SETTING_MAPPING_BIRTHDATE,
170172
self::SETTING_UNIQUE_UID,
171173
self::SETTING_CHECK_BEARER,
174+
self::SETTING_USE_PRIVATE_KEY_JWT,
172175
self::SETTING_SEND_ID_TOKEN_HINT,
173176
self::SETTING_BEARER_PROVISIONING,
174177
self::SETTING_EXTRA_CLAIMS,

src/components/AdminSettings.vue

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,7 @@ export default {
200200
endSessionEndpoint: '',
201201
postLogoutUri: '',
202202
settings: {
203+
usePrivateKeyJwt: false,
203204
uniqueUid: true,
204205
checkBearer: false,
205206
bearerProvisioning: false,

src/components/SettingsForm.vue

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,21 @@
2323
type="text"
2424
required>
2525
</p>
26+
<NcCheckboxRadioSwitch
27+
v-model="localProvider.settings.usePrivateKeyJwt"
28+
wrapper-element="div">
29+
{{ t('user_oidc', 'Use private key JWT authentication method') }}
30+
</NcCheckboxRadioSwitch>
31+
<!-- TODO: link to https://openid.net/specs/openid-connect-core-1_0.html#ClientAuthentication -->
32+
<!-- TODO: give the JWKs URL to configure the IdP -->
2633
<p>
2734
<label for="oidc-client-secret">{{ t('user_oidc', 'Client secret') }}</label>
2835
<input id="oidc-client-secret"
2936
v-model="localProvider.clientSecret"
30-
:placeholder="update ? t('user_oidc', 'Leave empty to keep existing') : null"
37+
:placeholder="clientSecretPlaceholder"
3138
type="text"
32-
:required="!update"
39+
:disabled="localProvider.settings.usePrivateKeyJwt"
40+
:required="!update && !localProvider.settings.usePrivateKeyJwt"
3341
autocomplete="off">
3442
</p>
3543
<p class="settings-hint warning-hint">
@@ -392,6 +400,14 @@ export default {
392400
identifierLength() {
393401
return this.localProvider.identifier.length
394402
},
403+
clientSecretPlaceholder() {
404+
if (this.localProvider.settings.usePrivateKeyJwt) {
405+
return t('user_oidc', 'Not used with private key JWT authentication')
406+
}
407+
return this.update
408+
? t('user_oidc', 'Leave empty to keep existing')
409+
: null
410+
},
395411
},
396412
created() {
397413
this.localProvider = this.provider

tests/unit/Service/ProviderServiceTest.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ public function testGetProvidersWithSettings() {
8989
'mappingBirthdate' => '1',
9090
'uniqueUid' => true,
9191
'checkBearer' => true,
92+
'usePrivateKeyJwt' => true,
9293
'bearerProvisioning' => true,
9394
'sendIdTokenHint' => true,
9495
'extraClaims' => '1',
@@ -135,6 +136,7 @@ public function testGetProvidersWithSettings() {
135136
'mappingBirthdate' => '1',
136137
'uniqueUid' => true,
137138
'checkBearer' => true,
139+
'usePrivateKeyJwt' => true,
138140
'bearerProvisioning' => true,
139141
'sendIdTokenHint' => true,
140142
'extraClaims' => '1',
@@ -157,6 +159,7 @@ public function testSetSettings() {
157159
'mappingGroups' => 'groups',
158160
'uniqueUid' => true,
159161
'checkBearer' => false,
162+
'usePrivateKeyJwt' => false,
160163
'bearerProvisioning' => false,
161164
'sendIdTokenHint' => true,
162165
'extraClaims' => 'claim1 claim2',
@@ -216,6 +219,7 @@ public function testSetSettings() {
216219
[Application::APP_ID, 'provider-1-' . ProviderService::SETTING_MAPPING_BIRTHDATE, '', 'birthdate'],
217220
[Application::APP_ID, 'provider-1-' . ProviderService::SETTING_UNIQUE_UID, '', '1'],
218221
[Application::APP_ID, 'provider-1-' . ProviderService::SETTING_CHECK_BEARER, '', '0'],
222+
[Application::APP_ID, 'provider-1-' . ProviderService::SETTING_USE_PRIVATE_KEY_JWT, '', '0'],
219223
[Application::APP_ID, 'provider-1-' . ProviderService::SETTING_BEARER_PROVISIONING, '', '0'],
220224
[Application::APP_ID, 'provider-1-' . ProviderService::SETTING_SEND_ID_TOKEN_HINT, '', '1'],
221225
[Application::APP_ID, 'provider-1-' . ProviderService::SETTING_EXTRA_CLAIMS, '', 'claim1 claim2'],

0 commit comments

Comments
 (0)