Asp.net core CloudConfigurationManager.GetSetting() is null - azure

I have an asp.net 4 application where it works fine, but I can't get it working for asp.net core. The documentation says that GetSetting looks in either web.config or app.config file.
Storage emulator is turned on.
public void ConfigureServices(IServiceCollection services)
{
AzureConfig.Initialize();
}
public static void Initialize()
{
//Always null
var connectionString = CloudConfigurationManager.GetSetting("StorageConnectionString");
}
root web.config file:
<configuration>
<appSettings>
<add key="StorageConnectionString" value="UseDevelopmentStorage=true;" />
</appSettings>
</configuration>
I have these dependencies in my project.json:
"Microsoft.WindowsAzure.ConfigurationManager": "3.2.1",
"WindowsAzure.Storage": "7.1.2",
"AzureSDK2.2DLLs": "1.0.0"
Edit, this doesn't work either:
{
"ConnectionStrings": {
"DefaultConnection": "..."
"StorageConnectionString": "UseDevelopmentStorage=true"
},
"Logging": {
"IncludeScopes": false,
"LogLevel": {
"Default": "Debug",
"System": "Information",
"Microsoft": "Information"
}
},
"StorageConnectionString": "UseDevelopmentStorage=true"
}

In ASP.NET core, the settings have been moved out of the web.config and in to appsettings.json. Have a look at the documentation for how it has changed:
https://docs.asp.net/en/latest/fundamentals/configuration.html
Also, have a look at this previous answer to a similar question:
https://stackoverflow.com/a/30580006/2823539

Related

Azure App Service application settings not overriding application.json array setting for .NET Core 3.1 application

We have a .NET Core 3.1 application deployed to Microsoft Azure.
In the application.json file of the application we have the following contents:
{
"Settings": {
"ServicesURIs": [
{
"Name": "Features",
"URL": "https://abc.azurewebsites.net",
"Port": "443",
"ScopeUri": "api://xxxxxx",
"enabled": "true"
},
{
"Name": "Questions",
"URL": "https://def.azurewebsites.net",
"Port": "443",
"ScopeUri": "api://XXXXX",
"enabled": "true"
}
]
},
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"AllowedHosts": "*",
"pwa": {
"cacheId": "v1.3",
"strategy": "networkFirst",
"registerWebmanifest": true,
"routesToPreCache": "/"
}
}
I wish to override the URL properties from the Application settings section in Configuration of the app service in Azure.
I am currently specifying the following application setting in the configuration blade per documentation and lots of online blogs:
Name= Settings:ServicesURIs:0:URL
Value= https://Somevalidurl.azurewebsites.net
But I find that the application is not using the value from the portal configuration, and always try to use the value in the .json file.
I have tried specifying the name as
Settings__ServicesURIs__0__URL
(where the ":" are replaced with double underscores)
I have restarted the application service after registering the setting in Azure.
I test this using Chrome in Incognito to ensure cache is not playing a role.

Application Insights in Azure Function App Core v2

I am trying to use the standard ILogger and make it log to Azure. First I added following to host file:
{
"version": "2.0",
"Logging": {
"ApplicationInsights": {
"LogLevel": {
"Default": "Trace",
"System": "None",
"Microsoft": "None"
}
}
},
"ApplicationInsights": {
"Instrumentationkey": "xx-xx-xx-xx-xx"
}
}
And this is my function:
namespace Jobs
{
public static class ExchangeRates
{
[FunctionName("ExchangeRates")]
public static void Run([TimerTrigger("0 0 0 * * *", RunOnStartup =true)]TimerInfo myTimer, ILogger log)
{
string lol1 = "lol1 text";
string lol2 = "lol2 text";
log.LogWarning("adsad");
log.LogDebug("LogDebug", "asdasd", lol2);
log.LogTrace("LogTrace {lol1}, {lol2}", lol1, lol2);
log.LogInformation("LogInfo {lol1}, {lol2}", lol1, lol2);
log.LogError("LogError");
log.LogInformation($"C# Timer trigger function executed at: {DateTime.Now}");
}
}
}
But no logging are added. I also tried installing nuget package:
Microsoft.Extensions.Logging.ApplicationInsights
Am I missing something - what does it take to make an function app writing to Application Insights?
I think you're running the azure function locally with application insights, right?
If yes, actually it's not recommended since application insights is integrated with azure function in azure portal.
But for testing only, you can just add this line of setting "APPINSIGHTS_INSTRUMENTATIONKEY": "the key" in local.settings.json(remember to set it as "copy if newer"). The sample settings in local.settings.json looks like below:
{
"IsEncrypted": false,
"Values": {
"AzureWebJobsStorage": "xxxxxx",
"FUNCTIONS_WORKER_RUNTIME": "dotnet",
"APPINSIGHTS_INSTRUMENTATIONKEY": "the key"
}
}
By the way, I also installed the nuget package Microsoft.Extensions.Logging.ApplicationInsights in my test.

