Store appsettings.json in Azure App Service Web App - asp.net-core

I have created my first ASP Core MVC 3.1 app and published it in Azure. This works fine but I noticed that my settings.json file is visible in the root exposing my db connection string and Azure AD info.
I have been successful in 'hiding' the db connection string by adding a new connection string called Database in App Service>Settings>configuration. I named it the same as the entry in my settings.json file and it magically works. I have now removed this from the settings.json file.
In Startup I use
var connection = Configuration.GetConnectionString("Database");
services.AddDbContext<BookStoreContext>(options => options.UseSqlServer(connection));
The Azure login info is in an Array so I am not sure how I add this to the App Service Settings:
"AzureAd": {
"Instance": "https://login.microsoftonline.com/",
"Domain": "xxxx.onmicrosoft.com",
"TenantId": "xxxxxx-a2dd-4fde-bf8f-f75ab18b21ac",
"ClientId": "xxxxxxxxx-a9bb-4722-b615-6dcbdc646326",
"ClientSecret":xxxxxxxxxxxxxxxxxxxxxxxxxx",
"CallbackPath": "/signin-oidc"
},
In Startup I use:
services.AddAuthentication(AzureADDefaults.AuthenticationScheme)
.AddAzureAD(options => Configuration.Bind("AzureAd", options));
Any help will be much appeciated.
Thanks,

According to my test, if you want to store array settings in Azure App Service configuration. You have two choices.
With Azure APP service window, you can store it like {"AzureAd:Domain" :""}
With App Service on Linux or Web App for Containers, you can store it like {"AzureAd_Domain" :""}

The Azure login info is in an Array so I am not sure how I add this to the App Service Settings
You can try to add these setting data with nested JSON key structure as below in Application settings.
For more information about setting configuration keys and values, please check these Docs:
https://learn.microsoft.com/en-us/aspnet/core/fundamentals/configuration/?view=aspnetcore-5.0#configuration-keys-and-values
https://learn.microsoft.com/en-us/azure/app-service/configure-common#add-or-edit

Related

Attempting Authentication via Azure AD B2C and Authorization via groups from AAD

So I followed the below examples:
Hosted Blazor Web Assembly AAD B2C: here
Azure Active Directory groups and roles : here
I first implemented Hosted Blazor Web Assembly and got that working fine. Went to implement the Group and Roles parts and began to have issues.
Everything is word for word as in the examples but not sure I merged or setup the Program.cs right in the client. When attempting the call I get a "Microsoft.AspNetCore.Authorization.DefaultAuthorizationService[2]
Authorization failed."
Unfortunately none of my breakpoints work so I figured I would reach out and see if any one has any advice.
This is built from the scaffolding for Blazor.
Here is my program.cs in my client app setup.
builder.Services.AddHttpClient("<Server Project Name>", client => client.BaseAddress = new Uri(builder.HostEnvironment.BaseAddress))
.AddHttpMessageHandler<BaseAddressAuthorizationMessageHandler>();
// Supply HttpClient instances that include access tokens when making requests to the server project
builder.Services.AddScoped(sp => sp.GetRequiredService<IHttpClientFactory>().CreateClient("KeeperLife.UI.ServerAPI"));
builder.Services.AddMsalAuthentication(options =>
{
builder.Configuration.Bind("AzureAdB2C", options.ProviderOptions.Authentication);
options.ProviderOptions.DefaultAccessTokenScopes.Add("https://<Full path to >/API.Access ");
});
builder.Services.AddScoped<GraphAPIAuthorizationMessageHandler>();
builder.Services.AddHttpClient("GraphAPI",
client => client.BaseAddress = new Uri("https://graph.microsoft.com"))
.AddHttpMessageHandler<GraphAPIAuthorizationMessageHandler>();
builder.Services.AddMsalAuthentication<RemoteAuthenticationState,
CustomUserAccount>(options =>
{
builder.Configuration.Bind("AzureAd",
options.ProviderOptions.Authentication);
//Originally this was "..." but it seemed to break base config so i added the same as above and that worked but then tested with it commented out and it still worked so left it commented out.
//options.ProviderOptions.DefaultAccessTokenScopes.Add("https://<Url to full API PAth>/API.Access");
options.ProviderOptions.AdditionalScopesToConsent.Add(
"https://graph.microsoft.com/Directory.Read.All");
})
.AddAccountClaimsPrincipalFactory<RemoteAuthenticationState, CustomUserAccount,
CustomUserFactory>();
builder.Services.AddAuthorizationCore(options =>
{
options.AddPolicy("SiteAdmin", policy =>
policy.RequireClaim("group", "<The Object ID of the group>"));
});
Not sure why your breakpoints don't work. But as far as I know, AAD B2C does not provide an Out-of-the-box RBAC functionality.
In Azure AD we can implement it by modifying the "groupMembershipClaims" field in application manifest: "groupMembershipClaims": "SecurityGroup". But it's not available in Azure AD B2C.
There is a workaround. Add a new claim type 'groups' into the custom policy and call the Microsoft Graph to get user's groups. Here is an example for your reference.
Vote this user voice post will be helpful.

