.NET Core 3.1 - Bearer error="invalid_token", error_description="The audience 'xxxx-xxxx-xxxx-xxxx' is invalid"} - scope

I am getting this error (Bearer error="invalid_token", error_description="The audience 'xxxx-xxxx-xxxx-xxxx' is invalid"}) when attempting to access information from a registered API. The audience is the clientId of the registered API in Azure ADB2C. I have inspected the access token and it also has the same value against the aud key of the token.
My startup configuration is as follows in the app hosting the API:
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApi(Configuration.GetSection("AzureAd"));
The web app calling the API has the following setup in the startup configuration
services.AddAuthentication(AzureADDefaults.AuthenticationScheme);
services.AddMicrosoftIdentityWebAppAuthentication(Configuration, "AzureAd")
.EnableTokenAcquisitionToCallDownstreamApi(ScopeConstants.SCOPES)
.AddDistributedTokenCaches();

I have managed to get a solution on this though it has no direct correlation with the basic AzureAd parameters setup. I had the the following lines of code in my startup configuration. After removing them, the error disappeared.
services.AddControllersWithViews(options =>
{
var policy = new AuthorizationPolicyBuilder()
.AddAuthenticationSchemes(JwtBearerDefaults.AuthenticationScheme)
.RequireScope(Configuration["AzureAd:Scopes"])
.Build();
options.Filters.Add(new AuthorizeFilter(policy));
});

Related

Unauthorize Error to Azure App Configuration with Azure Functions

I'm using App Configuration and Key Vault for store my config. Firstly, I used access key where was Endpoint, Id and Secret. That is working fine, but it isn't secure, because Id and Secret are sensitive data.
I tried to use value after 'Endpoint=' and in Startup.cs set DefaultAzureCredential(), but always when I launch my Azure Function, I get 401 (Unauthorize error). Why do I get this and how could I fix that?
ConfigureAppConfiguration in Startup
public override void ConfigureAppConfiguration(IFunctionsConfigurationBuilder builder)
{
base.ConfigureAppConfiguration(builder);
var configurationBuilder = builder.UseAppSettings().ConfigurationBuilder.AddEnvironmentVariables().Build();
var connectionString = configurationBuilder["appConfiguration"];
builder.ConfigurationBuilder.AddAzureAppConfiguration(options =>
{
var credentials = new DefaultAzureCredential();
options.Connect(new Uri(connectionString), credentials)
.Select(KeyFilter.Any, LabelFilter.Null)
.Select(KeyFilter.Any, builder.GetContext().EnvironmentName)
.ConfigureKeyVault(kv =>
{
kv.SetCredential(new DefaultAzureCredential());
});
});
}
appConfiguration from appsettings
"appConfiguration": "https://rta-dev-edu-app-config.azconfig.io"
Error
A host error has occurred during startup operation '9467e813-9979-44b9-8ecf-3d956fbaf72e'.
Azure.Data.AppConfiguration: Service request failed.
Status: 401 (Unauthorized)
WWW-Authenticate: HMAC-SHA256,Bearer error="invalid_token", error_description="The access token is from the wrong issuer. It must match the AD tenant associated with the subscription, to which the configuration store belongs. If you just transferred your subscription and see this error message, please try back later.
P.S. I already added my account to IAM for my App Configuration.
The access token is from the wrong issuer. It must match the AD tenant associated with the subscription, to which the configuration store belongs. If you just transferred your subscription and see this error message, please try back later.
As Mentioned in this MS Doc of Accessing the Key Vault from the Dot Net Core Application,
you have to check that your account should have the multiple tenants access and then Set the Credential types such as SharedTokenCacheTenantId, VisualStudioTenantId to the DefaultAzureCredentialOptionswhile using the DefaultAzureCrendential in the required tenant.
Your Azure Account should be logged in the Same tenant level as you're trying to access the app configuration resource from the same tenant.
Refer to the GitHub Issue #14867.

usage details api using azure app registration in azure AD

