OIDC with Azure Active Directory B2C: Unexpected Issuer or Unexpected type of key #4258

Closed
opened 2026-02-05 08:22:17 +03:00 by OVERLORD · 4 comments
Owner

Originally created by @JanekOstendorf on GitHub (Oct 4, 2023).

Attempted Debugging

  • I have read the debugging page

Searched GitHub Issues

  • I have searched GitHub for the issue.

Describe the Scenario

I'm working on using Microsoft's Azure Actice Directory B2C for authentication with BookStack.
Azure AD B2C does support and use OpenID Connect, which already is supported by BookStack.
However, when setting up the OIDC configuration, I run into one of two problems, depending on whether OIDC_ISSUER_DISCOVERY is enabled or disabled:

Scenario 1: OIDC_ISSUER_DISCOVERY enabled

Azure AD B2C provides a discovery URL at https://[tenant name].b2clogin.com/[tenant name].onmicrosoft.com/[policy name]/v2.0/.well-known/openid-configuration, so I used https://[tenant name].b2clogin.com/[tenant name].onmicrosoft.com/[policy name]/v2.0/ as the OIDC_ISSUER in the BookStack configuration.

The [policy name] in the URL is the name of the B2C policy, which defines the behavior of B2C regarding UI, login method, etc.

This way, BookStack retrieves the discovery info at <issuer>/.well-known/openid-configuration correctly and gets the correct info from B2C.

Configuration

AUTH_METHOD=OIDC
AUTH_AUTO_INITIATE=false
OIDC_NAME=[Name]
OIDC_DISPLAY_NAME_CLAIMS=name
OIDC_CLIENT_ID=[B2C Client ID]
OIDC_CLIENT_SECRET=[B2C Client Secret]
OIDC_ISSUER=https://[tenant name].b2clogin.com/[tenant name].onmicrosoft.com/[policy name]/v2.0/
OIDC_ISSUER_DISCOVER=true

On login, BookStack does not redirect to the OIDC Identity Provider.
The browser displays this error message:

OIDC Discovery Error: Unexpected issuer value found on discovery response

From the code I can see that this happens when the issuer from OIDC_ISSUER does not match the issuer field in the auto discovers JSON.

The issuer URL does indeed not match.
Microsoft lists the actual issuer URL https://[tenant name].b2clogin.com/[tenant UUID]/v2.0/ in the JSON openid-configuration which is also the URL used in the actual OIDC/OAuth tokens.
This actual issuer URL is used for all B2C policies.
For the openid-configuration, however, it is necessary to distinguish between the different B2C policies, because they use different endpoints for authorization and token.

Scenario 2: OIDC_ISSUER_DISCOVERY disabled

In order to solve the problem with the issuer mismatch, I tried setting up the integration without OIDC_ISSUER_DISCOVERY:

AUTH_METHOD=OIDC
AUTH_AUTO_INITIATE=false
OIDC_NAME=[Name]
OIDC_DISPLAY_NAME_CLAIMS=name
OIDC_CLIENT_ID=[B2C Client ID]
OIDC_CLIENT_SECRET=[B2C Client Secret]
OIDC_ISSUER=https://[tenant name].b2clogin.com/[tenant UUID]/v2.0/
OIDC_ISSUER_DISCOVER=false
OIDC_PUBLIC_KEY=https://[tenant name].b2clogin.com/[tenant name].onmicrosoft.com/[policy name]/discovery/v2.0/keys
OIDC_AUTH_ENDPOINT=https://[tenant name].b2clogin.com/[tenant name].onmicrosoft.com/[policy name]/oauth2/v2.0/authorize
OIDC_TOKEN_ENDPOINT=https://[tenant name].b2clogin.com/[tenant name].onmicrosoft.com/[policy name]/oauth2/v2.0/token

I retrieved these values directly from the JSON returned from the discovery URL at https://[tenant name].b2clogin.com/[tenant name].onmicrosoft.com/[policy name]/v2.0/.well-known/openid-configuration.

BookStack then correctly redirects to the login page of B2C.
When BookStack receives the token back, the browser shows this error message:

ID token validate failed with error: Failed to read signing key with error: Unexpected type of key value provided

