-
Notifications
You must be signed in to change notification settings - Fork 7
IIIF Auth 2.0 Support
Ramp supports the IIIF Authentication Flow API 2.0 for Canvases with media resource(s) that require authorization before playback. When a Canvas' Annotation body declares a service block containing an AuthProbeService2, Ramp renders a login overlay over the player and drives the probe -> access -> token exchange described by the spec before allowing playback to start.
Ramp reads and parses service property off the first Annotation's body for each Canvas. If the body property is a Choice (multiple source qualities/formats), the auth service is read from the first item in body.items, and Ramp assumes auth service information is identical across all choices in a single Canvas.
The nested auth service structure Probe → AccessService → [Token, Logout] is then parsed to:
-
AuthProbeService2- as the top-level probe service. And is required for auth to be recognized -
AuthAccessService2— nested under the probe's ownservicearray; only services with either'active'or'kiosk'are used -
AuthAccessTokenService2andAuthLogoutService2— nested under the access service'sservicearray
An example nested auth service block looks as follows;
"service": [
{
"id": "https://example.org/iiif/auth/probe",
"type": "AuthProbeService2",
"service": [
{
"id": "https://example.org/iiif/auth/login",
"type": "AuthAccessService2",
"profile": "active",
"label": { "en": ["Login"] },
"service": [
{ "id": "https://example.org/iiif/auth/token", "type": "AuthAccessTokenService2" },
{ "id": "https://example.org/iiif/auth/logout", "type": "AuthLogoutService2", "label": { "en": ["Sign out"] } }
]
}
]
}
]
If no AuthAccessService2 or no AuthAccessTokenService2 is found under the probe, the Canvas is flagged restricted: true and Ramp displays an error state instead of a login prompt, since there's no way to complete the auth flow.
Auth status for the currently active Canvas is tracked in the central state via Context Providers under state.auth: { token, status } property. The value of status moves through: idle -> probing -> login-required | authorized | error | cancelled.
Auth state resets to idle on logout (see below), which re-triggers the initial probe to display the login prompt.
Ramp follows the expected auth flow from a IIIF client detailed in the IIIF Auth spec 2.0.
AuthOverlay.js renders over the VideoJSPlayer whenever a Canvas has a non-restricted auth service, and drives the flow:
-
Request probe on mount as an unauthenticated
GETto the probe service'sid. A200sets status toauthorized; anything else setslogin-requiredand the overlay renders the login prompt with descriptive properties available from the parsed access service. -
Request login when clicked on the
Loginbutton depending on the access service'sprofile:-
kiosk— acquires a token immediately without a user interaction -
active— opens the access serviceidin a new tab and polls every 500ms for the tab to close. If the browser blocks the popup, Ramp falls back to acquiring the token directly without opening a tab.
-
-
Token acquisition appends a
messageIdand the client'soriginto the token service URL, loads it in a hidden,iframe, and listens for amessageevent using post Message API where, a successful response resolves{ accessToken, expiresIn }. -
Re-probe with the received token with
Authorization: Bearer <token>. A200marks the Canvasauthorizedand stores the token in central state; otherwise the overlay shows an error using descriptive properties if the probe or token service provides it.
Cancelling mid-flow (closing the login tab manually, or clicking Cancel) clears the polling interval, closes any open login tab, and sets status to cancelled, dismissing the overlay without retrying.
When the parsed access service defines an AuthLogoutService2, Ramp displays a logout control once the user is authorized. Per the logout interaction spec, the logout action button simply opens a new tab with the results of the HTTP GET request on the logout service’s URI in the browser, which is expected to end the server-side session.
Because the usable space provided to display a logout menu is different for video vs. audio, Ramp uses two different UI choices:
-
For video players —
AuthOverlayrenders a persistent "Authenticated" badge in the top-right corner of the player once authenticated successfully. Clicking it opens a keyboard accessible popup menu showing an optional label from the logout service and a "Log out" action.
-
For audio players - a custom VideoJS component named
VideoJSAuthMenu.jsrenders aMenuButtoncomponent, inserted into the control-bar immediately at the end of the control-bar. Since the control-bar is always visible for audio players (unlike video, where it auto-hides during playback) with enough usable space, this provides a clear UI for this functionality in audio players. It renders a control icon that opens an optional label from the logout service and "Log out" menu pattern similarly.
Both logout actions invoke the same logout sequence in Ramp:
- Tears down and disables the current player instance so the authenticated media is removed from playback immediately, and resets the player's aspect ratio back to
16:9(accommodating the login overlay's layout, since authenticated player may have used a different ratio). - Opens the logout URI in a new tab to clear the server-side session.
- Clears the stored token/status back to
idlein central state in Context Providers in Ramp, which causesAuthOverlayto re-run its initial probe to re-render the login prompt.
Keyboard accessibility: both logout menu buttons and menu items are reachable via keyboard navigation.
(support from @samvera/ramp — version pending release; implemented in PRs #959 and #979) 🚀🔥
- AutoAdvanceToggle
- IIIFPlayer
- Annotations
-
MediaPlayer
- Player hotkeys
- Inaccessible resource display
- Forced Text Tracks
- Audio Description (AD) support (New in 5.1.0 🚀)
- Resume Playback (New in 5.1.0 🚀)
- IIIF Auth 2.0 Support (Next release 🚀)
- MetadataDisplay
- StructuredNavigation
- SupplementalFiles
- Transcript