issue with api, unauthorised

Abdul Baba Syed 21 Reputation points
2024-12-14T07:56:42.24+00:00

I have this simple Webapi, which is published as APP service

[Route("api/[controller]")]

[ApiController]

public class DateTimeController : Controller

{

 [Authorize]

 [HttpGet]

     public IActionResult GetCurrentDateTime()

     {

         return Ok(new { CurrentDateTime = DateTime.UtcNow });

     }

 

}

==========================
I have below code in the mvc controller calling the above api (deployed in azure app services)

using System.Diagnostics;

using Microsoft.AspNetCore.Mvc;

using System.Net.Http.Headers;

using System.Net.Http;

using webapp14122024.Models;

using Microsoft.AspNetCore.Authorization;

namespace webapp14122024.Controllers

{

public class HomeController : Controller

{

    private readonly ILogger<HomeController> _logger;

    private readonly IHttpClientFactory _httpClientFactory;

    private readonly IHttpContextAccessor _httpContextAccessor;

    public HomeController(IHttpClientFactory httpClientFactory, IHttpContextAccessor httpContextAccessor)

    {

        _httpClientFactory = httpClientFactory;

        _httpContextAccessor = httpContextAccessor;

    }



    public async Task<IActionResult> Index()

    {

        string accessToken = _httpContextAccessor.HttpContext.Request.Headers["X-MS-TOKEN-AAD-ACCESS-TOKEN"];

        if (string.IsNullOrEmpty(accessToken))

        {

            return Unauthorized("Access token not found.");

        }

        var client = _httpClientFactory.CreateClient();

        client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);

        string apiUrl = "https://xxxxxxxxxxxxxxxx01.azurewebsites.net/api/datetime";

        try

        {

            var response = await client.GetAsync(apiUrl);

            if (response.IsSuccessStatusCode)

            {

                var result = await response.Content.ReadAsStringAsync();

                ViewBag.DateTimeResult = result;

            }

            else

            {

                ViewBag.DateTimeResult = $"Error: {response.StatusCode} - {response.ReasonPhrase}";

            }

        }

        catch (Exception ex)

        {

            ViewBag.DateTimeResult = $"Exception: {ex.Message}";

        }

        return View();

    }

 and index.cshtml

h2>Current Date and Time from API</h2>

<div>

@if (ViewBag.DateTimeResult != null)

{

    <p>@ViewBag.DateTimeResult</p>

}

else

{

    <p>No data received.</p>

}

</div>

===================================================program.cs
using Microsoft.AspNetCore.Authentication;

using Microsoft.AspNetCore.Authentication.AzureAD.UI;

using Microsoft.AspNetCore.Authentication.JwtBearer;

using Microsoft.Extensions.DependencyInjection;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddHttpClient();

builder.Services.AddHttpContextAccessor();

// Add services to the container.

builder.Services.AddControllersWithViews();

// Add Azure AD authentication

// Add authentication services

builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)

.AddJwtBearer(options =>

{

    options.Events = new JwtBearerEvents

    {

        OnMessageReceived = context =>

        {

            // Get the token from the X-MS-TOKEN-AAD-ACCESS-TOKEN header

            var token = context.Request.Headers["X-MS-TOKEN-AAD-ACCESS-TOKEN"].FirstOrDefault();

            if (!string.IsNullOrEmpty(token))

            {

                context.Token = token;

            }

            return Task.CompletedTask;

        }

    };

});

builder.Services.AddAuthorization();

builder.Services.AddControllers();

var app = builder.Build();

// Configure the HTTP request pipeline.

if (!app.Environment.IsDevelopment())

{

app.UseExceptionHandler("/Home/Error");

// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.

app.UseHsts();

}

app.UseHttpsRedirection();

app.UseStaticFiles();

app.UseRouting();

app.UseAuthentication(); // Add this middleware

app.UseAuthorization();

app.MapControllerRoute(

name: "default",

pattern: "{controller=Home}/{action=Index}/{id?}");

app.Run();

once i enter the microsoft logon password i can see this index.cshtml
unfortunately Im getting unauthorized-unauthorized

Microsoft Identity Manager
Microsoft Identity Manager
A family of Microsoft products that manage a user's digital identity using identity synchronization, certificate management, and user provisioning.
730 questions
ASP.NET Core
ASP.NET Core
A set of technologies in the .NET Framework for building web applications and XML web services.
4,706 questions
ASP.NET API
ASP.NET API
ASP.NET: A set of technologies in the .NET Framework for building web applications and XML web services.API: A software intermediary that allows two applications to interact with each other.
355 questions
{count} votes

2 answers

Sort by: Most helpful
  1. Abdul Baba Syed 21 Reputation points
    2024-12-14T15:27:01.4433333+00:00

    Im sorry I have gone through the url earlier,
    intention was to design(webapp/api) using simple easy auth with very minimal configuration in both webapi/webapp, where a web api will be called in the web app.

    Webapp will have authentication to microsoft logon, once logon it uses the same token and grant the authorization to the webapi, it can display the method result. Hope it is clear


  2. Bruce (SqlWork.com) 68,716 Reputation points
    2024-12-20T16:02:48.71+00:00

    I assume you are using azure Entra as the provider. you need to register the api application. then in api app configure api access. this will give you a client id, secret and scope for calling the api.

    for the webapi project use the single org template and configure with the app registration values. this site will use bearer token for authentication.

    for the web app project config azure easy auth with this api site clientid. this site will use cookie authenication, and cache the access token by userid. easy auth will pass the token as header. your sample code looks correct to pass the bearer token to api.

    0 comments No comments

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.