From what I can see in the code, this error is thrown when the OIDC key configuration does not fit into these possibilities:

  • If OIDC_ISSUER_DISCOVERY is enabled, the jwks_uri is read from the discovery JSON and the keys are then downloaded from there.
  • If auto-discovery is disabled, the configuration OIDC_PUBLIC_KEY must be a local file and the configuration string must start with file://. It is not possible to set a JWKS URI manually this way.

However in my scenario, I would like to set OIDC_PUBLIC_KEY to the JWKS URL manually, but BookStack does not allow this.

Possible solutions

I understand that Azure AD B2C might not be following the OIDC specs correctly with their difference between the actual issuer URI and the URI for openid-configuration.

Because of this, I'd like to set the OIDC endpoints manually.
I would also like to use the existing JWKS URI instead of downloading the public key files locally.
Microsoft may change keys without further notice and already provides the JWKS URI for this purpose.

Is it possible to change the behavior of the OIDC_PUBLIC_KEY configuration to allow to set JWKS URIs manually?

Exact BookStack Version

v23.08.3

Log Content

For scenario 1 with OIDC_ISSUER_DISCOVER enabled, the browser shows this error message when clicking the Login with ... button on the BookStack login page:

OIDC Discovery Error: Unexpected issuer value found on discovery response

In scenario 2 with OIDC_ISSUER_DISCOVER disabled, the browser redirects to Azure AD B2C correctly when clicking the Login with ... button.
When Azure AD B2C redirects back to BookStack, the browser shows this error message:

ID token validate failed with error: Failed to read signing key with error: Unexpected type of key value provided

The laravel.log, nginx logs, and PHP logs do not contain any errors.

Hosting Environment

I'm currently hosting this as a Proof of Concept running on Windows using Docker Desktop with WSL Ubuntu 22.04.2 LTS.

  • Host OS: Windows 11 22H2 (Build 22621.2134)
  • WSL Distribution: Ubuntu 22.04.2 LTS
  • Docker 24.0.6

I am running using the Linuxserver Docker image lscr.io/linuxserver/bookstack with mysql:8.0.32 as the image for the database container.

