Blazor WASM - AzureAD Auth - HttpContext.User.Claims are Empty? - azure-active-directory

I am trying to switchover to Azure AD for my identity platform on a Blazor WASM app I am building. I have followed this documentation from Microsoft incredibly closely.
When I log in to the app, the client app is able to display the logged in user's name, which comes from the AuthenticationState object.
However, on the server side, when I sent a an HTTP request (POSTing a comment for example), the HttpContext.User.Claims are empty, and the following line I was using previously to get the userId returns null:
comment.UserId = HttpContext.User.FindFirstValue(ClaimTypes.NameIdentifier);
I plead some ignorance on Claims/Identitys/Microsoft Graph etc., but I still don't know understand why the user / claims would be unknown given this information was accessible at least at one point since the Client App was able to display the user's name...
I've also looked at the following StackOverflow/GitHub posts, but have not found anything that has solved this issue:
Blazor with AzureAD Auth, Context.Identity.User.Name is null
Out of box AAD B2C not grabbing user.identity.name
User.Identity.Name empty when implementing Azure B2C in Blazor WebAssembly
What am I missing here to be able to identify the user on the incoming HTTP requests?
FWIW, here is my Startup.cs class (with some irrelevant code emitted):
public void ConfigureServices(IServiceCollection services)
{
#region Azure Active Directory
services.AddAuthentication(AzureADDefaults.BearerAuthenticationScheme)
.AddAzureADBearer(options => {
Configuration.Bind("AzureAd", options);
}
);
#endregion
services.Configure<JwtBearerOptions>(
AzureADDefaults.JwtBearerAuthenticationScheme, options =>
{
options.TokenValidationParameters.NameClaimType = "name";
//options.TokenValidationParameters.NameClaimType = "preferred_username";
});
services.AddHttpContextAccessor();
services.AddControllersWithViews().AddNewtonsoftJson(x => x.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore);
services.AddRazorPages();
}
And Configure():
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.UseHttpsRedirection();
app.UseBlazorFrameworkFiles();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapRazorPages();
endpoints.MapControllers();
endpoints.MapFallbackToFile("index.html");
});
}

The issue was that removing/not having the "api://" scheme prepended to the client ID caused this to not populate the claims for some reason. Very odd. .

Related

Authorization on a Blazor Server app using Microsoft Identity (Azure AD Authentication) doesn't work

