Our Blog

Running locally via Visual Studio and JetBrains Rider and managing the ASPNETCORE_ENVIRONMENT variable has been challenging.  Changing and setting ASPNETCORE_ENVIRONMENT within launchSettings.json and/or within Project Properties impacts the web.{envrionment}.config files.  Without the appropriate configuration within the publish steps the site was being deployed with incorrect settings and it was time consuming to track it back to the best approach.  So for now I have a pipeline build process setup for each AppService ‘slot’ setting different BuildConfiguration within each to ensure the most appropriate web.config is deployed.

This is a .net core asp.net web application so why the web.config? It appears that locally during IIS Express/IIS there is still a dependency on this web.config to identify the hosting model (inprocess) and reference to the exe that would be run.  This is of course when deploying to Windows infrastructure.

Project Properties – Environment variables

image

My launchSettings.json – you can see I can modify before running how IIS or IIS Express identifies the environment variable

image

The resultant/related web.configs looks like the following for Development and Staging environments.

web.config
image

web.Staging.config (you can see the addition of the xdt:Transform=”Replace” attribute which informs publish that when building for Staging to replace this variable within web.config with this value)
image

By default the build process on Azure DevOps – Pipelines was ignoring any file transformation requirements.  In order to establish File Transformation on publish notice the –configuration $(BuildConfiguration)
image

and the respective variable that is used during publish to identify the appropriate configuration to use (development/staging etc.)
image

After the build and using App Service Editor my web.config was successfully transformed

image

Azure – while trying to read pfx (certificate) from disk I came across a number of issues, but thought this might help some out.

The fix was adding the final parameter X509KeyStorageFlags

var cert = new X509Certificate2($"{Environment.ContentRootPath}/App_Data/mycert.pfx", "{password}", X509KeyStorageFlags.MachineKeySet);



Other references:
https://support.microsoft.com/en-us/help/950090/installing-a-pfx-file-using-x509certificate-from-a-standard-net-applic
https://stackoverflow.com/questions/52750160/what-is-the-rationale-for-all-the-different-x509keystorageflags

An unhandled exception occurred while processing the request.
WindowsCryptographicException: The system cannot find the file specified.
System.Security.Cryptography.CngKey.Open(string keyName, CngProvider provider, CngKeyOpenOptions openOptions)

Exception: An error was encountered while handling the remote login.
Microsoft.AspNetCore.Authentication.RemoteAuthenticationHandler<TOptions>.HandleRequestAsync()

Stack Query Cookies Headers Routing
WindowsCryptographicException: The system cannot find the file specified.
System.Security.Cryptography.CngKey.Open(string keyName, CngProvider provider, CngKeyOpenOptions openOptions)
System.Security.Cryptography.CngKey.Open(string keyName, CngProvider provider)
Internal.Cryptography.Pal.CertificatePal.GetPrivateKey<T>(Func<CspParameters, T> createCsp, Func<CngKey, T> createCng)
Internal.Cryptography.Pal.CertificatePal.GetRSAPrivateKey()
System.Security.Cryptography.X509Certificates.X509Certificate2.get_PrivateKey()
Microsoft.IdentityModel.Tokens.X509SecurityKey.get_PrivateKey()
Microsoft.IdentityModel.Tokens.X509SecurityKey.get_PrivateKeyStatus()
Microsoft.IdentityModel.Tokens.AsymmetricSignatureProvider.FoundPrivateKey(SecurityKey key)
Microsoft.IdentityModel.Tokens.AsymmetricSignatureProvider..ctor(SecurityKey key, string algorithm, bool willCreateSignatures)
Microsoft.IdentityModel.Tokens.AsymmetricSignatureProvider..ctor(SecurityKey key, string algorithm, bool willCreateSignatures, CryptoProviderFactory cryptoProviderFactory)
Microsoft.IdentityModel.Tokens.CryptoProviderFactory.CreateSignatureProvider(SecurityKey key, string algorithm, bool willCreateSignatures)
Microsoft.IdentityModel.Tokens.CryptoProviderFactory.CreateForSigning(SecurityKey key, string algorithm)
Microsoft.IdentityModel.JsonWebTokens.JwtTokenUtilities.CreateEncodedSignature(string input, SigningCredentials signingCredentials)
System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler.WriteToken(SecurityToken token)
Sample.Idp.Startup+<>c__DisplayClass7_0.<ConfigureServices>b__8(AuthorizationCodeReceivedContext context) in Startup.cs
Microsoft.AspNetCore.Authentication.OpenIdConnect.OpenIdConnectEvents.AuthorizationCodeReceived(AuthorizationCodeReceivedContext context)
Microsoft.AspNetCore.Authentication.OpenIdConnect.OpenIdConnectHandler.RunAuthorizationCodeReceivedEventAsync(OpenIdConnectMessage authorizationResponse, ClaimsPrincipal user, AuthenticationProperties properties, JwtSecurityToken jwt)
Microsoft.AspNetCore.Authentication.OpenIdConnect.OpenIdConnectHandler.HandleRemoteAuthenticateAsync()

image

About Us

Web/Mobile Solutions

Our Contacts

Cincinnati, OH 45069