Skip to main content

Get Started

1

Create a new .NET project

Create a new .NET MAUI or .NET Android/iOS project for this quickstart.
In Visual Studio 2022 or later:
  1. FileNewProject
  2. Select .NET MAUI App template
  3. Configure your project:
    • Project name: Auth0MauiSample
    • Location: Choose your preferred location
    • Framework: .NET 8.0 or later
  4. Click Create
This quickstart focuses on .NET Android and iOS, which are the next generation of Xamarin.Android and Xamarin.iOS. If you’re still using Xamarin, you can follow this guide as the integration is identical and the SDKs are compatible.
2

Install Auth0 SDK

Add the Auth0 OIDC Client SDK to your project.
Open the Package Manager Console (ViewOther WindowsPackage Manager Console) and install the appropriate package:For .NET Android:
Package Manager Console
Install-Package Auth0.OidcClient.AndroidX
For .NET iOS:
Package Manager Console
Install-Package Auth0.OidcClient.iOS
For .NET MAUI (both platforms):
Package Manager Console
Install-Package Auth0.OidcClient.MAUI
The Auth0 OIDC Client SDK handles all the OAuth 2.0 and OIDC protocol details, providing a simple API for authentication.
3

Setup your Auth0 App

Create a new application in your Auth0 tenant and configure it for mobile.
  1. Head to the Auth0 Dashboard
  2. Click on ApplicationsApplicationsCreate Application
  3. Enter a name for your app, select Native as the app type, and click Create
  4. Switch to the Settings tab on the Application Details page
  5. Note your Domain and Client ID - you’ll need these in the next step
Configure Callback URLs:On the Settings tab, add the following URLs:Allowed Callback URLs:
YOUR_ANDROID_PACKAGE_NAME://{yourDomain}/android/YOUR_ANDROID_PACKAGE_NAME/callback
Replace:
  • YOUR_ANDROID_PACKAGE_NAME with your app’s package name (e.g., com.mycompany.myapp)
  • {yourDomain} with your Auth0 domain (e.g., dev-abc123.us.auth0.com)
Example: com.mycompany.myapp://dev-abc123.us.auth0.com/android/com.mycompany.myapp/callback
Allowed Logout URLs:Use the same URLs as your callback URLs.
Ensure that callback and logout URLs are in lowercase. Mismatched URLs will cause authentication to fail.
Allowed Callback URLs are essential for security - they ensure users are safely returned to your application after authentication. Without a matching URL, the login process will fail.Allowed Logout URLs provide a seamless experience when users sign out, redirecting them back to your app instead of leaving them on an Auth0 page.
4

Initialize the Auth0 Client

Create an Auth0Client instance to communicate with Auth0.
MainActivity.cs
using Auth0.OidcClient;
using Android.App;
using Android.Content;

[Activity(Label = "Auth0Sample", MainLauncher = true, Icon = "@drawable/icon",
    LaunchMode = LaunchMode.SingleTask)]
[IntentFilter(
    new[] { Intent.ActionView },
    Categories = new[] { Intent.CategoryDefault, Intent.CategoryBrowsable },
    DataScheme = "YOUR_ANDROID_PACKAGE_NAME",
    DataHost = "{yourDomain}",
    DataPathPrefix = "/android/YOUR_ANDROID_PACKAGE_NAME/callback")]
public class MainActivity : Activity
{
    private Auth0Client auth0Client;

    protected override void OnCreate(Bundle savedInstanceState)
    {
        base.OnCreate(savedInstanceState);

        // Initialize Auth0 client
        auth0Client = new Auth0Client(new Auth0ClientOptions
        {
            Domain = "{yourDomain}",
            ClientId = "{yourClientId}"
        }, this);
    }

    protected override async void OnNewIntent(Intent intent)
    {
        base.OnNewIntent(intent);
        Auth0.OidcClient.ActivityMediator.Instance.Send(intent.DataString);
    }
}
Replace YOUR_ANDROID_PACKAGE_NAME, {yourDomain}, and {yourClientId} with your actual values. Ensure all text in DataScheme, DataHost, and DataPathPrefix is lowercase.
The IntentFilter registers your app to handle the callback URL. The LaunchMode.SingleTask ensures Android doesn’t create a new activity instance when the callback is invoked.
Store your Auth0 domain and client ID in a configuration file or app settings instead of hardcoding them for better maintainability.
5

