How-To: Get Started with Oidc Authentication
OidcAuthenticationProvider
is a specific implementation of IAuthenticationProvider
that allows your users to sign in using their identities from a participating identity provider. It provides seamless integration with any OpenID Connect backend, such as IdentityServer. By acting as an adapter, it integrates OpenID Connect authentication into the Uno.Extensions ecosystem, allowing you to leverage a unified approach across platforms.
Under the hood, OidcAuthenticationProvider
relies on IdentityModel.OidcClient, a widely-used .NET library that handles the core OpenID Connect and OAuth 2.0 protocols. This library manages the complex operations like token handling and user authentication.
Note
It may be useful to familiarize yourself with the OpenID Connect protocol before proceeding. You can also explore the Uno Tutorial for Oidc Authentication to learn more about the particularities for different platforms.
Step-by-step
Important
This guide assumes you used the template wizard or dotnet new unoapp
to create your solution. If not, it is recommended that you follow the Creating an application with Uno.Extensions documentation to create an application from the template.
1. Prepare for OIDC authentication
For this type of authentication, the application must already be registered with the desired identity provider.
A client id (and client secret) will be provided to you.
Add
AuthenticationOidc
to the<UnoFeatures>
property in the Class Library (.csproj) file.<UnoFeatures> Material; + AuthenticationOidc; Toolkit; MVUX; </UnoFeatures>
2. Set up OIDC authentication
Use the
UseAuthentication()
extension method to configure theIHostBuilder
to use an authentication provider. In our case, we will be using theOidcAuthenticationProvider
.private IHost Host { get; set; } protected override void OnLaunched(LaunchActivatedEventArgs args) { var builder = this.CreateBuilder(args) .Configure(host => { host .UseAuthentication(builder => { // Add the authentication provider here }); }); ... }
Add the
OidcAuthenticationProvider
using theAddOidc()
extension method which configures theIAuthenticationBuilder
to use it.private IHost Host { get; set; } protected override void OnLaunched(LaunchActivatedEventArgs args) { var builder = this.CreateBuilder(args) .Configure(host => { host .UseAuthentication(builder => { builder.AddOidc(); }); }); ... }
The
IAuthenticationBuilder
is responsible for managing the lifecycle of the associated provider that was built.Because it is configured to use OpenID Connect, the user will eventually be prompted to sign in to their identity provider account when they use your application.
OidcAuthenticationProvider
will then store the user's access token in credential storage. The token will be automatically refreshed when it expires.
3. Configure the OidcAuthenticationProvider
While the
AddOidc()
extension method will configure theIAuthenticationBuilder
to use theOidcAuthenticationProvider
, it will not configure the provider itself. TheOidcAuthenticationProvider
can be configured using a configuration section.We will use the default section name
Oidc
in this example:{ "Oidc": { "Authority": "https://demo.duendesoftware.com/", "ClientId": "interactive.confidential", "ClientSecret": "secret", "Scope": "openid profile email api offline_access", "RedirectUri": "oidc-auth://callback", } }
Common scopes include
openid
,profile
,email
, andoffline_access
. Theopenid
scope is required for OpenID Connect authentication. Theprofile
andemail
scopes are used to request additional user information, and theoffline_access
scope is used to request a refresh token. Your identity provider may provide additional scopes, such asapi
, to request access to specific APIs.Authority
: The URL of the identity provider.ClientId
andClientSecret
: The client ID and client secret that were provided to you.Scope
: The scope of the access token.RedirectUri
: The URL that the identity provider will redirect to after the user has authenticated.It is also possible to populate this setting automatically from the WebAuthenticationBroker using the
.AutoRedirectUriFromAuthenticationBroker()
extension method, which will set the redirect URI to the value returned by theWebAuthenticationBroker.GetCurrentApplicationCallbackUri()
method, which should discover the correct redirect URI for the application/platform. More information can be found in the Web Authentication Broker documentation.When used, this setting will override the value set in the configuration file for both the redirect URI and the post-logout redirect URI. This setting is ON by default on WebAssembly but opt-in on other platforms.
Advanced settings: some advanced settings may need to access directly the
OidcClientOptions
fromIdentityModel.OidcClient
used by this extension. This can be done by using the.ConfigureOidcClientOptions()
extension method.builder.AddOidc() .ConfigureOidcClientOptions(options => { // Example of advanced settings for the OidcClientOptions options.DisablePushedAuthorization = false; // Disable the PAR endpoint options.Policy.RequireIdentityTokenOnRefreshTokenResponse = true; // Require an identity token on refresh token response options.Policy.Discovery.ValidateIssuerName = false; // Disable issuer name validation });
4. Use the provider in your application
Update the
MainPage
to include a button that will allow the user to sign in with your desired service.<Page x:Class="UnoOidcAuthentication.MainPage" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="using:UnoOidcAuthentication" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d"> <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"> <Button x:Name="SignInButton" Content="Sign In" Command="{x:Bind ViewModel.Authenticate}" /> </Grid> </Page>
Update the
MainViewModel
to include a command that will allow the user to sign in with your desired service.public class MainViewModel : ObservableObject { private readonly IAuthenticationService _authenticationService; public MainViewModel(IAuthenticationService authenticationService) { _authenticationService = authenticationService; } public ICommand Authenticate => new AsyncRelayCommand(AuthenticateImpl); private async Task AuthenticateImpl() { await _authenticationService.LoginAsync(/* ... */); } }
Finally, we can pass the login credentials to the
LoginAsync()
method and authenticate with the identity provider. The user will be prompted to sign in to their account when they tap the button in the application.OidcAuthenticationProvider
will then store the user's access token in credential storage. The token will be automatically refreshed when it expires.
Advanced Customizations
You can use your own implementation of
IBrowser
(an interface from theIdentityModel.OidcClient
library) to customize the browser behavior. This should be done by creating a class that implements the interface and register it using the.ConfigureServices()
in theApp.xaml.cs
file..ConfigureServices((context, services) => { services.AddTransient<IBrowser, CustomBrowser>(); })