Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to securely use credentials outside web.config for ASP.NET & Azure

Goal: Host an ASP.NET Web App to Azure and utilize OAuth2 for Google, Twilio, and SendGrid, with a database for user information.

Issue: I receive errors upon publishing when I utilize an external config file that my "appSettings" within my Web.config file references. Within Azure I've also entered credentials to be securely stored for Google OAuth2, which overrides the published Web.config settings from my research and understanding. How do I properly and securely use and reference within my code sensitive credentials for Azure?

Research: I've been following this link step by step -

https://azure.microsoft.com/en-us/documentation/articles/web-sites-dotnet-deploy-aspnet-mvc-app-membership-oauth-sql-database/

This link also leads to another link for Google OAuth2 implementation below -

www.asp.net/mvc/overview/security/create-an-aspnet-mvc-5-app-with-facebook-and-google-oauth2-and-openid-sign-on#goog

However this insecurely puts the sensitive information within the web.config file which is noted by a Security note that leads here for secure/best practices for deploying sensitive ASP.NET information to Azure -

www.asp.net/identity/overview/features-api/best-practices-for-deploying-passwords-and-other-sensitive-data-to-aspnet-and-azure

My understanding is that referencing an external file that houses the sensitive data/credentials from within the web.config file is a best practice. I note that IIS does not serve *.config and because of the referenced configuration file location below even "git add *" will not add the sensitive credentials to the repository.

Web.config - (Note appSettings on line 2)

    </connectionStrings>
   <appSettings file="..\..\AppSettingsSecrets.config">      
      <add key="webpages:Version" value="3.0.0.0" />
      <add key="webpages:Enabled" value="false" />
      <add key="ClientValidationEnabled" value="true" />
      <add key="UnobtrusiveJavaScriptEnabled" value="true" />      
   </appSettings>
  <system.web>

AppSettingsSecrets.config

<appSettings>   
   <!-- SendGrid-->
   <add key="mailAccount" value="My mail account." />
   <add key="mailPassword" value="My mail password." />
   <!-- Twilio-->
   <add key="TwilioSid" value="My Twilio SID." />
   <add key="TwilioToken" value="My Twilio Token." />
   <add key="TwilioFromPhone" value="+12065551234" />

   <add key="GoogClientID" value="1.apps.googleusercontent.com" />
   <add key="GoogClientSecret" value="My Google client secret." />
</appSettings>

How do I properly/securely reference my ID and Secret from the AppSettingsSecrets.config from within the code that is listed in step 7?

www.asp.net/mvc/overview/security/create-an-aspnet-mvc-5-app-with-facebook-and-google-oauth2-and-openid-sign-on#goog

Relevant code is listed below (note the bottom used for Google Authentication):

public void ConfigureAuth(IAppBuilder app)
{
    // Configure the db context and user manager to use a single instance per request
    app.CreatePerOwinContext(ApplicationDbContext.Create);
    app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);

    // Enable the application to use a cookie to store information for the signed in user
    // and to use a cookie to temporarily store information about a user logging in with a third party login provider
    // Configure the sign in cookie
    app.UseCookieAuthentication(new CookieAuthenticationOptions
    {
        AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
        LoginPath = new PathString("/Account/Login"),
        Provider = new CookieAuthenticationProvider
        {
            OnValidateIdentity = SecurityStampValidator.OnValidateIdentity<ApplicationUserManager, ApplicationUser>(
                validateInterval: TimeSpan.FromMinutes(30),
                regenerateIdentity: (manager, user) => user.GenerateUserIdentityAsync(manager))
        }
    });

    app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);

    // Uncomment the following lines to enable logging in with third party login providers
    //app.UseMicrosoftAccountAuthentication(
    //    clientId: "",
    //    clientSecret: "");

    //app.UseTwitterAuthentication(
    //   consumerKey: "",
    //   consumerSecret: "");

    //app.UseFacebookAuthentication(
    //   appId: "",
    //   appSecret: "");

    app.UseGoogleAuthentication(
         clientId: "000-000.apps.googleusercontent.com",
         clientSecret: "00000000000");
}

Additionally in the tutorial for deploying secrets to Azure this information is listed:

When you deploy your web app to Azure, the AppSettingsSecrets.config  file won't be deployed (that's what you want). You could go to the Azure Management Portal and set them manually, to do that:
1.  Go to http://portal.azure.com, and sign in with your Azure credentials.
2.  Click Browse > Web Apps, then click the name of your web app.
3.  Click All settings > Application settings.
The app settings and connection string values override the same settings in the web.config file. In our example, we did not deploy these settings to Azure, but if these keys were in the web.config file, the settings shown on the portal would take precedence.

This tells me that I can manually enter the sensitive information into Azure through the portal and (I’m assuming) this is a secure method of keeping the sensitive credentials private while allowing my web application to access and utilize the information. (Please correct me if I'm wrong!) However, when I manually entered this information, my web application is now throwing a runtime error as shown below as an image link:

Server Runtime Error

Any suggestions, or other links or pointers/tips would be greatly appreciated! Thanks in advance!

EDIT: After turning off the customErrors in the web.config file, and refreshing the Azure deployment this is the error the site now yields - Essentially my code is not pulling the stored Google OAuth2 credentials I've stored in Azure. How do I get my code to pull the credentials stored in Azure for Google OAuth2? NewSiteError

like image 696
jat247 Avatar asked Nov 08 '22 12:11

jat247


1 Answers

First I would turn the customErrors off so you can find the real problem, but my guess is that you aren't including the AppSettingsSecrets.config in your solution. This will cause a problem once deployed because the file isn't there - so you should remove the configSource or file attributes from the config using a web.config transform.

So in the Web.Release.config you can add the following inside the:

<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
...
    <connectionStrings xdt:Transform="RemoveAttributes(configSource)"/>
    <appSettings xdt:Transform="RemoveAttributes(file)"/>

When you do a publish of the release build, this will remove those file paths from the config so it won't fail at startup once deployed.

Update

Now you'll need to add all the appSettings that were in the AppSettingsSecrets.config file to the appSettings in the portal. This will keep your published site credentials only in Azure.

All The appSettings in the Web.config and any other files get merged into the same listing (meaning your code doesn't need to know the appSetting is coming from the web.config, AppSettingsSecrets.config or being configured from the azure portal. Here is a good article on appSettings: https://buildazure.com/2015/11/30/azure-web-app-application-settings/

The good things about your setup is:

  1. the AppSettingsSecrets.config has the secrets needed only for developers and is not included in source control or published
  2. the published site credentials are only in Azure and available to only those with access to the Azure account.
like image 171
Jason Haley Avatar answered Nov 14 '22 21:11

Jason Haley