Click here to Skip to main content
15,881,173 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
Alright, this is difficult to explain (especially since I don't fully understand what I'm doing myself), but here it goes...

I've got an ASP.NET Core 3.1 web application, the client, and a .NET Framework Web API, the service.
Both run in an Azure Web App.
Calling the service from the client is easy enough, but now I have to secure the service using Open ID Connect (if I'm not mistaken) and Azure AD so that not just anybody can access it.
I've got this to work for another .NET Core Web API, but I can't seem to figure out how to make this work for .NET Framework.

Let's go over the steps in Azure AD first.
I've created two app registrations, one for the client and one for the service.
I've given the service an Application ID URI and an app role, AccessAsApplication.
For the client, I've added a secret and added the AccessAsApplication app role to the API permissions and granted admin consent.

Then, in the .NET Core Web API, I can secure this using some Azure AD configuration and two lines in the Startup ConfigureServices and Configure methods:
C#
public void ConfigureServices(IServiceCollection services)
{
    services.AddMicrosoftIdentityWebApiAuthentication(Configuration);
    // ...
}

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    // ...
    app.UseAuthentication();
    app.UseAuthorization();
    // ...
}
I can then use the AuthorizeAttribute on my Controllers.
This is the behavior I'm trying to get for my .NET Framework Web API, but I can't seem to figure it out.

Using this setup should allow me to connect to either an ASP.NET Core Web API or an .NET Frameework Web API from an ASP.NET Core Web App using MSAL.
More specifically (client code):
C#
var app = ConfidentialClientApplicationBuilder.CreateWithApplicationOptions(options).Build();
var scopes = new[] { $"{applicationIdUri}/.default" };
var tokenbuilder = app.AcquireTokenForClient(scopes);
var tokenResult = await tokenbuilder.ExecuteAsync();

var httpClient = httpClientFactory.CreateClient();
var defaultRequetHeaders = httpClient.DefaultRequestHeaders;
if (defaultRequetHeaders.Accept == null || !defaultRequetHeaders.Accept.Any(m => m.MediaType == "application/json"))
{
    httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
}
defaultRequetHeaders.Authorization = new AuthenticationHeaderValue("Bearer", tokenResult.AccessToken);

// Use httpClient as you would normally...
Again, this works for the client to a .NET Core service, but not to my .NET Framework service.
Rewriting the .NET Framework service to .NET Core is not an option.

So my question is, what do I need to do to get my ASP.NET Web API behave the same as the ASP.NET Core Web API?

What I have tried:

I've got this Owin stuff in my .NET Framework Web API.
C#
public partial class Startup
{
    public void Configuration(IAppBuilder app)
    {
        ConfigureAuth(app);
    }
}

public partial class Startup
{
	public void ConfigureAuth(IAppBuilder app)
	{
		app.UseWindowsAzureActiveDirectoryBearerAuthentication(
			new WindowsAzureActiveDirectoryBearerAuthenticationOptions
			{
				Tenant = ConfigurationManager.AppSettings["ida:Tenant"],
				TokenValidationParameters = new TokenValidationParameters()
				{
					ValidAudience = ConfigurationManager.AppSettings["ida:Audience"]
				}
			});
	}
}
And then in my Web.Config I've got the following values:
HTML
<add key="ida:Audience" value="[The Application ID URI for the service]" />
<add key="ida:ClientID" value="[The client ID for the service]" />
<add key="ida:Tenant" value="[The name of my Azure AD tenant]" />
This is basically what I find in each example on Google and this is also the default example for new projects using "Work or School Account" authentication, but I keep getting a 401 Unauthorized when I use the connection method described above.

I'm not even sure if the error is in my client or service, but I suspect the latter since the specific client code should not matter for the OpenID Connect protocol.
Posted
Updated 25-Nov-20 3:51am
v2

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900