Forgive me if this is an obvious question with an easy answer but for the life of me I cannot get my app to behave the way I want.
When I normally use MS Identity in my Blazor apps I can create roles and policies which all come from a SQL database. For this B2B app I need to use Azure AD and the groups within there to authenticate and authorize access.
At the moment the whole app is secured because the default policy is being applied to all parts of the site but I would like to use [Authorize(Policy = "ViewCustomer")] for example to ensure users have the right permission to view a particular part.
I am sure that this part of my program.cs is missing policies and is part of the problem:
builder.Services.AddAuthorization(options =>
{
options.FallbackPolicy = options.DefaultPolicy;
});
Trouble is I don't have a clue how to create these so they refer to groups (or similar) in the Azure AD tenant. My complete program.cs is:
using DevExpress.Blazor;
using DataModel.Models;
using Microsoft.EntityFrameworkCore;
using BlazorUI.Hubs;
using BlazorUI.Services;
using Xero.NetStandard.OAuth2.Config;
using BlazorUI.Services.Interfaces;
using DataModel.Xero.Interface;
using DataModel.DickerData.Interfaces;
using DataModel.DickerData;
using DataModel.Xero;
using Microsoft.Identity.Web;
using Microsoft.Identity.Web.UI;
using Microsoft.AspNetCore.Authentication.OpenIdConnect;
var builder = WebApplication.CreateBuilder(args);
var initialScopes = builder.Configuration["DownstreamApi:Scopes"]?.Split(' ') ?? builder.Configuration["MicrosoftGraph:Scopes"]?.Split(' ');
builder.Services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApp(builder.Configuration.GetSection("AzureAd"))
.EnableTokenAcquisitionToCallDownstreamApi(initialScopes)
.AddMicrosoftGraph(builder.Configuration.GetSection("MicrosoftGraph"))
.AddInMemoryTokenCaches();
builder.Services.AddControllersWithViews()
.AddMicrosoftIdentityUI();
builder.Services.AddAuthorization(options =>
{
options.FallbackPolicy = options.DefaultPolicy;
});
// Add services to the container.
builder.Services.AddRazorPages();
builder.Services.AddServerSideBlazor()
.AddMicrosoftIdentityConsentHandler();
builder.Services.AddScoped<ISettingService, SettingService>();
builder.Services.AddScoped<IXeroService, XeroService>();
builder.Services.AddScoped<IDickerDataService, DickerDataService>();
//XERO SETTINGS
builder.Services.Configure<XeroConfiguration>(builder.Configuration.GetSection("XeroConfiguration"));
//DICKER DATA SETTINGS
builder.Services.Configure<DickerConfig>(builder.Configuration.GetSection("DickerDataConfiguration"));
//DEVEXPRESS
builder.Services.AddDevExpressBlazor(configure => configure.BootstrapVersion = BootstrapVersion.v5);
//ENTITY FRAMEWORK
builder.Services.AddDbContextFactory<ApplicationDBContext>(options =>
{
options.UseSqlServer(builder.Configuration.GetConnectionString("DBConnection"));
options.EnableSensitiveDataLogging();
});
var app = builder.Build();
//DEVEXPRESS
builder.WebHost.UseWebRoot("wwwroot");
builder.WebHost.UseStaticWebAssets();
// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/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();
app.UseAuthorization();
app.MapControllers();
app.MapBlazorHub();
app.MapFallbackToPage("/_Host");
//REGISTER SIGNAL R HUBS
app.MapHub<MessageHub>(MessageHub.PATHTOHUB);
app.Run();
Thank you so much to anyone that may be able to enlighten me.
You can add app roles to your application, assign them to selected users and obtain them as claims so they can be used in tandem with your AuthorizeAttribute.
Alternatively, you can further customize or augment the authorization criteria using Claim Based Authorization in tandem with your policy.

Microsoft.Identity.Web OpenIdConnect was not authenticated. Failure message: Not authenticated