AzureAD B2C, return URL signin-oidc ERR_CONNECTION_CLOSED

I've been playing with AzureAD B2C using ASP.NET Core 3.1
I've already set up an AzureAD B2C using the project wizard and it's worked well. I now need to retro fit an existing application to use AzureAD B2C.
I've imported the same package from the existing application, ie..
I've setup the appsetting.json file ...
"AzureAdB2C": {
"Instance": "https://xxx.b2clogin.com/tfp/",
"ClientId": "xxx-xxx-xxx-xxx-xxx",
"CallbackPath": "/signin-oidc",
"Domain": "xxx.onmicrosoft.com",
"SignUpSignInPolicyId": "B2C_1_SignInRegister",
"ResetPasswordPolicyId": "B2C_1_PasswordReset",
"EditProfilePolicyId": "B2C_1_ProfileEdit"
},
Added the services in ConfigureServices..
services.AddAuthentication(AzureADB2CDefaults.AuthenticationScheme)
.AddAzureADB2C(options => Configuration.Bind("AzureAdB2C", options));
and added Auth in Configure
app.UseAuthentication();
app.UseAuthorization();
For a moment, I see my app shooting over to azure for authentication, but then I get redirected back to https://localhost:xxxx/signin-oidc, with a ERR_CONNECTION_CLOSED
I've missed something somewhere.
I fixed this myself, it was an oversight when I set up the new project.
As is typically the case with Visual Studio when using IIS Express to Debug, the new project used a different ssl port. I needed to enter the new port with the Azure AD B2C App Registration.
Note the correct address and port in VS
Go to the Azure Portal, bring up the B2C Overview for the relevant Domain
Click on "App Registrations"
Select the relevant Application
Select the redirect uri's link
Click "Add URI", and enter the correct signin-oidc link, for me, that was https://localhost:44304/signin-oidc
I'll need to remember that when I eventually publish the code. I found that I could enter as many uri's as I needed. Eg, one for DEV, one for QA, one for PROD etc....

Not trying to use /Common endpoint, but Azure AD believes I am