Implement Login and Logout

Add methods to handle user authentication.Implement Login:
Authentication.cs
public async Task LoginAsync()
{
    var loginResult = await auth0Client.LoginAsync();

    if (!loginResult.IsError)
    {
        // Authentication successful
        var accessToken = loginResult.AccessToken;
        var idToken = loginResult.IdentityToken;
        var user = loginResult.User;

        // Store credentials and update UI
        Console.WriteLine($"Logged in as: {user.FindFirst("name")?.Value}");
    }
    else
    {
        // Handle authentication error
        Console.WriteLine($"Login error: {loginResult.Error}");
    }
}
Implement Logout:
Authentication.cs
public async Task LogoutAsync()
{
    var logoutResult = await auth0Client.LogoutAsync();

    if (logoutResult == BrowserResultType.Success)
    {
        // Clear stored credentials
        // Update UI to logged-out state
        Console.WriteLine("Logged out successfully");
    }
}
The LoginAsync() method launches the system browser (or Chrome Custom Tabs on Android) to display Auth0’s Universal Login page. After authentication, the user is redirected back to your app via the callback URL.
Add these methods to your MainActivity (Android) or a ViewController (iOS) and call them when users tap Login/Logout buttons.
6

Run your app

Build and run your application.
For Android:
  1. Select an Android emulator or connected device from the device dropdown
  2. Press F5 or click the Run button
  3. The app will build, deploy, and launch
For iOS (requires Mac build host):
  1. Connect to your Mac build host
  2. Select an iOS simulator or device from the device dropdown
  3. Press F5 or click the Run button
Expected flow:
  1. App launches with Login button
  2. Tap Log In → Browser/Chrome Custom Tab opens → Complete authentication
  3. Redirects back to your app automatically
  4. User is authenticated successfully
On first run, iOS may prompt you to confirm opening the browser for authentication. This is normal and expected behavior.
CheckpointYou now have a fully functional Auth0 login experience in your .NET Android or iOS application. The app uses the system browser for secure authentication and automatically handles the callback flow.

Access User Information

After successful authentication, you can access user information from the login result.

Authentication Result

The LoginAsync() method returns a LoginResult object containing:
UserInfo.cs
var loginResult = await auth0Client.LoginAsync();

if (!loginResult.IsError)
{
    // Access tokens
    var accessToken = loginResult.AccessToken;
    var idToken = loginResult.IdentityToken;
    var refreshToken = loginResult.RefreshToken;

    // Access user claims
    var user = loginResult.User;
    var name = user.FindFirst("name")?.Value;
    var email = user.FindFirst("email")?.Value;
    var picture = user.FindFirst("picture")?.Value;

    Console.WriteLine($"Name: {name}");
    Console.WriteLine($"Email: {email}");
}

Iterate Through All Claims

To see all available user information:
UserClaims.cs
if (!loginResult.IsError)
{
    foreach (var claim in loginResult.User.Claims)
    {
        Console.WriteLine($"{claim.Type}: {claim.Value}");
    }
}
The exact claims returned depend on the scopes requested. For more information, see Using Scopes in the Auth0 OIDC Client documentation.

Request Custom Scopes

To request additional user information, specify scopes when creating the Auth0Client:
CustomScopes.cs
var auth0Client = new Auth0Client(new Auth0ClientOptions
{
    Domain = "{yourDomain}",
    ClientId = "{yourClientId}",
    Scope = "openid profile email offline_access read:posts"
});

Troubleshooting & Advanced

Browser doesn’t redirect back to app

Solutions:
  1. Verify callback URLs in Auth0 Dashboard exactly match your app’s package name/bundle identifier
  2. Ensure callback URLs are in lowercase
  3. Check that DataScheme, DataHost, and DataPathPrefix (Android) or URL scheme (iOS) match your configuration
  4. Clean and rebuild your project