My app had been working with Microsoft.Identity for the past couple of years and something changed that is causing users to have to clear cache to authenticate. I have verified reply url's, the tenant id, client id and client secret and they all have not changed and are correctly setup. I updated to the latest nuget package. And after clearing browser cache the authentication works perfectly. What could be causing this?
public void ConfigureServices(IServiceCollection services)
{
services.Configure<CookiePolicyOptions>(options =>
{
options.CheckConsentNeeded = context => false;
options.MinimumSameSitePolicy = SameSiteMode.Unspecified;
options.HandleSameSiteCookieCompatibility();
});
services.AddMicrosoftIdentityWebAppAuthentication(Configuration, "AzureAd");
//services.AddSignIn(Configuration);
// Token acquisition service based on MSAL.NET
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseCookiePolicy();
app.UseRouting();
app.UseCors(MyAllowSpecificOrigins);
app.UseAuthentication();
app.UseSession();
app.UseMiddleware<UserClaims>();
app.UseAuthorization();
Microsoft.AspNetCore.Hosting.Diagnostics: Information: Request starting HTTP/2.0 POST https://localhost:44326/signin-oidc application/x-www-form-urlencoded 3217
Microsoft.AspNetCore.Cors.Infrastructure.CorsService: Information: CORS policy execution successful.
Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationHandler: Information: AuthenticationScheme: Cookies signed in.
Microsoft.AspNetCore.Hosting.Diagnostics: Information: Request finished in 626.0063ms 302
Microsoft.AspNetCore.Hosting.Diagnostics: Information: Request starting HTTP/2.0 GET https://localhost:44326/
Microsoft.AspNetCore.Authentication.OpenIdConnect.OpenIdConnectHandler: Information: OpenIdConnect was not authenticated. Failure message: Not authenticated
Microsoft.AspNetCore.Authorization.DefaultAuthorizationService: Information: Authorization failed.
Microsoft.AspNetCore.Authentication.OpenIdConnect.OpenIdConnectHandler: Information: AuthenticationScheme: OpenIdConnect was challenged.
Microsoft.AspNetCore.Hosting.Diagnostics: Information: Request finished in 225.1113ms 302
Please make sure to add authentication middleware in order that app.UseAuthentication(); comes before app.UseMvc();
app.UseAuthentication();
app.UseAuthorization();
Note that AddMicrosoftIdentityWebApp is using its own cookie (auth) provider
instead using the existing one (maybe After being upgraded).
Try using by making cookiescheme to null
services.AddAuthentication() .AddMicrosoftIdentityWebApp(Configuration,"AzureAd", "AzureAD", cookieScheme: null);
or
try to explicity add the schemes so that scheme is able to handles exceptions of challenge errors like 401.
For that you may need to call AddAuthentication() and configure a default challenge schemes something like this.
services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApp(Configuration.GetSection("AzureAd"))
NOTE: AddAuthentication() method actually configures the service to add cookie-based authentication.This cookie used in browser scenarios and also to set the challenge to OpenID Connect.
and register Microsoft Identity routes with one call minumum to endpoints.MapControllerRoute() or a call to endpoints.MapControllers().
or
services.Configure<CookiePolicyOptions>(options =>
{
options.CheckConsentNeeded = context => true;
options.MinimumSameSitePolicy = SameSiteMode.None;
});
services.AddAuthentication(AzureADDefaults.AuthenticationScheme)
.AddAzureAD(options => Configuration.Bind("AzureAd", options));
services.Configure<OpenIdConnectOptions>(AzureADDefaults.OpenIdScheme, options =>
{
options.Authority = options.Authority + "/v2.0/";
options.TokenValidationParameters.ValidateIssuer = false;
});
Please check microsoft-identity-web issues in github
References:
aspnetcore-webapp-openidconnect-v2 (github.com)
asp.net mvc - IdentityServer4 - Stack Overflow
Stack Overflow reference

Blazor Client side get CORS error when accessing Azure Function using Azure Active directory

I've been trying to deploy my Blazor PWA for 2 days without any success so far, if someone has an idea of what I’m doing wrong I would be really grateful.
hello
I could resolve most of my issues by myself but I'm now stuck on a CORS problem using AAD.
Here's my project setup:
Blazor webassembly client hosted on Static Website Storage (works
great), Net 5
AzureFunctions connected to an Azure Sql Server database (works great
with anonymous authentication in Blazor)
Azure Active Directory I want to use to authenticate the users.
(protecting both the blazor app and the functions)
So I’ve created an App registration, added my static web site address as SPA uri and uncheck both implicit.
In my blazor client, program.cs, I’ve added the following code to connect to AAD:
builder.Services.AddMsalAuthentication(options =>
{
builder.Configuration.Bind("AzureAd", options.ProviderOptions.Authentication); //contains clientId, Authority
options.ProviderOptions.DefaultAccessTokenScopes.Add("https://graph.microsoft.com/User.Read");
options.ProviderOptions.LoginMode = "redirect";
});
That works great too, I can login, authorize view works as expected.
The problem is when I try to authenticate Azure functions with «Login with Azure Active Directory»,
I' tried with both express and advanced configurations (using clientId, tenantId) but when I
Access to fetch at 'https://login.windows.net/tenantid/oauth2/authorize ... (redirected from 'https://myfunctionstorage.azurewebsites.net/api/client/list') from origin 'https://*****9.web.core.windows.net' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
I have of course enabled CORS for my Blazor Client Address on Azure Functions configuration but the problem seems to be about the login windows uri...
Also, if I enable the token id implicit flow in the App registration and access the login url in the browser it works perfectly fine.
All the examples I could find so far are about msal 1.0 and App registration using implicit flow instead of SPA so it doesn't help...
Thank you for your time and your help.
UPDATE:
I’ve done more researches since yesterday and I think it could by related to my HTTPClient, currently I use the basic one (with just a base adress).
But I’ve seen on some example that when using the Client using AAD it needs more parameters, for example:
builder.Services.AddHttpClient("companiesAPI", cl => { cl.BaseAddress = new Uri("https://localhost:5001/api/"); }) .AddHttpMessageHandler(sp => { var handler = sp.GetService<AuthorizationMessageHandler>() .ConfigureHandler( authorizedUrls: new[] { "https://localhost:5001" }, scopes: new[] { "companyApi" } ); return handler; });
Is that AuthorizationMessageHandler needed ?
Also I see some references to the need of using the «use_impersonation» scope.
Are those changes (on HttpClient and the use_impersonation scope) also required when using msal2/SPA app registration ?
Thank you
If want to call the Azure function projected by Azure AD in Blazor webassembly client, please refer to the following steps
If you want to call Azure function projected by Azure AD in angular application, please refer to the following code
Create Azure AD application to protect function
Register Azure AD application. After doing that, please copy Application (client) ID and the Directory (tenant) ID
Configure Redirect URI. Select Web and type <app-url>/.auth/login/aad/callback.
Enable Implicit grant flow
Define API scope and copy it
Create client secret.
Enable Azure Active Directory in your App Service app
Configure CORS policy in Azure Function
Create Client AD application to access function
Register application
Enable Implicit grant flow
configure API permissions. Let your client application have permissions to access function
Code
Create Custom AuthorizationMessageHandler class
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.WebAssembly.Authentication;
public class CustomAuthorizationMessageHandler : AuthorizationMessageHandler
{
public CustomAuthorizationMessageHandler(IAccessTokenProvider provider,
NavigationManager navigationManager)
: base(provider, navigationManager)
{
ConfigureHandler(
authorizedUrls: new[] { "<your function app url>" },
scopes: new[] { "<the function app API scope your define>" });
}
}
Add the following code in Program.cs.
public static async Task Main(string[] args)
{
var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.RootComponents.Add<App>("app");
// register CustomAuthorizationMessageHandler
builder.Services.AddScoped<CustomAuthorizationMessageHandler>();
// configure httpclient
// call the following code please add packageMicrosoft.Extensions.Http 3.1.0
builder.Services.AddHttpClient("ServerAPI", client =>
client.BaseAddress = new Uri("<your function app url>"))
.AddHttpMessageHandler<CustomAuthorizationMessageHandler>();
// register the httpclient
builder.Services.AddScoped(sp => sp.GetRequiredService<IHttpClientFactory>()
.CreateClient("ServerAPI"));
// configure Azure AD auth
builder.Services.AddMsalAuthentication(options =>
{
builder.Configuration.Bind("AzureAd", options.ProviderOptions.Authentication);
options.ProviderOptions.DefaultAccessTokenScopes.Add("<the function app API scope your define>");
});
await builder.Build().RunAsync();
}
Call the API
#page "/fetchdata"
#using Microsoft.AspNetCore.Components.WebAssembly.Authentication
#inject HttpClient Http
<h1>Call Azure Function</h1>
<p>This component demonstrates fetching data from the server.</p>
<p>Result: #forecasts</p>
<button class="btn btn-primary" #onclick="CallFun">Call Function</button>
#code {
private string forecasts;
protected async Task CallFun()
{
forecasts = await Http.GetStringAsync("api/http");
}
}