In basic terms, I am trying to get an access token to get Azure Cost Centre Data through the Usage Details API. The problem is that I can't seem to configure my service principal with azure properly. I have:
Created the registered app in Azure Active Directory
added https://www.thunderclient.io/oauth/callback in the redirect URL
generated a client secret
Included the following information in my Generate New Token in Thunder Client:
Request URL:
GET: https://management.azure.com/subscriptions/{subscription-id}/resourceGroupName/{resourceGroupName}/providers/Microsoft.CostManagement/dimensions?api-version=2019-11-01
Grant Type: Authorization Code
Auth Url: https://login.mmicrosoftonline.com/common/oauthorize
Token Url: https://login.microsoft.com/{tenant-id}/oauth2/v2.0/authorize from app registration
callback Url: https://thunderclient.io/oauth/callback
client ID: {{client_id}} from app registration
client secret: {{client_secret}} from app registration
scope: user_impersonation
{
Status 401 Unauthorized
"error": {
"code": "AuthenticationFailed",
"message": Authentication failed."
}
}
Header:
Bearer authorization_uri "https://login.windows.net/{tenant_id}, error= "invalid_token", error description="Could not find identity for access token"
Answering my own question. And big thanks to Guarav Mantri in the comments below.
The Scope should be set to https://management.azure.com/.default
The Grant Type is client credentials and not authorization code
The service principal needs to be added to the resource in azure that is part of the request (i.e. if looking for subscription data, then add the service principal as a reader role to the subscription).

Getting error when trying to secure aspnet core web api with B2C authentication: Unable to retrieve openid config

I'm trying to secure my aspnet core web API server by making it authenticate against Azure B2C using user-provided JWT bearer tokens. I've followed some sample code found on official microsoft github pages, but can't seem to get it working.
In my B2C policy, I've got it set to use the default issuer URL format: https:////v2.0/
In my web application, I've got that same URL specified as the Authority in the JWT options.
When I submit an HTTP request to my server, the identity server code fails as it tries to reach out to B2C to fetch the openid-configuration. It fails with the following error ...
HttpRequestException: Response status code does not indicate success: 404 (Not Found).
System.Net.Http.HttpResponseMessage.EnsureSuccessStatusCode()
IOException: IDX20804: Unable to retrieve document from: 'https://innovativelitfoundry.b2clogin.com/0f55bfb6-6af5-4293-8963-29ae099183cc/v2.0/.well-known/openid-configuration'.
Microsoft.IdentityModel.Protocols.HttpDocumentRetriever.GetDocumentAsync(string address, CancellationToken cancel)
InvalidOperationException: IDX20803: Unable to obtain configuration from: 'https://innovativelitfoundry.b2clogin.com/0f55bfb6-6af5-4293-8963-29ae099183cc/v2.0/.well-known/openid-configuration'.
Microsoft.IdentityModel.Protocols.ConfigurationManager<T>.GetConfigurationAsync(CancellationToken cancel)
Indeed, that URL will not work because it does not appear to be including the policy name, from the used token, in the query string. So, that URL does indeed not work.
I'm unsure how to make the code provide that policy name in the query string, though? Or should it be doing that automatically?
Here is the code, in my aspnet core web api application, where I configure the authentication settings ...
public void ConfigureServices(IServiceCollection services)
{
IdentityModelEventSource.ShowPII = true;
services
.AddAuthentication(ConfigureAuthentication)
.AddJwtBearer(ConfigureJwt);
services
.AddCors();
services
.AddMvc()
.SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
services
.AddSingleton(Configuration);
}
private void ConfigureAuthentication(AuthenticationOptions options)
{
options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
}
private void ConfigureJwt(JwtBearerOptions options)
{
var tenant = Configuration["AzureAd:TenantId"];
options.Audience = Configuration["AzureAd:ApplicationId"];
options.Authority = $"https://innovativelitfoundry.b2clogin.com/{tenant}/v2.0/";
}
Does anybody perhaps know what I may be doing incorrectly here? How can I get my aspnet core web api application to correctly pull down that openid configuration document?
You must set options.Authority to an authority URL that includes the policy ID:
options.Authority = $"https://innovativelitfoundry.b2clogin.com/{tenant}/{policy}/v2.0/";
As long as you have set the issuer claim for all policies to the issuer URL that doesn't contain the policy ID, then your API application can download the configuration document for any policy and then validate tokens that are issued for all policies.

