OAuth Login Authenticating With Identity Provider In Xamarin.Forms

Introduction

 
OAuth is an authorization framework that enables the application to obtain limited access to user accounts on HTTP service on Facebook, Google, and Microsoft, etc. Nowadays, there is no need to create a registration logic. Alternatively, you can choose using identity provider login. In this case, a person signs up for the app using identity provider login, an account is created for them, and the authentication step is taken care of by the identity provider.
 
In this article, I will explain how to implement the below OAuth identity provider in Xamarin Forms and manage the authentication process in a Xamarin Forms application.

 

  1. GOOGLE
  2. FACEBOOK
  3. TWITTER
  4. MICROSOFT
  5. LINKEDIN
  6. GITHUB
  7. FLICKER
  8. YAHOO
  9. DROPBOX
xamarin Forms application
 
Register a Mobile App with Identity Provider
 
You can find my previous article for registering a mobile app with an identity provider from here.
 
Step 1 - Create New Xamarin.Forms Project
 
Let's start by creating a new Xamarin Forms Project in Visual Studio.
 
Open Run - Type Devenev.Exe and enter - New Project (Ctrl+Shift+N) - select Blank Xaml App (Xamarin.Forms Portable) template.
 
Blank
 
It will automatically create multiple projects, like Portable, Android, iOS, and UWP but here, I will be targeting only Android. However, the implementation of iOS and UWP is similar.
 
Step 2 - Install OAuth Client Components
 
Xamarin.Auth is a cross-platform SDK for authenticating users and storing their accounts. It includes OAuth authenticators that provide support for consuming identity providers.
 
Let's add the Xamarin.Auth component for OAuth. We will have to add this in all platform-specific projects, separately. 
 
Go to any project (DevEnVExeLogin.Droid) - Components - Right-click on "Get More Components".
 
If you are not logged in already, it will show the login page. So, log in there.
 
Next, search and double-click on Xamarin.Auth component and click on "Add to App".
 
Xamarin.Auth
 
Step 3 - Create Base Login Page (LoginPage.Xaml)
 
I have created quick and simple login screens . You can modify them as per your requirement.
 
Right-click on Portable Class Library - Add New Item - Select Xaml Page(Login Page).
 
LoginPage.Xaml

 

  1. <?xml version="1.0" encoding="utf-8" ?>  
  2. <ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:local="clr-namespace:DevEnvExeLogin" x:Class="DevEnvExeLogin.LoginPage">  
  3.     <StackLayout>  
  4.         <Entry Placeholder="Username" />  
  5.         <Entry IsPassword="true" Placeholder="Password" />  
  6.         <Button Text="Login" HeightRequest="50" />  
  7.         <Button Text="Google" Clicked="LoginClick" Image="GOOGLE.png" HeightRequest="50" />  
  8.         <Button Text="FaceBook" Clicked="LoginClick" Image="FACEBOOK.png" HeightRequest="50" />  
  9.         <Button Text="Twitter" Clicked="LoginClick" Image="TWITTER.png" HeightRequest="50" />  
  10.         <Button Text="Github" Clicked="LoginClick" Image="GITHUB.png" HeightRequest="50" />  
  11.         <Button Text="Yahoo" Clicked="LoginClick" Image="YAHOO.png" HeightRequest="50" />  
  12.         <Button Text="DropBox" Clicked="LoginClick" Image="DROPBOX.png" HeightRequest="50" />  
  13.         <Button Text="LinkedIn" Clicked="LoginClick" Image="LINKEDIN.png" HeightRequest="50" />  
  14.         <Button Text="Flicker" Clicked="LoginClick" Image="FLICKER.png" HeightRequest="40" />  
  15.         <Button Text="Twitter" Clicked="LoginClick" Image="MICROSOFT.png" HeightRequest="40" /> </StackLayout>  
  16. </ContentPage>  
LoginPage.Xaml.CS
 
