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 Console
add an application; follow the directions at Set up your Application and accept the defaults. - In your
Okta Developer Console
register 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.SignIn
to begin the login flow.
To register redirect URIs do the following:
- Sign in to your
Okta Developer Console
as an administrator. - Click the
Applications
tab and select your application. If you need to set up your application see Set up your Application. - Ensure you are on the
General
tab, then go toGeneral Settings
and clickEdit
. - Go to the
Login
section. - Below
Login redirect URIs
click theAdd URI
button. - Enter a value appropriate for your application, this example uses the following:
my.app.login:/callback
- Below
Logout redirect URIs
click theAdd URI
button. - 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
MyOktaApp
into theProject name
field of theConfigure your new project
form. - Fill in the remaining fields of the
Configure your new project
form 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 Console
window typeUpdate-Package
and 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
MyOktaApp
and selectManage Nuget Packages
. - From the
Installed
tab selectXamarin.Essentials
and clickUpdate
; this should updateXamarin.Essentials
to the latest version (v1.6.1 as of 03/08/2021). - From the
Installed
tab selectXamarin.Forms
and clickUpdate
; this should updateXamarin.Forms
to the latest version (v5.0.0.2012 as of 03.08/2021). - Right click
MyOktaApp.Android
and selectManage Nuget Packages
. - From the
Installed
tab selectXamarin.Essentials
and clickUpdate
; this should updateXamarin.Essentials
to the latest version (v1.6.1 as of 03/08/2021). - From the
Installed
tab selectXamarin.Forms
and clickUpdate
; this should updateXamarin.Forms
to the latest version (v5.0.0.2012 as of 03.08/2021). - Right click
MyOktaApp.iOS
and selectManage Nuget Packages
. - From the
Installed
tab selectXamarin.Essentials
and clickUpdate
; this should updateXamarin.Essentials
to the latest version (v1.6.1 as of 03/08/2021). - From the
Installed
tab selectXamarin.Forms
and clickUpdate
; this should updateXamarin.Forms
to 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
MyOktaApp
and selectManage Nuget Packages...
. - In the
NuGet Package Manager
window clickBrowse
. - In the search box type
Okta.Xamarin
. - Select
Okta.Xamarin
then click theInstall
button. Accept defaults on any prompts that may appear. - Right click on the project
MyOktaApp.Android
and selectManage Nuget Packages...
. - In the
NuGet Package Manager
window clickBrowse
. - In the search box type
Okta.Xamarin
. - Select
Okta.Xamarin
then click theInstall
button. Accept defaults on any prompts that may appear. - Select
Okta.Xamarin.Android
then click theInstall
button. Accept defaults on any prompts that may appear. - Right click on the project
MyOktaApp.iOS
and selectManage Nuget Packages...
. - In the
NuGet Package Manager
window clickBrowse
. - In the search box type
Okta.Xamarin
. - Select
Okta.Xamarin
then click theInstall
button. Accept defaults on any prompts that may appear. - Select
Okta.Xamarin.iOS
then click theInstall
button. 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.Android
and selectProperties
. - In the properties window ensure that the
Application
section 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
Assets
folder of your Xamarin Android project, create a file calledOktaConfig.xml
. - Add the following content to the
OktaConfig.xml
file:<?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.xml
file, 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.plist
file to open Visual Studio's Info.plist file editor. - Click the
Advanced
tab. - Expand the
URL Types
section. - Click the
Add URL Type
button. - In the
Identifier
field, enter the following:Okta OAuth login callback
- In the
URL Schemes
field, enter a value appropriate for your application. This example uses:my.app.login
Note: the value entered here MUST match the prefix entered in step 6 of Register Redirects.
- In the
Role
dropdown selectViewer
. - Click the
Add URL Type
button again. - In the
Identifier
field, enter the following:Okta OAuth logout callback
- In the
URL Schemes
field, enter a value appropriate for your application. This example uses:my.app.logout
Note: the value entered here MUST match the prefix entered in step 8 of Register Redirects.
- In the
Role
dropdown selectViewer
. - Save your changes.
- In the root of your Xamarin iOS project, create a file called
OktaConfig.plist
. - Select the
OktaConfig.plist
file, 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.plist
file and selectView Code
. - Replace the contents of the
OktaConfig.plist
file 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
MainActivity
to 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.cs
should 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
DataSchemes
MUST match the prefix entered in step 6 of Register Redirects and theDataPath
MUST 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
DataSchemes
MUST match the prefix entered in step 8 of Register Redirects and theDataPath
MUST match the suffix.
To handle Okta authentication redirects on iOS do the following:
- Modify your
AppDelegate
class to extendOktaAppDelegate<App>
. - In the
FinishedLaunching
method add event handlers for theSignInCompleted
andSignOutCompleted
events, 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 Token
is checked in theAllowed grant types
section of your application.- Sign in to the admin dashboard for your application.
- Click on
Applications
and go toGeneral Settings
>Application
>Allowed grant types
. - Check the box next to
Refresh Token
.
- Specify the
offline_access
scope along with the default scopes in your config file.- Android:
- Add the following element inside the
Okta
element of the fileAssets/OktaConfig.xml
.<Scope>openid profile offline_access</Scope>
- Add the following element inside the
- iOS:
- Add the
Scope
property 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.plist
file found in the root of your Xamarin iOS project. - Select
Keychain
in 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(TokenKind.AccessToken);
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)