Browse Source

Merge branch 'release/2.1' into release/2.2

John Luo 7 years ago
parent
commit
8f1eedf5a9

+ 0 - 30
build/AzureIntegration.targets

@@ -1,30 +0,0 @@
-<Project>
-  <PropertyGroup>
-    <AzureIntegrationProjectRoot>$(MSBuildThisFileDirectory)..\modules\AzureIntegration\</AzureIntegrationProjectRoot>
-  </PropertyGroup>
-
-  <Target Name="BuildAzureIntegration" DependsOnTargets="PrepareOutputPaths;GeneratePropsFiles">
-    <PropertyGroup>
-      <AzureIntegrationProjProperties>
-        AspNetUniverseBuildOffline=true;
-        RepositoryRoot=$(AzureIntegrationProjectRoot);
-        DotNetRestoreSourcePropsPath=$(GeneratedRestoreSourcesPropsPath);
-        DotNetPackageVersionPropsPath=$(GeneratedPackageVersionPropsPath);
-        BuildNumber=$(BuildNumber);
-        Configuration=$(Configuration);
-        IsFinalBuild=$(IsFinalBuild);
-      </AzureIntegrationProjProperties>
-    </PropertyGroup>
-
-    <MSBuild Projects="$(MSBuildProjectFullPath)"
-             Targets="$(AzureIntegrationProjectTargets)"
-             Properties="$(AzureIntegrationProjProperties)" />
-
-    <ItemGroup>
-      <AzureIntegrationArtifacts Include="$(AzureIntegrationProjectRoot)artifacts\build\*" />
-    </ItemGroup>
-
-    <Copy SourceFiles="@(AzureIntegrationArtifacts)" DestinationFolder="$(BuildDir)" />
-  </Target>
-
-</Project>

+ 22 - 0
build/SharedFx.targets

@@ -41,6 +41,28 @@
 
   </Target>
 
+  <Target Name="BuildSiteExtension" DependsOnTargets="BuildMetapackages" Condition="'$(BuildSiteExtension)' == 'true'" >
+    <PropertyGroup>
+      <AzureIntegrationProjProperties>
+        AspNetUniverseBuildOffline=true;
+        DotNetRestoreSourcePropsPath=$(GeneratedRestoreSourcesPropsPath);
+        DotNetPackageVersionPropsPath=$(GeneratedPackageVersionPropsPath);
+        BuildNumber=$(BuildNumber);
+        Configuration=$(Configuration);
+        IsFinalBuild=$(IsFinalBuild);
+      </AzureIntegrationProjProperties>
+    </PropertyGroup>
+
+    <!-- Pack logging site extension -->
+    <MSBuild Projects="$(RepositoryRoot)\src\SiteExtensions\LoggingBranch\LoggingBranch.csproj" Targets="Restore;Pack" Properties="$(AzureIntegrationProjProperties);PackageOutputPath=$(BuildDir)" />
+  </Target>
+
+  <Target Name="GetSiteExtensionArtifactInfo" Condition="'$(BuildSiteExtension)' == 'true'" >
+    <MSBuild Projects="$(RepositoryRoot)\src\SiteExtensions\LoggingBranch\LoggingBranch.csproj" Targets="GetArtifactInfo" Properties="PackageOutputPath=$(BuildDir);BuildNumber=$(BuildNumber);DesignTimeBuild=true;IsFinalBuild=$(IsFinalBuild)">
+      <Output TaskParameter="TargetOutputs" ItemName="ArtifactInfo" />
+    </MSBuild>
+  </Target>
+
   <Target Name="_BuildSharedFxProjects" DependsOnTargets="GeneratePropsFiles;ResolveCommitHash">
 
     <PropertyGroup>

+ 1 - 0
build/artifacts.props

@@ -44,6 +44,7 @@
     <PackageArtifact Include="Microsoft.AspNetCore.Authentication" Category="ship" />
     <PackageArtifact Include="Microsoft.AspNetCore.Authorization.Policy" Category="ship" />
     <PackageArtifact Include="Microsoft.AspNetCore.Authorization" Category="ship" />
+    <PackageArtifact Include="Microsoft.AspNetCore.AzureAppServices.SiteExtension.2.2" Category="noship" Condition="'$(BuildSiteExtension)' == 'true'" />
     <PackageArtifact Include="Microsoft.AspNetCore.AzureAppServices.HostingStartup" Category="ship" />
     <PackageArtifact Include="Microsoft.AspNetCore.AzureAppServicesIntegration" Category="ship" />
     <PackageArtifact Include="Microsoft.AspNetCore.Connections.Abstractions" Category="ship" />

+ 3 - 0
build/repo.props

@@ -17,6 +17,9 @@
     <SignedDependencyPackageDir>$(RepositoryRoot).deps\Signed\Packages\</SignedDependencyPackageDir>
     <SignCheckExclusionsFile>$(RepositoryRoot)eng\signcheck.exclusions.txt</SignCheckExclusionsFile>
     <SharedSourcesFolder>$(RepositoryRoot)src\Shared\</SharedSourcesFolder>
