Retarget to netstandard2.0 and net461
This commit is contained in:
parent
769da5fd87
commit
30392a1811
48
Security.sln
48
Security.sln
|
|
@ -1,6 +1,6 @@
|
|||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 15
|
||||
VisualStudioVersion = 15.0.26403.7
|
||||
VisualStudioVersion = 15.0.26510.0
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{4D2B6A51-2F9F-44F5-8131-EA5CAC053652}"
|
||||
EndProject
|
||||
|
|
@ -46,10 +46,22 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Authen
|
|||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "JwtBearerSample", "samples\JwtBearerSample\JwtBearerSample.csproj", "{D399B84F-591B-4E98-92BA-B0F63E7B6957}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Owin.Security.Interop", "src\Microsoft.Owin.Security.Interop\Microsoft.Owin.Security.Interop.csproj", "{A7922DD8-09F1-43E4-938B-CC523EA08898}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Owin.Security.Interop.Test", "test\Microsoft.Owin.Security.Interop.Test\Microsoft.Owin.Security.Interop.Test.csproj", "{A2B5DC39-68D5-4145-A8CC-6AEAB7D33A24}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenIdConnect.AzureAdSample", "samples\OpenIdConnect.AzureAdSample\OpenIdConnect.AzureAdSample.csproj", "{3A7AD414-EBDE-4F92-B307-4E8F19B6117E}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.ChunkingCookieManager.Sources.Test", "test\Microsoft.AspNetCore.ChunkingCookieManager.Sources.Test\Microsoft.AspNetCore.ChunkingCookieManager.Sources.Test.csproj", "{51563775-C659-4907-9BAF-9995BAB87D01}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{86BD08B1-F978-4F58-9982-2A017807F01C}"
|
||||
ProjectSection(SolutionItems) = preProject
|
||||
build\common.props = build\common.props
|
||||
build\dependencies.props = build\dependencies.props
|
||||
build\Key.snk = build\Key.snk
|
||||
build\repo.props = build\repo.props
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
|
|
@ -360,6 +372,38 @@ Global
|
|||
{D399B84F-591B-4E98-92BA-B0F63E7B6957}.Release|x64.Build.0 = Release|Any CPU
|
||||
{D399B84F-591B-4E98-92BA-B0F63E7B6957}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{D399B84F-591B-4E98-92BA-B0F63E7B6957}.Release|x86.Build.0 = Release|Any CPU
|
||||
{A7922DD8-09F1-43E4-938B-CC523EA08898}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{A7922DD8-09F1-43E4-938B-CC523EA08898}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{A7922DD8-09F1-43E4-938B-CC523EA08898}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
|
||||
{A7922DD8-09F1-43E4-938B-CC523EA08898}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
|
||||
{A7922DD8-09F1-43E4-938B-CC523EA08898}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{A7922DD8-09F1-43E4-938B-CC523EA08898}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{A7922DD8-09F1-43E4-938B-CC523EA08898}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{A7922DD8-09F1-43E4-938B-CC523EA08898}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{A7922DD8-09F1-43E4-938B-CC523EA08898}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{A7922DD8-09F1-43E4-938B-CC523EA08898}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{A7922DD8-09F1-43E4-938B-CC523EA08898}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
|
||||
{A7922DD8-09F1-43E4-938B-CC523EA08898}.Release|Mixed Platforms.Build.0 = Release|Any CPU
|
||||
{A7922DD8-09F1-43E4-938B-CC523EA08898}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{A7922DD8-09F1-43E4-938B-CC523EA08898}.Release|x64.Build.0 = Release|Any CPU
|
||||
{A7922DD8-09F1-43E4-938B-CC523EA08898}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{A7922DD8-09F1-43E4-938B-CC523EA08898}.Release|x86.Build.0 = Release|Any CPU
|
||||
{A2B5DC39-68D5-4145-A8CC-6AEAB7D33A24}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{A2B5DC39-68D5-4145-A8CC-6AEAB7D33A24}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{A2B5DC39-68D5-4145-A8CC-6AEAB7D33A24}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
|
||||
{A2B5DC39-68D5-4145-A8CC-6AEAB7D33A24}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
|
||||
{A2B5DC39-68D5-4145-A8CC-6AEAB7D33A24}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{A2B5DC39-68D5-4145-A8CC-6AEAB7D33A24}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{A2B5DC39-68D5-4145-A8CC-6AEAB7D33A24}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{A2B5DC39-68D5-4145-A8CC-6AEAB7D33A24}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{A2B5DC39-68D5-4145-A8CC-6AEAB7D33A24}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{A2B5DC39-68D5-4145-A8CC-6AEAB7D33A24}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{A2B5DC39-68D5-4145-A8CC-6AEAB7D33A24}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
|
||||
{A2B5DC39-68D5-4145-A8CC-6AEAB7D33A24}.Release|Mixed Platforms.Build.0 = Release|Any CPU
|
||||
{A2B5DC39-68D5-4145-A8CC-6AEAB7D33A24}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{A2B5DC39-68D5-4145-A8CC-6AEAB7D33A24}.Release|x64.Build.0 = Release|Any CPU
|
||||
{A2B5DC39-68D5-4145-A8CC-6AEAB7D33A24}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{A2B5DC39-68D5-4145-A8CC-6AEAB7D33A24}.Release|x86.Build.0 = Release|Any CPU
|
||||
{3A7AD414-EBDE-4F92-B307-4E8F19B6117E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{3A7AD414-EBDE-4F92-B307-4E8F19B6117E}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{3A7AD414-EBDE-4F92-B307-4E8F19B6117E}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
|
||||
|
|
@ -416,6 +460,8 @@ Global
|
|||
{1790E052-646F-4529-B90E-6FEA95520D69} = {7BF11F3A-60B6-4796-B504-579C67FFBA34}
|
||||
{2755BFE5-7421-4A31-A644-F817DF5CAA98} = {4D2B6A51-2F9F-44F5-8131-EA5CAC053652}
|
||||
{D399B84F-591B-4E98-92BA-B0F63E7B6957} = {F8C0AA27-F3FB-4286-8E4C-47EF86B539FF}
|
||||
{A7922DD8-09F1-43E4-938B-CC523EA08898} = {4D2B6A51-2F9F-44F5-8131-EA5CAC053652}
|
||||
{A2B5DC39-68D5-4145-A8CC-6AEAB7D33A24} = {7BF11F3A-60B6-4796-B504-579C67FFBA34}
|
||||
{3A7AD414-EBDE-4F92-B307-4E8F19B6117E} = {F8C0AA27-F3FB-4286-8E4C-47EF86B539FF}
|
||||
{51563775-C659-4907-9BAF-9995BAB87D01} = {7BF11F3A-60B6-4796-B504-579C67FFBA34}
|
||||
EndGlobalSection
|
||||
|
|
|
|||
|
|
@ -16,8 +16,8 @@
|
|||
<PackageReference Include="Internal.AspNetCore.Sdk" Version="$(InternalAspNetCoreSdkVersion)" PrivateAssets="All" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition="'$(TargetFrameworkIdentifier)'=='.NETFramework' AND '$(OutputType)'=='library'">
|
||||
<PackageReference Include="NETStandard.Library" Version="$(BundledNETStandardPackageVersion)" />
|
||||
<ItemGroup Condition="'$(TargetFrameworkIdentifier)'=='.NETFramework'">
|
||||
<PackageReference Include="NETStandard.Library.NETFramework" Version="$(NETStandardLibraryNETFrameworkVersion)" PrivateAssets="All" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
|
|||
|
|
@ -1,11 +1,13 @@
|
|||
<Project>
|
||||
<PropertyGroup>
|
||||
<AspNetCoreVersion>2.0.0-*</AspNetCoreVersion>
|
||||
<CoreFxVersion>4.4.0-*</CoreFxVersion>
|
||||
<IdentityModelActiveDirectoryVersion>3.13.8</IdentityModelActiveDirectoryVersion>
|
||||
<IdentityModelOpenIdVersion>2.1.3</IdentityModelOpenIdVersion>
|
||||
<InternalAspNetCoreSdkVersion>2.1.0-*</InternalAspNetCoreSdkVersion>
|
||||
<JsonNetVersion>10.0.1</JsonNetVersion>
|
||||
<NETStandardImplicitPackageVersion>$(BundledNETStandardPackageVersion)</NETStandardImplicitPackageVersion>
|
||||
<NETStandardLibraryNETFrameworkVersion>2.0.0-*</NETStandardLibraryNETFrameworkVersion>
|
||||
<OwinVersion>3.0.1</OwinVersion>
|
||||
<TestSdkVersion>15.3.0-*</TestSdkVersion>
|
||||
<XunitVersion>2.3.0-beta2-*</XunitVersion>
|
||||
</PropertyGroup>
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
<Project>
|
||||
<ItemGroup>
|
||||
<ExcludeFromTest Include="$(RepositoryRoot)test\Microsoft.Owin.Security.Interop.Test\*.csproj" Condition="'$(OS)' != 'Windows_NT'"/>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
|
||||
<Import Project="..\..\build\dependencies.props" />
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp2.0</TargetFramework>
|
||||
<TargetFrameworks>net461;netcoreapp2.0</TargetFrameworks>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
@ -19,4 +19,8 @@
|
|||
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="$(AspNetCoreVersion)" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition="'$(TargetFramework)'=='net461'">
|
||||
<PackageReference Include="NETStandard.Library.NETFramework" Version="$(NETStandardLibraryNETFrameworkVersion)" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
|
||||
<Import Project="..\..\build\dependencies.props" />
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp2.0</TargetFramework>
|
||||
<TargetFrameworks>net461;netcoreapp2.0</TargetFrameworks>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
@ -19,4 +19,8 @@
|
|||
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="$(AspNetCoreVersion)" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition="'$(TargetFramework)'=='net461'">
|
||||
<PackageReference Include="NETStandard.Library.NETFramework" Version="$(NETStandardLibraryNETFrameworkVersion)" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
|
||||
<Import Project="..\..\build\dependencies.props" />
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp2.0</TargetFramework>
|
||||
<TargetFrameworks>net461;netcoreapp2.0</TargetFrameworks>
|
||||
<UserSecretsId>aspnet5-JwtBearerSample-20151210102827</UserSecretsId>
|
||||
</PropertyGroup>
|
||||
|
||||
|
|
@ -20,4 +20,8 @@
|
|||
<PackageReference Include="Microsoft.AspNetCore.Diagnostics" Version="$(AspNetCoreVersion)" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition="'$(TargetFramework)'=='net461'">
|
||||
<PackageReference Include="NETStandard.Library.NETFramework" Version="$(NETStandardLibraryNETFrameworkVersion)" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
<Import Project="..\..\build\dependencies.props" />
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp2.0</TargetFramework>
|
||||
<TargetFrameworks>net461;netcoreapp2.0</TargetFrameworks>
|
||||
<UserSecretsId>aspnet5-OpenIdConnectSample-20151210110318</UserSecretsId>
|
||||
</PropertyGroup>
|
||||
|
||||
|
|
@ -23,4 +23,8 @@
|
|||
<DotNetCliToolReference Include="Microsoft.Extensions.SecretManager.Tools" Version="$(AspNetCoreVersion)" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition="'$(TargetFramework)'=='net461'">
|
||||
<PackageReference Include="NETStandard.Library.NETFramework" Version="$(NETStandardLibraryNETFrameworkVersion)" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
<Import Project="..\..\build\dependencies.props" />
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp2.0</TargetFramework>
|
||||
<TargetFrameworks>net461;netcoreapp2.0</TargetFrameworks>
|
||||
<UserSecretsId>aspnet5-OpenIdConnectSample-20151210110318</UserSecretsId>
|
||||
</PropertyGroup>
|
||||
|
||||
|
|
@ -33,4 +33,8 @@
|
|||
<EmbeddedResource Include="compiler\resources\cert.pfx" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition="'$(TargetFramework)'=='net461'">
|
||||
<PackageReference Include="NETStandard.Library.NETFramework" Version="$(NETStandardLibraryNETFrameworkVersion)" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
<Import Project="..\..\build\dependencies.props" />
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp2.0</TargetFramework>
|
||||
<TargetFrameworks>net461;netcoreapp2.0</TargetFrameworks>
|
||||
<UserSecretsId>aspnet5-SocialSample-20151210111056</UserSecretsId>
|
||||
</PropertyGroup>
|
||||
|
||||
|
|
@ -35,4 +35,8 @@
|
|||
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="$(AspNetCoreVersion)" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition="'$(TargetFramework)'=='net461'">
|
||||
<PackageReference Include="NETStandard.Library.NETFramework" Version="$(NETStandardLibraryNETFrameworkVersion)" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
<PropertyGroup>
|
||||
<Description>ASP.NET Core middleware that enables an application to use cookie based authentication.</Description>
|
||||
<TargetFramework>netcoreapp2.0</TargetFramework>
|
||||
<TargetFramework>netstandard2.0</TargetFramework>
|
||||
<DefineConstants>$(DefineConstants);SECURITY</DefineConstants>
|
||||
<NoWarn>$(NoWarn);CS1591</NoWarn>
|
||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
<PropertyGroup>
|
||||
<Description>ASP.NET Core middleware that enables an application to support Facebook's OAuth 2.0 authentication workflow.</Description>
|
||||
<TargetFramework>netcoreapp2.0</TargetFramework>
|
||||
<TargetFramework>netstandard2.0</TargetFramework>
|
||||
<NoWarn>$(NoWarn);CS1591</NoWarn>
|
||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||
<PackageTags>aspnetcore;authentication;security</PackageTags>
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
<PropertyGroup>
|
||||
<Description>ASP.NET Core contains middleware to support Google's OpenId and OAuth 2.0 authentication workflows.</Description>
|
||||
<TargetFramework>netcoreapp2.0</TargetFramework>
|
||||
<TargetFramework>netstandard2.0</TargetFramework>
|
||||
<NoWarn>$(NoWarn);CS1591</NoWarn>
|
||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||
<PackageTags>aspnetcore;authentication;security</PackageTags>
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
<Import Project="..\..\build\common.props" />
|
||||
<PropertyGroup>
|
||||
<Description>ASP.NET Core middleware that enables an application to receive an OpenID Connect bearer token.</Description>
|
||||
<TargetFramework>netcoreapp2.0</TargetFramework>
|
||||
<TargetFramework>netstandard2.0</TargetFramework>
|
||||
<NoWarn>$(NoWarn);CS1591</NoWarn>
|
||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||
<PackageTags>aspnetcore;authentication;security</PackageTags>
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
<PropertyGroup>
|
||||
<Description>ASP.NET Core middleware that enables an application to support the Microsoft Account authentication workflow.</Description>
|
||||
<TargetFramework>netcoreapp2.0</TargetFramework>
|
||||
<TargetFramework>netstandard2.0</TargetFramework>
|
||||
<NoWarn>$(NoWarn);CS1591</NoWarn>
|
||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||
<PackageTags>aspnetcore;authentication;security</PackageTags>
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
<PropertyGroup>
|
||||
<Description>ASP.NET Core middleware that enables an application to support any standard OAuth 2.0 authentication workflow.</Description>
|
||||
<TargetFramework>netcoreapp2.0</TargetFramework>
|
||||
<TargetFramework>netstandard2.0</TargetFramework>
|
||||
<NoWarn>$(NoWarn);CS1591</NoWarn>
|
||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||
<PackageTags>aspnetcore;authentication;security</PackageTags>
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
<Import Project="..\..\build\common.props" />
|
||||
<PropertyGroup>
|
||||
<Description>ASP.NET Core middleware that enables an application to support the OpenID Connect authentication workflow.</Description>
|
||||
<TargetFramework>netcoreapp2.0</TargetFramework>
|
||||
<TargetFramework>netstandard2.0</TargetFramework>
|
||||
<NoWarn>$(NoWarn);CS1591</NoWarn>
|
||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||
<PackageTags>aspnetcore;authentication;security</PackageTags>
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
<PropertyGroup>
|
||||
<Description>ASP.NET Core middleware that enables an application to support Twitter's OAuth 1.0 authentication workflow.</Description>
|
||||
<TargetFramework>netcoreapp2.0</TargetFramework>
|
||||
<TargetFramework>netstandard2.0</TargetFramework>
|
||||
<NoWarn>$(NoWarn);CS1591</NoWarn>
|
||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||
<PackageTags>aspnetcore;authentication;security</PackageTags>
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
<PropertyGroup>
|
||||
<Description>ASP.NET Core common types used by the various authentication middleware components.</Description>
|
||||
<TargetFramework>netcoreapp2.0</TargetFramework>
|
||||
<TargetFramework>netstandard2.0</TargetFramework>
|
||||
<NoWarn>$(NoWarn);CS1591</NoWarn>
|
||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||
<PackageTags>aspnetcore;authentication;security</PackageTags>
|
||||
|
|
@ -18,7 +18,7 @@
|
|||
<PackageReference Include="Microsoft.AspNetCore.Http.Extensions" Version="$(AspNetCoreVersion)" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="$(AspNetCoreVersion)" />
|
||||
<PackageReference Include="Microsoft.Extensions.Options" Version="$(AspNetCoreVersion)" />
|
||||
<PackageReference Include="Microsoft.Extensions.SecurityHelper.Sources" Version="$(AspNetCoreVersion)" PrivateAssets="All" />
|
||||
<PackageReference Include="Microsoft.Extensions.SecurityHelper.Sources" Version="$(AspNetCoreVersion)" PrivateAssets="All" />
|
||||
<PackageReference Include="Microsoft.Extensions.TaskCache.Sources" Version="$(AspNetCoreVersion)" PrivateAssets="All" />
|
||||
<PackageReference Include="Microsoft.Extensions.WebEncoders" Version="$(AspNetCoreVersion)" />
|
||||
</ItemGroup>
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
Commonly used types:
|
||||
Microsoft.AspNetCore.Authorization.AllowAnonymousAttribute
|
||||
Microsoft.AspNetCore.Authorization.AuthorizeAttribute</Description>
|
||||
<TargetFramework>netcoreapp2.0</TargetFramework>
|
||||
<TargetFramework>netstandard2.0</TargetFramework>
|
||||
<NoWarn>$(NoWarn);CS1591</NoWarn>
|
||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||
<PackageTags>aspnetcore;authorization</PackageTags>
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
<PropertyGroup>
|
||||
<Description>ASP.NET Core cookie policy classes to control the behavior of cookies.</Description>
|
||||
<TargetFramework>netcoreapp2.0</TargetFramework>
|
||||
<TargetFramework>netstandard2.0</TargetFramework>
|
||||
<NoWarn>$(NoWarn);CS1591</NoWarn>
|
||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||
<PackageTags>aspnetcore</PackageTags>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,17 @@
|
|||
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using Microsoft.Owin.Security.DataHandler;
|
||||
using Microsoft.Owin.Security.DataHandler.Encoder;
|
||||
using Microsoft.Owin.Security.DataProtection;
|
||||
|
||||
namespace Microsoft.Owin.Security.Interop
|
||||
{
|
||||
public class AspNetTicketDataFormat : SecureDataFormat<AuthenticationTicket>
|
||||
{
|
||||
public AspNetTicketDataFormat(IDataProtector protector)
|
||||
: base(AspNetTicketSerializer.Default, protector, TextEncodings.Base64Url)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,220 @@
|
|||
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Security.Claims;
|
||||
using Microsoft.Owin.Security.DataHandler.Serializer;
|
||||
|
||||
namespace Microsoft.Owin.Security.Interop
|
||||
{
|
||||
// This MUST be kept in sync with Microsoft.AspNetCore.Authentication.DataHandler.TicketSerializer
|
||||
public class AspNetTicketSerializer : IDataSerializer<AuthenticationTicket>
|
||||
{
|
||||
private const string DefaultStringPlaceholder = "\0";
|
||||
private const int FormatVersion = 5;
|
||||
|
||||
public static AspNetTicketSerializer Default { get; } = new AspNetTicketSerializer();
|
||||
|
||||
public virtual byte[] Serialize(AuthenticationTicket ticket)
|
||||
{
|
||||
using (var memory = new MemoryStream())
|
||||
{
|
||||
using (var writer = new BinaryWriter(memory))
|
||||
{
|
||||
Write(writer, ticket);
|
||||
}
|
||||
return memory.ToArray();
|
||||
}
|
||||
}
|
||||
|
||||
public virtual AuthenticationTicket Deserialize(byte[] data)
|
||||
{
|
||||
using (var memory = new MemoryStream(data))
|
||||
{
|
||||
using (var reader = new BinaryReader(memory))
|
||||
{
|
||||
return Read(reader);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void Write(BinaryWriter writer, AuthenticationTicket ticket)
|
||||
{
|
||||
writer.Write(FormatVersion);
|
||||
writer.Write(ticket.Identity.AuthenticationType);
|
||||
|
||||
var identity = ticket.Identity;
|
||||
if (identity == null)
|
||||
{
|
||||
throw new ArgumentNullException("ticket.Identity");
|
||||
}
|
||||
|
||||
// There is always a single identity
|
||||
writer.Write(1);
|
||||
WriteIdentity(writer, identity);
|
||||
PropertiesSerializer.Write(writer, ticket.Properties);
|
||||
}
|
||||
|
||||
protected virtual void WriteIdentity(BinaryWriter writer, ClaimsIdentity identity)
|
||||
{
|
||||
var authenticationType = identity.AuthenticationType ?? string.Empty;
|
||||
|
||||
writer.Write(authenticationType);
|
||||
WriteWithDefault(writer, identity.NameClaimType, ClaimsIdentity.DefaultNameClaimType);
|
||||
WriteWithDefault(writer, identity.RoleClaimType, ClaimsIdentity.DefaultRoleClaimType);
|
||||
|
||||
// Write the number of claims contained in the identity.
|
||||
writer.Write(identity.Claims.Count());
|
||||
|
||||
foreach (var claim in identity.Claims)
|
||||
{
|
||||
WriteClaim(writer, claim);
|
||||
}
|
||||
|
||||
var bootstrap = identity.BootstrapContext as string;
|
||||
if (!string.IsNullOrEmpty(bootstrap))
|
||||
{
|
||||
writer.Write(true);
|
||||
writer.Write(bootstrap);
|
||||
}
|
||||
else
|
||||
{
|
||||
writer.Write(false);
|
||||
}
|
||||
|
||||
if (identity.Actor != null)
|
||||
{
|
||||
writer.Write(true);
|
||||
WriteIdentity(writer, identity.Actor);
|
||||
}
|
||||
else
|
||||
{
|
||||
writer.Write(false);
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual void WriteClaim(BinaryWriter writer, Claim claim)
|
||||
{
|
||||
WriteWithDefault(writer, claim.Type, claim.Subject?.NameClaimType ?? ClaimsIdentity.DefaultNameClaimType);
|
||||
writer.Write(claim.Value);
|
||||
WriteWithDefault(writer, claim.ValueType, ClaimValueTypes.String);
|
||||
WriteWithDefault(writer, claim.Issuer, ClaimsIdentity.DefaultIssuer);
|
||||
WriteWithDefault(writer, claim.OriginalIssuer, claim.Issuer);
|
||||
|
||||
// Write the number of properties contained in the claim.
|
||||
writer.Write(claim.Properties.Count);
|
||||
|
||||
foreach (var property in claim.Properties)
|
||||
{
|
||||
writer.Write(property.Key ?? string.Empty);
|
||||
writer.Write(property.Value ?? string.Empty);
|
||||
}
|
||||
}
|
||||
|
||||
public virtual AuthenticationTicket Read(BinaryReader reader)
|
||||
{
|
||||
if (reader.ReadInt32() != FormatVersion)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var scheme = reader.ReadString();
|
||||
|
||||
// Any identities after the first will be ignored.
|
||||
var count = reader.ReadInt32();
|
||||
if (count < 0)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var identity = ReadIdentity(reader);
|
||||
var properties = PropertiesSerializer.Read(reader);
|
||||
|
||||
return new AuthenticationTicket(identity, properties);
|
||||
}
|
||||
|
||||
protected virtual ClaimsIdentity ReadIdentity(BinaryReader reader)
|
||||
{
|
||||
var authenticationType = reader.ReadString();
|
||||
var nameClaimType = ReadWithDefault(reader, ClaimsIdentity.DefaultNameClaimType);
|
||||
var roleClaimType = ReadWithDefault(reader, ClaimsIdentity.DefaultRoleClaimType);
|
||||
|
||||
// Read the number of claims contained
|
||||
// in the serialized identity.
|
||||
var count = reader.ReadInt32();
|
||||
|
||||
var identity = new ClaimsIdentity(authenticationType, nameClaimType, roleClaimType);
|
||||
|
||||
for (int index = 0; index != count; ++index)
|
||||
{
|
||||
var claim = ReadClaim(reader, identity);
|
||||
|
||||
identity.AddClaim(claim);
|
||||
}
|
||||
|
||||
// Determine whether the identity
|
||||
// has a bootstrap context attached.
|
||||
if (reader.ReadBoolean())
|
||||
{
|
||||
identity.BootstrapContext = reader.ReadString();
|
||||
}
|
||||
|
||||
// Determine whether the identity
|
||||
// has an actor identity attached.
|
||||
if (reader.ReadBoolean())
|
||||
{
|
||||
identity.Actor = ReadIdentity(reader);
|
||||
}
|
||||
|
||||
return identity;
|
||||
}
|
||||
|
||||
protected virtual Claim ReadClaim(BinaryReader reader, ClaimsIdentity identity)
|
||||
{
|
||||
var type = ReadWithDefault(reader, identity.NameClaimType);
|
||||
var value = reader.ReadString();
|
||||
var valueType = ReadWithDefault(reader, ClaimValueTypes.String);
|
||||
var issuer = ReadWithDefault(reader, ClaimsIdentity.DefaultIssuer);
|
||||
var originalIssuer = ReadWithDefault(reader, issuer);
|
||||
|
||||
var claim = new Claim(type, value, valueType, issuer, originalIssuer, identity);
|
||||
|
||||
// Read the number of properties stored in the claim.
|
||||
var count = reader.ReadInt32();
|
||||
|
||||
for (var index = 0; index != count; ++index)
|
||||
{
|
||||
var key = reader.ReadString();
|
||||
var propertyValue = reader.ReadString();
|
||||
|
||||
claim.Properties.Add(key, propertyValue);
|
||||
}
|
||||
|
||||
return claim;
|
||||
}
|
||||
|
||||
private static void WriteWithDefault(BinaryWriter writer, string value, string defaultValue)
|
||||
{
|
||||
if (string.Equals(value, defaultValue, StringComparison.Ordinal))
|
||||
{
|
||||
writer.Write(DefaultStringPlaceholder);
|
||||
}
|
||||
else
|
||||
{
|
||||
writer.Write(value);
|
||||
}
|
||||
}
|
||||
|
||||
private static string ReadWithDefault(BinaryReader reader, string defaultValue)
|
||||
{
|
||||
var value = reader.ReadString();
|
||||
if (string.Equals(value, DefaultStringPlaceholder, StringComparison.Ordinal))
|
||||
{
|
||||
return defaultValue;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,281 @@
|
|||
// 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;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using Microsoft.Owin.Infrastructure;
|
||||
|
||||
namespace Microsoft.Owin.Security.Interop
|
||||
{
|
||||
// This MUST be kept in sync with Microsoft.AspNetCore.Authentication.Cookies.ChunkingCookieManager
|
||||
/// <summary>
|
||||
/// This handles cookies that are limited by per cookie length. It breaks down long cookies for responses, and reassembles them
|
||||
/// from requests.
|
||||
/// </summary>
|
||||
public class ChunkingCookieManager : ICookieManager
|
||||
{
|
||||
private const string ChunkKeySuffix = "C";
|
||||
private const string ChunkCountPrefix = "chunks-";
|
||||
|
||||
public ChunkingCookieManager()
|
||||
{
|
||||
// Lowest common denominator. Safari has the lowest known limit (4093), and we leave little extra just in case.
|
||||
// See http://browsercookielimits.x64.me/.
|
||||
// Leave at least 20 in case CookiePolicy tries to add 'secure' and/or 'httponly'.
|
||||
ChunkSize = 4070;
|
||||
ThrowForPartialCookies = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The maximum size of cookie to send back to the client. If a cookie exceeds this size it will be broken down into multiple
|
||||
/// cookies. Set this value to null to disable this behavior. The default is 4090 characters, which is supported by all
|
||||
/// common browsers.
|
||||
///
|
||||
/// Note that browsers may also have limits on the total size of all cookies per domain, and on the number of cookies per domain.
|
||||
/// </summary>
|
||||
public int? ChunkSize { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Throw if not all chunks of a cookie are available on a request for re-assembly.
|
||||
/// </summary>
|
||||
public bool ThrowForPartialCookies { get; set; }
|
||||
|
||||
// Parse the "chunks-XX" to determine how many chunks there should be.
|
||||
private static int ParseChunksCount(string value)
|
||||
{
|
||||
if (value != null && value.StartsWith(ChunkCountPrefix, StringComparison.Ordinal))
|
||||
{
|
||||
var chunksCountString = value.Substring(ChunkCountPrefix.Length);
|
||||
int chunksCount;
|
||||
if (int.TryParse(chunksCountString, NumberStyles.None, CultureInfo.InvariantCulture, out chunksCount))
|
||||
{
|
||||
return chunksCount;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the reassembled cookie. Non chunked cookies are returned normally.
|
||||
/// Cookies with missing chunks just have their "chunks-XX" header returned.
|
||||
/// </summary>
|
||||
/// <param name="context"></param>
|
||||
/// <param name="key"></param>
|
||||
/// <returns>The reassembled cookie, if any, or null.</returns>
|
||||
public string GetRequestCookie(IOwinContext context, string key)
|
||||
{
|
||||
if (context == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(context));
|
||||
}
|
||||
|
||||
if (key == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(key));
|
||||
}
|
||||
|
||||
var requestCookies = context.Request.Cookies;
|
||||
var value = requestCookies[key];
|
||||
var chunksCount = ParseChunksCount(value);
|
||||
if (chunksCount > 0)
|
||||
{
|
||||
var chunks = new string[chunksCount];
|
||||
for (var chunkId = 1; chunkId <= chunksCount; chunkId++)
|
||||
{
|
||||
var chunk = requestCookies[key + ChunkKeySuffix + chunkId.ToString(CultureInfo.InvariantCulture)];
|
||||
if (string.IsNullOrEmpty(chunk))
|
||||
{
|
||||
if (ThrowForPartialCookies)
|
||||
{
|
||||
var totalSize = 0;
|
||||
for (int i = 0; i < chunkId - 1; i++)
|
||||
{
|
||||
totalSize += chunks[i].Length;
|
||||
}
|
||||
throw new FormatException(
|
||||
string.Format(CultureInfo.CurrentCulture,
|
||||
"The chunked cookie is incomplete. Only {0} of the expected {1} chunks were found, totaling {2} characters. A client size limit may have been exceeded.",
|
||||
chunkId - 1, chunksCount, totalSize));
|
||||
}
|
||||
// Missing chunk, abort by returning the original cookie value. It may have been a false positive?
|
||||
return value;
|
||||
}
|
||||
|
||||
chunks[chunkId - 1] = chunk;
|
||||
}
|
||||
|
||||
return string.Join(string.Empty, chunks);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Appends a new response cookie to the Set-Cookie header. If the cookie is larger than the given size limit
|
||||
/// then it will be broken down into multiple cookies as follows:
|
||||
/// Set-Cookie: CookieName=chunks-3; path=/
|
||||
/// Set-Cookie: CookieNameC1=Segment1; path=/
|
||||
/// Set-Cookie: CookieNameC2=Segment2; path=/
|
||||
/// Set-Cookie: CookieNameC3=Segment3; path=/
|
||||
/// </summary>
|
||||
/// <param name="context"></param>
|
||||
/// <param name="key"></param>
|
||||
/// <param name="value"></param>
|
||||
/// <param name="options"></param>
|
||||
public void AppendResponseCookie(IOwinContext context, string key, string value, CookieOptions options)
|
||||
{
|
||||
if (context == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(context));
|
||||
}
|
||||
|
||||
if (key == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(key));
|
||||
}
|
||||
|
||||
if (options == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(options));
|
||||
}
|
||||
|
||||
var domainHasValue = !string.IsNullOrEmpty(options.Domain);
|
||||
var pathHasValue = !string.IsNullOrEmpty(options.Path);
|
||||
var expiresHasValue = options.Expires.HasValue;
|
||||
|
||||
var templateLength = key.Length + "=".Length
|
||||
+ (domainHasValue ? "; domain=".Length + options.Domain.Length : 0)
|
||||
+ (pathHasValue ? "; path=".Length + options.Path.Length : 0)
|
||||
+ (expiresHasValue ? "; expires=ddd, dd-MMM-yyyy HH:mm:ss GMT".Length : 0)
|
||||
+ (options.Secure ? "; secure".Length : 0)
|
||||
+ (options.HttpOnly ? "; HttpOnly".Length : 0);
|
||||
|
||||
// Normal cookie
|
||||
var responseCookies = context.Response.Cookies;
|
||||
if (!ChunkSize.HasValue || ChunkSize.Value > templateLength + value.Length)
|
||||
{
|
||||
responseCookies.Append(key, value, options);
|
||||
}
|
||||
else if (ChunkSize.Value < templateLength + 10)
|
||||
{
|
||||
// 10 is the minimum data we want to put in an individual cookie, including the cookie chunk identifier "CXX".
|
||||
// No room for data, we can't chunk the options and name
|
||||
throw new InvalidOperationException("The cookie key and options are larger than ChunksSize, leaving no room for data.");
|
||||
}
|
||||
else
|
||||
{
|
||||
// Break the cookie down into multiple cookies.
|
||||
// Key = CookieName, value = "Segment1Segment2Segment2"
|
||||
// Set-Cookie: CookieName=chunks-3; path=/
|
||||
// Set-Cookie: CookieNameC1="Segment1"; path=/
|
||||
// Set-Cookie: CookieNameC2="Segment2"; path=/
|
||||
// Set-Cookie: CookieNameC3="Segment3"; path=/
|
||||
var dataSizePerCookie = ChunkSize.Value - templateLength - 3; // Budget 3 chars for the chunkid.
|
||||
var cookieChunkCount = (int)Math.Ceiling(value.Length * 1.0 / dataSizePerCookie);
|
||||
|
||||
responseCookies.Append(key, ChunkCountPrefix + cookieChunkCount.ToString(CultureInfo.InvariantCulture), options);
|
||||
|
||||
var offset = 0;
|
||||
for (var chunkId = 1; chunkId <= cookieChunkCount; chunkId++)
|
||||
{
|
||||
var remainingLength = value.Length - offset;
|
||||
var length = Math.Min(dataSizePerCookie, remainingLength);
|
||||
var segment = value.Substring(offset, length);
|
||||
offset += length;
|
||||
|
||||
responseCookies.Append(key + ChunkKeySuffix + chunkId.ToString(CultureInfo.InvariantCulture), segment, options);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Deletes the cookie with the given key by setting an expired state. If a matching chunked cookie exists on
|
||||
/// the request, delete each chunk.
|
||||
/// </summary>
|
||||
/// <param name="context"></param>
|
||||
/// <param name="key"></param>
|
||||
/// <param name="options"></param>
|
||||
public void DeleteCookie(IOwinContext context, string key, CookieOptions options)
|
||||
{
|
||||
if (context == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(context));
|
||||
}
|
||||
|
||||
if (key == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(key));
|
||||
}
|
||||
|
||||
if (options == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(options));
|
||||
}
|
||||
|
||||
var keys = new List<string>();
|
||||
keys.Add(key + "=");
|
||||
|
||||
var requestCookie = context.Request.Cookies[key];
|
||||
var chunks = ParseChunksCount(requestCookie);
|
||||
if (chunks > 0)
|
||||
{
|
||||
for (int i = 1; i <= chunks + 1; i++)
|
||||
{
|
||||
var subkey = key + ChunkKeySuffix + i.ToString(CultureInfo.InvariantCulture);
|
||||
keys.Add(subkey + "=");
|
||||
}
|
||||
}
|
||||
|
||||
var domainHasValue = !string.IsNullOrEmpty(options.Domain);
|
||||
var pathHasValue = !string.IsNullOrEmpty(options.Path);
|
||||
|
||||
Func<string, bool> rejectPredicate;
|
||||
Func<string, bool> predicate = value => keys.Any(k => value.StartsWith(k, StringComparison.OrdinalIgnoreCase));
|
||||
if (domainHasValue)
|
||||
{
|
||||
rejectPredicate = value => predicate(value) && value.IndexOf("domain=" + options.Domain, StringComparison.OrdinalIgnoreCase) != -1;
|
||||
}
|
||||
else if (pathHasValue)
|
||||
{
|
||||
rejectPredicate = value => predicate(value) && value.IndexOf("path=" + options.Path, StringComparison.OrdinalIgnoreCase) != -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
rejectPredicate = value => predicate(value);
|
||||
}
|
||||
|
||||
var responseHeaders = context.Response.Headers;
|
||||
string[] existingValues;
|
||||
if (responseHeaders.TryGetValue(Constants.Headers.SetCookie, out existingValues) && existingValues != null)
|
||||
{
|
||||
responseHeaders.SetValues(Constants.Headers.SetCookie, existingValues.Where(value => !rejectPredicate(value)).ToArray());
|
||||
}
|
||||
|
||||
AppendResponseCookie(
|
||||
context,
|
||||
key,
|
||||
string.Empty,
|
||||
new CookieOptions()
|
||||
{
|
||||
Path = options.Path,
|
||||
Domain = options.Domain,
|
||||
Expires = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc),
|
||||
});
|
||||
|
||||
for (int i = 1; i <= chunks; i++)
|
||||
{
|
||||
AppendResponseCookie(
|
||||
context,
|
||||
key + "C" + i.ToString(CultureInfo.InvariantCulture),
|
||||
string.Empty,
|
||||
new CookieOptions()
|
||||
{
|
||||
Path = options.Path,
|
||||
Domain = options.Domain,
|
||||
Expires = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc),
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
// 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.Owin.Security.Interop
|
||||
{
|
||||
internal static class Constants
|
||||
{
|
||||
internal static class Headers
|
||||
{
|
||||
internal const string SetCookie = "Set-Cookie";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using Microsoft.AspNetCore.DataProtection;
|
||||
|
||||
namespace Microsoft.Owin.Security.Interop
|
||||
{
|
||||
/// <summary>
|
||||
/// Converts an <see cref="IDataProtector"/> to an
|
||||
/// <see cref="Microsoft.Owin.Security.DataProtection.IDataProtector"/>.
|
||||
/// </summary>
|
||||
public sealed class DataProtectorShim : Microsoft.Owin.Security.DataProtection.IDataProtector
|
||||
{
|
||||
private readonly IDataProtector _protector;
|
||||
|
||||
public DataProtectorShim(IDataProtector protector)
|
||||
{
|
||||
_protector = protector;
|
||||
}
|
||||
|
||||
public byte[] Protect(byte[] userData)
|
||||
{
|
||||
return _protector.Protect(userData);
|
||||
}
|
||||
|
||||
public byte[] Unprotect(byte[] protectedData)
|
||||
{
|
||||
return _protector.Unprotect(protectedData);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<Import Project="..\..\build\common.props" />
|
||||
|
||||
<PropertyGroup>
|
||||
<Description>A compatibility layer for sharing authentication tickets between Microsoft.Owin.Security and Microsoft.AspNetCore.Authentication.</Description>
|
||||
<TargetFramework>net461</TargetFramework>
|
||||
<NoWarn>$(NoWarn);CS1591</NoWarn>
|
||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||
<PackageTags>aspnetcore;katana;owin;security</PackageTags>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.AspNetCore.DataProtection.Extensions" Version="$(AspNetCoreVersion)" />
|
||||
<PackageReference Include="Microsoft.Owin.Security" Version="$(OwinVersion)" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
@ -0,0 +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.Runtime.InteropServices;
|
||||
|
||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
[assembly: Guid("a7922dd8-09f1-43e4-938b-cc523ea08898")]
|
||||
|
||||
|
|
@ -0,0 +1,373 @@
|
|||
{
|
||||
"AssemblyIdentity": "Microsoft.Owin.Security.Interop, Version=1.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60",
|
||||
"Types": [
|
||||
{
|
||||
"Name": "Microsoft.Owin.Security.Interop.AspNetTicketDataFormat",
|
||||
"Visibility": "Public",
|
||||
"Kind": "Class",
|
||||
"BaseType": "Microsoft.Owin.Security.DataHandler.SecureDataFormat<Microsoft.Owin.Security.AuthenticationTicket>",
|
||||
"ImplementedInterfaces": [],
|
||||
"Members": [
|
||||
{
|
||||
"Kind": "Constructor",
|
||||
"Name": ".ctor",
|
||||
"Parameters": [
|
||||
{
|
||||
"Name": "protector",
|
||||
"Type": "Microsoft.Owin.Security.DataProtection.IDataProtector"
|
||||
}
|
||||
],
|
||||
"Visibility": "Public",
|
||||
"GenericParameter": []
|
||||
}
|
||||
],
|
||||
"GenericParameters": []
|
||||
},
|
||||
{
|
||||
"Name": "Microsoft.Owin.Security.Interop.AspNetTicketSerializer",
|
||||
"Visibility": "Public",
|
||||
"Kind": "Class",
|
||||
"ImplementedInterfaces": [
|
||||
"Microsoft.Owin.Security.DataHandler.Serializer.IDataSerializer<Microsoft.Owin.Security.AuthenticationTicket>"
|
||||
],
|
||||
"Members": [
|
||||
{
|
||||
"Kind": "Method",
|
||||
"Name": "get_Default",
|
||||
"Parameters": [],
|
||||
"ReturnType": "Microsoft.Owin.Security.Interop.AspNetTicketSerializer",
|
||||
"Static": true,
|
||||
"Visibility": "Public",
|
||||
"GenericParameter": []
|
||||
},
|
||||
{
|
||||
"Kind": "Method",
|
||||
"Name": "Serialize",
|
||||
"Parameters": [
|
||||
{
|
||||
"Name": "ticket",
|
||||
"Type": "Microsoft.Owin.Security.AuthenticationTicket"
|
||||
}
|
||||
],
|
||||
"ReturnType": "System.Byte[]",
|
||||
"Virtual": true,
|
||||
"ImplementedInterface": "Microsoft.Owin.Security.DataHandler.Serializer.IDataSerializer<Microsoft.Owin.Security.AuthenticationTicket>",
|
||||
"Visibility": "Public",
|
||||
"GenericParameter": []
|
||||
},
|
||||
{
|
||||
"Kind": "Method",
|
||||
"Name": "Deserialize",
|
||||
"Parameters": [
|
||||
{
|
||||
"Name": "data",
|
||||
"Type": "System.Byte[]"
|
||||
}
|
||||
],
|
||||
"ReturnType": "Microsoft.Owin.Security.AuthenticationTicket",
|
||||
"Virtual": true,
|
||||
"ImplementedInterface": "Microsoft.Owin.Security.DataHandler.Serializer.IDataSerializer<Microsoft.Owin.Security.AuthenticationTicket>",
|
||||
"Visibility": "Public",
|
||||
"GenericParameter": []
|
||||
},
|
||||
{
|
||||
"Kind": "Method",
|
||||
"Name": "Write",
|
||||
"Parameters": [
|
||||
{
|
||||
"Name": "writer",
|
||||
"Type": "System.IO.BinaryWriter"
|
||||
},
|
||||
{
|
||||
"Name": "ticket",
|
||||
"Type": "Microsoft.Owin.Security.AuthenticationTicket"
|
||||
}
|
||||
],
|
||||
"ReturnType": "System.Void",
|
||||
"Virtual": true,
|
||||
"Visibility": "Public",
|
||||
"GenericParameter": []
|
||||
},
|
||||
{
|
||||
"Kind": "Method",
|
||||
"Name": "WriteIdentity",
|
||||
"Parameters": [
|
||||
{
|
||||
"Name": "writer",
|
||||
"Type": "System.IO.BinaryWriter"
|
||||
},
|
||||
{
|
||||
"Name": "identity",
|
||||
"Type": "System.Security.Claims.ClaimsIdentity"
|
||||
}
|
||||
],
|
||||
"ReturnType": "System.Void",
|
||||
"Virtual": true,
|
||||
"Visibility": "Protected",
|
||||
"GenericParameter": []
|
||||
},
|
||||
{
|
||||
"Kind": "Method",
|
||||
"Name": "WriteClaim",
|
||||
"Parameters": [
|
||||
{
|
||||
"Name": "writer",
|
||||
"Type": "System.IO.BinaryWriter"
|
||||
},
|
||||
{
|
||||
"Name": "claim",
|
||||
"Type": "System.Security.Claims.Claim"
|
||||
}
|
||||
],
|
||||
"ReturnType": "System.Void",
|
||||
"Virtual": true,
|
||||
"Visibility": "Protected",
|
||||
"GenericParameter": []
|
||||
},
|
||||
{
|
||||
"Kind": "Method",
|
||||
"Name": "Read",
|
||||
"Parameters": [
|
||||
{
|
||||
"Name": "reader",
|
||||
"Type": "System.IO.BinaryReader"
|
||||
}
|
||||
],
|
||||
"ReturnType": "Microsoft.Owin.Security.AuthenticationTicket",
|
||||
"Virtual": true,
|
||||
"Visibility": "Public",
|
||||
"GenericParameter": []
|
||||
},
|
||||
{
|
||||
"Kind": "Method",
|
||||
"Name": "ReadIdentity",
|
||||
"Parameters": [
|
||||
{
|
||||
"Name": "reader",
|
||||
"Type": "System.IO.BinaryReader"
|
||||
}
|
||||
],
|
||||
"ReturnType": "System.Security.Claims.ClaimsIdentity",
|
||||
"Virtual": true,
|
||||
"Visibility": "Protected",
|
||||
"GenericParameter": []
|
||||
},
|
||||
{
|
||||
"Kind": "Method",
|
||||
"Name": "ReadClaim",
|
||||
"Parameters": [
|
||||
{
|
||||
"Name": "reader",
|
||||
"Type": "System.IO.BinaryReader"
|
||||
},
|
||||
{
|
||||
"Name": "identity",
|
||||
"Type": "System.Security.Claims.ClaimsIdentity"
|
||||
}
|
||||
],
|
||||
"ReturnType": "System.Security.Claims.Claim",
|
||||
"Virtual": true,
|
||||
"Visibility": "Protected",
|
||||
"GenericParameter": []
|
||||
},
|
||||
{
|
||||
"Kind": "Constructor",
|
||||
"Name": ".ctor",
|
||||
"Parameters": [],
|
||||
"Visibility": "Public",
|
||||
"GenericParameter": []
|
||||
}
|
||||
],
|
||||
"GenericParameters": []
|
||||
},
|
||||
{
|
||||
"Name": "Microsoft.Owin.Security.Interop.ChunkingCookieManager",
|
||||
"Visibility": "Public",
|
||||
"Kind": "Class",
|
||||
"ImplementedInterfaces": [
|
||||
"Microsoft.Owin.Infrastructure.ICookieManager"
|
||||
],
|
||||
"Members": [
|
||||
{
|
||||
"Kind": "Method",
|
||||
"Name": "get_ChunkSize",
|
||||
"Parameters": [],
|
||||
"ReturnType": "System.Nullable<System.Int32>",
|
||||
"Visibility": "Public",
|
||||
"GenericParameter": []
|
||||
},
|
||||
{
|
||||
"Kind": "Method",
|
||||
"Name": "set_ChunkSize",
|
||||
"Parameters": [
|
||||
{
|
||||
"Name": "value",
|
||||
"Type": "System.Nullable<System.Int32>"
|
||||
}
|
||||
],
|
||||
"ReturnType": "System.Void",
|
||||
"Visibility": "Public",
|
||||
"GenericParameter": []
|
||||
},
|
||||
{
|
||||
"Kind": "Method",
|
||||
"Name": "get_ThrowForPartialCookies",
|
||||
"Parameters": [],
|
||||
"ReturnType": "System.Boolean",
|
||||
"Visibility": "Public",
|
||||
"GenericParameter": []
|
||||
},
|
||||
{
|
||||
"Kind": "Method",
|
||||
"Name": "set_ThrowForPartialCookies",
|
||||
"Parameters": [
|
||||
{
|
||||
"Name": "value",
|
||||
"Type": "System.Boolean"
|
||||
}
|
||||
],
|
||||
"ReturnType": "System.Void",
|
||||
"Visibility": "Public",
|
||||
"GenericParameter": []
|
||||
},
|
||||
{
|
||||
"Kind": "Method",
|
||||
"Name": "GetRequestCookie",
|
||||
"Parameters": [
|
||||
{
|
||||
"Name": "context",
|
||||
"Type": "Microsoft.Owin.IOwinContext"
|
||||
},
|
||||
{
|
||||
"Name": "key",
|
||||
"Type": "System.String"
|
||||
}
|
||||
],
|
||||
"ReturnType": "System.String",
|
||||
"Sealed": true,
|
||||
"Virtual": true,
|
||||
"ImplementedInterface": "Microsoft.Owin.Infrastructure.ICookieManager",
|
||||
"Visibility": "Public",
|
||||
"GenericParameter": []
|
||||
},
|
||||
{
|
||||
"Kind": "Method",
|
||||
"Name": "AppendResponseCookie",
|
||||
"Parameters": [
|
||||
{
|
||||
"Name": "context",
|
||||
"Type": "Microsoft.Owin.IOwinContext"
|
||||
},
|
||||
{
|
||||
"Name": "key",
|
||||
"Type": "System.String"
|
||||
},
|
||||
{
|
||||
"Name": "value",
|
||||
"Type": "System.String"
|
||||
},
|
||||
{
|
||||
"Name": "options",
|
||||
"Type": "Microsoft.Owin.CookieOptions"
|
||||
}
|
||||
],
|
||||
"ReturnType": "System.Void",
|
||||
"Sealed": true,
|
||||
"Virtual": true,
|
||||
"ImplementedInterface": "Microsoft.Owin.Infrastructure.ICookieManager",
|
||||
"Visibility": "Public",
|
||||
"GenericParameter": []
|
||||
},
|
||||
{
|
||||
"Kind": "Method",
|
||||
"Name": "DeleteCookie",
|
||||
"Parameters": [
|
||||
{
|
||||
"Name": "context",
|
||||
"Type": "Microsoft.Owin.IOwinContext"
|
||||
},
|
||||
{
|
||||
"Name": "key",
|
||||
"Type": "System.String"
|
||||
},
|
||||
{
|
||||
"Name": "options",
|
||||
"Type": "Microsoft.Owin.CookieOptions"
|
||||
}
|
||||
],
|
||||
"ReturnType": "System.Void",
|
||||
"Sealed": true,
|
||||
"Virtual": true,
|
||||
"ImplementedInterface": "Microsoft.Owin.Infrastructure.ICookieManager",
|
||||
"Visibility": "Public",
|
||||
"GenericParameter": []
|
||||
},
|
||||
{
|
||||
"Kind": "Constructor",
|
||||
"Name": ".ctor",
|
||||
"Parameters": [],
|
||||
"Visibility": "Public",
|
||||
"GenericParameter": []
|
||||
}
|
||||
],
|
||||
"GenericParameters": []
|
||||
},
|
||||
{
|
||||
"Name": "Microsoft.Owin.Security.Interop.DataProtectorShim",
|
||||
"Visibility": "Public",
|
||||
"Kind": "Class",
|
||||
"Sealed": true,
|
||||
"ImplementedInterfaces": [
|
||||
"Microsoft.Owin.Security.DataProtection.IDataProtector"
|
||||
],
|
||||
"Members": [
|
||||
{
|
||||
"Kind": "Method",
|
||||
"Name": "Protect",
|
||||
"Parameters": [
|
||||
{
|
||||
"Name": "userData",
|
||||
"Type": "System.Byte[]"
|
||||
}
|
||||
],
|
||||
"ReturnType": "System.Byte[]",
|
||||
"Sealed": true,
|
||||
"Virtual": true,
|
||||
"ImplementedInterface": "Microsoft.Owin.Security.DataProtection.IDataProtector",
|
||||
"Visibility": "Public",
|
||||
"GenericParameter": []
|
||||
},
|
||||
{
|
||||
"Kind": "Method",
|
||||
"Name": "Unprotect",
|
||||
"Parameters": [
|
||||
{
|
||||
"Name": "protectedData",
|
||||
"Type": "System.Byte[]"
|
||||
}
|
||||
],
|
||||
"ReturnType": "System.Byte[]",
|
||||
"Sealed": true,
|
||||
"Virtual": true,
|
||||
"ImplementedInterface": "Microsoft.Owin.Security.DataProtection.IDataProtector",
|
||||
"Visibility": "Public",
|
||||
"GenericParameter": []
|
||||
},
|
||||
{
|
||||
"Kind": "Constructor",
|
||||
"Name": ".ctor",
|
||||
"Parameters": [
|
||||
{
|
||||
"Name": "protector",
|
||||
"Type": "Microsoft.AspNetCore.DataProtection.IDataProtector"
|
||||
}
|
||||
],
|
||||
"Visibility": "Public",
|
||||
"GenericParameter": []
|
||||
}
|
||||
],
|
||||
"GenericParameters": []
|
||||
}
|
||||
],
|
||||
"SourceFilters": []
|
||||
}
|
||||
|
|
@ -3,9 +3,8 @@
|
|||
<Import Project="..\..\build\common.props" />
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp2.0</TargetFramework>
|
||||
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
|
||||
<GenerateBindingRedirectsOutputType>true</GenerateBindingRedirectsOutputType>
|
||||
<TargetFrameworks>netcoreapp2.0;net461</TargetFrameworks>
|
||||
<TargetFrameworks Condition=" '$(OS)' != 'Windows_NT' ">netcoreapp2.0</TargetFrameworks>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
@ -24,6 +23,7 @@
|
|||
<PackageReference Include="Microsoft.AspNetCore.TestHost" Version="$(AspNetCoreVersion)" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Testing" Version="$(AspNetCoreVersion)" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="$(TestSdkVersion)" />
|
||||
<PackageReference Include="System.Net.Http" Version="$(CoreFxVersion)" />
|
||||
<PackageReference Include="xunit.runner.visualstudio" Version="$(XunitVersion)" />
|
||||
<PackageReference Include="xunit" Version="$(XunitVersion)" />
|
||||
</ItemGroup>
|
||||
|
|
|
|||
|
|
@ -3,7 +3,8 @@
|
|||
<Import Project="..\..\build\common.props" />
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp2.0</TargetFramework>
|
||||
<TargetFrameworks>netcoreapp2.0;net461</TargetFrameworks>
|
||||
<TargetFrameworks Condition=" '$(OS)' != 'Windows_NT' ">netcoreapp2.0</TargetFrameworks>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
|
|||
|
|
@ -3,7 +3,8 @@
|
|||
<Import Project="..\..\build\common.props" />
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp2.0</TargetFramework>
|
||||
<TargetFrameworks>netcoreapp2.0;net461</TargetFrameworks>
|
||||
<TargetFrameworks Condition=" '$(OS)' != 'Windows_NT' ">netcoreapp2.0</TargetFrameworks>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
|
|||
|
|
@ -2,9 +2,8 @@
|
|||
|
||||
<Import Project="..\..\build\common.props" />
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp2.0</TargetFramework>
|
||||
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
|
||||
<GenerateBindingRedirectsOutputType>true</GenerateBindingRedirectsOutputType>
|
||||
<TargetFrameworks>netcoreapp2.0;net461</TargetFrameworks>
|
||||
<TargetFrameworks Condition=" '$(OS)' != 'Windows_NT' ">netcoreapp2.0</TargetFrameworks>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,332 @@
|
|||
// 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.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Security.Claims;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Xml;
|
||||
using System.Xml.Linq;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.DataProtection;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.Authentication;
|
||||
using Microsoft.AspNetCore.Authentication.Cookies;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Net.Http.Headers;
|
||||
using Microsoft.Owin.Security.Cookies;
|
||||
using Microsoft.Owin.Testing;
|
||||
using Owin;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.Owin.Security.Interop
|
||||
{
|
||||
public class CookiesInteropTests
|
||||
{
|
||||
[Fact]
|
||||
public async Task AspNetCoreWithInteropCookieContainsIdentity()
|
||||
{
|
||||
var identity = new ClaimsIdentity("Cookies");
|
||||
identity.AddClaim(new Claim(ClaimTypes.Name, "Alice"));
|
||||
|
||||
var dataProtection = DataProtectionProvider.Create(new DirectoryInfo("..\\..\\artifacts"));
|
||||
var dataProtector = dataProtection.CreateProtector(
|
||||
"Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationMiddleware", // full name of the ASP.NET Core type
|
||||
Cookies.CookieAuthenticationDefaults.AuthenticationType, "v2");
|
||||
|
||||
var interopServer = TestServer.Create(app =>
|
||||
{
|
||||
app.Properties["host.AppName"] = "Microsoft.Owin.Security.Tests";
|
||||
|
||||
app.UseCookieAuthentication(new Cookies.CookieAuthenticationOptions
|
||||
{
|
||||
TicketDataFormat = new AspNetTicketDataFormat(new DataProtectorShim(dataProtector)),
|
||||
CookieName = AspNetCore.Authentication.Cookies.CookieAuthenticationDefaults.CookiePrefix
|
||||
+ AspNetCore.Authentication.Cookies.CookieAuthenticationDefaults.AuthenticationScheme,
|
||||
});
|
||||
|
||||
app.Run(context =>
|
||||
{
|
||||
context.Authentication.SignIn(identity);
|
||||
return Task.FromResult(0);
|
||||
});
|
||||
});
|
||||
|
||||
var transaction = await SendAsync(interopServer, "http://example.com");
|
||||
|
||||
var builder = new WebHostBuilder()
|
||||
.Configure(app =>
|
||||
{
|
||||
app.UseAuthentication();
|
||||
app.Run(async context =>
|
||||
{
|
||||
var result = await context.AuthenticateAsync("Cookies");
|
||||
await context.Response.WriteAsync(result.Ticket.Principal.Identity.Name);
|
||||
});
|
||||
})
|
||||
.ConfigureServices(services => services.AddCookieAuthentication(o => o.DataProtectionProvider = dataProtection));
|
||||
var newServer = new AspNetCore.TestHost.TestServer(builder);
|
||||
|
||||
var request = new HttpRequestMessage(HttpMethod.Get, "http://example.com/login");
|
||||
foreach (var cookie in SetCookieHeaderValue.ParseList(transaction.SetCookie))
|
||||
{
|
||||
request.Headers.Add("Cookie", cookie.Name + "=" + cookie.Value);
|
||||
}
|
||||
var response = await newServer.CreateClient().SendAsync(request);
|
||||
|
||||
Assert.Equal("Alice", await response.Content.ReadAsStringAsync());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task AspNetCoreWithLargeInteropCookieContainsIdentity()
|
||||
{
|
||||
var identity = new ClaimsIdentity("Cookies");
|
||||
identity.AddClaim(new Claim(ClaimTypes.Name, new string('a', 1024 * 5)));
|
||||
|
||||
var dataProtection = DataProtectionProvider.Create(new DirectoryInfo("..\\..\\artifacts"));
|
||||
var dataProtector = dataProtection.CreateProtector(
|
||||
"Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationMiddleware", // full name of the ASP.NET Core type
|
||||
Cookies.CookieAuthenticationDefaults.AuthenticationType, "v2");
|
||||
|
||||
var interopServer = TestServer.Create(app =>
|
||||
{
|
||||
app.Properties["host.AppName"] = "Microsoft.Owin.Security.Tests";
|
||||
|
||||
app.UseCookieAuthentication(new Cookies.CookieAuthenticationOptions
|
||||
{
|
||||
TicketDataFormat = new AspNetTicketDataFormat(new DataProtectorShim(dataProtector)),
|
||||
CookieName = AspNetCore.Authentication.Cookies.CookieAuthenticationDefaults.CookiePrefix
|
||||
+ AspNetCore.Authentication.Cookies.CookieAuthenticationDefaults.AuthenticationScheme,
|
||||
CookieManager = new ChunkingCookieManager(),
|
||||
});
|
||||
|
||||
app.Run(context =>
|
||||
{
|
||||
context.Authentication.SignIn(identity);
|
||||
return Task.FromResult(0);
|
||||
});
|
||||
});
|
||||
|
||||
var transaction = await SendAsync(interopServer, "http://example.com");
|
||||
|
||||
var builder = new WebHostBuilder()
|
||||
.Configure(app =>
|
||||
{
|
||||
app.UseAuthentication();
|
||||
app.Run(async context =>
|
||||
{
|
||||
var result = await context.AuthenticateAsync("Cookies");
|
||||
await context.Response.WriteAsync(result.Ticket.Principal.Identity.Name);
|
||||
});
|
||||
})
|
||||
.ConfigureServices(services => services.AddCookieAuthentication(o => o.DataProtectionProvider = dataProtection));
|
||||
var newServer = new AspNetCore.TestHost.TestServer(builder);
|
||||
|
||||
var request = new HttpRequestMessage(HttpMethod.Get, "http://example.com/login");
|
||||
foreach (var cookie in SetCookieHeaderValue.ParseList(transaction.SetCookie))
|
||||
{
|
||||
request.Headers.Add("Cookie", cookie.Name + "=" + cookie.Value);
|
||||
}
|
||||
var response = await newServer.CreateClient().SendAsync(request);
|
||||
|
||||
Assert.Equal(1024 * 5, (await response.Content.ReadAsStringAsync()).Length);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task InteropWithNewCookieContainsIdentity()
|
||||
{
|
||||
var user = new ClaimsPrincipal();
|
||||
var identity = new ClaimsIdentity("scheme");
|
||||
identity.AddClaim(new Claim(ClaimTypes.Name, "Alice"));
|
||||
user.AddIdentity(identity);
|
||||
|
||||
var dataProtection = DataProtectionProvider.Create(new DirectoryInfo("..\\..\\artifacts"));
|
||||
var dataProtector = dataProtection.CreateProtector(
|
||||
"Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationMiddleware", // full name of the ASP.NET Core type
|
||||
Cookies.CookieAuthenticationDefaults.AuthenticationType, "v2");
|
||||
|
||||
var builder = new WebHostBuilder()
|
||||
.Configure(app =>
|
||||
{
|
||||
app.UseAuthentication();
|
||||
app.Run(context => context.SignInAsync("Cookies", user));
|
||||
})
|
||||
.ConfigureServices(services => services.AddCookieAuthentication(o => o.DataProtectionProvider = dataProtection));
|
||||
var newServer = new AspNetCore.TestHost.TestServer(builder);
|
||||
|
||||
var cookies = await SendAndGetCookies(newServer, "http://example.com/login");
|
||||
|
||||
var server = TestServer.Create(app =>
|
||||
{
|
||||
app.Properties["host.AppName"] = "Microsoft.Owin.Security.Tests";
|
||||
|
||||
app.UseCookieAuthentication(new Cookies.CookieAuthenticationOptions
|
||||
{
|
||||
TicketDataFormat = new AspNetTicketDataFormat(new DataProtectorShim(dataProtector)),
|
||||
CookieName = AspNetCore.Authentication.Cookies.CookieAuthenticationDefaults.CookiePrefix
|
||||
+ AspNetCore.Authentication.Cookies.CookieAuthenticationDefaults.AuthenticationScheme,
|
||||
});
|
||||
|
||||
app.Run(async context =>
|
||||
{
|
||||
var result = await context.Authentication.AuthenticateAsync("Cookies");
|
||||
Describe(context.Response, result);
|
||||
});
|
||||
});
|
||||
|
||||
var transaction2 = await SendAsync(server, "http://example.com/me/Cookies", cookies);
|
||||
|
||||
Assert.Equal("Alice", FindClaimValue(transaction2, ClaimTypes.Name));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task InteropWithLargeNewCookieContainsIdentity()
|
||||
{
|
||||
var user = new ClaimsPrincipal();
|
||||
var identity = new ClaimsIdentity("scheme");
|
||||
identity.AddClaim(new Claim(ClaimTypes.Name, new string('a', 1024 * 5)));
|
||||
user.AddIdentity(identity);
|
||||
|
||||
var dataProtection = DataProtectionProvider.Create(new DirectoryInfo("..\\..\\artifacts"));
|
||||
var dataProtector = dataProtection.CreateProtector(
|
||||
"Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationMiddleware", // full name of the ASP.NET Core type
|
||||
Cookies.CookieAuthenticationDefaults.AuthenticationType, "v2");
|
||||
|
||||
var builder = new WebHostBuilder()
|
||||
.Configure(app =>
|
||||
{
|
||||
app.UseAuthentication();
|
||||
app.Run(context => context.SignInAsync("Cookies", user));
|
||||
})
|
||||
.ConfigureServices(services => services.AddCookieAuthentication(o => o.DataProtectionProvider = dataProtection));
|
||||
var newServer = new AspNetCore.TestHost.TestServer(builder);
|
||||
|
||||
var cookies = await SendAndGetCookies(newServer, "http://example.com/login");
|
||||
|
||||
var server = TestServer.Create(app =>
|
||||
{
|
||||
app.Properties["host.AppName"] = "Microsoft.Owin.Security.Tests";
|
||||
|
||||
app.UseCookieAuthentication(new Cookies.CookieAuthenticationOptions
|
||||
{
|
||||
TicketDataFormat = new AspNetTicketDataFormat(new DataProtectorShim(dataProtector)),
|
||||
CookieName = AspNetCore.Authentication.Cookies.CookieAuthenticationDefaults.CookiePrefix
|
||||
+ AspNetCore.Authentication.Cookies.CookieAuthenticationDefaults.AuthenticationScheme,
|
||||
CookieManager = new ChunkingCookieManager(),
|
||||
});
|
||||
|
||||
app.Run(async context =>
|
||||
{
|
||||
var result = await context.Authentication.AuthenticateAsync("Cookies");
|
||||
Describe(context.Response, result);
|
||||
});
|
||||
});
|
||||
|
||||
var transaction2 = await SendAsync(server, "http://example.com/me/Cookies", cookies);
|
||||
|
||||
Assert.Equal(1024 * 5, FindClaimValue(transaction2, ClaimTypes.Name).Length);
|
||||
}
|
||||
|
||||
private static async Task<IList<string>> SendAndGetCookies(AspNetCore.TestHost.TestServer server, string uri)
|
||||
{
|
||||
var request = new HttpRequestMessage(HttpMethod.Get, uri);
|
||||
var response = await server.CreateClient().SendAsync(request);
|
||||
if (response.Headers.Contains("Set-Cookie"))
|
||||
{
|
||||
IList<string> cookieHeaders = new List<string>();
|
||||
foreach (var cookie in SetCookieHeaderValue.ParseList(response.Headers.GetValues("Set-Cookie").ToList()))
|
||||
{
|
||||
cookieHeaders.Add(cookie.Name + "=" + cookie.Value);
|
||||
}
|
||||
return cookieHeaders;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static string FindClaimValue(Transaction transaction, string claimType)
|
||||
{
|
||||
XElement claim = transaction.ResponseElement.Elements("claim").SingleOrDefault(elt => elt.Attribute("type").Value == claimType);
|
||||
if (claim == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return claim.Attribute("value").Value;
|
||||
}
|
||||
|
||||
private static void Describe(IOwinResponse res, AuthenticateResult result)
|
||||
{
|
||||
res.StatusCode = 200;
|
||||
res.ContentType = "text/xml";
|
||||
var xml = new XElement("xml");
|
||||
if (result != null && result.Identity != null)
|
||||
{
|
||||
xml.Add(result.Identity.Claims.Select(claim => new XElement("claim", new XAttribute("type", claim.Type), new XAttribute("value", claim.Value))));
|
||||
}
|
||||
if (result != null && result.Properties != null)
|
||||
{
|
||||
xml.Add(result.Properties.Dictionary.Select(extra => new XElement("extra", new XAttribute("type", extra.Key), new XAttribute("value", extra.Value))));
|
||||
}
|
||||
using (var memory = new MemoryStream())
|
||||
{
|
||||
using (var writer = new XmlTextWriter(memory, Encoding.UTF8))
|
||||
{
|
||||
xml.WriteTo(writer);
|
||||
}
|
||||
res.Body.Write(memory.ToArray(), 0, memory.ToArray().Length);
|
||||
}
|
||||
}
|
||||
|
||||
private static async Task<Transaction> SendAsync(TestServer server, string uri, IList<string> cookieHeaders = null, bool ajaxRequest = false)
|
||||
{
|
||||
var request = new HttpRequestMessage(HttpMethod.Get, uri);
|
||||
if (cookieHeaders != null)
|
||||
{
|
||||
request.Headers.Add("Cookie", cookieHeaders);
|
||||
}
|
||||
if (ajaxRequest)
|
||||
{
|
||||
request.Headers.Add("X-Requested-With", "XMLHttpRequest");
|
||||
}
|
||||
var transaction = new Transaction
|
||||
{
|
||||
Request = request,
|
||||
Response = await server.HttpClient.SendAsync(request),
|
||||
};
|
||||
if (transaction.Response.Headers.Contains("Set-Cookie"))
|
||||
{
|
||||
transaction.SetCookie = transaction.Response.Headers.GetValues("Set-Cookie").ToList();
|
||||
}
|
||||
if (transaction.SetCookie != null && transaction.SetCookie.Any())
|
||||
{
|
||||
transaction.CookieNameValue = transaction.SetCookie.First().Split(new[] { ';' }, 2).First();
|
||||
}
|
||||
transaction.ResponseText = await transaction.Response.Content.ReadAsStringAsync();
|
||||
|
||||
if (transaction.Response.Content != null &&
|
||||
transaction.Response.Content.Headers.ContentType != null &&
|
||||
transaction.Response.Content.Headers.ContentType.MediaType == "text/xml")
|
||||
{
|
||||
transaction.ResponseElement = XElement.Parse(transaction.ResponseText);
|
||||
}
|
||||
return transaction;
|
||||
}
|
||||
|
||||
private class Transaction
|
||||
{
|
||||
public HttpRequestMessage Request { get; set; }
|
||||
public HttpResponseMessage Response { get; set; }
|
||||
|
||||
public IList<string> SetCookie { get; set; }
|
||||
public string CookieNameValue { get; set; }
|
||||
|
||||
public string ResponseText { get; set; }
|
||||
public XElement ResponseElement { get; set; }
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<Import Project="..\..\build\common.props" />
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net461</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\src\Microsoft.AspNetCore.Authentication.Cookies\Microsoft.AspNetCore.Authentication.Cookies.csproj" />
|
||||
<ProjectReference Include="..\..\src\Microsoft.Owin.Security.Interop\Microsoft.Owin.Security.Interop.csproj" />
|
||||
|
||||
<PackageReference Include="Microsoft.AspNetCore.TestHost" Version="$(AspNetCoreVersion)" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="$(TestSdkVersion)" />
|
||||
<PackageReference Include="Microsoft.Owin.Security.Cookies" Version="$(OwinVersion)" />
|
||||
<PackageReference Include="Microsoft.Owin.Testing" Version="$(OwinVersion)" />
|
||||
<PackageReference Include="System.Net.Http" Version="$(CoreFxVersion)" />
|
||||
<PackageReference Include="xunit" Version="$(XunitVersion)" />
|
||||
<PackageReference Include="xunit.runner.visualstudio" Version="$(XunitVersion)" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Service Include="{82a7f48d-3b50-4b1e-b82e-3ada8210c358}" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
@ -0,0 +1,91 @@
|
|||
// 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;
|
||||
using System.Linq;
|
||||
using System.Security.Claims;
|
||||
using Microsoft.AspNetCore.Authentication;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.Owin.Security.Interop.Test
|
||||
{
|
||||
public class TicketInteropTests
|
||||
{
|
||||
[Fact]
|
||||
public void NewSerializerCanReadInteropTicket()
|
||||
{
|
||||
var identity = new ClaimsIdentity("scheme");
|
||||
identity.AddClaim(new Claim("Test", "Value"));
|
||||
|
||||
var expires = DateTime.Today;
|
||||
var issued = new DateTime(1979, 11, 11);
|
||||
var properties = new Owin.Security.AuthenticationProperties();
|
||||
properties.IsPersistent = true;
|
||||
properties.RedirectUri = "/redirect";
|
||||
properties.Dictionary["key"] = "value";
|
||||
properties.ExpiresUtc = expires;
|
||||
properties.IssuedUtc = issued;
|
||||
|
||||
var interopTicket = new Owin.Security.AuthenticationTicket(identity, properties);
|
||||
var interopSerializer = new AspNetTicketSerializer();
|
||||
|
||||
var bytes = interopSerializer.Serialize(interopTicket);
|
||||
|
||||
var newSerializer = new TicketSerializer();
|
||||
var newTicket = newSerializer.Deserialize(bytes);
|
||||
|
||||
Assert.NotNull(newTicket);
|
||||
Assert.Equal(1, newTicket.Principal.Identities.Count());
|
||||
var newIdentity = newTicket.Principal.Identity as ClaimsIdentity;
|
||||
Assert.NotNull(newIdentity);
|
||||
Assert.Equal("scheme", newIdentity.AuthenticationType);
|
||||
Assert.True(newIdentity.HasClaim(c => c.Type == "Test" && c.Value == "Value"));
|
||||
Assert.NotNull(newTicket.Properties);
|
||||
Assert.True(newTicket.Properties.IsPersistent);
|
||||
Assert.Equal("/redirect", newTicket.Properties.RedirectUri);
|
||||
Assert.Equal("value", newTicket.Properties.Items["key"]);
|
||||
Assert.Equal(expires, newTicket.Properties.ExpiresUtc);
|
||||
Assert.Equal(issued, newTicket.Properties.IssuedUtc);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void InteropSerializerCanReadNewTicket()
|
||||
{
|
||||
var user = new ClaimsPrincipal();
|
||||
var identity = new ClaimsIdentity("scheme");
|
||||
identity.AddClaim(new Claim("Test", "Value"));
|
||||
user.AddIdentity(identity);
|
||||
|
||||
var expires = DateTime.Today;
|
||||
var issued = new DateTime(1979, 11, 11);
|
||||
var properties = new AspNetCore.Authentication.AuthenticationProperties();
|
||||
properties.IsPersistent = true;
|
||||
properties.RedirectUri = "/redirect";
|
||||
properties.Items["key"] = "value";
|
||||
properties.ExpiresUtc = expires;
|
||||
properties.IssuedUtc = issued;
|
||||
|
||||
var newTicket = new AspNetCore.Authentication.AuthenticationTicket(user, properties, "scheme");
|
||||
var newSerializer = new TicketSerializer();
|
||||
|
||||
var bytes = newSerializer.Serialize(newTicket);
|
||||
|
||||
var interopSerializer = new AspNetTicketSerializer();
|
||||
var interopTicket = interopSerializer.Deserialize(bytes);
|
||||
|
||||
Assert.NotNull(interopTicket);
|
||||
var newIdentity = interopTicket.Identity;
|
||||
Assert.NotNull(newIdentity);
|
||||
Assert.Equal("scheme", newIdentity.AuthenticationType);
|
||||
Assert.True(newIdentity.HasClaim(c => c.Type == "Test" && c.Value == "Value"));
|
||||
Assert.NotNull(interopTicket.Properties);
|
||||
Assert.True(interopTicket.Properties.IsPersistent);
|
||||
Assert.Equal("/redirect", interopTicket.Properties.RedirectUri);
|
||||
Assert.Equal("value", interopTicket.Properties.Dictionary["key"]);
|
||||
Assert.Equal(expires, interopTicket.Properties.ExpiresUtc);
|
||||
Assert.Equal(issued, interopTicket.Properties.IssuedUtc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Loading…
Reference in New Issue