I'm using my organization's Azure AD to authenticate users on a corporate web app. I intend for this to be a single-tenant application. When I run it, I'm prompted to log in with my organization's credentials, as expected. On submitting my credentials, however, I get this error:
Sorry, but we’re having trouble signing you in.
AADSTS50194: Application 'appId'(appname) is not configured as a multi-tenant application. Usage of the /common endpoint is not supported for such applications created after '10/15/2018'. Use a tenant-specific endpoint or configure the application to be multi-tenant.
The thing is, I'm not trying to use the /common endpoint. Here is the relevant bit of my appsettings.json:
"AzureAd": {
"Instance": "https://login.microsoftonline.com/",
"Domain": "COMPANYDOMAIN.onmicrosoft.com",
"TenantId": "MYTENANTID-xxxx-xxxx-xxxx-xxxx",
"ClientId": "MYCLIENTID-yyyy-yyyy-yyyy-yyyy",
"CallbackPath": "/signin-oidc"
},
And here's the app's settings in the Azure portal (Home>AppRegistrations>App>PlatformConfigurations>Authentication):
My startup.cs, which I assumed set the endpoint in question, is taken directly from the Microsoft-provided sample:
services.Configure<OpenIdConnectOptions>(AzureADDefaults.OpenIdScheme, options =>
{
options.Authority = options.Authority + "/v2.0/";
options.TokenValidationParameters.ValidateIssuer = false;
});
I've also set false to true for kicks, but the result was the same.
What am I doing wrong, here? Why does Azure AD continue to believe I want to use the /common endpoint?
Edit: As I continued to search, I happened on #jack-jia's answer here: Application is not configured as a multi-tenant application
I haven't quite solved my issue, but their answer offered some promising clues.
Since you have configured it as single tenant application on Azure portal, this issue must occurred due to the wrong authorization endpoint. Please check the value of options.Authority again. If it is identified as single tenant, you can use fiddler to capture the request, the request is something like
GET https://login.microsoftonline.com/{tenant}/oauth2/v2.0/authorize?
client_id=6731de76-14a6-49ae-97bc-6eba6914391e
&response_type=id_token
&redirect_uri=http%3A%2F%2Flocalhost%2Fmyapp%2F
&response_mode=form_post
&scope=openid
&state=12345
&nonce=678910
Check if the endpoint is correct.
I came here with the same error but using python to authenticate my API calls.
Specifically I was using authOAuthDesktopMobileAuthCodeGrant class from bingads.authorization
The solution I ended up with is as follows:
The init for authOAuthDesktopMobileAuthCodeGrant shows the following, note that tenant is defaulted to "common".
def __init__(self, client_id, oauth_tokens=None, env=PRODUCTION, oauth_scope=MSADS_MANAGE, **tenant='common'**):
Therefore, in order to overwrite /common like others here have done. I had to set this tenant component here to my app's tenant ID
authentication = OAuthDesktopMobileAuthCodeGrant(
client_id=client_id,
tenant="{YOUR_TENANT_ID}",
env='production'
Hope this is useful to others who are working out of python.

Where is the secret key stored when you add authentication at project creation time in ASP.NET 4?

Assume I create an ASP.NET Core 2.0 App in Visual Studio 2017:
I can integrate with Azure Active Directory by clicking the Change Authentication dialog.
Then after entering my MSDN credentials 2 or three times it will register my application with Azure Active Directory:
That creates the following snippet in appsettings.json:
"AzureAd": {
"Instance": "https://login.microsoftonline.com/",
"Domain": "XXXXXXXX.onmicrosoft.com",
"TenantId": "XXXXXXXXX",
"ClientId": "XXXXXXXXX",
"CallbackPath": "/signin-oidc"
},
Tenant Id matches what this question said it would. And ClientId matches Azure ID. However, I don't see where this Key, that Visual Studio created during the app provisions, is stored:
Where is that stored?
AFAIK, the template of Visual Studio does't save the secret when it create it on the Azure. If you want a secret for this app, you can delete the old one and create a new.
Please Note: Once you left that page, the secret was not able to see again.

publishing appsettings.json securely to Azure

I am using the SecretManager tool in aspnetcore to store a connection string during development to keep it out of source control.
This works just fine.
But now I want to publish the app to Azure. When it publishes, there is no connection string in appsettings.json so the app cannot connect to the database.
So how am I supposed to include the connection string?
If I simple add it to appsettings.json, does it not defeat the whole purpose of using the secrets manager? As now I have put a username and password into a document which is under source control.
Is there something I am missing? Am I supposed to FTP to the site and add it there?
You're supposed to put it in the Azure site settings. That's the preferred approach.
If your json looks like this:
{
"ConnectionStrings": {
"Context": "Server=(localdb)\\mssqllocaldb;Database=local-dev;Trusted_Connection=True"
}
}
You create a connection string with the name Context (alternatively a setting with the key ConnectionStrings:Context) and enter your connection string in the apps Application Settings page:
Just make sure you're using environment variables in your Startup:
var builder = new ConfigurationBuilder()
.AddEnvironmentVariables();