Add LoginClick event in login page code behind the file and sender object will return the button text name (eg: Facebook, Twitter, etc).
  1. using System;  
  2. using Xamarin.Forms;  
  3. namespace DevEnvExeLogin {  
  4.     public partial class LoginPage: ContentPage {  
  5.         public LoginPage() {  
  6.             InitializeComponent();  
  7.         }  
  8.         void LoginClick(object sender, EventArgs args) {  
  9.             Button btncontrol = (Button) sender;  
  10.             string providername = btncontrol.Text;  
  11.             if (OAuthConfig.User == null) {  
  12.                 Navigation.PushModalAsync(new ProviderLoginPage(providername));  
  13.                 //Need to create ProviderLoginPage so follow Step 4 and Step 5  
  14.             }  
  15.         }  
  16.     }  
  17. }  
Step 4 - Create Identity Provider Login Page
 
As we will be having platform-specific LoginPage implementation of Xamarin.Auth, we don't need any specific implementation in the portable project.
 
We do need to add an empty ProviderLoginPage which will be resolved at runtime and substituted by actual implementation regarding this will explain in step 5.
 
Right Click Portable Project - Add New Item Select Xaml page (ProviderLoginPage.Xaml )
  1. using Xamarin.Forms;  
  2. namespace DevEnvExeLogin {  
  3.     public partial class ProviderLoginPage: ContentPage {  
  4.         //we will refer providename from renderer page  
  5.         public string ProviderName {  
  6.             get;  
  7.             set;  
  8.         }  
  9.         public ProviderLoginPage(string _providername) {  
  10.             InitializeComponent();  
  11.             ProviderName = _providername;  
  12.         }  
  13.     }  
  14. }  
** In Xaml page, you need to make no changes.
 
Step 5: Create Platform Specific Login Renderer
 
Create Platform
 
We need to create platform-specific LoginRenderer Page. So, you have to create platform-specific Login page (loginRenderer.CS) to iOS, Android, and UWP projects.
 
We need to add LoginPageRenderer which will be used by Xamarin.Auth to display the webView for OAuth Login Page
 
Code Snippet Explanation
 
The below code is for Xamarin.Forms Dependency Service which maps ProviderLoginPage to LoginRenderer.
  1. [assembly: ExportRenderer(typeof(ProviderLoginPage), typeof(LoginRenderer))]  
  2.   
  3.   
  4. Get Identity ProviderName from Providerloginpage  
  5. var loginPage = Element as ProviderLoginPage;  
  6. string providername = loginPage.ProviderName;  
