Theodorus Agum Gumilang
Theodorus Agum Gumilang

Reputation: 1486

Trying to get users info with microsoft graph in Xamarin Forms

I want to get data from logedin users , so im searching in internet and found that i can use Azure AD Graph, or Microsoft Graph. So i Chose using Microsoft Graph and found this solution https://github.com/Azure-Samples/active-directory-xamarin-native-v2 and then im trying to implement with my azure b2c login so there some code that i change, here is some my code. This is my App.Cs

using Microsoft.Identity.Client;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;


using Xamarin.Forms;

namespace UsingGraphApi
{
    public partial class App : Application
    {

        public static PublicClientApplication AuthenticationClient { get; private set; }
      //  public static PublicClientApplication PCA = null;
        //public static string ClientID = "a7d8cef0-4145-49b2-a91d-95c54051fa3f";
      //  public static string[] Scopes = { "User.Read" };
       // public static string Username = string.Empty;

        //public static UIParent UiParent = null;


        public App()
        {
            InitializeComponent();
            AuthenticationClient = new PublicClientApplication(Constants.ApplicationID);

            MainPage = new NavigationPage(new MainPage());
        }

        protected override void OnStart()
        {
            // Handle when your app starts
        }

        protected override void OnSleep()
        {
            // Handle when your app sleeps
        }

        protected override void OnResume()
        {
            // Handle when your app resumes
        }
    }
}

this is my Constant.Cs

namespace UsingGraphApi
{
    public static class Constants
    {
        public static string ApplicationID = "c2026789-5e43-4d25-acc9-e00768d4b0b4";
        //public static string[] Scopes = { ApplicationID };
        public static string[] Scopes = { "User.Read" };
        public static string SignUpSignInPolicy = "B2C_1_signin";
        public static string ResetPasswordPolicy = "b2c_1_reset";
        public static string Authority = "https://login.microsoftonline.com/kgvaluecard.onmicrosoft.com/";


    }
}

and here is my MainPage.Cs

using Microsoft.Identity.Client;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;

using Xamarin.Forms;

namespace UsingGraphApi
{
    public partial class MainPage : ContentPage
    {
        public MainPage()
        {
            InitializeComponent();
        }

        protected override async void OnAppearing()
        {
            // let's see if we have a user in our belly already
            try
            {
                var result = await App.AuthenticationClient.AcquireTokenSilentAsync(Constants.Scopes);
                RefreshUserData(result.Token);
                //btnSignInSignOut.Text = "Sign out";
                await DisplayAlert("OK", "OK", "OK");

            }
            catch
            {
                // doesn't matter, we go in interactive more
               // btnSignInSignOut.Text = "Sign in";
            }
        }


        async void OnSignInSignOut(object sender, EventArgs e)
        {
            try
            {

                    var result = await App.AuthenticationClient.AcquireTokenAsync(
                    Constants.Scopes,
                    string.Empty,
                    UiOptions.SelectAccount,
                    string.Empty,
                    null,
                    Constants.Authority,
                    Constants.SignUpSignInPolicy);

                    RefreshUserData(result.Token);
                    //btnSignInSignOut.Text = "Sign out";

            }
            catch (Exception )
            {
                //
            }
        }

        public async void RefreshUserData(string Token)
        {

            //get data from API
            HttpClient client = new HttpClient();
            HttpRequestMessage message = new HttpRequestMessage(HttpMethod.Get, "https://graph.microsoft.com/v1.0/me");
            message.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("bearer", Token);
            HttpResponseMessage response = await client.SendAsync(message);
            string responseString = await response.Content.ReadAsStringAsync();
            if (response.IsSuccessStatusCode)
            {
                JObject user = JObject.Parse(responseString);

                slUser.IsVisible = true;
                lblDisplayName.Text = user["displayName"].ToString();
                lblGivenName.Text = user["givenName"].ToString();
                lblId.Text = user["id"].ToString();
                lblSurname.Text = user["mail"].ToString();
                lblUserPrincipalName.Text = user["userPrincipalName"].ToString();

                // just in case
                btnSignInSignOut.Text = "Sign out";


            }
            else
            {
                //DisplayAlert("Something went wrong with the API call", responseString, "Dismiss");
            }
        }

    }
}

the application is can be deployed and run well but the problem is i dont get the users information, is there any wrong with my code that i shouldnt change and by the way here is my MainPage.Xaml

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:UsingGraphApi"
             x:Class="UsingGraphApi.MainPage">

    <ContentPage.Content>
        <StackLayout>
            <Label Text="MSAL Xamarin Forms Sample" VerticalOptions="Start" HorizontalTextAlignment="Center" HorizontalOptions="FillAndExpand" />
            <BoxView Color="Transparent" VerticalOptions="FillAndExpand" HorizontalOptions="FillAndExpand" />
            <StackLayout x:Name="slUser" IsVisible="True" Padding="5,10">
                <StackLayout Orientation="Horizontal">
                    <Label Text="DisplayName " FontAttributes="Bold" />
                    <Label x:Name="lblDisplayName" />
                </StackLayout>
                <StackLayout Orientation="Horizontal">
                    <Label Text="GivenName " FontAttributes="Bold" />
                    <Label x:Name="lblGivenName" />
                </StackLayout>
                <StackLayout Orientation="Horizontal">
                    <Label Text="Surname " FontAttributes="Bold" />
                    <Label x:Name="lblSurname" />
                </StackLayout>
                <StackLayout Orientation="Horizontal">
                    <Label Text="Id " FontAttributes="Bold" />
                    <Label x:Name="lblId" />
                </StackLayout>
                <StackLayout Orientation="Horizontal">
                    <Label Text="UserPrincipalName " FontAttributes="Bold" />
                    <Label x:Name="lblUserPrincipalName" />
                </StackLayout>
            </StackLayout>
            <BoxView Color="Transparent" VerticalOptions="FillAndExpand" HorizontalOptions="FillAndExpand" />
            <Button x:Name="btnSignInSignOut" Text="Sign in" Clicked="OnSignInSignOut" VerticalOptions="End" HorizontalOptions="FillAndExpand"/>
        </StackLayout>
    </ContentPage.Content>

</ContentPage>

Upvotes: 1

Views: 801

Answers (1)

Fei Xue
Fei Xue

Reputation: 14649

This code sample is used for the converged applications which register from Application Registration Portal.

Based on the code of app config above, you were integrating app register from Azure AD B2C. In this scenario, this code sample is not suitable because the Azure AD B2C doesn't support the Microsoft Graph for the b2c apps. We need to register a separate app if we want to use the Microsoft Graph or Azure AD Graph with Azure AD b2c(refer Azure AD B2C: Use the Graph API).

To get the user info from Azure AD B2C, you can decode id_token directly which return after you authenticate. Refer the link below about decoding the token to retrieve the info:

How to decode JWT Token?

Upvotes: 2

Related Questions