Originally created by @JanekOstendorf on GitHub (Oct 4, 2023). ### Attempted Debugging - [X] I have read the debugging page ### Searched GitHub Issues - [X] I have searched GitHub for the issue. ### Describe the Scenario I'm working on using Microsoft's [Azure Actice Directory B2C](https://learn.microsoft.com/en-us/azure/active-directory-b2c/overview) for authentication with BookStack. Azure AD B2C does support and use OpenID Connect, which already is supported by BookStack. However, when setting up the OIDC configuration, I run into one of two problems, depending on whether `OIDC_ISSUER_DISCOVERY` is enabled or disabled: #### Scenario 1: `OIDC_ISSUER_DISCOVERY` enabled Azure AD B2C provides a discovery URL at `https://[tenant name].b2clogin.com/[tenant name].onmicrosoft.com/[policy name]/v2.0/.well-known/openid-configuration`, so I used `https://[tenant name].b2clogin.com/[tenant name].onmicrosoft.com/[policy name]/v2.0/` as the `OIDC_ISSUER` in the BookStack configuration. The `[policy name]` in the URL is the name of the B2C policy, which defines the behavior of B2C regarding UI, login method, etc. This way, BookStack retrieves the discovery info at `<issuer>/.well-known/openid-configuration` correctly and gets the correct info from B2C. **Configuration** ```dotenv AUTH_METHOD=OIDC AUTH_AUTO_INITIATE=false OIDC_NAME=[Name] OIDC_DISPLAY_NAME_CLAIMS=name OIDC_CLIENT_ID=[B2C Client ID] OIDC_CLIENT_SECRET=[B2C Client Secret] OIDC_ISSUER=https://[tenant name].b2clogin.com/[tenant name].onmicrosoft.com/[policy name]/v2.0/ OIDC_ISSUER_DISCOVER=true ``` On login, BookStack does not redirect to the OIDC Identity Provider. The browser displays this error message: ``` OIDC Discovery Error: Unexpected issuer value found on discovery response ``` [From the code](https://github.com/BookStackApp/BookStack/blob/1267068d9c6c50a0490534187d5be67acee08179/app/Access/Oidc/OidcProviderSettings.php#L117) I can see that this happens when the issuer from `OIDC_ISSUER` does not match the `issuer` field in the auto discovers JSON. The issuer URL does indeed not match. Microsoft lists the actual issuer URL `https://[tenant name].b2clogin.com/[tenant UUID]/v2.0/` in the JSON `openid-configuration` which is also the URL used in the actual OIDC/OAuth tokens. This actual issuer URL is used for all B2C policies. For the `openid-configuration`, however, it is necessary to distinguish between the different B2C policies, because they use different endpoints for authorization and token. #### Scenario 2: `OIDC_ISSUER_DISCOVERY` disabled In order to solve the problem with the issuer mismatch, I tried setting up the integration without `OIDC_ISSUER_DISCOVERY`: ```dotenv AUTH_METHOD=OIDC AUTH_AUTO_INITIATE=false OIDC_NAME=[Name] OIDC_DISPLAY_NAME_CLAIMS=name OIDC_CLIENT_ID=[B2C Client ID] OIDC_CLIENT_SECRET=[B2C Client Secret] OIDC_ISSUER=https://[tenant name].b2clogin.com/[tenant UUID]/v2.0/ OIDC_ISSUER_DISCOVER=false OIDC_PUBLIC_KEY=https://[tenant name].b2clogin.com/[tenant name].onmicrosoft.com/[policy name]/discovery/v2.0/keys OIDC_AUTH_ENDPOINT=https://[tenant name].b2clogin.com/[tenant name].onmicrosoft.com/[policy name]/oauth2/v2.0/authorize OIDC_TOKEN_ENDPOINT=https://[tenant name].b2clogin.com/[tenant name].onmicrosoft.com/[policy name]/oauth2/v2.0/token ``` I retrieved these values directly from the JSON returned from the discovery URL at `https://[tenant name].b2clogin.com/[tenant name].onmicrosoft.com/[policy name]/v2.0/.well-known/openid-configuration`. BookStack then correctly redirects to the login page of B2C. When BookStack receives the token back, the browser shows this error message: ``` ID token validate failed with error: Failed to read signing key with error: Unexpected type of key value provided ``` From what I can see [in the code](https://github.com/BookStackApp/BookStack/blob/1267068d9c6c50a0490534187d5be67acee08179/app/Access/Oidc/OidcJwtSigningKey.php#L34), this error is thrown when the OIDC key configuration does not fit into these possibilities: - If `OIDC_ISSUER_DISCOVERY` is enabled, the `jwks_uri` is read from the discovery JSON and the keys are then downloaded from there. - If auto-discovery is disabled, the configuration `OIDC_PUBLIC_KEY` *must* be a local file and the configuration string must start with `file://`. It is not possible to set a JWKS URI manually this way. However in my scenario, I would like to set `OIDC_PUBLIC_KEY` to the JWKS URL manually, but BookStack does not allow this. #### Possible solutions I understand that Azure AD B2C might not be following the OIDC specs correctly with their difference between the actual issuer URI and the URI for `openid-configuration`. Because of this, I'd like to set the OIDC endpoints manually. I would also like to use the existing JWKS URI instead of downloading the public key files locally. Microsoft may change keys without further notice and already provides the JWKS URI for this purpose. Is it possible to change the behavior of the `OIDC_PUBLIC_KEY` configuration to allow to set JWKS URIs manually? ### Exact BookStack Version v23.08.3 ### Log Content For scenario 1 with `OIDC_ISSUER_DISCOVER` enabled, the browser shows this error message when clicking the `Login with ...` button on the BookStack login page: ``` OIDC Discovery Error: Unexpected issuer value found on discovery response ``` In scenario 2 with `OIDC_ISSUER_DISCOVER` disabled, the browser redirects to Azure AD B2C correctly when clicking the `Login with ...` button. When Azure AD B2C redirects back to BookStack, the browser shows this error message: ``` ID token validate failed with error: Failed to read signing key with error: Unexpected type of key value provided ``` The `laravel.log`, nginx logs, and PHP logs do not contain any errors. ### Hosting Environment I'm currently hosting this as a Proof of Concept running on Windows using Docker Desktop with WSL Ubuntu 22.04.2 LTS. - Host OS: Windows 11 22H2 (Build 22621.2134) - WSL Distribution: Ubuntu 22.04.2 LTS - Docker 24.0.6 I am running using the Linuxserver Docker image `lscr.io/linuxserver/bookstack` with `mysql:8.0.32` as the image for the database container.
OVERLORD added the 🐕 Support label 2026-02-05 08:22:17 +03:00
Author
Owner