+    <SharedFxArchitecture Condition="'$(SharedFxArchitecture)' == ''">$(SharedFxRid.Substring($([MSBuild]::Add($(SharedFxRid.LastIndexOf('-')), 1))))</SharedFxArchitecture>
+    <BuildSiteExtension>false</BuildSiteExtension>
+    <BuildSiteExtension Condition="'$(BuildSiteExtension)' == 'true' AND '$(OS)' != 'Windows_NT'">false</BuildSiteExtension>
   </PropertyGroup>
 
   <ItemGroup>

+ 2 - 3
build/repo.targets

@@ -1,7 +1,6 @@
 <Project>
   <Import Project="RepositoryBuild.targets" />
   <Import Project="PackageArchive.targets" />
-  <Import Project="AzureIntegration.targets" />
   <Import Project="SharedFx.targets" />
   <Import Project="CodeSign.targets" />
   <Import Project="Publish.targets" />
@@ -22,7 +21,7 @@
     <CompileDependsOn>$(CompileDependsOn);BuildProjects;PackSharedSources</CompileDependsOn>
     <CompileDependsOn Condition="'$(_ProjectsOnly)' != 'true'">$(CompileDependsOn);PackProjects;BuildRepositories;BuildSharedFx</CompileDependsOn>
     <PackageDependsOn Condition=" '$(_ProjectsOnly)' == 'true'">$(PackageDependsOn);PackProjects</PackageDependsOn>
-    <PackageDependsOn Condition="'$(TestOnly)' != 'true' AND '$(_ProjectsOnly)' != 'true'">$(PackageDependsOn);CheckExpectedPackagesExist</PackageDependsOn>
+    <PackageDependsOn Condition="'$(TestOnly)' != 'true' AND '$(_ProjectsOnly)' != 'true'">$(PackageDependsOn);BuildSiteExtension;CheckExpectedPackagesExist</PackageDependsOn>
     <PackageDependsOn Condition="'$(TestOnly)' != 'true'">$(PackageDependsOn);CodeSign</PackageDependsOn>
     <TestDependsOn>$(TestDependsOn);TestProjects</TestDependsOn>
     <TestDependsOn Condition="'$(_ProjectsOnly)' != 'true'">$(TestDependsOn);_TestRepositories</TestDependsOn>
@@ -73,7 +72,7 @@
     </ItemGroup>
   </Target>
 
-  <Target Name="ResolveRepoInfo" DependsOnTargets="_ResolveProjectArtifactsInfoShipped;_PrepareRepositories">
+  <Target Name="ResolveRepoInfo" DependsOnTargets="_ResolveProjectArtifactsInfoShipped;_PrepareRepositories;GetSiteExtensionArtifactInfo">
     <!-- We need to pass the NETCoreApp package versions to msbuild so that it doesn't complain about us using a different one than it was restored against.  -->
     <PropertyGroup>
       <DesignTimeBuildProps>$(BuildProperties);MicrosoftNETCoreAppPackageVersion=$(MicrosoftNETCoreAppPackageVersion);</DesignTimeBuildProps>

+ 1 - 0
eng/PatchConfig.props

@@ -28,6 +28,7 @@ Later on, this will be checked using this condition:
   <PropertyGroup Condition=" '$(VersionPrefix)' == '2.2.2' ">
     <PackagesInPatch>
       @aspnet/signalr;
+      Microsoft.AspNetCore.Authentication.Google;
     </PackagesInPatch>
   </PropertyGroup>
 

+ 25 - 4
src/Razor/Razor.Design/test/IntegrationTests/Microsoft.AspNetCore.Razor.Design.Test.csproj

@@ -13,12 +13,10 @@
     <!-- Copy references locally so that we can use them in the test. -->
     <CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
     <BuildVariablesGeneratedFile>$(MSBuildProjectDirectory)\obj\BuildVariables.generated.cs</BuildVariablesGeneratedFile>
-    <CompileDependsOn>EnsureBuildVariablesGeneratedFile;$(CompileDependsOn)</CompileDependsOn>
   </PropertyGroup>
 
   <ItemGroup>
     <None Include="xunit.runner.json" CopyToOutputDirectory="PreserveNewest" />
-    <Compile Include="$(BuildVariablesGeneratedFile)" Condition="Exists('$(BuildVariablesGeneratedFile)')" />
   </ItemGroup>
 
   <!-- The test projects rely on these binaries being available -->
@@ -43,8 +41,31 @@
     <Reference Include="Microsoft.AspNetCore.Razor.Test.MvcShim.ClassLib" />
   </ItemGroup>
 
