Blazor wasm to public APIs - api

I have a Blazor wasm project (.NET6) that uses internal APIs to communicate with the client application. The project uses IdentityServer4 to authenticate users and most APIs require authorization before being granted access.
My question is how can I move those internal APIs to public APIs? What changes do I need to make in the authentication system so APIs can be accessed? How should I move the APIs to being public? Do I need to create separate API users as opposed to app users right now?

Add access tokens to the requests being sent from your Blazor wasm app. It's fairly involved, but here's a good resource.
Configure the API to accept access tokens (from this guide).
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.UseStaticFiles();
app.UseRouting();
app.UseIdentityServer();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapDefaultControllerRoute();
});
}

Related

How to implement Windows Authentication in a .Net Core API Gateway using Ocelot so that all downstream services can access IWindowsPrincipal?

Background
I have two microservices that require access to IWindowsPrincipal of the calling user.
I am writing an API Gateway using .Net Core 3.1 that will act as a reverse proxy for these services.
I have configured Authentication and Authorization in the API Gateway as follows:
public void ConfigureServices(IServiceCollection services)
{
services.AddCors(options =>
{
options.AddPolicy("All allowed",
builder =>
{
builder
.AllowAnyOrigin()
.AllowAnyMethod()
.AllowAnyHeader();
});
});
services.AddAuthentication(NegotiateDefaults.AuthenticationScheme)
.AddNegotiate();
services.AddAuthorization();
services.AddControllers();
services.AddHttpForwarder();
services.AddOcelot();
services.AddSwaggerForOcelot(_configuration);
}
public void Configure(IApplicationBuilder app)
{
app.UseCors("All allowed");
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
app.UseSwaggerForOcelotUI(options =>
{
options.PathToSwaggerGenerator = "/swagger/docs";
});
app.UseOcelot();
}
Requirement
I would like to access the calling user's identity using HttpContext.User.Identity
in the method of the microservices.
Actual Result
In the methods of the microservices, HttpContext.User.Identity.IsAuthenticated is false and the identity information is empty.
Question
Is there a way to configure Ocelot in the gateway so that it will Challenge the caller if necessary receive Windows Authentication information and pass it on to the microservices?
If this is not possible, is the recommend way to achieve my goal, to perform implement Windows Authentication in each of the microservices?
Isn't Ocelot supposed to allow me to handle Authentication in one place for all microservices?
Follow on Question 1
Ocelot's documentation refers to Authentication using a JWT.
Should I conclude that Ocelot only provides JWT configuration?
Follow on Question 2
I have read a little about Yarp (https://microsoft.github.io/reverse-proxy/)
Should I be using Yarp instead of Ocelot to achieve my goal?
I thought the answer is No
Is there a way to configure Ocelot in the gateway so that it will Challenge the caller if necessary receive Windows Authentication information and pass it on to the microservices?
The problem is Windows Authentication is stateful, server and client are in the same Active Directory , you can find the note in .NET Core Windows Authentication
Windows Authentication is a stateful scenario primarily used in an intranet, where a proxy or load balancer doesn't usually handle traffic between clients and servers.
Microservices architecture requires a stateless instead stateful (means the server and client are in different AD/OS/Network). And Gateway is a stateless component in Microservices picture.
The only way Ocelot can authenticate Windows User is using Active Directory Federated Services (ADFS) with OpenID Connect (OIDC) or constructing Identity Server in the IIS Server by yourself. You can read the scenario in ADFS or Azure AD for more details.
Beside, there are my answers for two following questions:
No, Ocelot just provides the add-in feature to detect which claims of JWT must be included before it allows the request to go through downstream. You can build the custom Authentication/Authorization middleware to allow/deny the correct upstream.
No, YARP is the same meaning of Ocelot in your requirement.

Windows Authentication using Blazor with .Net Core WebApi

I have the task to develop a Blazor Webassembly App. This app is only used within the companys network and for security reasons we would like to use the existing AD and NTLM Authentication.
So far I have a minimal Blazor App configured and running in IIS. Its configured to use Windows Authentication and that works so far. When I open the app in Browser I get asked for my credentials.
The app should also communicate with a .net core webapi which is also secured by windows authentication. This webapi security too works as it should. When I open an URL to it in Browser I get asked for my credentials and the page loads as it should.
Now the Problem: When I call the same url (that works in Browser) from my Blazor app with HttpClient.GetAsync I get an "401: Not Authorized" error. Even though the app itself is loaded with the same authentication. Is there something I have to do?
The MSDN Documenations a gigantic and I couldnt find a Solution.
In the WebApi Startup.cs in ConfigureServices() I added
services.AddAuthentication(IISDefaults.AuthenticationScheme);
services.AddAuthorization();
and in Configure()
app.UseCors(x => x.AllowAnyMethod().AllowAnyHeader().SetIsOriginAllowed(origin => true).AllowCredentials());
app.UseAuthentication();
app.UseAuthorization();
PS:
The Blazor App uses .NET Core 3.1
The WebApi uese .NET 5.0
I recommend checking Blazor WebAssembly additional security scenarios (all the examples are there)
To authorize your request, you can use HttpClient with BaseAddressAuthorizationMessageHandler:
builder.Services.AddHttpClient("ServerAPI",
client => client.BaseAddress = new Uri("https://www.example.com/base"))
.AddHttpMessageHandler<BaseAddressAuthorizationMessageHandler>();
BaseAddressAuthorizationMessageHandler will automatically add Authorize header to all outgoing requests.
Note: This works only with Blazor Wasm, not Server.

Authorization on .NET Core 2.1 Web API built on .NET Framework problem

I am trying to get the [Authroize] tag working on .NET Core 2.1 Web API project built on .NET Framework. There is no IAppBuilder.UseAuthorization(). I wrote my own JWT custom auth handler and tried the following in the Startup:
services.AddAuthentication("Basic")
.AddScheme<BasicAuthenticationOptions, EdcAuthenticationHandler>("Basic", null);
services.AddAuthorization();
I also have
app.UseAuthentication();
but, again, there is no app.UseAuthorization()
I want to be able to add [Authorize] attributes (with roles as well) and be able to access the User object inside my controller methods.
Any insight would be appreciated.
Turns out it was simple. I needed the authorization tag like this:
[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
And
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddScheme<BasicAuthenticationOptions, EdcAuthenticationHandler>(JwtBearerDefaults.AuthenticationScheme, null);
There was no need for:
app.UseAuthorization();
Sorry for the trouble. Just couldn't figure out that I needed the scheme name in the authorize tag.

Basic auth for healthchecks in asp.net core

I have an ASP.NET Core 3.1 API which already uses OAuth for authorization. I added healthchecks middleware and I would like to make it protected with basic auth so that client which check the health status can simply provide credentials to check the service health.
So far I did not manage to configure it for the healthcheck endpoint.
Any clue how this can be added?
You can use RequireAuthorization method. For example:
app.UseEndpoints(endpoints =>
{
endpoints.MapHealthChecks("/health").RequireAuthorization();
});

aspnetcore is skipping authentication middle ware

I am currently using 3 middleware in my .netcore api application.
app.UseAuthentication();
app.UseMultiTenancy();
app.UseMvc();
From my understanding each middleware is run based on the sequence they are added to the pipeline.
For some reasons, the UseMultiTenancy is run before UseAuthentication.
Note, all my API controllers are marked with authorize attributes.
I would expect the authentication middleware to check whether the user has been authentication and then call the UseMultiTenancy .
Is this correct understanding? If not, is there a way to run UseMultiTenancy after authentication?