Load an SSL certificate from appsettings.json

I built a .NET core 2.2 application, that I am loading onto a raspberry pi. I am hosting the web service using Kestrel. On the pi, I have created a self-assigned certificate.pfx. If I hard code into the application a .UseHttps with the certificate name and password, the browser can find it.
However, if I comment it out of the code and use the appsettings.json file instead (I would like it in the appsettings.json, so clients can upload their own certificates), the redirect to Https will work, but the certificate is not loading and the page fails to connect.
This is the document I have been using to configure my appsettings.json file:
https://learn.microsoft.com/en-us/aspnet/core/fundamentals/servers/kestrel?view=aspnetcore-2.2
The certificate is located in the application folder.
Currently I have this code commented out of the application, but it does work when the code is not commented. I am hoping to set up these same settings through the appsettings.json file instead.
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
.ConfigureKestrel((context, options) =>
{
/*options.Listen(IPAddress.Any, 80);*/ // http:*:80
//options.Listen(IPAddress.Any, 5001, listenOptions =>
//{
// listenOptions.UseHttps("certificate.pfx", "password");
//});
});
here is the appsettings.json file:
{
"https_port": 5001,
"Logging": {
"LogLevel": {
"Default": "Warning"
}
},
"AllowedHosts": "*",
"AllowInvalid": true,
"Kestrel": {
"Endpoints": {
"Http": {
"Url": "http://*:80"
}
},
"Https": {
"Url": "https://*:5001",
"Certificate": {
"Path": "certificate.pfx",
"Password": "password"
}
}
}
}
This article ended up having the solution I needed:
https://www.humankode.com/asp-net-core/develop-locally-with-https-self-signed-certificates-and-asp-net-core
To be more precise its the part of the article titled "Configuring HTTPS in ASP.NET Core 2.0"
Instead of using appsettings.json, I created a new json file called certificate.json.
I then pull in the certificate name and password from the certificate.json into the program.cs code.

How set up Ocelot Api Gateway with Azure Active Directory

