Using Bearer Token for Authentication in .NET MAUI

In this blog, we'll walk through how to use Bearer Token authentication in a .NET MAUI application. The example shows how to authenticate a user via a POST request and then use the Bearer Token to fetch data from an API. We'll break down the implementation using XAML for the UI, C# for handling API requests, and token-based authentication.

Step 1. Creating the UI (MainPage.xaml)

We first need a UI where users can input their credentials (email and password) and view data fetched after successful authentication.

Here’s the XAML code.

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="Mauitemp.PageThree"
             Title="PageThree">
    <VerticalStackLayout Spacing="20">
        <Label 
            Text="Welcome to the page where we used Bearer token Authentication"
            VerticalOptions="Center" 
            HorizontalOptions="Center"
            FontSize="24"
            FontAttributes="Bold"/>
        <Label/>
        <Entry x:Name="Email" Placeholder="Email" Text="" HorizontalOptions="Center" WidthRequest="250" />
        <Entry x:Name="Pass" Placeholder="Password" Text="" HorizontalOptions="Center"  WidthRequest="250" />

        <Button  Text="Fetch Data" BackgroundColor="White"  WidthRequest="250"  Clicked="Button_Clicked"/>

        <Label/>
        <HorizontalStackLayout  Spacing="20" HorizontalOptions="Center">
            <Label  Text="Date:" TextColor="White" FontSize="24" />
            <Label x:Name="Date" Text="" TextColor="Red" FontSize="24" />
        </HorizontalStackLayout>
        <Label/>
        <HorizontalStackLayout Spacing="20" HorizontalOptions="Center">
            <Label   Text="Temperature in F:" TextColor="White" FontSize="24" />
            <Label  x:Name="TempF" Text="" TextColor="Red" FontSize="24" />
        </HorizontalStackLayout>
        <Label/>
        <HorizontalStackLayout Spacing="20" HorizontalOptions="Center">
            <Label   Text="temperatue in C:" TextColor="White" FontSize="24" />
            <Label  x:Name="TempC" Text="" TextColor="Red" FontSize="24" />
        </HorizontalStackLayout>
        <Label/>
        <HorizontalStackLayout  Spacing="20">
            <Label  Text="Summary:" TextColor="White" FontSize="24" />
            <Label   x:Name="Summary" Text="" TextColor="Red" FontSize="24" />
        </HorizontalStackLayout>

    </VerticalStackLayout>
</ContentPage>

UI

Step 2. Handling Authentication and Data Fetch (MainPage.cs)

The core logic resides in the Button_Clicked event handler. When the user clicks the "Fetch Data" button, we send the user's credentials to the API via a POST request to retrieve a Bearer Token. Once we have the token, we use it to fetch weather data from a protected endpoint.

Here’s the C# code that manages the authentication and data fetch.

using Mauitemp.Model;
using System.Diagnostics;
using System.Text.Json;

namespace Mauitemp
{
    public partial class PageThree : ContentPage
    {
        private readonly RestService restService;
        public PageThree()
        {
            InitializeComponent();
        }
        private async void Button_Clicked(object sender, EventArgs e)
        {
            // Create a model instance with user-provided email and password
            BModel model = new()
            {
                email = Email.Text,
                password = Pass.Text
            };
            // Define the URLs for login and fetching weather data
            string loginUrl = "https://localhost:7111/login";
            string weatherUrl = "https://localhost:7111/WeatherForecast";
            // Attempt to authenticate the user
            (int statuscode, string content) = await RestService.HTTPCall2(loginUrl, "POST", model, false);
            if (statuscode == 200)
            {
                // Deserialize the response to retrieve the access token
                BModel User = BModel.GetInstance;
                BModel UserData = JsonSerializer.Deserialize<BModel>(content);
                if (UserData != null)
                {
                    User.accessToken = UserData.accessToken;
                }
                // Check if the token was successfully retrieved
                if (!string.IsNullOrEmpty(User.accessToken))
                {
                    // Fetch the weather data using the retrieved token
                    (int statuscode1, string content1) = await RestService.HTTPCall2(weatherUrl, "GET", null, true);
                    if (statuscode1 == 200)
                    {
                        // Deserialize the weather data and display it
                        var weatherData = JsonSerializer.Deserialize<List<BModel>>(content1);
                        if (weatherData != null)
                        {
                            Date.Text = weatherData[0].date.ToString();
                            TempF.Text = weatherData[0].temperatureF.ToString();
                            TempC.Text = weatherData[0].temperatureC.ToString();
                            Summary.Text = weatherData[0].summary;
                        }
                    }
                    else
                    {
                        await DisplayAlert("Error", "Failed to retrieve weather data", "OK");
                    }
                }
                else
                {
                    await DisplayAlert("Error", "Token not retrieved", "OK");
                }
            }
            else
            {
                await DisplayAlert("Error", "Invalid Credentials", "OK");
            }
        }
    }
}

Step 3. The Rest Service (RestService.cs)

The RestService handles the HTTP calls, including attaching the Bearer Token to the request headers when fetching protected data.

Here’s the relevant part of the Rest service.

using System.Text;
using System.Text.Json;
using System.Text.Json.Serialization;
namespace Mauitemp
{
    public class RestService
    {
        private static readonly HttpClient _client = new HttpClient();
        private static readonly JsonSerializerOptions _serializerOptions = new JsonSerializerOptions
        {
            PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
            WriteIndented = true
        };
        // Used for Bearer Auth
        public static async Task<(int ResultValue, string ResponseContent)> HTTPCall2(string url, string method, object data, bool Auth)
        {
            // For Bearer Token Auth
            HttpResponseMessage response;
            string responseContent = string.Empty;
            if (Auth)
            {
                BModel UserProfile = BModel.GetInstance;
                string AuthToken = UserProfile.accessToken;
                _client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", AuthToken);
            }
            try
            {
                if (method.ToUpper() == "GET")
                {
                    response = await _client.GetAsync(url);
                }
                else if (method.ToUpper() == "POST")
                {
                    var jsonData = JsonSerializer.Serialize(data, _serializerOptions);
                    var content = new StringContent(jsonData, Encoding.UTF8, "application/json");
                    response = await _client.PostAsync(url, content);
                }
                else
                {
                    throw new ArgumentException("HTTP method not supported. Use 'GET' or 'POST'.");
                }
                responseContent = await response.Content.ReadAsStringAsync();
                return ((int)response.StatusCode, responseContent);
            }
            catch (Exception ex)
            {
                Debug.WriteLine($"\tERROR: {ex.Message}");
                return (-1, $"Error: {ex.Message}");
            }
        }
    }
}

Bearer token authentication

Summary

This blog demonstrated how to use Bearer Token authentication in a .NET MAUI application. We covered how to.

  1. Build a UI for user login.
  2. Handle authentication and API requests.
  3. Use a Bearer Token to access protected resources.

By following these steps, you can securely authenticate users and retrieve data in your .NET MAUI applications.

For better clarity, feel free to download the attached sample project and check out the snapshots provided.

Next Recommended Reading Shell vs. NavigationPage in .NET MAUI