Blocking web.config inheritance in a sub-application
Asked Answered
P

2

6

We have a legacy .NET solution which has a combination of MVC and WebForms stuff, and some Web API projects as applications under the website root. Obviously these Web API applications will inherit the website's web.config settings.

We also have another project - a bounded context - for SSO authentication which sits inside the same root folder and consequently also inherits the website's web.config settings. This bounded context application has been built with .NET Core.

- wwwroot   // .NET Framework
    - API 1 // .NET Framework
    - API 2 // .NET Framework
    - ...
    - SSO / authentication // bounded context, built in .NET Core

We have recently started using Azure Key Vault to store our secrets, and to work with these secrets locally we're using a secrets.xml file. So the web.config of the root website looks like this...

<configSections>
  <section name="configBuilders" ... />
</configSections>  

<configBuilders>
  <builders>
    <add name="Secrets" optional="false" userSecretsFile="~\secrets.xml" [elided attributes] />
  </builders>
</configBuilders>

<appSettings configBuilders="Secrets">
  <add key="a_key" value="value specified in secrets.xml" />
  ...
</appSettings>

Here's the problem: the Authentication bounded context project throws an exception because it can't find the Microsoft.Configuration.ConfigurationBuilders.UserSecrets assembly - because it's inheriting the website's config it needs to know what that config section is all about.

But if reference that NuGet package in the .NET Core authentication project I get the message...

This package may not be fully compatible with your project.

...and it automatically rolls back.

So if I can't reference the UserSecrets assembly in the .NET Core sub-application then how can I get it to recognise the <configBuilders> section in the inherited config file?

I've also tried removing the element...

<configSections>
  <section name="configBuilders" />
</configSections>

...from the root config file, but the sub-application then sees the <configBuilders> element and doesn't recognise it.

So the problem boils down to:

  1. The sub-application needs a NuGet package in which the <configBuilders> element is defined.
    If not...
  2. The sub-application sees the <configSections> / <section name="configBuilders" /> element and needs to know where this is defined.
    Or, I remove that <section name="configBuilders" /> element in the sub-application and then...
  3. The sub-application sees the <configBuilders> element and needs to know which config section defines this.
Phaidra answered 7/5, 2020 at 15:48 Comment(0)
P
0

Here's how we solved this problem:

  1. Created a custom config section in which we declare the secrets.
    A note of warning to anyone following this: In order to declare the configBuilders attribute on a custom config section you also must declare a corresponding implementation of SectionHandler<your-custom-config-section> - here's the documentation.
  2. Added this custom config section and custom SectionHandler<T> to our top-level site and to the API projects within the site, but not to the .NET Core-built SSO / authentication sub-application.
  3. In the top-level site, wrapped the custom config section in <location path="." inheritInChildApplications="false">.

The downside to this is that we have to obtain the secrets using our custom config manager while all non-secret app-settings are obtained using the default ConfigurationManager, but I don't detect any code smell about this.

Phaidra answered 17/5, 2020 at 9:56 Comment(0)
S
0

Publish the WEB API in another Virtual Directory. Create Redirect or Rewrite rules to route the Web API traffic to this Virtual Directory.

Shetler answered 17/5, 2020 at 8:33 Comment(0)
P
0

Here's how we solved this problem:

  1. Created a custom config section in which we declare the secrets.
    A note of warning to anyone following this: In order to declare the configBuilders attribute on a custom config section you also must declare a corresponding implementation of SectionHandler<your-custom-config-section> - here's the documentation.
  2. Added this custom config section and custom SectionHandler<T> to our top-level site and to the API projects within the site, but not to the .NET Core-built SSO / authentication sub-application.
  3. In the top-level site, wrapped the custom config section in <location path="." inheritInChildApplications="false">.

The downside to this is that we have to obtain the secrets using our custom config manager while all non-secret app-settings are obtained using the default ConfigurationManager, but I don't detect any code smell about this.

Phaidra answered 17/5, 2020 at 9:56 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.