I followed this tutorial and managed to use api with Azure Active Directory
authentication & authorization.
However I would like to consume the api from behind the Ocelot Api Gateway.
I could use ocelot with custom basic authorization but could not accomplish to use with Azure Active Directory.
I have added Ocelot api gateway url to my api redirect url list already.
How should I set ReRoutes values in config.json and Ocelot Api Gateway project StartUp.cs ?
Any help will be appreciated.
Eventually I could.
First of all thanks to ocelot library because it supports Azure Active Directory authorization.
I assume that you can already completed this tutorial.
1-Create an ocelot api gateway project as usual.
2-Add Microsoft.Identity.Web class library to ocelot project as reference
3-Add ocelot.json and it should be like below
{
"ReRoutes": [
{
"DownstreamPathTemplate": "/api/{catchAll}",
"DownstreamScheme": "http",
"DownstreamHostAndPorts": [
{
"Host": "localhost",
"Port": 44351
}
],
"UpstreamPathTemplate": "/to-do-service/api/{catchAll}",
"AuthenticationOptions": {
"AuthenticationProviderKey": "AzureADJwtBearer",
"AllowedScopes": []
}
}
],
"GlobalConfiguration": {
"BaseUrl": "http://localhost:7070",
"RequestIdKey": "OcRequestId",
"AdministrationPath": "/administration"
}
}
4-Edit CreateWebHostBuilder method in Program.cs so that ocelot.json is used as additional config source.
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.ConfigureAppConfiguration((hostingContext, config) =>
{
config.AddJsonFile("ocelot.json", false, false);
})
.UseStartup<Startup>();
5-Edit ConfigureServices and Configure methods in Startup.cs like below
public void ConfigureServices(IServiceCollection services)
{
services.AddProtectWebApiWithMicrosoftIdentityPlatformV2(Configuration); //this extension comes from Microsoft.Identity.Web class library
services.AddOcelot(Configuration);
//services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public async void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
await app.UseOcelot();
}
6-Last but not least you should add your AzureAd configuration to ocelot api gateway project. (It should be same as ToDoListService for reference tutorial)
Her you can see an example appsettings.json .
{
"AzureAd": {
"Instance": "https://login.microsoftonline.com/",
"ClientId": "client-id-guid-from-azure-ad",
/*
You need specify the TenantId only if you want to accept access tokens from a single tenant (line of business app)
Otherwise you can leave them set to common
*/
"Domain": "blablabla.onmicrosoft.com", // for instance contoso.onmicrosoft.com. Not used in the ASP.NET core template
"TenantId": "tenant-id-guid-from-azure-ad" // A guid (Tenant ID = Directory ID) or 'common' or 'organizations' or 'consumers'
},
"Logging": {
"LogLevel": {
"Default": "Warning"
}
},
"AllowedHosts": "*"
}
I hope this answer save someones time and make their life happier :)
Happy coding!
I was unable to get this working with the "Microsoft.Identity.Web" library. I received a host of errors such as:
AuthenticationScheme: AzureADCookie was not authenticated...
-- and --
Signature validation failed...
Instead, I managed to get the Azure B2C token validation, as well as the scopes, working as follows:
1) ConfigureServices method (Startup.cs):
services.AddAuthentication(options =>
{
options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(jwtOptions =>
{
jwtOptions.Authority = $"{Configuration["AzureAdB2C:Instance"]}/tfp/{Configuration["AzureAdB2C:TenantId"]}/{Configuration["AzureAdB2C:SignUpSignInPolicyId"]}";
jwtOptions.Audience = Configuration["AzureAdB2C:ClientId"];
jwtOptions.TokenValidationParameters.ValidateIssuer = true;
jwtOptions.TokenValidationParameters.ValidIssuer = $"{Configuration["AzureAdB2C:Instance"]}/{Configuration["AzureAdB2C:TenantId"]}/v2.0/";
});
// Map scp to scope claims instead of http://schemas.microsoft.com/identity/claims/scope to allow ocelot to read/verify them
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Remove("scp");
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Add("scp", "scope");
2) Ocelot re-routing configuration:
{
"DownstreamPathTemplate": "/{everything}",
"DownstreamScheme": "http",
"DownstreamHostAndPorts": [
{
"Host": "master-api",
"Port": 5000
}
],
"UpstreamPathTemplate": "/master-api/{everything}",
"UpstreamHttpMethod": [ "POST", "PUT", "GET", "DELETE" ],
"ReRoutesCaseSensitive": false,
"AuthenticationOptions": {
"AuthenticationProviderKey": "Bearer",
"AllowedScopes": [ "master" ]
}
}
3) Azure AD B2C configuration (appsettings.json):
"AzureAdB2C": {
"Instance": "https://yourdomain.b2clogin.com",
"TenantId": "{tenantId}",
"SignUpSignInPolicyId": "your_signin_policy",
"ClientId": "{clientId}"
}
Hope this helps! :)

ASP.NET Core app not working after publish to Azure