-  <Target Name="EnsureBuildVariablesGeneratedFile">
-    <Error Text="BuildVariables.generated.cs was not found. Run .\build /t:Prepare from the root of the repository to generate it." Condition="!Exists('$(BuildVariablesGeneratedFile)')" />
+  <Target Name="GenerateBuildVariablesFile" BeforeTargets="BeforeBuild">
+    <Warning Text="Some SDK tests on Windows require the project to be built once using Desktop MSBuild, but the current build is executed using .NET Core MSBuild. This may result in test failures."
+        Condition="!Exists('$(BuildVariablesGeneratedFile)') and '$(MSBuildRuntimeType)' != 'Full' and '$(OS)' == 'Windows_NT'" />
+
+    <PropertyGroup>
+      <GeneratedFileContents>
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests
+{
+    internal static partial class BuildVariables
+    {
+        static partial void InitializeVariables()
+        {
+            _msBuildPath = @"$(MSBuildBinPath)\MSBuild.exe"%3B
+        }
+    }
+}
+      </GeneratedFileContents>
+    </PropertyGroup>
+    <WriteLinesToFile Lines="$(GeneratedFileContents)" File="$(BuildVariablesGeneratedFile)" Overwrite="true" WriteOnlyWhenDifferent="true" Condition="'$(MSBuildRuntimeType)' == 'Full'" />
+    <ItemGroup>
+      <Compile Include="$(BuildVariablesGeneratedFile)"  Condition="Exists('$(BuildVariablesGeneratedFile)')" />
+    </ItemGroup>
   </Target>
 
 </Project>

+ 20 - 2
src/Security/Authentication/Google/src/GoogleDefaults.cs

@@ -1,6 +1,8 @@
 // Copyright (c) .NET Foundation. All rights reserved.
 // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
 
+using System;
+
 namespace Microsoft.AspNetCore.Authentication.Google
 {
     /// <summary>
@@ -17,7 +19,23 @@ namespace Microsoft.AspNetCore.Authentication.Google
 
         public static readonly string TokenEndpoint = "https://www.googleapis.com/oauth2/v4/token";
 
-        // https://developers.google.com/+/web/people/
-        public static readonly string UserInformationEndpoint = "https://www.googleapis.com/plus/v1/people/me";
+        public static readonly string UserInformationEndpoint;
+
+        private const string UseGooglePlusSwitch = "Switch.Microsoft.AspNetCore.Authentication.Google.UsePlus";
+
+        internal static readonly bool UseGooglePlus;
+
+        static GoogleDefaults()
+        {
+            if (AppContext.TryGetSwitch(UseGooglePlusSwitch, out UseGooglePlus) && UseGooglePlus)
+            {
+                // https://developers.google.com/+/web/people/
+                UserInformationEndpoint = "https://www.googleapis.com/plus/v1/people/me";
+            }
+            else
+            {
+                UserInformationEndpoint = "https://www.googleapis.com/oauth2/v2/userinfo";
+            }
+        }
     }
 }

+ 17 - 7
src/Security/Authentication/Google/src/GoogleOptions.cs

@@ -2,7 +2,6 @@
 // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
 
 using System.Security.Claims;
-using Microsoft.AspNetCore.Authentication;
 using Microsoft.AspNetCore.Authentication.OAuth;
 using Microsoft.AspNetCore.Http;
 
@@ -27,11 +26,22 @@ namespace Microsoft.AspNetCore.Authentication.Google
             Scope.Add("email");
 
             ClaimActions.MapJsonKey(ClaimTypes.NameIdentifier, "id");
-            ClaimActions.MapJsonKey(ClaimTypes.Name, "displayName");
-            ClaimActions.MapJsonSubKey(ClaimTypes.GivenName, "name", "givenName");
-            ClaimActions.MapJsonSubKey(ClaimTypes.Surname, "name", "familyName");
-            ClaimActions.MapJsonKey("urn:google:profile", "url");
-            ClaimActions.MapCustomJson(ClaimTypes.Email, GoogleHelper.GetEmail);
+            if (GoogleDefaults.UseGooglePlus)
+            {
+                ClaimActions.MapJsonKey(ClaimTypes.Name, "displayName");
+                ClaimActions.MapJsonSubKey(ClaimTypes.GivenName, "name", "givenName");
+                ClaimActions.MapJsonSubKey(ClaimTypes.Surname, "name", "familyName");
+                ClaimActions.MapJsonKey("urn:google:profile", "url");
+                ClaimActions.MapCustomJson(ClaimTypes.Email, GoogleHelper.GetEmail);
+            }
+            else
+            {
+                ClaimActions.MapJsonKey(ClaimTypes.Name, "name");
+                ClaimActions.MapJsonKey(ClaimTypes.GivenName, "given_name");
+                ClaimActions.MapJsonKey(ClaimTypes.Surname, "family_name");
+                ClaimActions.MapJsonKey("urn:google:profile", "link");
+                ClaimActions.MapJsonKey(ClaimTypes.Email, "email");
+            }
         }
 
         /// <summary>
