Add authorization to header and access [Authorize] controllers - asp.net-core

I use Jwt token to login with .NET Core API version 3.1.
I saw token generated but it couldn't access [Authorize] controllers, always returns 401. I've found the way to add authorization to the headers. However, there's no detailed instructions to set up and how to use it to access [Authorize] controllers.
Could anyone tell me how to pass header values by using HttpClient and is there any set up else in Startup.cs? Thank you so much for helping me!

Make sure you are adding JWT authentication to your DI pipeline in Startup.cs like this:
public void ConfigureServices(IServiceCollection services)
{
⋮
services.AddAuthentication("Bearer")
.AddJwtBearer("Bearer", options =>
{
options.Audience = "http://localhost:5001/";
options.Authority = "http://localhost:5000/";
});
⋮
}
Authorize with a specific scheme in ASP.NET Core
Overview of ASP.NET Core authentication
Also, make sure you are using the Authorization middleware in Startup.cs like this:
public void Configure(IApplicationBuilder app)
{
⋮
app.UseAuthentication();
app.UseAuthorization();
⋮
}
UPDATE:
Here is how you can setup the HttpClient:
var client = new HttpClient();
string token; // your token
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
ASP.NET Core Middleware

Related

Asp.net Web API .NET Core 3.1 and Azure AD - system.unauthorizedaccessexception: neither scope or roles claim was found in the bearer token

I am trying to secure my Web Api with Azure AD. This application will be accessed by a console app, and the token will be generated from a client id / secret. I followed the quickstart from https://learn.microsoft.com/en-us/azure/active-directory/develop/quickstart-v2-aspnet-core-web-api .
After obtaining a client token and sending through the bearer auth header, I am getting an error
System.UnauthorizedAccessException: IDW10201: Neither scope or roles claim was found in the bearer token.
I'm obtaining an access token with this code:
public static async Task<string> GetAccessToken(string aadInstance, string aadTenant, string aadClientId, string aadClientSecret, string apiResourceId)
{
string authority = aadInstance.TrimEnd('/') + "/" + aadTenant;
var app = ConfidentialClientApplicationBuilder.Create(apiResourceId)
.WithClientId(aadClientId)
.WithClientSecret(aadClientSecret)
.WithAuthority(authority)
.Build();
var tokenrequest = app.AcquireTokenForClient(new string[] { "api://resourceid/.default" });
var tokenresult = await tokenrequest.ExecuteAsync();
return tokenresult.AccessToken;
}
My startup code in the web api looks like this:
public void ConfigureServices(IServiceCollection services)
{
JwtSecurityTokenHandler.DefaultMapInboundClaims = false;
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApi(Configuration);
later in the startup...
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseHttpsRedirection();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
app.UseOpenApi();
app.UseSwaggerUi3();
}
It turns out that the setup in Azure AD was missing a role that needed to be added to the manifest as well as the permissions to the api of the client application, as per step 8 in https://dotnetplaybook.com/secure-a-net-core-api-using-bearer-authentication/
Unfortunately the MS documentation doesn't put this part in the quick start.

How to login a user with a JWT in asp.net core

I have an IdentityServer4 instance.
This IdentityServer4 instance is called by a separate asp.net core web app (from an http post login action) to receive a JWT.
What do I do with this JWT to "login" the a user?
Your client application that wants to authenticate should communicate with the Identity Server application on the Open ID Connect (OIDC) protocol. Asp.net core supports this out of the box with AddAuthentication().AddOpenIdConnect() extension that you can use on the IServiceCollection in your Startup.cs file.
In the Configure method, the call to UseAuthetication is what actually "login" the user (it will add the user claims to the incoming requests). So if you are using for example MVC, make sure to add that line before the call to UseMvc().
The Identity Server documentation even provides a sample of this here: http://docs.identityserver.io/en/latest/quickstarts/3_interactive_login.html#creating-an-mvc-client
A very simple example would look something like this:
public void ConfigureServices(IServiceCollection services)
{
// other configuration...
services.AddAuthentication(options =>
{
options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
})
.AddCookie()
.AddOpenIdConnect(options =>
{
options.Authority = Configuration["auth:oidc:authority"];
options.ClientId = Configuration["auth:oidc:clientid"];
});
// other configuration...
}
public void Configure(IApplicationBuilder app, ILoggerFactory loggerFactory)
{
// other configuration...
app.UseAuthentication();
// other configuration...
}

how to get the client_id that genereted a bearer token? (.NetCore2.1, IdentityServer4)

i working with netcore 2.1 and identityserver4 with Resource owner password flow
i need to get the client_id that generate the token bearer in one request
exist one way to get the client_id?
exist the relation in database userId,token,client_id?
the problem is that i not know what client_id make the request
i have a API in net core, multiple databases and multiples clients, in function of client_id i get information a database
By default , the access token issued from identity server 4 includes client_id claim:
After the client send request to your web api with access token , on web api side , add the authentication services to DI and the authentication middleware to the pipeline:
1.Add IdentityServer4.AccessTokenValidation NuGet package to your project
2.Update Startup to look like this:
public void ConfigureServices(IServiceCollection services)
{
services.AddMvcCore()
.AddAuthorization()
.AddJsonFormatters();
services.AddAuthentication("Bearer")
.AddIdentityServerAuthentication(options =>
{
options.Authority = "http://localhost:5000";
options.RequireHttpsMetadata = false;
options.ApiName = "api1";
});
}
public void Configure(IApplicationBuilder app)
{
app.UseAuthentication();
app.UseMvc();
}
Then you can get the claims which include the client id :

