ASP .Net Core Google Authentication - asp.net-core

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"

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.

Azure AD - Expose an API to consume it with application permissions

I'm developing a custom API and a windows service. I want to use Azure AD for authentication and authorization between the api and the windows service.
My question ist: How can I expose the API, so that I can add the api permissions to the win service with the type "application permissions"?
I can only select "delegated permissions" when I want to add the api permissions to the win service. But I need "application persmissions" because the win service runs without an user.
Thank you in forward!
Best regards
Matthias
Ok. Now I know how to set up the manifest in the app registration. I also get a bearor token and in the bearor token I can see (if I bas64-decode it) the Client ID of the Web API and also the App roles: "roles":["User.Sync2"]
So I think that the token is correct.
In the second step I call the Web API (https://localhost:44358/api/AzureADB2C/Ping) with authentication "Bearor" and the token. But then I receive a 401. (I have not registered any platform in the app registration for the Web API and therefore also no redirect URI. But I think I don't need it?)
Here's the Startup.cs of my Web API project (It's standard generated with Visual Studio):
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.AzureAD.UI;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
namespace AzureADB2CConnect.API
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddAuthentication(AzureADDefaults.BearerAuthenticationScheme)
.AddAzureADBearer(options => Configuration.Bind("AzureAd", options));
services.AddControllers();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
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();
});
}
}
}
and here is my API Controller:
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
namespace AzureADB2CConnect.API.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class AzureADB2CController : ControllerBase
{
[HttpGet("Ping")]
[Authorize(Roles = "User.Sync2")]
//[Authorize]
public async void GetPing()
{
//foreach(Claim claim in ClaimsPrincipal.Current.Claims)
//{
//}
}
}
}
If I remove the "Authorized"-Tags I can call the API. And it doesn't matter If I use only Authorize or Authorize(Roles = "User.Sync2") I always receive a 401.
Where is the error/bug?
Thank you in forward!
Here is the decoded bearor token:
That's how I call the GET-Method to get the token:
you need to add app roles. Please follow How to: Add app roles in your application and receive them in the token. App role allowedMemberTypes should include Application.
I can reproduce your problem. You entered the wrong parameters when verifying the token. You need to change Authorized to Authorization and Bearor to Bearer.

CORS problem with custom controller and CustomClientStore in IdentityServer4

I want to add a custom end-point into IdentityServer4 but when I call API from another site, I have a CORS error.
I use a CustomClientStore to load my clients so i need to add CustomCorsPolicyService
Access to XMLHttpRequest at 'http://localhost:8082/embedded/log' from origin 'http://localhost:8080' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
In Startup, I add my CustomClientStore and CustomCorsPolicyService
public void ConfigureServices(IServiceCollection services)
{
...
CustomClientStore.Init(_Configuration);
var builder = services.AddIdentityServer()
.AddInMemoryIdentityResources(Config.GetIdentityResources())
.AddInMemoryApiScopes(Config.GetApiScopes())
.AddRedirectUriValidator<MyUriValidator>();
builder.Services.AddSingleton<IUserRepository, UserRepository>();
builder.AddProfileService<CustomProfileService>();
builder.AddClientStore<CustomClientStore>();
//services.AddCors(setup => setup.AddDefaultPolicy(b => b.AllowAnyOrigin().AllowAnyHeader().AllowAnyMethod()));
builder.AddCorsPolicyService<CustomCorsPolicyService>();
...
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
app.UseDeveloperExceptionPage();
app.UseStaticFiles();
// Add this before any other middleware that might write cookies
app.UseCookiePolicy();
app.UseIdentityServer();
app.UseRouting();
app.UseCors();
app.UseMvcWithDefaultRoute();
// This will write cookies, so make sure it's after the cookie policy
app.UseAuthentication();
}
In My Controller
[ApiController]
public sealed class EmbeddedLogController : ControllerBase
{
[HttpPost]
[Route("/embedded/log/")]
[EnableCors()]
public ActionResult Log(ParametersLog parameters)
{
....
}
}
Without CustomClientStore I could call services.AddCors(setup => setup.AddDefaultPolicy... to accept CORS
But now I need to use builder.AddClientStore<CustomClientStore>(); because of CustomProfileService.
How can I fix that ?
Thanks
this GitHub issue might give you some clues.
That says:
Solved When using Endpoint Routing CORS and IdentityServer4, the call
to UseCors() must be after UseRouting() but BEFORE UseIdentityServer()
and UseAuthorization(). Otherwise it will appear to work but
Pre-Flight checks will fail

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

Redirect to HTTPS in Blazor

I have a blazor app.
I hosted it on server and have access with https.
But when i do redirect (in one controller), happens exception.
Startap.cs
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.UseResponseCompression();
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseHttpsRedirection();
app.UseMvc(routes =>
{
routes.MapRoute(name: "default", template: "{controller}/{action}/{id?}");
});
app.Map("/schedule", subdirApp =>
{
subdirApp.UseBlazor<Client.Startup>();
});
}
And method in controller
[HttpGet]
[Route("***")]
public IActionResult Return()
{
FileStream fs = new FileStream(_filePath, FileMode.Open);
System.Runtime.Serialization.Formatters.Binary.BinaryFormatter formatter = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
List<ScheduleEntity> _list = (List<ScheduleEntity>)formatter.Deserialize(fs);
foreach (var x in _list)
Schedules.Add(x);
fs.Close();
return Redirect("~//schedule");
}
Exception
Please, help me
These API responses can be a bit misleading. Without seeing the rest of your code around the configuration of endpoints, I suspect this might be a CORS issue with the API.
Try adding the following code to the public void Configure(IApplicationBuilder app, IHostingEnvironment env) method in your API's Startup.cs class:
app.UseCors(opts => opts
.AllowAnyOrigin()
.AllowAnyMethod()
.AllowAnyHeader()
.AllowCredentials()
);
The fetch response may be due to the request preflight being rejected.
Having said that, the first exception message is saying you're trying to load insecure content, so I'd also check your Blazor front-end app's configuration to see what the API client is requesting and ensure the API endpoint certificate is valid?