diff --git a/.env.example.complete b/.env.example.complete index 03e52d6bb..7e6c6ee3c 100644 --- a/.env.example.complete +++ b/.env.example.complete @@ -268,6 +268,7 @@ OIDC_DUMP_USER_DETAILS=false OIDC_USER_TO_GROUPS=false OIDC_GROUPS_CLAIM=groups OIDC_REMOVE_FROM_GROUPS=false +OIDC_EXTERNAL_ID_CLAIM=sub # Disable default third-party services such as Gravatar and Draw.IO # Service-specific options will override this option diff --git a/app/Auth/Access/Oidc/OidcService.php b/app/Auth/Access/Oidc/OidcService.php index a9323d423..1ca5e19a2 100644 --- a/app/Auth/Access/Oidc/OidcService.php +++ b/app/Auth/Access/Oidc/OidcService.php @@ -198,7 +198,8 @@ class OidcService */ protected function getUserDetails(OidcIdToken $token): array { - $id = $token->getClaim('sub'); + $idClaim = $this->config()['external_id_claim']; + $id = $token->getClaim($idClaim); return [ 'external_id' => $id, diff --git a/app/Config/oidc.php b/app/Config/oidc.php index d223a63ef..1f73fb688 100644 --- a/app/Config/oidc.php +++ b/app/Config/oidc.php @@ -8,9 +8,12 @@ return [ // Dump user details after a login request for debugging purposes 'dump_user_details' => env('OIDC_DUMP_USER_DETAILS', false), - // Attribute, within a OpenId token, to find the user's display name + // Claim, within an OpenId token, to find the user's display name 'display_name_claims' => explode('|', env('OIDC_DISPLAY_NAME_CLAIMS', 'name')), + // Claim, within an OpenID token, to use to connect a BookStack user to the OIDC user. + 'external_id_claim' => env('OIDC_EXTERNAL_ID_CLAIM', 'sub'), + // OAuth2/OpenId client id, as configured in your Authorization server. 'client_id' => env('OIDC_CLIENT_ID', null), diff --git a/tests/Auth/OidcTest.php b/tests/Auth/OidcTest.php index 32c2d4ae2..35acb7752 100644 --- a/tests/Auth/OidcTest.php +++ b/tests/Auth/OidcTest.php @@ -42,6 +42,7 @@ class OidcTest extends TestCase 'oidc.user_to_groups' => false, 'oidc.groups_claim' => 'group', 'oidc.remove_from_groups' => false, + 'oidc.external_id_claim' => 'sub', ]); } @@ -391,6 +392,25 @@ class OidcTest extends TestCase $this->assertTrue(auth()->check()); } + public function test_auth_uses_configured_external_id_claim_option() + { + config()->set([ + 'oidc.external_id_claim' => 'super_awesome_id', + ]); + $roleA = Role::factory()->create(['display_name' => 'Wizards']); + + $resp = $this->runLogin([ + 'email' => 'benny@example.com', + 'sub' => 'benny1010101', + 'super_awesome_id' => 'xXBennyTheGeezXx', + ]); + $resp->assertRedirect('/'); + + /** @var User $user */ + $user = User::query()->where('email', '=', 'benny@example.com')->first(); + $this->assertEquals('xXBennyTheGeezXx', $user->external_auth_id); + } + public function test_login_group_sync() { config()->set([