Loading...
Loading...
Use when adding Auth0 login or token management to a .NET Android application. Integrates Auth0.OidcClient.AndroidX — use even if the user says "add login to my .NET Android app" or references Xamarin Android.
npx skill4agent add auth0/agent-skills auth0-net-androidAuth0.OidcClient.AndroidXAgent instruction: Before providing SDK setup instructions, fetch the latest release version by running:bashgh api repos/auth0/auth0-oidc-client-net/releases --jq '[.[] | select(.tag_name | startswith("androidx-")) | .tag_name | ltrimstr("androidx-")] | .[0]'Use the returned version in all dependency lines instead of any hardcoded version below.
| Use Case | Recommended Skill |
|---|---|
| .NET MAUI cross-platform app (iOS + Android + Windows) | |
| .NET iOS-only app | |
| Android-only Kotlin app | |
| ASP.NET Core server-side web app | |
| ASP.NET Core Web API (JWT validation) | |
| React Native mobile app | |
Agent instruction: Before starting, examine the user's project:
- Identify the .NET version from the
file (.csproj)TargetFramework- Check for existing authentication implementations — search for existing login/logout handlers and hook into them if found (reuse existing UI elements like login buttons rather than creating duplicates)
- Note the project's namespace and package name from the
or.csprojAndroidManifest.xml- Look for existing
orAuth0Clientusage to avoid duplicate configurationAuth0ClientOptions
dotnet add package Auth0.OidcClient.AndroidXAuth0ClientIntentFilterOnNewIntentActivityMediator.Instance.Send(intent.DataString)dotnet buildAgent instruction: When writing the Auth0Client configuration:
- Pass
(the Activity) as the second argument tothisconstructor.Auth0Client- Always set
— theScope = "openid profile email offline_access"scope is required to receive refresh tokens, enabling silent token renewal without re-prompting the user.offline_access- The callback URL format is
— all lowercase.YOUR_ANDROID_PACKAGE_NAME://YOUR_AUTH0_DOMAIN/android/YOUR_ANDROID_PACKAGE_NAME/callback- The
in theDataSchememust be lowercase or Android will not receive callbacks.IntentFilter- Set
on the Activity to prevent duplicate instances. Do NOT useLaunchMode = LaunchMode.SingleTask— it does not correctly handle the callback redirect and will create duplicate Activity instances.SingleTop- The Activity should either extend
OR manually overrideAuth0ClientActivityand callOnNewIntent.ActivityMediator.Instance.Send(intent.DataString)- Store tokens securely: After successful login, persist
andAccessTokenusingRefreshToken(MAUI/Essentials) orSecureStorage(AndroidX Security — requiresEncryptedSharedPreferences). Never store tokens in plaindotnet add package Xamarin.AndroidX.Security.SecurityCryptoor in-memory variables only.SharedPreferencesAfter writing configuration and code, verify the build succeeds:bashdotnet buildIf the build fails, attempt to fix the issue. After 5-6 failed attempts, ask the user for help.
LoginAsync()/authorizeOnNewIntentActivityMediatorYOUR_ANDROID_PACKAGE_NAME://YOUR_AUTH0_DOMAIN/android/YOUR_ANDROID_PACKAGE_NAME/callbackYOUR_ANDROID_PACKAGE_NAMEcom.mycompany.myapplicationcom.mycompany.myapp://tenant.us.auth0.com/android/com.mycompany.myapp/callbackNote: Some Auth0 native SDKs useas the callback URL format. The .NET Android SDK uses the package name as the URL scheme instead.https://{domain}/android/{package}/callback
IntentFilterDataSchemeDataHostDataPathPrefixAuth0.OidcClient.AndroidXAuth0ClientScope = "openid profile email offline_access"IntentFilterLaunchMode = LaunchMode.SingleTaskOnNewIntentActivityMediator.Instance.Send(intent.DataString)Auth0ClientOptions| Mistake | Fix |
|---|---|
| App type not set to Native in Auth0 Dashboard | Change application type to "Native" in Dashboard settings |
| Missing callback URL in Auth0 Dashboard | Add |
| Android requires the scheme to be lowercase — use lowercase package name |
Missing | Set |
Not handling | Override |
Using | Domain should be hostname only (e.g., |
| Not passing Activity context to Auth0Client | Pass |
| IntentFilter DataHost/DataPathPrefix mismatch | Ensure DataHost matches your Auth0 domain and DataPathPrefix is |
Missing | Always include |
Using | Must use |
| Storing tokens in plain SharedPreferences | Use |
Agent instruction: Remind the user to test on a physical device in addition to emulators. Some WebAuth behaviors (Chrome Custom Tabs, URL scheme interception) may differ on physical devices vs. emulators. Test the full login → callback → token flow on real hardware before shipping.
OnNewIntentUserCancelusing Auth0.OidcClient;
var client = new Auth0Client(new Auth0ClientOptions
{
Domain = "YOUR_AUTH0_DOMAIN",
ClientId = "YOUR_AUTH0_CLIENT_ID",
Scope = "openid profile email offline_access"
}, this);var loginResult = await client.LoginAsync();var loginResult = await client.LoginAsync();
if (loginResult.IsError)
{
Debug.WriteLine($"An error occurred during login: {loginResult.Error}");
}var loginResult = await client.LoginAsync();
if (!loginResult.IsError)
{
Debug.WriteLine($"Authentication successful.");
}if (!loginResult.IsError)
{
Debug.WriteLine($"name: {loginResult.User.FindFirst(c => c.Type == "name")?.Value}");
Debug.WriteLine($"email: {loginResult.User.FindFirst(c => c.Type == "email")?.Value}");
}if (!loginResult.IsError)
{
foreach (var claim in loginResult.User.Claims)
{
Debug.WriteLine($"{claim.Type} = {claim.Value}");
}
}BrowserResultType browserResult = await client.LogoutAsync();[Activity(Label = "AndroidSample", MainLauncher = true, Icon = "@drawable/icon",
LaunchMode = LaunchMode.SingleTask)]
[IntentFilter(
new[] { Intent.ActionView },
Categories = new[] { Intent.CategoryDefault, Intent.CategoryBrowsable },
DataScheme = "YOUR_ANDROID_PACKAGE_NAME",
DataHost = "YOUR_AUTH0_DOMAIN",
DataPathPrefix = "/android/YOUR_ANDROID_PACKAGE_NAME/callback")]
public class MainActivity : Activity
{
// Code omitted
}protected override async void OnNewIntent(Intent intent)
{
base.OnNewIntent(intent);
Auth0.OidcClient.ActivityMediator.Instance.Send(intent.DataString);
}