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

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 :

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.

Add authorization to header and access [Authorize] controllers

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

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...
}

User is authenticated after OpenId Connect (AAD) but Unable to find access token

I am trying to find the access token from AAD after user is authenticated from OpenId Connect. It is a web application integrated with AAD OpenId Connect. I need to get the access token to call another API that uses the same AAD. Here's what I've tried:
Clone this sample code.
In Startup.cs file, add the following block of code:
public void ConfigureServices(IServiceCollection services) {
services.TryAddSingleton<IHttpContextAccessor, HttpContextAccessor();
services.AddAuthentication(sharedOptions =>
{
sharedOptions.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
sharedOptions.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
})
.AddAzureAd(options => Configuration.Bind("AzureAd", options))
.AddOpenIdConnect("oidc", options =>
{
options.Authority = "http://localhost:5000";
options.ClientId = "<<client-id>>";
options.SignInScheme = "cookie";
options.SaveTokens = true;
options.GetClaimsFromUserInfoEndpoint = true;
options.RequireHttpsMetadata = false;
})
.AddCookie();
services.AddMvc();}
In HomeController class, I added a private variable called httpContextAccessor and also set it in the constructor.
private IHttpContextAccessor _httpContextAccessor;
public HomeController(IHttpContextAccessor httpContextAccessor)
{
_httpContextAccessor = httpContextAccessor;
}
In the HomeController class, I added some code to access the access token.
public IActionResult Index()
{
if (User.Identity.IsAuthenticated)
{
var attempt1 = Request.Headers["Authorization"];
var attempt2 = HttpContext.GetTokenAsync("access_token");
var attempt3 = _httpContextAccessor.HttpContext.GetTokenAsync("access_token");
var attempt4 = _httpContextAccessor.HttpContext.Request.Headers["Authorziation"];
}
return View();
}
But all of them return either empty or null. Did I miss anything?
I've looked at this following posts for reference:
How to refresh access token
How to get access token from HttpContext in .Net core 2.0
You need to set SaveTokens to true in OpenID Connect configuration:
Clone that code sample
Keep the Startup.cs , you don't need to add .AddOpenIdConnect part , AddAzureAd extension method would help add Azure Active Directory Authentication to your application.
Modify the AzureAdAuthenticationBuilderExtensions.cs in Extensions folder :
public void Configure(string name, OpenIdConnectOptions options)
{
options.ClientId = _azureOptions.ClientId;
options.Authority = $"{_azureOptions.Instance}{_azureOptions.TenantId}";
options.UseTokenLifetime = true;
options.CallbackPath = _azureOptions.CallbackPath;
options.RequireHttpsMetadata = false;
options.SaveTokens = true; // set to true
}
Then you can get the ID token from httpContextAccessor:
var idToken = _httpContextAccessor.HttpContext.GetTokenAsync("id_token");
But the access token is still null . The sample shows how to use the OpenID Connect ASP.NET Core middleware to sign-in users from a single Azure AD tenant , that means you can get the ID Token which is sent to the client application as part of an OpenID Connect flow and is used by the client to authenticate the user. Please refer to document : ID tokens .
While Access tokens enable clients to securely call APIs protected by Azure . Please refer to document : Azure Active Directory access tokens .
If you want to get the access token for accessing resource which protected by Azure AD , you should use ADAL(Azure AD V1.0 endpoint) to obtain the token , see code sample(especially use OnAuthorizationCodeReceived to acquire access token):
https://github.com/Azure-Samples/active-directory-dotnet-webapp-webapi-openidconnect-aspnetcore
Or use MSAL if you are using Azure AD V2.0 endpoint .

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"

Categories