MobileAndroidOAuth with Xamarin Forms Passive Authentication for iOS Apps

OAuth with Xamarin Forms Passive Authentication for iOS Apps

Developer.com content and product recommendations are editorially independent. We may make money when you click on links to our partners. Learn More.

Introduction

There are scenarios where we need to authenticate against an API that has its own OAuth. The user gets redirected to their API authentication site and it returns a token to the calling app. This process is a passive authentication because the user does not key the credentials in the app directly. In this article, we will learn how to do a passive authentication in Xamarin Forms for iOS.

Description

To begin with, we will create a Xamarin Forms application with a target platform as iOS. Passive authentication will be implemented at the iOS level using ‘SFSafariViewControllerDelegate‘.

Xamarin Forms Level Changes

In the Xamarin Forms project, add a new interface named “IConnect.cs” with the following definition:

public interface IConnect
{
   Task ConnectAuth();
}

The method ‘ConnectAuth‘ will be defined in the platform-specific project.

Add the ‘FreshMVVM’ NuGet package to the project. In the constructor method of App.Xaml.cs, register and resolve the dependency service—IConnect—as shown in this next code snippet:

FreshIOC.Container.Register(DependencyService.Get<IConnect>());
var connectService = FreshIOC.Container.Resolve<IConnect>();

This dependency service will be injected in the <xaml>.cs page as a parameter in the constructor. In this example, a page named ‘ConnectAppPage.xaml’ is created and the page is set as a main page in App.xaml.cs:

MainPage = new ConnectAppPage(connectService);

In ConnectAppPage.xaml.cs, the constructor is defined as shown next:

IConnect _connect;
public ConnectAppPage(IConnect connect)
{
   InitializeComponent();
   _connect = connect;
}

In the XAML project, add a button. In the button click event handler, call the IConnect’s Connect method:

async void Connect_Clicked(object sender, System.EventArgs e)
{
   await _connect.ConnectAuth();
}

This completes the required changes in the forms app.

iOS Changes

Dependency Implementation

In the iOS project, add a class file named ‘Connect.cs’. This will be the implementation for the ‘IConnect’ service created in the forms project. This class inherits the SFSafariViewControllerDelegate class and the ‘IConnect’ interface.

The namespace with decorated with the following:

[assembly: Xamarin.Forms.Dependency(typeof(Connect))]
namespace ConnectApp.iOS
{
   public class Connect: SFSafariViewControllerDelegate, IConnect
....

In most OAuth authentication, there are a few common parameters that are required. They are:

const string baseURL = "https://<OAuth Url>";
const string redirectURI = "testauthentication://logincallback";

The baseUrl is the URL to the authentication site and the redirectURI is a value with which the app is identified and is redirected. Please note that redirectURI should match with the redirect URL scheme defined at the authentication site when the app was registered with it.

Declare an object of SFSafariViewController. In the constructor, define the following:

SFSafariViewController authorizationVC;

public Connect()
{
   NSNotificationCenter.DefaultCenter.AddObserver
      (new NSString("SampleAuth"), (obj) =>
   {
      // Parse and extract token
      string urlValue = obj.ToString();

      // Dismiss the view controller
      authorizationVC?.DismissViewController(true, null);

   });
}

We have added an observer the received the token from the app delegate.

Now, we define the ConnectAuth method as shown in the following code section:

public async Task ConnectAuth()
{
   var url = baseURL + "?redirect_uri=" + redirectURI;

   Foundation.NSUrl nsUrl = new Foundation.NSUrl(url);

   authorizationVC = new SFSafariViewController(nsUrl);
   authorizationVC.Delegate = this;
   var rootController = UIApplication.SharedApplication.KeyWindow
      .RootViewController;

   rootController.PresentViewController(authorizationVC,
      true, null);
}

The URL defined above is just a sample; in real scenarios, there will be other parameters in addition to the base URL and the redirect URI. This method opens the URL in a Safari browser. The user can enter the login credentials and get navigated to the calling app.

AppDelegate Changes

In the app delegate, add the following method to retrieve the redirect URL with the auth token information:

public override bool OpenUrl(UIApplication app, NSUrl url,
   NSDictionary options)
{
   if (url.ToString().ToLower().Contains("testauthentication"))
   {
      NSNotificationCenter.DefaultCenter.PostNotificationName
         ("SampleAuth", url);
      return true;
   }

   return base.OpenUrl(app, url, options);
}

When the Safari view controller completes its operation, the redirect URL return value can be accessed in the OpenUrl method. We check if the redirect URL is correct; in other words, we check for ‘testauthentication‘ and trigger a notification named ‘SampleAuth‘ and pass the URL value as a message. This notification message then is read by the observer defined in the dependency implementation constructor.

In addition, the following changes are required in the info.plist:

<key>CFBundleURLTypes</key>
<array>
   <dict>
      <key>CFBundleURLName</key>
      <string><bundle identifier></string>
      <key>CFBundleURLSchemes</key>
      <array>
         <string>testauthentication</string>
      </array>
      <key>CFBundleURLTypes</key>
      <string>Viewer</string>
   </dict>
</array>

Add the ‘CFBundleUrlTypes’ key with array values ‘bundle identifier’, the URL scheme—’testauthentication’—and the CFBundleURLTypes as ‘Viewer’.

<key>LSApplicationQueriesSchemes</key>
<array>
   <string>testauthentication</string>
   <string><bundle identifier></string>
</array>

Add another key named ‘LSApplicationQueriesSchemes’ with the array values as the URL scheme; in other words, the first part of the redirect URI and the bundle identifier.

This completes the required configuration. Next, the app gets authenticated by using oAuth.

Summary

In this article, we saw how to do a passive authentication using SFSafariViewController. The token is passed back to the redirect URL as a query string that can be parsed and used for accessing APIs.

Get the Free Newsletter!

Subscribe to Developer Insider for top news, trends & analysis

Latest Posts

Related Stories