Xamarin Google authentication with OAuth

In this article i will show you how authenticate against google with oauth and a mobile app.

When i was trying to get the authentication running, i did not find a good working example for a android phone and Xamarin. There are a lot of good post and blogs out in the internet, but somehow they uses deprecated libs a lot.

All the code i use here can be found on my github page

Setup your data and environment

In this example i will use following libs

The following data needs to prepared in order to start the App

packagename

Something like –> ‚com.companyname.googleoauthexample‘. more info

visual studio package nameing


The name is important for the authentication flow. You will need the name in different places

  • android manifest
  • google auth client id
  • request data
  • redirect activity

Service Scope

select a/the scope to which service you want to talk to

google auth client id

get a google auth client id something like ‚7yyyyyyyyyy-8xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.apps.googleusercontent.com‘ (how to create a id) .

shows how to setup android mobile devcic oauth client at google cloud console

When you have all the data we can start with the app .


The App : get started

Basically the app has 3 main parts

  1. authorization request code
  2. redirection activity
  3. get credential code

authorization request code

this will authenticate you with google and the requested service.

            string redirectUri = "com.xxxx.yyyyyy:/oauth2redirect";
            var client_id = "nnnnnnnnnnnnnnnnnnnnnnnnnnn.apps.googleusercontent.com";
            var authUrl = CreateAuthorizationRequest(client_id, redirectUri, AndroidManagementService.Scope.Androidmanagement);

            var authResult = await WebAuthenticator.AuthenticateAsync(
                new Uri(authUrl), 
                new Uri(redirectUri));       

            var code = authResult.Properties["code"];

           
  public string CreateAuthorizationRequest(string clientId, string redirectURI, string scope)
        {
            // Create URI to authorization endpoint
            var authorizeRequest = new RequestUrl(GoogleAuthConsts.AuthorizationUrl);
            currentCSRFToken = Guid.NewGuid().ToString("N");

            var dic = new Dictionary<string, string>
            {
                {"client_id", clientId},
                {"response_type", "code"},
                {"scope", scope},
                {"redirect_uri", redirectURI},
                {"prompt", "consent"},

                {"state", currentCSRFToken}  , // Add CSRF token to protect against cross-site request forgery attacks.
                {"token_uri", "https://accounts.google.com/o/oauth2/token" }
            };

            var authorizeUri = authorizeRequest.Create(Parameters.FromObject(dic));
            return authorizeUri;
        }

This call/code popup a new Authentication Window which guides the user thru the process. When the process is finished the Window needs to know where to send the result. On Android Xamarin this is done by adding a callback activity

Error :dissallowed_useragent

When executing the code on a emulator device i get the error dissallowed_useragent, however, if i execute this on my real device it will work. So be aware using emulated devices.

error 403 (dissallowed_useragent) when when using a emulated device
disallowed_useragent

redirection activity

As mentioned above you need to tell the device where to send the authentication result. Just add a class to the android project

visual studio project structure shows the files needed to redirect from a web call
using Android.App;
using Android.Content;
using Android.Content.PM;

namespace GoogleOAuthExample.Droid
{


    [Activity(NoHistory = true, LaunchMode = LaunchMode.SingleTop, Exported = true)]
    [IntentFilter(new[] { Intent.ActionView }, Categories = new[] { Intent.CategoryDefault, Intent.CategoryBrowsable }, DataScheme = "com.xxxx.yyyyyyr")]

    public class WebAuthenticationCallbackActivity : Xamarin.Essentials.WebAuthenticatorCallbackActivity
    {
    }
}

get the access_token

when use the WebAuthentictor we do not get the access_token in the first place. We need to call google again. (If someone knows why this is so, please let me know in the comments)

var authResult = await WebAuthenticator.AuthenticateAsync(new Uri(authUrl), new Uri(redirectUri));       

var code = authResult.Properties["code"];

var client = new RestClient(new Uri("https://oauth2.googleapis.com"));
var request = new RestRequest("token", Method.Post);
request.AddParameter("code", code);
request.AddParameter("client_id", client_id);
request.AddParameter("redirect_uri", redirectUri);
request.AddParameter("grant_type", "authorization_code");
request.AddHeader("content-type", "application/x-www-form-urlencoded");
var response = await client.ExecuteAsync<MyAuthResult>(request);
[Serializable]
public class MyAuthResult
{
   public string access_token { get; set; }
   public int expires_in { get; set; }
   public string refresh_token { get; set; }
   public string scope { get; set; }
   public string token_type { get; set; }
}

The return of the post call should look like this :

{
  "access_token": "ya29.a0Aa4xrXO_FCrRmljQ4r-BnHi-AWUZ_jArZimTfAJ6XLUfueXE_OmVjqVSq5P8U4cHEzu2tgqXs4SJ18f6hvC3bV7DjMgkH44a_zcmIMIX6-ThKIcm1FHbXI...................",
  "expires_in": 3599,
  "refresh_token": "1//09--o7bUJZk0iCgYIARAAGAkSNwF-L9Ir15GxMlHBpwy62TC57iNkCMDsDO.............",
  "scope": "https://www.googleapis.com/auth/androidmanagement",
  "token_type": "Bearer"
}

With the access_token you should be able to authenticate to the google services you need


With this information you should be able to authenticate with xamarin forms against google. It worked on my real Xiaomi Mi 9 (Api 29). Checkout the code on my github page

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert