web.config transform for microsoft.identitymodel configsection - asp.net

How does one go about transforming the audienceUris and federatedAuthentication elements in the microsoft.identitymodel configuration section using the standard visual studio web.config transforms?
For the development environment, we have all the subdomains postfixed with a '-dev' along with special localhost port numbers, for example: realm="https://client-dev.domain.com:444". Today the main web.config reflects this but ideally we would like to move this setting to Web.Debug.config and in the Web.Release.config we would like to specify the proper audience and realms sans the '-dev' postfix and the local port settings. However, attempting to put xdt:Transform="Replace" in the microsoft.identitymodel element inside the Web.Debug.Config results in this warning:
The 'http://schemas.microsoft.com/XML-Document-Transform:transform' attribute is not declared.
and of course runtime failures (not being able to find servicecertificate for example).
Here's the microsoft.identitymodel sections:
<configuration>
<configSections>
<section name="microsoft.identityModel" type="Microsoft.IdentityModel.Configuration.MicrosoftIdentityModelSection, Microsoft.IdentityModel, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
</configSections>
<microsoft.identityModel>
<service>
<applicationService>
<claimTypeRequired>
<claimType type="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/privatepersonalidentifier" optional="false" />
<claimType type="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress" optional="false" />
</claimTypeRequired>
</applicationService>
<serviceCertificate>
<certificateReference x509FindType="FindByThumbprint" findValue="NNNNNNNNNN" storeLocation="LocalMachine" storeName="My" />
</serviceCertificate>
<certificateValidation certificateValidationMode="None" />
<audienceUris>
<add value="https://url/" />
</audienceUris>
<federatedAuthentication>
<wsFederation passiveRedirectEnabled="true" issuer="https://url/" realm="https://url/" requireHttps="true" />
<cookieHandler requireSsl="true" />
</federatedAuthentication>
<issuerNameRegistry type="Microsoft.IdentityModel.Tokens.ConfigurationBasedIssuerNameRegistry, Microsoft.IdentityModel, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35">
<trustedIssuers>
<add thumbprint="NNNNNNNNNN" name="https://url/" />
</trustedIssuers>
</issuerNameRegistry>
</service>
</microsoft.identityModel>
<configuration>
Existing solutions that don't work:
1) Same issue was raised here but no proper response. The RemoveAll and Insert doesn't work:
Web config transform on microsoft.identityModel - 'http://schemas.microsoft.com/XML-Document-Transform' attribute is not declared
2) Also, tried to manipulate the namespace as suggested on this thread and this doesn't work either:
http://social.msdn.microsoft.com/Forums/en-US/csharpgeneral/thread/9ededb66-3e34-4bba-8e20-a2cc6025f0f9
3) configSource looked promising but again does work when specified in the microsoft.identitymodel element.
I get:
Warning 1 The 'configSource' attribute is not declared.
http://blog.andreloker.de/post/2008/06/16/Keep-your-config-clean-with-external-config-files.aspx
Any help will be appreciated! Thanks.

After a lot of trial and error, I resorted to using XMLPreProcess by Loren Halvorson to auto-generate the correct Web.config from a TemplateWeb.config as part of the pre-Build event for each project.
Although I would have liked Visual Studio's attempt at this to work for developers, alas, time is of money and its time for me to move on. Needless to say, it's broken in the SQL Azure SDK as well because the transforms only occured when you publish a site. In the latest Azure SDK, that is no longer the case and hence transforms stopped working as well. Oh joy!
Here's a link to the excellent tool, I think, a must-have for every ASP.NET developer:
http://xmlpreprocess.codeplex.com/

Related

User Secrets in .NET 4.7 connectionstrings format

I have been digging for hours and keep coming up with information about .NET Core, yet hardly anything about .NET 4.7 full framework. I figured out how to add User Secrets to the main project of my Web API solution. I get the basic secrets.xml file where I need to to either store my database username and password or my connection string. Every post I find talks about the changes you need to make to web.config. However nothing shows what to do with my connection string, how to format it, in the secrets.xml file. I could create a name/value pair but that does not seem to do anything, my app cannot connect to the database.
I have this in my Web.config:
<configBuilders>
<builders>
<add name="Secrets" userSecretsId="5c65f7eb-a7e1-46cc-bff4-a526678005f2" type="Microsoft.Configuration.ConfigurationBuilders.UserSecretsConfigBuilder, Microsoft.Configuration.ConfigurationBuilders.UserSecrets, Version=1.0.0.0, Culture=neutral" /></builders>
</configBuilders>
<connectionStrings configBuilders="Secrets">
<add name="ShopAPDbConnectionString" connectionString="" providerName="System.Data.SqlClient" />
</connectionStrings>
My secrets.xml looks like this:
<?xml version="1.0" encoding="utf-8"?>
<root>
<secrets ver="1.0">
<secret name="ShopAPDbConnectionString" value="Server=SQLDEV01;Database=ShopAP; Integrated Security=True;" />
</secrets>
</root>
How do I properly format and get this to work?
Here is what I was able to get to work based on https://github.com/aspnet/MicrosoftConfigurationBuilders
Web.config
<configuration>
<configSections>
<section name="configBuilders" type="System.Configuration.ConfigurationBuildersSection, System.Configuration, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" restartOnExternalChanges="false" requirePermission="false" />
</configSections>
<configBuilders>
<builders>
<add name="Secrets" userSecretsFile="~/../../../SecretsTest/secrets.xml" mode="Greedy" type="Microsoft.Configuration.ConfigurationBuilders.UserSecretsConfigBuilder, Microsoft.Configuration.ConfigurationBuilders.UserSecrets, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
<add name="Json" jsonFile="${JSONConfigFileB}" optional="true" type="Microsoft.Configuration.ConfigurationBuilders.SimpleJsonConfigBuilder, Microsoft.Configuration.ConfigurationBuilders.Json, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
</builders>
</configBuilders>
<!--...-->
<appSettings configBuilders="Secrets">
<!--...-->
</appSettings>
<!--...-->
<connectionStrings configBuilders="Json">
<add name="DefaultConnection" providerName="System.Data.SqlClient" connectionString="dummy.value.required" />
</connectionStrings>
<!--...-->
</configuration>
secrets.xml
<?xml version="1.0" encoding="utf-8" ?>
<root>
<secrets ver="1.0">
<secret name="usersecret1" value="dogodog" />
<secret name="usersecret2" value="secretbar" />
<secret name="JSONConfigFileB" value="C://Users//xxx//Documents//xxx//xxx//SecretsTest//settings.json" />
</secrets>
</root>
settings.json
{
"DefaultConnection": "Server=666.66.666.6;Database=BigToe;User ID=FireBall;Password=BunniesAreSoft",
}
Both your files look fine - pretty much exactly the same as mine.
How did you create your secrets file? Did you use right-click on the Web project and Manage User Secrets?
That will create a file in a folder location in %APPDATA% that should be picked up when you hit F5 in Visual Studio (Debug > Start Debugging). However, it will not be seen by IIS if you compile and then browse to localhost. Even if you change the App Pool Identity in inetmgr to run under your account, and set Load User Profile - it still will not find it.
To find the correct location for the secrets for this case, run your web app and obtain the result of
string appdata = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
and copy the secrets file into the matching sub-folder Microsoft\UserSecrets\(guid)\
e.g.
C:\Windows\System32\config\systemprofile\AppData\Roaming\Microsoft\UserSecrets\5c65f7eb-a7e1-46cc-bff4-a526678005f2\secrets.xml
you may need to one-off obtain access in Explorer, and create the UserSecrets folder and below.
Remember to update both copies if you edit it in future.
Make sure the only file in your UserSecrets folder (C:\Users...\UserSecrets{guid}) is the secrets.xml file. I was messing around and had a secrets.json file in there (along with the secrets.xml file) and it wouldn't load my secrets.xml file. After I removed the json file, it worked fine.
I am attempting to do the same thing, but unfortunately I think this is only for appSettings when it comes to .Net Framework/Web.config.