I have an ASP.NET Core app which is running fine locally.
However, when I publish (Web Deploy) the site to Azure, I get a 403: You do not have permission to view this directory or page.
I have a default controller and a route defined in Startup.cs:
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller}/{action}/{id?}",
defaults: new { controller = "Home", action = "Index" });
});
The folder structure after web deploy to Azure looks like:
|_ home
|_ site
|_ wwwroot (contains DLL's and files specified through 'publishOptions' in project.json)
|_ wwwroot (the contents of the 'wwwroot' folder I have in Visual Studio)
|_ Views (contains MVC views)
|_ refs (contains referenced DLLs, I think?)
Any idea of what I should look for in project.json or the Kudu portal to figure out what's wrong?
My project.json file:
{
"title": "My Web App",
"version": "1.0.0-*",
"buildOptions": {
"debugType": "portable",
"emitEntryPoint": true,
"preserveCompilationContext": true,
"compile": {
"exclude": [ "bin/**", "obj/**", "node_modules/" ]
}
},
"publishOptions": {
"include": [ "wwwroot", "Views", "appsettings.json", "appsettings.*.json" ]
},
"scripts": {
"prepublish": [ "jspm install", "gulp build" ]
},
"dependencies": {
"Microsoft.ApplicationInsights.AspNetCore": "1.0.0",
"Microsoft.AspNetCore.Diagnostics": "1.0.0",
"Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore": "1.0.0",
"Microsoft.AspNetCore.Mvc": "1.0.0",
"Microsoft.AspNetCore.StaticFiles": "1.0.0",
"Microsoft.Extensions.Configuration.Json": "1.0.0",
"Microsoft.Extensions.Configuration.UserSecrets": "1.0.0",
"Microsoft.Extensions.Logging.Console": "1.0.0",
"Microsoft.Extensions.Logging.Debug": "1.0.0",
"Microsoft.VisualStudio.Web.BrowserLink.Loader": "14.0.0",
"System.IO.FileSystem": "4.0.1"
},
"frameworks": {
"netcoreapp1.0": {
"dependencies": {
"Microsoft.NETCore.App": {
"type": "platform",
"version": "1.0.0"
},
"Microsoft.AspNetCore.Server.Kestrel": "1.0.0"
},
"imports": "dnxcore50"
}
},
"commands": {
"web": "Microsoft.AspNet.Server.Kestrel --server.urls=http://*:8000/"
}
}
Edit:
For one, I was missing the Microsoft.AspNetCore.Server.IISIntegration NuGet package. When I added it, I also got a web.config file in the site root (which I included through project.json).
I also added .UseIISIntegration() to my WebHostBuilder in Startup.cs:
public static void Main(string[] args)
{
new WebHostBuilder()
.UseKestrel()
.UseContentRoot(Directory.GetCurrentDirectory())
.UseStartup<Startup>()
.UseIISIntegration() // This was missing
.Build()
.Run();
}
I can now run it on IIS Express locally (although I guess it's IIS fronting Kestrel?), but when published to Azure I get error:
HTTP Error 502.5 - Process Failure
The event log in Azure states: Failed to start process with commandline '"%LAUNCHER_PATH%" %LAUNCHER_ARGS%', ErrorCode = '0x80070002'.
According to the documentation, the troubleshooting step is:
If the server does not have Internet access while installing the server hosting bundle, this exception will ensue when the installer is prevented from obtaining the Microsoft Visual C++ 2015 Redistributable (x64) packages online. You may obtain an installer for the packages from the Microsoft Download Center.
Not sure how this applies to Azure, though?
The problem came from insufficient IIS integration/configuration.
I had to add the following to project.json:
"tools": {
"Microsoft.AspNetCore.Server.IISIntegration.Tools": "1.0.0-preview2-final"
}
I also added a postPublish script for IIS publishing:
"scripts": {
"postpublish": [ "dotnet publish-iis --publish-folder %publish:OutputPath% --framework %publish:FullTargetFramework%" ]
}
I also added the Microsoft.AspNetCore.Server.IISIntegration NuGet package:
"dependencies": {
"Microsoft.AspNetCore.Server.IISIntegration": "1.0.0"
}
This created a web.config file, which I had to modify as:
<configuration>
<system.webServer>
<handlers>
<add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModule" resourceType="Unspecified" />
</handlers>
<aspNetCore processPath=".\My.Web.App.dll" arguments="" forwardWindowsAuthToken="false" stdoutLogEnabled="true" stdoutLogFile="\\?\%home%\LogFiles\stdout" />
</system.webServer>
</configuration>
Finally I added UseIISIntegration to my WebHostBuilder:
public static void Main(string[] args)
{
new WebHostBuilder()
.UseKestrel()
.UseContentRoot(Directory.GetCurrentDirectory())
.UseStartup<Startup>()
.UseIISIntegration() // This was missing
.Build()
.Run();
}
A standard Publish (Web Deploy) from Visual Studio and the website started just fine on Azure (although in my case I also had to add a prepublish script for some Gulp tasks).

Resources