This library is a Xamarin library for communicating with Okta as an OAuth 2.0 + OpenID Connect provider, it follows current best practice for native apps using Authorization Code Flow + PKCE.
This library uses semantic versioning and follows Okta's library version policy.
| Version | Status |
|---|---|
| 1.x | ✔️ Stable |
| 2.x | ✔️ Stable |
| 3.x | ✔️ Stable |
The latest release is found on the releases page.
To use the Okta Xamarin Sdk do the following:
- Create an Okta account, also know as an organization, see Developer Signup.
- In your
Okta Developer Consoleadd an application; follow the directions at Set up your Application and accept the defaults. - In your
Okta Developer Consoleregister your application's login and logout redirect callbacks, see Register Redirects. - Configure your application to use the values registered in the previous step, see Configure Your Application.
- Add platform specific code, see Platform Wiring.
- Call
OktaContext.Current.SignInto begin the login flow.
To register redirect URIs do the following:
- Sign in to your
Okta Developer Consoleas an administrator. - Click the
Applicationstab and select your application. If you need to set up your application see Set up your Application. - Ensure you are on the
Generaltab, then go toGeneral Settingsand clickEdit. - Go to the
Loginsection. - Below
Login redirect URIsclick theAdd URIbutton. - Enter a value appropriate for your application, this example uses the following:
my.app.login:/callback - Below
Logout redirect URIsclick theAdd URIbutton. - Enter a value appropriate for your application, this example uses the following:
my.app.logout:/callback - Click
Save.
This section describes how to configure your Xamarin Forms application to use Okta Oidc. These instructions assume you are using Visual Studio and were tested with Visual Studio Community 2019 Version 16.8.0. For the purposes of this example the project name used is MyOktaApp.
Create a new Mobile App (Xamarin.Forms) project:
- Start Visual Studio and select "Create a new project".
- Find and select the project template named
Mobile App (Xamarin.Forms), click next. - Enter
MyOktaAppinto theProject namefield of theConfigure your new projectform. - Fill in the remaining fields of the
Configure your new projectform and clickCreate.
Now that your Visual Studio solution is initialized, you can continue to update package references.
This section describes how to update package references automatically. If you prefer to update package references manually, see Update Package References Manually.
To update package references automatically do the following:
- Go to
View>Other Windows>Package Manager Console. - In the
Package Manager Consolewindow typeUpdate-Packageand press enter.
This section describes how to update package references manually. If you prefer to update package references automatically, see Update Package References Automatically.
The following operations are performed from Solution Explorer; to ensure Solution Explorer is visible go to View > Solution Explorer.
To update package references do the following:
- Right click
MyOktaAppand selectManage Nuget Packages. - From the
Installedtab selectXamarin.Essentialsand clickUpdate; this should updateXamarin.Essentialsto the latest version (v1.6.1 as of 03/08/2021). - From the
Installedtab selectXamarin.Formsand clickUpdate; this should updateXamarin.Formsto the latest version (v5.0.0.2012 as of 03.08/2021). - Right click
MyOktaApp.Androidand selectManage Nuget Packages. - From the
Installedtab selectXamarin.Essentialsand clickUpdate; this should updateXamarin.Essentialsto the latest version (v1.6.1 as of 03/08/2021). - From the
Installedtab selectXamarin.Formsand clickUpdate; this should updateXamarin.Formsto the latest version (v5.0.0.2012 as of 03.08/2021). - Right click
MyOktaApp.iOSand selectManage Nuget Packages. - From the
Installedtab selectXamarin.Essentialsand clickUpdate; this should updateXamarin.Essentialsto the latest version (v1.6.1 as of 03/08/2021). - From the
Installedtab selectXamarin.Formsand clickUpdate; this should updateXamarin.Formsto the latest version (v5.0.0.2012 as of 03.08/2021).
This section describes how to add Xamarin related Okta packages to your projects.
The following operations are performed from Solution Explorer; to ensure Solution Explorer is visible go to View > Solution Explorer.
To add Okta Xamarin packages do the following:
- Right click on the project
MyOktaAppand selectManage Nuget Packages.... - In the
NuGet Package Managerwindow clickBrowse. - In the search box type
Okta.Xamarin. - Select
Okta.Xamarinthen click theInstallbutton. Accept defaults on any prompts that may appear. - Right click on the project
MyOktaApp.Androidand selectManage Nuget Packages.... - In the
NuGet Package Managerwindow clickBrowse. - In the search box type
Okta.Xamarin. - Select
Okta.Xamarinthen click theInstallbutton. Accept defaults on any prompts that may appear. - Select
Okta.Xamarin.Androidthen click theInstallbutton. Accept defaults on any prompts that may appear. - Right click on the project
MyOktaApp.iOSand selectManage Nuget Packages.... - In the
NuGet Package Managerwindow clickBrowse. - In the search box type
Okta.Xamarin. - Select
Okta.Xamarinthen click theInstallbutton. Accept defaults on any prompts that may appear. - Select
Okta.Xamarin.iOSthen click theInstallbutton. Accept defaults on any prompts that may appear.
The minimum supported Android version of the Okta Xamarin Sdk is Android 10.0 (Q).
The following operations are performed from Solution Explorer; to ensure Solution Explorer is visible go to View > Solution Explorer.
To update the Android version for your Android project do the following:
- Right click on
MyOktaApp.Androidand selectProperties. - In the properties window ensure that the
Applicationsection is selected. - From the dropdown labeled
Compile using Android version: (Target Framework)selectAndroid 10.0 (Q).
This section describes how to configure your Okta Xamarin application. These instructions assume you are using Visual Studio and were tested with Visual Studio Community 2019 Version 16.8.0.
To configure your Android application do the following:
- In the
Assetsfolder of your Xamarin Android project, create a file calledOktaConfig.xml. - Add the following content to the
OktaConfig.xmlfile:<?xml version="1.0" encoding="utf-8" ?> <Okta> <ClientId>{ClientId}</ClientId> <OktaDomain>https://{yourOktaDomain}</OktaDomain> <RedirectUri>my.app.login:/callback</RedirectUri> <PostLogoutRedirectUri>my.app.logout:/callback</PostLogoutRedirectUri> </Okta>
Note:
- The value entered for RedirectURI MUST match the value entered in step 6 of Register Redirects.
- The value entered for PostLogoutRedirectUri MUST match the value entere in step 8 of Register Redirects.
- Replace
{ClientId}and{yourOktaDomain}with appropriate values for your application, see Find your Application's credentials. - Select the
OktaConfig.xmlfile, then go toView->Properties Window. - In the Properties window set the following value:
- Build Action —
AndroidAsset
To configure your iOS application do the following:
- In your Xamarin iOS project, double click the
Info.plistfile to open Visual Studio's Info.plist file editor. - Click the
Advancedtab. - Expand the
URL Typessection. - Click the
Add URL Typebutton. - In the
Identifierfield, enter the following:Okta OAuth login callback - In the
URL Schemesfield, enter a value appropriate for your application. This example uses:my.app.loginNote: the value entered here MUST match the prefix entered in step 6 of Register Redirects.
- In the
Roledropdown selectViewer. - Click the
Add URL Typebutton again. - In the
Identifierfield, enter the following:Okta OAuth logout callback - In the
URL Schemesfield, enter a value appropriate for your application. This example uses:my.app.logoutNote: the value entered here MUST match the prefix entered in step 8 of Register Redirects.
- In the
Roledropdown selectViewer. - Save your changes.
- In the root of your Xamarin iOS project, create a file called
OktaConfig.plist. - Select the
OktaConfig.plistfile, then go toView->Properties Window. - In the Properties window set the following values:
- Build Action —
Content - Copy to Output Directory —
Copy always
- Right click the
OktaConfig.plistfile and selectView Code. - Replace the contents of the
OktaConfig.plistfile with the following:<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>ClientId</key> <string>{ClientId}</string> <key>OktaDomain</key> <string>https://{yourOktaDomain}</string> <key>RedirectUri</key> <string>my.app.login:/callback</string> <key>PostLogoutRedirectUri</key> <string>my.app.logout:/callback</string> </dict> </plist>
Note:
- The value entered for RedirectURI MUST match the value entered in step 6 of Register Redirects.
- The value entered for PostLogoutRedirectUri MUST match the value entered in step 8 of Register Redirects.
- Replace
{ClientId}and{yourOktaDomain}with appropriate values for your application, see Find your Application's credentials.
This section describes the minimal code necessary to handle Okta authentication related redirects when using the Okta Xamarin Sdk.
To handle Okta authentication redirects on Android do the following:
- Update your
MainActivityto extendOktaMainActivity<App>.public class MainActivity : OktaMainActivity<App>
- Override the OnSignInCompleted and OnSignOutCompleted methods.
public override void OnSignInCompleted(object sender, SignInEventArgs signInEventArgs) { // for demo purposes go to the profile page Shell.Current.GoToAsync("//ProfilePage", true); } public override void OnSignOutCompleted(object sender, SignOutEventArgs signOutEventArgs) { // for demo purposes go to the profile page Shell.Current.GoToAsync("//ProfilePage", true); }
- Your completed
MainActivity.csshould look similar to the following:[Activity(Label = "MyOktaApp", Icon = "@mipmap/icon", Theme = "@style/MainTheme", MainLauncher = true, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation | ConfigChanges.UiMode | ConfigChanges.ScreenLayout | ConfigChanges.SmallestScreenSize)] public class MainActivity : OktaMainActivity<App> { public override void OnSignInCompleted(object sender, SignInEventArgs signInEventArgs) { // for demo purposes go to the profile page Shell.Current.GoToAsync("//ProfilePage", true); } public override void OnSignOutCompleted(object sender, SignOutEventArgs signOutEventArgs) { // for demo purposes go to the profile page Shell.Current.GoToAsync("//ProfilePage", true); } }
- Create a new Activity to intercept Login redirects, this example uses
LoginCallbackInterceptorActivity. - Replace the activity implementation with the following code:
[Activity(Label = "LoginCallbackInterceptorActivity", NoHistory = true, LaunchMode = LaunchMode.SingleInstance)] [ IntentFilter ( actions: new[] { Intent.ActionView }, Categories = new[] { Intent.CategoryDefault, Intent.CategoryBrowsable }, DataSchemes = new[] { "my.app.login" }, DataPath = "/callback" ) ] public class LoginCallbackInterceptorActivity : OktaLoginCallbackInterceptorActivity<MainActivity> { }
Note that the value specified for
DataSchemesMUST match the prefix entered in step 6 of Register Redirects and theDataPathMUST match the suffix. - Create a new Activity to intercept Logout redirects, this example uses
LogoutCallbackInterceptorActivity. - Replace the activity implementation with the following code:
[Activity(Label = "LogoutCallbackInterceptorActivity", NoHistory = true, LaunchMode = LaunchMode.SingleInstance)] [ IntentFilter ( actions: new[] { Intent.ActionView }, Categories = new[] { Intent.CategoryDefault, Intent.CategoryBrowsable }, DataSchemes = new[] { "my.app.logout" }, DataPath = "/callback" ) ] public class LogoutCallbackInterceptorActivity : OktaLogoutCallbackInterceptorActivity<MainActivity> { }
Note that the value specified for
DataSchemesMUST match the prefix entered in step 8 of Register Redirects and theDataPathMUST match the suffix.
To handle Okta authentication redirects on iOS do the following:
- Modify your
AppDelegateclass to extendOktaAppDelegate<App>. - In the
FinishedLaunchingmethod add event handlers for theSignInCompletedandSignOutCompletedevents, this example navigates to theProfilePage, you should provide logic appropriate for your application:OktaContext.AddSignInCompletedListener(OnSignInCompleted); OktaContext.AddSignOutCompletedListener(OnSignOutCompleted);
A complete AppDelegate example follows:
[Register("AppDelegate")] public partial class AppDelegate : OktaAppDelegate<App> { public override bool FinishedLaunching(UIApplication app, NSDictionary options) { bool result = base.FinishedLaunching(app, options); OktaContext.AddSignInCompletedListener(OnSignInCompleted); OktaContext.AddSignOutCompletedListener(OnSignOutCompleted); return result; } public void OnSignInCompleted(object sender, SignInEventArgs signInEventArgs) { // for demo purposes go to the profile page Shell.Current.GoToAsync("//ProfilePage", true); } public void OnSignOutCompleted(object sender, SignOutEventArgs signOutEventArgs) { // for demo purposes go to the profile page Shell.Current.GoToAsync("//ProfilePage", true); } }
To receive a refresh token along with id and access tokens do the following:
- Ensure that
Refresh Tokenis checked in theAllowed grant typessection of your application.- Sign in to the admin dashboard for your application.
- Click on
Applicationsand go toGeneral Settings>Application>Allowed grant types. - Check the box next to
Refresh Token.
- Specify the
offline_accessscope along with the default scopes in your config file.- Android:
- Add the following element inside the
Oktaelement of the fileAssets/OktaConfig.xml.<Scope>openid profile offline_access</Scope>
- Add the following element inside the
- iOS:
- Add the
Scopeproperty to the OktaConfig.plist file.- Property =
Scope - Type =
String - Value =
openid profile offline_access
- Property =
- Add the
- Android:
Okta Xamarin Sdk provides convenience methods to store authentication state in platform specific secure storage. To enable secure storage do the following:
- Android:
- To use secure storage on Android no special setup is required.
- iOS
- To use secure storage on iOS you must enable keychain:
- Using Visual Studio open the file
Entitlements.plistfile found in the root of your Xamarin iOS project. - Select
Keychainin the list of Entitlements - Check the box labeled
Enable Keychain
- Using Visual Studio open the file
- To use secure storage on iOS you must enable keychain:
See also, SaveStateAsync, LoadStateAsync, LoadStateStarted event, LoadStateCompleted event and LoadStateException event.
The OktaContext.Current singleton provides a top level entry point into Okta functionality.
Signs a user in. Returns a reference to OktaContext.Current.StateManager after the sign in process completes. See also, SignInStarted event and SignInCompleted event.
await OktaContext.Current.SignInAsync();Signs a user out. See also, SignOutStarted event and SignOutCompleted event.
await OktaContext.Current.SignOutAsync();Calls the introspection endpoint to inspect the validity of the specified token. See also, IntrospectStarted event and IntrospectCompleted event.
await OktaContext.Current.IntrospectAsync(TokenKind.AccessToken);Since access tokens are traditionally short-lived, you can renew expired tokens by exchanging a refresh token for new ones. See Refresh Tokens to ensure your app is configured properly for this flow. See also, RenewStarted event and RenewCompleted event.
OktaContext.Current.RenewAsync("<YOUR-ACCESS-TOKEN>");Calls the revocation endpoint to revoke the access token. See also, RevokeStarted event and RevokeCompleted event.
OktaContext.RevokeAccessToken();
// or revoke a specific access token
OktaContext.RevokeAccessToken("<YOUR-ACCESS-TOKEN>");Calls the revocation endpoint to revoke the refresh token. See also, RevokeStarted event and RevokeCompleted event.
OktaContext.RevokeRefreshToken();
// or revoke a specific refresh token
OktaContext.RevokeRefreshToken("<YOUR-REFRESH-TOKEN>");Calls the revocation endpoint to revoke the specified kind of token. See also, RevokeStarted event and RevokeCompleted event.
OktaContext.Current.RevokeAsync();Saves current state to secure storage. See also, LoadSateAsync.
// using static convenience method
OktaContet.SaveStateAsync();
// using OktaContext.Current
OktaContext.Current.SaveSatateAsync();Loads previously saved state from secure storage. See also, SaveStateAsync.
// using static convenience method
OktaContext.LoadStateAsync();
// using OktaContext.Current
OktaContext.Current.LoadStateAsync();Calls the OpenID Connect UserInfo endpoint with the stored access token to return user claim information. See also, GetUserStarted event and GetUserCompleted event.
OktaContext.Current.GetUserAsync();Removes the local authentication state by removing tokens from the state manager.
OktaContext.Clear();Gets the token of the specified kind from the state manager.
OktaContext.GetToken(TokenKind.AccessToken);The OktaContext.Current.InitServicesStarted event is raised before internal Okta services are initialized. To execute code when the InitServicesStarted event is raised, add an event handler to the OktAcontext.Current.InitServicesStarted event.
OktaContext.Current.InitServicesStarted += (sender, initServicesEventArgs) => Console.WriteLine("Init services started");The OktaContext.Current.InitServicesCompleted event is raised after internal Okta services are initialized. To execute code when the InitServicesCompleted event is raised, add an event handler to the OktAcontext.Current.InitServicesCompleted event.
OktaContext.Current.InitServicesCompleted += (sender, initServicesEventArgs) => Console.WriteLine("Init services completed");The OktaContext.Current.InitServicesException event is raised if an exception occurs initializing internal Okta services. To execute code when the InitServicesException event is raised, add an event handler to the OktAcontext.Current.InitServicesException event.
OktaContext.Current.InitServicesException += (sender, initServicesEventArgs) => Console.WriteLine("Init services exception: {0}", initServicesEventArgs.Exception.Message);The OktaContext.Current.SignInStarted event is raised before the login flow begins. To execute code when the SignInStarted event is raised, add an event handler to the OktaContext.Current.SignInStarted event. This is done directly or using the static AddSignInStartedListener method.
// directly
OktaContext.Current.SignInStarted += (sender, signInEventArgs) => Console.WriteLine("SignIn started");
// using AddSignInStartedListener
OktaContext.AddSignInStartedListener((sender, signInEventArgs) => Console.WriteLine("SignIn started"));The OktaContext.Current.SignInCompleted event is raised when the login flow completes. To execute code when the SignInCompleted event is raised, add an event handler to the OktaContext.Current.SignInCompleted event. This is done directly or using the static AddSignInCompletedListener method.
// directly
OktaContext.Current.SignInCompleted += (sender, signInEventArgs) => Console.WriteLine("SignIn completed");
// using AddSignInCompletedListener
OktaContext.AddSignInCompletedListener((sender, signInEventArgs) => Console.WriteLine("SignIn completed"));The OktaContext.Current.SignOutStarted event is raised when the logout flow begins. To execute code when the SignOutStarted event is raised, add an event handler to the OktaContext.Current.SignOutStarted event. This is done directly or using the static AddSignOutStartedListener method.
// directly
OktaContext.Current.SignOutStarted += (sender, signOutEventArgs) => Console.WriteLine("SignOut completed");
// using AddSignOutStartedListener
OktaContext.AddSignOutStartedListener((sender, signOutEventArgs) => Console.WriteLine("SignOut completed"));The OktaContext.Current.SignOutCompleted event is raised when the logout flow completes. To execute code when the SignOutCompleted event is raised, add an event handler to the OktaContext.Current.SignOutCompleted event. This is done directly or using the static AddSignOutCompletedListener method.
// directly
OktaContext.Current.SignOutCompleted += (sender, signOutEventArgs) => Console.WriteLine("SignOut completed");
// using AddSignOutCompletedListener
OktaContext.AddSignOutCompletedListener((sender, signOutEventArgs) => Console.WriteLine("SignOut completed"));The OktaContext.Current.AuthenticationFailed event is raised when an error response is received during the authentication process. To execute code when the AuthenticationFailed event is raised, add an event handler to the OktaContext.Current.AuthenticationFailed event.
// directly
OktaContext.Current.AuthenticationFailed += (sender, authenticationFailedEventArgs) =>
{
oAuthException = authenticationFailedEventArgs.OAuthException;
// ... additional custom logic
};
// using AddAuthenticationFailedListener
OktaContext.AddAuthenticationFailedListener((sender, authenticationFailedEventArgs) =>
{
oAuthException = authenticationFailedEventArgs.OAuthException;
// ... additional custom logic
})The OktaContext.Current.LoadStateStarted event is raised before state is loaded from secure storage. To execute code when the LoadStateStarted event is raised, add an event handler to the OktaContext.Current.LoadStateStarted event.
// directly
OktaContext.Current.LoadStateStarted += (sender, secureStorageEventArgs) =>
{
IOktaStateManager oktaStateManager = secureStorageEventArgs.OktaStateManager;
// ... additional custom logic
}
// using AddLoadStateStartedListener
OktaContext.AddLoadStateStartedListener((sender, secureStorageEventArgs) =>
{
IOktaStateManager oktaStateManager = secureStorageEventArgs.OktaStateManager;
// ... additional custom logic
})The OktaContext.Current.LoadStateCompleted event is raised after state is loaded. To execute code when the LoadStateCompleted event is raised, add an event handler to the OktaContext.Current.LoadStateCompleted event.
// directly
OktaContext.Current.LoadStateCompleted += (sender, secureStorageEventArgs) =>
{
IOktaStateManager oktaStateManager = secureStorageEventArgs.OktaStateManager;
// ... additional custom logic
}
// using AddLoadStateCompletedListener
OktaContext.AddLoadStateCompletedListener((sender, secureStorageEventArgs) =>
{
IOktaStateManager oktaStateManager = secureStorageEventArgs.OktaStateManager;
// ... additional custom logic
})The OktaContext.Current.LoadStateException event is raised when an exception occurs when loading state. To execute code when the LoadStateException event is raised, add an event handler to the OktaContext.Current.LoadStateException event.
// directly
OktaContext.Current.LoadStateException += (sender, secureStorageExceptionEventArgs) =>
{
Exception exception = secureStorageExceptionEventArgs.Exception;
// ... additional custom logic
}
// using AddLoadStateExceptionListener
OktaContext.AddLoadStateExceptionListener((sender, secureStorageExceptionEventArgs) =>
{
Exception exception = secureStorageExceptionEventArgs.Exception;
// ... additional custom logic
})The OktaContext.Current.SecureStorageWriteStarted event is raised before data is written to secure storage. To execute code when the SecureStorageWriteStarted event is raised, add an event handler to the OktaContext.Current.SecureStorageWriteStarted event.
// directly
OktaContext.Current.SecureStorageWriteStarted += (sender, secureStorageEventArgs) =>
{
IOktaStateManager oktaStateManager = secureStorageEventArgs.OktaStateManager;
// ... additional custom logic
}
// using AddSecureStorageWriteStartedListener
OktaContext.AddSecureStorageWriteStartedListener((sender, secureStorageEventArgs) =>
{
IOktaStateManager oktaStateManager = secureStorageEventArgs.OktaStateManager;
// ... additional custom logic
})The OktaContext.Current.SecureStorageWriteCompleted event is raised after data is written to secure storage. To execute code when the SecureStorageWriteCompleted event is raised, add an event handler to the OktaContext.Current.SecureStorageWriteCompleted event.
// directly
OktaContext.Current.SecureStorageWriteCompleted += (sender, secureStorageEventArgs) =>
{
IOktaStateManager oktaStateManager = secureStorageEventArgs.OktaStateManager;
// ... additional custom logic
}
// using AddSecureStorageWriteCompletedListener
OktaContext.AddSecureStorageWriteCompletedListener((sender, secureStorageEventArgs) =>
{
IOktaStateManager oktaStateManager = secureStorageEventArgs.OktaStateManager;
// ... additional custom logic
})The OktaContext.Current.SecureStorageWriteException event is raised when an exception occurs writing to secure storage. To execute code when the SecureStorageWriteException event is raised, add an event handler to the OktaContext.Current.SecureStorageWriteException event.
// directly
OktaContext.Current.SecureStorageWriteException += (sender, secureStorageExceptionEventArgs) =>
{
Exception exception = secureStorageExceptionEventArgs.Exception;
// ... additional custom logic
}
// using AddSecureStorageWriteExceptionListener
OktaContext.AddSecureStorageWriteExceptionListener((sender, secureStorageExceptionEventArgs) =>
{
Exception exception = secureStorageExceptionEventArgs.Exception;
// ... additional custom logic
})The OktaContext.Current.SecureStorageReadStarted event is raised before data is read from secure storage. To execute code when the SecureStorageReadStarted event is raised, add an event handler to the OktaContext.Current.SecureStorageReadStarted event.
// directly
OktaContext.Current.SecureStorageReadStarted += (sender, secureStorageEventArgs) =>
{
IOktaStateManager oktaStateManager = secureStorageEventArgs.OktaStateManager;
// ... additional custom logic
}
// using AddSecureStorageReadStartedListener
OktaContext.AddSecureStorageReadStartedListener((sender, secureStorageEventArgs) =>
{
IOktaStateManager oktaStateManager = secureStorageEventArgs.OktaStateManager;
// ... additional custom logic
})The OktaContext.Current.SecureStorageReadCompleted event is raised after data is read from secure storage. To execute code when the SecureStorageReadCompleted event is raised, add an event handler to the OktaContext.Current.SecureStorageReadCompleted event.
// directly
OktaContext.Current.SecureStorageReadCompleted += (sender, secureStorageEventArgs) =>
{
IOktaStateManager oktaStateManager = secureStorageEventArgs.OktaStateManager;
// ... additional custom logic
}
// using AddSecureStorageReadCompletedListener
OktaContext.AddSecureStorageReadCompletedListener((sender, secureStorageEventArgs) =>
{
IOktaStateManager oktaStateManager = secureStorageEventArgs.OktaStateManager;
// ... additional custom logic
})The OktaContext.Current.SecureStorageReadException event is raised when an exception occurs reading from secure storage. To execute code when the SecureStorageReadException event is raised, add an event handler to the OktaContext.Current.SecureStorageReadException event.
// directly
OktaContext.Current.SecureStorageReadException += (sender, secureStorageExceptionEventArgs) =>
{
Exception exception = secureStorageExceptionEventArgs.Exception;
// ... additional custom logic
}
// using AddSecureStorageReadExceptionListener
OktaContext.AddSecureStorageReadExceptionListener((sender, secureStorageExceptionEventArgs) =>
{
Exception exception = secureStorageExceptionEventArgs.Exception;
// ... additional custom logic
})The OktaContext.Current.RevokeStarted event is raised before token revocation begins. To execute code when the RevokeStarted event is raised, add an event handler to the OktaContext.Current.RevokeStarted event.
// directly
OktaContext.Current.RevokeStarted += (sender, revokeEventArgs) =>
{
string token = revokeEventArgs.Token;
TokenKind kindOfToken = revokeEventArgs.TokenKind;
// ... additional custom logic
}
// using AddRevokeStartedListener
OktaContext.AddRevokeStartedListener((sender, revokeEventArgs) =>
{
string token = revokeEventArgs.Token;
TokenKind kindOfToken = revokeEventArgs.TokenKind;
// ... additional custom logic
})The OktaContext.Current.RevokeCompleted event is raised when token revocation completes. To execute code when the RevokeCompleted event is raised, add an event handler to the OktaContext.Current.RevokeCompleted event.
// directly
OktaContext.Current.RevokeCompleted += (sender, revokeEventArgs) =>
{
string token = revokeEventArgs.Token;
TokenKind kindOfToken = revokeEventArgs.TokenKind;
// ... additional custom logic
}
// using AddRevokeCompletedListener
OktaContext.AddRevokeCompletedListener((sender, revokeEventArgs) =>
{
string token = revokeEventArgs.Token;
TokenKind kindOfToken = revokeEventArgs.TokenKind;
// ... additional custom logic
})The OktaContext.Current.RevokeException event is raised when an exception occurs during token revocation. To execute code when the RevokeException event is raised, add an event handler to the OktaContext.Current.RevokeException event.
// directly
OktaContext.Current.RevokeException += (sender, revokeExceptionEventArgs) =>
{
Exception exception = revokeExceptionEventArgs.Exception;
// ... additional custom logic
}
// using AddRenewExceptionListener
OktaContext.AddRevokeExceptionListener((sender, revokeExceptionEventArgs =>
{
Exception exception = revokeExceptionEventArgs.Exception;
// ... additional custom logic
}))The OktaContext.Current.GetUserStarted event is raised before user information is retrieved. To execute code when the GetUserStarted event is raised, add an event handler to the OktaContext.Current.GetUserStarted event.
// directly
OktaContext.Current.GetUserStarted += (sender, getUserEventArgs) =>
{
object userInfo = getUserEventArgs.UserInfo; // object type varies depending on which variation of the GetUser method is used
// ... additional custom logic
}
// using AddGetUserStartedListener
OktaContext.AddGetUserStartedListener((sender, getUserEventArgs) =>
{
object userInfo = getUserEventArgs.UserInfo; // object type varies depending on which variation of the GetUser method is used
// ... additional custom logic
})The OktaContext.Current.GetUserCompleted event is raised after user information is retrieved. To execute code when the GetUserCompleted event is raised, add an event handler to the OktaContext.Current.GetUserCompleted event.
// directly
OktaContext.Current.GetUserCompleted += (sender, getUserEventArgs) =>
{
object userInfo = getUserEventArgs.UserInfo; // object type varies depending on which variation of the GetUser method is used
// ... additional custom logic
}
// using AddGetUserCompletedListener
OktaContext.AddGetUserCompletedListener((sender, getUserEventArgs) =>
{
object userInfo = getUserEventArgs.UserInfo; // object type varies depending on which variation of the GetUser method is used
// ... additional custom logic
})The OktaContext.Current.IntrospectStarted event is raised before token introspection. To execute code when the IntrospectStarted event is raised, add an event handler to the OktaContext.Current.IntrospectStarted event.
// directly
OktaContext.Current.IntrospectStarted += (sender, introspectEventArgs) =>
{
string token = introspectEventArgs.Token;
TokenKind tokenKind = introspectEventArgs.TokenKind;
// ... additional custom logic
}
// using AddIntrospectStartedListener
OktaContext.AddIntrospectStartedListener((sender, introspectEventArgs) =>
{
string token = introspectEventArgs.Token;
TokenKind tokenKind = introspectEventArgs.TokenKind;
// ... additional custom logic
})The OktaContext.Current.IntrospectCompleted event is raised after token introspection. To execute code when the IntrospectCompleted event is raised, add an event handler to the OktaContext.Current.IntrospectCompleted event.
// directly
OktaContext.Current.IntrospectCompleted += (sender, introspectEventArgs) =>
{
string token = introspectEventArgs.Token;
TokenKind tokenKind = introspectEventArgs.TokenKind;
// ... additional custom logic
}
// using AddIntrospectCompletedListener
OktaContext.AddIntrospectCompletedListener((sender, introspectEventArgs) =>
{
string token = introspectEventArgs.Token;
TokenKind tokenKind = introspectEventArgs.TokenKind;
// ... additional custom logic
})The OktaContext.Current.RenewStarted event is raised before token renewal begins. To execute code when the RenewStarted event is raised, add an event handler to the OktaContext.Current.RenewStarted event.
// directly
OktaContext.Current.RenewStarted += (sender, renewEventArgs) =>
{
IOktaStateManager stateManager = renewEventArgs.StateManager;
// ... additional custom logic
}
// using AddRenewStartedListener
OktaContext.AddRenewStartedListener((sender, renewEventArgs) =>
{
IOktaStateManager stateManager = renewEventArgs.StateManager;
// ... additional custom logic
})The OktaContext.Current.RenewCompleted event is raised after token renewal completes. To execute code when the RenewCompleted event is raised, add an event handler to the OktaContext.Current.RenewCompleted event.
// directly
OktaContext.Current.RenewCompleted += (sender, renewEventArgs) =>
{
IOktaStateManager stateManager = renewEventArgs.StateManager;
// ... additional custom logic
}
// using AddRenewCompletedListener
OktaContext.AddRenewCompletedListener((sender, renewEventArgs) =>
{
IOktaStateManager stateManager = renewEventArgs.StateManager;
// ... additional custom logic
})The OktaContext.Current.RenewException event is raised when an exception occurs during token renewal. To execute code when the RenewException event is raised, add an event handler to the OktaContext.Current.RenewException event.
// directly
OktaContext.Current.RenewException += (sender, renewExceptionEventArgs) =>
{
Exception exception = renewExceptionEventArgs.Exception;
// ... additional custom logic
}
// using AddRenewExceptionListener
OktaContext.AddRenewExceptionListener((sender, renewExceptionEventArgs =>
{
Exception exception = renewExceptionEventArgs.Exception;
// ... additional custom logic
}))After authentication completes, use OktaContext.Current.StateManager to access tokens for the current authenticated Okta session.
// get access token
string accessToken = OktaContext.Current.StateManager.GetAccessToken();
// get refresh token
string refreshToken = OktaContext.Current.StateManager.GetRefreshToken();
// get Id token
string idToken = OktaContext.Current.StateManager.GetIdToken();When the SignInCompleted event is raised the EventArgs parameter instance is of type SignInEventArgs which provides access to an instance of the OktaStateManager class. Use code similar to the following to read the authentication state and access the bearer token claims when sign in completes:
OktaContext.AddSignInCompletedListener((sender, args) =>
{
SignInEventArgs signInEventArgs = (SignInEventArgs)args;
IOktaStateManager oktaStateManager = signInEventArgs.StateManager; //
BearerToken bearerToken = new BearerToken(oktaStateManager.AccessToken);
BearerTokenClaims claims = BearerTokenClaims.FromBearerToken(bearerToken);
// Access claims properties
Console.WriteLine(claims.Issuer);
Console.WriteLine(claims.Subject);
Console.WriteLine(claims.Audience);
Console.WriteLine(claims.ExpirationTime);
});We're happy to accept contributions and PRs! Please see the contribution guide to understand how to structure a contribution.
If you run into problems using the SDK, you can
- Ask questions on the Okta Developer Forums
- Post issues here on GitHub (for code errors)