Authentication fails with “Invalid Callback URL” error

Fix:
  • Double-check that your callback URL in the Auth0 Dashboard matches the format:
    • Android: packagename://yourdomain/android/packagename/callback
    • iOS: bundleidentifier://yourdomain/ios/bundleidentifier/callback
  • Ensure the URL is in lowercase
  • Verify the Domain in your code matches the Domain in the Auth0 Dashboard

LoginAsync() hangs or never completes

Solutions:
  • Ensure the Intent filter (Android) or URL scheme (iOS) is properly configured
  • Check that OnNewIntent() (Android) or OpenUrl() (iOS) calls the ActivityMediator
  • Verify your app can open the system browser
  • Check network connectivity

Error: “Default App must use Token Endpoint Authentication Method ‘None’”

Fix:
  1. Go to your Auth0 Application Settings in the Dashboard
  2. Scroll to Application Properties
  3. Set Application Type to Native
  4. Set Token Endpoint Authentication Method to None
  5. Click Save Changes

iOS: Browser doesn’t open

Solutions:
  • Verify Info.plist contains the correct URL scheme configuration
  • Check that OpenUrl() is implemented in AppDelegate
  • Ensure iOS deployment target is compatible with your Auth0 SDK version

Security Best Practices

  • Secure Token Storage: Use platform-specific secure storage (Android Keystore, iOS Keychain) to store tokens
  • Token Refresh: Implement refresh token handling to maintain user sessions
  • Certificate Pinning: Consider certificate pinning for additional API security
  • ProGuard/Code Obfuscation: Add appropriate rules if using code obfuscation on Android

App Store Requirements

  • Privacy Policy: Ensure your app has a privacy policy that describes Auth0 usage
  • User Data Handling: Follow platform guidelines for handling user authentication data
  • Deep Linking: Test callback URL handling thoroughly across different scenarios
  • Network Requirements: Handle offline scenarios gracefully

Performance Optimization

  • Cache Auth0Client: Create a single instance and reuse it throughout your app
  • Lazy Loading: Initialize Auth0Client only when needed
  • Background Refresh: Implement background token refresh for long-running sessions

Custom Scopes and Audience

Request specific scopes and set an audience for your API:
AdvancedAuth.cs
var auth0Client = new Auth0Client(new Auth0ClientOptions
{
    Domain = "{yourDomain}",
    ClientId = "{yourClientId}",
    Scope = "openid profile email offline_access read:posts write:posts",
    Audience = "https://myapi.example.com"
});

var loginResult = await auth0Client.LoginAsync();

Additional Parameters

Pass additional parameters to the authorization request:
ExtraParams.cs
var extraParameters = new Dictionary<string, string>
{
    { "prompt", "login" },
    { "ui_locales", "es" },
    { "custom_param", "value" }
};

var loginResult = await auth0Client.LoginAsync(extraParameters);

Refresh Tokens

Use refresh tokens to get new access tokens without user interaction:
RefreshToken.cs
var refreshResult = await auth0Client.RefreshTokenAsync(loginResult.RefreshToken);

if (!refreshResult.IsError)
{
    var newAccessToken = refreshResult.AccessToken;
    var newIdToken = refreshResult.IdentityToken;
    // Store new tokens
}
To receive a refresh token, include the offline_access scope in your authentication request.

Platform-Specific Browser Configuration

Android - Use Chrome Custom Tabs with custom colors:
AndroidBrowser.cs
var auth0Client = new Auth0Client(new Auth0ClientOptions
{
    Domain = "{yourDomain}",
    ClientId = "{yourClientId}",
    Browser = new AndroidBrowser
    {
        ToolbarColor = Android.Graphics.Color.ParseColor("#FF6B35")
    }
}, this);
iOS - Use SFSafariViewController with custom presentation:
iOSBrowser.cs
var auth0Client = new Auth0Client(new Auth0ClientOptions
{
    Domain = "{yourDomain}",
    ClientId = "{yourClientId}",
    Browser = new ASWebAuthenticationSessionBrowser
    {
        PrefersEphemeralWebBrowserSession = false
    }
});

Next Steps