Using the plugin
all the classes that are exposed by this plugin start with Oidc*.
OidcUserManager
Construction
OidcUserManager is the main class this plugin provides, as the name suggests, it manages the current user session.
you have two ways to construct it, depending on the availability of the Discovery Document.
- If you have the discovery document already:
final manager = OidcUserManager( discoveryDocument: OidcProviderMetadata.fromJson({ 'issuer': 'https://server.example.com', 'authorization_endpoint': 'https://server.example.com/connect/authorize', 'token_endpoint': 'https://server.example.com/connect/token', //...other metadata }), //...other parameters. ); - If you don't have the discovery document
aside from the discovery document, both constructors share the same parameters:
Constructing multiple user managers
If you want to support multiple identity providers, you can construct multiple OidcUserManager instances, each with its own discovery document and id.
final googleManager = OidcUserManager.lazy(
id: 'google',
discoveryDocumentUri: Uri.parse('https://accounts.google.com/.well-known/openid-configuration'),
//...other parameters.
);
final microsoftManager = OidcUserManager.lazy(
id: 'microsoft',
discoveryDocumentUri: Uri.parse('https://login.microsoftonline.com/common/v2.0/.well-known/openid-configuration'),
//...other parameters.
);
clientCredentials
an OidcClientAuthentication describes how the client authenticates with the identity provider, which has the following constructors:
.none: good for public clients, only theclientIdis required..clientSecretBasic: good for confidential clients that can keep a secret. this uses the HTTP Basic authentication scheme..clientSecretPost: same asclientSecretBasic, but passes theclientIdandclientSecretas form parameters, instead ofAuthorizationheader..clientSecretJwt: you create a JWT based on theclientIdandclientSecret, instead of passing the secret directly..privateKeyJwt: similar toclientSecretJwt, but you first have to create an Asymmetric key pair, and sign the JWT using the public key.
how you create/obtain the jwt is outside the scope of this package.
you can use to help you.
-
.tlsClientAuth/.selfSignedTlsClientAuth: mutual-TLS client authentication (RFC 8705), using a CA-issued (§2.1) or a self-signed (§2.2) client certificate. Onlyclient_idgoes into the request; the proof is the certificate on the TLS connection.The certificate lives in the transport, never in
OidcClientAuthentication. Build a cert-bearing client withOidcMtls.createHttpClientand pass it as the manager'shttpClient:final mtlsClient = OidcMtls.createHttpClient( certificate: OidcMtlsClientCertificate( certificateChain: File('client.pem').readAsBytesSync(), // leaf first privateKey: File('client.key').readAsBytesSync(), // password: '...', // for an encrypted key / PKCS#12 bundle ), // Optional: trust a private CA for the SERVER's certificate. // trustedCertificates: File('ca.pem').readAsBytesSync(), ); final manager = OidcUserManager.lazy( discoveryDocumentUri: discoveryUri, clientCredentials: const OidcClientAuthentication.tlsClientAuth( clientId: 'my_client_id', ), httpClient: mtlsClient, store: OidcDefaultStore(), settings: OidcUserManagerSettings( redirectUri: redirectUri, // Use the provider's `mtls_endpoint_aliases` when it publishes them. useMtlsEndpointAliases: true, ), );- Endpoint aliases (RFC 8705 §5). With
useMtlsEndpointAliases: true, every request the client makes directly to the provider — token (all grants), UserInfo, revocation, introspection, PAR, device authorization and dynamic client registration — goes to the alias inmtls_endpoint_aliaseswhen the provider publishes one, and to the normal endpoint otherwise. The setting is opt-in and never inferred from the auth method. The authorization, end-session and check-session endpoints are visited by the browser, not called by the client, so their aliases are ignored as §5 requires.jwks_urialways uses the top-level value: it is a public read that needs no client certificate. - Certificate-bound access tokens (RFC 8705 §3). The RP has two jobs here: present the certificate at the token endpoint, and present the same certificate when it uses the token. Because the manager sends UserInfo through the same
httpClient, that is already covered. Call your resource servers with the samemtlsClientas well. Checking the token'scnf/x5t#S256is the resource server's job, not this library's. - Dynamic client registration. A registration response with
token_endpoint_auth_methodset totls_client_authorself_signed_tls_client_authbecomes the matching mTLS credentials. The certificate still comes fromhttpClient. - Platforms. VM, Android, iOS, macOS, Windows and Linux are supported through
dart:io'sSecurityContext. If you already have aSecurityContext, you can passIOClient(HttpClient(context: context))directly. Web is not supported: browsers givefetch/XHR no way to present a client certificate. On web,OidcMtls.isSupportedisfalse,OidcMtls.createHttpClientthrows anUnsupportedError, andinit()throws anUnsupportedErrorbefore any network call when the manager is configured with an mTLS method (or a registration hands it one).
- Endpoint aliases (RFC 8705 §5). With
store
an instance of OidcStore, we provide 3 types of stores out of the box, depending on your use case:
OidcMemoryStorefrom package:oidc_core; which stores the auth state in memory (good for CLI apps or during testing).OidcDefaultStorefrom package:oidc_default_store; which persists the auth state on disk orlocalStorageon web, And tries to encrypt the data if possible.OidcWebStorefrom package:oidc_web_core; which persists the auth state onlocalStorage/session_storageon web.
settings
settings to control the behavior of the instance.
-
bool supportOfflineAuth = false: whether the app should keep expired tokens if it's not able to contact the server.Warning
Enabling offline auth can be a security risk, as it allows the app to keep tokens that are no longer valid. And it may open up unexpected attack vectors.
Tip
For detailed information about offline authentication, including security best practices, error handling, and implementation examples, see the Offline Authentication Guide.
-
ID-token (and signed UserInfo / signed discovery
signed_metadata) signature verification is always strict (fail-closed): a token/response whose signature cannot be verified is rejected. There is no opt-out setting.Key rotation
A
kidthat isn't in the currently-cached JWKS (e.g. right after the OP rotates its signing keys) triggers one rate-limited, cache-busting JWKS refetch before failing, so a routine key rotation does not cause spurious login failures.HS256 id_tokens (e.g. Auth0's default client signing algorithm)
Some OPs (Auth0 in particular, for confidential clients by default) sign id_tokens with
HS256, a symmetric algorithm keyed by yourclient_secretrather than a JWKS-published public key. Verifying these requires passingclientSecreton yourOidcClientAuthentication— the manager registers it as the HS256 verification key duringinit(). Without aclientSecret, an HS256-signed id_token cannot be verified and login will fail-closed.Uri redirectUri: the redirect uri that was configured with the provider.Uri? postLogoutRedirectUri: the post logout redirect uri that was configured with the provider.Uri? frontChannelLogoutUri: the uri of the front channel logout flow. this Uri MUST be registered with the OP first. the OP will call this Uri when it wants to logout the user.Future<String?> Function(OidcToken token) getIdToken: pass this function to control how an idToken is fetched from a token response. This can be used to trick the user manager into using a JWTaccess_tokenas anid_tokenfor example.frontChannelRequestListeningOptions: the options to use when listening for front channel logout requests.frontChannelRequestListeningOptions: OidcFrontChannelRequestListeningOptions( //currently only supports web. web: OidcFrontChannelRequestListeningOptions_Web( broadcastChannel: 'oidc_flutter_web/request' ) )Note that this channel needs to be the same as the one in your redirect.html page.
-
Duration expiryTolerance: also known as clock skew, it's a small duration that lengthens the token expiry time, to account for communication delays; default is 1 minute. -
Duration? Function(OidcToken token)? refreshBefore: a function that controls how you want the automatic refresh_token handling to work. you receive a token, and you decide for it how early the token gets refreshed. for example:- if
Duration.zerois returned, the token gets refreshed once it's expired. - if
nullis returned, automatic refresh is disabled.
by default, this is a function that returns
Duration(minutes: 1)for every token, which means that all tokens are refreshed 1 minute before they expire. - if
-
Duration? Function(OidcTokenResponse tokenResponse)? getExpiresIn: a function that overrides a token's expires_in value, it's not recommended to change this, since it's only used for testing. -
OidcSessionManagementSettings sessionManagementSettings: contains settings for the session management spec:bool enabled: (default false) whether to enable checking the session.Duration interval: (default 5 seconds) how often to check the current user session.bool stopIfErrorReceived: (default true) whether to stop checking the current user session if the OP sends anerrormessage.Duration endSessionConfirmationTimeout: (default 10 seconds) how long the one-off post-logoutcheck_session_iframeprobe waits for the OP's answer before reportingtimedOut(see Confirming logout at the OP). It never delays logout itself.
-
OidcPlatformSpecificOptions? options: platform specific options to control auth requests:bool allowInsecureConnections: Whether to allow non-HTTPS endpoints; forandroid🤖 platform only.-
OidcAppAuthExternalUserAgent externalUserAgent: Selects the strategy for opening external browser in ios📱and macos 💻:-
asWebAuthenticationSession(default) Uses the ASWebAuthenticationSession APIs where possible.This is the default for macOS and iOS 12 and above. On iOS 11, it will use SFAuthenticationSession instead.
Behind the scenes, the plugin makes use of the default external user-agent provided by the AppAuth iOS SDK. This will use the best user-agent available on the device. Specifically, on iOS it will use OIDExternalUserAgentIOS and on macOS it will use OIDExternalUserAgentMac.
Using this follows the best practices on using the appropriate native APIs based on the OS version. -
ephemeralAsWebAuthenticationSession: Indicates a preference in using an ephemeral sessions by using the ASWebAuthenticationSession APIs where possible. This is only applicable to macOS and iOS 12 and above. On these platforms, the session will not share browser data with user's normal browser session and does not keep the cache.Like
asWebAuthenticationSession, it fallback to use SFAuthenticationSession on iOS 11 where there's no support for ephemeral sessions. -sfSafariViewController: Uses the SFSafariViewController APIs. This does not share browser data with the user's normal browser session but keeps the cache.This is only applicable to iOS. On macOS, it will use the same behavior as
asWebAuthenticationSession. One reason for using this is when applications trigger an end session request but wants to avoid the prompt that would have appeared when the ASWebAuthenticationSession APIs are used.In this case, there's concern that the system-generated prompt would confuse the user as they are trying to sign out but the prompt states that it's taking the user through a sign-in flow.
Note that as this does not follow the best practices on using the appropriate native APIs based on the OS version, developers should use this at their own discretion.
-
-
Native options: these are options that apply to desktop 🖥️ platforms (linux $$+ windows) that use loopback interface redirection, to customize how the server responds to redirect responses:
String? successfulPageResponse: What to return if a URI is matchedString? methodMismatchResponse: What to return if a method other thanGETis requested.String? notFoundResponse: What to return if a different path is used.
- Web 🌐 options:
OidcPlatformSpecificOptions_Web_NavigationMode navigationMode: how the auth request is launched; possible values are:samePage: NOT RECOMMENDED; since you have to reload your app and lose current ui state.newPage: RECOMMENDED, navigates in a new tab.popup: NOT RECOMMENDED; since some browsers block popups.you can also pass
popupWidthandpopupHeightto control the popup window dimensions.
String broadcastChannel: The broadcast channel to use when receiving messages from the browser; defaults to:oidc_flutter_web/redirectNote: This MUST be the same as the one in your redirect.html page.
Hooks
OidcUserManagerHooks? hooks: a set of hooks that allow you to customize the behavior of the user manager.
- All hooks inherit
OidcHookMixin<TRequest, TResponse>, which is just a marker mixin. - By default, we support the following hooks:
token: to hook into the token request and response.authorization: to hook into the authorization request and response.
To define a hook you can either extend OidcHookBase, or use the OidcHook class directly.
Example:
To remove the scope from the refresh_token request, you can define a hook like this:
OidcUserManagerSettings(
hooks: OidcUserManagerHooks(
token: OidcHook(
modifyRequest: (request) {
if (request.request.grantType == 'refresh_token') {
// Remove the scope from refresh_token requests
request.request.scope = null;
}
return Future.value(request);
},
),
),
),
You can also group multiple hooks together, for example:
hooks: OidcUserManagerHooks(
token: OidcHookGroup(
// Only modifyRequest, modifyResponse hooks can be chained.
hooks: [
OidcHook(
modifyResponse: (response) {
logger.info(
'Modifying token response: ${response.src}',
);
return Future.value(response);
},
),
],
// Only a single executionHook can be defined for the group.
executionHook: OidcHook(
modifyExecution: (request, defaultExecution) async {
logger.info(
'Executing token request: ${request.request.toMap()}',
);
final response = await defaultExecution(request);
logger.info(
'Executed token request: ${response.src}',
);
return response;
},
),
),
),
Default Auth request parameters
These are parameters that you send with the auth request, and you can either define them in the login* functions, or define the default values here.
List<String> scope: possible values are inOidcConstants_Scopes- openid
- profile
- address
- phone
List<String> prompt: possible values are inOidcConstants_AuthorizeRequest_Prompt- none
- login
- consent
- selectAccount
String? display: possible values are inOidcConstants_AuthorizeRequest_Display- page
- popup
- touch
- wap
List<String>? uiLocalesList<String>? acrValuesDuration? maxAgeMap<String, dynamic>? extraAuthenticationParameters: these are extra parameters that you can send with every authentication request.Map<String, String>? extraTokenHeaders: these are extra headers that you can send with every token request.Map<String, dynamic>? extraTokenParameters: these are extra parameters that you can send with every token request.
httpClient
We depend on , and you can provide your own http client which will let you intercept and modify request/response behavior.
This is also where mutual-TLS gets its client certificate: pass the client from OidcMtls.createHttpClient (see clientCredentials, item 6).
keyStore
A custom keystore from , if you want to maintain your own store.
this is used for validating the JWT signature.
Initialization
After constructing the manager with the proper settings, you MUST call the manager.init() function, which will do the following:
- If the function has already been initialized (checked via the hasInit variable), it simply returns. This is because certain configurations and setups do not need to be repeated.
- initialize the passed store (calls
OidcStore.init()) - ensure that the discovery document has been retrieved (if the lazy constructor was used).
- if the discovery document contains a
jwks_uriadds it the to the keystore. - handle various state management tasks. It loads logout requests and state results (from samePage redirects), also attempts to load cached tokens if there are no state results or logout requests.
- If the loaded token has expired and a refresh token exists, it attempts to refresh it, otherwise the token will be removed form the store.
- Starts Listening to incoming Front Channel Logout requests.
- Starts listening to token expiry events for automatic
refresh_tokencirculation.
Login
loginAuthorizationCodeFlow
If you provided the settings earlier, there are no required parameters here, so you can just call manager.loginAuthorizationCodeFlow().
however there are some new parameters:
originalUri: mainly used forsamePagenavigation on web; this is the Uri the user will navigate to after they are redirected to theredirect.htmlpageextraStateData: arbitrary data that you want to persist in the state parameter, note that this MUST be json serializable.idTokenHintOverride: pass anid_token_hint.includeIdTokenHintFromCurrentUser: if true, will include the currentid_tokenas theidTokenHintparameter.Note that this is ignored if
idTokenHintOverrideis assigned.- if you pass
optionshere and at the settings, they WILL NOT get merged, and the options from the login request takes precedence. -
extraParameters: extra parameters that will get passed to the auth server as part of the request. These ARE merged withsettings.extraAuthenticationParameters. -
extraTokenParameters: extra parameters that will get passed to the auth server when making the token request. These ARE merged withsettings.extraTokenParameters. extraTokenHeaders: extra parameters that will get passed to the auth server when making the token request. These ARE merged withsettings.extraTokenHeaders.
loginImplicitFlow
Same parameters as loginAuthorizationCodeFlow, but you MUST specify the responseType.
possible values are in OidcConstants_AuthorizationEndpoint_ResponseType:
idTokentokencode
and any combination of them.
Warning
This flow is deprecated due to security concerns, and is only available for backward-compatibility with providers that don't support invoking the token endpoint without a client_secret (like google).
loginPassword
you only need to provide the username and the password.
you can also pass scopeOverride to override the scopes from settings.scopes.
Logout
The word "Logout" can have different behaviors depending on the context:
Forgetting the user
- this is as simple as calling
forgetUser()which will clear the cache, and unassign thecurrentUser. - this DOES NOT inform the identity provider that the user has logged out, nor revoke the token.
Note
A user that logs in after being forgotten, might not get prompted to enter their username/password again, keeping them in an infinite loop unable to change their credentials.
To counter this, you need to specify the prompt parameter when logging in (e.g. prompt: ["login"]), or logout from the Identity provider.
Logging out from the identity provider.
This can be done by calling logout with the following optional parameters:
logoutHint: can be the email/username or any documented value.postLogoutRedirectUriOverride: if assigned, overrides the value passed insettings.postLogoutRedirectUri.originalUri: mainly used forsamePagenavigation on web; this is the Uri the user will navigate to after they are redirected to theredirect.htmlpage.extraStateData: arbitrary data that you want to persist in the state parameter, note that this MUST be json serializable.uiLocalesOverride: overrides the value passed insettings.uiLocales.options: platform-specific navigation options, which are the same assettings.options.extraParameters: extra parameters to pass to the logout request.
Session Management
OpenID Connect Session Management 1.0 lets the RP poll whether the user's session at the OP is still alive, by embedding check_session_iframe in a frame it controls and reading back the OP's postMessage answer ("unchanged" / "changed" / "error"). package:oidc implements this on web only — this is a deliberate, permanent scoping decision, not a gap awaiting a native implementation:
Note
On native platforms (Android, iOS, macOS, Linux, Windows), RFC 8252 §8.12 requires login to run in an external user-agent (the system browser), never an embedded WebView — so the app has no browser surface of its own to host check_session_iframe in. And even an app-controlled WebView created purely to poll the session would not work around this: OpenID Connect Session Management 1.0 §3.2 computes the answer from the OP session cookie held by whichever user-agent is loading the iframe, and that cookie lives in the EXTERNAL browser the §8.12 login happened in — a separate, freshly-created WebView carries no such cookie and could only ever report "changed".
Detect a session that ended at the OP on native platforms through other signals instead:
OidcTokenRefreshFailedEventonmanager.events()— a terminal automatic token-refresh failure (e.g.invalid_grant) surfaces the next time the token is refreshed.OidcUserInfoFailedEventonmanager.events()— a401from the userinfo endpoint surfaces the next time it's called.- Front-Channel Logout / Back-Channel Logout, if your OP can push the logout to the app directly.
- OpenID Connect Native SSO for Mobile Apps, if several apps from the same vendor need to share a signed-out state.
None of these are instant the way check_session_iframe polling is on web — they surface on the next token use, not the moment the OP session actually ends.
Listening to currentUser changes
Whenever a user logs in, logs out, or a token gets refreshed automatically, an event is added to the userChanges() stream.
This is similar to firebase auth, and can be used to track the current session.
You can also get access to the current authenticated user via currentUser property.
userChanges() replays the current user to every new listener, even before init() has completed. At that point the current user is still the initial null, so a listener attached before init() can't tell "not initialized yet" apart from "signed out".
If you need that distinction, for example because you subscribe before init() alongside events() (which has to happen before init() to observe an invalid_grant while the cached session is restored), use userChangesAfterInit() instead. It emits nothing until init() completes, then emits the settled user, then every later change. Any null it emits means signed out:
manager.events().listen(handleEvent);
manager.userChangesAfterInit().listen((user) {
// Only runs once init() has completed; null here really means signed out.
});
await manager.init();
If init() fails, userChangesAfterInit() emits the error and closes. If the manager is disposed before init() completes, it closes without emitting.
Listening to events
Events are an advanced form of user changes, since they occur in more places than the currentUser stream, and help the developer hook into every flow.
for example you might want to make an API call before logging out the user, then you would do:
manager.events().listen((event) {
switch (event) {
case OidcPreLogoutEvent(:final currentUser):
// make an api call with the currentUser.
break;
default:
}
});
Confirming logout at the OP (Session Management)
When session management is enabled (sessionManagementSettings.enabled), the OP advertises a check_session_iframe, and the signed-in session has a session_state, logout() asks the OP's check_session_iframe once more about the session it just ended, after the OP's end-session response arrives (including a web samePage logout resumed on the reloaded page). The answer is reported as an OidcEndSessionConfirmationEvent:
outcome |
meaning |
|---|---|
changed |
the expected answer after a successful logout, but not proof of it (see below). |
unchanged |
the OP still considers the session alive, so the OP-side logout did not take, e.g. the End-User declined to log out of the OP (RP-Initiated Logout 1.0 §2 lets the OP ask). This app is still logged out locally. |
error |
the OP iframe answered error (or an unknown value), or the probe failed. |
timedOut |
no answer within sessionManagementSettings.endSessionConfirmationTimeout. |
Only unchanged is a reliable signal. changed also shows up when the logout did not happen: when the browser blocks third-party cookies or storage (Safari and Firefox block or partition the OP iframe's cookies by default), cookie-based OPs "might then return changed for every single call" (Session Management 1.0 §5.1), and changes to unrelated sessions can produce false positives (§3.2).
The check runs in the background: the user is forgotten and userChanges() emits null without waiting for it, so the event usually arrives after that. The manager does not act on the outcome (it does not re-authenticate with prompt=none, which would sign the user back in); what to do, for example telling the user they are still signed in at the OP, is up to the app. The event is not emitted on platforms without session monitoring (everything except web), or if the manager is disposed or a new session starts before the OP answers.
On web with the samePage navigation mode, the end-session response is handled during init() on the reloaded page, so the event is emitted there: subscribe to events() before calling init() to receive it.
manager.events().listen((event) {
if (event case OidcEndSessionConfirmationEvent(
outcome: OidcEndSessionConfirmationOutcome.unchanged,
)) {
// Logged out of this app, but still signed in at the OP.
}
});
Revoking tokens
The OidcUserManager provides methods to revoke tokens at the authorization server, making them invalid for future use.
revokeAccessToken
Revokes the current user's access token, making it invalid for accessing protected resources.
// Revoke current user's access token and forget user
await manager.revokeAccessToken();
// Revoke specific token without forgetting user
await manager.revokeAccessToken(
overrideAccessToken: 'specific_token',
forgetUser: false,
);
// Revoke with custom headers
await manager.revokeAccessToken(
headers: {'Custom-Header': 'value'},
extraBodyFields: {'custom_param': 'value'},
);
Parameters:
- discoveryDocumentOverride: Optional discovery document to use instead of the default
- options: Platform-specific options for the revocation request
- forgetUser: Whether to forget the current user after successful revocation (defaults to true)
- overrideAccessToken: Specific access token to revoke instead of the current user's token
- revocationEndpointOverride: Custom revocation endpoint URL to use
- extraBodyFields: Additional fields to include in the revocation request body
- headers: Additional HTTP headers to include in the request
revokeRefreshToken
Revokes the current user's refresh token, making it invalid for obtaining new access tokens.
// Revoke current user's refresh token
await manager.revokeRefreshToken();
// Revoke specific refresh token with custom endpoint
await manager.revokeRefreshToken(
overrideRefreshToken: 'specific_refresh_token',
revocationEndpointOverride: Uri.parse('https://custom.revoke.endpoint'),
);
Parameters:
- discoveryDocumentOverride: Optional discovery document to use instead of the default
- options: Platform-specific options for the revocation request
- forgetUser: Whether to forget the current user after successful revocation (defaults to true)
- overrideRefreshToken: Specific refresh token to revoke instead of the current user's token
- revocationEndpointOverride: Custom revocation endpoint URL to use
- extraBodyFields: Additional fields to include in the revocation request body
- headers: Additional HTTP headers to include in the request
Behavior:
- Both methods return early if no current user exists
- Both methods return early if the respective token is not available to revoke
- Both methods return early if the authorization server doesn't provide a revocation endpoint
- Both methods call forgetUser() automatically after successful revocation when forgetUser is true
- Both methods use the hooks system to allow customization of the revocation process
Note
Token revocation is a best-effort operation. Some authorization servers may not support token revocation, in which case these methods will return without error. Always check your authorization server's capabilities before relying on token revocation.
Refreshing the token manually
You can refresh the token manually by calling manager.refreshToken().
You can also override the refresh token manager.refreshToken(overrideRefreshToken: 'my_refresh_token').
It will either return OidcUser with the new token, null or throw an [OidcException].
null is returned in the following cases:
- The discovery document doesn't have
grant_types_supportedincluderefresh_token - The current user is null.
- The current user's refresh token is null.
Overriding the discovery document
There are cases where you want to change some properties in the retrieved discovery document, either permanently, or for a specific method.
e.g., you might want to have a register and a login button where the register button overrides the discovery document's authorizationEndpoint parameter, but the login button uses the idp provided value.
We use package:copy_with_extension_gen to generate copyWith extension methods to help consumers override specific parts of the OidcProviderMetadata discovery document.
Permanent override
You can do that via the discoveryDocument setter in OidcUserManager, e.g.
final userManager = OidcUserManager.lazy(/*...*/);
await userManager.init();
userManager.discoveryDocument = userManager.discoveryDocument.copyWith(/*...*/);
Per-method override
You can pass the OidcProviderMetadata? discoveryDocumentOverride parameter in some methods.
Example:
final userManager = OidcUserManager.lazy(/*...*/);
await userManager.init();
await userManager.loginAuthorizationCodeFlow(
discoveryDocumentOverride: userManager.discoveryDocument.copyWith(
authorizationEndpoint: "https://idp.com/register", //change to register url instead of login
)
);
Dispose
If you aren't maintaining a single instance of the OidcUserManager class, you might want to dispose() it when you are done with the instance.
This will stop refreshing the tokens, and stop listening to logout requests.
It will also raise a done event in the userChanges() stream.
OidcFlutter
The class OidcFlutter exposes static methods for the underlying platform implementations, if you don't want to use the OidcUserManager class.
They are defined as such:
/// starts the authorization flow, and returns the response.
///
/// on android/ios/macos, if the `request.responseType` is set to anything other than `code`, it returns null.
///
/// NOTE: this DOES NOT do token exchange.
///
/// consider using [OidcEndpoints.getProviderMetadata] to get the [metadata] parameter if you don't have it.
static Future<OidcAuthorizeResponse?> getPlatformAuthorizationResponse({
required OidcProviderMetadata metadata,
required OidcAuthorizeRequest request,
OidcPlatformSpecificOptions options = const OidcPlatformSpecificOptions(),
});
/// starts the end session flow, and returns the response.
///
/// consider using [OidcEndpoints.getProviderMetadata] to get the [metadata] parameter if you don't have it.
static Future<OidcEndSessionResponse?> getPlatformEndSessionResponse({
required OidcProviderMetadata metadata,
required OidcEndSessionRequest request,
OidcPlatformSpecificOptions options = const OidcPlatformSpecificOptions(),
});
/// Listens to incoming front channel logout requests.
///
/// [listenTo] parameter determines which path should be listened for to receive
/// the request.
///
/// on windows/linux/macosx this starts a server on the same prt
static Stream<OidcFrontChannelLogoutIncomingRequest> listenToFrontChannelLogoutRequests({
required Uri listenTo,
OidcFrontChannelRequestListeningOptions options = const OidcFrontChannelRequestListeningOptions(),
});