Using Active Directory B2C to secure a Blazor WASM app and Web API

I have a scenario where I have a Blazor WASM (client only) app that is secured via AD B2C. As per the documentation I have read, I have registered an application in AD B2C (e.g. BlazorApp) and wired the Blazor app to this instance. This Blazor app makes API calls to a .NET Core Web API where the endpoints are secured (using the [Authorize] attributes). As per the documentation I have read, I have also registered the Web API in AD B2C (e.g. WebApi) and wired the API to connect to this instance.
The problem I have is that when I authenticate in the Blazor app, and then pass the access/id token through the API calls, the Web API can't authenticate that token (unauthorized error response). It works when I wire the Web API to connect to the BlazorApp registration (I'm guessing because that is where the token was issued from). But this seems to go against the recommendation of registering each app/api in AD as a separate registration.
How can I get the WebApi registration to recognise a token issued by BlazorApp? Am I going about this wrong and should I just wire the Web API to talk to the BlazorApp instance?
Additional Information:
Blazor WASM (client) - Program.cs
(sensitive information removed)
public static async Task Main(string[] args)
{
var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.RootComponents.Add<App>("app");
...
builder.Services.AddMsalAuthentication(options =>
{
builder.Configuration.Bind("AzureAdB2C", options.ProviderOptions.Authentication);
options.ProviderOptions.DefaultAccessTokenScopes.Add(#"https://<tenant name>.onmicrosoft.com/blazorapp/app.read");
options.ProviderOptions.DefaultAccessTokenScopes.Add(#"https://<tenant name>.onmicrosoft.com/blazorapp/app.write");
});
...
await builder.Build().RunAsync();
}
Blazor WASM (client) - appsettings.json
(sensitive information removed)
{
"AzureAdB2C": {
"Authority": "https://<tenant name>.b2clogin.com/<tenant name>.onmicrosoft.com/B2C_1_SignUpSignIn",
"ClientId": "<BlazorApp Application ID>",
"ValidateAuthority": false
}
}
Web API (.NET Core 3.1) - StartUp.cs
(sensitive information removed)
public void ConfigureServices(IServiceCollection services)
{
...
services.AddAuthentication(AzureADB2CDefaults.BearerAuthenticationScheme)
.AddAzureADB2CBearer(options => Configuration.Bind("AzureAdB2C", options));
services.AddControllers();
...
}
Web API (.NET Core 3.1) - appsettings.json
(sensitive information removed)
NOTE: Authentication works when I replace the WebApi Application ID with the BlazorApp Application ID
{
"AzureAdB2C": {
"Instance": "https://<tenant name>.b2clogin.com/tfp/",
"ClientId": "<WebAPI Application ID>",
"Domain": "<tenant name>.onmicrosoft.com",
"SignUpSignInPolicyId": "B2C_1_SignUpSignIn"
},
...
}
Your project is not using OBO flow, OBO flow requires three applications, specifically one client-side and two api-side, see here.
Back to the problem, first of all your problem is misconfigured scope, as the api-side app needs to expose its own api, the API permission on your blazor app side gets access to the api-side, so the access to the scope is configured on the api-side, so we need to put https://<tenant name>.onmicrosoft.com/webapiapp/app.read on the scope, your blazor app is only used to configure access.
It works because you use blazor app to request the blazor app's own api, which is feasible, although a little strange, to request yourself.
So for your project, the correct request should be like this.
public static async Task Main(string[] args)
{
var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.RootComponents.Add<App>("app");
...
builder.Services.AddMsalAuthentication(options =>
{
builder.Configuration.Bind("AzureAdB2C", options.ProviderOptions.Authentication);
options.ProviderOptions.DefaultAccessTokenScopes.Add(#"https://<tenant name>.onmicrosoft.com/webapiapp/app.read");
options.ProviderOptions.DefaultAccessTokenScopes.Add(#"https://<tenant name>.onmicrosoft.com/webapiapp/app.write");
});
...
await builder.Build().RunAsync();
}
{
"AzureAdB2C": {
"Instance": "https://<tenant name>.b2clogin.com/tfp/",
"ClientId": "<Application ID>",
"Domain": "<tenant name>.onmicrosoft.com",
"SignUpSignInPolicyId": "B2C_1_SignUpSignIn"
},
...
}

Ocelot Integration with Azure Active Directory Authentication .Net Core 3.1

Context: My company is moving to an API Gateway to manage all our or services in our network. Each service is currently authenticated using azure AD. Everything is single tenant and just allows company users.
Question: Am I understanding this correctly?
Problem: When I call http:localhost:5000/authResource/get I get a 401 response back from Ocelot. After tracing through the error, I see that I get null back when the Ocelot Authentication middle ware attempts to authenticate using the AzureADJwtBearer scheme.
I followed the advice from questions related to Ocelot and azure ad but even following that I am unable to get anything to work. (Mostly from this answer: How set up Ocelot Api Gateway with Azure Active Directory)
I think I may be misunderstanding how the authentication is supposed to work. My current understanding is that I tell Ocelot to authenticate against one of my Apis using the AzureADJwtBearer scheme. In my configuration I have the information for that specific api set up (ClientId, TenantId, etc).
Once I call the route, I am expecting Ocelot to make a call to Microsoft to start authentication. At this point, I expect the same flow as the Apis provide, i.e. I make the call and get the Microsoft login page which then redirects me back to the application once I enter my username and password.
After redirecting me back to Ocelot I guess (this is the part I am fuzzy on), I expect ocelot to store the access token Microsoft sends back FOR THE SPECIFIC RESOURCE I JUST REQUESTED. Then I expect ocelot to attach the token to an Auth header and then send the request for the resource I initially asked for.
To clarify this, I will include the code I have for my startup files, and my ocelot.json file.
From Startup.cs
public void ConfigureServices(IServiceCollection services)
{
services.AddProtectedWebApi(Configuration)
.AddProtectedApiCallsWebApis(Configuration)
.AddInMemoryTokenCaches();
services.AddOcelot(Configuration);
services.AddControllers();
}
Also from Startup.cs
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseHttpsRedirection();
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
app.UseOcelot().Wait();
app.UseAuthentication();
}
My ocelot.json file for the authenticated resource is as follows (names changed for security reasons):
{
"DownstreamPathTemplate": "/api/Controller/Get",
"DownstreamScheme": "http",
"DownstreamHostAndPorts": [
{
"Host": "localhost",
"Port": 5003
}
],
"UpstreamPathTemplate": "/authResource/get",
"UpstreamHttpMethod": [ "GET" ],
"AuthenticationOptions": {
"AuthenticationProviderKey": "AzureADJwtBearer",
"AllowedScopes": []
}
}
To solidify how I understand this, I will go through an example using the sample api shown in the ocelot configuration.
I wish to access resource http://localhost:5003/api/Controller/Get which is a protected API meaning I can only get a response from this if I provide an authorization header with my get request.
I make a request through my ocelot gateway for the url http://localhost:5000/authResource/get (I am hosting Ocelot on localhost:5000).
Ocelot sees it needs to authenticate to access this resource, so it makes a request using the AzureADJwtBearer scheme.
I am redirected to microsoft to login. Once done, I am sent back to the Ocelot application with an access token in tow.
Ocelot takes this taken, creates the Auth header, and finally calls http://localhost:5003/api/Controller/Get and returns the result.
Working Example for .Net Core 3.1
I ended up getting this working using the Microsoft.Identity.Web library (current version located at https://github.com/AzureAD/microsoft-identity-web/tree/master/src/Microsoft.Identity.Web)
First up, my ocelot configuration file (ocelot.json):
{
"ReRoutes": [
{
"DownstreamPathTemplate": "/myapp/api/{everything}",
"DownstreamScheme": "https",
"DownstreamHostAndPorts": [
{
"Host": "apphost.com",
"Port": 443
}
],
"UpstreamPathTemplate": "/api/{everything}",
"UpstreamHttpMethod": [ "GET", "POST" ],
"AuthenticationOptions": {
"AuthenticationProviderKey": "Bearer",
"AllowedScopes": []
}
}
]
}
Notice the AuthenticationProviderKey has the value Bearer.
My appsettings.json file contains my azure configurations:
"AzureAd": {
"Instance": "https://login.microsoftonline.com/",
"Domain": "mydomain.com",
"TenantId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"ClientId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
}
Then finally, my Startup.cs file contains something like this (reduced for brevity)
public void ConfigureServices(IServiceCollection services)
{
services.AddProtectedWebApi(Configuration)
.AddProtectedApiCallsWebApis(Configuration)
.AddInMemoryTokenCaches();
services.AddOcelot(Configuration);
services.AddControllers();
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
IdentityModelEventSource.ShowPII = true;
}
app.UseHttpsRedirection();
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
app.UseOcelot().Wait();
app.UseAuthentication();
}
With this all set up, I can pass in a bearer token generated using my azure credentials, and the ocelot gateway will correctly validate it.

Resources