Add authentication to your Xamarin.Android app

Overview

This topic shows you how to authenticate users of a Mobile App from your client application. In this tutorial, you add authentication to the quickstart project using an identity provider that is supported by Azure Mobile Apps. After being successfully authenticated and authorized in the Mobile App, the user ID value is displayed.

This tutorial is based on the Mobile App quickstart. You must also first complete the tutorial Create a Xamarin.Android app. If you do not use the downloaded quick start server project, you must add the authentication extension package to your project. For more information about server extension packages, see Work with the .NET backend server SDK for Azure Mobile Apps.

Register your app for authentication and configure App Services

First, you need to register your app at an identity provider's site, and then you will set the provider-generated credentials in the Mobile Apps back end.

  1. Configure your preferred identity provider by following the provider-specific instructions:

  2. Repeat the previous steps for each provider you want to support in your app.

Add your app to the Allowed External Redirect URLs

Secure authentication requires that you define a new URL scheme for your app. This allows the authentication system to redirect back to your app once the authentication process is complete. In this tutorial, we use the URL scheme appname throughout. However, you can use any URL scheme you choose. It should be unique to your mobile application. To enable the redirection on the server side:

  1. In the [Azure portal], select your App Service.

  2. Click the Authentication / Authorization menu option.

  3. In the Allowed External Redirect URLs, enter url_scheme_of_your_app://easyauth.callback. The url_scheme_of_your_app in this string is the URL Scheme for your mobile application. It should follow normal URL specification for a protocol (use letters and numbers only, and start with a letter). You should make a note of the string that you choose as you will need to adjust your mobile application code with the URL Scheme in several places.

  4. Click OK.

  5. Click Save.

Restrict permissions to authenticated users

By default, APIs in a Mobile Apps back end can be invoked anonymously. Next, you need to restrict access to only authenticated clients.

  • Node.js back end (via the Azure portal) :

    In your Mobile Apps settings, click Easy Tables and select your table. Click Change permissions, select Authenticated access only for all permissions, and then click Save.

  • .NET back end (C#):

    In the server project, navigate to Controllers > TodoItemController.cs. Add the [Authorize] attribute to the TodoItemController class, as follows. To restrict access only to specific methods, you can also apply this attribute just to those methods instead of the class. Republish the server project.

      [Authorize]
      public class TodoItemController : TableController<TodoItem>
    
  • Node.js backend (via Node.js code) :

    To require authentication for table access, add the following line to the Node.js server script:

      table.access = 'authenticated';
    

    For more details, see How to: Require authentication for access to tables. To learn how to download the quickstart code project from your site, see How to: Download the Node.js backend quickstart code project using Git.

In Visual Studio or Xamarin Studio, run the client project on a device or emulator. Verify that an unhandled exception with a status code of 401 (Unauthorized) is raised after the app starts. This happens because the app attempts to access your Mobile App backend as an unauthenticated user. The TodoItem table now requires authentication.

Next, you will update the client app to request resources from the Mobile App backend with an authenticated user.

Add authentication to the app

The app is updated to require users to tap the Sign in button and authenticate before data is displayed.

  1. Add the following code to the TodoActivity class:

     // Define an authenticated user.
     private MobileServiceUser user;
     private async Task<bool> Authenticate()
     {
             var success = false;
             try
             {
                 // Sign in with Facebook login using a server-managed flow.
                 user = await client.LoginAsync(this,
                     MobileServiceAuthenticationProvider.Facebook, "{url_scheme_of_your_app}");
                 CreateAndShowDialog(string.Format("you are now logged in - {0}",
                     user.UserId), "Logged in!");
    
                 success = true;
             }
             catch (Exception ex)
             {
                 CreateAndShowDialog(ex, "Authentication failed");
             }
             return success;
     }
    
     [Java.Interop.Export()]
     public async void LoginUser(View view)
     {
         // Load data only after authentication succeeds.
         if (await Authenticate())
         {
             //Hide the button after authentication succeeds.
             FindViewById<Button>(Resource.Id.buttonLoginUser).Visibility = ViewStates.Gone;
    
             // Load the data.
             OnRefreshItemsSelected();
         }
     }
    
     public override void OnResume()
     {
         base.OnResume();
         Xamarin.Essentials.Platform.OnResume();
     }
    

    This creates a new method to authenticate a user and a method handler for a new Sign in button. The user in the example code above is authenticated by using a Facebook login. A dialog is used to display the user ID once authenticated.

    Note

    If you are using an identity provider other than Facebook, change the value passed to LoginAsync above to one of the following: MicrosoftAccount, Twitter, Google, or WindowsAzureActiveDirectory.

  2. In the OnCreate method, delete or comment-out the following line of code:

     OnRefreshItemsSelected ();
    
  3. In the Activity_To_Do.axml file, add the following LoginUser button definition before the existing AddItem button:

       <Button
         android:id="@+id/buttonLoginUser"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:onClick="LoginUser"
         android:text="@string/login_button_text" />
    
  4. Add the following element to the Strings.xml resources file:

     <string name="login_button_text">Sign in</string>
    
  5. Open the AndroidManifest.xml file, add the following code inside <application> XML element:

     <activity android:name="com.microsoft.windowsazure.mobileservices.authentication.RedirectUrlActivity" android:launchMode="singleTop" android:noHistory="true">
       <intent-filter>
         <action android:name="android.intent.action.VIEW" />
         <category android:name="android.intent.category.DEFAULT" />
         <category android:name="android.intent.category.BROWSABLE" />
         <data android:scheme="{url_scheme_of_your_app}" android:host="easyauth.callback" />
       </intent-filter>
     </activity>
    
  6. In Visual Studio or Xamarin Studio, run the client project on a device or emulator and sign in with your chosen identity provider. When you are successfully logged-in, the app will display your login ID and the list of todo items, and you can make updates to the data.

Troubleshooting

The application crashed with Java.Lang.NoSuchMethodError: No static method startActivity

In some cases, conflicts in the support packages displayed as just a warning in the Visual studio, but the application crashes with this exception at runtime. In this case you need to make sure that all the support packages referenced in your project have the same version. The Azure Mobile Apps NuGet package has Xamarin.Android.Support.CustomTabs dependency for Android platform, so if your project uses newer support packages you need to install this package with required version directly to avoid conflicts.