@@ -39,4 +49,4 @@ namespace Microsoft.AspNetCore.Authentication.Google
         /// </summary>
         public string AccessType { get; set; }
     }
-}
+}

+ 12 - 176
src/Security/Authentication/test/GoogleTests.cs

@@ -809,45 +809,7 @@ namespace Microsoft.AspNetCore.Authentication.Google
                 {
                     o.ClaimsIssuer = claimsIssuer;
                 }
-                o.BackchannelHttpHandler = new TestHttpMessageHandler
-                {
-                    Sender = req =>
-                    {
-                        if (req.RequestUri.AbsoluteUri == "https://www.googleapis.com/oauth2/v4/token")
-                        {
-                            return ReturnJsonResponse(new
-                            {
-                                access_token = "Test Access Token",
-                                expires_in = 3600,
-                                token_type = "Bearer"
-                            });
-                        }
-                        else if (req.RequestUri.GetComponents(UriComponents.SchemeAndServer | UriComponents.Path, UriFormat.UriEscaped) == "https://www.googleapis.com/plus/v1/people/me")
-                        {
-                            return ReturnJsonResponse(new
-                            {
-                                id = "Test User ID",
-                                displayName = "Test Name",
-                                name = new
-                                {
-                                    familyName = "Test Family Name",
-                                    givenName = "Test Given Name"
-                                },
-                                url = "Profile link",
-                                emails = new[]
-                                {
-                                    new
-                                    {
-                                        value = "Test email",
-                                        type = "account"
-                                    }
-                                }
-                            });
-                        }
-
-                        throw new NotImplementedException(req.RequestUri.AbsoluteUri);
-                    }
-                };
+                o.BackchannelHttpHandler = CreateBackchannel();
             });
 
             var properties = new AuthenticationProperties();
@@ -999,46 +961,7 @@ namespace Microsoft.AspNetCore.Authentication.Google
                 o.ClientId = "Test Id";
                 o.ClientSecret = "Test Secret";
                 o.StateDataFormat = stateFormat;
-                o.BackchannelHttpHandler = new TestHttpMessageHandler
-                {
-                    Sender = req =>
-                    {
-                        if (req.RequestUri.AbsoluteUri == "https://www.googleapis.com/oauth2/v4/token")
-                        {
-                            return ReturnJsonResponse(new
-                            {
-                                access_token = "Test Access Token",
-                                expires_in = 3600,
-                                token_type = "Bearer",
-                                refresh_token = "Test Refresh Token"
-                            });
-                        }
-                        else if (req.RequestUri.GetComponents(UriComponents.SchemeAndServer | UriComponents.Path, UriFormat.UriEscaped) == "https://www.googleapis.com/plus/v1/people/me")
-                        {
-                            return ReturnJsonResponse(new
-                            {
-                                id = "Test User ID",
-                                displayName = "Test Name",
-                                name = new
-                                {
-                                    familyName = "Test Family Name",
-                                    givenName = "Test Given Name"
-                                },
-                                url = "Profile link",
-                                emails = new[]
-                                    {
-                                        new
-                                        {
-                                            value = "Test email",
-                                            type = "account"
-                                        }
-                                    }
-                            });
-                        }
-
-                        throw new NotImplementedException(req.RequestUri.AbsoluteUri);
-                    }
-                };
+                o.BackchannelHttpHandler = CreateBackchannel();
                 o.Events = new OAuthEvents
                 {
                     OnCreatingTicket = context =>
@@ -1079,46 +1002,7 @@ namespace Microsoft.AspNetCore.Authentication.Google
                 o.ClientId = "Test Id";
                 o.ClientSecret = "Test Secret";
                 o.StateDataFormat = stateFormat;
-                o.BackchannelHttpHandler = new TestHttpMessageHandler
-                {
-                    Sender = req =>
-                    {
-                        if (req.RequestUri.AbsoluteUri == "https://www.googleapis.com/oauth2/v4/token")
-                        {
-                            return ReturnJsonResponse(new
-                            {
-                                access_token = "Test Access Token",
-                                expires_in = 3600,
-                                token_type = "Bearer",
-                                refresh_token = "Test Refresh Token"
-                            });
-                        }
-                        else if (req.RequestUri.GetComponents(UriComponents.SchemeAndServer | UriComponents.Path, UriFormat.UriEscaped) == "https://www.googleapis.com/plus/v1/people/me")
-                        {
-                            return ReturnJsonResponse(new
-                            {
-                                id = "Test User ID",
-                                displayName = "Test Name",
-                                name = new
-                                {
-                                    familyName = "Test Family Name",
-                                    givenName = "Test Given Name"
-                                },
-                                url = "Profile link",
-                                emails = new[]
-                                    {
-                                        new
-                                        {
-                                            value = "Test email",
-                                            type = "account"
-                                        }
-                                    }
-                            });
-                        }
-
-                        throw new NotImplementedException(req.RequestUri.AbsoluteUri);
-                    }
-                };
+                o.BackchannelHttpHandler = CreateBackchannel();
                 o.Events = new OAuthEvents
                 {
                     OnTicketReceived = context =>
@@ -1169,46 +1053,7 @@ namespace Microsoft.AspNetCore.Authentication.Google
                         return Task.FromResult(0);
                     }
                 };
-                o.BackchannelHttpHandler = new TestHttpMessageHandler
-                {
-                    Sender = req =>
-                    {
-                        if (req.RequestUri.AbsoluteUri == "https://www.googleapis.com/oauth2/v4/token")
-                        {
-                            return ReturnJsonResponse(new
-                            {
-                                access_token = "Test Access Token",
-                                expires_in = 3600,
-                                token_type = "Bearer",
-                                refresh_token = "Test Refresh Token"
-                            });
-                        }
-                        else if (req.RequestUri.GetComponents(UriComponents.SchemeAndServer | UriComponents.Path, UriFormat.UriEscaped) == "https://www.googleapis.com/plus/v1/people/me")
-                        {
-                            return ReturnJsonResponse(new
-                            {
-                                id = "Test User ID",
-                                displayName = "Test Name",
-                                name = new
-                                {
-                                    familyName = "Test Family Name",
-                                    givenName = "Test Given Name"
-                                },
-                                url = "Profile link",
-                                emails = new[]
-                                    {
-                                        new
-                                        {
-                                            value = "Test email",
-                                            type = "account"
-                                        }
-                                    }
-                            });
-                        }
-
-                        throw new NotImplementedException(req.RequestUri.AbsoluteUri);
-                    }
-                };
+                o.BackchannelHttpHandler = CreateBackchannel();
             });
 
             var properties = new AuthenticationProperties();
@@ -1439,29 +1284,20 @@ namespace Microsoft.AspNetCore.Authentication.Google
                         {
                             access_token = "Test Access Token",
                             expires_in = 3600,
-                            token_type = "Bearer"
+                            token_type = "Bearer",
+                            refresh_token = "Test Refresh Token"
                         });
                     }
-                    else if (req.RequestUri.GetComponents(UriComponents.SchemeAndServer | UriComponents.Path, UriFormat.UriEscaped) == "https://www.googleapis.com/plus/v1/people/me")
+                    else if (req.RequestUri.GetComponents(UriComponents.SchemeAndServer | UriComponents.Path, UriFormat.UriEscaped) == "https://www.googleapis.com/oauth2/v2/userinfo")
                     {
                         return ReturnJsonResponse(new
                         {
                             id = "Test User ID",
-                            displayName = "Test Name",
-                            name = new
-                            {
-                                familyName = "Test Family Name",
-                                givenName = "Test Given Name"
-                            },
-                            url = "Profile link",
-                            emails = new[]
-                            {
-                                new
-                                {
-                                    value = "Test email",
-                                    type = "account"
-                                }
-                            }
+                            name = "Test Name",
+                            given_name = "Test Given Name",
+                            family_name = "Test Family Name",
+                            link = "Profile link",
+                            email = "Test email",
                         });
                     }
 

+ 7 - 7
src/Security/Security.sln

@@ -96,12 +96,12 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Diagno
 EndProject
 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.StaticFiles", "..\Middleware\StaticFiles\src\Microsoft.AspNetCore.StaticFiles.csproj", "{6FFBD7CD-2B7D-4EC9-8D18-54E53F852B04}"
 EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Server.IISIntegration", "..\Servers\IIS\IISIntegration\src\Microsoft.AspNetCore.Server.IISIntegration.csproj", "{43AF597A-FCB8-41A5-8279-345FEE9A61AD}"
-EndProject
 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Server.Kestrel", "..\Servers\Kestrel\Kestrel\src\Microsoft.AspNetCore.Server.Kestrel.csproj", "{707CBFB4-4D35-479E-9BAF-39B4DA9782DE}"
 EndProject
 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Server.Kestrel.Https", "..\Servers\Kestrel\Https\src\Microsoft.AspNetCore.Server.Kestrel.Https.csproj", "{AFE880E8-2E9E-46FD-BE87-DFC8192E7B2D}"
 EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Server.IISIntegration", "..\Servers\IIS\IISIntegration\src\Microsoft.AspNetCore.Server.IISIntegration.csproj", "{81D0E81F-4711-4C7B-BBD4-E168102D0D7D}"
+EndProject
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
 		Debug|Any CPU = Debug|Any CPU
@@ -236,10 +236,6 @@ Global
 		{6FFBD7CD-2B7D-4EC9-8D18-54E53F852B04}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{6FFBD7CD-2B7D-4EC9-8D18-54E53F852B04}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{6FFBD7CD-2B7D-4EC9-8D18-54E53F852B04}.Release|Any CPU.Build.0 = Release|Any CPU
