'#' ( pound or hash ) Character not Supported in Application Callback URL

Problem statement

We experienced an error after deploying our SPA application:

The scope ‘offline_access’ was requested, but no ‘refresh_token’ was issued because the authorization code exchange originated from a browser .”

Symptoms

Repeated instances of this message appear in the tenant logs:

The scope ‘offline_access’ was requested, but no ‘refresh_token’ was issued because the authorization code exchange originated from a browser.”

  • These errors are typically associated with a specific application.
  • If more than one application has been misconfigured, these messages may be associated with two or more applications.

Steps to reproduce

Configure an application that features the ‘#’ character in one or more of the Callback URLs.

Troubleshooting

  • Check the tenant logs for instances of the error:

The scope ‘offline_access’ was requested, but no ‘refresh_token’ was issued because the authorization code exchange originated from a browser.”

  • Check the application settings for instances of Callback URLs that include the ‘#’ character in the path. For example: https://auth.example.com.au/webclient/#/callback

Cause

The ‘#’ ( pound or hash ) character within a URL acts as an anchor or bookmark to another part of the URL resource, as explained in this MDN reference document:

Auth0 does not support the user of the ‘#’ within Callback URLs and the OAuth standards advise against its use.

OAuth RFC states that a fragment component (what comes after the # symbol) must not be used in redirect URIs. Note fragments are only used by browsers to find something locally in the web page after it has been loaded and as such are not sent along with HTTP requests. Even if currently configured a callback URL in Auth0 with a fragment component, what comes after the # will not be included by browsers in the redirection to authorize, and on the app callback, browsers will interpret everything after # as a fragment and not a query parameter.

Solution

Avoid using the ‘#’ character within Callback URLs.