Create OAuthProviderSetting class from Portable Class Library with OAuth Implementation. It is explained in Step 6.
  1. //Create OauthProviderSetting class with Oauth Implementation .Refer Step 6  
  2. OAuthProviderSetting oauth = new OAuthProviderSetting();  
  3. var auth = oauth.LoginWithProvider(providername);  
  4. Create Oauth event  
  5. for provider login completed and canceled.  
  6. auth.Completed += (sender, eventArgs) => {  
  7.         if (eventArgs.IsAuthenticated) { //Login Success }  
  8.             else {  
  9.                 // The user canceled 
  10.             }  
  11.         };  
If you want to get and save user info. You can create UserEntity from Portable Library and refer the below code.
  1. namespace DevEnvExeLogin {  
  2.     public class UserDetails {  
  3.         public string TwitterId {  
  4.             get;  
  5.             set;  
  6.         }  
  7.         public string Name {  
  8.             get;  
  9.             set;  
  10.         }  
  11.         public string ScreenName {  
  12.             get;  
  13.             set;  
  14.         }  
  15.         public string Token {  
  16.             get;  
  17.             set;  
  18.         }  
  19.         public string TokenSecret {  
  20.             get;  
  21.             set;  
  22.         }  
  23.         public bool IsAuthenticated {  
  24.             get {  
  25.                 return !string.IsNullOrWhiteSpace(Token);  
  26.             }  
  27.         }  
  28.     }  
  29. }  
LoginRenderer.CS
  1. using Android.App;  
  2. using Xamarin.Forms.Platform.Android;  
  3. using DevEnvExeLogin;  
  4. using Xamarin.Forms;  
  5. using DevEnvExeLogin.Droid.PageRender;  
  6. [assembly: ExportRenderer(typeof(ProviderLoginPage), typeof(LoginRenderer))]  
  7. namespace DevEnvExeLogin.Droid.PageRender {  
  8.     public class LoginRenderer: PageRenderer {  
  9.         bool showLogin = true;  
  10.         protected override void OnElementChanged(ElementChangedEventArgs < Page > e) {  
  11.             base.OnElementChanged(e);  
  12.             //Get and Assign ProviderName from ProviderLoginPage  
  13.             var loginPage = Element as ProviderLoginPage;  
  14.             string providername = loginPage.ProviderName;  
  15.             var activity = this.Context as Activity;  
  16.             if (showLogin && OAuthConfig.User == null) {  
  17.                 showLogin = false;  
  18.                 //Create OauthProviderSetting class with Oauth Implementation .Refer Step 6  
  19.                 OAuthProviderSetting oauth = new OAuthProviderSetting();  
  20.                 var auth = oauth.LoginWithProvider(providername);  
  21.                 // After facebook,google and all identity provider login completed   
  22.                 auth.Completed += (sender, eventArgs) => {  
  23.                     if (eventArgs.IsAuthenticated) {  
  24.                         OAuthConfig.User = new UserDetails();  
  25.                         // Get and Save User Details   
  26.                         OAuthConfig.User.Token = eventArgs.Account.Properties["oauth_token"];  
  27.                         OAuthConfig.User.TokenSecret = eventArgs.Account.Properties["oauth_token_secret"];  
  28.                         OAuthConfig.User.TwitterId = eventArgs.Account.Properties["user_id"];  
  29.                         OAuthConfig.User.ScreenName = eventArgs.Account.Properties["screen_name"];  
  30.                         OAuthConfig.SuccessfulLoginAction.Invoke();  
  31.                     } else {  
  32.                         // The user cancelled  
  33.                     }  
  34.                 };  
  35.                 activity.StartActivity(auth.GetUI(activity));  
  36.             }  
  37.         }  
  38.     }  
  39. }  
Step 6: OAuth Implementation
 
The OAuth2Authenticator class is responsible for managing the user interface and communicating with authentication services. It will support all the identity providers. 
 
But, on Twitter, OAuth authentication will support only on OAuth1Authenticator. So, you can use the OAuth1Authenticator instead of the OAuth2Authenticator.
 
The OAuth2Authenticator and OAuth1Authenticator class require a number of parameters, as shown in the following list. 
  • Client ID – Identity provider-client ID. While registering the app, you will need a unique Client ID.
  • Client Secret – identifies the client that is making the request. While registering the app, you will need a unique Client Secret
  • Scope – identifies the API access being requested by the application, and the value informs the consent screen that is shown to the user.
  • Authorize URL – identifies the URL where the authorization code will be obtained from.
  • Redirect URL –  identifies the URL where the response will be sent. The value of this parameter must match one of the values that appear on the Credentials page of the project.
  • AccessToken URL —  identifies the URL used to request access tokens after an authorization code is obtained.
     
    Step 6.1: Access GOOGLE Account
    1. var googleauth = new OAuth2Authenticator(  
    2. // For Google login, for configure refer http://www.c-sharpcorner.com/article/register-identity-provider-for-new-oauth-application/  
    3. "ClientId",  
    4. "ClientSecret",  
    5. // Below values do not need changing  
    6. "https://www.googleapis.com/auth/userinfo.email",  
    7. new Uri("https://accounts.google.com/o/oauth2/auth"),  
    8. new Uri("http://www.devenvexe.com"),// Set this property to the location the user will be redirected too after successfully authenticating  
    9. new Uri("https://accounts.google.com/o/oauth2/token")  
    10. );  
    Step 6.2: Access FACEBOOK Account
    1. var OauthFacebook = new OAuth2Authenticator(  
    2. clientId: "MyAppId"// For Facebook login, for configure refer http://www.c-sharpcorner.com/article/register-identity-provider-for-new-oauth-application/  
    3. scope: "",  
    4. authorizeUrl: new Uri("https://m.facebook.com/dialog/oauth/"), // These values do not need changing  
    5. redirectUrl: new Uri("http://www.facebook.com/connect/login_success.html")// These values do not need changing  
    6. );  
    Step 6.3: Access TWITTER Account
    1. OAuth1Authenticator auth = new OAuth1Authenticator(  
    2. consumerKey: "*****"// For Twitter login, for configure refer http://www.c-sharpcorner.com/article/register-identity-provider-for-new-oauth-application/  
    3. consumerSecret: "****"// For Twitter login, for configure refer http://www.c-sharpcorner.com/article/register-identity-provider-for-new-oauth-application/  
    4. requestTokenUrl: new Uri("https://api.twitter.com/oauth/request_token"), // These values do not need changing  
    5. authorizeUrl: new Uri("https://api.twitter.com/oauth/authorize"), // These values do not need changing  
    6. accessTokenUrl: new Uri("https://api.twitter.com/oauth/access_token"), // These values do not need changing  
    7. callbackUrl: new Uri("http://www.devenvexe.com") // Set this property to the location the user will be redirected too after successfully authenticating  
    Step 6.4 Access Microsoft Account
    1. var OauthMicrosoft = new OAuth2Authenticator(  
    2. clientId: "MY ID"// For Micrsoft login, for configure refer http://www.c-sharpcorner.com/article/register-identity-provider-for-new-oauth-application/  
    3. scope: "bingads.manage",  
    4. authorizeUrl: new Uri("https://login.live.com/oauth20_authorize.srf?client_id=myid&scope=bingads.manage&response_type=token&redirect_uri=https://login.live.com/oauth20_desktop.srf"),  
    5. redirectUrl: new Uri("https://adult-wicareerpathways-dev.azurewebsites.net/Account/ExternalLoginCallback")  
    6. );  
    Step 6.5 Access LINKEDIN Account
    1. var authLinkediN = new OAuth2Authenticator(  
    2. clientId: "**",// For LinkedIN login, for configure refer http://www.c-sharpcorner.com/article/register-identity-provider-for-new-oauth-application/  
    3. clientSecret: "**",  
    4. scope: "",  
    5. authorizeUrl: new Uri("https://www.linkedin.com/uas/oauth2/authorization"),  
    6. redirectUrl: new Uri("http://devenvexe.com/"),  
    7. accessTokenUrl: new Uri("https://www.linkedin.com/uas/oauth2/accessToken")  
    Step 6.6 Access GITHUB Account
    1. auth = new OAuth2Authenticator(  
    2. // For GITHUB login, for configure refer http://www.c-sharpcorner.com/article/register-identity-provider-for-new-oauth-application/  
    3. "ClientId",  
    4. "ClientSecret",  
    5. // Below values do not need changing  
    6. "",  
    7. new Uri("https://github.com/login/oauth/authorize"),  
    8. new Uri("http://www.devenvexe.com"),// Set this property to the location the user will be redirected too after successfully authenticating  
    9. new Uri("https://github.com/login/oauth/access_token")  
    10. );  
    Step 6.7 Access FLICKER Account
    1. auth = new OAuth2Authenticator(  
    2. // For Flicker login, for configure refer http://www.c-sharpcorner.com/article/register-identity-provider-for-new-oauth-application/  
    3. "ClientId",  
    4. "ClientSecret",  
    5. // Below values do not need changing  
    6. "",  
    7. new Uri("https://www.flickr.com/services/oauth/request_token"),  
    8. new Uri("http://www.devenvexe.com"),// Set this property to the location the user will be redirected too after successfully authenticating  
    9. new Uri("http://www.flickr.com/services/oauth/access_token")  
    10. );  
    Step 6.8 Access YAHOO Account
    1. auth = new OAuth2Authenticator(  
    2. // For Yahoo login, for configure refer http://www.c-sharpcorner.com/article/register-identity-provider-for-new-oauth-application/  
    3. "ClientId",  
    4. "ClientSecret",  
    5. // Below values do not need changing  
    6. "",  
    7. new Uri("https://api.login.yahoo.com/oauth2/request_auth"),  
    8. new Uri("http://www.devenvexe.com"),// Set this property to the location the user will be redirected too after successfully authenticating  
    9. new Uri("https://api.login.yahoo.com/oauth2/get_token")  
    10. );  
You can download the source code and replace the Client ID or AppID and Client secret.
 
OUTPUT
 
OUTPUT
 
OUTPUT
 


Similar Articles