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 | :heavy_check_mark: Stable |
2.x | :heavy_check_mark: Stable |
3.x | :heavy_check_mark: Stable |
The latest release is found on the releases page.
To use the Okta Xamarin Sdk do the following:
Okta Developer Console
add an application; follow the directions at Set up your Application and accept the defaults.Okta Developer Console
register your application's login and logout redirect callbacks, see Register Redirects.OktaContext.Current.SignIn
to begin the login flow.To register redirect URIs do the following:
Okta Developer Console
as an administrator.Applications
tab and select your application. If you need to set up your application see Set up your Application. General
tab, then go to General Settings
and click Edit
.Login
section.Login redirect URIs
click the Add URI
button.my.app.login:/callback
Logout redirect URIs
click the Add URI
button.my.app.logout:/callback
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:
Mobile App (Xamarin.Forms)
, click next.MyOktaApp
into the Project name
field of the Configure your new project
form.Configure your new project
form and click Create
.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:
View
> Other Windows
> Package Manager Console
.Package Manager Console
window type Update-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:
MyOktaApp
and select Manage Nuget Packages
.Installed
tab select Xamarin.Essentials
and click Update
; this should update Xamarin.Essentials
to the latest version (v1.6.1 as of 03/08/2021).Installed
tab select Xamarin.Forms
and click Update
; this should update Xamarin.Forms
to the latest version (v5.0.0.2012 as of 03.08/2021).MyOktaApp.Android
and select Manage Nuget Packages
.Installed
tab select Xamarin.Essentials
and click Update
; this should update Xamarin.Essentials
to the latest version (v1.6.1 as of 03/08/2021).Installed
tab select Xamarin.Forms
and click Update
; this should update Xamarin.Forms
to the latest version (v5.0.0.2012 as of 03.08/2021).MyOktaApp.iOS
and select Manage Nuget Packages
.Installed
tab select Xamarin.Essentials
and click Update
; this should update Xamarin.Essentials
to the latest version (v1.6.1 as of 03/08/2021).Installed
tab select Xamarin.Forms
and click Update
; this should update Xamarin.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:
MyOktaApp
and select Manage Nuget Packages...
.NuGet Package Manager
window click Browse
.Okta.Xamarin
.Okta.Xamarin
then click the Install
button. Accept defaults on any prompts that may appear.MyOktaApp.Android
and select Manage Nuget Packages...
.NuGet Package Manager
window click Browse
.Okta.Xamarin
.Okta.Xamarin
then click the Install
button. Accept defaults on any prompts that may appear.Okta.Xamarin.Android
then click the Install
button. Accept defaults on any prompts that may appear.MyOktaApp.iOS
and select Manage Nuget Packages...
.NuGet Package Manager
window click Browse
.Okta.Xamarin
.Okta.Xamarin
then click the Install
button. Accept defaults on any prompts that may appear.Okta.Xamarin.iOS
then click the Install
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:
MyOktaApp.Android
and select Properties
.Application
section is selected.Compile using Android version: (Target Framework)
select Android 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:
Assets
folder of your Xamarin Android project, create a file called OktaConfig.xml
.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.
{ClientId}
and {yourOktaDomain}
with appropriate values for your application, see Find your Application's credentials.OktaConfig.xml
file, then go to View
-> Properties Window
.AndroidAsset
To configure your iOS application do the following:
Info.plist
file to open Visual Studio's Info.plist file editor.Advanced
tab.URL Types
section.Add URL Type
button.Identifier
field, enter the following:
Okta OAuth login callback
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.
Role
dropdown select Viewer
.Add URL Type
button again.Identifier
field, enter the following:
Okta OAuth logout callback
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.
Role
dropdown select Viewer
.OktaConfig.plist
.OktaConfig.plist
file, then go to View
-> Properties Window
.Content
Copy always
OktaConfig.plist
file and select View Code
.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.
{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:
MainActivity
to extend OktaMainActivity<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);
}
}
LoginCallbackInterceptorActivity
.[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.
LogoutCallbackInterceptorActivity
.[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:
AppDelegate
class to extend OktaAppDelegate<App>
.In the FinishedLaunching
method add event handlers for the SignInCompleted
and SignOutCompleted
events, this example navigates to the ProfilePage
, 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:
Refresh Token
is checked in the Allowed grant types
section of your application.
Applications
and go to General Settings
> Application
> Allowed grant types
.Refresh Token
.offline_access
scope along with the default scopes in your config file.
Okta
element of the file Assets/OktaConfig.xml
.
<Scope>openid profile offline_access</Scope>
Scope
property to the OktaConfig.plist file.Scope
String
openid profile offline_access
Okta Xamarin Sdk provides convenience methods to store authentication state in platform specific secure storage. To enable secure storage do the following:
Entitlements.plist
file found in the root of your Xamarin iOS project.Keychain
in the list of EntitlementsEnable 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