-		{43AF597A-FCB8-41A5-8279-345FEE9A61AD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
-		{43AF597A-FCB8-41A5-8279-345FEE9A61AD}.Debug|Any CPU.Build.0 = Debug|Any CPU
-		{43AF597A-FCB8-41A5-8279-345FEE9A61AD}.Release|Any CPU.ActiveCfg = Release|Any CPU
-		{43AF597A-FCB8-41A5-8279-345FEE9A61AD}.Release|Any CPU.Build.0 = Release|Any CPU
 		{707CBFB4-4D35-479E-9BAF-39B4DA9782DE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
 		{707CBFB4-4D35-479E-9BAF-39B4DA9782DE}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{707CBFB4-4D35-479E-9BAF-39B4DA9782DE}.Release|Any CPU.ActiveCfg = Release|Any CPU
@@ -248,6 +244,10 @@ Global
 		{AFE880E8-2E9E-46FD-BE87-DFC8192E7B2D}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{AFE880E8-2E9E-46FD-BE87-DFC8192E7B2D}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{AFE880E8-2E9E-46FD-BE87-DFC8192E7B2D}.Release|Any CPU.Build.0 = Release|Any CPU
+		{81D0E81F-4711-4C7B-BBD4-E168102D0D7D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{81D0E81F-4711-4C7B-BBD4-E168102D0D7D}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{81D0E81F-4711-4C7B-BBD4-E168102D0D7D}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{81D0E81F-4711-4C7B-BBD4-E168102D0D7D}.Release|Any CPU.Build.0 = Release|Any CPU
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
 		HideSolutionNode = FALSE
@@ -295,9 +295,9 @@ Global
 		{B6CA96E4-674A-4616-9A38-DED07BE458E1} = {A3766414-EB5C-40F7-B031-121804ED5D0A}
 		{54CBBAED-36D5-4855-BB4E-D1AE3523AA23} = {A3766414-EB5C-40F7-B031-121804ED5D0A}
 		{6FFBD7CD-2B7D-4EC9-8D18-54E53F852B04} = {A3766414-EB5C-40F7-B031-121804ED5D0A}
-		{43AF597A-FCB8-41A5-8279-345FEE9A61AD} = {A3766414-EB5C-40F7-B031-121804ED5D0A}
 		{707CBFB4-4D35-479E-9BAF-39B4DA9782DE} = {A3766414-EB5C-40F7-B031-121804ED5D0A}
 		{AFE880E8-2E9E-46FD-BE87-DFC8192E7B2D} = {A3766414-EB5C-40F7-B031-121804ED5D0A}
+		{81D0E81F-4711-4C7B-BBD4-E168102D0D7D} = {A3766414-EB5C-40F7-B031-121804ED5D0A}
 	EndGlobalSection
 	GlobalSection(ExtensibilityGlobals) = postSolution
 		SolutionGuid = {ABF8089E-43D0-4010-84A7-7A9DCFE49357}

+ 33 - 0
src/SiteExtensions/LoggingBranch/Directory.Build.targets

@@ -0,0 +1,33 @@
+<Project>
+
+  <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory)..\, Directory.Build.targets))\Directory.Build.targets" />
+
+  <Import Project="..\Sdk\SiteExtension.targets" />
+
+  <PropertyGroup>
+    <!-- There is no build output -->
+    <IncludeBuildOutput>false</IncludeBuildOutput>
+    <!-- There are no symbols. -->
+    <IncludeSymbols>false</IncludeSymbols>
+    <!-- There is no API to check -->
+    <EnableApiCheck>false</EnableApiCheck>
+    <!-- Manually control dependencies -->
+    <DisableImplicitFrameworkReferences>true</DisableImplicitFrameworkReferences>
+    <!-- There is no documentation  -->
+    <GenerateDocumentationFile>false</GenerateDocumentationFile>
+    <!-- There is no documentation  -->
+    <RunPackageAnalysis>false</RunPackageAnalysis>
+    <GenerateAssemblyInfo>false</GenerateAssemblyInfo>
+  </PropertyGroup>
+
+  <Target Name="GetArtifactInfo" Returns="@(ArtifactInfo)">
+    <ItemGroup>
+      <ArtifactInfo Include="$(TargetPath)">
+        <ArtifactType>NuGetPackage</ArtifactType>
+        <PackageId>$(PackageId)</PackageId>
+        <Version>$(PackageVersion)</Version>
+      </ArtifactInfo>
+    </ItemGroup>
+  </Target>
+
+</Project>

+ 33 - 0
src/SiteExtensions/LoggingBranch/LoggingBranch.csproj

