Copyright © Bentley Systems, Incorporated. All rights reserved. See LICENSE.md for license terms and full copyright notice.
The @itwin/browser-authorization package contains a browser based client for authorization with the iTwin platform.
Create a new instance of BrowserAuthorizationClient, passing in needed credentials:
const client = new BrowserAuthorizationClient({
clientId: // find at developer.bentley.com
redirectUri: // find/set at developer.bentley.com
scope: // find/set at developer.bentley.com
authority: // ims.bentley.com
postSignoutRedirectUri: // find/set at developer.bentley.com (see note below)
responseType: "code",
silentRedirectUri: // find/set at developer.bentley.com
});Important! The above
postSignoutRedirectUriwill not fully work if the url ends with /logout and https is not supported on your site. For local development where https is less common, we suggest using /logout-local for the url path.
The most common way to use an instance of BrowserAuthorizationClient will depend on your specific application and workflow. Here's one common way:
// will attempt to sign in silently,
// and then via redirect if not possible.
await client.signInRedirect();Instead of a redirect, you may want to trigger a pop up to handle the sign in process:
await client.signInPopup();After the user signs in, they will be redirected to the redirect url specified in your oidc configuration (developer.bentley.com) Once on that page, you must call:
await client.handleSigninCallback();to complete the process. Once back on your initial page, the call to client.signInSilent will succeed and you should be authorized.
If the callback occurs on a page where the configured client is not available, you can use the static method to complete the process:
await BrowserAuthorizationClient.handleSigninCallback();
// This library defaults to localStorage for storing state.
// To use sessionStorage (or another Storage object), you can pass it as an argument.
// If overriding the default localStorage, also set the stateStore via client.setAdvancedSettings({stateStore: yourStore})
await BrowserAuthorizationClient.handleSigninCallback(window.sessionStorage);This will pull the client configuration from localStorage, using the state nonce provided by OIDC to select the proper configuration.
Other notable methods:
client.signOutRedirect() - starts the signout flow via redirect
client.signOutPopup() - starts the signout flow via popup.
client.setAdvancedSettings(userManagerSettings) - Allows for advanced options to be supplied to the underlying UserManager.
The silentRedirectUri is required for automatic token renewal to work. Without it, your access token will expire after approximately 1 hour with no warning.
Token renewal happens in a hidden iframe approximately every 55 minutes. For best performance, this should point to a dedicated lightweight page rather than your main application.
(Your implementation may vary)
Create a lightweight HTML file (e.g., silent-callback.html) in your public/static folder:
<!DOCTYPE html>
<html>
<head>
<title>Silent Callback</title>
</head>
<body>
<script type="module">
import { BrowserAuthorizationClient } from "@itwin/browser-authorization";
const client = new BrowserAuthorizationClient({
clientId: "...",
redirectUri: "https://yourapp.com/callback",
silentRedirectUri: "https://yourapp.com/silent-callback.html", // dedicated lightweight page
scope: "...",
});
await client.handleSignInCallback();
</script>
</body>
</html>
> **Note:** The `silentRedirectUri` must also be registered as a valid redirect
URI for your client in the [developer portal](https://developer.bentley.com). ##
Authorization Overview For information about the browser authorization workflow
please visit the [Authorization Overview
Page](https://developer.bentley.com/apis/overview/authorization/#authorizingwebapplications).
## Running integration tests - Ensure you've run `rush update` (or `rush
install`) and `rush build` - Create an .env file based on .env.example - ask
Arun G or Ben P for the values. - `rush test:integration` will run integration
tests for the entire repo. - `rushx test:integration` runs the tests only in the
Browser package. - Playwright options are in playwright.config.ts (head-ful vs
headless, timeouts, etc). - The tests start the /test-app using vite before
running. - To run only the test app: `rushx test:integration:start-test-app` and
access <http://localhost:5173> in your browser.