Getting Authorization has been denied for this request in Fiddler with Azure AD

I have created a ASP.Net Web API (.Net Framework) app with "Work or School Accounts" as authentication type. This automatically registers this API app in my Azure subscription and I can see it under "App Registrations". I can see that Home Page Url is pointing to localhost address. I can see that API is launching locally on localhost address. I then launch Fiddler to get access token from Azure AD. My POST request to endpoint https://login.microsoftonline.com/<mytenant>.onmicrosoft.com/oauth2/token. has following 4 parameters
grant_type=client_credentials
&client_id=<appid from Azure AD Portal>
&client_secret=<secret from Azure AD Portal>
&resource=<appid from Azure AD Portal>
I get a token back. When I decode this token, I see aud and appid as expected(matching appid in Azure AD). I use this token as bearer token to invoke API call by adding Authorization: Bearer <mytoken> header in GET request to https://localhost:44374/api/values. However, this GET call to my API is returning me {"Message":"Authorization has been denied for this request."} error message.
What am I missing?
You should use App ID URI as the resource value when acquiring token , you could find the App ID URI in Properties of api app in azure portal ,like https://xxxxx.onmicrosoft.com/WebApplicationName . Web api will check whether the aud claim in access token matches the one you set in web.config :
app.UseWindowsAzureActiveDirectoryBearerAuthentication(
new WindowsAzureActiveDirectoryBearerAuthenticationOptions
{
Tenant = ConfigurationManager.AppSettings["ida:Tenant"],
TokenValidationParameters = new TokenValidationParameters {
ValidAudience = ConfigurationManager.AppSettings["ida:Audience"]
},
});
ida:Audience value in web.config is the allowed audience .

How to configure permissions for the Azure AD authentication v2.0

I have set up a new web app to be able to use the Oauth2 V2 authorization endpoint. I defined the app in https://apps.dev.microsoft.com/
If I want to obtain a new authorization token, following instructions in
https://blogs.msdn.microsoft.com/richard_dizeregas_blog/2015/09/04/working-with-the-converged-azure-ad-v2-app-model/
I get the following error on the login page:
Sorry, but we’re having trouble signing you in.
We received a bad request.
Additional technical information:
Correlation ID: eb9c2331-32bd-45a9-90d1-e9105f0bfa87
Timestamp: 2016-05-22 18:10:48Z
AADSTS70011: The provided value for the input parameter 'scope' is not valid. The scope https://graph.microsoft.com/Calendar.Read is not valid.
The scope is taken from an example in :
https://github.com/Azure/azure-content/blob/master/articles/active-directory/active-directory-v2-scopes.md
So I imagine it is a valid scope.
In v1 of the OAuth2 protocol, it was necessary to configure access to APIs in the Azure AD of my tenant, prior to using them. So I attempted to do so for the new application.
Attempting to do so, the Azure application management reports an error:
{
"message":"This request has a value that is not valid.",
"ErrorMessage":"This request has a value that is not valid.",
"httpStatusCode":"InternalServerError","operationTrackingId":null,"stackTrace":null,"Padding":null
}
What is missing to be able to use the new authorization endpoint ?
The documentation contains a typo if states calendar.read. It must be calendars.read:
private static string[] scopes = {
"https://graph.microsoft.com/calendars.readwrite"};
Uri authUri = await authContext.GetAuthorizationRequestUrlAsync(scopes, additionalScopes, clientId, redirectUri, UserIdentifier.AnyUser, null);

Resources