ASP .Net Core Google Authentication

I have a problem with google authentication on my .net core web api application.
My use case is simple, get bearer token from google put token in authorization header as "Bearer {token}" and call my web api.
But I cannot make it work. After I get token from google on following url:
https://accounts.google.com/o/oauth2/v2/auth?scope=email%20openid&include_granted_scopes=true&state=some_test_state&redirect_uri=http%3A%2F%2Flocalhost%3A53512&response_type=token&client_id={someClientID}
I will make call to my api with header:
Authorization: Bearer {TokenValue}
But every time I'm getting 401 Unauthorized.
This is my Startup class:
public static IConfigurationRoot Configuration { get; private set; }
// This method gets called by the runtime. Use this method to add services to the container
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
// Pull in any SDK configuration from Configuration object
services.AddDefaultAWSOptions(Configuration.GetAWSOptions());
// Add S3 to the ASP.NET Core dependency injection framework.
services.AddAWSService<Amazon.S3.IAmazonS3>();
IocConfig.Configure(services);
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
loggerFactory.AddLambdaLogger(Configuration.GetLambdaLoggerOptions());
var googleOptions = new GoogleOptions
{
AuthenticationScheme = "Google",
ClientId = "clientid",
ClientSecret = "cs",
SignInScheme = "Google"
};
app.UseGoogleAuthentication(googleOptions);
app.UseDeveloperExceptionPage();
app.UseMvc();
}
It's because your authentication scheme is "Google", but if you want to use bearer token you need to add it to your startup.cs
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
// here's your options
})
And use this authentication scheme instead of "Google"

Re-challenge authenticated users in ASP.NET Core

I'm running into some issues with the authentication pipeline in ASP.NET Core. My scenario is that I want to issue a challenge to a user who is already authenticated using OpenID Connect and Azure AD. There are multiple scenarios where you'd want to do that, for example when requesting additional scopes in a AAD v2 endpoint scenario.
This works like a charm in ASP.NET MVC, but in ASP.NET Core MVC the user is being redirected to the Access Denied-page as configured in the cookie authentication middleware. (When the user is not logged in, issuing a challenge works as expected.)
After a couple of hours searching the web and trying different parameters for my middleware options, I'm beginning to suspect that either I'm missing something obvious, or this behavior is by design and I need to solve my requirement some other way. Anyone any ideas on this?
EDIT: the relevant parts of my Startup.cs look like this:
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
services.AddAuthentication(
SharedOptions => SharedOptions.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme);
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
// <snip...>
app.UseCookieAuthentication(new CookieAuthenticationOptions { AuthenticationScheme = CookieAuthenticationDefaults.AuthenticationScheme });
var options = new OpenIdConnectOptions
{
AuthenticationScheme = OpenIdConnectDefaults.AuthenticationScheme,
ClientId = ClientId,
Authority = Authority,
CallbackPath = Configuration["Authentication:AzureAd:CallbackPath"],
ResponseType = OpenIdConnectResponseType.CodeIdToken,
PostLogoutRedirectUri = "https://localhost:44374/",
TokenValidationParameters = new Microsoft.IdentityModel.Tokens.TokenValidationParameters
{
ValidateIssuer = false
}
};
options.Scope.Add("email");
options.Scope.Add("offline_access");
app.UseOpenIdConnectAuthentication(options);
}
And the Action looks like this:
public void RefreshSession()
{
HttpContext.Authentication.ChallengeAsync(OpenIdConnectDefaults.AuthenticationScheme, new AuthenticationProperties { RedirectUri = "/" });
}
I found a hint and the solution here: https://github.com/aspnet/Security/issues/912.
ChallengeBehavior.Unauthorized is the "key".
This post gives the current (november 2016 - ASPNet 1.0.1) workaround: https://joonasw.net/view/azure-ad-b2c-with-aspnet-core
You'll need a new ActionResult to be able to call the AuthauticationManager.ChallengeAsync with the ChallengeBehavior.Unauthorized behavior.
Once the issue https://github.com/aspnet/Mvc/issues/5187 will be sucessfully closed, this should be integrated.
I tested it and it worked perfectly well (my goal was simply to extend Google scopes on a per user basis).
Try to sign out:
public void RefreshSession()
{
HttpContext.Authentication.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
HttpContext.Authentication.SignOutAsync(OpenIdConnectDefaults.AuthenticationScheme);
HttpContext.Authentication.ChallengeAsync(OpenIdConnectDefaults.AuthenticationScheme, new AuthenticationProperties { RedirectUri = "/" });
}