Closed megastary closed 11 months ago
Hi @megastary, Please see #4147 for a lot of prior context and conversation on this.
My comment in #4200 provides an example of a workaround that can be use to make zitadel's behavior compatible.
Hi @ssddanbrown,
thank you very much for responding with all I needed! Sorry that I did not find mentioned issue myself.
On #4147 I personally side with @the-voidl and think that Bookstack should be able to handle array on its own as it is imho clearly stated in RFC 7519, but you made working workaround and it's great!
The only thing I think could be improved is to have those tips how to setup Zitadel SSO in docs. I guess the reason is that currently it is clearly new and not that big, but as stated by @the-voidl, Zitadel may not be the only identity server that sends array in audience, so maybe some general heads up could be included in https://www.bookstackapp.com/docs/admin/oidc-auth/ docs page?
Also to be fair, I wish Zitadel could be the flexible one and allow us to send aud
as string as there are many applications that do not support array in the aud
claim. I will try to chat with maintainers to see if there are any plans to implement this.
Now to results. I got it working!
In Bookstack, create following file (and folder structure) /var/www/bookstack/themes/custom/functions.php
<?php
use BookStack\Facades\Theme;
use BookStack\Theming\ThemeEvents;
Theme::listen(ThemeEvents::OIDC_ID_TOKEN_PRE_VALIDATE, function (array $idTokenData, array $accessTokenData) {
if (is_array($idTokenData['aud']) && in_array($idTokenData['azp'], $idTokenData['aud'])) {
return array_merge($idTokenData, [
'aud' => [$idTokenData['azp']]
]);
}
});
Add following options to /var/www/bookstack/.env
# Set OIDC to be the authentication method
AUTH_METHOD=oidc
# Control if BookStack automatically initiates login via your OIDC system
# if it's the only authentication method. Prevents the need for the
# user to click the "Login with x" button on the login page.
# Setting this to true enables auto-initiation.
AUTH_AUTO_INITIATE=true
# Set the display name to be shown on the login button.
# (Login with <name>)
OIDC_NAME="SSO"
# Name of the claims(s) to use for the user's display name.
# Can have multiple attributes listed, separated with a '|' in which
# case those values will be joined with a space.
# Example: OIDC_DISPLAY_NAME_CLAIMS=given_name|family_name
OIDC_DISPLAY_NAME_CLAIMS=name
# OAuth Client ID to access the identity provider
OIDC_CLIENT_ID=ClientId
# OAuth Client Secret to access the identity provider
OIDC_CLIENT_SECRET=ClientSecret
# Issuer URL
# Must start with 'https://'
OIDC_ISSUER=https://your-zitadel-instance.example.com
# Enable auto-discovery of endpoints and token keys.
# As per the standard, expects the service to serve a
# `<issuer>/.well-known/openid-configuration` endpoint.
OIDC_ISSUER_DISCOVER=true
# Load custom functions from custom template
APP_THEME=custom
So overall, it is indeed doable and quite easy to do! As a low priority improvement could be function to that pairs Bookstack's Email Confirmation with Zitadels info in token, which states if e-mail is verified, in other words to delegate that check to identtiy server. Example response from Zitadel (last line):
{
"iss": "https:\/\/your-zitadel-instance.example.com",
"sub": "12345",
"aud": [
"12345@bookstack"
],
"exp": 12345,
"iat": 12345,
"auth_time": 12345,
"amr": [
"password",
"pwd",
"mfa",
"user"
],
"azp": "12345@bookstack",
"client_id": "12345@bookstack",
"at_hash": "hash",
"c_hash": "hash",
"name": "Name Surname",
"given_name": "Name",
"family_name": "Surname",
"locale": "en",
"updated_at": 12345,
"preferred_username": "name@example.com",
"email": "name@example.com",
"email_verified": true
}
Good to hear the workaround works for you here!
think that Bookstack should be able to handle array on its own as it is imho clearly stated in RFC 7519
Just to confirm, BookStack does accept an array or string value as per the RFC, it's just that it also validates that property to my strict interpretation of the OIDC spec, so rejects when there's more that one value since that's never expected in the OIDC flow scenario for BookStack.
@megastary thanks for the tips, I was able to get login working with Zitadel! Did you have any luck with group sync? I cannot seem to figure out how to get my Zitadel roles working. I have created a role called "Wiki Admin" and I have an equivalent role in BookStack, but it is no getting applied when a user logs in.
@Chaz6 You can use the OIDC_DUMP_USER_DETAILS=true
option to help see if the details are being provided by Zitadel and, if so, how they are named.
Details in our docs: https://www.bookstackapp.com/docs/admin/oidc-auth/#debugging Example in video of using this to debug: https://youtu.be/TJQ4NJrMvkw?t=1154 (19:14 mark)
@megastary thanks for the tips, I was able to get login working with Zitadel! Did you have any luck with group sync? I cannot seem to figure out how to get my Zitadel roles working. I have created a role called "Wiki Admin" and I have an equivalent role in BookStack, but it is no getting applied when a user logs in.
@Chaz6 I think the trick part was to enable Assert Roles on Authentication
This is my config which works:
And .env for bookstack
OIDC_USER_TO_GROUPS=true
OIDC_GROUPS_CLAIM=groups
OIDC_REMOVE_FROM_GROUPS=false
Hi,
I successfully setup OIDC with Zitadel using the steps from @megastary. But after some time, after 24 hours at the latest, I get this error:
ID token validation failed with error: Token signature could not be validated using the provided keys.
Deleting the bookstack docker container and recreating it fixes the error for some hours.
Anybody else having this error? Am I missing a configuration?
Now to results. I got it working!
- In Zitadel, create new project
- Create Web application
- Select Code configuration
- Copy Client Id and Client Secret for later use
- In Token settings, enable User Info inside ID Token authtoken option
- In Bookstack, create following file (and folder structure)
/var/www/bookstack/themes/custom/functions.php
<?php use BookStack\Facades\Theme; use BookStack\Theming\ThemeEvents; Theme::listen(ThemeEvents::OIDC_ID_TOKEN_PRE_VALIDATE, function (array $idTokenData, array $accessTokenData) { if (is_array($idTokenData['aud']) && in_array($idTokenData['azp'], $idTokenData['aud'])) { return array_merge($idTokenData, [ 'aud' => [$idTokenData['azp']] ]); } });
- Add following options to
/var/www/bookstack/.env
# Set OIDC to be the authentication method AUTH_METHOD=oidc # Control if BookStack automatically initiates login via your OIDC system # if it's the only authentication method. Prevents the need for the # user to click the "Login with x" button on the login page. # Setting this to true enables auto-initiation. AUTH_AUTO_INITIATE=true # Set the display name to be shown on the login button. # (Login with <name>) OIDC_NAME="SSO" # Name of the claims(s) to use for the user's display name. # Can have multiple attributes listed, separated with a '|' in which # case those values will be joined with a space. # Example: OIDC_DISPLAY_NAME_CLAIMS=given_name|family_name OIDC_DISPLAY_NAME_CLAIMS=name # OAuth Client ID to access the identity provider OIDC_CLIENT_ID=ClientId # OAuth Client Secret to access the identity provider OIDC_CLIENT_SECRET=ClientSecret # Issuer URL # Must start with 'https://' OIDC_ISSUER=https://your-zitadel-instance.example.com # Enable auto-discovery of endpoints and token keys. # As per the standard, expects the service to serve a # `<issuer>/.well-known/openid-configuration` endpoint. OIDC_ISSUER_DISCOVER=true # Load custom functions from custom template APP_THEME=custom
- Login with Zitadel SSO to Bookstack
@baua1310 We do some caching of auto-discovery findings in BookStack which could lead to something like that, especially as it looks like Zitadel has frequent key rotation by default, but our caching is only intended for 15 minutes.
Feel free to raise as a seperate support issue for potential debug/workaround options, as it's something different to what was originally discussed in this closed thread.
Hi @ssddanbrown thank you for your message. I created a new issue #5049
Describe the Bug
When trying to use Zitadel Identity server for OIDC login to bookstack, it always fails as it does not expect audience claim to be array. According to standard,
aud
should usually be array, only in special case, when only one audience is available, it may present it as string. Source: https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.3It may not be usually presented as an array, but sadly Zitadel always sends
aud
as an array and there is currently no way to disable that behaviour, though it's kinda expected as they do not break the standard with that implementation.Stack trace in log:
Steps to Reproduce
Expected Behaviour
Screenshots or Additional Context
Browser Details
Brave 1.60.118 Chromium: 119.0.6045.163 on Windows 11
Exact BookStack Version
v23.10.2