@@ -0,0 +1,33 @@
+<Project Sdk="Microsoft.NET.Sdk">
+
+  <PropertyGroup>
+    <TrimmedVersion>$(AspNetCoreMajorVersion).$(AspNetCoreMinorVersion)</TrimmedVersion>
+    <title>ASP.NET Core Extensions</title>
+    <Description>This extension enables additional functionality for ASP.NET Core on Azure WebSites, such as enabling Azure logging.</Description>
+    <TargetFramework>net461</TargetFramework>
+    <GenerateDocumentationFile>false</GenerateDocumentationFile>
+    <PackageTags>aspnet;logging;aspnetcore;AzureSiteExtension;keyvault;configuration;dataprotection</PackageTags>
+    <ContentTargetFolders>content</ContentTargetFolders>
+    <PackageId>Microsoft.AspNetCore.AzureAppServices.SiteExtension.$(TrimmedVersion)</PackageId>
+    <MicrosoftAspNetCoreAppPackageVersion>$(PackageVersion)</MicrosoftAspNetCoreAppPackageVersion>
+    <HostingStartupRuntimeFrameworkVersion>$(MicrosoftNETCoreApp21PackageVersion)</HostingStartupRuntimeFrameworkVersion>
+    <TargetFramework>net461</TargetFramework>
+    <GenerateDocumentationFile>false</GenerateDocumentationFile>
+    <PackageType>AzureSiteExtension</PackageType>
+    <NoPackageAnalysis>true</NoPackageAnalysis>
+    <IncludeBuildOutput>false</IncludeBuildOutput>
+    <IncludeSymbols>false</IncludeSymbols>
+    <IncludeSource>false</IncludeSource>
+    <ContentTargetFolders>content</ContentTargetFolders>
+    <IsPackageInThisPatch>true</IsPackageInThisPatch>
+  </PropertyGroup>
+
+  <ItemGroup>
+    <HostingStartupRuntimeStoreTargets Include="netcoreapp2.1" Runtime="win7-x64" />
+    <HostingStartupRuntimeStoreTargets Include="netcoreapp2.1" Runtime="win7-x86" />
+    <HostingStartupPackageReference Include="Microsoft.AspNetCore.AzureAppServices.HostingStartup" Version="$(PackageVersion)" />
+
+    <PackageReference Include="Internal.AspNetCore.Sdk" PrivateAssets="All" Version="$(InternalAspNetCoreSdkPackageVersion)" />
+  </ItemGroup>
+
+</Project>

+ 13 - 0
src/SiteExtensions/Sdk/HostingStartup/HostingStartup.csproj

@@ -0,0 +1,13 @@
+<Project Sdk="Microsoft.NET.Sdk">
+
+  <PropertyGroup>
+    <TargetFramework>netcoreapp2.1</TargetFramework>
+    <OutputType>Exe</OutputType>
+  </PropertyGroup>
+
+  <ItemGroup>
+    <PackageReference Include="Microsoft.AspNetCore.App" Version="$(MicrosoftAspNetCoreAppPackageVersion)" PrivateAssets="None" />
+    <PackageReference Include="$(HostingStartupPackageName)" Version="$(HostingStartupPackageVersion)" PrivateAssets="None" />
+  </ItemGroup>
+
+</Project>

+ 7 - 0
src/SiteExtensions/Sdk/HostingStartup/Program.cs

@@ -0,0 +1,7 @@
+// Copyright (c) .NET Foundation and contributors. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+public class Program
+{
+    public static void Main() { }
+}

+ 86 - 0
src/SiteExtensions/Sdk/SiteExtension.targets