Is the web.config/app.config element configSections deprecated in DotNet4.5?

I have an old application in ASP.Net (3.5) that needs upgrading, however, after updating to 4.5, a configSections element in the web.config file is not recognized and the app fails to load. Did something change here?
the following used to work...
<configuration>
<configSections>
<section name="paypal" type="PayPal.SDKConfigHandler, PayPal" />
</configSections>
<!-- PayPal SDK settings -->
<paypal>
<settings>
<add name="mode" value="sandbox"/>
<add name="clientId" value="YOUR APPLICATION CLIENT ID"/>
<add name="clientSecret" value="YOUR APPLICATION CLIENT SECRET"/>
</settings>
</paypal>
</configuration>
but no joy
HTTP Error 500.19 - Internal Server Error
The requested page cannot be accessed because the related configuration data for the page is invalid.
Config Source:
22:
23: <configSections>
24: <section name="paypal" type="PayPal.SDKConfigHandler, PayPal" />
I figured it out. It had nothing to do with permissions, IISExpress, or anything else, but only the position in the section. I moved element to just under the element and there's no error anymore. Go figure.
<configuration>
<configSections>
<section name="paypal" type="PayPal.SDKConfigHandler, PayPal" />
</configSections>
...
I've written my own XML parsers in the past that read the entire file and are not dependent on the order of the elements (just so long as it follows the structure & required elements are present). I incorrectly assumed that order does not matter in the web.config file. Good to know (probably save lots of coders headaches in the future).

How do I get a SecurityTokenHandler to load its configuration from web.config?

I have been struggling with trying to add a SAML2 SSO entry point to an asp.net 4.6 web application using WIF -- a technology I was totally unfamiliar with before starting. What has worked so far is to create everything programmatically, for which purpose I have subclassed various object types such as Saml2SecurityTokenHandler and X509CertificateValidator and IssuerNameRegistry, and for this handler I build up a SecurityTokenHandlerConfiguration object from scratch. But it has come to my attention that the right way to do this is to have the SecurityTokenHandlerConfiguration load from web.config, or rather app.config as this is in a side assembly rather than the website itself.
If I can get that to work, I can remove a lot of the programmatic stuff I've been duct-taping together. So I started putting the requisite sections in web.config. I added the identityModel sections to the configSections tag, and added something like this to my config:
<system.identityModel>
<identityConfiguration>
<tokenReplayDetection enabled="true" />
<audienceUris>
<add value="http://myurl.com" />
</audienceUris>
<issuerNameRegistry type="System.IdentityModel.Tokens.ConfigurationBasedIssuerNameRegistry, System.IdentityModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089">
<trustedIssuers>
<add thumbprint="1234123412341234ABCDABCDABCDABCD00000001" name="theirurl.com" />
</trustedIssuers>
</issuerNameRegistry>
</identityConfiguration>
</system.identityModel>
I also tried setting it up like this, which looks like it ought to fit right into what I need:
<system.identityModel>
<identityConfiguration>
<securityTokenHandlers>
<securityTokenHandlerConfiguration>
<tokenReplayDetection enabled="true" />
<audienceUris mode="Always">
<add value="http://myurl.com" />
</audienceUris>
<issuerNameRegistry type="System.IdentityModel.Tokens.ConfigurationBasedIssuerNameRegistry, System.IdentityModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089">
<trustedIssuers>
<add thumbprint="1234123412341234ABCDABCDABCDABCD00000001" name="theirurl.com" />
</trustedIssuers>
</issuerNameRegistry>
</securityTokenHandlerConfiguration>
</securityTokenHandlers>
</identityConfiguration>
</system.identityModel>
The problem is that I can't seem to bridge the gap between the configuration and the code. Nothing seems to load this automatically, and I can't find any useful information about how to load it manually. It seems that this whole section is just being ignored. If there's a "load config" step that's needed, I can't find where it's described.
How do I construct an instance of a Saml2SecurityTokenHandler, and have its Configuration be loaded from the stuff in app.config?
Update
I am no longer pursuing this approach. I'd still kind of like to know how this works, but there's no importance to it any more.
By creating an instance of IdentityConfiguration it will read your settings from configuration. The default constructor will perform this but there is also a constructor overload that lets you specify this explicitly (new IdentityConfiguration(true)). That one also grants you an exception if there is no <system.identityModel> configuration element.
If you haven't cleared the collection of SecurityTokenHandlers you will be able to access a variety of of them via your IdentityConfiguration instance's SecurityTokenHandlers property. This was true for me so I have to search for the handler I'm looking for.
In my case I wanted to read the TokenLifeTime property of the SessionSecurityTokenHandler (additionally using System.Linq):
System.IdentityModel.Tokens.SessionSecurityTokenHandler sessionSecurityTokenHandler =
new IdentityConfiguration(true)
.SecurityTokenHandlers
.SingleOrDefault(sth => sth.TokenType == typeof(System.IdentityModel.Tokens.SessionSecurityToken))
as System.IdentityModel.Tokens.SessionSecurityTokenHandler;
TimeSpan tokenLifeTime = sessionSecurityTokenHandler.TokenLifetime;
My configuration looks like this:
<system.identityModel>
<identityConfiguration>
<securityTokenHandlers>
<remove type="System.IdentityModel.Tokens.SessionSecurityTokenHandler, System.IdentityModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
<add type="System.IdentityModel.Tokens.SessionSecurityTokenHandler, System.IdentityModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
<sessionTokenRequirement lifetime="01:00" />
</add>
</securityTokenHandlers>
</identityConfiguration>
</system.identityModel>
From the securityTokenHandlers documentation:
By default, the collection is populated with the following handler types: SamlSecurityTokenHandler, Saml2SecurityTokenHandler, KerberosSecurityTokenHandler, WindowsUserNameSecurityTokenHandler, RsaSecurityTokenHandler, X509SecurityTokenHandler, and EncryptedSecurityTokenHandler. You can modify the collection by using the add, remove, and clear elements. You must ensure that only a single handler of any particular type exists in the collection. For example, if you derive a handler from the Saml2SecurityTokenHandler class, either your handler or the Saml2SecurityTokenHandler may be configured in a single collection, but not both.