@ssddanbrown commented on GitHub (Oct 4, 2023):

Hi @JanekOstendorf,
Thanks for the amount of detail provided for this.

To be honest though, I really am not keen on making changes and/or supporting features at our cost due to the complexities and issues of Microsoft. The keys setup is part of the discovery spec, and really that should be followed rather than us maintaining partial compatibility support.
It could be possible to hack support for this via the logical theme system, but might be a bit janky (fetching keys manually and caching for a time).

While looking over this issue I did come across this from Microsoft docs:
https://learn.microsoft.com/en-us/azure/active-directory-b2c/tokens-overview#compatibility

Specifically "Compatibility > Issuer (iss) claim" section which states:

If your application or library needs Azure AD B2C to be compliant with the OpenID Connect Discovery 1.0 spec, use this value.

Do you have this compatibility option active? Further related docs here.

@ssddanbrown commented on GitHub (Oct 4, 2023): Hi @JanekOstendorf, Thanks for the amount of detail provided for this. To be honest though, I really am not keen on making changes and/or supporting features at our cost due to the complexities and issues of Microsoft. The keys setup is part of the discovery spec, and really that should be followed rather than us maintaining partial compatibility support. It could be possible to hack support for this via the [logical theme system](https://github.com/BookStackApp/BookStack/blob/development/dev/docs/logical-theme-system.md), but might be a bit janky (fetching keys manually and caching for a time). While looking over this issue I did come across this from Microsoft docs: https://learn.microsoft.com/en-us/azure/active-directory-b2c/tokens-overview#compatibility Specifically "Compatibility > Issuer (iss) claim" section which states: > If your application or library needs Azure AD B2C to be compliant with the [OpenID Connect Discovery 1.0 spec](https://openid.net/specs/openid-connect-discovery-1_0.html), use this value. Do you have this compatibility option active? Further [related docs here](https://learn.microsoft.com/en-us/azure/active-directory-b2c/configure-tokens?pivots=b2c-user-flow#token-compatibility-settings).
Author
Owner

@JanekOstendorf commented on GitHub (Oct 6, 2023):

Hi! Thanks for your response.

I will check out the token compatibility and check if they work with our custom B2C policies. This looks like a good way to solve this. I'll report back.

@JanekOstendorf commented on GitHub (Oct 6, 2023): Hi! Thanks for your response. I will check out the token compatibility and check if they work with our custom B2C policies. This looks like a good way to solve this. I'll report back.
Author
Owner

@ssddanbrown commented on GitHub (Nov 2, 2023):

Since it's been a little while I'm going to go ahead and close this off.
If that solved things, please still report back though so that it can help others that may have come across the same scenario.

@ssddanbrown commented on GitHub (Nov 2, 2023): Since it's been a little while I'm going to go ahead and close this off. If that solved things, please still report back though so that it can help others that may have come across the same scenario.
Author
Owner

@JanekOstendorf commented on GitHub (Dec 19, 2023):

Hi!

I just wanted to let you know that we were able to get the Azure AD B2C integration running with the AuthorityWithTfp option enabled (https://learn.microsoft.com/en-us/azure/active-directory-b2c/tokens-overview#compatibility).

Thanks again for your help.

@JanekOstendorf commented on GitHub (Dec 19, 2023): Hi! I just wanted to let you know that we were able to get the Azure AD B2C integration running with the `AuthorityWithTfp` option enabled (https://learn.microsoft.com/en-us/azure/active-directory-b2c/tokens-overview#compatibility). Thanks again for your help.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/BookStack#4258