@@ -0,0 +1,86 @@
+<!--
+  This file is automatically imported by NuGet into a user's project
+  when it targets a single framework, or in classic (pre 2017) csproj projects.
+-->
+
+<Project>
+  <Target Name="GenerateHostingStartupDeps" Condition="'@(HostingStartupPackageReference->Count())' != '0'" BeforeTargets="_GetPackageFiles" >
+
+    <PropertyGroup>
+      <_TemplatesDirectory>$(MSBuildThisFileDirectory)..\content\</_TemplatesDirectory>
+      <_DepsOutputDirectory>$(RepositoryRoot).w\se\</_DepsOutputDirectory>
+      <_WorkingDirectory>$(_DepsOutputDirectory)\depswork</_WorkingDirectory>
+      <_BasePackagePath>content\additionaldeps\</_BasePackagePath>
+      <_RuntimeStoreManifestFile>$(_DepsOutputDirectory)\rs.csproj</_RuntimeStoreManifestFile>
+      <_RuntimeStoreOutput>$(_DepsOutputDirectory)\rs\</_RuntimeStoreOutput>
+      <ManifestFileContents>
+      <![CDATA[
+<Project Sdk="Microsoft.NET.Sdk">
+  <ItemGroup>
+    <PackageReference Remove="Internal.AspNetCore.Sdk" />
+    <PackageReference Include="Microsoft.AspNetCore.App" Version="$(MicrosoftAspNetCoreAppPackageVersion)" IsImplicitlyDefined="true"/>
+    <PackageReference Include="%(HostingStartupPackageReference.Identity)" Version="%(HostingStartupPackageReference.Version)" />
+  </ItemGroup>
+</Project>
+      ]]>
+      </ManifestFileContents>
+    </PropertyGroup>
+
+    <ItemGroup>
+      <_TemplateFiles Include="$(MSBuildThisFileDirectory)\HostingStartup\*.cs*" />
+      <_HostingStartupPackageReference
+        Include="%(HostingStartupPackageReference.Identity)"
+        Source="%(HostingStartupPackageReference.Source)"
+        Version="%(HostingStartupPackageReference.Version)"
+        WorkingDirectory="$(_DepsOutputDirectory)%(HostingStartupPackageReference.Identity)"
+        Project="$(_DepsOutputDirectory)%(HostingStartupPackageReference.Identity)\HostingStartup.csproj"
+        DepsFile="$(_DepsOutputDirectory)%(HostingStartupPackageReference.Identity)\p\HostingStartup.deps.json"
+        TrimmedDepsFile="$(_DepsOutputDirectory)%(HostingStartupPackageReference.Identity)\%(HostingStartupPackageReference.Identity).deps.json"
+        PackagePath="$(_BasePackagePath)%(HostingStartupPackageReference.Identity)\shared\Microsoft.AspNetCore.App\$(MicrosoftAspNetCoreAppPackageVersion)\"
+         />
+    </ItemGroup>
+    <MakeDir Directories="$(_DepsOutputDirectory)" />
+
+    <!-- Generate runtime store -->
+    <WriteLinesToFile File="$(_RuntimeStoreManifestFile)" Lines="$(ManifestFileContents)" Overwrite="true" Encoding="Unicode"/>
+
+    <PropertyGroup>
+      <_CommonProperties>
+        AspNetUniverseBuildOffline=true;
+        DotNetRestoreSourcePropsPath=$(DotNetRestoreSourcePropsPath);
+        DotNetPackageVersionPropsPath=$(DotNetPackageVersionPropsPath);
+        BuildNumber=$(BuildNumber);
+        Configuration=$(Configuration);
+        IsFinalBuild=$(IsFinalBuild);
+        MicrosoftAspNetCoreAppPackageVersion=$(MicrosoftAspNetCoreAppPackageVersion);
+        RuntimeFrameworkVersion=$(HostingStartupRuntimeFrameworkVersion);
+      </_CommonProperties>
+    </PropertyGroup>
+
+    <MSBuild Projects="$(_RuntimeStoreManifestFile)"
+             Targets="ComposeStore"
+             Properties="TargetFramework=%(HostingStartupRuntimeStoreTargets.Identity);RuntimeIdentifier=%(HostingStartupRuntimeStoreTargets.Runtime);ComposeDir=$(_RuntimeStoreOutput)\%(HostingStartupRuntimeStoreTargets.Runtime);SkipOptimization=true;$(_CommonProperties)" />
+    <!-- Generate deps -->
+    <RemoveDir Directories="%(_HostingStartupPackageReference.WorkingDirectory)" />
+
+    <Copy SourceFiles="@(_TemplateFiles)" DestinationFolder="%(_HostingStartupPackageReference.WorkingDirectory)" />
+
+    <MSBuild Projects="%(_HostingStartupPackageReference.Project)"
+             Targets="Restore"
+             Properties="HostingStartupPackageName=%(_HostingStartupPackageReference.Identity);HostingStartupPackageVersion=%(_HostingStartupPackageReference.Version);UseAppHost=false;NoBuild=false;$(_CommonProperties)" />
+
+    <MSBuild Projects="%(_HostingStartupPackageReference.Project)"
+             Targets="Publish"
+             Properties="PublishDir=%(_HostingStartupPackageReference.WorkingDirectory)\p;HostingStartupPackageName=%(_HostingStartupPackageReference.Identity);HostingStartupPackageVersion=%(_HostingStartupPackageReference.Version);UseAppHost=false;NoBuild=false;IncludeMainProjectInDepsFile=false;$(_CommonProperties)" />
+    <Copy SourceFiles="%(_HostingStartupPackageReference.DepsFile)" DestinationFiles="%(_HostingStartupPackageReference.TrimmedDepsFile)" />
+
+    <ItemGroup>
+      <_RuntimeStoreFiles Include="$(_RuntimeStoreOutput)\%(HostingStartupRuntimeStoreTargets.Runtime)\**\*.dll" />
+
+      <Content Include="%(_RuntimeStoreFiles.Identity)" PackagePath="content\store\%(RecursiveDir)" />
+      <Content Include="%(_HostingStartupPackageReference.TrimmedDepsFile)" PackagePath="%(_HostingStartupPackageReference.PackagePath)" />
+    </ItemGroup>
+
+  </Target>
+
+</Project>