Configuration issue with System.IdentityModel.Tokens.ValidatingIssuerNameRegistry

I am having an issue with properly configuring ValidatingIssuerNameRegistry in my ASP.NET Web Application. According to this article, I configured Azure AD sign-on to my app. Everything appears to work fine, but Visual Studio 2013 gives me a config warning (blue underline) on the configuration section for trustedIssuers so I decided to find a fix. This gentleman describes an alternative way of doing it that lines up with the VS2013 config warning. But alas, it does not work for me. IIS Express gives me an error when I try to run it.
Any thoughts on what I have mixed up? I'm guessing there is a version issue with .NET 4.5/4.0 or something of that nature but I can't find it.
This does not work...
(Server Error: WIF10112: The only supported element inside 'issuerNameRegistry' is 'authority'. Found element 'trustedIssuers'.) NOTE: Bottom of error page reports:
Version Information: Microsoft .NET Framework Version:4.0.30319; ASP.NET Version:4.0.30319.34009
<issuerNameRegistry type="System.IdentityModel.Tokens.ValidatingIssuerNameRegistry, System.IdentityModel.Tokens.ValidatingIssuerNameRegistry">
<trustedIssuers>
<add name="[MYNAME]" thumbprint="[MYTHUMB]"/>
</trustedIssuers>
</issuerNameRegistry>
This does work, but gives a compile time warning (expected 'trustedIssuers')...
<issuerNameRegistry type="System.IdentityModel.Tokens.ValidatingIssuerNameRegistry, System.IdentityModel.Tokens.ValidatingIssuerNameRegistry">
<authority name="MYNAME">
<keys>
<add thumbprint="MYTHUMB" />
</keys>
<validIssuers>
<add name="MYNAME" />
</validIssuers>
</authority>
</issuerNameRegistry>
Visual Studio uses XSD schemas to validate the config as far as I am aware. They usually reside in a folder like C:\Program Files (x86)\Microsoft Visual Studio 11.0\Xml\Schemas
The schema for the ValidatingIssuerNameRegistry is (http://msdn.microsoft.com/en-us/library/system.identitymodel.tokens.validatingissuernameregistry(v=vs.115).aspx):
<system.identityModel>
<issuerNameRegistry type='derived from ValidatingIssuerNameRegistry'>
<authority name='someFriendlyName'>
<keys>
<add thumbprint='caseInsensitiveString'/>
<add symmetricKey='Base64Encoded bytes' />
</keys>
<validIssuers>
<add name='issuer1'/>
<add name='issuer2'/>
</validIssuers>
</authority>
</issuerNameRegistry>
</system.identityModel>
The schema for the ConfigurationBasedIssuerNameRegistry is (http://msdn.microsoft.com/en-us/library/system.identitymodel.tokens.configurationbasedissuernameregistry(v=vs.110).aspx):
<system.identityModel>
<identityConfiguration>
<issuerNameRegistry type="System.IdentityModel.Tokens.ConfigurationBasedIssuerNameRegistry, System.IdentityModel">
<trustedIssuers>
<add thumbprint="thumbprint" name="name" />
</trustedIssuers>
</issuerNameRegistry>
</identityConfiguration>
It is likely the XSD files that visual studio uses only reference one or the other. The easiest way to find it is to search the XSD files for the string vs:help="configuration/system.identityModel/issuerNameRegistry"
You can update the schema if you wish so you no longer get the blue underlined text. I'm only using Visual Studio 2012 so I can't confirm this will work for you.
I think I figured out the issue but I'm not sure why. For some reason, the system must be picking up a previous version of "System.IdentityModel.Tokens.ValidatingIssuerNameRegistry". If you can explain why, I'll be happy to mark you as answer.
<issuerNameRegistry type="System.IdentityModel.Tokens.ValidatingIssuerNameRegistry, System.IdentityModel.Tokens.ValidatingIssuerNameRegistry">
<trustedIssuers>
<add name="[MYNAME]" thumbprint="[MYTHUMB]"/>
</trustedIssuers>
</issuerNameRegistry>
Should Be...
<issuerNameRegistry type="System.IdentityModel.Tokens.ConfigurationBasedIssuerNameRegistry, System.IdentityModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<trustedIssuers>
<add name="[MYNAME]" thumbprint="[MYTHUMB]"/>
</trustedIssuers>
</issuerNameRegistry>

Why might this ASP.NET profile section fail to dynamically compile?

When the following profile section is in my web.config, the first page request fail with FileNotFoundException and a bunch of error coming from the compiler (from the look of the stack trace). When the properties section is removed, everything works again (until I try to reference something from the Profile of course). The rest of the website is pre-compiled, assembly per page, not-updatable.
The problem has only been reproduced on one machine-- the same build worked on other highly similar machines.
Am I missing anything obvious?
<profile>
<providers>
<clear />
<add name="AspNetSqlProfileProvider"
connectionStringName="ConnectionString"
applicationName="OIWebApps"
type="System.Web.Profile.SqlProfileProvider"/>
</providers>
<properties>
<group name="UI">
<add name="MasterPage" defaultValue="Horizontal.master"/>
<add name="Theme" defaultValue="Default"/>
<add name="IsSessionWarningEnabled" defaultValue="True" type="System.Boolean"/>
<add name="UseTelerikMultilineTextBoxes" defaultValue="True" type="System.Boolean"/>
<add name="FontSize" defaultValue="Smaller" type="System.String"/>
</group>
</properties>
</profile>
I see "UseTelereikMultilineTextBoxes". Could it be that a file needed for Telerik is missing on this machine?
It failed to compile because of a missing native .dll It was extremely hard to identify because the page that was executing didn't directly use the .net dll that depended on the missing native .dll, and even more confusingly, only some pages raised the compile error instead of being raised on all pages.

Resources