Auth: hbf-webchat
How this widget handles authentication. Full flows:
docs/architecture/auth-flows.md
This is an embeddable browser widget, not a backend service.
Tokens This Service Accepts
N/A. This is a client-side widget. It does not expose an API or validate incoming tokens.
Tokens This Service Sends
| Calling | Token used | How attached |
|---|---|---|
| Bot Framework Direct Line (WebSocket) | Direct Line token obtained from tokenURL | Authorization: Bearer <token> via createDirectLine({ token }) |
Tokens This Service Issues
None.
Authentication Flow
- Init: Host page calls
window.HBFWebchat.init({ deploymentId, apiUrl }). - Config fetch:
GET {apiUrl}/public/bot-deployments/{deploymentId}(unauthenticated). Returns widget configuration including the tokenURL. - Token fetch:
GET {tokenURL}(typically a Lambda endpoint). Returns{ token, expires_in }. - Direct Line connection:
createDirectLine({ token })establishes the WebSocket connection to Bot Framework.
User Identity Resolution
Resolved in priority order:
window.HBF_retrieveUserId()function (host page provides identity)- URL parameter
?hsh=<id> - Previously stored localStorage value (
wcUserId) - Generated fallback:
hbf-{uuidv4()}
Optional user info callbacks:
window.HBF_retrieveUserInfo()returns{ name, email, language, customData }.window.HBF_retrieveMetadata()returns page context metadata.
Token Storage
Stored in localStorage under the botDiv key as a JSON object:
| Field | Purpose |
|---|---|
token | Current Direct Line token |
tokenExpiresAt | Token expiry timestamp |
expiresAt | Session expiry timestamp |
wcUserId | Resolved user ID |
conversationId | Active conversation ID |
watermark | Message watermark for resuming |
wcUserInfo | Cached user info |
wcMetadata | Cached page metadata |
Roles / Scopes Enforced
None. The widget operates as an anonymous or guest client. There is no role-based access control.
Pre-Auth Token Passing
Host pages can pass OIDC tokens at init time via HBF_retrieveUserInfo():
window.HBF_retrieveUserInfo = () => ({
name: "...",
email: "...",
customData: {
authToken: "<jwt>", // extracted, not forwarded in customData
authRefreshToken: "<refresh>", // optional, same treatment
otherField: "value" // remains in customData normally
}
});
invokeCustomFunctions() extracts authToken and authRefreshToken from customData, stores them on the widget instance, and strips them before customData reaches channelData.user. On every outbound activity, the stored tokens are injected into channelData.auth.token (and channelData.auth.refreshToken if present). This is how hbf-bot's PreAuthTokenStrategy receives the token.
If customFunctionsIntervalTime is configured, tokens are re-read on each interval tick, allowing the host page to rotate tokens dynamically.
Auth Notes
- No explicit user authentication is required. Anonymous/guest users are supported via the generated UUID identity.
- The deprecated
secretparameter bypasses the tokenURL and connects directly. Using it logs a console warning. - Direct Line tokens expire after approximately 15 minutes and are re-fetched on expiry.
- Session duration is configurable (default: 365 days).