ASP.NET Core Web App using Work (Azure AD) Authentication works debugging locally, but not after publish to Azure - azure

My ASP.NET Core web app works great when running and debugging locally, but fails to run once published to Azure.
I enabled Organizational Authentication and selected the appropriate domain upon publishing.
The appropriate reply URL was registered
After I publish to Azure I get this error:
An unhandled exception occurred while processing the request.
OpenIdConnectProtocolException: Message contains error: 'invalid_client', error_description: 'AADSTS70002: The request body must contain the following parameter: 'client_secret or client_assertion'.
Trace ID: 640186d6-9a50-4fce-ae39-bbfc1caf2400
Correlation ID: 622758b2-ca52-4bb0-9a98-e14d5a45cf80
Timestamp: 2017-04-19 16:36:32Z', error_uri: 'error_uri is null'.
I'm assuming that it's because the Client Secret needs to be stored in Azure somewhere; however, the value in secrets.json did not work when I added it as an App Setting (invalid client secret error) as I saw someone was able to do on another post. Also not sure if putting the value of "Authentication:AzureAd:ClientSecret" in Azure AppSettings is a good idea anyway.

Not sure if this is useful to anyone or not. But i receive a similar error message.
OpenIdConnectProtocolException: Message contains error: 'invalid_client', error_description: 'error_description is null', error_uri: 'error_uri is null'.
Microsoft.AspNetCore.Authentication.OpenIdConnect.OpenIdConnectHandler+<RedeemAuthorizationCodeAsync>d__22.MoveNext()
The solution for me was to provide a secret in the token service
,new Client
{
ClientId = "Testclient",
ClientName = "client",
ClientSecrets =
{
new Secret("secret".Sha256())
},
//Hybrid is a mix between implicit and authorization flow
AllowedGrantTypes = GrantTypes.Hybrid,
And provide the secret in the client
app.UseOpenIdConnectAuthentication(new OpenIdConnectOptions
{
//The name of the authentication configuration.. just incase we have multiple
AuthenticationScheme = "oidc",
//Represents where to store the identity information -> which points to the cookie middleware declared above
SignInScheme = "Cookies",
//where the token service reside -> system will configure itself by invoking the discovery endpoint for the token service
Authority = "http://localhost:5000",
RequireHttpsMetadata = false,
ClientId = "Testclient",
ClientSecret = "secret",
//hybrid flow -grant type
ResponseType = "code id_token",
Hopefully this helps someone

Somehow I the Azure AD IDs needed for the proper Azure Active Directory App Registration were mixed up. There were 2 App Registration entries and the ClientID and TenentID's didn't match up with the local. So I synchronized the Client and Tenent IDs with one of the App Registration entries, and made sure the Client Secret was in App Settings, and it worked properly.
I verified these steps with this fine example Win's GitHub repository and they match now.

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.

msal-node error trying to resolve endpoints

I have been using MSAL in my React app for some time with success. One of the tokens that my app requests is for scope 'https://management.core.windows.net/user_impersonation'. I have a nodeJS server that I want to push that token acquisition to so I installed msal-node (1.12.1) and tried using the OBO flow:
const pca = new msal.ConfidentialClientApplication({
auth: {
clientId: settings.config.azure.clientId,
clientSecret: settings.config.azure.clientSecret,
authority: "https://login.microsoftonline.com/<tenantid>",
knownAuthorities: ["https://login.microsoftonline.com/<tenantid>"],
}
});
const request = {
scopes: ['https://management.core.windows.net//user_impersonation'],
oboAssertion: <token_extracted_from_auth_header>
}
const response = await pca.acquireTokenOnBehalfOf(request);
return response.accessToken;
However the above code results in the following error:
ClientAuthError: endpoints_resolution_error: Error: could not resolve endpoints. Please check network and try again. Detail: ClientAuthError: openid_config_error: Could not retrieve endpoints. Check your authority and verify the .well-known/openid-configuration endpoint returns the required endpoints. Attempted to retrieve endpoints from: https://login.microsoftonline.com/tenantid/v2.0/.well-known/openid-configuration
If I visit the URL it complains about I do get back some metadata so not really sure why it is failing.
Anybody have a suggestion?
Also in regards to OBO flow:
For my nodeJS app I have added that permission to the required API list
I presume the oboAssertion field is the token that is passed to my nodeJS app by the client? I simply extracted it from the Auth header
The actual error message there means that the URL that we are trying to contact is wrong. And it is wrong https://login.microsoftonline.com/tenantid/v2.0/.well-known/openid-configuration returns an error.
A coorrect one is: https://login.microsoftonline.com/19d5f71f-6c9a-4e7f-b629-2b0c38f2b167/v2.0/.well-known/openid-configuration
Notice how I used an actual teanant_id there. You can get yours from the Azure Portal - it's the "directory id"
If your web api is single tenant, i.e. it is only meant for the people in 1 organization, then the is the tenant id of that organization. It is also known as "directory id". You get it from the Azure Portal.
However, if your api is multi-tenant, i.e. it's a bit more complicated, and the "correct" answer is to use the tenant id of the incoming assertion. It's the tid claim in it.

Getting "unauthorized_client" when trying to login using Microsoft account

In my IS4's Startup.cs:
services.AddAuthentication()
.AddMicrosoftAccount(o =>
{
o.SignInScheme = IdentityServer4.IdentityServerConstants.ExternalCookieAuthenticationScheme;
o.ClientId = "clientId";
o.ClientSecret = "clientSecret";
});
I have defined the scope:
openid
profile
And I get the error after I tried to login:
unauthorized_client: The client does not exist or is not enabled for consumers. If you are the application developer, configure a new application through the App Registrations in the Azure Portal at https://go.microsoft.com/fwlink/?linkid=2083908.
It's a web app. So what am I doing wrong here:
I assume the client ID is this:
And my client secret is this:
I have also set up the redirect URI:
The error means the Supported account types are not set for the personal account(Microsoft account in your case).
To solve the issue, navigate to the Manifest of your App registration, set the two properties accessTokenAcceptedVersion and signInAudience like below.
"accessTokenAcceptedVersion": 2,
"signInAudience": "AzureADandPersonalMicrosoftAccount"
When you save the setting, make sure your app meets the requirement of the validation, otherwise there will be some errors.

Azure MSI using app services

I am trying to protect my backing services to my frontend webapp using MSI and AAD auth.
I keep getting a 401 when I call my backing services form the public facing webapp. I have added the public webapp as a reader in the IAM section of the backing services.
What I can't figure out is how to obtain the access token, it seems that no matter which endpoint I use for obtaining the access token, it says that it is not found.
Here is my code:
{
var azureServiceTokenProvider = new AzureServiceTokenProvider();
string accessToken = azureServiceTokenProvider.GetAccessTokenAsync("https://<mywebapi>.azurewebsites.net").GetAwaiter().GetResult();
var httpClient = new HttpClient();
httpClient.DefaultRequestHeaders.Authorization = new
AuthenticationHeaderValue("Bearer", accessToken);
RemoteIp = httpClient.GetStringAsync("https://<mywebapi>.azurewebsites.net/api/default/remoteIp").GetAwaiter().GetResult();
LocalIp = httpClient.GetStringAsync("https://<mywebapi>.azurewebsites.net/api/default/localIp").GetAwaiter().GetResult();
ConnectionId = httpClient.GetStringAsync("https://<mywebapi>.azurewebsites.net/api/default/connectionId").GetAwaiter().GetResult();
}
And here is the error message:
Parameters: Connectionstring: [No connection string specified], Resource: https://<mywebapi>.azurewebsites.net, Authority: .
Exception Message: Tried to get token using Managed Service Identity.
Unable to connect to the Managed Service Identity (MSI) endpoint.
Please check that you are running on an Azure resource that has MSI setup.
UPDATE:
<mywebapi> is obviously the actual endpoint value, but not exposed here on stackoverflow. Furthermore I should mention that calling the API endpoints directly works fine, after I have authorized with my personal credentials xxx#xxx.xxx. The issue is related to the webapp trying to identify itself to the webapi, even though it is a registered application which has been assigned the necessary IAM rights on the webapi resource.
The error says it tried to use MSI, but could not. Are you sure you are running this code on the Web App with MSI enabled?
Also, you need to replace "https://<mywebapi>.azurewebsites.net" with the App Id URI or Application Id of your API in Azure AD.
In other words, this needs to match the valid audience that you have configured for the API.

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