diff --git a/Security.sln b/Security.sln
index 50805feb1..ea297aff0 100644
--- a/Security.sln
+++ b/Security.sln
@@ -1,6 +1,6 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
-VisualStudioVersion = 15.0.26020.0
+VisualStudioVersion = 15.0.26228.0
MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{4D2B6A51-2F9F-44F5-8131-EA5CAC053652}"
EndProject
@@ -18,8 +18,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenIdConnectSample", "samp
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Authentication.Cookies", "src\Microsoft.AspNetCore.Authentication.Cookies\Microsoft.AspNetCore.Authentication.Cookies.csproj", "{FC152CC4-054B-457E-8D91-389C5DE3C561}"
EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Authentication", "src\Microsoft.AspNetCore.Authentication\Microsoft.AspNetCore.Authentication.csproj", "{2286250A-52C8-4126-9F93-B1E45F0AD078}"
-EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Authentication.Facebook", "src\Microsoft.AspNetCore.Authentication.Facebook\Microsoft.AspNetCore.Authentication.Facebook.csproj", "{EEAAEE68-607B-4E33-AF3E-45C66B4DBA5A}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Authentication.Google", "src\Microsoft.AspNetCore.Authentication.Google\Microsoft.AspNetCore.Authentication.Google.csproj", "{76579C39-B829-490D-B8BE-1BD35FE8412E}"
@@ -54,13 +52,27 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenIdConnect.AzureAdSample
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("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Authentication", "src\Microsoft.AspNetCore.Authentication\Microsoft.AspNetCore.Authentication.csproj", "{BC0D4B56-1A5B-4D88-AFBF-68C0F2D545FB}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Extensions.Options", "..\Options\src\Microsoft.Extensions.Options\Microsoft.Extensions.Options.csproj", "{151B7C1C-8E47-48CC-B04C-7414001D0F7B}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Authentication.Abstractions", "..\HttpAbstractions\src\Microsoft.AspNetCore.Authentication.Abstractions\Microsoft.AspNetCore.Authentication.Abstractions.csproj", "{EB473BEB-9231-484E-BB66-05453ECC21DE}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Authentication.Core", "..\HttpAbstractions\src\Microsoft.AspNetCore.Authentication.Core\Microsoft.AspNetCore.Authentication.Core.csproj", "{95DE3093-35C9-4DA1-ADDD-DD1E980AC809}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.DataProtection", "..\DataProtection\src\Microsoft.AspNetCore.DataProtection\Microsoft.AspNetCore.DataProtection.csproj", "{269FACA1-956D-4B32-9994-16F2C4CB364A}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.DataProtection.Abstractions", "..\DataProtection\src\Microsoft.AspNetCore.DataProtection.Abstractions\Microsoft.AspNetCore.DataProtection.Abstractions.csproj", "{A48DA86C-BD8E-4A99-95EC-7441232F0586}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Debug|Mixed Platforms = Debug|Mixed Platforms
+ Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|Any CPU = Release|Any CPU
Release|Mixed Platforms = Release|Mixed Platforms
+ Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
@@ -68,272 +80,444 @@ Global
{558C2C2A-AED8-49DE-BB60-D5F8AE06C714}.Debug|Any CPU.Build.0 = Debug|Any CPU
{558C2C2A-AED8-49DE-BB60-D5F8AE06C714}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{558C2C2A-AED8-49DE-BB60-D5F8AE06C714}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
+ {558C2C2A-AED8-49DE-BB60-D5F8AE06C714}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {558C2C2A-AED8-49DE-BB60-D5F8AE06C714}.Debug|x64.Build.0 = Debug|Any CPU
{558C2C2A-AED8-49DE-BB60-D5F8AE06C714}.Debug|x86.ActiveCfg = Debug|Any CPU
{558C2C2A-AED8-49DE-BB60-D5F8AE06C714}.Release|Any CPU.ActiveCfg = Release|Any CPU
{558C2C2A-AED8-49DE-BB60-D5F8AE06C714}.Release|Any CPU.Build.0 = Release|Any CPU
{558C2C2A-AED8-49DE-BB60-D5F8AE06C714}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{558C2C2A-AED8-49DE-BB60-D5F8AE06C714}.Release|Mixed Platforms.Build.0 = Release|Any CPU
+ {558C2C2A-AED8-49DE-BB60-D5F8AE06C714}.Release|x64.ActiveCfg = Release|Any CPU
+ {558C2C2A-AED8-49DE-BB60-D5F8AE06C714}.Release|x64.Build.0 = Release|Any CPU
{558C2C2A-AED8-49DE-BB60-D5F8AE06C714}.Release|x86.ActiveCfg = Release|Any CPU
{8C73D216-332D-41D8-BFD0-45BC4BC36552}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{8C73D216-332D-41D8-BFD0-45BC4BC36552}.Debug|Any CPU.Build.0 = Debug|Any CPU
{8C73D216-332D-41D8-BFD0-45BC4BC36552}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{8C73D216-332D-41D8-BFD0-45BC4BC36552}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
+ {8C73D216-332D-41D8-BFD0-45BC4BC36552}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {8C73D216-332D-41D8-BFD0-45BC4BC36552}.Debug|x64.Build.0 = Debug|Any CPU
{8C73D216-332D-41D8-BFD0-45BC4BC36552}.Debug|x86.ActiveCfg = Debug|Any CPU
{8C73D216-332D-41D8-BFD0-45BC4BC36552}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8C73D216-332D-41D8-BFD0-45BC4BC36552}.Release|Any CPU.Build.0 = Release|Any CPU
{8C73D216-332D-41D8-BFD0-45BC4BC36552}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{8C73D216-332D-41D8-BFD0-45BC4BC36552}.Release|Mixed Platforms.Build.0 = Release|Any CPU
+ {8C73D216-332D-41D8-BFD0-45BC4BC36552}.Release|x64.ActiveCfg = Release|Any CPU
+ {8C73D216-332D-41D8-BFD0-45BC4BC36552}.Release|x64.Build.0 = Release|Any CPU
{8C73D216-332D-41D8-BFD0-45BC4BC36552}.Release|x86.ActiveCfg = Release|Any CPU
{19711880-46DA-4A26-9E0F-9B2E41D27651}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{19711880-46DA-4A26-9E0F-9B2E41D27651}.Debug|Any CPU.Build.0 = Debug|Any CPU
{19711880-46DA-4A26-9E0F-9B2E41D27651}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{19711880-46DA-4A26-9E0F-9B2E41D27651}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
+ {19711880-46DA-4A26-9E0F-9B2E41D27651}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {19711880-46DA-4A26-9E0F-9B2E41D27651}.Debug|x64.Build.0 = Debug|Any CPU
{19711880-46DA-4A26-9E0F-9B2E41D27651}.Debug|x86.ActiveCfg = Debug|Any CPU
{19711880-46DA-4A26-9E0F-9B2E41D27651}.Release|Any CPU.ActiveCfg = Release|Any CPU
{19711880-46DA-4A26-9E0F-9B2E41D27651}.Release|Any CPU.Build.0 = Release|Any CPU
{19711880-46DA-4A26-9E0F-9B2E41D27651}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{19711880-46DA-4A26-9E0F-9B2E41D27651}.Release|Mixed Platforms.Build.0 = Release|Any CPU
+ {19711880-46DA-4A26-9E0F-9B2E41D27651}.Release|x64.ActiveCfg = Release|Any CPU
+ {19711880-46DA-4A26-9E0F-9B2E41D27651}.Release|x64.Build.0 = Release|Any CPU
{19711880-46DA-4A26-9E0F-9B2E41D27651}.Release|x86.ActiveCfg = Release|Any CPU
{BEF0F5C3-EF4E-4649-9C49-D5E279A3CA2B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{BEF0F5C3-EF4E-4649-9C49-D5E279A3CA2B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{BEF0F5C3-EF4E-4649-9C49-D5E279A3CA2B}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{BEF0F5C3-EF4E-4649-9C49-D5E279A3CA2B}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
+ {BEF0F5C3-EF4E-4649-9C49-D5E279A3CA2B}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {BEF0F5C3-EF4E-4649-9C49-D5E279A3CA2B}.Debug|x64.Build.0 = Debug|Any CPU
{BEF0F5C3-EF4E-4649-9C49-D5E279A3CA2B}.Debug|x86.ActiveCfg = Debug|Any CPU
{BEF0F5C3-EF4E-4649-9C49-D5E279A3CA2B}.Debug|x86.Build.0 = Debug|Any CPU
{BEF0F5C3-EF4E-4649-9C49-D5E279A3CA2B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{BEF0F5C3-EF4E-4649-9C49-D5E279A3CA2B}.Release|Any CPU.Build.0 = Release|Any CPU
{BEF0F5C3-EF4E-4649-9C49-D5E279A3CA2B}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{BEF0F5C3-EF4E-4649-9C49-D5E279A3CA2B}.Release|Mixed Platforms.Build.0 = Release|Any CPU
+ {BEF0F5C3-EF4E-4649-9C49-D5E279A3CA2B}.Release|x64.ActiveCfg = Release|Any CPU
+ {BEF0F5C3-EF4E-4649-9C49-D5E279A3CA2B}.Release|x64.Build.0 = Release|Any CPU
{BEF0F5C3-EF4E-4649-9C49-D5E279A3CA2B}.Release|x86.ActiveCfg = Release|Any CPU
{BEF0F5C3-EF4E-4649-9C49-D5E279A3CA2B}.Release|x86.Build.0 = Release|Any CPU
{FC152CC4-054B-457E-8D91-389C5DE3C561}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{FC152CC4-054B-457E-8D91-389C5DE3C561}.Debug|Any CPU.Build.0 = Debug|Any CPU
{FC152CC4-054B-457E-8D91-389C5DE3C561}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{FC152CC4-054B-457E-8D91-389C5DE3C561}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
+ {FC152CC4-054B-457E-8D91-389C5DE3C561}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {FC152CC4-054B-457E-8D91-389C5DE3C561}.Debug|x64.Build.0 = Debug|Any CPU
{FC152CC4-054B-457E-8D91-389C5DE3C561}.Debug|x86.ActiveCfg = Debug|Any CPU
{FC152CC4-054B-457E-8D91-389C5DE3C561}.Debug|x86.Build.0 = Debug|Any CPU
{FC152CC4-054B-457E-8D91-389C5DE3C561}.Release|Any CPU.ActiveCfg = Release|Any CPU
{FC152CC4-054B-457E-8D91-389C5DE3C561}.Release|Any CPU.Build.0 = Release|Any CPU
{FC152CC4-054B-457E-8D91-389C5DE3C561}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{FC152CC4-054B-457E-8D91-389C5DE3C561}.Release|Mixed Platforms.Build.0 = Release|Any CPU
+ {FC152CC4-054B-457E-8D91-389C5DE3C561}.Release|x64.ActiveCfg = Release|Any CPU
+ {FC152CC4-054B-457E-8D91-389C5DE3C561}.Release|x64.Build.0 = Release|Any CPU
{FC152CC4-054B-457E-8D91-389C5DE3C561}.Release|x86.ActiveCfg = Release|Any CPU
{FC152CC4-054B-457E-8D91-389C5DE3C561}.Release|x86.Build.0 = Release|Any CPU
- {2286250A-52C8-4126-9F93-B1E45F0AD078}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {2286250A-52C8-4126-9F93-B1E45F0AD078}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {2286250A-52C8-4126-9F93-B1E45F0AD078}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
- {2286250A-52C8-4126-9F93-B1E45F0AD078}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
- {2286250A-52C8-4126-9F93-B1E45F0AD078}.Debug|x86.ActiveCfg = Debug|Any CPU
- {2286250A-52C8-4126-9F93-B1E45F0AD078}.Debug|x86.Build.0 = Debug|Any CPU
- {2286250A-52C8-4126-9F93-B1E45F0AD078}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {2286250A-52C8-4126-9F93-B1E45F0AD078}.Release|Any CPU.Build.0 = Release|Any CPU
- {2286250A-52C8-4126-9F93-B1E45F0AD078}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
- {2286250A-52C8-4126-9F93-B1E45F0AD078}.Release|Mixed Platforms.Build.0 = Release|Any CPU
- {2286250A-52C8-4126-9F93-B1E45F0AD078}.Release|x86.ActiveCfg = Release|Any CPU
- {2286250A-52C8-4126-9F93-B1E45F0AD078}.Release|x86.Build.0 = Release|Any CPU
{EEAAEE68-607B-4E33-AF3E-45C66B4DBA5A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{EEAAEE68-607B-4E33-AF3E-45C66B4DBA5A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{EEAAEE68-607B-4E33-AF3E-45C66B4DBA5A}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{EEAAEE68-607B-4E33-AF3E-45C66B4DBA5A}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
+ {EEAAEE68-607B-4E33-AF3E-45C66B4DBA5A}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {EEAAEE68-607B-4E33-AF3E-45C66B4DBA5A}.Debug|x64.Build.0 = Debug|Any CPU
{EEAAEE68-607B-4E33-AF3E-45C66B4DBA5A}.Debug|x86.ActiveCfg = Debug|Any CPU
{EEAAEE68-607B-4E33-AF3E-45C66B4DBA5A}.Debug|x86.Build.0 = Debug|Any CPU
{EEAAEE68-607B-4E33-AF3E-45C66B4DBA5A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{EEAAEE68-607B-4E33-AF3E-45C66B4DBA5A}.Release|Any CPU.Build.0 = Release|Any CPU
{EEAAEE68-607B-4E33-AF3E-45C66B4DBA5A}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{EEAAEE68-607B-4E33-AF3E-45C66B4DBA5A}.Release|Mixed Platforms.Build.0 = Release|Any CPU
+ {EEAAEE68-607B-4E33-AF3E-45C66B4DBA5A}.Release|x64.ActiveCfg = Release|Any CPU
+ {EEAAEE68-607B-4E33-AF3E-45C66B4DBA5A}.Release|x64.Build.0 = Release|Any CPU
{EEAAEE68-607B-4E33-AF3E-45C66B4DBA5A}.Release|x86.ActiveCfg = Release|Any CPU
{EEAAEE68-607B-4E33-AF3E-45C66B4DBA5A}.Release|x86.Build.0 = Release|Any CPU
{76579C39-B829-490D-B8BE-1BD35FE8412E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{76579C39-B829-490D-B8BE-1BD35FE8412E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{76579C39-B829-490D-B8BE-1BD35FE8412E}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{76579C39-B829-490D-B8BE-1BD35FE8412E}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
+ {76579C39-B829-490D-B8BE-1BD35FE8412E}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {76579C39-B829-490D-B8BE-1BD35FE8412E}.Debug|x64.Build.0 = Debug|Any CPU
{76579C39-B829-490D-B8BE-1BD35FE8412E}.Debug|x86.ActiveCfg = Debug|Any CPU
{76579C39-B829-490D-B8BE-1BD35FE8412E}.Debug|x86.Build.0 = Debug|Any CPU
{76579C39-B829-490D-B8BE-1BD35FE8412E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{76579C39-B829-490D-B8BE-1BD35FE8412E}.Release|Any CPU.Build.0 = Release|Any CPU
{76579C39-B829-490D-B8BE-1BD35FE8412E}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{76579C39-B829-490D-B8BE-1BD35FE8412E}.Release|Mixed Platforms.Build.0 = Release|Any CPU
+ {76579C39-B829-490D-B8BE-1BD35FE8412E}.Release|x64.ActiveCfg = Release|Any CPU
+ {76579C39-B829-490D-B8BE-1BD35FE8412E}.Release|x64.Build.0 = Release|Any CPU
{76579C39-B829-490D-B8BE-1BD35FE8412E}.Release|x86.ActiveCfg = Release|Any CPU
{76579C39-B829-490D-B8BE-1BD35FE8412E}.Release|x86.Build.0 = Release|Any CPU
{35115D55-B69E-46D4-BB33-C9E9E6EC5E7A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{35115D55-B69E-46D4-BB33-C9E9E6EC5E7A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{35115D55-B69E-46D4-BB33-C9E9E6EC5E7A}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{35115D55-B69E-46D4-BB33-C9E9E6EC5E7A}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
+ {35115D55-B69E-46D4-BB33-C9E9E6EC5E7A}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {35115D55-B69E-46D4-BB33-C9E9E6EC5E7A}.Debug|x64.Build.0 = Debug|Any CPU
{35115D55-B69E-46D4-BB33-C9E9E6EC5E7A}.Debug|x86.ActiveCfg = Debug|Any CPU
{35115D55-B69E-46D4-BB33-C9E9E6EC5E7A}.Debug|x86.Build.0 = Debug|Any CPU
{35115D55-B69E-46D4-BB33-C9E9E6EC5E7A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{35115D55-B69E-46D4-BB33-C9E9E6EC5E7A}.Release|Any CPU.Build.0 = Release|Any CPU
{35115D55-B69E-46D4-BB33-C9E9E6EC5E7A}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{35115D55-B69E-46D4-BB33-C9E9E6EC5E7A}.Release|Mixed Platforms.Build.0 = Release|Any CPU
+ {35115D55-B69E-46D4-BB33-C9E9E6EC5E7A}.Release|x64.ActiveCfg = Release|Any CPU
+ {35115D55-B69E-46D4-BB33-C9E9E6EC5E7A}.Release|x64.Build.0 = Release|Any CPU
{35115D55-B69E-46D4-BB33-C9E9E6EC5E7A}.Release|x86.ActiveCfg = Release|Any CPU
{35115D55-B69E-46D4-BB33-C9E9E6EC5E7A}.Release|x86.Build.0 = Release|Any CPU
{ACB45E19-F520-4D0C-8916-B0CEB9C017FE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{ACB45E19-F520-4D0C-8916-B0CEB9C017FE}.Debug|Any CPU.Build.0 = Debug|Any CPU
{ACB45E19-F520-4D0C-8916-B0CEB9C017FE}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{ACB45E19-F520-4D0C-8916-B0CEB9C017FE}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
+ {ACB45E19-F520-4D0C-8916-B0CEB9C017FE}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {ACB45E19-F520-4D0C-8916-B0CEB9C017FE}.Debug|x64.Build.0 = Debug|Any CPU
{ACB45E19-F520-4D0C-8916-B0CEB9C017FE}.Debug|x86.ActiveCfg = Debug|Any CPU
{ACB45E19-F520-4D0C-8916-B0CEB9C017FE}.Debug|x86.Build.0 = Debug|Any CPU
{ACB45E19-F520-4D0C-8916-B0CEB9C017FE}.Release|Any CPU.ActiveCfg = Release|Any CPU
{ACB45E19-F520-4D0C-8916-B0CEB9C017FE}.Release|Any CPU.Build.0 = Release|Any CPU
{ACB45E19-F520-4D0C-8916-B0CEB9C017FE}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{ACB45E19-F520-4D0C-8916-B0CEB9C017FE}.Release|Mixed Platforms.Build.0 = Release|Any CPU
+ {ACB45E19-F520-4D0C-8916-B0CEB9C017FE}.Release|x64.ActiveCfg = Release|Any CPU
+ {ACB45E19-F520-4D0C-8916-B0CEB9C017FE}.Release|x64.Build.0 = Release|Any CPU
{ACB45E19-F520-4D0C-8916-B0CEB9C017FE}.Release|x86.ActiveCfg = Release|Any CPU
{ACB45E19-F520-4D0C-8916-B0CEB9C017FE}.Release|x86.Build.0 = Release|Any CPU
{0330FFF6-B4B5-42DD-8C99-26A789569000}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{0330FFF6-B4B5-42DD-8C99-26A789569000}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0330FFF6-B4B5-42DD-8C99-26A789569000}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{0330FFF6-B4B5-42DD-8C99-26A789569000}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
+ {0330FFF6-B4B5-42DD-8C99-26A789569000}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {0330FFF6-B4B5-42DD-8C99-26A789569000}.Debug|x64.Build.0 = Debug|Any CPU
{0330FFF6-B4B5-42DD-8C99-26A789569000}.Debug|x86.ActiveCfg = Debug|Any CPU
{0330FFF6-B4B5-42DD-8C99-26A789569000}.Debug|x86.Build.0 = Debug|Any CPU
{0330FFF6-B4B5-42DD-8C99-26A789569000}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0330FFF6-B4B5-42DD-8C99-26A789569000}.Release|Any CPU.Build.0 = Release|Any CPU
{0330FFF6-B4B5-42DD-8C99-26A789569000}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{0330FFF6-B4B5-42DD-8C99-26A789569000}.Release|Mixed Platforms.Build.0 = Release|Any CPU
+ {0330FFF6-B4B5-42DD-8C99-26A789569000}.Release|x64.ActiveCfg = Release|Any CPU
+ {0330FFF6-B4B5-42DD-8C99-26A789569000}.Release|x64.Build.0 = Release|Any CPU
{0330FFF6-B4B5-42DD-8C99-26A789569000}.Release|x86.ActiveCfg = Release|Any CPU
{0330FFF6-B4B5-42DD-8C99-26A789569000}.Release|x86.Build.0 = Release|Any CPU
{1657C79E-7755-4AEE-9D61-571295B69A30}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{1657C79E-7755-4AEE-9D61-571295B69A30}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1657C79E-7755-4AEE-9D61-571295B69A30}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{1657C79E-7755-4AEE-9D61-571295B69A30}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
+ {1657C79E-7755-4AEE-9D61-571295B69A30}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {1657C79E-7755-4AEE-9D61-571295B69A30}.Debug|x64.Build.0 = Debug|Any CPU
{1657C79E-7755-4AEE-9D61-571295B69A30}.Debug|x86.ActiveCfg = Debug|Any CPU
{1657C79E-7755-4AEE-9D61-571295B69A30}.Debug|x86.Build.0 = Debug|Any CPU
{1657C79E-7755-4AEE-9D61-571295B69A30}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1657C79E-7755-4AEE-9D61-571295B69A30}.Release|Any CPU.Build.0 = Release|Any CPU
{1657C79E-7755-4AEE-9D61-571295B69A30}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{1657C79E-7755-4AEE-9D61-571295B69A30}.Release|Mixed Platforms.Build.0 = Release|Any CPU
+ {1657C79E-7755-4AEE-9D61-571295B69A30}.Release|x64.ActiveCfg = Release|Any CPU
+ {1657C79E-7755-4AEE-9D61-571295B69A30}.Release|x64.Build.0 = Release|Any CPU
{1657C79E-7755-4AEE-9D61-571295B69A30}.Release|x86.ActiveCfg = Release|Any CPU
{1657C79E-7755-4AEE-9D61-571295B69A30}.Release|x86.Build.0 = Release|Any CPU
{8DA26CD1-1302-4CFD-9270-9FA1B7C6138B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{8DA26CD1-1302-4CFD-9270-9FA1B7C6138B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{8DA26CD1-1302-4CFD-9270-9FA1B7C6138B}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{8DA26CD1-1302-4CFD-9270-9FA1B7C6138B}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
+ {8DA26CD1-1302-4CFD-9270-9FA1B7C6138B}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {8DA26CD1-1302-4CFD-9270-9FA1B7C6138B}.Debug|x64.Build.0 = Debug|Any CPU
{8DA26CD1-1302-4CFD-9270-9FA1B7C6138B}.Debug|x86.ActiveCfg = Debug|Any CPU
{8DA26CD1-1302-4CFD-9270-9FA1B7C6138B}.Debug|x86.Build.0 = Debug|Any CPU
{8DA26CD1-1302-4CFD-9270-9FA1B7C6138B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8DA26CD1-1302-4CFD-9270-9FA1B7C6138B}.Release|Any CPU.Build.0 = Release|Any CPU
{8DA26CD1-1302-4CFD-9270-9FA1B7C6138B}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{8DA26CD1-1302-4CFD-9270-9FA1B7C6138B}.Release|Mixed Platforms.Build.0 = Release|Any CPU
+ {8DA26CD1-1302-4CFD-9270-9FA1B7C6138B}.Release|x64.ActiveCfg = Release|Any CPU
+ {8DA26CD1-1302-4CFD-9270-9FA1B7C6138B}.Release|x64.Build.0 = Release|Any CPU
{8DA26CD1-1302-4CFD-9270-9FA1B7C6138B}.Release|x86.ActiveCfg = Release|Any CPU
{8DA26CD1-1302-4CFD-9270-9FA1B7C6138B}.Release|x86.Build.0 = Release|Any CPU
{7AF5AD96-EB6E-4D0E-8ABE-C0B543C0F4C2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{7AF5AD96-EB6E-4D0E-8ABE-C0B543C0F4C2}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7AF5AD96-EB6E-4D0E-8ABE-C0B543C0F4C2}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{7AF5AD96-EB6E-4D0E-8ABE-C0B543C0F4C2}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
+ {7AF5AD96-EB6E-4D0E-8ABE-C0B543C0F4C2}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {7AF5AD96-EB6E-4D0E-8ABE-C0B543C0F4C2}.Debug|x64.Build.0 = Debug|Any CPU
{7AF5AD96-EB6E-4D0E-8ABE-C0B543C0F4C2}.Debug|x86.ActiveCfg = Debug|Any CPU
{7AF5AD96-EB6E-4D0E-8ABE-C0B543C0F4C2}.Debug|x86.Build.0 = Debug|Any CPU
{7AF5AD96-EB6E-4D0E-8ABE-C0B543C0F4C2}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7AF5AD96-EB6E-4D0E-8ABE-C0B543C0F4C2}.Release|Any CPU.Build.0 = Release|Any CPU
{7AF5AD96-EB6E-4D0E-8ABE-C0B543C0F4C2}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{7AF5AD96-EB6E-4D0E-8ABE-C0B543C0F4C2}.Release|Mixed Platforms.Build.0 = Release|Any CPU
+ {7AF5AD96-EB6E-4D0E-8ABE-C0B543C0F4C2}.Release|x64.ActiveCfg = Release|Any CPU
+ {7AF5AD96-EB6E-4D0E-8ABE-C0B543C0F4C2}.Release|x64.Build.0 = Release|Any CPU
{7AF5AD96-EB6E-4D0E-8ABE-C0B543C0F4C2}.Release|x86.ActiveCfg = Release|Any CPU
{7AF5AD96-EB6E-4D0E-8ABE-C0B543C0F4C2}.Release|x86.Build.0 = Release|Any CPU
{6AB3E514-5894-4131-9399-DC7D5284ADDB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{6AB3E514-5894-4131-9399-DC7D5284ADDB}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6AB3E514-5894-4131-9399-DC7D5284ADDB}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{6AB3E514-5894-4131-9399-DC7D5284ADDB}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
+ {6AB3E514-5894-4131-9399-DC7D5284ADDB}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {6AB3E514-5894-4131-9399-DC7D5284ADDB}.Debug|x64.Build.0 = Debug|Any CPU
{6AB3E514-5894-4131-9399-DC7D5284ADDB}.Debug|x86.ActiveCfg = Debug|Any CPU
{6AB3E514-5894-4131-9399-DC7D5284ADDB}.Debug|x86.Build.0 = Debug|Any CPU
{6AB3E514-5894-4131-9399-DC7D5284ADDB}.Release|Any CPU.ActiveCfg = Release|Any CPU
{6AB3E514-5894-4131-9399-DC7D5284ADDB}.Release|Any CPU.Build.0 = Release|Any CPU
{6AB3E514-5894-4131-9399-DC7D5284ADDB}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{6AB3E514-5894-4131-9399-DC7D5284ADDB}.Release|Mixed Platforms.Build.0 = Release|Any CPU
+ {6AB3E514-5894-4131-9399-DC7D5284ADDB}.Release|x64.ActiveCfg = Release|Any CPU
+ {6AB3E514-5894-4131-9399-DC7D5284ADDB}.Release|x64.Build.0 = Release|Any CPU
{6AB3E514-5894-4131-9399-DC7D5284ADDB}.Release|x86.ActiveCfg = Release|Any CPU
{6AB3E514-5894-4131-9399-DC7D5284ADDB}.Release|x86.Build.0 = Release|Any CPU
{86183DC3-02A8-4A68-8B60-71ECEC066E79}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{86183DC3-02A8-4A68-8B60-71ECEC066E79}.Debug|Any CPU.Build.0 = Debug|Any CPU
{86183DC3-02A8-4A68-8B60-71ECEC066E79}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{86183DC3-02A8-4A68-8B60-71ECEC066E79}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
+ {86183DC3-02A8-4A68-8B60-71ECEC066E79}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {86183DC3-02A8-4A68-8B60-71ECEC066E79}.Debug|x64.Build.0 = Debug|Any CPU
{86183DC3-02A8-4A68-8B60-71ECEC066E79}.Debug|x86.ActiveCfg = Debug|Any CPU
{86183DC3-02A8-4A68-8B60-71ECEC066E79}.Debug|x86.Build.0 = Debug|Any CPU
{86183DC3-02A8-4A68-8B60-71ECEC066E79}.Release|Any CPU.ActiveCfg = Release|Any CPU
{86183DC3-02A8-4A68-8B60-71ECEC066E79}.Release|Any CPU.Build.0 = Release|Any CPU
{86183DC3-02A8-4A68-8B60-71ECEC066E79}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{86183DC3-02A8-4A68-8B60-71ECEC066E79}.Release|Mixed Platforms.Build.0 = Release|Any CPU
+ {86183DC3-02A8-4A68-8B60-71ECEC066E79}.Release|x64.ActiveCfg = Release|Any CPU
+ {86183DC3-02A8-4A68-8B60-71ECEC066E79}.Release|x64.Build.0 = Release|Any CPU
{86183DC3-02A8-4A68-8B60-71ECEC066E79}.Release|x86.ActiveCfg = Release|Any CPU
{86183DC3-02A8-4A68-8B60-71ECEC066E79}.Release|x86.Build.0 = Release|Any CPU
{1790E052-646F-4529-B90E-6FEA95520D69}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{1790E052-646F-4529-B90E-6FEA95520D69}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1790E052-646F-4529-B90E-6FEA95520D69}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{1790E052-646F-4529-B90E-6FEA95520D69}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
+ {1790E052-646F-4529-B90E-6FEA95520D69}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {1790E052-646F-4529-B90E-6FEA95520D69}.Debug|x64.Build.0 = Debug|Any CPU
{1790E052-646F-4529-B90E-6FEA95520D69}.Debug|x86.ActiveCfg = Debug|Any CPU
{1790E052-646F-4529-B90E-6FEA95520D69}.Debug|x86.Build.0 = Debug|Any CPU
{1790E052-646F-4529-B90E-6FEA95520D69}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1790E052-646F-4529-B90E-6FEA95520D69}.Release|Any CPU.Build.0 = Release|Any CPU
{1790E052-646F-4529-B90E-6FEA95520D69}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{1790E052-646F-4529-B90E-6FEA95520D69}.Release|Mixed Platforms.Build.0 = Release|Any CPU
+ {1790E052-646F-4529-B90E-6FEA95520D69}.Release|x64.ActiveCfg = Release|Any CPU
+ {1790E052-646F-4529-B90E-6FEA95520D69}.Release|x64.Build.0 = Release|Any CPU
{1790E052-646F-4529-B90E-6FEA95520D69}.Release|x86.ActiveCfg = Release|Any CPU
{1790E052-646F-4529-B90E-6FEA95520D69}.Release|x86.Build.0 = Release|Any CPU
{2755BFE5-7421-4A31-A644-F817DF5CAA98}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{2755BFE5-7421-4A31-A644-F817DF5CAA98}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2755BFE5-7421-4A31-A644-F817DF5CAA98}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{2755BFE5-7421-4A31-A644-F817DF5CAA98}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
+ {2755BFE5-7421-4A31-A644-F817DF5CAA98}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {2755BFE5-7421-4A31-A644-F817DF5CAA98}.Debug|x64.Build.0 = Debug|Any CPU
{2755BFE5-7421-4A31-A644-F817DF5CAA98}.Debug|x86.ActiveCfg = Debug|Any CPU
{2755BFE5-7421-4A31-A644-F817DF5CAA98}.Debug|x86.Build.0 = Debug|Any CPU
{2755BFE5-7421-4A31-A644-F817DF5CAA98}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2755BFE5-7421-4A31-A644-F817DF5CAA98}.Release|Any CPU.Build.0 = Release|Any CPU
{2755BFE5-7421-4A31-A644-F817DF5CAA98}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{2755BFE5-7421-4A31-A644-F817DF5CAA98}.Release|Mixed Platforms.Build.0 = Release|Any CPU
+ {2755BFE5-7421-4A31-A644-F817DF5CAA98}.Release|x64.ActiveCfg = Release|Any CPU
+ {2755BFE5-7421-4A31-A644-F817DF5CAA98}.Release|x64.Build.0 = Release|Any CPU
{2755BFE5-7421-4A31-A644-F817DF5CAA98}.Release|x86.ActiveCfg = Release|Any CPU
{2755BFE5-7421-4A31-A644-F817DF5CAA98}.Release|x86.Build.0 = Release|Any CPU
{D399B84F-591B-4E98-92BA-B0F63E7B6957}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D399B84F-591B-4E98-92BA-B0F63E7B6957}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D399B84F-591B-4E98-92BA-B0F63E7B6957}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{D399B84F-591B-4E98-92BA-B0F63E7B6957}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
+ {D399B84F-591B-4E98-92BA-B0F63E7B6957}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {D399B84F-591B-4E98-92BA-B0F63E7B6957}.Debug|x64.Build.0 = Debug|Any CPU
{D399B84F-591B-4E98-92BA-B0F63E7B6957}.Debug|x86.ActiveCfg = Debug|Any CPU
{D399B84F-591B-4E98-92BA-B0F63E7B6957}.Debug|x86.Build.0 = Debug|Any CPU
{D399B84F-591B-4E98-92BA-B0F63E7B6957}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D399B84F-591B-4E98-92BA-B0F63E7B6957}.Release|Any CPU.Build.0 = Release|Any CPU
{D399B84F-591B-4E98-92BA-B0F63E7B6957}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{D399B84F-591B-4E98-92BA-B0F63E7B6957}.Release|Mixed Platforms.Build.0 = Release|Any CPU
+ {D399B84F-591B-4E98-92BA-B0F63E7B6957}.Release|x64.ActiveCfg = Release|Any CPU
+ {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
{3A7AD414-EBDE-4F92-B307-4E8F19B6117E}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
+ {3A7AD414-EBDE-4F92-B307-4E8F19B6117E}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {3A7AD414-EBDE-4F92-B307-4E8F19B6117E}.Debug|x64.Build.0 = Debug|Any CPU
{3A7AD414-EBDE-4F92-B307-4E8F19B6117E}.Debug|x86.ActiveCfg = Debug|Any CPU
{3A7AD414-EBDE-4F92-B307-4E8F19B6117E}.Debug|x86.Build.0 = Debug|Any CPU
{3A7AD414-EBDE-4F92-B307-4E8F19B6117E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{3A7AD414-EBDE-4F92-B307-4E8F19B6117E}.Release|Any CPU.Build.0 = Release|Any CPU
{3A7AD414-EBDE-4F92-B307-4E8F19B6117E}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{3A7AD414-EBDE-4F92-B307-4E8F19B6117E}.Release|Mixed Platforms.Build.0 = Release|Any CPU
+ {3A7AD414-EBDE-4F92-B307-4E8F19B6117E}.Release|x64.ActiveCfg = Release|Any CPU
+ {3A7AD414-EBDE-4F92-B307-4E8F19B6117E}.Release|x64.Build.0 = Release|Any CPU
{3A7AD414-EBDE-4F92-B307-4E8F19B6117E}.Release|x86.ActiveCfg = Release|Any CPU
{3A7AD414-EBDE-4F92-B307-4E8F19B6117E}.Release|x86.Build.0 = Release|Any CPU
{51563775-C659-4907-9BAF-9995BAB87D01}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{51563775-C659-4907-9BAF-9995BAB87D01}.Debug|Any CPU.Build.0 = Debug|Any CPU
{51563775-C659-4907-9BAF-9995BAB87D01}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{51563775-C659-4907-9BAF-9995BAB87D01}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
+ {51563775-C659-4907-9BAF-9995BAB87D01}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {51563775-C659-4907-9BAF-9995BAB87D01}.Debug|x64.Build.0 = Debug|Any CPU
{51563775-C659-4907-9BAF-9995BAB87D01}.Debug|x86.ActiveCfg = Debug|Any CPU
{51563775-C659-4907-9BAF-9995BAB87D01}.Debug|x86.Build.0 = Debug|Any CPU
{51563775-C659-4907-9BAF-9995BAB87D01}.Release|Any CPU.ActiveCfg = Release|Any CPU
{51563775-C659-4907-9BAF-9995BAB87D01}.Release|Any CPU.Build.0 = Release|Any CPU
{51563775-C659-4907-9BAF-9995BAB87D01}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{51563775-C659-4907-9BAF-9995BAB87D01}.Release|Mixed Platforms.Build.0 = Release|Any CPU
+ {51563775-C659-4907-9BAF-9995BAB87D01}.Release|x64.ActiveCfg = Release|Any CPU
+ {51563775-C659-4907-9BAF-9995BAB87D01}.Release|x64.Build.0 = Release|Any CPU
{51563775-C659-4907-9BAF-9995BAB87D01}.Release|x86.ActiveCfg = Release|Any CPU
{51563775-C659-4907-9BAF-9995BAB87D01}.Release|x86.Build.0 = Release|Any CPU
+ {BC0D4B56-1A5B-4D88-AFBF-68C0F2D545FB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {BC0D4B56-1A5B-4D88-AFBF-68C0F2D545FB}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {BC0D4B56-1A5B-4D88-AFBF-68C0F2D545FB}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
+ {BC0D4B56-1A5B-4D88-AFBF-68C0F2D545FB}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
+ {BC0D4B56-1A5B-4D88-AFBF-68C0F2D545FB}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {BC0D4B56-1A5B-4D88-AFBF-68C0F2D545FB}.Debug|x64.Build.0 = Debug|Any CPU
+ {BC0D4B56-1A5B-4D88-AFBF-68C0F2D545FB}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {BC0D4B56-1A5B-4D88-AFBF-68C0F2D545FB}.Debug|x86.Build.0 = Debug|Any CPU
+ {BC0D4B56-1A5B-4D88-AFBF-68C0F2D545FB}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {BC0D4B56-1A5B-4D88-AFBF-68C0F2D545FB}.Release|Any CPU.Build.0 = Release|Any CPU
+ {BC0D4B56-1A5B-4D88-AFBF-68C0F2D545FB}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
+ {BC0D4B56-1A5B-4D88-AFBF-68C0F2D545FB}.Release|Mixed Platforms.Build.0 = Release|Any CPU
+ {BC0D4B56-1A5B-4D88-AFBF-68C0F2D545FB}.Release|x64.ActiveCfg = Release|Any CPU
+ {BC0D4B56-1A5B-4D88-AFBF-68C0F2D545FB}.Release|x64.Build.0 = Release|Any CPU
+ {BC0D4B56-1A5B-4D88-AFBF-68C0F2D545FB}.Release|x86.ActiveCfg = Release|Any CPU
+ {BC0D4B56-1A5B-4D88-AFBF-68C0F2D545FB}.Release|x86.Build.0 = Release|Any CPU
+ {151B7C1C-8E47-48CC-B04C-7414001D0F7B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {151B7C1C-8E47-48CC-B04C-7414001D0F7B}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {151B7C1C-8E47-48CC-B04C-7414001D0F7B}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
+ {151B7C1C-8E47-48CC-B04C-7414001D0F7B}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
+ {151B7C1C-8E47-48CC-B04C-7414001D0F7B}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {151B7C1C-8E47-48CC-B04C-7414001D0F7B}.Debug|x64.Build.0 = Debug|Any CPU
+ {151B7C1C-8E47-48CC-B04C-7414001D0F7B}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {151B7C1C-8E47-48CC-B04C-7414001D0F7B}.Debug|x86.Build.0 = Debug|Any CPU
+ {151B7C1C-8E47-48CC-B04C-7414001D0F7B}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {151B7C1C-8E47-48CC-B04C-7414001D0F7B}.Release|Any CPU.Build.0 = Release|Any CPU
+ {151B7C1C-8E47-48CC-B04C-7414001D0F7B}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
+ {151B7C1C-8E47-48CC-B04C-7414001D0F7B}.Release|Mixed Platforms.Build.0 = Release|Any CPU
+ {151B7C1C-8E47-48CC-B04C-7414001D0F7B}.Release|x64.ActiveCfg = Release|Any CPU
+ {151B7C1C-8E47-48CC-B04C-7414001D0F7B}.Release|x64.Build.0 = Release|Any CPU
+ {151B7C1C-8E47-48CC-B04C-7414001D0F7B}.Release|x86.ActiveCfg = Release|Any CPU
+ {151B7C1C-8E47-48CC-B04C-7414001D0F7B}.Release|x86.Build.0 = Release|Any CPU
+ {EB473BEB-9231-484E-BB66-05453ECC21DE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {EB473BEB-9231-484E-BB66-05453ECC21DE}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {EB473BEB-9231-484E-BB66-05453ECC21DE}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
+ {EB473BEB-9231-484E-BB66-05453ECC21DE}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
+ {EB473BEB-9231-484E-BB66-05453ECC21DE}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {EB473BEB-9231-484E-BB66-05453ECC21DE}.Debug|x64.Build.0 = Debug|Any CPU
+ {EB473BEB-9231-484E-BB66-05453ECC21DE}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {EB473BEB-9231-484E-BB66-05453ECC21DE}.Debug|x86.Build.0 = Debug|Any CPU
+ {EB473BEB-9231-484E-BB66-05453ECC21DE}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {EB473BEB-9231-484E-BB66-05453ECC21DE}.Release|Any CPU.Build.0 = Release|Any CPU
+ {EB473BEB-9231-484E-BB66-05453ECC21DE}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
+ {EB473BEB-9231-484E-BB66-05453ECC21DE}.Release|Mixed Platforms.Build.0 = Release|Any CPU
+ {EB473BEB-9231-484E-BB66-05453ECC21DE}.Release|x64.ActiveCfg = Release|Any CPU
+ {EB473BEB-9231-484E-BB66-05453ECC21DE}.Release|x64.Build.0 = Release|Any CPU
+ {EB473BEB-9231-484E-BB66-05453ECC21DE}.Release|x86.ActiveCfg = Release|Any CPU
+ {EB473BEB-9231-484E-BB66-05453ECC21DE}.Release|x86.Build.0 = Release|Any CPU
+ {95DE3093-35C9-4DA1-ADDD-DD1E980AC809}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {95DE3093-35C9-4DA1-ADDD-DD1E980AC809}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {95DE3093-35C9-4DA1-ADDD-DD1E980AC809}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
+ {95DE3093-35C9-4DA1-ADDD-DD1E980AC809}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
+ {95DE3093-35C9-4DA1-ADDD-DD1E980AC809}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {95DE3093-35C9-4DA1-ADDD-DD1E980AC809}.Debug|x64.Build.0 = Debug|Any CPU
+ {95DE3093-35C9-4DA1-ADDD-DD1E980AC809}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {95DE3093-35C9-4DA1-ADDD-DD1E980AC809}.Debug|x86.Build.0 = Debug|Any CPU
+ {95DE3093-35C9-4DA1-ADDD-DD1E980AC809}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {95DE3093-35C9-4DA1-ADDD-DD1E980AC809}.Release|Any CPU.Build.0 = Release|Any CPU
+ {95DE3093-35C9-4DA1-ADDD-DD1E980AC809}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
+ {95DE3093-35C9-4DA1-ADDD-DD1E980AC809}.Release|Mixed Platforms.Build.0 = Release|Any CPU
+ {95DE3093-35C9-4DA1-ADDD-DD1E980AC809}.Release|x64.ActiveCfg = Release|Any CPU
+ {95DE3093-35C9-4DA1-ADDD-DD1E980AC809}.Release|x64.Build.0 = Release|Any CPU
+ {95DE3093-35C9-4DA1-ADDD-DD1E980AC809}.Release|x86.ActiveCfg = Release|Any CPU
+ {95DE3093-35C9-4DA1-ADDD-DD1E980AC809}.Release|x86.Build.0 = Release|Any CPU
+ {269FACA1-956D-4B32-9994-16F2C4CB364A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {269FACA1-956D-4B32-9994-16F2C4CB364A}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {269FACA1-956D-4B32-9994-16F2C4CB364A}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
+ {269FACA1-956D-4B32-9994-16F2C4CB364A}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
+ {269FACA1-956D-4B32-9994-16F2C4CB364A}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {269FACA1-956D-4B32-9994-16F2C4CB364A}.Debug|x64.Build.0 = Debug|Any CPU
+ {269FACA1-956D-4B32-9994-16F2C4CB364A}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {269FACA1-956D-4B32-9994-16F2C4CB364A}.Debug|x86.Build.0 = Debug|Any CPU
+ {269FACA1-956D-4B32-9994-16F2C4CB364A}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {269FACA1-956D-4B32-9994-16F2C4CB364A}.Release|Any CPU.Build.0 = Release|Any CPU
+ {269FACA1-956D-4B32-9994-16F2C4CB364A}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
+ {269FACA1-956D-4B32-9994-16F2C4CB364A}.Release|Mixed Platforms.Build.0 = Release|Any CPU
+ {269FACA1-956D-4B32-9994-16F2C4CB364A}.Release|x64.ActiveCfg = Release|Any CPU
+ {269FACA1-956D-4B32-9994-16F2C4CB364A}.Release|x64.Build.0 = Release|Any CPU
+ {269FACA1-956D-4B32-9994-16F2C4CB364A}.Release|x86.ActiveCfg = Release|Any CPU
+ {269FACA1-956D-4B32-9994-16F2C4CB364A}.Release|x86.Build.0 = Release|Any CPU
+ {A48DA86C-BD8E-4A99-95EC-7441232F0586}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {A48DA86C-BD8E-4A99-95EC-7441232F0586}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {A48DA86C-BD8E-4A99-95EC-7441232F0586}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
+ {A48DA86C-BD8E-4A99-95EC-7441232F0586}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
+ {A48DA86C-BD8E-4A99-95EC-7441232F0586}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {A48DA86C-BD8E-4A99-95EC-7441232F0586}.Debug|x64.Build.0 = Debug|Any CPU
+ {A48DA86C-BD8E-4A99-95EC-7441232F0586}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {A48DA86C-BD8E-4A99-95EC-7441232F0586}.Debug|x86.Build.0 = Debug|Any CPU
+ {A48DA86C-BD8E-4A99-95EC-7441232F0586}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {A48DA86C-BD8E-4A99-95EC-7441232F0586}.Release|Any CPU.Build.0 = Release|Any CPU
+ {A48DA86C-BD8E-4A99-95EC-7441232F0586}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
+ {A48DA86C-BD8E-4A99-95EC-7441232F0586}.Release|Mixed Platforms.Build.0 = Release|Any CPU
+ {A48DA86C-BD8E-4A99-95EC-7441232F0586}.Release|x64.ActiveCfg = Release|Any CPU
+ {A48DA86C-BD8E-4A99-95EC-7441232F0586}.Release|x64.Build.0 = Release|Any CPU
+ {A48DA86C-BD8E-4A99-95EC-7441232F0586}.Release|x86.ActiveCfg = Release|Any CPU
+ {A48DA86C-BD8E-4A99-95EC-7441232F0586}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -344,7 +528,6 @@ Global
{19711880-46DA-4A26-9E0F-9B2E41D27651} = {F8C0AA27-F3FB-4286-8E4C-47EF86B539FF}
{BEF0F5C3-EF4E-4649-9C49-D5E279A3CA2B} = {F8C0AA27-F3FB-4286-8E4C-47EF86B539FF}
{FC152CC4-054B-457E-8D91-389C5DE3C561} = {4D2B6A51-2F9F-44F5-8131-EA5CAC053652}
- {2286250A-52C8-4126-9F93-B1E45F0AD078} = {4D2B6A51-2F9F-44F5-8131-EA5CAC053652}
{EEAAEE68-607B-4E33-AF3E-45C66B4DBA5A} = {4D2B6A51-2F9F-44F5-8131-EA5CAC053652}
{76579C39-B829-490D-B8BE-1BD35FE8412E} = {4D2B6A51-2F9F-44F5-8131-EA5CAC053652}
{35115D55-B69E-46D4-BB33-C9E9E6EC5E7A} = {4D2B6A51-2F9F-44F5-8131-EA5CAC053652}
@@ -362,5 +545,11 @@ Global
{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}
+ {BC0D4B56-1A5B-4D88-AFBF-68C0F2D545FB} = {4D2B6A51-2F9F-44F5-8131-EA5CAC053652}
+ {151B7C1C-8E47-48CC-B04C-7414001D0F7B} = {4D2B6A51-2F9F-44F5-8131-EA5CAC053652}
+ {EB473BEB-9231-484E-BB66-05453ECC21DE} = {4D2B6A51-2F9F-44F5-8131-EA5CAC053652}
+ {95DE3093-35C9-4DA1-ADDD-DD1E980AC809} = {4D2B6A51-2F9F-44F5-8131-EA5CAC053652}
+ {269FACA1-956D-4B32-9994-16F2C4CB364A} = {4D2B6A51-2F9F-44F5-8131-EA5CAC053652}
+ {A48DA86C-BD8E-4A99-95EC-7441232F0586} = {4D2B6A51-2F9F-44F5-8131-EA5CAC053652}
EndGlobalSection
EndGlobal
diff --git a/samples/CookieSample/Startup.cs b/samples/CookieSample/Startup.cs
index 002d87888..0480556f6 100644
--- a/samples/CookieSample/Startup.cs
+++ b/samples/CookieSample/Startup.cs
@@ -1,5 +1,6 @@
using System.Linq;
using System.Security.Claims;
+using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
@@ -13,24 +14,21 @@ public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
- services.AddAuthentication();
+ services.AddCookieAuthentication();
}
public void Configure(IApplicationBuilder app, ILoggerFactory loggerfactory)
{
loggerfactory.AddConsole(LogLevel.Information);
- app.UseCookieAuthentication(new CookieAuthenticationOptions
- {
- AutomaticAuthenticate = true
- });
+ app.UseAuthentication();
app.Run(async context =>
{
if (!context.User.Identities.Any(identity => identity.IsAuthenticated))
{
var user = new ClaimsPrincipal(new ClaimsIdentity(new[] { new Claim(ClaimTypes.Name, "bob") }, CookieAuthenticationDefaults.AuthenticationScheme));
- await context.Authentication.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, user);
+ await context.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, user);
context.Response.ContentType = "text/plain";
await context.Response.WriteAsync("Hello First timer");
diff --git a/samples/CookieSessionSample/Startup.cs b/samples/CookieSessionSample/Startup.cs
index ecb61ab66..ca21070dc 100644
--- a/samples/CookieSessionSample/Startup.cs
+++ b/samples/CookieSessionSample/Startup.cs
@@ -4,6 +4,7 @@
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Hosting;
+using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
@@ -14,18 +15,14 @@ public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
- services.AddAuthentication();
+ services.AddCookieAuthentication(o => o.SessionStore = new MemoryCacheTicketStore());
}
public void Configure(IApplicationBuilder app, ILoggerFactory loggerfactory)
{
loggerfactory.AddConsole(LogLevel.Information);
- app.UseCookieAuthentication(new CookieAuthenticationOptions
- {
- AutomaticAuthenticate = true,
- SessionStore = new MemoryCacheTicketStore()
- });
+ app.UseAuthentication();
app.Run(async context =>
{
@@ -39,7 +36,7 @@ public void Configure(IApplicationBuilder app, ILoggerFactory loggerfactory)
claims.Add(new Claim(ClaimTypes.Role, "SomeRandomGroup" + i, ClaimValueTypes.String, "IssuedByBob", "OriginalIssuerJoe"));
}
- await context.Authentication.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme,
+ await context.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme,
new ClaimsPrincipal(new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme)));
context.Response.ContentType = "text/plain";
diff --git a/samples/JwtBearerSample/Startup.cs b/samples/JwtBearerSample/Startup.cs
index 4d1ca7476..202960198 100644
--- a/samples/JwtBearerSample/Startup.cs
+++ b/samples/JwtBearerSample/Startup.cs
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.IO;
+using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
@@ -42,7 +43,28 @@ public Startup(IHostingEnvironment env)
// For more information on how to configure your application, visit http://go.microsoft.com/fwlink/?LinkID=398940
public void ConfigureServices(IServiceCollection services)
{
- services.AddAuthentication();
+ services.AddJwtBearerAuthentication(o =>
+ {
+ // You also need to update /wwwroot/app/scripts/app.js
+ o.Authority = Configuration["jwt:authority"];
+ o.Audience = Configuration["jwt:audience"];
+ o.Events = new JwtBearerEvents()
+ {
+ OnAuthenticationFailed = c =>
+ {
+ c.HandleResponse();
+
+ c.Response.StatusCode = 500;
+ c.Response.ContentType = "text/plain";
+ if (Environment.IsDevelopment())
+ {
+ // Debug only, in production do not share exceptions with the remote host.
+ return c.Response.WriteAsync(c.Exception.ToString());
+ }
+ return c.Response.WriteAsync("An error occurred processing your authentication.");
+ }
+ };
+ });
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
@@ -69,44 +91,22 @@ public void Configure(IApplicationBuilder app)
app.UseDefaultFiles();
app.UseStaticFiles();
- app.UseJwtBearerAuthentication(new JwtBearerOptions
- {
- // You also need to update /wwwroot/app/scripts/app.js
- Authority = Configuration["jwt:authority"],
- Audience = Configuration["jwt:audience"],
- Events = new JwtBearerEvents()
- {
- OnAuthenticationFailed = c =>
- {
- c.HandleResponse();
-
- c.Response.StatusCode = 500;
- c.Response.ContentType = "text/plain";
- if (Environment.IsDevelopment())
- {
- // Debug only, in production do not share exceptions with the remote host.
- return c.Response.WriteAsync(c.Exception.ToString());
- }
- return c.Response.WriteAsync("An error occurred processing your authentication.");
- }
- }
- });
+ app.UseAuthentication();
// [Authorize] would usually handle this
app.Use(async (context, next) =>
{
- // Use this if options.AutomaticAuthenticate = false
+ // Use this if there are multiple authentication schemes
// var user = await context.Authentication.AuthenticateAsync(JwtBearerDefaults.AuthenticationScheme);
- var user = context.User; // We can do this because of options.AutomaticAuthenticate = true;
+ var user = context.User; // We can do this because of there's only a single authentication scheme
if (user?.Identity?.IsAuthenticated ?? false)
{
await next();
}
else
{
- // We can do this because of options.AutomaticChallenge = true;
- await context.Authentication.ChallengeAsync();
+ await context.ChallengeAsync(JwtBearerDefaults.AuthenticationScheme);
}
});
diff --git a/samples/OpenIdConnect.AzureAdSample/AuthPropertiesTokenCache.cs b/samples/OpenIdConnect.AzureAdSample/AuthPropertiesTokenCache.cs
index 54989c13a..7d9b39121 100644
--- a/samples/OpenIdConnect.AzureAdSample/AuthPropertiesTokenCache.cs
+++ b/samples/OpenIdConnect.AzureAdSample/AuthPropertiesTokenCache.cs
@@ -1,9 +1,8 @@
using System;
using System.Security.Claims;
+using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Http;
-using Microsoft.AspNetCore.Http.Authentication;
-using Microsoft.AspNetCore.Http.Features.Authentication;
using Microsoft.IdentityModel.Clients.ActiveDirectory;
namespace OpenIdConnect.AzureAdSample
@@ -58,10 +57,9 @@ private void BeforeAccessNotificationWithProperties(TokenCacheNotificationArgs a
private void BeforeAccessNotificationWithContext(TokenCacheNotificationArgs args)
{
// Retrieve the auth session with the cached tokens
- var authenticateContext = new AuthenticateContext(_signInScheme);
- _httpContext.Authentication.AuthenticateAsync(authenticateContext).Wait();
- _authProperties = new AuthenticationProperties(authenticateContext.Properties);
- _principal = authenticateContext.Principal;
+ var result = _httpContext.AuthenticateAsync(_signInScheme).Result;
+ _authProperties = result.Ticket.Properties;
+ _principal = result.Ticket.Principal;
BeforeAccessNotificationWithProperties(args);
}
@@ -87,7 +85,7 @@ private void AfterAccessNotificationWithContext(TokenCacheNotificationArgs args)
var cachedTokens = Serialize();
var cachedTokensText = Convert.ToBase64String(cachedTokens);
_authProperties.Items[TokenCacheKey] = cachedTokensText;
- _httpContext.Authentication.SignInAsync(_signInScheme, _principal, _authProperties).Wait();
+ _httpContext.SignInAsync(_signInScheme, _principal, _authProperties).Wait();
}
}
diff --git a/samples/OpenIdConnect.AzureAdSample/Startup.cs b/samples/OpenIdConnect.AzureAdSample/Startup.cs
index ec80cd651..07ed0f2b3 100644
--- a/samples/OpenIdConnect.AzureAdSample/Startup.cs
+++ b/samples/OpenIdConnect.AzureAdSample/Startup.cs
@@ -3,12 +3,12 @@
using System.Linq;
using System.Text.Encodings.Web;
using System.Threading.Tasks;
+using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Authentication.OpenIdConnect;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
-using Microsoft.AspNetCore.Http.Authentication;
using Microsoft.AspNetCore.Http.Extensions;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
@@ -37,10 +37,42 @@ public Startup(IHostingEnvironment env)
public IConfiguration Configuration { get; set; }
+ private string ClientId => Configuration["oidc:clientid"];
+ private string ClientSecret => Configuration["oidc:clientsecret"];
+ private string Authority => Configuration["oidc:authority"];
+ private string Resource => "https://graph.windows.net";
+
public void ConfigureServices(IServiceCollection services)
{
+ services.AddCookieAuthentication();
+
+ services.AddOpenIdConnectAuthentication(o =>
+ {
+ o.ClientId = ClientId;
+ o.ClientSecret = ClientSecret; // for code flow
+ o.Authority = Authority;
+ o.ResponseType = OpenIdConnectResponseType.CodeIdToken;
+ o.PostLogoutRedirectUri = "/signed-out";
+ // GetClaimsFromUserInfoEndpoint = true,
+ o.Events = new OpenIdConnectEvents()
+ {
+ OnAuthorizationCodeReceived = async context =>
+ {
+ var request = context.HttpContext.Request;
+ var currentUri = UriHelper.BuildAbsolute(request.Scheme, request.Host, request.PathBase, request.Path);
+ var credential = new ClientCredential(ClientId, ClientSecret);
+ var authContext = new AuthenticationContext(Authority, AuthPropertiesTokenCache.ForCodeRedemption(context.Properties));
+
+ var result = await authContext.AcquireTokenByAuthorizationCodeAsync(
+ context.ProtocolMessage.Code, new Uri(currentUri), credential, Resource);
+
+ context.HandleCodeRedemption(result.AccessToken, result.IdToken);
+ }
+ };
+ });
+
services.AddAuthentication(sharedOptions =>
- sharedOptions.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme);
+ sharedOptions.DefaultAuthenticationScheme = CookieAuthenticationDefaults.AuthenticationScheme);
}
public void Configure(IApplicationBuilder app, ILoggerFactory loggerfactory)
@@ -69,36 +101,7 @@ public void Configure(IApplicationBuilder app, ILoggerFactory loggerfactory)
}
});
- app.UseCookieAuthentication(new CookieAuthenticationOptions());
-
- var clientId = Configuration["oidc:clientid"];
- var clientSecret = Configuration["oidc:clientsecret"];
- var authority = Configuration["oidc:authority"];
- var resource = "https://graph.windows.net";
- app.UseOpenIdConnectAuthentication(new OpenIdConnectOptions
- {
- ClientId = clientId,
- ClientSecret = clientSecret, // for code flow
- Authority = authority,
- ResponseType = OpenIdConnectResponseType.CodeIdToken,
- PostLogoutRedirectUri = "/signed-out",
- // GetClaimsFromUserInfoEndpoint = true,
- Events = new OpenIdConnectEvents()
- {
- OnAuthorizationCodeReceived = async context =>
- {
- var request = context.HttpContext.Request;
- var currentUri = UriHelper.BuildAbsolute(request.Scheme, request.Host, request.PathBase, request.Path);
- var credential = new ClientCredential(clientId, clientSecret);
- var authContext = new AuthenticationContext(authority, AuthPropertiesTokenCache.ForCodeRedemption(context.Properties));
-
- var result = await authContext.AcquireTokenByAuthorizationCodeAsync(
- context.ProtocolMessage.Code, new Uri(currentUri), credential, resource);
-
- context.HandleCodeRedemption(result.AccessToken, result.IdToken);
- }
- }
- });
+ app.UseAuthentication();
app.Run(async context =>
{
@@ -111,13 +114,13 @@ public void Configure(IApplicationBuilder app, ILoggerFactory loggerfactory)
return;
}
- await context.Authentication.ChallengeAsync(
+ await context.ChallengeAsync(
OpenIdConnectDefaults.AuthenticationScheme,
new AuthenticationProperties { RedirectUri = "/" });
}
else if (context.Request.Path.Equals("/signout"))
{
- await context.Authentication.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
+ await context.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
await WriteHtmlAsync(context.Response,
async response =>
{
@@ -127,8 +130,8 @@ await WriteHtmlAsync(context.Response,
}
else if (context.Request.Path.Equals("/signout-remote"))
{
- await context.Authentication.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
- await context.Authentication.SignOutAsync(OpenIdConnectDefaults.AuthenticationScheme);
+ await context.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
+ await context.SignOutAsync(OpenIdConnectDefaults.AuthenticationScheme);
}
else if (context.Request.Path.Equals("/signed-out"))
{
@@ -141,7 +144,7 @@ await WriteHtmlAsync(context.Response,
}
else if (context.Request.Path.Equals("/remote-signedout"))
{
- await context.Authentication.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
+ await context.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
await WriteHtmlAsync(context.Response,
async response =>
{
@@ -153,7 +156,7 @@ await WriteHtmlAsync(context.Response,
{
if (!context.User.Identities.Any(identity => identity.IsAuthenticated))
{
- await context.Authentication.ChallengeAsync(OpenIdConnectDefaults.AuthenticationScheme, new AuthenticationProperties { RedirectUri = "/" });
+ await context.ChallengeAsync(OpenIdConnectDefaults.AuthenticationScheme, new AuthenticationProperties { RedirectUri = "/" });
return;
}
@@ -170,10 +173,10 @@ await WriteHtmlAsync(context.Response, async response =>
try
{
// Use ADAL to get the right token
- var authContext = new AuthenticationContext(authority, AuthPropertiesTokenCache.ForApiCalls(context, CookieAuthenticationDefaults.AuthenticationScheme));
- var credential = new ClientCredential(clientId, clientSecret);
+ var authContext = new AuthenticationContext(Authority, AuthPropertiesTokenCache.ForApiCalls(context, CookieAuthenticationDefaults.AuthenticationScheme));
+ var credential = new ClientCredential(ClientId, ClientSecret);
string userObjectID = context.User.FindFirst("http://schemas.microsoft.com/identity/claims/objectidentifier").Value;
- var result = await authContext.AcquireTokenSilentAsync(resource, credential, new UserIdentifier(userObjectID, UserIdentifierType.UniqueId));
+ var result = await authContext.AcquireTokenSilentAsync(Resource, credential, new UserIdentifier(userObjectID, UserIdentifierType.UniqueId));
await response.WriteAsync($"
access_token
{HtmlEncode(result.AccessToken)}
");
}
diff --git a/samples/OpenIdConnectSample/Startup.cs b/samples/OpenIdConnectSample/Startup.cs
index 587e1e9c1..27c6099b0 100644
--- a/samples/OpenIdConnectSample/Startup.cs
+++ b/samples/OpenIdConnectSample/Startup.cs
@@ -3,12 +3,12 @@
using System.Linq;
using System.Text.Encodings.Web;
using System.Threading.Tasks;
+using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Authentication.OpenIdConnect;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
-using Microsoft.AspNetCore.Http.Authentication;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
@@ -41,8 +41,39 @@ public Startup(IHostingEnvironment env)
public void ConfigureServices(IServiceCollection services)
{
+ services.AddCookieAuthentication();
+
+ services.AddOpenIdConnectAuthentication(o =>
+ {
+ o.ClientId = Configuration["oidc:clientid"];
+ o.ClientSecret = Configuration["oidc:clientsecret"]; // for code flow
+ o.Authority = Configuration["oidc:authority"];
+ o.ResponseType = OpenIdConnectResponseType.CodeIdToken;
+ o.GetClaimsFromUserInfoEndpoint = true;
+ o.Events = new OpenIdConnectEvents()
+ {
+ OnAuthenticationFailed = c =>
+ {
+ c.HandleResponse();
+
+ c.Response.StatusCode = 500;
+ c.Response.ContentType = "text/plain";
+ if (Environment.IsDevelopment())
+ {
+ // Debug only, in production do not share exceptions with the remote host.
+ return c.Response.WriteAsync(c.Exception.ToString());
+ }
+ return c.Response.WriteAsync("An error occurred processing your authentication.");
+ }
+ };
+ });
+
+
services.AddAuthentication(sharedOptions =>
- sharedOptions.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme);
+ {
+ sharedOptions.DefaultAuthenticationScheme = CookieAuthenticationDefaults.AuthenticationScheme;
+ sharedOptions.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
+ });
}
public void Configure(IApplicationBuilder app, ILoggerFactory loggerfactory)
@@ -72,32 +103,7 @@ public void Configure(IApplicationBuilder app, ILoggerFactory loggerfactory)
}
});
- app.UseCookieAuthentication(new CookieAuthenticationOptions());
-
- app.UseOpenIdConnectAuthentication(new OpenIdConnectOptions
- {
- ClientId = Configuration["oidc:clientid"],
- ClientSecret = Configuration["oidc:clientsecret"], // for code flow
- Authority = Configuration["oidc:authority"],
- ResponseType = OpenIdConnectResponseType.CodeIdToken,
- GetClaimsFromUserInfoEndpoint = true,
- Events = new OpenIdConnectEvents()
- {
- OnAuthenticationFailed = c =>
- {
- c.HandleResponse();
-
- c.Response.StatusCode = 500;
- c.Response.ContentType = "text/plain";
- if (Environment.IsDevelopment())
- {
- // Debug only, in production do not share exceptions with the remote host.
- return c.Response.WriteAsync(c.Exception.ToString());
- }
- return c.Response.WriteAsync("An error occurred processing your authentication.");
- }
- }
- });
+ app.UseAuthentication();
app.Run(async context =>
{
@@ -113,7 +119,7 @@ await WriteHtmlAsync(context.Response, async res =>
if (context.Request.Path.Equals("/signout"))
{
- await context.Authentication.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
+ await context.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
await WriteHtmlAsync(context.Response, async res =>
{
await context.Response.WriteAsync($"Signed out {HtmlEncode(context.User.Identity.Name)}
");
@@ -125,8 +131,8 @@ await WriteHtmlAsync(context.Response, async res =>
if (context.Request.Path.Equals("/signout-remote"))
{
// Redirects
- await context.Authentication.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
- await context.Authentication.SignOutAsync(OpenIdConnectDefaults.AuthenticationScheme, new AuthenticationProperties()
+ await context.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
+ await context.SignOutAsync(OpenIdConnectDefaults.AuthenticationScheme, new AuthenticationProperties()
{
RedirectUri = "/signedout"
});
@@ -135,7 +141,7 @@ await WriteHtmlAsync(context.Response, async res =>
if (context.Request.Path.Equals("/Account/AccessDenied"))
{
- await context.Authentication.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
+ await context.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
await WriteHtmlAsync(context.Response, async res =>
{
await context.Response.WriteAsync($"Access Denied for user {HtmlEncode(context.User.Identity.Name)} to resource '{HtmlEncode(context.Request.Query["ReturnUrl"])}'
");
@@ -158,7 +164,7 @@ await WriteHtmlAsync(context.Response, async res =>
{
// This is what [Authorize] calls
// The cookie middleware will intercept this 401 and redirect to /login
- await context.Authentication.ChallengeAsync();
+ await context.ChallengeAsync(CookieAuthenticationDefaults.AuthenticationScheme);
// This is what [Authorize(ActiveAuthenticationSchemes = OpenIdConnectDefaults.AuthenticationScheme)] calls
// await context.Authentication.ChallengeAsync(OpenIdConnectDefaults.AuthenticationScheme);
@@ -169,7 +175,7 @@ await WriteHtmlAsync(context.Response, async res =>
// Authenticated, but not authorized
if (context.Request.Path.Equals("/restricted") && !user.Identities.Any(identity => identity.HasClaim("special", "true")))
{
- await context.Authentication.ChallengeAsync();
+ await context.ChallengeAsync(CookieAuthenticationDefaults.AuthenticationScheme);
return;
}
diff --git a/samples/SocialSample/SocialSample.csproj b/samples/SocialSample/SocialSample.csproj
index 09ece106c..fe63ab5ca 100644
--- a/samples/SocialSample/SocialSample.csproj
+++ b/samples/SocialSample/SocialSample.csproj
@@ -22,6 +22,7 @@
+
diff --git a/samples/SocialSample/Startup.cs b/samples/SocialSample/Startup.cs
index 31ec187a0..ee6b986d3 100644
--- a/samples/SocialSample/Startup.cs
+++ b/samples/SocialSample/Startup.cs
@@ -14,7 +14,6 @@
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
-using Microsoft.AspNetCore.Http.Authentication;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
@@ -45,38 +44,6 @@ public Startup(IHostingEnvironment env)
public void ConfigureServices(IServiceCollection services)
{
- services.AddAuthentication(options => options.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme);
- }
-
- public void Configure(IApplicationBuilder app, ILoggerFactory loggerfactory)
- {
- loggerfactory.AddConsole(LogLevel.Information);
-
- // Simple error page to avoid a repo dependency.
- app.Use(async (context, next) =>
- {
- try
- {
- await next();
- }
- catch (Exception ex)
- {
- if (context.Response.HasStarted)
- {
- throw;
- }
- context.Response.StatusCode = 500;
- await context.Response.WriteAsync(ex.ToString());
- }
- });
-
- app.UseCookieAuthentication(new CookieAuthenticationOptions
- {
- AutomaticAuthenticate = true,
- AutomaticChallenge = true,
- LoginPath = new PathString("/login")
- });
-
if (string.IsNullOrEmpty(Configuration["facebook:appid"]))
{
// User-Secrets: https://docs.asp.net/en/latest/security/app-secrets.html
@@ -84,40 +51,44 @@ public void Configure(IApplicationBuilder app, ILoggerFactory loggerfactory)
throw new InvalidOperationException("User secrets must be configured for each authentication provider.");
}
+ services.AddCookieAuthentication(o => o.LoginPath = new PathString("/login"));
+
// You must first create an app with Facebook and add its ID and Secret to your user-secrets.
// https://developers.facebook.com/apps/
- app.UseFacebookAuthentication(new FacebookOptions
+ services.AddFacebookAuthentication(o =>
{
- AppId = Configuration["facebook:appid"],
- AppSecret = Configuration["facebook:appsecret"],
- Scope = { "email" },
- Fields = { "name", "email" },
- SaveTokens = true,
+ o.AppId = Configuration["facebook:appid"];
+ o.AppSecret = Configuration["facebook:appsecret"];
+ o.Scope.Add("email");
+ o.Fields.Add("name");
+ o.Fields.Add("email");
+ o.SaveTokens = true;
});
// You must first create an app with Google and add its ID and Secret to your user-secrets.
// https://console.developers.google.com/project
- app.UseOAuthAuthentication(new OAuthOptions
+ services.AddOAuthAuthentication("Google-AccessToken", o =>
{
- AuthenticationScheme = "Google-AccessToken",
- DisplayName = "Google-AccessToken",
- ClientId = Configuration["google:clientid"],
- ClientSecret = Configuration["google:clientsecret"],
- CallbackPath = new PathString("/signin-google-token"),
- AuthorizationEndpoint = GoogleDefaults.AuthorizationEndpoint,
- TokenEndpoint = GoogleDefaults.TokenEndpoint,
- Scope = { "openid", "profile", "email" },
- SaveTokens = true
+ o.DisplayName = "Google-AccessToken";
+ o.ClientId = Configuration["google:clientid"];
+ o.ClientSecret = Configuration["google:clientsecret"];
+ o.CallbackPath = new PathString("/signin-google-token");
+ o.AuthorizationEndpoint = GoogleDefaults.AuthorizationEndpoint;
+ o.TokenEndpoint = GoogleDefaults.TokenEndpoint;
+ o.Scope.Add("openid");
+ o.Scope.Add("profile");
+ o.Scope.Add("email");
+ o.SaveTokens = true;
});
// You must first create an app with Google and add its ID and Secret to your user-secrets.
// https://console.developers.google.com/project
- var googleOptions = new GoogleOptions
+ services.AddGoogleAuthentication(o =>
{
- ClientId = Configuration["google:clientid"],
- ClientSecret = Configuration["google:clientsecret"],
- SaveTokens = true,
- Events = new OAuthEvents()
+ o.ClientId = Configuration["google:clientid"];
+ o.ClientSecret = Configuration["google:clientsecret"];
+ o.SaveTokens = true;
+ o.Events = new OAuthEvents()
{
OnRemoteFailure = ctx =>
{
@@ -125,23 +96,23 @@ public void Configure(IApplicationBuilder app, ILoggerFactory loggerfactory)
ctx.HandleResponse();
return Task.FromResult(0);
}
- }
- };
- googleOptions.ClaimActions.MapJsonSubKey("urn:google:image", "image", "url");
- googleOptions.ClaimActions.Remove(ClaimTypes.GivenName);
- app.UseGoogleAuthentication(googleOptions);
+ };
+ o.ClaimActions.MapJsonSubKey("urn:google:image", "image", "url");
+ o.ClaimActions.Remove(ClaimTypes.GivenName);
+ });
// You must first create an app with Twitter and add its key and Secret to your user-secrets.
// https://apps.twitter.com/
- var twitterOptions = new TwitterOptions
+ services.AddTwitterAuthentication(o =>
{
- ConsumerKey = Configuration["twitter:consumerkey"],
- ConsumerSecret = Configuration["twitter:consumersecret"],
+ o.ConsumerKey = Configuration["twitter:consumerkey"];
+ o.ConsumerSecret = Configuration["twitter:consumersecret"];
// http://stackoverflow.com/questions/22627083/can-we-get-email-id-from-twitter-oauth-api/32852370#32852370
// http://stackoverflow.com/questions/36330675/get-users-email-from-twitter-api-for-external-login-authentication-asp-net-mvc?lq=1
- RetrieveUserDetails = true,
- SaveTokens = true,
- Events = new TwitterEvents()
+ o.RetrieveUserDetails = true;
+ o.SaveTokens = true;
+ o.ClaimActions.MapJsonKey("urn:twitter:profilepicture", "profile_image_url", ClaimTypes.Uri);
+ o.Events = new TwitterEvents()
{
OnRemoteFailure = ctx =>
{
@@ -149,10 +120,8 @@ public void Configure(IApplicationBuilder app, ILoggerFactory loggerfactory)
ctx.HandleResponse();
return Task.FromResult(0);
}
- }
- };
- twitterOptions.ClaimActions.MapJsonKey("urn:twitter:profilepicture", "profile_image_url", ClaimTypes.Uri);
- app.UseTwitterAuthentication(twitterOptions);
+ };
+ });
/* Azure AD app model v2 has restrictions that prevent the use of plain HTTP for redirect URLs.
Therefore, to authenticate through microsoft accounts, tryout the sample using the following URL:
@@ -160,59 +129,60 @@ public void Configure(IApplicationBuilder app, ILoggerFactory loggerfactory)
*/
// You must first create an app with Microsoft Account and add its ID and Secret to your user-secrets.
// https://apps.dev.microsoft.com/
- app.UseOAuthAuthentication(new OAuthOptions
+ services.AddOAuthAuthentication("Microsoft-AccessToken", o =>
{
- AuthenticationScheme = "Microsoft-AccessToken",
- DisplayName = "MicrosoftAccount-AccessToken",
- ClientId = Configuration["microsoftaccount:clientid"],
- ClientSecret = Configuration["microsoftaccount:clientsecret"],
- CallbackPath = new PathString("/signin-microsoft-token"),
- AuthorizationEndpoint = MicrosoftAccountDefaults.AuthorizationEndpoint,
- TokenEndpoint = MicrosoftAccountDefaults.TokenEndpoint,
- Scope = { "https://graph.microsoft.com/user.read" },
- SaveTokens = true
+ o.DisplayName = "MicrosoftAccount-AccessToken";
+ o.ClientId = Configuration["microsoftaccount:clientid"];
+ o.ClientSecret = Configuration["microsoftaccount:clientsecret"];
+ o.CallbackPath = new PathString("/signin-microsoft-token");
+ o.AuthorizationEndpoint = MicrosoftAccountDefaults.AuthorizationEndpoint;
+ o.TokenEndpoint = MicrosoftAccountDefaults.TokenEndpoint;
+ o.Scope.Add("https://graph.microsoft.com/user.read");
+ o.SaveTokens = true;
});
// You must first create an app with Microsoft Account and add its ID and Secret to your user-secrets.
// https://azure.microsoft.com/en-us/documentation/articles/active-directory-v2-app-registration/
- app.UseMicrosoftAccountAuthentication(new MicrosoftAccountOptions
+ services.AddMicrosoftAccountAuthentication(o =>
{
- DisplayName = "MicrosoftAccount",
- ClientId = Configuration["microsoftaccount:clientid"],
- ClientSecret = Configuration["microsoftaccount:clientsecret"],
- SaveTokens = true
+ o.ClientId = Configuration["microsoftaccount:clientid"];
+ o.ClientSecret = Configuration["microsoftaccount:clientsecret"];
+ o.SaveTokens = true;
});
// You must first create an app with GitHub and add its ID and Secret to your user-secrets.
// https://github.com/settings/applications/
- app.UseOAuthAuthentication(new OAuthOptions
+ services.AddOAuthAuthentication("GitHub-AccessToken", o =>
{
- AuthenticationScheme = "GitHub-AccessToken",
- DisplayName = "Github-AccessToken",
- ClientId = Configuration["github-token:clientid"],
- ClientSecret = Configuration["github-token:clientsecret"],
- CallbackPath = new PathString("/signin-github-token"),
- AuthorizationEndpoint = "https://github.com/login/oauth/authorize",
- TokenEndpoint = "https://github.com/login/oauth/access_token",
- SaveTokens = true
+ o.DisplayName = "Github-AccessToken";
+ o.ClientId = Configuration["github-token:clientid"];
+ o.ClientSecret = Configuration["github-token:clientsecret"];
+ o.CallbackPath = new PathString("/signin-github-token");
+ o.AuthorizationEndpoint = "https://github.com/login/oauth/authorize";
+ o.TokenEndpoint = "https://github.com/login/oauth/access_token";
+ o.SaveTokens = true;
+ o.ClaimActions.MapJsonKey(ClaimTypes.NameIdentifier, "id");
+ o.ClaimActions.MapJsonKey(ClaimTypes.Name, "login");
+ o.ClaimActions.MapJsonKey("urn:github:name", "name");
+ o.ClaimActions.MapJsonKey(ClaimTypes.Email, "email", ClaimValueTypes.Email);
+ o.ClaimActions.MapJsonKey("urn:github:url", "url");
});
// You must first create an app with GitHub and add its ID and Secret to your user-secrets.
// https://github.com/settings/applications/
- var githubOptions = new OAuthOptions
+ services.AddOAuthAuthentication("GitHub", o =>
{
- AuthenticationScheme = "GitHub",
- DisplayName = "Github",
- ClientId = Configuration["github:clientid"],
- ClientSecret = Configuration["github:clientsecret"],
- CallbackPath = new PathString("/signin-github"),
- AuthorizationEndpoint = "https://github.com/login/oauth/authorize",
- TokenEndpoint = "https://github.com/login/oauth/access_token",
- UserInformationEndpoint = "https://api.github.com/user",
- ClaimsIssuer = "OAuth2-Github",
- SaveTokens = true,
+ o.DisplayName = "Github";
+ o.ClientId = Configuration["github:clientid"];
+ o.ClientSecret = Configuration["github:clientsecret"];
+ o.CallbackPath = new PathString("/signin-github");
+ o.AuthorizationEndpoint = "https://github.com/login/oauth/authorize";
+ o.TokenEndpoint = "https://github.com/login/oauth/access_token";
+ o.UserInformationEndpoint = "https://api.github.com/user";
+ o.ClaimsIssuer = "OAuth2-Github";
+ o.SaveTokens = true;
// Retrieving user information is unique to each provider.
- Events = new OAuthEvents
+ o.Events = new OAuthEvents
{
OnCreatingTicket = async context =>
{
@@ -228,14 +198,19 @@ public void Configure(IApplicationBuilder app, ILoggerFactory loggerfactory)
context.RunClaimActions(user);
}
- }
- };
- githubOptions.ClaimActions.MapJsonKey(ClaimTypes.NameIdentifier, "id");
- githubOptions.ClaimActions.MapJsonKey(ClaimTypes.Name, "login");
- githubOptions.ClaimActions.MapJsonKey("urn:github:name", "name");
- githubOptions.ClaimActions.MapJsonKey(ClaimTypes.Email, "email", ClaimValueTypes.Email);
- githubOptions.ClaimActions.MapJsonKey("urn:github:url", "url");
- app.UseOAuthAuthentication(githubOptions);
+ };
+ });
+
+ services.AddAuthentication(options => options.DefaultAuthenticationScheme = CookieAuthenticationDefaults.AuthenticationScheme);
+ }
+
+ public void Configure(IApplicationBuilder app, ILoggerFactory loggerfactory)
+ {
+ loggerfactory.AddConsole(LogLevel.Information);
+
+ app.UseDeveloperExceptionPage();
+
+ app.UseAuthentication();
// Choose an authentication type
app.Map("/login", signinApp =>
@@ -247,16 +222,18 @@ public void Configure(IApplicationBuilder app, ILoggerFactory loggerfactory)
{
// By default the client will be redirect back to the URL that issued the challenge (/login?authtype=foo),
// send them to the home page instead (/).
- await context.Authentication.ChallengeAsync(authType, new AuthenticationProperties() { RedirectUri = "/" });
+ await context.ChallengeAsync(authType, new AuthenticationProperties() { RedirectUri = "/" });
return;
}
context.Response.ContentType = "text/html";
await context.Response.WriteAsync("");
await context.Response.WriteAsync("Choose an authentication scheme:
");
- foreach (var type in context.Authentication.GetAuthenticationSchemes())
+ var schemeProvider = context.RequestServices.GetRequiredService();
+ foreach (var provider in await schemeProvider.GetAllSchemesAsync())
{
- await context.Response.WriteAsync("" + (type.DisplayName ?? "(suppressed)") + "
");
+ // REVIEW: we lost access to display name (which is buried in the handler options)
+ await context.Response.WriteAsync("" + (provider.Name ?? "(suppressed)") + "
");
}
await context.Response.WriteAsync("");
});
@@ -268,7 +245,7 @@ public void Configure(IApplicationBuilder app, ILoggerFactory loggerfactory)
signoutApp.Run(async context =>
{
context.Response.ContentType = "text/html";
- await context.Authentication.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
+ await context.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
await context.Response.WriteAsync("");
await context.Response.WriteAsync("You have been logged out. Goodbye " + context.User.Identity.Name + "
");
await context.Response.WriteAsync("Home");
@@ -296,20 +273,20 @@ public void Configure(IApplicationBuilder app, ILoggerFactory loggerfactory)
var user = context.User;
// This is what [Authorize] calls
- // var user = await context.Authentication.AuthenticateAsync(AuthenticationManager.AutomaticScheme);
+ // var user = await context.AuthenticateAsync(AuthenticationManager.AutomaticScheme);
// This is what [Authorize(ActiveAuthenticationSchemes = MicrosoftAccountDefaults.AuthenticationScheme)] calls
- // var user = await context.Authentication.AuthenticateAsync(MicrosoftAccountDefaults.AuthenticationScheme);
+ // var user = await context.AuthenticateAsync(MicrosoftAccountDefaults.AuthenticationScheme);
// Deny anonymous request beyond this point.
if (user == null || !user.Identities.Any(identity => identity.IsAuthenticated))
{
// This is what [Authorize] calls
// The cookie middleware will intercept this 401 and redirect to /login
- await context.Authentication.ChallengeAsync();
+ await context.ChallengeAsync(CookieAuthenticationDefaults.AuthenticationScheme);
// This is what [Authorize(ActiveAuthenticationSchemes = MicrosoftAccountDefaults.AuthenticationScheme)] calls
- // await context.Authentication.ChallengeAsync(MicrosoftAccountDefaults.AuthenticationScheme);
+ // await context.ChallengeAsync(MicrosoftAccountDefaults.AuthenticationScheme);
return;
}
@@ -324,11 +301,11 @@ public void Configure(IApplicationBuilder app, ILoggerFactory loggerfactory)
}
await context.Response.WriteAsync("Tokens:
");
-
- await context.Response.WriteAsync("Access Token: " + await context.Authentication.GetTokenAsync("access_token") + "
");
- await context.Response.WriteAsync("Refresh Token: " + await context.Authentication.GetTokenAsync("refresh_token") + "
");
- await context.Response.WriteAsync("Token Type: " + await context.Authentication.GetTokenAsync("token_type") + "
");
- await context.Response.WriteAsync("expires_at: " + await context.Authentication.GetTokenAsync("expires_at") + "
");
+
+ await context.Response.WriteAsync("Access Token: " + await context.GetTokenAsync(CookieAuthenticationDefaults.AuthenticationScheme, "access_token") + "
");
+ await context.Response.WriteAsync("Refresh Token: " + await context.GetTokenAsync(CookieAuthenticationDefaults.AuthenticationScheme, "refresh_token") + "
");
+ await context.Response.WriteAsync("Token Type: " + await context.GetTokenAsync(CookieAuthenticationDefaults.AuthenticationScheme, "token_type") + "
");
+ await context.Response.WriteAsync("expires_at: " + await context.GetTokenAsync(CookieAuthenticationDefaults.AuthenticationScheme, "expires_at") + "
");
await context.Response.WriteAsync("Logout
");
await context.Response.WriteAsync("");
});
diff --git a/src/Microsoft.AspNetCore.Authentication.Cookies/CookieAppBuilderExtensions.cs b/src/Microsoft.AspNetCore.Authentication.Cookies/CookieAppBuilderExtensions.cs
index 765d1f51c..a84da794b 100644
--- a/src/Microsoft.AspNetCore.Authentication.Cookies/CookieAppBuilderExtensions.cs
+++ b/src/Microsoft.AspNetCore.Authentication.Cookies/CookieAppBuilderExtensions.cs
@@ -1,9 +1,8 @@
-// Copyright (c) .NET Foundation. All rights reserved.
+// 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 Microsoft.AspNetCore.Authentication.Cookies;
-using Microsoft.Extensions.Options;
namespace Microsoft.AspNetCore.Builder
{
@@ -13,38 +12,26 @@ namespace Microsoft.AspNetCore.Builder
public static class CookieAppBuilderExtensions
{
///
- /// Adds the middleware to the specified , which enables cookie authentication capabilities.
+ /// Obsolete, see https://go.microsoft.com/fwlink/?linkid=845470
///
/// The to add the middleware to.
/// A reference to this instance after the operation has completed.
+ [Obsolete("See https://go.microsoft.com/fwlink/?linkid=845470", error: true)]
public static IApplicationBuilder UseCookieAuthentication(this IApplicationBuilder app)
{
- if (app == null)
- {
- throw new ArgumentNullException(nameof(app));
- }
-
- return app.UseMiddleware();
+ throw new NotSupportedException("This method is no longer supported, see https://go.microsoft.com/fwlink/?linkid=845470");
}
///
- /// Adds the middleware to the specified , which enables cookie authentication capabilities.
+ /// Obsolete, see https://go.microsoft.com/fwlink/?linkid=845470
///
/// The to add the middleware to.
/// A that specifies options for the middleware.
/// A reference to this instance after the operation has completed.
+ [Obsolete("See https://go.microsoft.com/fwlink/?linkid=845470", error: true)]
public static IApplicationBuilder UseCookieAuthentication(this IApplicationBuilder app, CookieAuthenticationOptions options)
{
- if (app == null)
- {
- throw new ArgumentNullException(nameof(app));
- }
- if (options == null)
- {
- throw new ArgumentNullException(nameof(options));
- }
-
- return app.UseMiddleware(Options.Create(options));
+ throw new NotSupportedException("This method is no longer supported, see https://go.microsoft.com/fwlink/?linkid=845470");
}
}
}
\ No newline at end of file
diff --git a/src/Microsoft.AspNetCore.Authentication.Cookies/CookieAuthenticationHandler.cs b/src/Microsoft.AspNetCore.Authentication.Cookies/CookieAuthenticationHandler.cs
index 1f2b395b1..2a8d5712e 100644
--- a/src/Microsoft.AspNetCore.Authentication.Cookies/CookieAuthenticationHandler.cs
+++ b/src/Microsoft.AspNetCore.Authentication.Cookies/CookieAuthenticationHandler.cs
@@ -1,32 +1,87 @@
// 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 System.Text.Encodings.Web;
using System.Threading.Tasks;
-using Microsoft.AspNetCore.Builder;
+using Microsoft.AspNetCore.DataProtection;
using Microsoft.AspNetCore.Http;
-using Microsoft.AspNetCore.Http.Authentication;
using Microsoft.AspNetCore.Http.Features;
-using Microsoft.AspNetCore.Http.Features.Authentication;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Logging;
+using Microsoft.Extensions.Options;
using Microsoft.Net.Http.Headers;
namespace Microsoft.AspNetCore.Authentication.Cookies
{
- internal class CookieAuthenticationHandler : AuthenticationHandler
+ public class CookieAuthenticationHandler : AuthenticationHandler
{
private const string HeaderValueNoCache = "no-cache";
private const string HeaderValueMinusOne = "-1";
private const string SessionIdClaim = "Microsoft.AspNetCore.Authentication.Cookies-SessionId";
private bool _shouldRefresh;
+ private bool _signInCalled;
+ private bool _signOutCalled;
+
private DateTimeOffset? _refreshIssuedUtc;
private DateTimeOffset? _refreshExpiresUtc;
private string _sessionKey;
private Task _readCookieTask;
+ public CookieAuthenticationHandler(IOptionsSnapshot options, ILoggerFactory logger, UrlEncoder encoder, ISystemClock clock)
+ : base(options, logger, encoder, clock)
+ { }
+
+ ///
+ /// The handler calls methods on the events which give the application control at certain points where processing is occurring.
+ /// If it is not provided a default instance is supplied which does nothing when the methods are called.
+ ///
+ protected new CookieAuthenticationEvents Events
+ {
+ get { return (CookieAuthenticationEvents)base.Events; }
+ set { base.Events = value; }
+ }
+
+ public override async Task InitializeAsync(AuthenticationScheme scheme, HttpContext context)
+ {
+ await base.InitializeAsync(scheme, context);
+
+ // Cookies needs to finish the response
+ Context.Response.OnStarting(FinishResponseAsync);
+
+ Events = Events ?? new CookieAuthenticationEvents();
+
+ if (String.IsNullOrEmpty(Options.CookieName))
+ {
+ Options.CookieName = CookieAuthenticationDefaults.CookiePrefix + Scheme.Name;
+ }
+ if (Options.TicketDataFormat == null)
+ {
+ var provider = Options.DataProtectionProvider ?? Context.RequestServices.GetRequiredService();
+ var dataProtector = provider.CreateProtector(typeof(CookieAuthenticationHandler).FullName, Scheme.Name, "v2");
+ Options.TicketDataFormat = new TicketDataFormat(dataProtector);
+ }
+ if (Options.CookieManager == null)
+ {
+ Options.CookieManager = new ChunkingCookieManager();
+ }
+ if (!Options.LoginPath.HasValue)
+ {
+ Options.LoginPath = CookieAuthenticationDefaults.LoginPath;
+ }
+ if (!Options.LogoutPath.HasValue)
+ {
+ Options.LogoutPath = CookieAuthenticationDefaults.LogoutPath;
+ }
+ if (!Options.AccessDeniedPath.HasValue)
+ {
+ Options.AccessDeniedPath = CookieAuthenticationDefaults.AccessDeniedPath;
+ }
+ }
+
private Task EnsureCookieTicket()
{
// We only need to read the ticket once
@@ -39,7 +94,7 @@ private Task EnsureCookieTicket()
private void CheckForRefresh(AuthenticationTicket ticket)
{
- var currentUtc = Options.SystemClock.UtcNow;
+ var currentUtc = Clock.UtcNow;
var issuedUtc = ticket.Properties.IssuedUtc;
var expiresUtc = ticket.Properties.ExpiresUtc;
var allowRefresh = ticket.Properties.AllowRefresh ?? true;
@@ -63,7 +118,7 @@ private void RequestRefresh(AuthenticationTicket ticket)
if (issuedUtc != null && expiresUtc != null)
{
_shouldRefresh = true;
- var currentUtc = Options.SystemClock.UtcNow;
+ var currentUtc = Clock.UtcNow;
_refreshIssuedUtc = currentUtc;
var timeSpan = expiresUtc.Value.Subtract(issuedUtc.Value);
_refreshExpiresUtc = currentUtc.Add(timeSpan);
@@ -75,7 +130,7 @@ private async Task ReadCookieTicket()
var cookie = Options.CookieManager.GetRequestCookie(Context, Options.CookieName);
if (string.IsNullOrEmpty(cookie))
{
- return AuthenticateResult.Skip();
+ return AuthenticateResult.None();
}
var ticket = Options.TicketDataFormat.Unprotect(cookie, GetTlsTokenBinding());
@@ -99,7 +154,7 @@ private async Task ReadCookieTicket()
}
}
- var currentUtc = Options.SystemClock.UtcNow;
+ var currentUtc = Clock.UtcNow;
var issuedUtc = ticket.Properties.IssuedUtc;
var expiresUtc = ticket.Properties.ExpiresUtc;
@@ -126,8 +181,8 @@ protected override async Task HandleAuthenticateAsync()
return result;
}
- var context = new CookieValidatePrincipalContext(Context, result.Ticket, Options);
- await Options.Events.ValidatePrincipal(context);
+ var context = new CookieValidatePrincipalContext(Context, Scheme, result.Ticket, Options);
+ await Events.ValidatePrincipal(context);
if (context.Principal == null)
{
@@ -139,7 +194,7 @@ protected override async Task HandleAuthenticateAsync()
RequestRefresh(result.Ticket);
}
- return AuthenticateResult.Success(new AuthenticationTicket(context.Principal, context.Properties, Options.AuthenticationScheme));
+ return AuthenticateResult.Success(new AuthenticationTicket(context.Principal, context.Properties, Scheme.Name));
}
private CookieOptions BuildCookieOptions()
@@ -163,10 +218,10 @@ private CookieOptions BuildCookieOptions()
return cookieOptions;
}
- protected override async Task FinishResponseAsync()
+ protected virtual async Task FinishResponseAsync()
{
// Only renew if requested, and neither sign in or sign out was called
- if (!_shouldRefresh || SignInAccepted || SignOutAccepted)
+ if (!_shouldRefresh || _signInCalled || _signOutCalled)
{
return;
}
@@ -192,8 +247,8 @@ protected override async Task FinishResponseAsync()
var principal = new ClaimsPrincipal(
new ClaimsIdentity(
new[] { new Claim(SessionIdClaim, _sessionKey, ClaimValueTypes.String, Options.ClaimsIssuer) },
- Options.AuthenticationScheme));
- ticket = new AuthenticationTicket(principal, null, Options.AuthenticationScheme);
+ Scheme.Name));
+ ticket = new AuthenticationTicket(principal, null, Scheme.Name);
}
var cookieValue = Options.TicketDataFormat.Protect(ticket, GetTlsTokenBinding());
@@ -216,16 +271,18 @@ protected override async Task FinishResponseAsync()
protected override async Task HandleSignInAsync(SignInContext signin)
{
+ _signInCalled = true;
+
// Process the request cookie to initialize members like _sessionKey.
var result = await EnsureCookieTicket();
var cookieOptions = BuildCookieOptions();
var signInContext = new CookieSigningInContext(
Context,
+ Scheme,
Options,
- Options.AuthenticationScheme,
signin.Principal,
- new AuthenticationProperties(signin.Properties),
+ signin.Properties,
cookieOptions);
DateTimeOffset issuedUtc;
@@ -235,7 +292,7 @@ protected override async Task HandleSignInAsync(SignInContext signin)
}
else
{
- issuedUtc = Options.SystemClock.UtcNow;
+ issuedUtc = Clock.UtcNow;
signInContext.Properties.IssuedUtc = issuedUtc;
}
@@ -244,7 +301,7 @@ protected override async Task HandleSignInAsync(SignInContext signin)
signInContext.Properties.ExpiresUtc = issuedUtc.Add(Options.ExpireTimeSpan);
}
- await Options.Events.SigningIn(signInContext);
+ await Events.SigningIn(signInContext);
if (signInContext.Properties.IsPersistent)
{
@@ -264,7 +321,7 @@ protected override async Task HandleSignInAsync(SignInContext signin)
new ClaimsIdentity(
new[] { new Claim(SessionIdClaim, _sessionKey, ClaimValueTypes.String, Options.ClaimsIssuer) },
Options.ClaimsIssuer));
- ticket = new AuthenticationTicket(principal, null, Options.AuthenticationScheme);
+ ticket = new AuthenticationTicket(principal, null, Scheme.Name);
}
var cookieValue = Options.TicketDataFormat.Protect(ticket, GetTlsTokenBinding());
@@ -277,12 +334,13 @@ protected override async Task HandleSignInAsync(SignInContext signin)
var signedInContext = new CookieSignedInContext(
Context,
+ Scheme,
Options,
- Options.AuthenticationScheme,
+ Scheme.Name,
signInContext.Principal,
signInContext.Properties);
- await Options.Events.SignedIn(signedInContext);
+ await Events.SignedIn(signedInContext);
// Only redirect on the login path
var shouldRedirect = Options.LoginPath.HasValue && OriginalPath == Options.LoginPath;
@@ -291,6 +349,8 @@ protected override async Task HandleSignInAsync(SignInContext signin)
protected override async Task HandleSignOutAsync(SignOutContext signOutContext)
{
+ _signOutCalled = true;
+
// Process the request cookie to initialize members like _sessionKey.
var ticket = await EnsureCookieTicket();
var cookieOptions = BuildCookieOptions();
@@ -301,11 +361,12 @@ protected override async Task HandleSignOutAsync(SignOutContext signOutContext)
var context = new CookieSigningOutContext(
Context,
+ Scheme,
Options,
- new AuthenticationProperties(signOutContext.Properties),
+ signOutContext.Properties,
cookieOptions);
- await Options.Events.SigningOut(context);
+ await Events.SigningOut(context);
Options.CookieManager.DeleteCookie(
Context,
@@ -343,8 +404,8 @@ private async Task ApplyHeaders(bool shouldRedirectToReturnUrl, AuthenticationPr
if (redirectUri != null)
{
- await Options.Events.RedirectToReturnUrl(
- new CookieRedirectContext(Context, Options, redirectUri, properties));
+ await Events.RedirectToReturnUrl(
+ new CookieRedirectContext(Context, Scheme, Options, redirectUri, properties));
}
}
}
@@ -362,28 +423,27 @@ private static bool IsHostRelative(string path)
return path[0] == '/' && path[1] != '/' && path[1] != '\\';
}
- protected override async Task HandleForbiddenAsync(ChallengeContext context)
+ protected override async Task HandleForbiddenAsync(ChallengeContext context)
{
- var properties = new AuthenticationProperties(context.Properties);
+ var properties = context.Properties;
var returnUrl = properties.RedirectUri;
if (string.IsNullOrEmpty(returnUrl))
{
returnUrl = OriginalPathBase + Request.Path + Request.QueryString;
}
var accessDeniedUri = Options.AccessDeniedPath + QueryString.Create(Options.ReturnUrlParameter, returnUrl);
- var redirectContext = new CookieRedirectContext(Context, Options, BuildRedirectUri(accessDeniedUri), properties);
- await Options.Events.RedirectToAccessDenied(redirectContext);
- return true;
+ var redirectContext = new CookieRedirectContext(Context, Scheme, Options, BuildRedirectUri(accessDeniedUri), properties);
+ await Events.RedirectToAccessDenied(redirectContext);
}
- protected override async Task HandleUnauthorizedAsync(ChallengeContext context)
+ protected override async Task HandleUnauthorizedAsync(ChallengeContext context)
{
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}
- var properties = new AuthenticationProperties(context.Properties);
+ var properties = context.Properties;
var redirectUri = properties.RedirectUri;
if (string.IsNullOrEmpty(redirectUri))
{
@@ -391,10 +451,8 @@ protected override async Task HandleUnauthorizedAsync(ChallengeContext con
}
var loginUri = Options.LoginPath + QueryString.Create(Options.ReturnUrlParameter, redirectUri);
- var redirectContext = new CookieRedirectContext(Context, Options, BuildRedirectUri(loginUri), properties);
- await Options.Events.RedirectToLogin(redirectContext);
- return true;
-
+ var redirectContext = new CookieRedirectContext(Context, Scheme, Options, BuildRedirectUri(loginUri), properties);
+ await Events.RedirectToLogin(redirectContext);
}
private string GetTlsTokenBinding()
diff --git a/src/Microsoft.AspNetCore.Authentication.Cookies/CookieAuthenticationMiddleware.cs b/src/Microsoft.AspNetCore.Authentication.Cookies/CookieAuthenticationMiddleware.cs
deleted file mode 100644
index 14d152a81..000000000
--- a/src/Microsoft.AspNetCore.Authentication.Cookies/CookieAuthenticationMiddleware.cs
+++ /dev/null
@@ -1,66 +0,0 @@
-// 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.Text.Encodings.Web;
-using Microsoft.AspNetCore.Builder;
-using Microsoft.AspNetCore.DataProtection;
-using Microsoft.AspNetCore.Http;
-using Microsoft.Extensions.Logging;
-using Microsoft.Extensions.Options;
-
-namespace Microsoft.AspNetCore.Authentication.Cookies
-{
- public class CookieAuthenticationMiddleware : AuthenticationMiddleware
- {
- public CookieAuthenticationMiddleware(
- RequestDelegate next,
- IDataProtectionProvider dataProtectionProvider,
- ILoggerFactory loggerFactory,
- UrlEncoder urlEncoder,
- IOptions options)
- : base(next, options, loggerFactory, urlEncoder)
- {
- if (dataProtectionProvider == null)
- {
- throw new ArgumentNullException(nameof(dataProtectionProvider));
- }
-
- if (Options.Events == null)
- {
- Options.Events = new CookieAuthenticationEvents();
- }
- if (String.IsNullOrEmpty(Options.CookieName))
- {
- Options.CookieName = CookieAuthenticationDefaults.CookiePrefix + Options.AuthenticationScheme;
- }
- if (Options.TicketDataFormat == null)
- {
- var provider = Options.DataProtectionProvider ?? dataProtectionProvider;
- var dataProtector = provider.CreateProtector(typeof(CookieAuthenticationMiddleware).FullName, Options.AuthenticationScheme, "v2");
- Options.TicketDataFormat = new TicketDataFormat(dataProtector);
- }
- if (Options.CookieManager == null)
- {
- Options.CookieManager = new ChunkingCookieManager();
- }
- if (!Options.LoginPath.HasValue)
- {
- Options.LoginPath = CookieAuthenticationDefaults.LoginPath;
- }
- if (!Options.LogoutPath.HasValue)
- {
- Options.LogoutPath = CookieAuthenticationDefaults.LogoutPath;
- }
- if (!Options.AccessDeniedPath.HasValue)
- {
- Options.AccessDeniedPath = CookieAuthenticationDefaults.AccessDeniedPath;
- }
- }
-
- protected override AuthenticationHandler CreateHandler()
- {
- return new CookieAuthenticationHandler();
- }
- }
-}
\ No newline at end of file
diff --git a/src/Microsoft.AspNetCore.Authentication.Cookies/CookieAuthenticationOptions.cs b/src/Microsoft.AspNetCore.Authentication.Cookies/CookieAuthenticationOptions.cs
index b42561250..703476c9c 100644
--- a/src/Microsoft.AspNetCore.Authentication.Cookies/CookieAuthenticationOptions.cs
+++ b/src/Microsoft.AspNetCore.Authentication.Cookies/CookieAuthenticationOptions.cs
@@ -2,19 +2,15 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
-using System.ComponentModel;
-using Microsoft.AspNetCore.Authentication;
-using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.DataProtection;
using Microsoft.AspNetCore.Http;
-using Microsoft.Extensions.Options;
-namespace Microsoft.AspNetCore.Builder
+namespace Microsoft.AspNetCore.Authentication.Cookies
{
///
- /// Configuration options for .
+ /// Configuration options for .
///
- public class CookieAuthenticationOptions : AuthenticationOptions, IOptions
+ public class CookieAuthenticationOptions : AuthenticationSchemeOptions
{
private string _cookieName;
@@ -23,14 +19,11 @@ public class CookieAuthenticationOptions : AuthenticationOptions, IOptions
public CookieAuthenticationOptions()
{
- AuthenticationScheme = CookieAuthenticationDefaults.AuthenticationScheme;
- AutomaticAuthenticate = true;
ReturnUrlParameter = CookieAuthenticationDefaults.ReturnUrlParameter;
ExpireTimeSpan = TimeSpan.FromDays(14);
SlidingExpiration = true;
CookieHttpOnly = true;
CookieSecure = CookieSecurePolicy.SameAsRequest;
- SystemClock = new SystemClock();
Events = new CookieAuthenticationEvents();
}
@@ -128,7 +121,11 @@ public string CookieName
/// calls methods on the provider which give the application control at certain points where processing is occurring.
/// If it is not provided a default instance is supplied which does nothing when the methods are called.
///
- public ICookieAuthenticationEvents Events { get; set; }
+ public new CookieAuthenticationEvents Events
+ {
+ get { return (CookieAuthenticationEvents)base.Events; }
+ set { base.Events = value; }
+ }
///
/// The TicketDataFormat is used to protect and unprotect the identity and other properties which are stored in the
@@ -150,13 +147,5 @@ public string CookieName
/// to the client. This can be used to mitigate potential problems with very large identities.
///
public ITicketStore SessionStore { get; set; }
-
- CookieAuthenticationOptions IOptions.Value
- {
- get
- {
- return this;
- }
- }
}
}
diff --git a/src/Microsoft.AspNetCore.Authentication.Cookies/CookieExtensions.cs b/src/Microsoft.AspNetCore.Authentication.Cookies/CookieExtensions.cs
new file mode 100644
index 000000000..e8a21d01b
--- /dev/null
+++ b/src/Microsoft.AspNetCore.Authentication.Cookies/CookieExtensions.cs
@@ -0,0 +1,21 @@
+// 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 Microsoft.AspNetCore.Authentication.Cookies;
+
+namespace Microsoft.Extensions.DependencyInjection
+{
+ public static class CookieExtensions
+ {
+ public static IServiceCollection AddCookieAuthentication(this IServiceCollection services) => services.AddCookieAuthentication(CookieAuthenticationDefaults.AuthenticationScheme);
+
+ public static IServiceCollection AddCookieAuthentication(this IServiceCollection services, string authenticationScheme) => services.AddCookieAuthentication(authenticationScheme, configureOptions: null);
+
+ public static IServiceCollection AddCookieAuthentication(this IServiceCollection services, Action configureOptions) =>
+ services.AddCookieAuthentication(CookieAuthenticationDefaults.AuthenticationScheme, configureOptions);
+
+ public static IServiceCollection AddCookieAuthentication(this IServiceCollection services, string authenticationScheme, Action configureOptions) =>
+ services.AddScheme(authenticationScheme, configureOptions);
+ }
+}
diff --git a/src/Microsoft.AspNetCore.Authentication.Cookies/Events/BaseCookieContext.cs b/src/Microsoft.AspNetCore.Authentication.Cookies/Events/BaseCookieContext.cs
index e5423fed2..4c949bb08 100644
--- a/src/Microsoft.AspNetCore.Authentication.Cookies/Events/BaseCookieContext.cs
+++ b/src/Microsoft.AspNetCore.Authentication.Cookies/Events/BaseCookieContext.cs
@@ -2,17 +2,18 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
-using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
namespace Microsoft.AspNetCore.Authentication.Cookies
{
- public class BaseCookieContext : BaseContext
+ public class BaseCookieContext : BaseAuthenticationContext
{
public BaseCookieContext(
HttpContext context,
- CookieAuthenticationOptions options)
- : base(context)
+ AuthenticationScheme scheme,
+ CookieAuthenticationOptions options,
+ AuthenticationProperties properties)
+ : base(context, scheme.Name, properties)
{
if (options == null)
{
@@ -23,5 +24,7 @@ public BaseCookieContext(
}
public CookieAuthenticationOptions Options { get; }
+
+ public AuthenticationScheme Scheme { get; }
}
}
diff --git a/src/Microsoft.AspNetCore.Authentication.Cookies/Events/CookieAuthenticationEvents.cs b/src/Microsoft.AspNetCore.Authentication.Cookies/Events/CookieAuthenticationEvents.cs
index 4364a2e54..5cb933ce1 100644
--- a/src/Microsoft.AspNetCore.Authentication.Cookies/Events/CookieAuthenticationEvents.cs
+++ b/src/Microsoft.AspNetCore.Authentication.Cookies/Events/CookieAuthenticationEvents.cs
@@ -13,7 +13,7 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
/// application only needs to override a few of the interface methods. This may be used as a base class
/// or may be instantiated directly.
///
- public class CookieAuthenticationEvents : ICookieAuthenticationEvents
+ public class CookieAuthenticationEvents
{
///
/// A delegate assigned to this property will be invoked when the related method is called.
diff --git a/src/Microsoft.AspNetCore.Authentication.Cookies/Events/CookieRedirectContext.cs b/src/Microsoft.AspNetCore.Authentication.Cookies/Events/CookieRedirectContext.cs
index 2cbb5ff09..0cd5cd87a 100644
--- a/src/Microsoft.AspNetCore.Authentication.Cookies/Events/CookieRedirectContext.cs
+++ b/src/Microsoft.AspNetCore.Authentication.Cookies/Events/CookieRedirectContext.cs
@@ -16,21 +16,19 @@ public class CookieRedirectContext : BaseCookieContext
/// Creates a new context object.
///
/// The HTTP request context
+ /// The scheme data
/// The cookie middleware options
/// The initial redirect URI
/// The .
- public CookieRedirectContext(HttpContext context, CookieAuthenticationOptions options, string redirectUri, AuthenticationProperties properties)
- : base(context, options)
+ public CookieRedirectContext(HttpContext context, AuthenticationScheme scheme, CookieAuthenticationOptions options, string redirectUri, AuthenticationProperties properties)
+ : base(context, scheme, options, properties)
{
RedirectUri = redirectUri;
- Properties = properties;
}
///
/// Gets or Sets the URI used for the redirect operation.
///
public string RedirectUri { get; set; }
-
- public AuthenticationProperties Properties { get; }
}
}
diff --git a/src/Microsoft.AspNetCore.Authentication.Cookies/Events/CookieSignedInContext.cs b/src/Microsoft.AspNetCore.Authentication.Cookies/Events/CookieSignedInContext.cs
index cfb7c5f1d..0e610c8b2 100644
--- a/src/Microsoft.AspNetCore.Authentication.Cookies/Events/CookieSignedInContext.cs
+++ b/src/Microsoft.AspNetCore.Authentication.Cookies/Events/CookieSignedInContext.cs
@@ -2,9 +2,7 @@
// 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.Builder;
using Microsoft.AspNetCore.Http;
-using Microsoft.AspNetCore.Http.Authentication;
namespace Microsoft.AspNetCore.Authentication.Cookies
{
@@ -17,36 +15,26 @@ public class CookieSignedInContext : BaseCookieContext
/// Creates a new instance of the context object.
///
/// The HTTP request context
- /// The middleware options
+ /// The scheme data
+ /// The handler options
/// Initializes AuthenticationScheme property
/// Initializes Principal property
/// Initializes Properties property
public CookieSignedInContext(
HttpContext context,
+ AuthenticationScheme scheme,
CookieAuthenticationOptions options,
string authenticationScheme,
ClaimsPrincipal principal,
AuthenticationProperties properties)
- : base(context, options)
+ : base(context, scheme, options, properties)
{
- AuthenticationScheme = authenticationScheme;
Principal = principal;
- Properties = properties;
}
- ///
- /// The name of the AuthenticationScheme creating a cookie
- ///
- public string AuthenticationScheme { get; }
-
///
/// Contains the claims that were converted into the outgoing cookie.
///
public ClaimsPrincipal Principal { get; }
-
- ///
- /// Contains the extra data that was contained in the outgoing cookie.
- ///
- public AuthenticationProperties Properties { get; }
}
}
diff --git a/src/Microsoft.AspNetCore.Authentication.Cookies/Events/CookieSigningInContext.cs b/src/Microsoft.AspNetCore.Authentication.Cookies/Events/CookieSigningInContext.cs
index d8b2307f3..f93060d21 100644
--- a/src/Microsoft.AspNetCore.Authentication.Cookies/Events/CookieSigningInContext.cs
+++ b/src/Microsoft.AspNetCore.Authentication.Cookies/Events/CookieSigningInContext.cs
@@ -2,9 +2,7 @@
// 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.Builder;
using Microsoft.AspNetCore.Http;
-using Microsoft.AspNetCore.Http.Authentication;
namespace Microsoft.AspNetCore.Authentication.Cookies
{
@@ -17,43 +15,30 @@ public class CookieSigningInContext : BaseCookieContext
/// Creates a new instance of the context object.
///
/// The HTTP request context
+ /// The scheme data
/// The middleware options
- /// Initializes AuthenticationScheme property
/// Initializes Principal property
/// Initializes Extra property
/// Initializes options for the authentication cookie.
public CookieSigningInContext(
HttpContext context,
+ AuthenticationScheme scheme,
CookieAuthenticationOptions options,
- string authenticationScheme,
ClaimsPrincipal principal,
AuthenticationProperties properties,
CookieOptions cookieOptions)
- : base(context, options)
+ : base(context, scheme, options, properties)
{
- AuthenticationScheme = authenticationScheme;
Principal = principal;
- Properties = properties;
CookieOptions = cookieOptions;
}
- ///
- /// The name of the AuthenticationScheme creating a cookie
- ///
- public string AuthenticationScheme { get; }
-
///
/// Contains the claims about to be converted into the outgoing cookie.
/// May be replaced or altered during the SigningIn call.
///
public ClaimsPrincipal Principal { get; set; }
- ///
- /// Contains the extra data about to be contained in the outgoing cookie.
- /// May be replaced or altered during the SigningIn call.
- ///
- public AuthenticationProperties Properties { get; set; }
-
///
/// The options for creating the outgoing cookie.
/// May be replace or altered during the SigningIn call.
diff --git a/src/Microsoft.AspNetCore.Authentication.Cookies/Events/CookieSigningOutContext.cs b/src/Microsoft.AspNetCore.Authentication.Cookies/Events/CookieSigningOutContext.cs
index 51c04a56b..0f4f4c7dc 100644
--- a/src/Microsoft.AspNetCore.Authentication.Cookies/Events/CookieSigningOutContext.cs
+++ b/src/Microsoft.AspNetCore.Authentication.Cookies/Events/CookieSigningOutContext.cs
@@ -1,9 +1,7 @@
// 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 Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
-using Microsoft.AspNetCore.Http.Authentication;
namespace Microsoft.AspNetCore.Authentication.Cookies
{
@@ -16,18 +14,19 @@ public class CookieSigningOutContext : BaseCookieContext
///
///
///
+ ///
///
///
///
public CookieSigningOutContext(
- HttpContext context,
+ HttpContext context,
+ AuthenticationScheme scheme,
CookieAuthenticationOptions options,
AuthenticationProperties properties,
CookieOptions cookieOptions)
- : base(context, options)
+ : base(context, scheme, options, properties)
{
CookieOptions = cookieOptions;
- Properties = properties;
}
///
@@ -35,7 +34,5 @@ public CookieSigningOutContext(
/// May be replace or altered during the SigningOut call.
///
public CookieOptions CookieOptions { get; set; }
-
- public AuthenticationProperties Properties { get; set; }
}
}
diff --git a/src/Microsoft.AspNetCore.Authentication.Cookies/Events/CookieValidatePrincipalContext.cs b/src/Microsoft.AspNetCore.Authentication.Cookies/Events/CookieValidatePrincipalContext.cs
index 57a28191c..3232ba52f 100644
--- a/src/Microsoft.AspNetCore.Authentication.Cookies/Events/CookieValidatePrincipalContext.cs
+++ b/src/Microsoft.AspNetCore.Authentication.Cookies/Events/CookieValidatePrincipalContext.cs
@@ -3,14 +3,12 @@
using System;
using System.Security.Claims;
-using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
-using Microsoft.AspNetCore.Http.Authentication;
namespace Microsoft.AspNetCore.Authentication.Cookies
{
///
- /// Context object passed to the ICookieAuthenticationProvider method ValidatePrincipal.
+ /// Context object passed to the CookieAuthenticationEvents ValidatePrincipal method.
///
public class CookieValidatePrincipalContext : BaseCookieContext
{
@@ -18,10 +16,11 @@ public class CookieValidatePrincipalContext : BaseCookieContext
/// Creates a new instance of the context object.
///
///
+ ///
/// Contains the initial values for identity and extra data
///
- public CookieValidatePrincipalContext(HttpContext context, AuthenticationTicket ticket, CookieAuthenticationOptions options)
- : base(context, options)
+ public CookieValidatePrincipalContext(HttpContext context, AuthenticationScheme scheme, AuthenticationTicket ticket, CookieAuthenticationOptions options)
+ : base(context, scheme, options, ticket?.Properties)
{
if (context == null)
{
@@ -39,7 +38,6 @@ public CookieValidatePrincipalContext(HttpContext context, AuthenticationTicket
}
Principal = ticket.Principal;
- Properties = ticket.Properties;
}
///
@@ -48,11 +46,6 @@ public CookieValidatePrincipalContext(HttpContext context, AuthenticationTicket
///
public ClaimsPrincipal Principal { get; private set; }
- ///
- /// Contains the extra meta-data arriving with the request ticket. May be altered.
- ///
- public AuthenticationProperties Properties { get; private set; }
-
///
/// If true, the cookie will be renewed
///
diff --git a/src/Microsoft.AspNetCore.Authentication.Cookies/Events/ICookieAuthenticationEvents.cs b/src/Microsoft.AspNetCore.Authentication.Cookies/Events/ICookieAuthenticationEvents.cs
deleted file mode 100644
index 1406d872d..000000000
--- a/src/Microsoft.AspNetCore.Authentication.Cookies/Events/ICookieAuthenticationEvents.cs
+++ /dev/null
@@ -1,64 +0,0 @@
-// 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.Threading.Tasks;
-
-namespace Microsoft.AspNetCore.Authentication.Cookies
-{
- ///
- /// Specifies callback methods which the invokes to enable developer control over the authentication process. />
- ///
- public interface ICookieAuthenticationEvents
- {
- ///
- /// Called each time a request principal has been validated by the middleware. By implementing this method the
- /// application may alter or reject the principal which has arrived with the request.
- ///
- /// Contains information about the login session as well as the user .
- /// A representing the completed operation.
- Task ValidatePrincipal(CookieValidatePrincipalContext context);
-
- ///
- /// Called when an endpoint has provided sign in information before it is converted into a cookie. By
- /// implementing this method the claims and extra information that go into the ticket may be altered.
- ///
- /// Contains information about the login session as well as the user .
- Task SigningIn(CookieSigningInContext context);
-
- ///
- /// Called when an endpoint has provided sign in information after it is converted into a cookie.
- ///
- /// Contains information about the login session as well as the user .
- Task SignedIn(CookieSignedInContext context);
-
- ///
- /// Called when a SignOut causes a redirect in the cookie middleware.
- ///
- /// Contains information about the event
- Task RedirectToLogout(CookieRedirectContext context);
-
- ///
- /// Called when a SignIn causes a redirect in the cookie middleware.
- ///
- /// Contains information about the event
- Task RedirectToLogin(CookieRedirectContext context);
-
- ///
- /// Called when redirecting back to the return url in the cookie middleware.
- ///
- /// Contains information about the event
- Task RedirectToReturnUrl(CookieRedirectContext context);
-
- ///
- /// Called when an access denied causes a redirect in the cookie middleware.
- ///
- /// Contains information about the event
- Task RedirectToAccessDenied(CookieRedirectContext context);
-
- ///
- /// Called during the sign-out flow to augment the cookie cleanup process.
- ///
- /// Contains information about the login session as well as information about the authentication cookie.
- Task SigningOut(CookieSigningOutContext context);
- }
-}
diff --git a/src/Microsoft.AspNetCore.Authentication.Cookies/Microsoft.AspNetCore.Authentication.Cookies.csproj b/src/Microsoft.AspNetCore.Authentication.Cookies/Microsoft.AspNetCore.Authentication.Cookies.csproj
index 4a711c318..3f2f0ee8d 100644
--- a/src/Microsoft.AspNetCore.Authentication.Cookies/Microsoft.AspNetCore.Authentication.Cookies.csproj
+++ b/src/Microsoft.AspNetCore.Authentication.Cookies/Microsoft.AspNetCore.Authentication.Cookies.csproj
@@ -17,9 +17,7 @@
-
-
diff --git a/src/Microsoft.AspNetCore.Authentication.Facebook/FacebookAppBuilderExtensions.cs b/src/Microsoft.AspNetCore.Authentication.Facebook/FacebookAppBuilderExtensions.cs
index 0435db794..1cf7ae13b 100644
--- a/src/Microsoft.AspNetCore.Authentication.Facebook/FacebookAppBuilderExtensions.cs
+++ b/src/Microsoft.AspNetCore.Authentication.Facebook/FacebookAppBuilderExtensions.cs
@@ -1,9 +1,8 @@
-// Copyright (c) .NET Foundation. All rights reserved.
+// 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 Microsoft.AspNetCore.Authentication.Facebook;
-using Microsoft.Extensions.Options;
namespace Microsoft.AspNetCore.Builder
{
@@ -13,38 +12,26 @@ namespace Microsoft.AspNetCore.Builder
public static class FacebookAppBuilderExtensions
{
///
- /// Adds the middleware to the specified , which enables Facebook authentication capabilities.
+ /// Obsolete, see https://go.microsoft.com/fwlink/?linkid=845470
///
/// The to add the middleware to.
/// A reference to this instance after the operation has completed.
+ [Obsolete("See https://go.microsoft.com/fwlink/?linkid=845470", error: true)]
public static IApplicationBuilder UseFacebookAuthentication(this IApplicationBuilder app)
{
- if (app == null)
- {
- throw new ArgumentNullException(nameof(app));
- }
-
- return app.UseMiddleware();
+ throw new NotSupportedException("This method is no longer supported, see https://go.microsoft.com/fwlink/?linkid=845470");
}
///
- /// Adds the middleware to the specified , which enables Facebook authentication capabilities.
+ /// Obsolete, see https://go.microsoft.com/fwlink/?linkid=845470
///
/// The to add the middleware to.
/// A that specifies options for the middleware.
/// A reference to this instance after the operation has completed.
+ [Obsolete("See https://go.microsoft.com/fwlink/?linkid=845470", error: true)]
public static IApplicationBuilder UseFacebookAuthentication(this IApplicationBuilder app, FacebookOptions options)
{
- if (app == null)
- {
- throw new ArgumentNullException(nameof(app));
- }
- if (options == null)
- {
- throw new ArgumentNullException(nameof(options));
- }
-
- return app.UseMiddleware(Options.Create(options));
+ throw new NotSupportedException("This method is no longer supported, see https://go.microsoft.com/fwlink/?linkid=845470");
}
}
-}
+}
\ No newline at end of file
diff --git a/src/Microsoft.AspNetCore.Authentication.Facebook/FacebookExtensions.cs b/src/Microsoft.AspNetCore.Authentication.Facebook/FacebookExtensions.cs
new file mode 100644
index 000000000..e0cbf7efb
--- /dev/null
+++ b/src/Microsoft.AspNetCore.Authentication.Facebook/FacebookExtensions.cs
@@ -0,0 +1,17 @@
+// 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 Microsoft.AspNetCore.Authentication.Facebook;
+
+namespace Microsoft.Extensions.DependencyInjection
+{
+ public static class FacebookAuthenticationOptionsExtensions
+ {
+ public static IServiceCollection AddFacebookAuthentication(this IServiceCollection services, Action configureOptions)
+ => services.AddFacebookAuthentication(FacebookDefaults.AuthenticationScheme, configureOptions);
+
+ public static IServiceCollection AddFacebookAuthentication(this IServiceCollection services, string authenticationScheme, Action configureOptions)
+ => services.AddScheme(authenticationScheme, configureOptions);
+ }
+}
diff --git a/src/Microsoft.AspNetCore.Authentication.Facebook/FacebookHandler.cs b/src/Microsoft.AspNetCore.Authentication.Facebook/FacebookHandler.cs
index 3c3c14c86..695a3c3c1 100644
--- a/src/Microsoft.AspNetCore.Authentication.Facebook/FacebookHandler.cs
+++ b/src/Microsoft.AspNetCore.Authentication.Facebook/FacebookHandler.cs
@@ -1,27 +1,27 @@
// 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.Globalization;
using System.Net.Http;
using System.Security.Claims;
using System.Security.Cryptography;
using System.Text;
+using System.Text.Encodings.Web;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authentication.OAuth;
-using Microsoft.AspNetCore.Builder;
-using Microsoft.AspNetCore.Http.Authentication;
+using Microsoft.AspNetCore.DataProtection;
using Microsoft.AspNetCore.WebUtilities;
+using Microsoft.Extensions.Logging;
+using Microsoft.Extensions.Options;
using Newtonsoft.Json.Linq;
namespace Microsoft.AspNetCore.Authentication.Facebook
{
internal class FacebookHandler : OAuthHandler
{
- public FacebookHandler(HttpClient httpClient)
- : base(httpClient)
- {
- }
+ public FacebookHandler(IOptions sharedOptions, IOptionsSnapshot options, ILoggerFactory logger, UrlEncoder encoder, IDataProtectionProvider dataProtection, ISystemClock clock)
+ : base(sharedOptions, options, logger, encoder, dataProtection, clock)
+ { }
protected override async Task CreateTicketAsync(ClaimsIdentity identity, AuthenticationProperties properties, OAuthTokenResponse tokens)
{
@@ -43,8 +43,8 @@ protected override async Task CreateTicketAsync(ClaimsIden
var payload = JObject.Parse(await response.Content.ReadAsStringAsync());
- var ticket = new AuthenticationTicket(new ClaimsPrincipal(identity), properties, Options.AuthenticationScheme);
- var context = new OAuthCreatingTicketContext(ticket, Context, Options, Backchannel, tokens, payload);
+ var ticket = new AuthenticationTicket(new ClaimsPrincipal(identity), properties, Scheme.Name);
+ var context = new OAuthCreatingTicketContext(ticket, Context, Scheme, Options, Backchannel, tokens, payload);
context.RunClaimActions();
await Options.Events.CreatingTicket(context);
diff --git a/src/Microsoft.AspNetCore.Authentication.Facebook/FacebookMiddleware.cs b/src/Microsoft.AspNetCore.Authentication.Facebook/FacebookMiddleware.cs
deleted file mode 100644
index ac57e8dde..000000000
--- a/src/Microsoft.AspNetCore.Authentication.Facebook/FacebookMiddleware.cs
+++ /dev/null
@@ -1,89 +0,0 @@
-// 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.Globalization;
-using System.Text.Encodings.Web;
-using Microsoft.AspNetCore.Authentication.OAuth;
-using Microsoft.AspNetCore.Builder;
-using Microsoft.AspNetCore.DataProtection;
-using Microsoft.AspNetCore.Http;
-using Microsoft.Extensions.Logging;
-using Microsoft.Extensions.Options;
-
-namespace Microsoft.AspNetCore.Authentication.Facebook
-{
- ///
- /// An ASP.NET Core middleware for authenticating users using Facebook.
- ///
- public class FacebookMiddleware : OAuthMiddleware
- {
- ///
- /// Initializes a new .
- ///
- /// The next middleware in the HTTP pipeline to invoke.
- ///
- ///
- ///
- ///
- /// Configuration options for the middleware.
- public FacebookMiddleware(
- RequestDelegate next,
- IDataProtectionProvider dataProtectionProvider,
- ILoggerFactory loggerFactory,
- UrlEncoder encoder,
- IOptions sharedOptions,
- IOptions options)
- : base(next, dataProtectionProvider, loggerFactory, encoder, sharedOptions, options)
- {
- if (next == null)
- {
- throw new ArgumentNullException(nameof(next));
- }
-
- if (dataProtectionProvider == null)
- {
- throw new ArgumentNullException(nameof(dataProtectionProvider));
- }
-
- if (loggerFactory == null)
- {
- throw new ArgumentNullException(nameof(loggerFactory));
- }
-
- if (encoder == null)
- {
- throw new ArgumentNullException(nameof(encoder));
- }
-
- if (sharedOptions == null)
- {
- throw new ArgumentNullException(nameof(sharedOptions));
- }
-
- if (options == null)
- {
- throw new ArgumentNullException(nameof(options));
- }
-
- if (string.IsNullOrEmpty(Options.AppId))
- {
- throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, Resources.Exception_OptionMustBeProvided, nameof(Options.AppId)));
- }
-
- if (string.IsNullOrEmpty(Options.AppSecret))
- {
- throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, Resources.Exception_OptionMustBeProvided, nameof(Options.AppSecret)));
- }
- }
-
- ///
- /// Provides the object for processing authentication-related requests.
- ///
- /// An configured with the supplied to the constructor.
- protected override AuthenticationHandler CreateHandler()
- {
- return new FacebookHandler(Backchannel);
- }
- }
-}
\ No newline at end of file
diff --git a/src/Microsoft.AspNetCore.Authentication.Facebook/FacebookOptions.cs b/src/Microsoft.AspNetCore.Authentication.Facebook/FacebookOptions.cs
index ae875bfaf..7010bb20a 100644
--- a/src/Microsoft.AspNetCore.Authentication.Facebook/FacebookOptions.cs
+++ b/src/Microsoft.AspNetCore.Authentication.Facebook/FacebookOptions.cs
@@ -1,16 +1,18 @@
// 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.Security.Claims;
using Microsoft.AspNetCore.Authentication;
-using Microsoft.AspNetCore.Authentication.Facebook;
+using System.Globalization;
+using Microsoft.AspNetCore.Authentication.OAuth;
using Microsoft.AspNetCore.Http;
-namespace Microsoft.AspNetCore.Builder
+namespace Microsoft.AspNetCore.Authentication.Facebook
{
///
- /// Configuration options for .
+ /// Configuration options for .
///
public class FacebookOptions : OAuthOptions
{
@@ -19,8 +21,6 @@ public class FacebookOptions : OAuthOptions
///
public FacebookOptions()
{
- AuthenticationScheme = FacebookDefaults.AuthenticationScheme;
- DisplayName = AuthenticationScheme;
CallbackPath = new PathString("/signin-facebook");
SendAppSecretProof = true;
AuthorizationEndpoint = FacebookDefaults.AuthorizationEndpoint;
@@ -49,6 +49,24 @@ public FacebookOptions()
ClaimActions.MapJsonKey("urn:facebook:timezone", "timezone");
}
+ ///
+ /// Check that the options are valid. Should throw an exception if things are not ok.
+ ///
+ public override void Validate()
+ {
+ if (string.IsNullOrEmpty(AppId))
+ {
+ throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, Resources.Exception_OptionMustBeProvided, nameof(AppId)), nameof(AppId));
+ }
+
+ if (string.IsNullOrEmpty(AppSecret))
+ {
+ throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, Resources.Exception_OptionMustBeProvided, nameof(AppSecret)), nameof(AppSecret));
+ }
+
+ base.Validate();
+ }
+
// Facebook uses a non-standard term for this field.
///
/// Gets or sets the Facebook-assigned appId.
diff --git a/src/Microsoft.AspNetCore.Authentication.Google/GoogleAppBuilderExtensions.cs b/src/Microsoft.AspNetCore.Authentication.Google/GoogleAppBuilderExtensions.cs
index 85a193d82..e9f1c6a98 100644
--- a/src/Microsoft.AspNetCore.Authentication.Google/GoogleAppBuilderExtensions.cs
+++ b/src/Microsoft.AspNetCore.Authentication.Google/GoogleAppBuilderExtensions.cs
@@ -3,6 +3,8 @@
using System;
using Microsoft.AspNetCore.Authentication.Google;
+using Microsoft.Extensions.Configuration;
+using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
namespace Microsoft.AspNetCore.Builder
@@ -13,41 +15,24 @@ namespace Microsoft.AspNetCore.Builder
public static class GoogleAppBuilderExtensions
{
///
- /// Adds the middleware to the specified ,
- /// which enables Google authentication capabilities.
+ /// Obsolete, see https://go.microsoft.com/fwlink/?linkid=845470
///
/// The to add the middleware to.
/// A reference to this instance after the operation has completed.
public static IApplicationBuilder UseGoogleAuthentication(this IApplicationBuilder app)
{
- if (app == null)
- {
- throw new ArgumentNullException(nameof(app));
- }
-
- return app.UseMiddleware();
+ throw new NotSupportedException("This method is no longer supported, see https://go.microsoft.com/fwlink/?linkid=845470");
}
///
- /// Adds the middleware to the specified ,
- /// which enables Google authentication capabilities.
+ /// Obsolete, see https://go.microsoft.com/fwlink/?linkid=845470
///
/// The to add the middleware to.
/// A that specifies options for the middleware.
/// A reference to this instance after the operation has completed.
public static IApplicationBuilder UseGoogleAuthentication(this IApplicationBuilder app, GoogleOptions options)
{
- if (app == null)
- {
- throw new ArgumentNullException(nameof(app));
- }
-
- if (options == null)
- {
- throw new ArgumentNullException(nameof(options));
- }
-
- return app.UseMiddleware(Options.Create(options));
+ throw new NotSupportedException("This method is no longer supported, see https://go.microsoft.com/fwlink/?linkid=845470");
}
}
}
diff --git a/src/Microsoft.AspNetCore.Authentication.Google/GoogleExtensions.cs b/src/Microsoft.AspNetCore.Authentication.Google/GoogleExtensions.cs
new file mode 100644
index 000000000..faa0dbb49
--- /dev/null
+++ b/src/Microsoft.AspNetCore.Authentication.Google/GoogleExtensions.cs
@@ -0,0 +1,17 @@
+// 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 Microsoft.AspNetCore.Authentication.Google;
+
+namespace Microsoft.Extensions.DependencyInjection
+{
+ public static class GoogleExtensions
+ {
+ public static IServiceCollection AddGoogleAuthentication(this IServiceCollection services, Action configureOptions) =>
+ services.AddGoogleAuthentication(GoogleDefaults.AuthenticationScheme, configureOptions);
+
+ public static IServiceCollection AddGoogleAuthentication(this IServiceCollection services, string authenticationScheme, Action configureOptions) =>
+ services.AddScheme(authenticationScheme, configureOptions);
+ }
+}
diff --git a/src/Microsoft.AspNetCore.Authentication.Google/GoogleHandler.cs b/src/Microsoft.AspNetCore.Authentication.Google/GoogleHandler.cs
index 87506e080..74f95c837 100644
--- a/src/Microsoft.AspNetCore.Authentication.Google/GoogleHandler.cs
+++ b/src/Microsoft.AspNetCore.Authentication.Google/GoogleHandler.cs
@@ -6,21 +6,22 @@
using System.Net.Http;
using System.Net.Http.Headers;
using System.Security.Claims;
+using System.Text.Encodings.Web;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authentication.OAuth;
-using Microsoft.AspNetCore.Builder;
-using Microsoft.AspNetCore.Http.Authentication;
+using Microsoft.AspNetCore.DataProtection;
using Microsoft.AspNetCore.WebUtilities;
+using Microsoft.Extensions.Logging;
+using Microsoft.Extensions.Options;
using Newtonsoft.Json.Linq;
namespace Microsoft.AspNetCore.Authentication.Google
{
internal class GoogleHandler : OAuthHandler
{
- public GoogleHandler(HttpClient httpClient)
- : base(httpClient)
- {
- }
+ public GoogleHandler(IOptions sharedOptions, IOptionsSnapshot options, ILoggerFactory logger, UrlEncoder encoder, IDataProtectionProvider dataProtection, ISystemClock clock)
+ : base(sharedOptions, options, logger, encoder, dataProtection, clock)
+ { }
protected override async Task CreateTicketAsync(
ClaimsIdentity identity,
@@ -40,8 +41,8 @@ protected override async Task CreateTicketAsync(
var payload = JObject.Parse(await response.Content.ReadAsStringAsync());
var principal = new ClaimsPrincipal(identity);
- var ticket = new AuthenticationTicket(principal, properties, Options.AuthenticationScheme);
- var context = new OAuthCreatingTicketContext(ticket, Context, Options, Backchannel, tokens, payload);
+ var ticket = new AuthenticationTicket(principal, properties, Scheme.Name);
+ var context = new OAuthCreatingTicketContext(ticket, Context, Scheme, Options, Backchannel, tokens, payload);
context.RunClaimActions();
await Options.Events.CreatingTicket(context);
diff --git a/src/Microsoft.AspNetCore.Authentication.Google/GoogleMiddleware.cs b/src/Microsoft.AspNetCore.Authentication.Google/GoogleMiddleware.cs
deleted file mode 100644
index 5f8afaff2..000000000
--- a/src/Microsoft.AspNetCore.Authentication.Google/GoogleMiddleware.cs
+++ /dev/null
@@ -1,81 +0,0 @@
-// 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.Text.Encodings.Web;
-using Microsoft.AspNetCore.Authentication.OAuth;
-using Microsoft.AspNetCore.Builder;
-using Microsoft.AspNetCore.DataProtection;
-using Microsoft.AspNetCore.Http;
-using Microsoft.Extensions.Logging;
-using Microsoft.Extensions.Options;
-
-namespace Microsoft.AspNetCore.Authentication.Google
-{
- ///
- /// An ASP.NET Core middleware for authenticating users using Google OAuth 2.0.
- ///
- public class GoogleMiddleware : OAuthMiddleware
- {
- ///
- /// Initializes a new .
- ///
- /// The next middleware in the HTTP pipeline to invoke.
- ///
- ///
- ///
- ///
- /// Configuration options for the middleware.
- public GoogleMiddleware(
- RequestDelegate next,
- IDataProtectionProvider dataProtectionProvider,
- ILoggerFactory loggerFactory,
- UrlEncoder encoder,
- IOptions sharedOptions,
- IOptions options)
- : base(next, dataProtectionProvider, loggerFactory, encoder, sharedOptions, options)
- {
- if (next == null)
- {
- throw new ArgumentNullException(nameof(next));
- }
-
- if (dataProtectionProvider == null)
- {
- throw new ArgumentNullException(nameof(dataProtectionProvider));
- }
-
- if (loggerFactory == null)
- {
- throw new ArgumentNullException(nameof(loggerFactory));
- }
-
- if (encoder == null)
- {
- throw new ArgumentNullException(nameof(encoder));
- }
-
- if (sharedOptions == null)
- {
- throw new ArgumentNullException(nameof(sharedOptions));
- }
-
- if (options == null)
- {
- throw new ArgumentNullException(nameof(options));
- }
- }
-
- ///
- /// Provides the object for processing authentication-related requests.
- ///
- ///
- /// An configured with the
- /// supplied to the constructor.
- ///
- protected override AuthenticationHandler CreateHandler()
- {
- return new GoogleHandler(Backchannel);
- }
- }
-}
\ No newline at end of file
diff --git a/src/Microsoft.AspNetCore.Authentication.Google/GoogleOptions.cs b/src/Microsoft.AspNetCore.Authentication.Google/GoogleOptions.cs
index d26977970..34028bc52 100644
--- a/src/Microsoft.AspNetCore.Authentication.Google/GoogleOptions.cs
+++ b/src/Microsoft.AspNetCore.Authentication.Google/GoogleOptions.cs
@@ -3,13 +3,13 @@
using System.Security.Claims;
using Microsoft.AspNetCore.Authentication;
-using Microsoft.AspNetCore.Authentication.Google;
+using Microsoft.AspNetCore.Authentication.OAuth;
using Microsoft.AspNetCore.Http;
-namespace Microsoft.AspNetCore.Builder
+namespace Microsoft.AspNetCore.Authentication.Google
{
///
- /// Configuration options for .
+ /// Configuration options for .
///
public class GoogleOptions : OAuthOptions
{
@@ -18,8 +18,6 @@ public class GoogleOptions : OAuthOptions
///
public GoogleOptions()
{
- AuthenticationScheme = GoogleDefaults.AuthenticationScheme;
- DisplayName = AuthenticationScheme;
CallbackPath = new PathString("/signin-google");
AuthorizationEndpoint = GoogleDefaults.AuthorizationEndpoint;
TokenEndpoint = GoogleDefaults.TokenEndpoint;
diff --git a/src/Microsoft.AspNetCore.Authentication.JwtBearer/Events/AuthenticationFailedContext.cs b/src/Microsoft.AspNetCore.Authentication.JwtBearer/Events/AuthenticationFailedContext.cs
index b3e0f0bdc..b47a9bab0 100644
--- a/src/Microsoft.AspNetCore.Authentication.JwtBearer/Events/AuthenticationFailedContext.cs
+++ b/src/Microsoft.AspNetCore.Authentication.JwtBearer/Events/AuthenticationFailedContext.cs
@@ -2,15 +2,14 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
-using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
namespace Microsoft.AspNetCore.Authentication.JwtBearer
{
public class AuthenticationFailedContext : BaseJwtBearerContext
{
- public AuthenticationFailedContext(HttpContext context, JwtBearerOptions options)
- : base(context, options)
+ public AuthenticationFailedContext(HttpContext context, AuthenticationScheme scheme, JwtBearerOptions options)
+ : base(context, scheme, options)
{
}
diff --git a/src/Microsoft.AspNetCore.Authentication.JwtBearer/Events/BaseJwtBearerContext.cs b/src/Microsoft.AspNetCore.Authentication.JwtBearer/Events/BaseJwtBearerContext.cs
index 5c28f2976..875bc6551 100644
--- a/src/Microsoft.AspNetCore.Authentication.JwtBearer/Events/BaseJwtBearerContext.cs
+++ b/src/Microsoft.AspNetCore.Authentication.JwtBearer/Events/BaseJwtBearerContext.cs
@@ -2,24 +2,21 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
-using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
namespace Microsoft.AspNetCore.Authentication.JwtBearer
{
public class BaseJwtBearerContext : BaseControlContext
{
- public BaseJwtBearerContext(HttpContext context, JwtBearerOptions options)
+ public BaseJwtBearerContext(HttpContext context, AuthenticationScheme scheme, JwtBearerOptions options)
: base(context)
{
- if (options == null)
- {
- throw new ArgumentNullException(nameof(options));
- }
-
- Options = options;
+ Options = options ?? throw new ArgumentNullException(nameof(options));
+ Scheme = scheme ?? throw new ArgumentException(nameof(scheme));
}
public JwtBearerOptions Options { get; }
+
+ public AuthenticationScheme Scheme { get; }
}
}
\ No newline at end of file
diff --git a/src/Microsoft.AspNetCore.Authentication.JwtBearer/Events/IJwtBearerEvents.cs b/src/Microsoft.AspNetCore.Authentication.JwtBearer/Events/IJwtBearerEvents.cs
deleted file mode 100644
index a7b8aeb55..000000000
--- a/src/Microsoft.AspNetCore.Authentication.JwtBearer/Events/IJwtBearerEvents.cs
+++ /dev/null
@@ -1,33 +0,0 @@
-// 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.Threading.Tasks;
-
-namespace Microsoft.AspNetCore.Authentication.JwtBearer
-{
- ///
- /// Specifies events which the invokes to enable developer control over the authentication process.
- ///
- public interface IJwtBearerEvents
- {
- ///
- /// Invoked if exceptions are thrown during request processing. The exceptions will be re-thrown after this event unless suppressed.
- ///
- Task AuthenticationFailed(AuthenticationFailedContext context);
-
- ///
- /// Invoked when a protocol message is first received.
- ///
- Task MessageReceived(MessageReceivedContext context);
-
- ///
- /// Invoked after the security token has passed validation and a ClaimsIdentity has been generated.
- ///
- Task TokenValidated(TokenValidatedContext context);
-
- ///
- /// Invoked to apply a challenge sent back to the caller.
- ///
- Task Challenge(JwtBearerChallengeContext context);
- }
-}
diff --git a/src/Microsoft.AspNetCore.Authentication.JwtBearer/Events/JwtBearerChallengeContext.cs b/src/Microsoft.AspNetCore.Authentication.JwtBearer/Events/JwtBearerChallengeContext.cs
index 584681253..e6f931f6d 100644
--- a/src/Microsoft.AspNetCore.Authentication.JwtBearer/Events/JwtBearerChallengeContext.cs
+++ b/src/Microsoft.AspNetCore.Authentication.JwtBearer/Events/JwtBearerChallengeContext.cs
@@ -2,16 +2,14 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
-using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
-using Microsoft.AspNetCore.Http.Authentication;
namespace Microsoft.AspNetCore.Authentication.JwtBearer
{
public class JwtBearerChallengeContext : BaseJwtBearerContext
{
- public JwtBearerChallengeContext(HttpContext context, JwtBearerOptions options, AuthenticationProperties properties)
- : base(context, options)
+ public JwtBearerChallengeContext(HttpContext context, AuthenticationScheme scheme, JwtBearerOptions options, AuthenticationProperties properties)
+ : base(context, scheme, options)
{
Properties = properties;
}
diff --git a/src/Microsoft.AspNetCore.Authentication.JwtBearer/Events/JwtBearerEvents.cs b/src/Microsoft.AspNetCore.Authentication.JwtBearer/Events/JwtBearerEvents.cs
index 8ac1c3631..c4e2e7b5a 100644
--- a/src/Microsoft.AspNetCore.Authentication.JwtBearer/Events/JwtBearerEvents.cs
+++ b/src/Microsoft.AspNetCore.Authentication.JwtBearer/Events/JwtBearerEvents.cs
@@ -8,9 +8,9 @@
namespace Microsoft.AspNetCore.Authentication.JwtBearer
{
///
- /// Specifies events which the invokes to enable developer control over the authentication process.
+ /// Specifies events which the invokes to enable developer control over the authentication process.
///
- public class JwtBearerEvents : IJwtBearerEvents
+ public class JwtBearerEvents
{
///
/// Invoked if exceptions are thrown during request processing. The exceptions will be re-thrown after this event unless suppressed.
diff --git a/src/Microsoft.AspNetCore.Authentication.JwtBearer/Events/MessageReceivedContext.cs b/src/Microsoft.AspNetCore.Authentication.JwtBearer/Events/MessageReceivedContext.cs
index a23f8356d..530a945ca 100644
--- a/src/Microsoft.AspNetCore.Authentication.JwtBearer/Events/MessageReceivedContext.cs
+++ b/src/Microsoft.AspNetCore.Authentication.JwtBearer/Events/MessageReceivedContext.cs
@@ -1,15 +1,14 @@
// 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 Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
namespace Microsoft.AspNetCore.Authentication.JwtBearer
{
public class MessageReceivedContext : BaseJwtBearerContext
{
- public MessageReceivedContext(HttpContext context, JwtBearerOptions options)
- : base(context, options)
+ public MessageReceivedContext(HttpContext context, AuthenticationScheme scheme, JwtBearerOptions options)
+ : base(context, scheme, options)
{
}
diff --git a/src/Microsoft.AspNetCore.Authentication.JwtBearer/Events/TokenValidatedContext.cs b/src/Microsoft.AspNetCore.Authentication.JwtBearer/Events/TokenValidatedContext.cs
index d6de5ca87..3667865da 100644
--- a/src/Microsoft.AspNetCore.Authentication.JwtBearer/Events/TokenValidatedContext.cs
+++ b/src/Microsoft.AspNetCore.Authentication.JwtBearer/Events/TokenValidatedContext.cs
@@ -1,7 +1,6 @@
// 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 Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using Microsoft.IdentityModel.Tokens;
@@ -9,8 +8,8 @@ namespace Microsoft.AspNetCore.Authentication.JwtBearer
{
public class TokenValidatedContext : BaseJwtBearerContext
{
- public TokenValidatedContext(HttpContext context, JwtBearerOptions options)
- : base(context, options)
+ public TokenValidatedContext(HttpContext context, AuthenticationScheme scheme, JwtBearerOptions options)
+ : base(context, scheme, options)
{
}
diff --git a/src/Microsoft.AspNetCore.Authentication.JwtBearer/JwtBearerAppBuilderExtensions.cs b/src/Microsoft.AspNetCore.Authentication.JwtBearer/JwtBearerAppBuilderExtensions.cs
index 13c06ca38..ca98d1ac4 100644
--- a/src/Microsoft.AspNetCore.Authentication.JwtBearer/JwtBearerAppBuilderExtensions.cs
+++ b/src/Microsoft.AspNetCore.Authentication.JwtBearer/JwtBearerAppBuilderExtensions.cs
@@ -1,4 +1,4 @@
-// Copyright (c) .NET Foundation. All rights reserved.
+// 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;
@@ -13,50 +13,26 @@ namespace Microsoft.AspNetCore.Builder
public static class JwtBearerAppBuilderExtensions
{
///
- /// Adds the middleware to the specified , which enables Bearer token processing capabilities.
- /// This middleware understands appropriately
- /// formatted and secured tokens which appear in the request header. If the Options.AuthenticationMode is Active, the
- /// claims within the bearer token are added to the current request's IPrincipal User. If the Options.AuthenticationMode
- /// is Passive, then the current request is not modified, but IAuthenticationManager AuthenticateAsync may be used at
- /// any time to obtain the claims from the request's bearer token.
- /// See also http://tools.ietf.org/html/rfc6749
+ /// Obsolete, see https://go.microsoft.com/fwlink/?linkid=845470
///
/// The to add the middleware to.
/// A reference to this instance after the operation has completed.
+ [Obsolete("See https://go.microsoft.com/fwlink/?linkid=845470", error: true)]
public static IApplicationBuilder UseJwtBearerAuthentication(this IApplicationBuilder app)
{
- if (app == null)
- {
- throw new ArgumentNullException(nameof(app));
- }
-
- return app.UseMiddleware();
+ throw new NotSupportedException("This method is no longer supported, see https://go.microsoft.com/fwlink/?linkid=845470");
}
///
- /// Adds the middleware to the specified , which enables Bearer token processing capabilities.
- /// This middleware understands appropriately
- /// formatted and secured tokens which appear in the request header. If the Options.AuthenticationMode is Active, the
- /// claims within the bearer token are added to the current request's IPrincipal User. If the Options.AuthenticationMode
- /// is Passive, then the current request is not modified, but IAuthenticationManager AuthenticateAsync may be used at
- /// any time to obtain the claims from the request's bearer token.
- /// See also http://tools.ietf.org/html/rfc6749
+ /// Obsolete, see https://go.microsoft.com/fwlink/?linkid=845470
///
/// The to add the middleware to.
/// A that specifies options for the middleware.
/// A reference to this instance after the operation has completed.
+ [Obsolete("See https://go.microsoft.com/fwlink/?linkid=845470", error: true)]
public static IApplicationBuilder UseJwtBearerAuthentication(this IApplicationBuilder app, JwtBearerOptions options)
{
- if (app == null)
- {
- throw new ArgumentNullException(nameof(app));
- }
- if (options == null)
- {
- throw new ArgumentNullException(nameof(options));
- }
-
- return app.UseMiddleware(Options.Create(options));
+ throw new NotSupportedException("This method is no longer supported, see https://go.microsoft.com/fwlink/?linkid=845470");
}
}
-}
+}
\ No newline at end of file
diff --git a/src/Microsoft.AspNetCore.Authentication.JwtBearer/JwtBearerExtensions.cs b/src/Microsoft.AspNetCore.Authentication.JwtBearer/JwtBearerExtensions.cs
new file mode 100644
index 000000000..575054b40
--- /dev/null
+++ b/src/Microsoft.AspNetCore.Authentication.JwtBearer/JwtBearerExtensions.cs
@@ -0,0 +1,17 @@
+// 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 Microsoft.AspNetCore.Authentication.JwtBearer;
+
+namespace Microsoft.Extensions.DependencyInjection
+{
+ public static class JwtBearerExtensions
+ {
+ public static IServiceCollection AddJwtBearerAuthentication(this IServiceCollection services, Action configureOptions) =>
+ services.AddJwtBearerAuthentication(JwtBearerDefaults.AuthenticationScheme, configureOptions);
+
+ public static IServiceCollection AddJwtBearerAuthentication(this IServiceCollection services, string authenticationScheme, Action configureOptions) =>
+ services.AddScheme(authenticationScheme, configureOptions);
+ }
+}
diff --git a/src/Microsoft.AspNetCore.Authentication.JwtBearer/JwtBearerHandler.cs b/src/Microsoft.AspNetCore.Authentication.JwtBearer/JwtBearerHandler.cs
index ee5575251..bbfccd947 100644
--- a/src/Microsoft.AspNetCore.Authentication.JwtBearer/JwtBearerHandler.cs
+++ b/src/Microsoft.AspNetCore.Authentication.JwtBearer/JwtBearerHandler.cs
@@ -4,14 +4,16 @@
using System;
using System.Collections.Generic;
using System.Linq;
+using System.Net.Http;
using System.Security.Claims;
using System.Text;
+using System.Text.Encodings.Web;
using System.Threading.Tasks;
-using Microsoft.AspNetCore.Builder;
+using Microsoft.AspNetCore.DataProtection;
using Microsoft.AspNetCore.Http;
-using Microsoft.AspNetCore.Http.Authentication;
-using Microsoft.AspNetCore.Http.Features.Authentication;
using Microsoft.Extensions.Logging;
+using Microsoft.Extensions.Options;
+using Microsoft.IdentityModel.Protocols;
using Microsoft.IdentityModel.Protocols.OpenIdConnect;
using Microsoft.IdentityModel.Tokens;
using Microsoft.Net.Http.Headers;
@@ -22,6 +24,64 @@ internal class JwtBearerHandler : AuthenticationHandler
{
private OpenIdConnectConfiguration _configuration;
+ public JwtBearerHandler(IOptionsSnapshot options, ILoggerFactory logger, UrlEncoder encoder, IDataProtectionProvider dataProtection, ISystemClock clock)
+ : base(options, logger, encoder, clock)
+ { }
+
+ ///
+ /// The handler calls methods on the events which give the application control at certain points where processing is occurring.
+ /// If it is not provided a default instance is supplied which does nothing when the methods are called.
+ ///
+ protected new JwtBearerEvents Events
+ {
+ get { return (JwtBearerEvents)base.Events; }
+ set { base.Events = value; }
+ }
+
+ public override async Task InitializeAsync(AuthenticationScheme scheme, HttpContext context)
+ {
+ await base.InitializeAsync(scheme, context);
+ Events = Events ?? new JwtBearerEvents();
+
+ if (string.IsNullOrEmpty(Options.TokenValidationParameters.ValidAudience) && !string.IsNullOrEmpty(Options.Audience))
+ {
+ Options.TokenValidationParameters.ValidAudience = Options.Audience;
+ }
+
+ if (Options.ConfigurationManager == null)
+ {
+ if (Options.Configuration != null)
+ {
+ Options.ConfigurationManager = new StaticConfigurationManager(Options.Configuration);
+ }
+ else if (!(string.IsNullOrEmpty(Options.MetadataAddress) && string.IsNullOrEmpty(Options.Authority)))
+ {
+ if (string.IsNullOrEmpty(Options.MetadataAddress) && !string.IsNullOrEmpty(Options.Authority))
+ {
+ Options.MetadataAddress = Options.Authority;
+ if (!Options.MetadataAddress.EndsWith("/", StringComparison.Ordinal))
+ {
+ Options.MetadataAddress += "/";
+ }
+
+ Options.MetadataAddress += ".well-known/openid-configuration";
+ }
+
+ if (Options.RequireHttpsMetadata && !Options.MetadataAddress.StartsWith("https://", StringComparison.OrdinalIgnoreCase))
+ {
+ throw new InvalidOperationException("The MetadataAddress or Authority must use HTTPS unless disabled for development by setting RequireHttpsMetadata=false.");
+ }
+
+ var httpClient = new HttpClient(Options.BackchannelHttpHandler ?? new HttpClientHandler());
+ httpClient.Timeout = Options.BackchannelTimeout;
+ httpClient.MaxResponseContentBufferSize = 1024 * 1024 * 10; // 10 MB
+
+ Options.ConfigurationManager = new ConfigurationManager(Options.MetadataAddress, new OpenIdConnectConfigurationRetriever(),
+ new HttpDocumentRetriever(httpClient) { RequireHttps = Options.RequireHttpsMetadata });
+ }
+ }
+ }
+
///
/// Searches the 'Authorization' header for a 'Bearer' token. If the 'Bearer' token is found, it is validated using set in the options.
///
@@ -33,11 +93,11 @@ protected override async Task HandleAuthenticateAsync()
try
{
// Give application opportunity to find from a different location, adjust, or reject token
- var messageReceivedContext = new MessageReceivedContext(Context, Options);
+ var messageReceivedContext = new MessageReceivedContext(Context, Scheme, Options);
// event can set the token
- await Options.Events.MessageReceived(messageReceivedContext);
- if (messageReceivedContext.CheckEventResult(out result))
+ await Events.MessageReceived(messageReceivedContext);
+ if (messageReceivedContext.ProcessingCompleted(out result))
{
return result;
}
@@ -52,7 +112,7 @@ protected override async Task HandleAuthenticateAsync()
// If no authorization header found, nothing to process further
if (string.IsNullOrEmpty(authorization))
{
- return AuthenticateResult.Skip();
+ return AuthenticateResult.None();
}
if (authorization.StartsWith("Bearer ", StringComparison.OrdinalIgnoreCase))
@@ -63,7 +123,7 @@ protected override async Task HandleAuthenticateAsync()
// If no token found, no further work possible
if (string.IsNullOrEmpty(token))
{
- return AuthenticateResult.Skip();
+ return AuthenticateResult.None();
}
}
@@ -120,15 +180,15 @@ protected override async Task HandleAuthenticateAsync()
Logger.TokenValidationSucceeded();
- var ticket = new AuthenticationTicket(principal, new AuthenticationProperties(), Options.AuthenticationScheme);
- var tokenValidatedContext = new TokenValidatedContext(Context, Options)
+ var ticket = new AuthenticationTicket(principal, new AuthenticationProperties(), Scheme.Name);
+ var tokenValidatedContext = new TokenValidatedContext(Context, Scheme, Options)
{
Ticket = ticket,
SecurityToken = validatedToken,
};
- await Options.Events.TokenValidated(tokenValidatedContext);
- if (tokenValidatedContext.CheckEventResult(out result))
+ await Events.TokenValidated(tokenValidatedContext);
+ if (tokenValidatedContext.ProcessingCompleted(out result))
{
return result;
}
@@ -148,13 +208,13 @@ protected override async Task HandleAuthenticateAsync()
if (validationFailures != null)
{
- var authenticationFailedContext = new AuthenticationFailedContext(Context, Options)
+ var authenticationFailedContext = new AuthenticationFailedContext(Context, Scheme, Options)
{
Exception = (validationFailures.Count == 1) ? validationFailures[0] : new AggregateException(validationFailures)
};
- await Options.Events.AuthenticationFailed(authenticationFailedContext);
- if (authenticationFailedContext.CheckEventResult(out result))
+ await Events.AuthenticationFailed(authenticationFailedContext);
+ if (authenticationFailedContext.ProcessingCompleted(out result))
{
return result;
}
@@ -168,13 +228,13 @@ protected override async Task HandleAuthenticateAsync()
{
Logger.ErrorProcessingMessage(ex);
- var authenticationFailedContext = new AuthenticationFailedContext(Context, Options)
+ var authenticationFailedContext = new AuthenticationFailedContext(Context, Scheme, Options)
{
Exception = ex
};
- await Options.Events.AuthenticationFailed(authenticationFailedContext);
- if (authenticationFailedContext.CheckEventResult(out result))
+ await Events.AuthenticationFailed(authenticationFailedContext);
+ if (authenticationFailedContext.ProcessingCompleted(out result))
{
return result;
}
@@ -183,11 +243,10 @@ protected override async Task HandleAuthenticateAsync()
}
}
- protected override async Task HandleUnauthorizedAsync(ChallengeContext context)
+ protected override async Task HandleUnauthorizedAsync(ChallengeContext context)
{
var authResult = await HandleAuthenticateOnceSafeAsync();
-
- var eventContext = new JwtBearerChallengeContext(Context, Options, new AuthenticationProperties(context.Properties))
+ var eventContext = new JwtBearerChallengeContext(Context, Scheme, Options, context.Properties)
{
AuthenticateFailure = authResult?.Failure
};
@@ -199,14 +258,10 @@ protected override async Task HandleUnauthorizedAsync(ChallengeContext con
eventContext.ErrorDescription = CreateErrorDescription(eventContext.AuthenticateFailure);
}
- await Options.Events.Challenge(eventContext);
- if (eventContext.HandledResponse)
- {
- return true;
- }
- if (eventContext.Skipped)
+ await Events.Challenge(eventContext);
+ if (eventContext.ProcessingCompleted(out var ignored))
{
- return false;
+ return;
}
Response.StatusCode = 401;
@@ -259,8 +314,6 @@ protected override async Task HandleUnauthorizedAsync(ChallengeContext con
Response.Headers.Append(HeaderNames.WWWAuthenticate, builder.ToString());
}
-
- return false;
}
private static string CreateErrorDescription(Exception authFailure)
diff --git a/src/Microsoft.AspNetCore.Authentication.JwtBearer/JwtBearerMiddleware.cs b/src/Microsoft.AspNetCore.Authentication.JwtBearer/JwtBearerMiddleware.cs
deleted file mode 100644
index bfb38793f..000000000
--- a/src/Microsoft.AspNetCore.Authentication.JwtBearer/JwtBearerMiddleware.cs
+++ /dev/null
@@ -1,108 +0,0 @@
-// 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.Net.Http;
-using System.Text.Encodings.Web;
-using Microsoft.AspNetCore.Builder;
-using Microsoft.AspNetCore.Http;
-using Microsoft.Extensions.Logging;
-using Microsoft.Extensions.Options;
-using Microsoft.IdentityModel.Protocols;
-using Microsoft.IdentityModel.Protocols.OpenIdConnect;
-
-namespace Microsoft.AspNetCore.Authentication.JwtBearer
-{
- ///
- /// Bearer authentication middleware component which is added to an HTTP pipeline. This class is not
- /// created by application code directly, instead it is added by calling the the IAppBuilder UseJwtBearerAuthentication
- /// extension method.
- ///
- public class JwtBearerMiddleware : AuthenticationMiddleware
- {
- ///
- /// Bearer authentication component which is added to an HTTP pipeline. This constructor is not
- /// called by application code directly, instead it is added by calling the the IAppBuilder UseJwtBearerAuthentication
- /// extension method.
- ///
- public JwtBearerMiddleware(
- RequestDelegate next,
- ILoggerFactory loggerFactory,
- UrlEncoder encoder,
- IOptions options)
- : base(next, options, loggerFactory, encoder)
- {
- if (next == null)
- {
- throw new ArgumentNullException(nameof(next));
- }
-
- if (loggerFactory == null)
- {
- throw new ArgumentNullException(nameof(loggerFactory));
- }
-
- if (encoder == null)
- {
- throw new ArgumentNullException(nameof(encoder));
- }
-
- if (options == null)
- {
- throw new ArgumentNullException(nameof(options));
- }
-
- if (Options.Events == null)
- {
- Options.Events = new JwtBearerEvents();
- }
-
- if (string.IsNullOrEmpty(Options.TokenValidationParameters.ValidAudience) && !string.IsNullOrEmpty(Options.Audience))
- {
- Options.TokenValidationParameters.ValidAudience = Options.Audience;
- }
-
- if (Options.ConfigurationManager == null)
- {
- if (Options.Configuration != null)
- {
- Options.ConfigurationManager = new StaticConfigurationManager(Options.Configuration);
- }
- else if (!(string.IsNullOrEmpty(Options.MetadataAddress) && string.IsNullOrEmpty(Options.Authority)))
- {
- if (string.IsNullOrEmpty(Options.MetadataAddress) && !string.IsNullOrEmpty(Options.Authority))
- {
- Options.MetadataAddress = Options.Authority;
- if (!Options.MetadataAddress.EndsWith("/", StringComparison.Ordinal))
- {
- Options.MetadataAddress += "/";
- }
-
- Options.MetadataAddress += ".well-known/openid-configuration";
- }
-
- if (Options.RequireHttpsMetadata && !Options.MetadataAddress.StartsWith("https://", StringComparison.OrdinalIgnoreCase))
- {
- throw new InvalidOperationException("The MetadataAddress or Authority must use HTTPS unless disabled for development by setting RequireHttpsMetadata=false.");
- }
-
- var httpClient = new HttpClient(Options.BackchannelHttpHandler ?? new HttpClientHandler());
- httpClient.Timeout = Options.BackchannelTimeout;
- httpClient.MaxResponseContentBufferSize = 1024 * 1024 * 10; // 10 MB
-
- Options.ConfigurationManager = new ConfigurationManager(Options.MetadataAddress, new OpenIdConnectConfigurationRetriever(),
- new HttpDocumentRetriever(httpClient) { RequireHttps = Options.RequireHttpsMetadata });
- }
- }
- }
-
- ///
- /// Called by the AuthenticationMiddleware base class to create a per-request handler.
- ///
- /// A new instance of the request handler
- protected override AuthenticationHandler CreateHandler()
- {
- return new JwtBearerHandler();
- }
- }
-}
diff --git a/src/Microsoft.AspNetCore.Authentication.JwtBearer/JwtBearerOptions.cs b/src/Microsoft.AspNetCore.Authentication.JwtBearer/JwtBearerOptions.cs
index 2aedf30d5..3d49bc665 100644
--- a/src/Microsoft.AspNetCore.Authentication.JwtBearer/JwtBearerOptions.cs
+++ b/src/Microsoft.AspNetCore.Authentication.JwtBearer/JwtBearerOptions.cs
@@ -3,32 +3,19 @@
using System;
using System.Collections.Generic;
-using System.ComponentModel;
using System.IdentityModel.Tokens.Jwt;
using System.Net.Http;
-using Microsoft.AspNetCore.Authentication;
-using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.IdentityModel.Protocols;
using Microsoft.IdentityModel.Protocols.OpenIdConnect;
using Microsoft.IdentityModel.Tokens;
-namespace Microsoft.AspNetCore.Builder
+namespace Microsoft.AspNetCore.Authentication.JwtBearer
{
///
/// Options class provides information needed to control Bearer Authentication middleware behavior
///
- public class JwtBearerOptions : AuthenticationOptions
+ public class JwtBearerOptions : AuthenticationSchemeOptions
{
- ///
- /// Creates an instance of bearer authentication options with default values.
- ///
- public JwtBearerOptions() : base()
- {
- AuthenticationScheme = JwtBearerDefaults.AuthenticationScheme;
- AutomaticAuthenticate = true;
- AutomaticChallenge = true;
- }
-
///
/// Gets or sets if HTTPS is required for the metadata address or authority.
/// The default is true. This should be disabled only in development environments.
@@ -63,7 +50,11 @@ public JwtBearerOptions() : base()
/// The application may implement the interface fully, or it may create an instance of JwtBearerAuthenticationEvents
/// and assign delegates only to the events it wants to process.
///
- public IJwtBearerEvents Events { get; set; } = new JwtBearerEvents();
+ public new JwtBearerEvents Events
+ {
+ get { return (JwtBearerEvents)base.Events; }
+ set { base.Events = value; }
+ }
///
/// The HttpMessageHandler used to retrieve metadata.
diff --git a/src/Microsoft.AspNetCore.Authentication.JwtBearer/Microsoft.AspNetCore.Authentication.JwtBearer.csproj b/src/Microsoft.AspNetCore.Authentication.JwtBearer/Microsoft.AspNetCore.Authentication.JwtBearer.csproj
index 7311aa3ae..df9f4af83 100644
--- a/src/Microsoft.AspNetCore.Authentication.JwtBearer/Microsoft.AspNetCore.Authentication.JwtBearer.csproj
+++ b/src/Microsoft.AspNetCore.Authentication.JwtBearer/Microsoft.AspNetCore.Authentication.JwtBearer.csproj
@@ -9,8 +9,8 @@
-
+
diff --git a/src/Microsoft.AspNetCore.Authentication.MicrosoftAccount/MicrosoftAccountAppBuilderExtensions.cs b/src/Microsoft.AspNetCore.Authentication.MicrosoftAccount/MicrosoftAccountAppBuilderExtensions.cs
index 660dd2e81..48add0f0d 100644
--- a/src/Microsoft.AspNetCore.Authentication.MicrosoftAccount/MicrosoftAccountAppBuilderExtensions.cs
+++ b/src/Microsoft.AspNetCore.Authentication.MicrosoftAccount/MicrosoftAccountAppBuilderExtensions.cs
@@ -1,9 +1,8 @@
-// Copyright (c) .NET Foundation. All rights reserved.
+// 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 Microsoft.AspNetCore.Authentication.MicrosoftAccount;
-using Microsoft.Extensions.Options;
namespace Microsoft.AspNetCore.Builder
{
@@ -13,38 +12,26 @@ namespace Microsoft.AspNetCore.Builder
public static class MicrosoftAccountAppBuilderExtensions
{
///
- /// Adds the middleware to the specified , which enables Microsoft Account authentication capabilities.
+ /// Obsolete, see https://go.microsoft.com/fwlink/?linkid=845470
///
/// The to add the middleware to.
/// A reference to this instance after the operation has completed.
+ [Obsolete("See https://go.microsoft.com/fwlink/?linkid=845470", error: true)]
public static IApplicationBuilder UseMicrosoftAccountAuthentication(this IApplicationBuilder app)
{
- if (app == null)
- {
- throw new ArgumentNullException(nameof(app));
- }
-
- return app.UseMiddleware();
+ throw new NotSupportedException("This method is no longer supported, see https://go.microsoft.com/fwlink/?linkid=845470");
}
///
- /// Adds the middleware to the specified , which enables Microsoft Account authentication capabilities.
+ /// Obsolete, see https://go.microsoft.com/fwlink/?linkid=845470
///
/// The to add the middleware to.
/// A that specifies options for the middleware.
/// A reference to this instance after the operation has completed.
+ [Obsolete("See https://go.microsoft.com/fwlink/?linkid=845470", error: true)]
public static IApplicationBuilder UseMicrosoftAccountAuthentication(this IApplicationBuilder app, MicrosoftAccountOptions options)
{
- if (app == null)
- {
- throw new ArgumentNullException(nameof(app));
- }
- if (options == null)
- {
- throw new ArgumentNullException(nameof(options));
- }
-
- return app.UseMiddleware(Options.Create(options));
+ throw new NotSupportedException("This method is no longer supported, see https://go.microsoft.com/fwlink/?linkid=845470");
}
}
-}
+}
\ No newline at end of file
diff --git a/src/Microsoft.AspNetCore.Authentication.MicrosoftAccount/MicrosoftAccountExtensions.cs b/src/Microsoft.AspNetCore.Authentication.MicrosoftAccount/MicrosoftAccountExtensions.cs
new file mode 100644
index 000000000..c5336db0b
--- /dev/null
+++ b/src/Microsoft.AspNetCore.Authentication.MicrosoftAccount/MicrosoftAccountExtensions.cs
@@ -0,0 +1,18 @@
+// 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 Microsoft.AspNetCore.Authentication.MicrosoftAccount;
+using Microsoft.AspNetCore.Http;
+
+namespace Microsoft.Extensions.DependencyInjection
+{
+ public static class MicrosoftAccountExtensions
+ {
+ public static IServiceCollection AddMicrosoftAccountAuthentication(this IServiceCollection services, Action configureOptions) =>
+ services.AddMicrosoftAccountAuthentication(MicrosoftAccountDefaults.AuthenticationScheme, configureOptions);
+
+ public static IServiceCollection AddMicrosoftAccountAuthentication(this IServiceCollection services, string authenticationScheme, Action configureOptions) =>
+ services.AddScheme(authenticationScheme, configureOptions);
+ }
+}
\ No newline at end of file
diff --git a/src/Microsoft.AspNetCore.Authentication.MicrosoftAccount/MicrosoftAccountHandler.cs b/src/Microsoft.AspNetCore.Authentication.MicrosoftAccount/MicrosoftAccountHandler.cs
index 2426cafe0..f9b2ccade 100644
--- a/src/Microsoft.AspNetCore.Authentication.MicrosoftAccount/MicrosoftAccountHandler.cs
+++ b/src/Microsoft.AspNetCore.Authentication.MicrosoftAccount/MicrosoftAccountHandler.cs
@@ -1,24 +1,24 @@
// 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.Net.Http;
using System.Net.Http.Headers;
using System.Security.Claims;
+using System.Text.Encodings.Web;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authentication.OAuth;
-using Microsoft.AspNetCore.Builder;
-using Microsoft.AspNetCore.Http.Authentication;
+using Microsoft.AspNetCore.DataProtection;
+using Microsoft.Extensions.Logging;
+using Microsoft.Extensions.Options;
using Newtonsoft.Json.Linq;
namespace Microsoft.AspNetCore.Authentication.MicrosoftAccount
{
internal class MicrosoftAccountHandler : OAuthHandler
{
- public MicrosoftAccountHandler(HttpClient httpClient)
- : base(httpClient)
- {
- }
+ public MicrosoftAccountHandler(IOptions sharedOptions, IOptionsSnapshot options, ILoggerFactory logger, UrlEncoder encoder, IDataProtectionProvider dataProtection, ISystemClock clock)
+ : base(sharedOptions, options, logger, encoder, dataProtection, clock)
+ { }
protected override async Task CreateTicketAsync(ClaimsIdentity identity, AuthenticationProperties properties, OAuthTokenResponse tokens)
{
@@ -33,8 +33,8 @@ protected override async Task CreateTicketAsync(ClaimsIden
var payload = JObject.Parse(await response.Content.ReadAsStringAsync());
- var ticket = new AuthenticationTicket(new ClaimsPrincipal(identity), properties, Options.AuthenticationScheme);
- var context = new OAuthCreatingTicketContext(ticket, Context, Options, Backchannel, tokens, payload);
+ var ticket = new AuthenticationTicket(new ClaimsPrincipal(identity), properties, Scheme.Name);
+ var context = new OAuthCreatingTicketContext(ticket, Context, Scheme, Options, Backchannel, tokens, payload);
context.RunClaimActions();
await Options.Events.CreatingTicket(context);
diff --git a/src/Microsoft.AspNetCore.Authentication.MicrosoftAccount/MicrosoftAccountMiddleware.cs b/src/Microsoft.AspNetCore.Authentication.MicrosoftAccount/MicrosoftAccountMiddleware.cs
deleted file mode 100644
index 3ad1bf557..000000000
--- a/src/Microsoft.AspNetCore.Authentication.MicrosoftAccount/MicrosoftAccountMiddleware.cs
+++ /dev/null
@@ -1,78 +0,0 @@
-// 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.Text.Encodings.Web;
-using Microsoft.AspNetCore.Authentication.OAuth;
-using Microsoft.AspNetCore.Builder;
-using Microsoft.AspNetCore.DataProtection;
-using Microsoft.AspNetCore.Http;
-using Microsoft.Extensions.Logging;
-using Microsoft.Extensions.Options;
-
-namespace Microsoft.AspNetCore.Authentication.MicrosoftAccount
-{
- ///
- /// An ASP.NET Core middleware for authenticating users using the Microsoft Account service.
- ///
- public class MicrosoftAccountMiddleware : OAuthMiddleware
- {
- ///
- /// Initializes a new .
- ///
- /// The next middleware in the HTTP pipeline to invoke.
- ///
- ///
- ///
- ///
- /// Configuration options for the middleware.
- public MicrosoftAccountMiddleware(
- RequestDelegate next,
- IDataProtectionProvider dataProtectionProvider,
- ILoggerFactory loggerFactory,
- UrlEncoder encoder,
- IOptions sharedOptions,
- IOptions options)
- : base(next, dataProtectionProvider, loggerFactory, encoder, sharedOptions, options)
- {
- if (next == null)
- {
- throw new ArgumentNullException(nameof(next));
- }
-
- if (dataProtectionProvider == null)
- {
- throw new ArgumentNullException(nameof(dataProtectionProvider));
- }
-
- if (loggerFactory == null)
- {
- throw new ArgumentNullException(nameof(loggerFactory));
- }
-
- if (encoder == null)
- {
- throw new ArgumentNullException(nameof(encoder));
- }
-
- if (sharedOptions == null)
- {
- throw new ArgumentNullException(nameof(sharedOptions));
- }
-
- if (options == null)
- {
- throw new ArgumentNullException(nameof(options));
- }
- }
-
- ///
- /// Provides the object for processing authentication-related requests.
- ///
- /// An configured with the supplied to the constructor.
- protected override AuthenticationHandler CreateHandler()
- {
- return new MicrosoftAccountHandler(Backchannel);
- }
- }
-}
diff --git a/src/Microsoft.AspNetCore.Authentication.MicrosoftAccount/MicrosoftAccountOptions.cs b/src/Microsoft.AspNetCore.Authentication.MicrosoftAccount/MicrosoftAccountOptions.cs
index 1aa4009a5..dbca3507e 100644
--- a/src/Microsoft.AspNetCore.Authentication.MicrosoftAccount/MicrosoftAccountOptions.cs
+++ b/src/Microsoft.AspNetCore.Authentication.MicrosoftAccount/MicrosoftAccountOptions.cs
@@ -5,11 +5,12 @@
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.MicrosoftAccount;
using Microsoft.AspNetCore.Http;
+using Microsoft.AspNetCore.Authentication.OAuth;
-namespace Microsoft.AspNetCore.Builder
+namespace Microsoft.AspNetCore.Authentication.MicrosoftAccount
{
///
- /// Configuration options for .
+ /// Configuration options for .
///
public class MicrosoftAccountOptions : OAuthOptions
{
@@ -18,8 +19,6 @@ public class MicrosoftAccountOptions : OAuthOptions
///
public MicrosoftAccountOptions()
{
- AuthenticationScheme = MicrosoftAccountDefaults.AuthenticationScheme;
- DisplayName = AuthenticationScheme;
CallbackPath = new PathString("/signin-microsoft");
AuthorizationEndpoint = MicrosoftAccountDefaults.AuthorizationEndpoint;
TokenEndpoint = MicrosoftAccountDefaults.TokenEndpoint;
diff --git a/src/Microsoft.AspNetCore.Authentication.OAuth/Events/IOAuthEvents.cs b/src/Microsoft.AspNetCore.Authentication.OAuth/Events/IOAuthEvents.cs
deleted file mode 100644
index 29316732c..000000000
--- a/src/Microsoft.AspNetCore.Authentication.OAuth/Events/IOAuthEvents.cs
+++ /dev/null
@@ -1,27 +0,0 @@
-// 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.Threading.Tasks;
-
-namespace Microsoft.AspNetCore.Authentication.OAuth
-{
- ///
- /// Specifies callback methods which the invokes to enable developer control over the authentication process.
- ///
- public interface IOAuthEvents : IRemoteAuthenticationEvents
- {
- ///
- /// Invoked after the provider successfully authenticates a user. This can be used to retrieve user information.
- /// This event may not be invoked by sub-classes of OAuthAuthenticationHandler if they override CreateTicketAsync.
- ///
- /// Contains information about the login session.
- /// A representing the completed operation.
- Task CreatingTicket(OAuthCreatingTicketContext context);
-
- ///
- /// Called when a Challenge causes a redirect to the authorize endpoint.
- ///
- /// Contains redirect URI and of the challenge.
- Task RedirectToAuthorizationEndpoint(OAuthRedirectToAuthorizationContext context);
- }
-}
diff --git a/src/Microsoft.AspNetCore.Authentication.OAuth/Events/OAuthCreatingTicketContext.cs b/src/Microsoft.AspNetCore.Authentication.OAuth/Events/OAuthCreatingTicketContext.cs
index b17d23c9b..7e118b98b 100644
--- a/src/Microsoft.AspNetCore.Authentication.OAuth/Events/OAuthCreatingTicketContext.cs
+++ b/src/Microsoft.AspNetCore.Authentication.OAuth/Events/OAuthCreatingTicketContext.cs
@@ -5,7 +5,6 @@
using System.Globalization;
using System.Net.Http;
using System.Security.Claims;
-using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using Newtonsoft.Json.Linq;
@@ -14,23 +13,25 @@ namespace Microsoft.AspNetCore.Authentication.OAuth
///
/// Contains information about the login session as well as the user .
///
- public class OAuthCreatingTicketContext : BaseContext
+ public class OAuthCreatingTicketContext : BaseAuthenticationContext
{
///
/// Initializes a new .
///
/// The .
/// The HTTP environment.
+ /// The authentication scheme.
/// The options used by the authentication middleware.
/// The HTTP client used by the authentication middleware
/// The tokens returned from the token endpoint.
public OAuthCreatingTicketContext(
AuthenticationTicket ticket,
HttpContext context,
+ AuthenticationScheme scheme,
OAuthOptions options,
HttpClient backchannel,
OAuthTokenResponse tokens)
- : this(ticket, context, options, backchannel, tokens, user: new JObject())
+ : this(ticket, context, scheme, options, backchannel, tokens, user: new JObject())
{
}
@@ -39,6 +40,7 @@ public OAuthCreatingTicketContext(
///
/// The .
/// The HTTP environment.
+ /// The authentication scheme.
/// The options used by the authentication middleware.
/// The HTTP client used by the authentication middleware
/// The tokens returned from the token endpoint.
@@ -46,46 +48,25 @@ public OAuthCreatingTicketContext(
public OAuthCreatingTicketContext(
AuthenticationTicket ticket,
HttpContext context,
+ AuthenticationScheme scheme,
OAuthOptions options,
HttpClient backchannel,
OAuthTokenResponse tokens,
JObject user)
- : base(context)
+ : base(context, scheme.Name, ticket.Properties)
{
- if (context == null)
- {
- throw new ArgumentNullException(nameof(context));
- }
-
- if (options == null)
- {
- throw new ArgumentNullException(nameof(options));
- }
-
- if (backchannel == null)
- {
- throw new ArgumentNullException(nameof(backchannel));
- }
-
- if (tokens == null)
- {
- throw new ArgumentNullException(nameof(tokens));
- }
-
- if (user == null)
- {
- throw new ArgumentNullException(nameof(user));
- }
-
- TokenResponse = tokens;
- Backchannel = backchannel;
- User = user;
- Options = options;
+ TokenResponse = tokens ?? throw new ArgumentNullException(nameof(tokens));
+ Backchannel = backchannel ?? throw new ArgumentNullException(nameof(backchannel));
+ User = user ?? throw new ArgumentNullException(nameof(user));
+ Options = options ?? throw new ArgumentNullException(nameof(options));
+ Scheme = scheme ?? throw new ArgumentNullException(nameof(scheme));
Ticket = ticket;
}
public OAuthOptions Options { get; }
+ public AuthenticationScheme Scheme { get; }
+
///
/// Gets the JSON-serialized user or an empty
/// if it is not available.
diff --git a/src/Microsoft.AspNetCore.Authentication.OAuth/Events/OAuthEvents.cs b/src/Microsoft.AspNetCore.Authentication.OAuth/Events/OAuthEvents.cs
index 066b324b7..bec040120 100644
--- a/src/Microsoft.AspNetCore.Authentication.OAuth/Events/OAuthEvents.cs
+++ b/src/Microsoft.AspNetCore.Authentication.OAuth/Events/OAuthEvents.cs
@@ -8,9 +8,9 @@
namespace Microsoft.AspNetCore.Authentication.OAuth
{
///
- /// Default implementation.
+ /// Default implementation.
///
- public class OAuthEvents : RemoteAuthenticationEvents, IOAuthEvents
+ public class OAuthEvents : RemoteAuthenticationEvents
{
///
/// Gets or sets the function that is invoked when the CreatingTicket method is invoked.
diff --git a/src/Microsoft.AspNetCore.Authentication.OAuth/Events/OAuthRedirectToAuthorizationContext.cs b/src/Microsoft.AspNetCore.Authentication.OAuth/Events/OAuthRedirectToAuthorizationContext.cs
index 63eaa3537..6dca3f6d9 100644
--- a/src/Microsoft.AspNetCore.Authentication.OAuth/Events/OAuthRedirectToAuthorizationContext.cs
+++ b/src/Microsoft.AspNetCore.Authentication.OAuth/Events/OAuthRedirectToAuthorizationContext.cs
@@ -3,7 +3,6 @@
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
-using Microsoft.AspNetCore.Http.Authentication;
namespace Microsoft.AspNetCore.Authentication.OAuth
{
diff --git a/src/Microsoft.AspNetCore.Authentication.OAuth/Microsoft.AspNetCore.Authentication.OAuth.csproj b/src/Microsoft.AspNetCore.Authentication.OAuth/Microsoft.AspNetCore.Authentication.OAuth.csproj
index c0e7569ac..c0aa162f5 100644
--- a/src/Microsoft.AspNetCore.Authentication.OAuth/Microsoft.AspNetCore.Authentication.OAuth.csproj
+++ b/src/Microsoft.AspNetCore.Authentication.OAuth/Microsoft.AspNetCore.Authentication.OAuth.csproj
@@ -12,8 +12,8 @@
-
+
diff --git a/src/Microsoft.AspNetCore.Authentication.OAuth/OAuthAppBuilderExtensions.cs b/src/Microsoft.AspNetCore.Authentication.OAuth/OAuthAppBuilderExtensions.cs
index eebeaf7a3..be31f0372 100644
--- a/src/Microsoft.AspNetCore.Authentication.OAuth/OAuthAppBuilderExtensions.cs
+++ b/src/Microsoft.AspNetCore.Authentication.OAuth/OAuthAppBuilderExtensions.cs
@@ -1,9 +1,8 @@
-// Copyright (c) .NET Foundation. All rights reserved.
+// 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 Microsoft.AspNetCore.Authentication.OAuth;
-using Microsoft.Extensions.Options;
namespace Microsoft.AspNetCore.Builder
{
@@ -13,38 +12,26 @@ namespace Microsoft.AspNetCore.Builder
public static class OAuthAppBuilderExtensions
{
///
- /// Adds the middleware to the specified , which enables OAuth 2.0 authentication capabilities.
+ /// Obsolete, see https://go.microsoft.com/fwlink/?linkid=845470
///
/// The to add the middleware to.
/// A reference to this instance after the operation has completed.
+ [Obsolete("See https://go.microsoft.com/fwlink/?linkid=845470", error: true)]
public static IApplicationBuilder UseOAuthAuthentication(this IApplicationBuilder app)
{
- if (app == null)
- {
- throw new ArgumentNullException(nameof(app));
- }
-
- return app.UseMiddleware>();
+ throw new NotSupportedException("This method is no longer supported, see https://go.microsoft.com/fwlink/?linkid=845470");
}
///
- /// Adds the middleware to the specified , which enables OAuth 2.0 authentication capabilities.
+ /// Obsolete, see https://go.microsoft.com/fwlink/?linkid=845470
///
/// The to add the middleware to.
/// A that specifies options for the middleware.
/// A reference to this instance after the operation has completed.
+ [Obsolete("See https://go.microsoft.com/fwlink/?linkid=845470", error: true)]
public static IApplicationBuilder UseOAuthAuthentication(this IApplicationBuilder app, OAuthOptions options)
{
- if (app == null)
- {
- throw new ArgumentNullException(nameof(app));
- }
- if (options == null)
- {
- throw new ArgumentNullException(nameof(options));
- }
-
- return app.UseMiddleware>(Options.Create(options));
+ throw new NotSupportedException("This method is no longer supported, see https://go.microsoft.com/fwlink/?linkid=845470");
}
}
-}
+}
\ No newline at end of file
diff --git a/src/Microsoft.AspNetCore.Authentication.OAuth/OAuthExtensions.cs b/src/Microsoft.AspNetCore.Authentication.OAuth/OAuthExtensions.cs
new file mode 100644
index 000000000..aa7c59f03
--- /dev/null
+++ b/src/Microsoft.AspNetCore.Authentication.OAuth/OAuthExtensions.cs
@@ -0,0 +1,15 @@
+// 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 Microsoft.AspNetCore.Authentication.OAuth;
+using Microsoft.Extensions.DependencyInjection;
+
+namespace Microsoft.AspNetCore.Builder
+{
+ public static class OAuthExtensions
+ {
+ public static IServiceCollection AddOAuthAuthentication(this IServiceCollection services, string authenticationScheme, Action configureOptions) =>
+ services.AddScheme>(authenticationScheme, configureOptions);
+ }
+}
diff --git a/src/Microsoft.AspNetCore.Authentication.OAuth/OAuthHandler.cs b/src/Microsoft.AspNetCore.Authentication.OAuth/OAuthHandler.cs
index a5c36c1c4..ecd89f12d 100644
--- a/src/Microsoft.AspNetCore.Authentication.OAuth/OAuthHandler.cs
+++ b/src/Microsoft.AspNetCore.Authentication.OAuth/OAuthHandler.cs
@@ -8,24 +8,57 @@
using System.Net.Http.Headers;
using System.Security.Claims;
using System.Text;
+using System.Text.Encodings.Web;
using System.Threading.Tasks;
-using Microsoft.AspNetCore.Builder;
-using Microsoft.AspNetCore.Http.Authentication;
-using Microsoft.AspNetCore.Http.Features.Authentication;
+using Microsoft.AspNetCore.DataProtection;
+using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.WebUtilities;
+using Microsoft.Extensions.Logging;
+using Microsoft.Extensions.Options;
using Microsoft.Extensions.Primitives;
using Newtonsoft.Json.Linq;
namespace Microsoft.AspNetCore.Authentication.OAuth
{
- public class OAuthHandler : RemoteAuthenticationHandler where TOptions : OAuthOptions
+ public class OAuthHandler : RemoteAuthenticationHandler where TOptions : OAuthOptions, new()
{
- public OAuthHandler(HttpClient backchannel)
+ protected HttpClient Backchannel { get; private set; }
+
+ protected ISecureDataFormat StateDataFormat { get; private set; }
+
+ ///
+ /// The handler calls methods on the events which give the application control at certain points where processing is occurring.
+ /// If it is not provided a default instance is supplied which does nothing when the methods are called.
+ ///
+ protected new OAuthEvents Events
{
- Backchannel = backchannel;
+ get { return (OAuthEvents)base.Events; }
+ set { base.Events = value; }
}
- protected HttpClient Backchannel { get; private set; }
+ public OAuthHandler(IOptions sharedOptions, IOptionsSnapshot options, ILoggerFactory logger, UrlEncoder encoder, IDataProtectionProvider dataProtection, ISystemClock clock)
+ : base(sharedOptions, options, dataProtection, logger, encoder, clock)
+ {
+ }
+
+ public override async Task InitializeAsync(AuthenticationScheme scheme, HttpContext context)
+ {
+ await base.InitializeAsync(scheme, context);
+ Events = Events ?? new OAuthEvents();
+
+ Backchannel = new HttpClient(Options.BackchannelHttpHandler ?? new HttpClientHandler());
+ Backchannel.DefaultRequestHeaders.UserAgent.ParseAdd("Microsoft ASP.NET Core OAuth middleware");
+ Backchannel.Timeout = Options.BackchannelTimeout;
+ Backchannel.MaxResponseContentBufferSize = 1024 * 1024 * 10; // 10 MB
+
+ StateDataFormat = Options.StateDataFormat;
+ if (Options.StateDataFormat == null)
+ {
+ var dataProtector = DataProtection.CreateProtector(
+ GetType().FullName, Scheme.Name, "v1");
+ Options.StateDataFormat = new PropertiesDataFormat(dataProtector);
+ }
+ }
protected override async Task HandleRemoteAuthenticateAsync()
{
@@ -107,7 +140,7 @@ protected override async Task HandleRemoteAuthenticateAsync(
{
// https://www.w3.org/TR/xmlschema-2/#dateTime
// https://msdn.microsoft.com/en-us/library/az4se3k1(v=vs.110).aspx
- var expiresAt = Options.SystemClock.UtcNow + TimeSpan.FromSeconds(value);
+ var expiresAt = Clock.UtcNow + TimeSpan.FromSeconds(value);
authTokens.Add(new AuthenticationToken
{
Name = "expires_at",
@@ -170,21 +203,20 @@ private static async Task Display(HttpResponseMessage response)
protected virtual async Task CreateTicketAsync(ClaimsIdentity identity, AuthenticationProperties properties, OAuthTokenResponse tokens)
{
- var ticket = new AuthenticationTicket(new ClaimsPrincipal(identity), properties, Options.AuthenticationScheme);
- var context = new OAuthCreatingTicketContext(ticket, Context, Options, Backchannel, tokens);
- await Options.Events.CreatingTicket(context);
+ var ticket = new AuthenticationTicket(new ClaimsPrincipal(identity), properties, Scheme.Name);
+ var context = new OAuthCreatingTicketContext(ticket, Context, Scheme, Options, Backchannel, tokens);
+ await Events.CreatingTicket(context);
return context.Ticket;
}
- protected override async Task HandleUnauthorizedAsync(ChallengeContext context)
+ protected override async Task HandleUnauthorizedAsync(ChallengeContext context)
{
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}
- var properties = new AuthenticationProperties(context.Properties);
-
+ var properties = context.Properties;
if (string.IsNullOrEmpty(properties.RedirectUri))
{
properties.RedirectUri = CurrentUri;
@@ -197,8 +229,7 @@ protected override async Task HandleUnauthorizedAsync(ChallengeContext con
var redirectContext = new OAuthRedirectToAuthorizationContext(
Context, Options,
properties, authorizationEndpoint);
- await Options.Events.RedirectToAuthorizationEndpoint(redirectContext);
- return true;
+ await Events.RedirectToAuthorizationEndpoint(redirectContext);
}
protected virtual string BuildChallengeUrl(AuthenticationProperties properties, string redirectUri)
diff --git a/src/Microsoft.AspNetCore.Authentication.OAuth/OAuthMiddleware.cs b/src/Microsoft.AspNetCore.Authentication.OAuth/OAuthMiddleware.cs
deleted file mode 100644
index 75139c1c8..000000000
--- a/src/Microsoft.AspNetCore.Authentication.OAuth/OAuthMiddleware.cs
+++ /dev/null
@@ -1,138 +0,0 @@
-// 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.Globalization;
-using System.Net.Http;
-using System.Text.Encodings.Web;
-using Microsoft.AspNetCore.Builder;
-using Microsoft.AspNetCore.DataProtection;
-using Microsoft.AspNetCore.Http;
-using Microsoft.Extensions.Logging;
-using Microsoft.Extensions.Options;
-
-namespace Microsoft.AspNetCore.Authentication.OAuth
-{
- ///
- /// An ASP.NET Core middleware for authenticating users using OAuth services.
- ///
- public class OAuthMiddleware : AuthenticationMiddleware where TOptions : OAuthOptions, new()
- {
- ///
- /// Initializes a new .
- ///
- /// The next middleware in the HTTP pipeline to invoke.
- ///
- ///
- /// The .
- /// The configuration options for this middleware.
- /// Configuration options for the middleware.
- public OAuthMiddleware(
- RequestDelegate next,
- IDataProtectionProvider dataProtectionProvider,
- ILoggerFactory loggerFactory,
- UrlEncoder encoder,
- IOptions sharedOptions,
- IOptions options)
- : base(next, options, loggerFactory, encoder)
- {
- if (next == null)
- {
- throw new ArgumentNullException(nameof(next));
- }
-
- if (dataProtectionProvider == null)
- {
- throw new ArgumentNullException(nameof(dataProtectionProvider));
- }
-
- if (loggerFactory == null)
- {
- throw new ArgumentNullException(nameof(loggerFactory));
- }
-
- if (encoder == null)
- {
- throw new ArgumentNullException(nameof(encoder));
- }
-
- if (sharedOptions == null)
- {
- throw new ArgumentNullException(nameof(sharedOptions));
- }
-
- if (options == null)
- {
- throw new ArgumentNullException(nameof(options));
- }
-
- // todo: review error handling
- if (string.IsNullOrEmpty(Options.AuthenticationScheme))
- {
- throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, Resources.Exception_OptionMustBeProvided, nameof(Options.AuthenticationScheme)));
- }
-
- if (string.IsNullOrEmpty(Options.ClientId))
- {
- throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, Resources.Exception_OptionMustBeProvided, nameof(Options.ClientId)));
- }
-
- if (string.IsNullOrEmpty(Options.ClientSecret))
- {
- throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, Resources.Exception_OptionMustBeProvided, nameof(Options.ClientSecret)));
- }
-
- if (string.IsNullOrEmpty(Options.AuthorizationEndpoint))
- {
- throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, Resources.Exception_OptionMustBeProvided, nameof(Options.AuthorizationEndpoint)));
- }
-
- if (string.IsNullOrEmpty(Options.TokenEndpoint))
- {
- throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, Resources.Exception_OptionMustBeProvided, nameof(Options.TokenEndpoint)));
- }
-
- if (!Options.CallbackPath.HasValue)
- {
- throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, Resources.Exception_OptionMustBeProvided, nameof(Options.CallbackPath)));
- }
-
- if (Options.Events == null)
- {
- Options.Events = new OAuthEvents();
- }
-
- if (Options.StateDataFormat == null)
- {
- var dataProtector = dataProtectionProvider.CreateProtector(
- GetType().FullName, Options.AuthenticationScheme, "v1");
- Options.StateDataFormat = new PropertiesDataFormat(dataProtector);
- }
-
- Backchannel = new HttpClient(Options.BackchannelHttpHandler ?? new HttpClientHandler());
- Backchannel.DefaultRequestHeaders.UserAgent.ParseAdd("Microsoft ASP.NET Core OAuth middleware");
- Backchannel.Timeout = Options.BackchannelTimeout;
- Backchannel.MaxResponseContentBufferSize = 1024 * 1024 * 10; // 10 MB
-
- if (string.IsNullOrEmpty(Options.SignInScheme))
- {
- Options.SignInScheme = sharedOptions.Value.SignInScheme;
- }
- if (string.IsNullOrEmpty(Options.SignInScheme))
- {
- throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, Resources.Exception_OptionMustBeProvided, nameof(Options.SignInScheme)));
- }
- }
-
- protected HttpClient Backchannel { get; private set; }
-
- ///
- /// Provides the object for processing authentication-related requests.
- ///
- /// An configured with the supplied to the constructor.
- protected override AuthenticationHandler CreateHandler()
- {
- return new OAuthHandler(Backchannel);
- }
- }
-}
diff --git a/src/Microsoft.AspNetCore.Authentication.OAuth/OAuthOptions.cs b/src/Microsoft.AspNetCore.Authentication.OAuth/OAuthOptions.cs
index 9bd08dfd8..3c71f055f 100644
--- a/src/Microsoft.AspNetCore.Authentication.OAuth/OAuthOptions.cs
+++ b/src/Microsoft.AspNetCore.Authentication.OAuth/OAuthOptions.cs
@@ -1,16 +1,18 @@
// 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 Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.OAuth;
using Microsoft.AspNetCore.Authentication.OAuth.Claims;
using Microsoft.AspNetCore.Http.Authentication;
+using System.Globalization;
-namespace Microsoft.AspNetCore.Builder
+namespace Microsoft.AspNetCore.Authentication.OAuth
{
///
- /// Configuration options for .
+ /// Configuration options OAuth.
///
public class OAuthOptions : RemoteAuthenticationOptions
{
@@ -19,6 +21,39 @@ public OAuthOptions()
Events = new OAuthEvents();
}
+ ///
+ /// Check that the options are valid. Should throw an exception if things are not ok.
+ ///
+ public override void Validate()
+ {
+ base.Validate();
+
+ if (string.IsNullOrEmpty(ClientId))
+ {
+ throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, Resources.Exception_OptionMustBeProvided, nameof(ClientId)), nameof(ClientId));
+ }
+
+ if (string.IsNullOrEmpty(ClientSecret))
+ {
+ throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, Resources.Exception_OptionMustBeProvided, nameof(ClientSecret)), nameof(ClientSecret));
+ }
+
+ if (string.IsNullOrEmpty(AuthorizationEndpoint))
+ {
+ throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, Resources.Exception_OptionMustBeProvided, nameof(AuthorizationEndpoint)), nameof(AuthorizationEndpoint));
+ }
+
+ if (string.IsNullOrEmpty(TokenEndpoint))
+ {
+ throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, Resources.Exception_OptionMustBeProvided, nameof(TokenEndpoint)), nameof(TokenEndpoint));
+ }
+
+ if (!CallbackPath.HasValue)
+ {
+ throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, Resources.Exception_OptionMustBeProvided, nameof(CallbackPath)), nameof(CallbackPath));
+ }
+ }
+
///
/// Gets or sets the provider-assigned client id.
///
@@ -47,11 +82,11 @@ public OAuthOptions()
public string UserInformationEndpoint { get; set; }
///
- /// Gets or sets the used to handle authentication events.
+ /// Gets or sets the used to handle authentication events.
///
- public new IOAuthEvents Events
+ public new OAuthEvents Events
{
- get { return (IOAuthEvents)base.Events; }
+ get { return (OAuthEvents)base.Events; }
set { base.Events = value; }
}
diff --git a/src/Microsoft.AspNetCore.Authentication.OpenIdConnect/Events/AuthenticationFailedContext.cs b/src/Microsoft.AspNetCore.Authentication.OpenIdConnect/Events/AuthenticationFailedContext.cs
index 776f78d6e..0c7d96863 100644
--- a/src/Microsoft.AspNetCore.Authentication.OpenIdConnect/Events/AuthenticationFailedContext.cs
+++ b/src/Microsoft.AspNetCore.Authentication.OpenIdConnect/Events/AuthenticationFailedContext.cs
@@ -9,8 +9,8 @@ namespace Microsoft.AspNetCore.Authentication.OpenIdConnect
{
public class AuthenticationFailedContext : BaseOpenIdConnectContext
{
- public AuthenticationFailedContext(HttpContext context, OpenIdConnectOptions options)
- : base(context, options)
+ public AuthenticationFailedContext(HttpContext context, AuthenticationScheme scheme, OpenIdConnectOptions options)
+ : base(context, scheme, options)
{
}
diff --git a/src/Microsoft.AspNetCore.Authentication.OpenIdConnect/Events/AuthorizationCodeReceivedContext.cs b/src/Microsoft.AspNetCore.Authentication.OpenIdConnect/Events/AuthorizationCodeReceivedContext.cs
index 49c863e4b..a2c36f3e6 100644
--- a/src/Microsoft.AspNetCore.Authentication.OpenIdConnect/Events/AuthorizationCodeReceivedContext.cs
+++ b/src/Microsoft.AspNetCore.Authentication.OpenIdConnect/Events/AuthorizationCodeReceivedContext.cs
@@ -18,8 +18,8 @@ public class AuthorizationCodeReceivedContext : BaseOpenIdConnectContext
///
/// Creates a
///
- public AuthorizationCodeReceivedContext(HttpContext context, OpenIdConnectOptions options)
- : base(context, options)
+ public AuthorizationCodeReceivedContext(HttpContext context, AuthenticationScheme scheme, OpenIdConnectOptions options)
+ : base(context, scheme, options)
{
}
diff --git a/src/Microsoft.AspNetCore.Authentication.OpenIdConnect/Events/BaseOpenIdConnectContext.cs b/src/Microsoft.AspNetCore.Authentication.OpenIdConnect/Events/BaseOpenIdConnectContext.cs
index d2f56a4ce..63f815d9e 100644
--- a/src/Microsoft.AspNetCore.Authentication.OpenIdConnect/Events/BaseOpenIdConnectContext.cs
+++ b/src/Microsoft.AspNetCore.Authentication.OpenIdConnect/Events/BaseOpenIdConnectContext.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;
-using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using Microsoft.IdentityModel.Protocols.OpenIdConnect;
@@ -10,19 +9,17 @@ namespace Microsoft.AspNetCore.Authentication.OpenIdConnect
{
public class BaseOpenIdConnectContext : BaseControlContext
{
- public BaseOpenIdConnectContext(HttpContext context, OpenIdConnectOptions options)
+ public BaseOpenIdConnectContext(HttpContext context, AuthenticationScheme scheme, OpenIdConnectOptions options)
: base(context)
{
- if (options == null)
- {
- throw new ArgumentNullException(nameof(options));
- }
-
- Options = options;
+ Options = options ?? throw new ArgumentNullException(nameof(options));
+ Scheme = scheme ?? throw new ArgumentNullException(nameof(scheme));
}
public OpenIdConnectOptions Options { get; }
+ public AuthenticationScheme Scheme { get; }
+
public OpenIdConnectMessage ProtocolMessage { get; set; }
}
}
\ No newline at end of file
diff --git a/src/Microsoft.AspNetCore.Authentication.OpenIdConnect/Events/IOpenIdConnectEvents.cs b/src/Microsoft.AspNetCore.Authentication.OpenIdConnect/Events/IOpenIdConnectEvents.cs
deleted file mode 100644
index 128fa08a3..000000000
--- a/src/Microsoft.AspNetCore.Authentication.OpenIdConnect/Events/IOpenIdConnectEvents.cs
+++ /dev/null
@@ -1,58 +0,0 @@
-// 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.Threading.Tasks;
-
-namespace Microsoft.AspNetCore.Authentication.OpenIdConnect
-{
- ///
- /// Specifies events which the invokes to enable developer control over the authentication process.
- ///
- public interface IOpenIdConnectEvents : IRemoteAuthenticationEvents
- {
- ///
- /// Invoked if exceptions are thrown during request processing. The exceptions will be re-thrown after this event unless suppressed.
- ///
- Task AuthenticationFailed(AuthenticationFailedContext context);
-
- ///
- /// Invoked after security token validation if an authorization code is present in the protocol message.
- ///
- Task AuthorizationCodeReceived(AuthorizationCodeReceivedContext context);
-
- ///
- /// Invoked when a protocol message is first received.
- ///
- Task MessageReceived(MessageReceivedContext context);
-
- ///
- /// Invoked before redirecting to the identity provider to authenticate.
- ///
- Task RedirectToIdentityProvider(RedirectContext context);
-
- ///
- /// Invoked before redirecting to the identity provider to sign out.
- ///
- Task RedirectToIdentityProviderForSignOut(RedirectContext context);
-
- ///
- /// Invoked when a request is received on the RemoteSignOutPath.
- ///
- Task RemoteSignOut(RemoteSignOutContext context);
-
- ///
- /// Invoked after "authorization code" is redeemed for tokens at the token endpoint.
- ///
- Task TokenResponseReceived(TokenResponseReceivedContext context);
-
- ///
- /// Invoked when an IdToken has been validated and produced an AuthenticationTicket.
- ///
- Task TokenValidated(TokenValidatedContext context);
-
- ///
- /// Invoked when user information is retrieved from the UserInfoEndpoint.
- ///
- Task UserInformationReceived(UserInformationReceivedContext context);
- }
-}
\ No newline at end of file
diff --git a/src/Microsoft.AspNetCore.Authentication.OpenIdConnect/Events/MessageReceivedContext.cs b/src/Microsoft.AspNetCore.Authentication.OpenIdConnect/Events/MessageReceivedContext.cs
index b2554969c..f0298ed05 100644
--- a/src/Microsoft.AspNetCore.Authentication.OpenIdConnect/Events/MessageReceivedContext.cs
+++ b/src/Microsoft.AspNetCore.Authentication.OpenIdConnect/Events/MessageReceivedContext.cs
@@ -1,16 +1,14 @@
// 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 Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
-using Microsoft.AspNetCore.Http.Authentication;
namespace Microsoft.AspNetCore.Authentication.OpenIdConnect
{
public class MessageReceivedContext : BaseOpenIdConnectContext
{
- public MessageReceivedContext(HttpContext context, OpenIdConnectOptions options)
- : base(context, options)
+ public MessageReceivedContext(HttpContext context, AuthenticationScheme scheme, OpenIdConnectOptions options)
+ : base(context, scheme, options)
{
}
diff --git a/src/Microsoft.AspNetCore.Authentication.OpenIdConnect/Events/OpenIdConnectEvents.cs b/src/Microsoft.AspNetCore.Authentication.OpenIdConnect/Events/OpenIdConnectEvents.cs
index f39b554ec..f6386aeec 100644
--- a/src/Microsoft.AspNetCore.Authentication.OpenIdConnect/Events/OpenIdConnectEvents.cs
+++ b/src/Microsoft.AspNetCore.Authentication.OpenIdConnect/Events/OpenIdConnectEvents.cs
@@ -8,9 +8,9 @@
namespace Microsoft.AspNetCore.Authentication.OpenIdConnect
{
///
- /// Specifies events which the invokes to enable developer control over the authentication process.
+ /// Specifies events which the invokes to enable developer control over the authentication process.
///
- public class OpenIdConnectEvents : RemoteAuthenticationEvents, IOpenIdConnectEvents
+ public class OpenIdConnectEvents : RemoteAuthenticationEvents
{
///
/// Invoked if exceptions are thrown during request processing. The exceptions will be re-thrown after this event unless suppressed.
diff --git a/src/Microsoft.AspNetCore.Authentication.OpenIdConnect/Events/RedirectContext.cs b/src/Microsoft.AspNetCore.Authentication.OpenIdConnect/Events/RedirectContext.cs
index 59b1c0efd..59b00827a 100644
--- a/src/Microsoft.AspNetCore.Authentication.OpenIdConnect/Events/RedirectContext.cs
+++ b/src/Microsoft.AspNetCore.Authentication.OpenIdConnect/Events/RedirectContext.cs
@@ -1,20 +1,18 @@
// 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 Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
-using Microsoft.AspNetCore.Http.Authentication;
namespace Microsoft.AspNetCore.Authentication.OpenIdConnect
{
///
- /// When a user configures the to be notified prior to redirecting to an IdentityProvider
+ /// When a user configures the to be notified prior to redirecting to an IdentityProvider
/// an instance of is passed to the 'RedirectToAuthenticationEndpoint' or 'RedirectToEndSessionEndpoint' events.
///
public class RedirectContext : BaseOpenIdConnectContext
{
- public RedirectContext(HttpContext context, OpenIdConnectOptions options, AuthenticationProperties properties)
- : base(context, options)
+ public RedirectContext(HttpContext context, AuthenticationScheme scheme, OpenIdConnectOptions options, AuthenticationProperties properties)
+ : base(context, scheme, options)
{
Properties = properties;
}
diff --git a/src/Microsoft.AspNetCore.Authentication.OpenIdConnect/Events/RemoteSignoutContext.cs b/src/Microsoft.AspNetCore.Authentication.OpenIdConnect/Events/RemoteSignoutContext.cs
index a76dc9e59..5c0172673 100644
--- a/src/Microsoft.AspNetCore.Authentication.OpenIdConnect/Events/RemoteSignoutContext.cs
+++ b/src/Microsoft.AspNetCore.Authentication.OpenIdConnect/Events/RemoteSignoutContext.cs
@@ -1,7 +1,6 @@
// 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 Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using Microsoft.IdentityModel.Protocols.OpenIdConnect;
@@ -11,9 +10,10 @@ public class RemoteSignOutContext : BaseOpenIdConnectContext
{
public RemoteSignOutContext(
HttpContext context,
+ AuthenticationScheme scheme,
OpenIdConnectOptions options,
OpenIdConnectMessage message)
- : base(context, options)
+ : base(context, scheme, options)
{
ProtocolMessage = message;
}
diff --git a/src/Microsoft.AspNetCore.Authentication.OpenIdConnect/Events/TokenResponseReceivedContext.cs b/src/Microsoft.AspNetCore.Authentication.OpenIdConnect/Events/TokenResponseReceivedContext.cs
index b4a9ad6d1..7c0d51fbb 100644
--- a/src/Microsoft.AspNetCore.Authentication.OpenIdConnect/Events/TokenResponseReceivedContext.cs
+++ b/src/Microsoft.AspNetCore.Authentication.OpenIdConnect/Events/TokenResponseReceivedContext.cs
@@ -1,9 +1,7 @@
// 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 Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
-using Microsoft.AspNetCore.Http.Authentication;
using Microsoft.IdentityModel.Protocols.OpenIdConnect;
namespace Microsoft.AspNetCore.Authentication.OpenIdConnect
@@ -16,8 +14,8 @@ public class TokenResponseReceivedContext : BaseOpenIdConnectContext
///
/// Creates a
///
- public TokenResponseReceivedContext(HttpContext context, OpenIdConnectOptions options, AuthenticationProperties properties)
- : base(context, options)
+ public TokenResponseReceivedContext(HttpContext context, AuthenticationScheme scheme, OpenIdConnectOptions options, AuthenticationProperties properties)
+ : base(context, scheme, options)
{
Properties = properties;
}
diff --git a/src/Microsoft.AspNetCore.Authentication.OpenIdConnect/Events/TokenValidatedContext.cs b/src/Microsoft.AspNetCore.Authentication.OpenIdConnect/Events/TokenValidatedContext.cs
index 130a4d987..fea89298c 100644
--- a/src/Microsoft.AspNetCore.Authentication.OpenIdConnect/Events/TokenValidatedContext.cs
+++ b/src/Microsoft.AspNetCore.Authentication.OpenIdConnect/Events/TokenValidatedContext.cs
@@ -15,8 +15,8 @@ public class TokenValidatedContext : BaseOpenIdConnectContext
///
/// Creates a
///
- public TokenValidatedContext(HttpContext context, OpenIdConnectOptions options)
- : base(context, options)
+ public TokenValidatedContext(HttpContext context, AuthenticationScheme scheme, OpenIdConnectOptions options)
+ : base(context, scheme, options)
{
}
diff --git a/src/Microsoft.AspNetCore.Authentication.OpenIdConnect/Events/UserInformationReceivedContext.cs b/src/Microsoft.AspNetCore.Authentication.OpenIdConnect/Events/UserInformationReceivedContext.cs
index c0a53db44..ee80cb71f 100644
--- a/src/Microsoft.AspNetCore.Authentication.OpenIdConnect/Events/UserInformationReceivedContext.cs
+++ b/src/Microsoft.AspNetCore.Authentication.OpenIdConnect/Events/UserInformationReceivedContext.cs
@@ -1,7 +1,6 @@
// 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 Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using Newtonsoft.Json.Linq;
@@ -9,8 +8,8 @@ namespace Microsoft.AspNetCore.Authentication.OpenIdConnect
{
public class UserInformationReceivedContext : BaseOpenIdConnectContext
{
- public UserInformationReceivedContext(HttpContext context, OpenIdConnectOptions options)
- : base(context, options)
+ public UserInformationReceivedContext(HttpContext context, AuthenticationScheme scheme, OpenIdConnectOptions options)
+ : base(context, scheme, options)
{
}
diff --git a/src/Microsoft.AspNetCore.Authentication.OpenIdConnect/OpenIdConnectAppBuilderExtensions.cs b/src/Microsoft.AspNetCore.Authentication.OpenIdConnect/OpenIdConnectAppBuilderExtensions.cs
index dde12494d..075849247 100644
--- a/src/Microsoft.AspNetCore.Authentication.OpenIdConnect/OpenIdConnectAppBuilderExtensions.cs
+++ b/src/Microsoft.AspNetCore.Authentication.OpenIdConnect/OpenIdConnectAppBuilderExtensions.cs
@@ -1,9 +1,8 @@
-// Copyright (c) .NET Foundation. All rights reserved.
+// 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 Microsoft.AspNetCore.Authentication.OpenIdConnect;
-using Microsoft.Extensions.Options;
namespace Microsoft.AspNetCore.Builder
{
@@ -13,38 +12,26 @@ namespace Microsoft.AspNetCore.Builder
public static class OpenIdConnectAppBuilderExtensions
{
///
- /// Adds the middleware to the specified , which enables OpenID Connect authentication capabilities.
+ /// Obsolete, see https://go.microsoft.com/fwlink/?linkid=845470
///
/// The to add the middleware to.
/// A reference to this instance after the operation has completed.
+ [Obsolete("See https://go.microsoft.com/fwlink/?linkid=845470", error: true)]
public static IApplicationBuilder UseOpenIdConnectAuthentication(this IApplicationBuilder app)
{
- if (app == null)
- {
- throw new ArgumentNullException(nameof(app));
- }
-
- return app.UseMiddleware();
+ throw new NotSupportedException("This method is no longer supported, see https://go.microsoft.com/fwlink/?linkid=845470");
}
///
- /// Adds the middleware to the specified , which enables OpenID Connect authentication capabilities.
+ /// Obsolete, see https://go.microsoft.com/fwlink/?linkid=845470
///
/// The to add the middleware to.
/// A that specifies options for the middleware.
/// A reference to this instance after the operation has completed.
+ [Obsolete("See https://go.microsoft.com/fwlink/?linkid=845470", error: true)]
public static IApplicationBuilder UseOpenIdConnectAuthentication(this IApplicationBuilder app, OpenIdConnectOptions options)
{
- if (app == null)
- {
- throw new ArgumentNullException(nameof(app));
- }
- if (options == null)
- {
- throw new ArgumentNullException(nameof(options));
- }
-
- return app.UseMiddleware(Options.Create(options));
+ throw new NotSupportedException("This method is no longer supported, see https://go.microsoft.com/fwlink/?linkid=845470");
}
}
-}
+}
\ No newline at end of file
diff --git a/src/Microsoft.AspNetCore.Authentication.OpenIdConnect/OpenIdConnectExtensions.cs b/src/Microsoft.AspNetCore.Authentication.OpenIdConnect/OpenIdConnectExtensions.cs
new file mode 100644
index 000000000..5c84307b1
--- /dev/null
+++ b/src/Microsoft.AspNetCore.Authentication.OpenIdConnect/OpenIdConnectExtensions.cs
@@ -0,0 +1,21 @@
+// 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 Microsoft.AspNetCore.Authentication.OpenIdConnect;
+
+namespace Microsoft.Extensions.DependencyInjection
+{
+ public static class OpenIdConnectExtensions
+ {
+ public static IServiceCollection AddOpenIdConnectAuthentication(this IServiceCollection services, Action configureOptions) =>
+ services.AddOpenIdConnectAuthentication(OpenIdConnectDefaults.AuthenticationScheme, configureOptions);
+
+ public static IServiceCollection AddOpenIdConnectAuthentication(this IServiceCollection services, string authenticationScheme, Action configureOptions)
+ {
+ //services.AddRemoteScheme(authenticationScheme, configureOptions, o => new PathString[] { o.CallbackPath, o.SignedOutCallbackPath, o.RemoteSignOutPath });
+ services.AddScheme(authenticationScheme, configureOptions);
+ return services;
+ }
+ }
+}
diff --git a/src/Microsoft.AspNetCore.Authentication.OpenIdConnect/OpenIdConnectHandler.cs b/src/Microsoft.AspNetCore.Authentication.OpenIdConnect/OpenIdConnectHandler.cs
index 6b24996e7..5a77f8345 100644
--- a/src/Microsoft.AspNetCore.Authentication.OpenIdConnect/OpenIdConnectHandler.cs
+++ b/src/Microsoft.AspNetCore.Authentication.OpenIdConnect/OpenIdConnectHandler.cs
@@ -13,12 +13,12 @@
using System.Text;
using System.Text.Encodings.Web;
using System.Threading.Tasks;
-using Microsoft.AspNetCore.Builder;
+using Microsoft.AspNetCore.DataProtection;
using Microsoft.AspNetCore.Http;
-using Microsoft.AspNetCore.Http.Authentication;
-using Microsoft.AspNetCore.Http.Features.Authentication;
using Microsoft.Extensions.Logging;
+using Microsoft.Extensions.Options;
using Microsoft.Extensions.Primitives;
+using Microsoft.IdentityModel.Protocols;
using Microsoft.IdentityModel.Protocols.OpenIdConnect;
using Microsoft.IdentityModel.Tokens;
using Microsoft.Net.Http.Headers;
@@ -55,26 +55,118 @@ public class OpenIdConnectHandler : RemoteAuthenticationHandler sharedOptions, IOptionsSnapshot options, ILoggerFactory logger, HtmlEncoder htmlEncoder, UrlEncoder encoder, IDataProtectionProvider dataProtection, ISystemClock clock)
+ : base(sharedOptions, options, dataProtection, logger, encoder, clock)
{
- Backchannel = backchannel;
HtmlEncoder = htmlEncoder;
}
- public override async Task HandleRequestAsync()
+ ///
+ /// The handler calls methods on the events which give the application control at certain points where processing is occurring.
+ /// If it is not provided a default instance is supplied which does nothing when the methods are called.
+ ///
+ protected new OpenIdConnectEvents Events
+ {
+ get { return (OpenIdConnectEvents)base.Events; }
+ set { base.Events = value; }
+ }
+
+ public override async Task InitializeAsync(AuthenticationScheme scheme, HttpContext context)
+ {
+ await base.InitializeAsync(scheme, context);
+ Events = Events ?? new OpenIdConnectEvents();
+
+ SignOutScheme = Options.SignOutScheme;
+ if (string.IsNullOrEmpty(SignOutScheme))
+ {
+ SignOutScheme = SignInScheme;
+ }
+
+ if (Options.StateDataFormat == null)
+ {
+ var dataProtector = DataProtection.CreateProtector(
+ GetType().FullName, scheme.Name, "v1");
+ Options.StateDataFormat = new PropertiesDataFormat(dataProtector);
+ }
+
+ if (Options.StringDataFormat == null)
+ {
+ var dataProtector = DataProtection.CreateProtector(
+ GetType().FullName,
+ typeof(string).FullName,
+ scheme.Name,
+ "v1");
+
+ Options.StringDataFormat = new SecureDataFormat(new StringSerializer(), dataProtector);
+ }
+
+ if (Events == null)
+ {
+ Events = new OpenIdConnectEvents();
+ }
+
+ if (string.IsNullOrEmpty(Options.TokenValidationParameters.ValidAudience) && !string.IsNullOrEmpty(Options.ClientId))
+ {
+ Options.TokenValidationParameters.ValidAudience = Options.ClientId;
+ }
+
+ Backchannel = new HttpClient(Options.BackchannelHttpHandler ?? new HttpClientHandler());
+ Backchannel.DefaultRequestHeaders.UserAgent.ParseAdd("Microsoft ASP.NET Core OpenIdConnect middleware");
+ Backchannel.Timeout = Options.BackchannelTimeout;
+ Backchannel.MaxResponseContentBufferSize = 1024 * 1024 * 10; // 10 MB
+
+ if (Options.ConfigurationManager == null)
+ {
+ if (Options.Configuration != null)
+ {
+ Options.ConfigurationManager = new StaticConfigurationManager(Options.Configuration);
+ }
+ else if (!(string.IsNullOrEmpty(Options.MetadataAddress) && string.IsNullOrEmpty(Options.Authority)))
+ {
+ if (string.IsNullOrEmpty(Options.MetadataAddress) && !string.IsNullOrEmpty(Options.Authority))
+ {
+ Options.MetadataAddress = Options.Authority;
+ if (!Options.MetadataAddress.EndsWith("/", StringComparison.Ordinal))
+ {
+ Options.MetadataAddress += "/";
+ }
+
+ Options.MetadataAddress += ".well-known/openid-configuration";
+ }
+
+ if (Options.RequireHttpsMetadata && !Options.MetadataAddress.StartsWith("https://", StringComparison.OrdinalIgnoreCase))
+ {
+ throw new InvalidOperationException("The MetadataAddress or Authority must use HTTPS unless disabled for development by setting RequireHttpsMetadata=false.");
+ }
+
+ Options.ConfigurationManager = new ConfigurationManager(Options.MetadataAddress, new OpenIdConnectConfigurationRetriever(),
+ new HttpDocumentRetriever(Backchannel) { RequireHttps = Options.RequireHttpsMetadata });
+ }
+ }
+
+ if (Options.ConfigurationManager == null)
+ {
+ throw new InvalidOperationException($"Provide {nameof(Options.Authority)}, {nameof(Options.MetadataAddress)}, "
+ + $"{nameof(Options.Configuration)}, or {nameof(Options.ConfigurationManager)} to {nameof(OpenIdConnectOptions)}");
+ }
+ }
+
+ public override Task HandleRequestAsync()
{
if (Options.RemoteSignOutPath.HasValue && Options.RemoteSignOutPath == Request.Path)
{
- return await HandleRemoteSignOutAsync();
+ return HandleRemoteSignOutAsync();
}
else if (Options.SignedOutCallbackPath.HasValue && Options.SignedOutCallbackPath == Request.Path)
{
- return await HandleSignOutCallbackAsync();
+ return HandleSignOutCallbackAsync();
}
- return await base.HandleRequestAsync();
+ return base.HandleRequestAsync();
}
protected virtual async Task HandleRemoteSignOutAsync()
@@ -97,8 +189,8 @@ protected virtual async Task HandleRemoteSignOutAsync()
message = new OpenIdConnectMessage(form.Select(pair => new KeyValuePair(pair.Key, pair.Value)));
}
- var remoteSignOutContext = new RemoteSignOutContext(Context, Options, message);
- await Options.Events.RemoteSignOut(remoteSignOutContext);
+ var remoteSignOutContext = new RemoteSignOutContext(Context, Scheme, Options, message);
+ await Events.RemoteSignOut(remoteSignOutContext);
if (remoteSignOutContext.HandledResponse)
{
@@ -120,7 +212,8 @@ protected virtual async Task HandleRemoteSignOutAsync()
// If the identifier cannot be found, bypass the session identifier checks: this may indicate that the
// authentication cookie was already cleared, that the session identifier was lost because of a lossy
// external/application cookie conversion or that the identity provider doesn't support sessions.
- var sid = (await Context.Authentication.AuthenticateAsync(Options.SignOutScheme))
+ var sid = (await Context.AuthenticateAsync(SignOutScheme))
+ ?.Principal
?.FindFirst(JwtRegisteredClaimNames.Sid)
?.Value;
if (!string.IsNullOrEmpty(sid))
@@ -142,7 +235,7 @@ protected virtual async Task HandleRemoteSignOutAsync()
Logger.RemoteSignOut();
// We've received a remote sign-out request
- await Context.Authentication.SignOutAsync(Options.SignOutScheme);
+ await Context.SignOutAsync(SignOutScheme);
return true;
}
@@ -169,7 +262,7 @@ protected override async Task HandleSignOutAsync(SignOutContext signout)
};
// Get the post redirect URI.
- var properties = new AuthenticationProperties(signout.Properties);
+ var properties = signout.Properties;
if (string.IsNullOrEmpty(properties.RedirectUri))
{
properties.RedirectUri = BuildRedirectUriIfRelative(Options.PostLogoutRedirectUri);
@@ -181,14 +274,14 @@ protected override async Task HandleSignOutAsync(SignOutContext signout)
Logger.PostSignOutRedirect(properties.RedirectUri);
// Attach the identity token to the logout request when possible.
- message.IdTokenHint = await Context.Authentication.GetTokenAsync(Options.SignOutScheme, OpenIdConnectParameterNames.IdToken);
+ message.IdTokenHint = await Context.GetTokenAsync(SignOutScheme, OpenIdConnectParameterNames.IdToken);
- var redirectContext = new RedirectContext(Context, Options, properties)
+ var redirectContext = new RedirectContext(Context, Scheme, Options, properties)
{
ProtocolMessage = message
};
- await Options.Events.RedirectToIdentityProviderForSignOut(redirectContext);
+ await Events.RedirectToIdentityProviderForSignOut(redirectContext);
if (redirectContext.HandledResponse)
{
Logger.RedirectToIdentityProviderForSignOutHandledResponse();
@@ -271,7 +364,6 @@ protected virtual Task HandleSignOutCallbackAsync()
if (!string.IsNullOrEmpty(properties?.RedirectUri))
{
Response.Redirect(properties.RedirectUri);
- return Task.FromResult(true);
}
}
@@ -282,7 +374,7 @@ protected virtual Task HandleSignOutCallbackAsync()
/// Responds to a 401 Challenge. Sends an OpenIdConnect message to the 'identity authority' to obtain an identity.
///
///
- protected override async Task HandleUnauthorizedAsync(ChallengeContext context)
+ protected override async Task HandleUnauthorizedAsync(ChallengeContext context)
{
if (context == null)
{
@@ -294,8 +386,7 @@ protected override async Task HandleUnauthorizedAsync(ChallengeContext con
// order for local RedirectUri
// 1. challenge.Properties.RedirectUri
// 2. CurrentUri if RedirectUri is not set)
- var properties = new AuthenticationProperties(context.Properties);
-
+ var properties = context.Properties;
if (string.IsNullOrEmpty(properties.RedirectUri))
{
properties.RedirectUri = CurrentUri;
@@ -335,21 +426,21 @@ protected override async Task HandleUnauthorizedAsync(ChallengeContext con
GenerateCorrelationId(properties);
- var redirectContext = new RedirectContext(Context, Options, properties)
+ var redirectContext = new RedirectContext(Context, Scheme, Options, properties)
{
ProtocolMessage = message
};
- await Options.Events.RedirectToIdentityProvider(redirectContext);
+ await Events.RedirectToIdentityProvider(redirectContext);
if (redirectContext.HandledResponse)
{
Logger.RedirectToIdentityProviderHandledResponse();
- return true;
+ return;
}
else if (redirectContext.Skipped)
{
Logger.RedirectToIdentityProviderSkipped();
- return false;
+ return;
}
message = redirectContext.ProtocolMessage;
@@ -379,7 +470,7 @@ protected override async Task HandleUnauthorizedAsync(ChallengeContext con
}
Response.Redirect(redirectUri);
- return true;
+ return;
}
else if (Options.AuthenticationMethod == OpenIdConnectRedirectBehavior.FormPost)
{
@@ -407,7 +498,7 @@ protected override async Task HandleUnauthorizedAsync(ChallengeContext con
Response.Headers[HeaderNames.Expires] = "-1";
await Response.Body.WriteAsync(buffer, 0, buffer.Length);
- return true;
+ return;
}
throw new NotImplementedException($"An unsupported authentication method has been configured: {Options.AuthenticationMethod}");
@@ -435,7 +526,7 @@ protected override async Task HandleRemoteAuthenticateAsync(
if (Options.SkipUnrecognizedRequests)
{
// Not for us?
- return AuthenticateResult.Skip();
+ return AuthenticateResult.None();
}
return AuthenticateResult.Fail("An OpenID Connect response cannot contain an " +
"identity token or an access token when using response_mode=query");
@@ -457,7 +548,7 @@ protected override async Task HandleRemoteAuthenticateAsync(
if (Options.SkipUnrecognizedRequests)
{
// Not for us?
- return AuthenticateResult.Skip();
+ return AuthenticateResult.None();
}
return AuthenticateResult.Fail("No message.");
}
@@ -473,7 +564,7 @@ protected override async Task HandleRemoteAuthenticateAsync(
}
var messageReceivedContext = await RunMessageReceivedEventAsync(authorizationResponse, properties);
- if (messageReceivedContext.CheckEventResult(out result))
+ if (messageReceivedContext.ProcessingCompleted(out result))
{
return result;
}
@@ -489,7 +580,7 @@ protected override async Task HandleRemoteAuthenticateAsync(
Logger.NullOrEmptyAuthorizationResponseState();
if (Options.SkipUnrecognizedRequests)
{
- return AuthenticateResult.Skip();
+ return AuthenticateResult.None();
}
return AuthenticateResult.Fail(Resources.MessageStateIsNullOrEmpty);
}
@@ -504,7 +595,7 @@ protected override async Task HandleRemoteAuthenticateAsync(
if (Options.SkipUnrecognizedRequests)
{
// Not for us?
- return AuthenticateResult.Skip();
+ return AuthenticateResult.None();
}
return AuthenticateResult.Fail(Resources.MessageStateIsInvalid);
}
@@ -550,7 +641,7 @@ protected override async Task HandleRemoteAuthenticateAsync(
}
var tokenValidatedContext = await RunTokenValidatedEventAsync(authorizationResponse, null, properties, ticket, jwt, nonce);
- if (tokenValidatedContext.CheckEventResult(out result))
+ if (tokenValidatedContext.ProcessingCompleted(out result))
{
return result;
}
@@ -575,7 +666,7 @@ protected override async Task HandleRemoteAuthenticateAsync(
if (!string.IsNullOrEmpty(authorizationResponse.Code))
{
var authorizationCodeReceivedContext = await RunAuthorizationCodeReceivedEventAsync(authorizationResponse, properties, ticket, jwt);
- if (authorizationCodeReceivedContext.CheckEventResult(out result))
+ if (authorizationCodeReceivedContext.ProcessingCompleted(out result))
{
return result;
}
@@ -593,7 +684,7 @@ protected override async Task HandleRemoteAuthenticateAsync(
}
var tokenResponseReceivedContext = await RunTokenResponseReceivedEventAsync(authorizationResponse, tokenEndpointResponse, properties, ticket);
- if (tokenResponseReceivedContext.CheckEventResult(out result))
+ if (tokenResponseReceivedContext.ProcessingCompleted(out result))
{
return result;
}
@@ -620,7 +711,7 @@ protected override async Task HandleRemoteAuthenticateAsync(
}
var tokenValidatedContext = await RunTokenValidatedEventAsync(authorizationResponse, tokenEndpointResponse, properties, tokenEndpointTicket, tokenEndpointJwt, nonce);
- if (tokenValidatedContext.CheckEventResult(out result))
+ if (tokenValidatedContext.ProcessingCompleted(out result))
{
return result;
}
@@ -689,7 +780,7 @@ protected override async Task HandleRemoteAuthenticateAsync(
}
var authenticationFailedContext = await RunAuthenticationFailedEventAsync(authorizationResponse, exception);
- if (authenticationFailedContext.CheckEventResult(out result))
+ if (authenticationFailedContext.ProcessingCompleted(out result))
{
return result;
}
@@ -804,7 +895,7 @@ protected virtual async Task GetUserInformationAsync(OpenIdC
var userInformationReceivedContext = await RunUserInformationReceivedEventAsync(ticket, message, user);
AuthenticateResult result;
- if (userInformationReceivedContext.CheckEventResult(out result))
+ if (userInformationReceivedContext.ProcessingCompleted(out result))
{
return result;
}
@@ -861,7 +952,7 @@ private void SaveTokens(AuthenticationProperties properties, OpenIdConnectMessag
int value;
if (int.TryParse(message.ExpiresIn, NumberStyles.Integer, CultureInfo.InvariantCulture, out value))
{
- var expiresAt = Options.SystemClock.UtcNow + TimeSpan.FromSeconds(value);
+ var expiresAt = Clock.UtcNow + TimeSpan.FromSeconds(value);
// https://www.w3.org/TR/xmlschema-2/#dateTime
// https://msdn.microsoft.com/en-us/library/az4se3k1(v=vs.110).aspx
tokens.Add(new AuthenticationToken { Name = "expires_at", Value = expiresAt.ToString("o", CultureInfo.InvariantCulture) });
@@ -891,7 +982,7 @@ private void WriteNonceCookie(string nonce)
{
HttpOnly = true,
Secure = Request.IsHttps,
- Expires = Options.SystemClock.UtcNow.Add(Options.ProtocolValidator.NonceLifetime)
+ Expires = Clock.UtcNow.Add(Options.ProtocolValidator.NonceLifetime)
});
}
@@ -971,13 +1062,13 @@ private AuthenticationProperties GetPropertiesFromState(string state)
private async Task RunMessageReceivedEventAsync(OpenIdConnectMessage message, AuthenticationProperties properties)
{
Logger.MessageReceived(message.BuildRedirectUrl());
- var messageReceivedContext = new MessageReceivedContext(Context, Options)
+ var messageReceivedContext = new MessageReceivedContext(Context, Scheme, Options)
{
ProtocolMessage = message,
Properties = properties,
};
- await Options.Events.MessageReceived(messageReceivedContext);
+ await Events.MessageReceived(messageReceivedContext);
if (messageReceivedContext.HandledResponse)
{
Logger.MessageReceivedContextHandledResponse();
@@ -992,7 +1083,7 @@ private async Task RunMessageReceivedEventAsync(OpenIdCo
private async Task RunTokenValidatedEventAsync(OpenIdConnectMessage authorizationResponse, OpenIdConnectMessage tokenEndpointResponse, AuthenticationProperties properties, AuthenticationTicket ticket, JwtSecurityToken jwt, string nonce)
{
- var tokenValidatedContext = new TokenValidatedContext(Context, Options)
+ var tokenValidatedContext = new TokenValidatedContext(Context, Scheme, Options)
{
ProtocolMessage = authorizationResponse,
TokenEndpointResponse = tokenEndpointResponse,
@@ -1002,7 +1093,7 @@ private async Task RunTokenValidatedEventAsync(OpenIdConn
Nonce = nonce,
};
- await Options.Events.TokenValidated(tokenValidatedContext);
+ await Events.TokenValidated(tokenValidatedContext);
if (tokenValidatedContext.HandledResponse)
{
Logger.TokenValidatedHandledResponse();
@@ -1029,7 +1120,7 @@ private async Task RunAuthorizationCodeReceive
RedirectUri = properties.Items[OpenIdConnectDefaults.RedirectUriForCodePropertiesKey]
};
- var authorizationCodeReceivedContext = new AuthorizationCodeReceivedContext(Context, Options)
+ var authorizationCodeReceivedContext = new AuthorizationCodeReceivedContext(Context, Scheme, Options)
{
ProtocolMessage = authorizationResponse,
Properties = properties,
@@ -1039,7 +1130,7 @@ private async Task RunAuthorizationCodeReceive
Backchannel = Backchannel,
};
- await Options.Events.AuthorizationCodeReceived(authorizationCodeReceivedContext);
+ await Events.AuthorizationCodeReceived(authorizationCodeReceivedContext);
if (authorizationCodeReceivedContext.HandledResponse)
{
Logger.AuthorizationCodeReceivedContextHandledResponse();
@@ -1059,14 +1150,14 @@ private async Task RunTokenResponseReceivedEventAs
AuthenticationTicket ticket)
{
Logger.TokenResponseReceived();
- var eventContext = new TokenResponseReceivedContext(Context, Options, properties)
+ var eventContext = new TokenResponseReceivedContext(Context, Scheme, Options, properties)
{
ProtocolMessage = message,
TokenEndpointResponse = tokenEndpointResponse,
Ticket = ticket
};
- await Options.Events.TokenResponseReceived(eventContext);
+ await Events.TokenResponseReceived(eventContext);
if (eventContext.HandledResponse)
{
Logger.TokenResponseReceivedHandledResponse();
@@ -1083,14 +1174,14 @@ private async Task RunUserInformationReceivedEve
{
Logger.UserInformationReceived(user.ToString());
- var userInformationReceivedContext = new UserInformationReceivedContext(Context, Options)
+ var userInformationReceivedContext = new UserInformationReceivedContext(Context, Scheme, Options)
{
Ticket = ticket,
ProtocolMessage = message,
User = user,
};
- await Options.Events.UserInformationReceived(userInformationReceivedContext);
+ await Events.UserInformationReceived(userInformationReceivedContext);
if (userInformationReceivedContext.HandledResponse)
{
Logger.UserInformationReceivedHandledResponse();
@@ -1105,13 +1196,13 @@ private async Task RunUserInformationReceivedEve
private async Task RunAuthenticationFailedEventAsync(OpenIdConnectMessage message, Exception exception)
{
- var authenticationFailedContext = new AuthenticationFailedContext(Context, Options)
+ var authenticationFailedContext = new AuthenticationFailedContext(Context, Scheme, Options)
{
ProtocolMessage = message,
Exception = exception
};
- await Options.Events.AuthenticationFailed(authenticationFailedContext);
+ await Events.AuthenticationFailed(authenticationFailedContext);
if (authenticationFailedContext.HandledResponse)
{
Logger.AuthenticationFailedContextHandledResponse();
@@ -1161,7 +1252,7 @@ private AuthenticationTicket ValidateToken(string idToken, AuthenticationPropert
throw new SecurityTokenException(string.Format(CultureInfo.InvariantCulture, Resources.UnableToValidateToken, idToken));
}
- var ticket = new AuthenticationTicket(principal, properties, Options.AuthenticationScheme);
+ var ticket = new AuthenticationTicket(principal, properties, Scheme.Name);
if (Options.UseTokenLifetime)
{
@@ -1220,5 +1311,18 @@ private OpenIdConnectProtocolException CreateOpenIdConnectProtocolException(Open
description,
errorUri));
}
+
+ private class StringSerializer : IDataSerializer
+ {
+ public string Deserialize(byte[] data)
+ {
+ return Encoding.UTF8.GetString(data);
+ }
+
+ public byte[] Serialize(string model)
+ {
+ return Encoding.UTF8.GetBytes(model);
+ }
+ }
}
}
diff --git a/src/Microsoft.AspNetCore.Authentication.OpenIdConnect/OpenIdConnectMiddleware.cs b/src/Microsoft.AspNetCore.Authentication.OpenIdConnect/OpenIdConnectMiddleware.cs
deleted file mode 100644
index 8d880d0d9..000000000
--- a/src/Microsoft.AspNetCore.Authentication.OpenIdConnect/OpenIdConnectMiddleware.cs
+++ /dev/null
@@ -1,209 +0,0 @@
-// 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.Net.Http;
-using System.Text;
-using System.Text.Encodings.Web;
-using Microsoft.AspNetCore.Builder;
-using Microsoft.AspNetCore.DataProtection;
-using Microsoft.AspNetCore.Http;
-using Microsoft.Extensions.Logging;
-using Microsoft.Extensions.Options;
-using Microsoft.IdentityModel.Protocols;
-using Microsoft.IdentityModel.Protocols.OpenIdConnect;
-
-namespace Microsoft.AspNetCore.Authentication.OpenIdConnect
-{
- ///
- /// ASP.NET Core middleware for obtaining identities using OpenIdConnect protocol.
- ///
- public class OpenIdConnectMiddleware : AuthenticationMiddleware
- {
- ///
- /// Initializes a
- ///
- /// The next middleware in the middleware pipeline to invoke.
- /// provider for creating a data protector.
- /// factory for creating a .
- ///
- ///
- ///
- ///
- /// The .
- public OpenIdConnectMiddleware(
- RequestDelegate next,
- IDataProtectionProvider dataProtectionProvider,
- ILoggerFactory loggerFactory,
- UrlEncoder encoder,
- IServiceProvider services,
- IOptions sharedOptions,
- IOptions options,
- HtmlEncoder htmlEncoder)
- : base(next, options, loggerFactory, encoder)
- {
- if (next == null)
- {
- throw new ArgumentNullException(nameof(next));
- }
-
- if (dataProtectionProvider == null)
- {
- throw new ArgumentNullException(nameof(dataProtectionProvider));
- }
-
- if (loggerFactory == null)
- {
- throw new ArgumentNullException(nameof(loggerFactory));
- }
-
- if (encoder == null)
- {
- throw new ArgumentNullException(nameof(encoder));
- }
-
- if (services == null)
- {
- throw new ArgumentNullException(nameof(services));
- }
-
- if (sharedOptions == null)
- {
- throw new ArgumentNullException(nameof(sharedOptions));
- }
-
- if (options == null)
- {
- throw new ArgumentNullException(nameof(options));
- }
-
- if (htmlEncoder == null)
- {
- throw new ArgumentNullException(nameof(htmlEncoder));
- }
-
- if (string.IsNullOrEmpty(Options.ClientId))
- {
- throw new ArgumentException("Options.ClientId must be provided", nameof(Options.ClientId));
- }
-
- if (!Options.CallbackPath.HasValue)
- {
- throw new ArgumentException("Options.CallbackPath must be provided.");
- }
-
- if (string.IsNullOrEmpty(Options.SignInScheme))
- {
- Options.SignInScheme = sharedOptions.Value.SignInScheme;
- }
- if (string.IsNullOrEmpty(Options.SignInScheme))
- {
- throw new ArgumentException("Options.SignInScheme is required.");
- }
- if (string.IsNullOrEmpty(Options.SignOutScheme))
- {
- Options.SignOutScheme = Options.SignInScheme;
- }
-
- HtmlEncoder = htmlEncoder;
-
- if (Options.StateDataFormat == null)
- {
- var dataProtector = dataProtectionProvider.CreateProtector(
- typeof(OpenIdConnectMiddleware).FullName,
- typeof(string).FullName,
- Options.AuthenticationScheme,
- "v1");
-
- Options.StateDataFormat = new PropertiesDataFormat(dataProtector);
- }
-
- if (Options.StringDataFormat == null)
- {
- var dataProtector = dataProtectionProvider.CreateProtector(
- typeof(OpenIdConnectMiddleware).FullName,
- typeof(string).FullName,
- Options.AuthenticationScheme,
- "v1");
-
- Options.StringDataFormat = new SecureDataFormat(new StringSerializer(), dataProtector);
- }
-
- if (Options.Events == null)
- {
- Options.Events = new OpenIdConnectEvents();
- }
-
- if (string.IsNullOrEmpty(Options.TokenValidationParameters.ValidAudience) && !string.IsNullOrEmpty(Options.ClientId))
- {
- Options.TokenValidationParameters.ValidAudience = Options.ClientId;
- }
-
- Backchannel = new HttpClient(Options.BackchannelHttpHandler ?? new HttpClientHandler());
- Backchannel.DefaultRequestHeaders.UserAgent.ParseAdd("Microsoft ASP.NET Core OpenIdConnect middleware");
- Backchannel.Timeout = Options.BackchannelTimeout;
- Backchannel.MaxResponseContentBufferSize = 1024 * 1024 * 10; // 10 MB
-
- if (Options.ConfigurationManager == null)
- {
- if (Options.Configuration != null)
- {
- Options.ConfigurationManager = new StaticConfigurationManager(Options.Configuration);
- }
- else if (!(string.IsNullOrEmpty(Options.MetadataAddress) && string.IsNullOrEmpty(Options.Authority)))
- {
- if (string.IsNullOrEmpty(Options.MetadataAddress) && !string.IsNullOrEmpty(Options.Authority))
- {
- Options.MetadataAddress = Options.Authority;
- if (!Options.MetadataAddress.EndsWith("/", StringComparison.Ordinal))
- {
- Options.MetadataAddress += "/";
- }
-
- Options.MetadataAddress += ".well-known/openid-configuration";
- }
-
- if (Options.RequireHttpsMetadata && !Options.MetadataAddress.StartsWith("https://", StringComparison.OrdinalIgnoreCase))
- {
- throw new InvalidOperationException("The MetadataAddress or Authority must use HTTPS unless disabled for development by setting RequireHttpsMetadata=false.");
- }
-
- Options.ConfigurationManager = new ConfigurationManager(Options.MetadataAddress, new OpenIdConnectConfigurationRetriever(),
- new HttpDocumentRetriever(Backchannel) { RequireHttps = Options.RequireHttpsMetadata });
- }
- }
-
- if (Options.ConfigurationManager == null)
- {
- throw new InvalidOperationException($"Provide {nameof(Options.Authority)}, {nameof(Options.MetadataAddress)}, "
- + $"{nameof(Options.Configuration)}, or {nameof(Options.ConfigurationManager)} to {nameof(OpenIdConnectOptions)}");
- }
- }
-
- protected HttpClient Backchannel { get; private set; }
-
- protected HtmlEncoder HtmlEncoder { get; private set; }
-
- ///
- /// Provides the object for processing authentication-related requests.
- ///
- /// An configured with the supplied to the constructor.
- protected override AuthenticationHandler CreateHandler()
- {
- return new OpenIdConnectHandler(Backchannel, HtmlEncoder);
- }
-
- private class StringSerializer : IDataSerializer
- {
- public string Deserialize(byte[] data)
- {
- return Encoding.UTF8.GetString(data);
- }
-
- public byte[] Serialize(string model)
- {
- return Encoding.UTF8.GetBytes(model);
- }
- }
- }
-}
diff --git a/src/Microsoft.AspNetCore.Authentication.OpenIdConnect/OpenIdConnectOptions.cs b/src/Microsoft.AspNetCore.Authentication.OpenIdConnect/OpenIdConnectOptions.cs
index 8269acbd8..64c24f4d1 100644
--- a/src/Microsoft.AspNetCore.Authentication.OpenIdConnect/OpenIdConnectOptions.cs
+++ b/src/Microsoft.AspNetCore.Authentication.OpenIdConnect/OpenIdConnectOptions.cs
@@ -8,27 +8,20 @@
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.OAuth.Claims;
using Microsoft.AspNetCore.Authentication.OpenIdConnect;
+using Microsoft.AspNetCore.DataProtection;
using Microsoft.AspNetCore.Http;
-using Microsoft.AspNetCore.Http.Authentication;
+using Microsoft.Extensions.Options;
using Microsoft.IdentityModel.Protocols;
using Microsoft.IdentityModel.Protocols.OpenIdConnect;
using Microsoft.IdentityModel.Tokens;
-namespace Microsoft.AspNetCore.Builder
+namespace Microsoft.AspNetCore.Authentication.OpenIdConnect
{
///
- /// Configuration options for
+ /// Configuration options for
///
public class OpenIdConnectOptions : RemoteAuthenticationOptions
{
- ///
- /// Initializes a new
- ///
- public OpenIdConnectOptions()
- : this(OpenIdConnectDefaults.AuthenticationScheme)
- {
- }
-
///
/// Initializes a new
///
@@ -44,11 +37,8 @@ public OpenIdConnectOptions()
/// TokenValidationParameters: new with AuthenticationScheme = authenticationScheme.
/// UseTokenLifetime: false.
///
- /// will be used to when creating the for the AuthenticationScheme property.
- public OpenIdConnectOptions(string authenticationScheme)
+ public OpenIdConnectOptions()
{
- AuthenticationScheme = authenticationScheme;
- AutomaticChallenge = true;
DisplayName = OpenIdConnectDefaults.Caption;
CallbackPath = new PathString("/signin-oidc");
SignedOutCallbackPath = new PathString("/signout-callback-oidc");
@@ -83,6 +73,24 @@ public OpenIdConnectOptions(string authenticationScheme)
ClaimActions.MapUniqueJsonKey("email", "email");
}
+ ///
+ /// Check that the options are valid. Should throw an exception if things are not ok.
+ ///
+ public override void Validate()
+ {
+ base.Validate();
+
+ if (string.IsNullOrEmpty(ClientId))
+ {
+ throw new ArgumentException("Options.ClientId must be provided", nameof(ClientId));
+ }
+
+ if (!CallbackPath.HasValue)
+ {
+ throw new ArgumentException("Options.CallbackPath must be provided.", nameof(CallbackPath));
+ }
+ }
+
///
/// Gets or sets the Authority to use when making OpenIdConnect calls.
///
@@ -133,11 +141,11 @@ public OpenIdConnectOptions(string authenticationScheme)
public string MetadataAddress { get; set; }
///
- /// Gets or sets the to notify when processing OpenIdConnect messages.
+ /// Gets or sets the to notify when processing OpenIdConnect messages.
///
- public new IOpenIdConnectEvents Events
+ public new OpenIdConnectEvents Events
{
- get { return (IOpenIdConnectEvents)base.Events; }
+ get { return (OpenIdConnectEvents)base.Events; }
set { base.Events = value; }
}
diff --git a/src/Microsoft.AspNetCore.Authentication.Twitter/Events/BaseTwitterContext.cs b/src/Microsoft.AspNetCore.Authentication.Twitter/Events/BaseTwitterContext.cs
index 5f00cb18b..b71b8655b 100644
--- a/src/Microsoft.AspNetCore.Authentication.Twitter/Events/BaseTwitterContext.cs
+++ b/src/Microsoft.AspNetCore.Authentication.Twitter/Events/BaseTwitterContext.cs
@@ -1,7 +1,6 @@
// 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 Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
namespace Microsoft.AspNetCore.Authentication.Twitter
@@ -9,19 +8,23 @@ namespace Microsoft.AspNetCore.Authentication.Twitter
///
/// Base class for other Twitter contexts.
///
- public class BaseTwitterContext : BaseContext
+ public class BaseTwitterContext : BaseAuthenticationContext
{
///
/// Initializes a
///
/// The HTTP environment
+ /// The scheme data
/// The options for Twitter
- public BaseTwitterContext(HttpContext context, TwitterOptions options)
- : base(context)
+ /// The AuthenticationProperties
+ public BaseTwitterContext(HttpContext context, AuthenticationScheme scheme, TwitterOptions options, AuthenticationProperties properties)
+ : base(context, scheme.Name, properties)
{
Options = options;
}
public TwitterOptions Options { get; }
+
+ public AuthenticationScheme Scheme { get; }
}
}
diff --git a/src/Microsoft.AspNetCore.Authentication.Twitter/Events/ITwitterEvents.cs b/src/Microsoft.AspNetCore.Authentication.Twitter/Events/ITwitterEvents.cs
deleted file mode 100644
index 006fafc73..000000000
--- a/src/Microsoft.AspNetCore.Authentication.Twitter/Events/ITwitterEvents.cs
+++ /dev/null
@@ -1,26 +0,0 @@
-// 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.Threading.Tasks;
-
-namespace Microsoft.AspNetCore.Authentication.Twitter
-{
- ///
- /// Specifies callback methods which the invokes to enable developer control over the authentication process. />
- ///
- public interface ITwitterEvents : IRemoteAuthenticationEvents
- {
- ///
- /// Invoked whenever Twitter succesfully authenticates a user
- ///
- /// Contains information about the login session as well as the user .
- /// A representing the completed operation.
- Task CreatingTicket(TwitterCreatingTicketContext context);
-
- ///
- /// Called when a Challenge causes a redirect to authorize endpoint in the Twitter middleware
- ///
- /// Contains redirect URI and of the challenge
- Task RedirectToAuthorizationEndpoint(TwitterRedirectToAuthorizationEndpointContext context);
- }
-}
diff --git a/src/Microsoft.AspNetCore.Authentication.Twitter/Events/TwitterCreatingTicketContext.cs b/src/Microsoft.AspNetCore.Authentication.Twitter/Events/TwitterCreatingTicketContext.cs
index 21c6189d7..eaf704bcb 100644
--- a/src/Microsoft.AspNetCore.Authentication.Twitter/Events/TwitterCreatingTicketContext.cs
+++ b/src/Microsoft.AspNetCore.Authentication.Twitter/Events/TwitterCreatingTicketContext.cs
@@ -3,9 +3,7 @@
using System;
using System.Security.Claims;
-using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
-using Microsoft.AspNetCore.Http.Authentication;
using Newtonsoft.Json.Linq;
namespace Microsoft.AspNetCore.Authentication.Twitter
@@ -19,21 +17,25 @@ public class TwitterCreatingTicketContext : BaseTwitterContext
/// Initializes a
///
/// The HTTP environment
+ /// The scheme data
/// The options for Twitter
/// Twitter user ID
/// Twitter screen name
/// Twitter access token
/// Twitter access token secret
/// User details
+ /// AuthenticationProperties.
public TwitterCreatingTicketContext(
HttpContext context,
+ AuthenticationScheme scheme,
TwitterOptions options,
+ AuthenticationProperties properties,
string userId,
string screenName,
string accessToken,
string accessTokenSecret,
JObject user)
- : base(context, options)
+ : base(context, scheme, options, properties)
{
UserId = userId;
ScreenName = screenName;
@@ -72,10 +74,5 @@ public TwitterCreatingTicketContext(
/// Gets the representing the user
///
public ClaimsPrincipal Principal { get; set; }
-
- ///
- /// Gets or sets a property bag for common authentication properties
- ///
- public AuthenticationProperties Properties { get; set; }
}
}
diff --git a/src/Microsoft.AspNetCore.Authentication.Twitter/Events/TwitterEvents.cs b/src/Microsoft.AspNetCore.Authentication.Twitter/Events/TwitterEvents.cs
index 033227542..d26055b81 100644
--- a/src/Microsoft.AspNetCore.Authentication.Twitter/Events/TwitterEvents.cs
+++ b/src/Microsoft.AspNetCore.Authentication.Twitter/Events/TwitterEvents.cs
@@ -8,9 +8,9 @@
namespace Microsoft.AspNetCore.Authentication.Twitter
{
///
- /// Default implementation.
+ /// Default implementation.
///
- public class TwitterEvents : RemoteAuthenticationEvents, ITwitterEvents
+ public class TwitterEvents : RemoteAuthenticationEvents
{
///
/// Gets or sets the function that is invoked when the Authenticated method is invoked.
diff --git a/src/Microsoft.AspNetCore.Authentication.Twitter/Events/TwitterRedirectToAuthorizationEndpointContext.cs b/src/Microsoft.AspNetCore.Authentication.Twitter/Events/TwitterRedirectToAuthorizationEndpointContext.cs
index aa1da43ed..c73c9d9ba 100644
--- a/src/Microsoft.AspNetCore.Authentication.Twitter/Events/TwitterRedirectToAuthorizationEndpointContext.cs
+++ b/src/Microsoft.AspNetCore.Authentication.Twitter/Events/TwitterRedirectToAuthorizationEndpointContext.cs
@@ -1,9 +1,7 @@
// 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 Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
-using Microsoft.AspNetCore.Http.Authentication;
namespace Microsoft.AspNetCore.Authentication.Twitter
{
@@ -16,12 +14,14 @@ public class TwitterRedirectToAuthorizationEndpointContext : BaseTwitterContext
/// Creates a new context object.
///
/// The HTTP request context.
+ /// The scheme data
/// The Twitter middleware options.
/// The authentication properties of the challenge.
/// The initial redirect URI.
- public TwitterRedirectToAuthorizationEndpointContext(HttpContext context, TwitterOptions options,
- AuthenticationProperties properties, string redirectUri)
- : base(context, options)
+ public TwitterRedirectToAuthorizationEndpointContext(HttpContext context, AuthenticationScheme scheme,
+
+ TwitterOptions options, AuthenticationProperties properties, string redirectUri)
+ : base(context, scheme, options, properties)
{
RedirectUri = redirectUri;
Properties = properties;
@@ -31,10 +31,5 @@ public TwitterRedirectToAuthorizationEndpointContext(HttpContext context, Twitte
/// Gets the URI used for the redirect operation.
///
public string RedirectUri { get; private set; }
-
- ///
- /// Gets the authentication properties of the challenge.
- ///
- public AuthenticationProperties Properties { get; private set; }
}
}
diff --git a/src/Microsoft.AspNetCore.Authentication.Twitter/TwitterAppBuilderExtensions.cs b/src/Microsoft.AspNetCore.Authentication.Twitter/TwitterAppBuilderExtensions.cs
index df6ca1d02..45129ca1b 100644
--- a/src/Microsoft.AspNetCore.Authentication.Twitter/TwitterAppBuilderExtensions.cs
+++ b/src/Microsoft.AspNetCore.Authentication.Twitter/TwitterAppBuilderExtensions.cs
@@ -1,9 +1,8 @@
-// Copyright (c) .NET Foundation. All rights reserved.
+// 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 Microsoft.AspNetCore.Authentication.Twitter;
-using Microsoft.Extensions.Options;
namespace Microsoft.AspNetCore.Builder
{
@@ -13,38 +12,26 @@ namespace Microsoft.AspNetCore.Builder
public static class TwitterAppBuilderExtensions
{
///
- /// Adds the middleware to the specified , which enables Twitter authentication capabilities.
+ /// Obsolete, see https://go.microsoft.com/fwlink/?linkid=845470
///
/// The to add the middleware to.
/// A reference to this instance after the operation has completed.
+ [Obsolete("See https://go.microsoft.com/fwlink/?linkid=845470", error: true)]
public static IApplicationBuilder UseTwitterAuthentication(this IApplicationBuilder app)
{
- if (app == null)
- {
- throw new ArgumentNullException(nameof(app));
- }
-
- return app.UseMiddleware();
+ throw new NotSupportedException("This method is no longer supported, see https://go.microsoft.com/fwlink/?linkid=845470");
}
///
- /// Adds the middleware to the specified , which enables Twitter authentication capabilities.
+ /// Obsolete, see https://go.microsoft.com/fwlink/?linkid=845470
///
/// The to add the middleware to.
/// An action delegate to configure the provided .
/// A reference to this instance after the operation has completed.
+ [Obsolete("See https://go.microsoft.com/fwlink/?linkid=845470", error: true)]
public static IApplicationBuilder UseTwitterAuthentication(this IApplicationBuilder app, TwitterOptions options)
{
- if (app == null)
- {
- throw new ArgumentNullException(nameof(app));
- }
- if (options == null)
- {
- throw new ArgumentNullException(nameof(options));
- }
-
- return app.UseMiddleware(Options.Create(options));
+ throw new NotSupportedException("This method is no longer supported, see https://go.microsoft.com/fwlink/?linkid=845470");
}
}
-}
+}
\ No newline at end of file
diff --git a/src/Microsoft.AspNetCore.Authentication.Twitter/TwitterExtensions.cs b/src/Microsoft.AspNetCore.Authentication.Twitter/TwitterExtensions.cs
new file mode 100644
index 000000000..e10ae4b17
--- /dev/null
+++ b/src/Microsoft.AspNetCore.Authentication.Twitter/TwitterExtensions.cs
@@ -0,0 +1,17 @@
+// 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 Microsoft.AspNetCore.Authentication.Twitter;
+
+namespace Microsoft.Extensions.DependencyInjection
+{
+ public static class TwitterExtensions
+ {
+ public static IServiceCollection AddTwitterAuthentication(this IServiceCollection services, Action configureOptions) =>
+ services.AddTwitterAuthentication(TwitterDefaults.AuthenticationScheme, configureOptions);
+
+ public static IServiceCollection AddTwitterAuthentication(this IServiceCollection services, string authenticationScheme, Action configureOptions) =>
+ services.AddScheme(authenticationScheme, configureOptions);
+ }
+}
diff --git a/src/Microsoft.AspNetCore.Authentication.Twitter/TwitterHandler.cs b/src/Microsoft.AspNetCore.Authentication.Twitter/TwitterHandler.cs
index 8481730a8..1d5cd0e01 100644
--- a/src/Microsoft.AspNetCore.Authentication.Twitter/TwitterHandler.cs
+++ b/src/Microsoft.AspNetCore.Authentication.Twitter/TwitterHandler.cs
@@ -8,13 +8,13 @@
using System.Security.Claims;
using System.Security.Cryptography;
using System.Text;
+using System.Text.Encodings.Web;
using System.Threading.Tasks;
-using Microsoft.AspNetCore.Builder;
+using Microsoft.AspNetCore.DataProtection;
using Microsoft.AspNetCore.Http;
-using Microsoft.AspNetCore.Http.Authentication;
-using Microsoft.AspNetCore.Http.Features.Authentication;
using Microsoft.AspNetCore.WebUtilities;
using Microsoft.Extensions.Logging;
+using Microsoft.Extensions.Options;
using Microsoft.Extensions.Primitives;
using Newtonsoft.Json.Linq;
@@ -28,11 +28,43 @@ internal class TwitterHandler : RemoteAuthenticationHandler
private const string AuthenticationEndpoint = "https://api.twitter.com/oauth/authenticate?oauth_token=";
private const string AccessTokenEndpoint = "https://api.twitter.com/oauth/access_token";
- private readonly HttpClient _httpClient;
+ private HttpClient _httpClient;
- public TwitterHandler(HttpClient httpClient)
+ ///
+ /// The handler calls methods on the events which give the application control at certain points where processing is occurring.
+ /// If it is not provided a default instance is supplied which does nothing when the methods are called.
+ ///
+ protected new TwitterEvents Events
{
- _httpClient = httpClient;
+ get { return (TwitterEvents)base.Events; }
+ set { base.Events = value; }
+ }
+
+ public TwitterHandler(IOptions sharedOptions, IOptionsSnapshot options, ILoggerFactory logger, UrlEncoder encoder, IDataProtectionProvider dataProtection, ISystemClock clock)
+ : base(sharedOptions, options, dataProtection, logger, encoder, clock)
+ {
+ }
+
+ public override async Task InitializeAsync(AuthenticationScheme scheme, HttpContext context)
+ {
+ await base.InitializeAsync(scheme, context);
+ Events = Events ?? new TwitterEvents();
+
+ if (Options.StateDataFormat == null)
+ {
+ var dataProtector = DataProtection.CreateProtector(
+ GetType().FullName, Scheme.Name, "v1");
+ Options.StateDataFormat = new SecureDataFormat(
+ new RequestTokenSerializer(),
+ dataProtector);
+ }
+
+ _httpClient = new HttpClient(Options.BackchannelHttpHandler ?? new HttpClientHandler());
+ _httpClient.Timeout = Options.BackchannelTimeout;
+ _httpClient.MaxResponseContentBufferSize = 1024 * 1024 * 10; // 10 MB
+ _httpClient.DefaultRequestHeaders.Accept.ParseAdd("*/*");
+ _httpClient.DefaultRequestHeaders.UserAgent.ParseAdd("Microsoft ASP.NET Core Twitter middleware");
+ _httpClient.DefaultRequestHeaders.ExpectContinue = false;
}
protected override async Task HandleRemoteAuthenticateAsync()
@@ -113,30 +145,29 @@ protected virtual async Task CreateTicketAsync(
action.Run(user, identity, Options.ClaimsIssuer);
}
- var context = new TwitterCreatingTicketContext(Context, Options, token.UserId, token.ScreenName, token.Token, token.TokenSecret, user)
+ var context = new TwitterCreatingTicketContext(Context, Scheme, Options, properties, token.UserId, token.ScreenName, token.Token, token.TokenSecret, user)
{
- Principal = new ClaimsPrincipal(identity),
- Properties = properties
+ Principal = new ClaimsPrincipal(identity)
};
- await Options.Events.CreatingTicket(context);
+ await Events.CreatingTicket(context);
if (context.Principal?.Identity == null)
{
return null;
}
- return new AuthenticationTicket(context.Principal, context.Properties, Options.AuthenticationScheme);
+ return new AuthenticationTicket(context.Principal, context.Properties, Scheme.Name);
}
- protected override async Task HandleUnauthorizedAsync(ChallengeContext context)
+ protected override async Task HandleUnauthorizedAsync(ChallengeContext context)
{
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}
- var properties = new AuthenticationProperties(context.Properties);
+ var properties = context.Properties;
if (string.IsNullOrEmpty(properties.RedirectUri))
{
@@ -151,16 +182,13 @@ protected override async Task HandleUnauthorizedAsync(ChallengeContext con
{
HttpOnly = true,
Secure = Request.IsHttps,
- Expires = Options.SystemClock.UtcNow.Add(Options.RemoteAuthenticationTimeout),
+ Expires = Clock.UtcNow.Add(Options.RemoteAuthenticationTimeout),
};
Response.Cookies.Append(StateCookie, Options.StateDataFormat.Protect(requestToken), cookieOptions);
- var redirectContext = new TwitterRedirectToAuthorizationEndpointContext(
- Context, Options,
- properties, twitterAuthenticationEndpoint);
- await Options.Events.RedirectToAuthorizationEndpoint(redirectContext);
- return true;
+ var redirectContext = new TwitterRedirectToAuthorizationEndpointContext(Context, Scheme, Options, properties, twitterAuthenticationEndpoint);
+ await Events.RedirectToAuthorizationEndpoint(redirectContext);
}
private async Task ObtainRequestTokenAsync(string callBackUri, AuthenticationProperties properties)
diff --git a/src/Microsoft.AspNetCore.Authentication.Twitter/TwitterMiddleware.cs b/src/Microsoft.AspNetCore.Authentication.Twitter/TwitterMiddleware.cs
deleted file mode 100644
index 67fb903dd..000000000
--- a/src/Microsoft.AspNetCore.Authentication.Twitter/TwitterMiddleware.cs
+++ /dev/null
@@ -1,123 +0,0 @@
-// 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.Globalization;
-using System.Net.Http;
-using System.Text.Encodings.Web;
-using Microsoft.AspNetCore.Builder;
-using Microsoft.AspNetCore.DataProtection;
-using Microsoft.AspNetCore.Http;
-using Microsoft.Extensions.Logging;
-using Microsoft.Extensions.Options;
-
-namespace Microsoft.AspNetCore.Authentication.Twitter
-{
- ///
- /// ASP.NET Core middleware for authenticating users using Twitter.
- ///
- public class TwitterMiddleware : AuthenticationMiddleware
- {
- private readonly HttpClient _httpClient;
-
- ///
- /// Initializes a
- ///
- /// The next middleware in the HTTP pipeline to invoke
- ///
- ///
- ///
- ///
- /// Configuration options for the middleware
- public TwitterMiddleware(
- RequestDelegate next,
- IDataProtectionProvider dataProtectionProvider,
- ILoggerFactory loggerFactory,
- UrlEncoder encoder,
- IOptions sharedOptions,
- IOptions options)
- : base(next, options, loggerFactory, encoder)
- {
- if (next == null)
- {
- throw new ArgumentNullException(nameof(next));
- }
-
- if (dataProtectionProvider == null)
- {
- throw new ArgumentNullException(nameof(dataProtectionProvider));
- }
-
- if (loggerFactory == null)
- {
- throw new ArgumentNullException(nameof(loggerFactory));
- }
-
- if (encoder == null)
- {
- throw new ArgumentNullException(nameof(encoder));
- }
-
- if (sharedOptions == null)
- {
- throw new ArgumentNullException(nameof(sharedOptions));
- }
-
- if (options == null)
- {
- throw new ArgumentNullException(nameof(options));
- }
-
- if (string.IsNullOrEmpty(Options.ConsumerSecret))
- {
- throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, Resources.Exception_OptionMustBeProvided, nameof(Options.ConsumerSecret)));
- }
- if (string.IsNullOrEmpty(Options.ConsumerKey))
- {
- throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, Resources.Exception_OptionMustBeProvided, nameof(Options.ConsumerKey)));
- }
- if (!Options.CallbackPath.HasValue)
- {
- throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, Resources.Exception_OptionMustBeProvided, nameof(Options.CallbackPath)));
- }
-
- if (Options.Events == null)
- {
- Options.Events = new TwitterEvents();
- }
- if (Options.StateDataFormat == null)
- {
- var dataProtector = dataProtectionProvider.CreateProtector(
- typeof(TwitterMiddleware).FullName, Options.AuthenticationScheme, "v1");
- Options.StateDataFormat = new SecureDataFormat(
- new RequestTokenSerializer(),
- dataProtector);
- }
-
- if (string.IsNullOrEmpty(Options.SignInScheme))
- {
- Options.SignInScheme = sharedOptions.Value.SignInScheme;
- }
- if (string.IsNullOrEmpty(Options.SignInScheme))
- {
- throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, Resources.Exception_OptionMustBeProvided, "SignInScheme"));
- }
-
- _httpClient = new HttpClient(Options.BackchannelHttpHandler ?? new HttpClientHandler());
- _httpClient.Timeout = Options.BackchannelTimeout;
- _httpClient.MaxResponseContentBufferSize = 1024 * 1024 * 10; // 10 MB
- _httpClient.DefaultRequestHeaders.Accept.ParseAdd("*/*");
- _httpClient.DefaultRequestHeaders.UserAgent.ParseAdd("Microsoft ASP.NET Core Twitter middleware");
- _httpClient.DefaultRequestHeaders.ExpectContinue = false;
- }
-
- ///
- /// Provides the object for processing authentication-related requests.
- ///
- /// An configured with the supplied to the constructor.
- protected override AuthenticationHandler CreateHandler()
- {
- return new TwitterHandler(_httpClient);
- }
- }
-}
diff --git a/src/Microsoft.AspNetCore.Authentication.Twitter/TwitterOptions.cs b/src/Microsoft.AspNetCore.Authentication.Twitter/TwitterOptions.cs
index 836dd3c0d..95a23e3eb 100644
--- a/src/Microsoft.AspNetCore.Authentication.Twitter/TwitterOptions.cs
+++ b/src/Microsoft.AspNetCore.Authentication.Twitter/TwitterOptions.cs
@@ -6,9 +6,10 @@
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.OAuth.Claims;
using Microsoft.AspNetCore.Authentication.Twitter;
+using Microsoft.AspNetCore.DataProtection;
using Microsoft.AspNetCore.Http;
-namespace Microsoft.AspNetCore.Builder
+namespace Microsoft.AspNetCore.Authentication.Twitter
{
///
/// Options for the Twitter authentication middleware.
@@ -20,8 +21,6 @@ public class TwitterOptions : RemoteAuthenticationOptions
///
public TwitterOptions()
{
- AuthenticationScheme = TwitterDefaults.AuthenticationScheme;
- DisplayName = AuthenticationScheme;
CallbackPath = new PathString("/signin-twitter");
BackchannelTimeout = TimeSpan.FromSeconds(60);
Events = new TwitterEvents();
@@ -60,11 +59,11 @@ public TwitterOptions()
public ISecureDataFormat StateDataFormat { get; set; }
///
- /// Gets or sets the used to handle authentication events.
+ /// Gets or sets the used to handle authentication events.
///
- public new ITwitterEvents Events
+ public new TwitterEvents Events
{
- get { return (ITwitterEvents)base.Events; }
+ get { return (TwitterEvents)base.Events; }
set { base.Events = value; }
}
}
diff --git a/src/Microsoft.AspNetCore.Authentication/AuthAppBuilderExtensions.cs b/src/Microsoft.AspNetCore.Authentication/AuthAppBuilderExtensions.cs
new file mode 100644
index 000000000..eba1ce30e
--- /dev/null
+++ b/src/Microsoft.AspNetCore.Authentication/AuthAppBuilderExtensions.cs
@@ -0,0 +1,29 @@
+// 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 Microsoft.AspNetCore.Authentication;
+
+namespace Microsoft.AspNetCore.Builder
+{
+ ///
+ /// Extension methods to add authentication capabilities to an HTTP application pipeline.
+ ///
+ public static class AuthAppBuilderExtensions
+ {
+ ///
+ /// Adds the middleware to the specified , which enables authentication capabilities.
+ ///
+ /// The to add the middleware to.
+ /// A reference to this instance after the operation has completed.
+ public static IApplicationBuilder UseAuthentication(this IApplicationBuilder app)
+ {
+ if (app == null)
+ {
+ throw new ArgumentNullException(nameof(app));
+ }
+
+ return app.UseMiddleware();
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Microsoft.AspNetCore.Authentication/AuthenticateResult.cs b/src/Microsoft.AspNetCore.Authentication/AuthenticateResult.cs
deleted file mode 100644
index 28f116d3d..000000000
--- a/src/Microsoft.AspNetCore.Authentication/AuthenticateResult.cs
+++ /dev/null
@@ -1,77 +0,0 @@
-// 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
-{
- ///
- /// Contains the result of an Authenticate call
- ///
- public class AuthenticateResult
- {
- private AuthenticateResult() { }
-
- ///
- /// If a ticket was produced, authenticate was successful.
- ///
- public bool Succeeded
- {
- get
- {
- return Ticket != null;
- }
- }
-
- ///
- /// The authentication ticket.
- ///
- public AuthenticationTicket Ticket { get; private set; }
-
- ///
- /// Holds failure information from the authentication.
- ///
- public Exception Failure { get; private set; }
-
- ///
- /// Indicates that stage of authentication was directly handled by user intervention and no
- /// further processing should be attempted.
- ///
- public bool Handled { get; private set; }
-
- ///
- /// Indicates that this stage of authentication was skipped by user intervention.
- ///
- public bool Skipped { get; private set; }
-
- public static AuthenticateResult Success(AuthenticationTicket ticket)
- {
- if (ticket == null)
- {
- throw new ArgumentNullException(nameof(ticket));
- }
- return new AuthenticateResult() { Ticket = ticket };
- }
-
- public static AuthenticateResult Handle()
- {
- return new AuthenticateResult() { Handled = true };
- }
-
- public static AuthenticateResult Skip()
- {
- return new AuthenticateResult() { Skipped = true };
- }
-
- public static AuthenticateResult Fail(Exception failure)
- {
- return new AuthenticateResult() { Failure = failure };
- }
-
- public static AuthenticateResult Fail(string failureMessage)
- {
- return new AuthenticateResult() { Failure = new Exception(failureMessage) };
- }
-
- }
-}
diff --git a/src/Microsoft.AspNetCore.Authentication/AuthenticationHandler.cs b/src/Microsoft.AspNetCore.Authentication/AuthenticationHandler.cs
index 8e7e42765..70b5b3c0a 100644
--- a/src/Microsoft.AspNetCore.Authentication/AuthenticationHandler.cs
+++ b/src/Microsoft.AspNetCore.Authentication/AuthenticationHandler.cs
@@ -4,29 +4,38 @@
using System;
using System.Text.Encodings.Web;
using System.Threading.Tasks;
-using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
-using Microsoft.AspNetCore.Http.Authentication;
-using Microsoft.AspNetCore.Http.Features.Authentication;
+using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Internal;
using Microsoft.Extensions.Logging;
+using Microsoft.Extensions.Options;
-namespace Microsoft.AspNetCore.Authentication
-{
- ///
- /// Base class for the per-request work performed by most authentication middleware.
- ///
- /// Specifies which type for of AuthenticationOptions property
- public abstract class AuthenticationHandler : IAuthenticationHandler where TOptions : AuthenticationOptions
+namespace Microsoft.AspNetCore.Authentication{
+
+ public abstract class AuthenticationHandler : IAuthenticationHandler where TOptions : AuthenticationSchemeOptions, new()
{
private Task _authenticateTask;
- private bool _finishCalled;
-
- protected bool SignInAccepted { get; set; }
- protected bool SignOutAccepted { get; set; }
- protected bool ChallengeCalled { get; set; }
+ public AuthenticationScheme Scheme { get; private set; }
+ public TOptions Options { get; private set; }
protected HttpContext Context { get; private set; }
+ protected PathString OriginalPathBase => Context.Features.Get()?.OriginalPathBase ?? Request.PathBase;
+
+ protected PathString OriginalPath => Context.Features.Get()?.OriginalPath ?? Request.Path;
+
+ protected ILogger Logger { get; }
+
+ protected UrlEncoder UrlEncoder { get; }
+
+ protected ISystemClock Clock { get; }
+
+ protected IOptionsSnapshot OptionsManager { get; }
+
+ ///
+ /// The handler calls methods on the events which give the application control at certain points where processing is occurring.
+ /// If it is not provided a default instance is supplied which does nothing when the methods are called.
+ ///
+ protected virtual object Events { get; set; }
protected HttpRequest Request
{
@@ -38,16 +47,6 @@ protected HttpResponse Response
get { return Context.Response; }
}
- protected PathString OriginalPathBase { get; private set; }
-
- protected PathString OriginalPath { get; private set; }
-
- protected ILogger Logger { get; private set; }
-
- protected UrlEncoder UrlEncoder { get; private set; }
-
- public IAuthenticationHandler PriorHandler { get; set; }
-
protected string CurrentUri
{
get
@@ -56,193 +55,72 @@ protected string CurrentUri
}
}
- protected TOptions Options { get; private set; }
-
- protected AuthenticateResult InitializeResult { get; private set; }
+ protected AuthenticationHandler(IOptionsSnapshot options, ILoggerFactory logger, UrlEncoder encoder, ISystemClock clock)
+ {
+ Logger = logger.CreateLogger(this.GetType().FullName);
+ UrlEncoder = encoder;
+ Clock = clock;
+ OptionsManager = options;
+ }
///
- /// Initialize is called once per request to contextualize this instance with appropriate state.
+ /// Initialize the handler, resolve the options and validate them.
///
- /// The original options passed by the application control behavior
- /// The utility object to observe the current request and response
- /// The logging factory used to create loggers
- /// The .
- /// async completion
- public async Task InitializeAsync(TOptions options, HttpContext context, ILogger logger, UrlEncoder encoder)
+ ///
+ ///
+ ///
+ public virtual Task InitializeAsync(AuthenticationScheme scheme, HttpContext context)
{
- if (options == null)
+ if (scheme == null)
{
- throw new ArgumentNullException(nameof(options));
+ throw new ArgumentNullException(nameof(scheme));
}
-
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}
- if (logger == null)
- {
- throw new ArgumentNullException(nameof(logger));
- }
-
- if (encoder == null)
- {
- throw new ArgumentNullException(nameof(encoder));
- }
-
- Options = options;
+ Scheme = scheme;
Context = context;
- OriginalPathBase = Request.PathBase;
- OriginalPath = Request.Path;
- Logger = logger;
- UrlEncoder = encoder;
-
- RegisterAuthenticationHandler();
- Response.OnStarting(OnStartingCallback, this);
+ Options = OptionsManager.Get(Scheme.Name) ?? new TOptions();
+ Options.Validate();
- if (ShouldHandleScheme(AuthenticationManager.AutomaticScheme, Options.AutomaticAuthenticate))
- {
- InitializeResult = await HandleAuthenticateOnceAsync();
- if (InitializeResult?.Skipped == true || InitializeResult?.Handled == true)
- {
- return;
- }
-
- if (InitializeResult?.Failure != null)
- {
- Logger.AuthenticationSchemeNotAuthenticatedWithFailure(Options.AuthenticationScheme, InitializeResult.Failure.Message);
- }
-
- var ticket = InitializeResult?.Ticket;
- if (ticket?.Principal != null)
- {
- Context.User = SecurityHelper.MergeUserPrincipal(Context.User, ticket.Principal);
- Logger.UserPrinicpalMerged(Options.AuthenticationScheme);
- }
- }
- }
-
- protected string BuildRedirectUri(string targetPath)
- {
- return Request.Scheme + "://" + Request.Host + OriginalPathBase + targetPath;
- }
-
- private static async Task OnStartingCallback(object state)
- {
- var handler = (AuthenticationHandler)state;
- await handler.FinishResponseOnce();
- }
+ // REVIEW: is there a better place for this default?
+ Options.DisplayName = Options.DisplayName ?? scheme.Name;
+ Options.ClaimsIssuer = Options.ClaimsIssuer ?? scheme.Name;
- private async Task FinishResponseOnce()
- {
- if (!_finishCalled)
+ Events = Options.Events;
+ if (Options.EventsType != null)
{
- _finishCalled = true;
- await FinishResponseAsync();
- await HandleAutomaticChallengeIfNeeded();
+ Events = Context.RequestServices.GetRequiredService(Options.EventsType);
}
- }
- ///
- /// Hook that is called when the response about to be sent
- ///
- ///
- protected virtual Task FinishResponseAsync()
- {
return TaskCache.CompletedTask;
}
- private async Task HandleAutomaticChallengeIfNeeded()
- {
- if (!ChallengeCalled && Options.AutomaticChallenge && Response.StatusCode == 401)
- {
- await HandleUnauthorizedAsync(new ChallengeContext(Options.AuthenticationScheme));
- }
- }
-
- ///
- /// Called once after Invoke by AuthenticationMiddleware.
- ///
- /// async completion
- internal async Task TeardownAsync()
- {
- try
- {
- await FinishResponseOnce();
- }
- finally
- {
- UnregisterAuthenticationHandler();
- }
- }
-
- ///
- /// Called once by common code after initialization. If an authentication middleware responds directly to
- /// specifically known paths it must override this virtual, compare the request path to it's known paths,
- /// provide any response information as appropriate, and true to stop further processing.
- ///
- /// Returning false will cause the common code to call the next middleware in line. Returning true will
- /// cause the common code to begin the async completion journey without calling the rest of the middleware
- /// pipeline.
- public virtual Task HandleRequestAsync()
- {
- if (InitializeResult?.Handled == true)
- {
- return Task.FromResult(true);
- }
- return Task.FromResult(false);
- }
-
- public void GetDescriptions(DescribeSchemesContext describeContext)
- {
- describeContext.Accept(Options.Description.Items);
-
- if (PriorHandler != null)
- {
- PriorHandler.GetDescriptions(describeContext);
- }
- }
-
- public bool ShouldHandleScheme(string authenticationScheme, bool handleAutomatic)
+ protected string BuildRedirectUri(string targetPath)
{
- return string.Equals(Options.AuthenticationScheme, authenticationScheme, StringComparison.Ordinal) ||
- (handleAutomatic && string.Equals(authenticationScheme, AuthenticationManager.AutomaticScheme, StringComparison.Ordinal));
+ return Request.Scheme + "://" + Request.Host + OriginalPathBase + targetPath;
}
- public async Task AuthenticateAsync(AuthenticateContext context)
+ public async Task AuthenticateAsync(AuthenticateContext context)
{
- var handled = false;
- if (ShouldHandleScheme(context.AuthenticationScheme, Options.AutomaticAuthenticate))
+ // Calling Authenticate more than once should always return the original value.
+ var result = await HandleAuthenticateOnceAsync();
+ if (result?.Failure == null)
{
- // Calling Authenticate more than once should always return the original value.
- var result = await HandleAuthenticateOnceAsync();
-
- if (result?.Failure != null)
+ var ticket = result?.Ticket;
+ if (ticket?.Principal != null)
{
- context.Failed(result.Failure);
+ Logger.AuthenticationSchemeAuthenticated(Scheme.Name);
}
else
{
- var ticket = result?.Ticket;
- if (ticket?.Principal != null)
- {
- context.Authenticated(ticket.Principal, ticket.Properties.Items, Options.Description.Items);
- Logger.AuthenticationSchemeAuthenticated(Options.AuthenticationScheme);
- handled = true;
- }
- else
- {
- context.NotAuthenticated();
- Logger.AuthenticationSchemeNotAuthenticated(Options.AuthenticationScheme);
- }
+ Logger.AuthenticationSchemeNotAuthenticated(Scheme.Name);
}
}
-
- if (PriorHandler != null && !handled)
- {
- await PriorHandler.AuthenticateAsync(context);
- }
+ return result;
}
///
@@ -280,17 +158,13 @@ protected async Task HandleAuthenticateOnceSafeAsync()
public async Task SignInAsync(SignInContext context)
{
- if (ShouldHandleScheme(context.AuthenticationScheme, handleAutomatic: false))
- {
- SignInAccepted = true;
- await HandleSignInAsync(context);
- Logger.AuthenticationSchemeSignedIn(Options.AuthenticationScheme);
- context.Accept();
- }
- else if (PriorHandler != null)
+ if (context == null)
{
- await PriorHandler.SignInAsync(context);
+ throw new ArgumentNullException(nameof(context));
}
+
+ await HandleSignInAsync(context);
+ Logger.AuthenticationSchemeSignedIn(Scheme.Name);
}
protected virtual Task HandleSignInAsync(SignInContext context)
@@ -305,17 +179,8 @@ public async Task SignOutAsync(SignOutContext context)
throw new ArgumentNullException(nameof(context));
}
- if (ShouldHandleScheme(context.AuthenticationScheme, handleAutomatic: false))
- {
- SignOutAccepted = true;
- await HandleSignOutAsync(context);
- Logger.AuthenticationSchemeSignedOut(Options.AuthenticationScheme);
- context.Accept();
- }
- else if (PriorHandler != null)
- {
- await PriorHandler.SignOutAsync(context);
- }
+ await HandleSignOutAsync(context);
+ Logger.AuthenticationSchemeSignedOut(Scheme.Name);
}
protected virtual Task HandleSignOutAsync(SignOutContext context)
@@ -327,10 +192,11 @@ protected virtual Task HandleSignOutAsync(SignOutContext context)
/// Override this method to deal with a challenge that is forbidden.
///
///
- protected virtual Task HandleForbiddenAsync(ChallengeContext context)
+ /// A Task.
+ protected virtual Task HandleForbiddenAsync(ChallengeContext context)
{
Response.StatusCode = 403;
- return Task.FromResult(true);
+ return TaskCache.CompletedTask;
}
///
@@ -339,58 +205,34 @@ protected virtual Task HandleForbiddenAsync(ChallengeContext context)
/// changing the 401 result to 302 of a login page or external sign-in location.)
///
///
- /// True if no other handlers should be called
- protected virtual Task HandleUnauthorizedAsync(ChallengeContext context)
+ /// A Task.
+ protected virtual Task HandleUnauthorizedAsync(ChallengeContext context)
{
Response.StatusCode = 401;
- return Task.FromResult(false);
+ return TaskCache.CompletedTask;
}
public async Task ChallengeAsync(ChallengeContext context)
{
- ChallengeCalled = true;
- var handled = false;
- if (ShouldHandleScheme(context.AuthenticationScheme, Options.AutomaticChallenge))
+ switch (context.Behavior)
{
- switch (context.Behavior)
- {
- case ChallengeBehavior.Automatic:
- // If there is a principal already, invoke the forbidden code path
- var result = await HandleAuthenticateOnceSafeAsync();
- if (result?.Ticket?.Principal != null)
- {
- goto case ChallengeBehavior.Forbidden;
- }
- goto case ChallengeBehavior.Unauthorized;
- case ChallengeBehavior.Unauthorized:
- handled = await HandleUnauthorizedAsync(context);
- Logger.AuthenticationSchemeChallenged(Options.AuthenticationScheme);
- break;
- case ChallengeBehavior.Forbidden:
- handled = await HandleForbiddenAsync(context);
- Logger.AuthenticationSchemeForbidden(Options.AuthenticationScheme);
- break;
- }
- context.Accept();
- }
-
- if (!handled && PriorHandler != null)
- {
- await PriorHandler.ChallengeAsync(context);
+ case ChallengeBehavior.Automatic:
+ // If there is a principal already, invoke the forbidden code path
+ var result = await HandleAuthenticateOnceSafeAsync();
+ if (result?.Principal != null)
+ {
+ goto case ChallengeBehavior.Forbidden;
+ }
+ goto case ChallengeBehavior.Unauthorized;
+ case ChallengeBehavior.Unauthorized:
+ await HandleUnauthorizedAsync(context);
+ Logger.AuthenticationSchemeChallenged(Scheme.Name);
+ break;
+ case ChallengeBehavior.Forbidden:
+ await HandleForbiddenAsync(context);
+ Logger.AuthenticationSchemeForbidden(Scheme.Name);
+ break;
}
}
-
- private void RegisterAuthenticationHandler()
- {
- var auth = Context.GetAuthentication();
- PriorHandler = auth.Handler;
- auth.Handler = this;
- }
-
- private void UnregisterAuthenticationHandler()
- {
- var auth = Context.GetAuthentication();
- auth.Handler = PriorHandler;
- }
}
}
diff --git a/src/Microsoft.AspNetCore.Authentication/AuthenticationMiddleware.cs b/src/Microsoft.AspNetCore.Authentication/AuthenticationMiddleware.cs
index a01490c3e..14102508e 100644
--- a/src/Microsoft.AspNetCore.Authentication/AuthenticationMiddleware.cs
+++ b/src/Microsoft.AspNetCore.Authentication/AuthenticationMiddleware.cs
@@ -2,90 +2,64 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
-using System.Text.Encodings.Web;
using System.Threading.Tasks;
-using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
-using Microsoft.Extensions.Logging;
-using Microsoft.Extensions.Options;
+using Microsoft.Extensions.DependencyInjection;
namespace Microsoft.AspNetCore.Authentication
{
- public abstract class AuthenticationMiddleware where TOptions : AuthenticationOptions, new()
+ public class AuthenticationMiddleware
{
private readonly RequestDelegate _next;
- protected AuthenticationMiddleware(
- RequestDelegate next,
- IOptions options,
- ILoggerFactory loggerFactory,
- UrlEncoder encoder)
+ public AuthenticationMiddleware(RequestDelegate next, IAuthenticationSchemeProvider schemes)
{
- if (next == null)
- {
- throw new ArgumentNullException(nameof(next));
- }
-
- if (options == null)
- {
- throw new ArgumentNullException(nameof(options));
- }
-
- if (loggerFactory == null)
- {
- throw new ArgumentNullException(nameof(loggerFactory));
- }
-
- if (encoder == null)
- {
- throw new ArgumentNullException(nameof(encoder));
- }
-
- Options = options.Value;
- Logger = loggerFactory.CreateLogger(this.GetType().FullName);
- UrlEncoder = encoder;
-
- if (string.IsNullOrEmpty(Options.ClaimsIssuer))
- {
- // Default to something reasonable
- Options.ClaimsIssuer = Options.AuthenticationScheme;
- }
-
- _next = next;
+ _next = next ?? throw new ArgumentNullException(nameof(next));
+ Schemes = schemes ?? throw new ArgumentNullException(nameof(schemes));
}
- public string AuthenticationScheme { get; set; }
-
- public TOptions Options { get; set; }
-
- public ILogger Logger { get; set; }
-
- public UrlEncoder UrlEncoder { get; set; }
+ public IAuthenticationSchemeProvider Schemes { get; set; }
public async Task Invoke(HttpContext context)
{
- var handler = CreateHandler();
- await handler.InitializeAsync(Options, context, Logger, UrlEncoder);
+ var oldFeature = context.Features.Get();
try
{
- if (!await handler.HandleRequestAsync())
+ context.Features.Set(new AuthenticationFeature
{
- await _next(context);
- }
- }
- finally
- {
- try
+ OriginalPath = context.Request.Path,
+ OriginalPathBase = context.Request.PathBase
+ });
+
+ var defaultAuthenticate = await Schemes.GetDefaultAuthenticateSchemeAsync();
+ if (defaultAuthenticate != null)
{
- await handler.TeardownAsync();
+ var result = await context.AuthenticateAsync(defaultAuthenticate.Name);
+ if (result?.Principal != null)
+ {
+ context.User = result.Principal;
+ }
}
- catch (Exception)
+
+ // REVIEW: alternatively could depend on a routing middleware to do this
+
+ // Give any IAuthenticationRequestHandler schemes a chance to handle the request
+ var handlers = context.RequestServices.GetRequiredService();
+ foreach (var scheme in await Schemes.GetRequestHandlerSchemesAsync())
{
- // Don't mask the original exception, if any
+ var handler = await handlers.GetHandlerAsync(context, scheme.Name) as IAuthenticationRequestHandler;
+ if (handler != null && await handler.HandleRequestAsync())
+ {
+ return;
+ }
}
+
+ await _next(context);
+ }
+ finally
+ {
+ context.Features.Set(oldFeature);
}
}
-
- protected abstract AuthenticationHandler CreateHandler();
}
}
\ No newline at end of file
diff --git a/src/Microsoft.AspNetCore.Authentication/AuthenticationOptions.cs b/src/Microsoft.AspNetCore.Authentication/AuthenticationOptions.cs
deleted file mode 100644
index 34ec577f1..000000000
--- a/src/Microsoft.AspNetCore.Authentication/AuthenticationOptions.cs
+++ /dev/null
@@ -1,59 +0,0 @@
-// 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 Microsoft.AspNetCore.Authentication;
-using Microsoft.AspNetCore.Http.Authentication;
-using System.ComponentModel;
-
-namespace Microsoft.AspNetCore.Builder
-{
- ///
- /// Base Options for all authentication middleware.
- ///
- public abstract class AuthenticationOptions
- {
- private string _authenticationScheme;
-
- ///
- /// The AuthenticationScheme in the options corresponds to the logical name for a particular authentication scheme. A different
- /// value may be assigned in order to use the same authentication middleware type more than once in a pipeline.
- ///
- public string AuthenticationScheme
- {
- get { return _authenticationScheme; }
- set
- {
- _authenticationScheme = value;
- Description.AuthenticationScheme = value;
- }
- }
-
- ///
- /// If true the authentication middleware alter the request user coming in. If false the authentication middleware will only provide
- /// identity when explicitly indicated by the AuthenticationScheme.
- ///
- public bool AutomaticAuthenticate { get; set; }
-
- ///
- /// If true the authentication middleware should handle automatic challenge.
- /// If false the authentication middleware will only alter responses when explicitly indicated by the AuthenticationScheme.
- ///
- public bool AutomaticChallenge { get; set; }
-
- ///
- /// Gets or sets the issuer that should be used for any claims that are created
- ///
- public string ClaimsIssuer { get; set; }
-
- ///
- /// Additional information about the authentication type which is made available to the application.
- ///
- public AuthenticationDescription Description { get; set; } = new AuthenticationDescription();
-
- ///
- /// For testing purposes only.
- ///
- [EditorBrowsable(EditorBrowsableState.Never)]
- public ISystemClock SystemClock { get; set; } = new SystemClock();
- }
-}
diff --git a/src/Microsoft.AspNetCore.Authentication/AuthenticationSchemeOptions.cs b/src/Microsoft.AspNetCore.Authentication/AuthenticationSchemeOptions.cs
new file mode 100644
index 000000000..98bccb666
--- /dev/null
+++ b/src/Microsoft.AspNetCore.Authentication/AuthenticationSchemeOptions.cs
@@ -0,0 +1,40 @@
+// 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
+{
+ ///
+ /// Contains the options used by the .
+ ///
+ public class AuthenticationSchemeOptions
+ {
+ ///
+ /// Check that the options are valid. Should throw an exception if things are not ok.
+ ///
+ public virtual void Validate()
+ {
+ }
+
+ ///
+ /// Gets or sets the display name for the authentication provider.
+ ///
+ public string DisplayName { get; set; }
+
+ ///
+ /// Gets or sets the issuer that should be used for any claims that are created
+ ///
+ public string ClaimsIssuer { get; set; }
+
+ ///
+ /// Instance used for events
+ ///
+ public object Events { get; set; }
+
+ ///
+ /// If set, will be used as the service type to get the Events instance instead of the property.
+ ///
+ public Type EventsType { get; set; }
+ }
+}
diff --git a/src/Microsoft.AspNetCore.Authentication/AuthenticationServiceCollectionExtensions.cs b/src/Microsoft.AspNetCore.Authentication/AuthenticationServiceCollectionExtensions.cs
index 2aa320ae2..074f45b5f 100644
--- a/src/Microsoft.AspNetCore.Authentication/AuthenticationServiceCollectionExtensions.cs
+++ b/src/Microsoft.AspNetCore.Authentication/AuthenticationServiceCollectionExtensions.cs
@@ -2,7 +2,11 @@
// 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 Microsoft.AspNetCore.Authentication;
+using Microsoft.AspNetCore.Http;
+using Microsoft.Extensions.DependencyInjection.Extensions;
+using Microsoft.Extensions.Options;
namespace Microsoft.Extensions.DependencyInjection
{
@@ -11,11 +15,6 @@ namespace Microsoft.Extensions.DependencyInjection
///
public static class AuthenticationServiceCollectionExtensions
{
- ///
- /// Adds authentication services to the specified .
- ///
- /// The to add services to.
- /// The so that additional calls can be chained.
public static IServiceCollection AddAuthentication(this IServiceCollection services)
{
if (services == null)
@@ -23,19 +22,14 @@ public static IServiceCollection AddAuthentication(this IServiceCollection servi
throw new ArgumentNullException(nameof(services));
}
- services.AddWebEncoders();
+ services.AddAuthenticationCore();
services.AddDataProtection();
+ services.AddWebEncoders();
+ services.TryAddSingleton();
return services;
}
- ///
- /// Adds authentication services to the specified .
- ///
- /// The to add services to.
- /// An action delegate to configure the provided .
- /// The so that additional calls can be chained.
- public static IServiceCollection AddAuthentication(this IServiceCollection services, Action configureOptions)
- {
+ public static IServiceCollection AddAuthentication(this IServiceCollection services, Action configureOptions) {
if (services == null)
{
throw new ArgumentNullException(nameof(services));
@@ -46,8 +40,33 @@ public static IServiceCollection AddAuthentication(this IServiceCollection servi
throw new ArgumentNullException(nameof(configureOptions));
}
+ services.AddAuthentication();
services.Configure(configureOptions);
- return services.AddAuthentication();
+ return services;
+ }
+
+ public static IServiceCollection AddScheme(this IServiceCollection services, string authenticationScheme, Action configureScheme, Action configureOptions)
+ where TOptions : AuthenticationSchemeOptions, new()
+ where THandler : AuthenticationHandler
+ {
+ services.AddAuthentication(o =>
+ {
+ o.AddScheme(authenticationScheme, scheme => {
+ scheme.HandlerType = typeof(THandler);
+ configureScheme?.Invoke(scheme);
+ });
+ });
+ if (configureOptions != null)
+ {
+ services.Configure(authenticationScheme, configureOptions);
+ }
+ services.AddTransient();
+ return services;
}
+
+ public static IServiceCollection AddScheme(this IServiceCollection services, string authenticationScheme, Action configureOptions)
+ where TOptions : AuthenticationSchemeOptions, new()
+ where THandler : AuthenticationHandler
+ => services.AddScheme(authenticationScheme, configureScheme: null, configureOptions: configureOptions);
}
}
diff --git a/src/Microsoft.AspNetCore.Authentication/AuthenticationTicket.cs b/src/Microsoft.AspNetCore.Authentication/AuthenticationTicket.cs
deleted file mode 100644
index 1d56a8fb3..000000000
--- a/src/Microsoft.AspNetCore.Authentication/AuthenticationTicket.cs
+++ /dev/null
@@ -1,47 +0,0 @@
-// 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.Security.Claims;
-using Microsoft.AspNetCore.Http.Authentication;
-
-namespace Microsoft.AspNetCore.Authentication
-{
- ///
- /// Contains user identity information as well as additional authentication state.
- ///
- public class AuthenticationTicket
- {
- ///
- /// Initializes a new instance of the class
- ///
- /// the that represents the authenticated user.
- /// additional properties that can be consumed by the user or runtime.
- /// the authentication middleware that was responsible for this ticket.
- public AuthenticationTicket(ClaimsPrincipal principal, AuthenticationProperties properties, string authenticationScheme)
- {
- if (principal == null)
- {
- throw new ArgumentNullException(nameof(principal));
- }
- AuthenticationScheme = authenticationScheme;
- Principal = principal;
- Properties = properties ?? new AuthenticationProperties();
- }
-
- ///
- /// Gets the authentication type.
- ///
- public string AuthenticationScheme { get; private set; }
-
- ///
- /// Gets the claims-principal with authenticated user identities.
- ///
- public ClaimsPrincipal Principal{ get; private set; }
-
- ///
- /// Additional state values for the authentication session.
- ///
- public AuthenticationProperties Properties { get; private set; }
- }
-}
diff --git a/src/Microsoft.AspNetCore.Authentication/AuthenticationToken.cs b/src/Microsoft.AspNetCore.Authentication/AuthenticationToken.cs
deleted file mode 100644
index 6503f0bb8..000000000
--- a/src/Microsoft.AspNetCore.Authentication/AuthenticationToken.cs
+++ /dev/null
@@ -1,12 +0,0 @@
-// 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.Authentication
-{
- public class AuthenticationToken
- {
- public string Name { get; set; }
- public string Value { get; set; }
- }
-}
\ No newline at end of file
diff --git a/src/Microsoft.AspNetCore.Authentication/ClaimsTransformationAppBuilderExtensions.cs b/src/Microsoft.AspNetCore.Authentication/ClaimsTransformationAppBuilderExtensions.cs
deleted file mode 100644
index 1edb4a0f4..000000000
--- a/src/Microsoft.AspNetCore.Authentication/ClaimsTransformationAppBuilderExtensions.cs
+++ /dev/null
@@ -1,75 +0,0 @@
-// 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.Security.Claims;
-using System.Threading.Tasks;
-using Microsoft.AspNetCore.Authentication;
-using Microsoft.Extensions.Options;
-
-namespace Microsoft.AspNetCore.Builder
-{
- ///
- /// Extension methods to add claims transformation capabilities to an HTTP application pipeline.
- ///
- public static class ClaimsTransformationAppBuilderExtensions
- {
- ///
- /// Adds the middleware to the specified , which enables claims transformation capabilities.
- ///
- /// The to add the middleware to.
- /// A reference to this instance after the operation has completed.
- public static IApplicationBuilder UseClaimsTransformation(this IApplicationBuilder app)
- {
- if (app == null)
- {
- throw new ArgumentNullException(nameof(app));
- }
-
- return app.UseMiddleware();
- }
-
- ///
- /// Adds the middleware to the specified , which enables claims transformation capabilities.
- ///
- /// The to add the middleware to.
- /// A function that asynchronously transforms one to another.
- /// A reference to this instance after the operation has completed.
- public static IApplicationBuilder UseClaimsTransformation(this IApplicationBuilder app, Func> transform)
- {
- if (app == null)
- {
- throw new ArgumentNullException(nameof(app));
- }
- if (transform == null)
- {
- throw new ArgumentNullException(nameof(transform));
- }
-
- return app.UseClaimsTransformation(new ClaimsTransformationOptions
- {
- Transformer = new ClaimsTransformer { OnTransform = transform }
- });
- }
-
- ///
- /// Adds the middleware to the specified , which enables claims transformation capabilities.
- ///
- /// The to add the middleware to.
- /// The to configure the middleware with.
- /// A reference to this instance after the operation has completed.
- public static IApplicationBuilder UseClaimsTransformation(this IApplicationBuilder app, ClaimsTransformationOptions options)
- {
- if (app == null)
- {
- throw new ArgumentNullException(nameof(app));
- }
- if (options == null)
- {
- throw new ArgumentNullException(nameof(options));
- }
-
- return app.UseMiddleware(Options.Create(options));
- }
- }
-}
diff --git a/src/Microsoft.AspNetCore.Authentication/ClaimsTransformationContext.cs b/src/Microsoft.AspNetCore.Authentication/ClaimsTransformationContext.cs
deleted file mode 100644
index 3c363ca98..000000000
--- a/src/Microsoft.AspNetCore.Authentication/ClaimsTransformationContext.cs
+++ /dev/null
@@ -1,15 +0,0 @@
-using Microsoft.AspNetCore.Http;
-using System.Security.Claims;
-
-namespace Microsoft.AspNetCore.Authentication
-{
- public class ClaimsTransformationContext
- {
- public ClaimsTransformationContext(HttpContext context)
- {
- Context = context;
- }
- public HttpContext Context { get; }
- public ClaimsPrincipal Principal { get; set; }
- }
-}
diff --git a/src/Microsoft.AspNetCore.Authentication/ClaimsTransformationHandler.cs b/src/Microsoft.AspNetCore.Authentication/ClaimsTransformationHandler.cs
deleted file mode 100644
index 27965dbf4..000000000
--- a/src/Microsoft.AspNetCore.Authentication/ClaimsTransformationHandler.cs
+++ /dev/null
@@ -1,92 +0,0 @@
-// 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.Threading.Tasks;
-using Microsoft.AspNetCore.Http;
-using Microsoft.AspNetCore.Http.Features.Authentication;
-using Microsoft.Extensions.Internal;
-
-namespace Microsoft.AspNetCore.Authentication
-{
- ///
- /// Handler that applies ClaimsTransformation to authentication
- ///
- public class ClaimsTransformationHandler : IAuthenticationHandler
- {
- private readonly IClaimsTransformer _transform;
- private readonly HttpContext _httpContext;
-
- public ClaimsTransformationHandler(IClaimsTransformer transform, HttpContext httpContext)
- {
- _transform = transform;
- _httpContext = httpContext;
- }
-
- public IAuthenticationHandler PriorHandler { get; set; }
-
- public async Task AuthenticateAsync(AuthenticateContext context)
- {
- if (PriorHandler != null)
- {
- await PriorHandler.AuthenticateAsync(context);
- if (_transform != null && context?.Principal != null)
- {
- var transformationContext = new ClaimsTransformationContext(_httpContext)
- {
- Principal = context.Principal
- };
- context.Authenticated(
- await _transform.TransformAsync(transformationContext),
- context.Properties,
- context.Description);
- }
- }
- }
-
- public Task ChallengeAsync(ChallengeContext context)
- {
- if (PriorHandler != null)
- {
- return PriorHandler.ChallengeAsync(context);
- }
- return TaskCache.CompletedTask;
- }
-
- public void GetDescriptions(DescribeSchemesContext context)
- {
- if (PriorHandler != null)
- {
- PriorHandler.GetDescriptions(context);
- }
- }
-
- public Task SignInAsync(SignInContext context)
- {
- if (PriorHandler != null)
- {
- return PriorHandler.SignInAsync(context);
- }
- return TaskCache.CompletedTask;
- }
-
- public Task SignOutAsync(SignOutContext context)
- {
- if (PriorHandler != null)
- {
- return PriorHandler.SignOutAsync(context);
- }
- return TaskCache.CompletedTask;
- }
-
- public void RegisterAuthenticationHandler(IHttpAuthenticationFeature auth)
- {
- PriorHandler = auth.Handler;
- auth.Handler = this;
- }
-
- public void UnregisterAuthenticationHandler(IHttpAuthenticationFeature auth)
- {
- auth.Handler = PriorHandler;
- }
- }
-}
diff --git a/src/Microsoft.AspNetCore.Authentication/ClaimsTransformationMiddleware.cs b/src/Microsoft.AspNetCore.Authentication/ClaimsTransformationMiddleware.cs
deleted file mode 100644
index 53f6a07a8..000000000
--- a/src/Microsoft.AspNetCore.Authentication/ClaimsTransformationMiddleware.cs
+++ /dev/null
@@ -1,58 +0,0 @@
-// 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.Threading.Tasks;
-using Microsoft.AspNetCore.Builder;
-using Microsoft.AspNetCore.Http;
-using Microsoft.Extensions.Options;
-
-namespace Microsoft.AspNetCore.Authentication
-{
- public class ClaimsTransformationMiddleware
- {
- private readonly RequestDelegate _next;
-
- public ClaimsTransformationMiddleware(
- RequestDelegate next,
- IOptions options)
- {
- if (next == null)
- {
- throw new ArgumentNullException(nameof(next));
- }
-
- if (options == null)
- {
- throw new ArgumentNullException(nameof(options));
- }
-
- Options = options.Value;
- _next = next;
- }
-
- public ClaimsTransformationOptions Options { get; set; }
-
- public async Task Invoke(HttpContext context)
- {
- var handler = new ClaimsTransformationHandler(Options.Transformer, context);
- handler.RegisterAuthenticationHandler(context.GetAuthentication());
- try
- {
- if (Options.Transformer != null)
- {
- var transformationContext = new ClaimsTransformationContext(context)
- {
- Principal = context.User
- };
- context.User = await Options.Transformer.TransformAsync(transformationContext);
- }
- await _next(context);
- }
- finally
- {
- handler.UnregisterAuthenticationHandler(context.GetAuthentication());
- }
- }
- }
-}
\ No newline at end of file
diff --git a/src/Microsoft.AspNetCore.Authentication/ClaimsTransformationOptions.cs b/src/Microsoft.AspNetCore.Authentication/ClaimsTransformationOptions.cs
deleted file mode 100644
index 70a76f27c..000000000
--- a/src/Microsoft.AspNetCore.Authentication/ClaimsTransformationOptions.cs
+++ /dev/null
@@ -1,18 +0,0 @@
-// 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 Microsoft.AspNetCore.Authentication;
-
-namespace Microsoft.AspNetCore.Builder
-{
- ///
- /// Contains the options used by the .
- ///
- public class ClaimsTransformationOptions
- {
- ///
- /// Responsible for transforming the claims principal.
- ///
- public IClaimsTransformer Transformer { get; set; }
- }
-}
diff --git a/src/Microsoft.AspNetCore.Authentication/ClaimsTransformer.cs b/src/Microsoft.AspNetCore.Authentication/ClaimsTransformer.cs
deleted file mode 100644
index db05db0e5..000000000
--- a/src/Microsoft.AspNetCore.Authentication/ClaimsTransformer.cs
+++ /dev/null
@@ -1,19 +0,0 @@
-// 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.Security.Claims;
-using System.Threading.Tasks;
-
-namespace Microsoft.AspNetCore.Authentication
-{
- public class ClaimsTransformer : IClaimsTransformer
- {
- public Func> OnTransform { get; set; }
-
- public virtual Task TransformAsync(ClaimsTransformationContext context)
- {
- return OnTransform?.Invoke(context) ?? Task.FromResult(context.Principal);
- }
- }
-}
diff --git a/src/Microsoft.AspNetCore.Authentication/DataHandler/IDataSerializer.cs b/src/Microsoft.AspNetCore.Authentication/Data/IDataSerializer.cs
similarity index 100%
rename from src/Microsoft.AspNetCore.Authentication/DataHandler/IDataSerializer.cs
rename to src/Microsoft.AspNetCore.Authentication/Data/IDataSerializer.cs
diff --git a/src/Microsoft.AspNetCore.Authentication/DataHandler/ISecureDataFormat.cs b/src/Microsoft.AspNetCore.Authentication/Data/ISecureDataFormat.cs
similarity index 100%
rename from src/Microsoft.AspNetCore.Authentication/DataHandler/ISecureDataFormat.cs
rename to src/Microsoft.AspNetCore.Authentication/Data/ISecureDataFormat.cs
diff --git a/src/Microsoft.AspNetCore.Authentication/DataHandler/PropertiesDataFormat.cs b/src/Microsoft.AspNetCore.Authentication/Data/PropertiesDataFormat.cs
similarity index 100%
rename from src/Microsoft.AspNetCore.Authentication/DataHandler/PropertiesDataFormat.cs
rename to src/Microsoft.AspNetCore.Authentication/Data/PropertiesDataFormat.cs
diff --git a/src/Microsoft.AspNetCore.Authentication/DataHandler/PropertiesSerializer.cs b/src/Microsoft.AspNetCore.Authentication/Data/PropertiesSerializer.cs
similarity index 100%
rename from src/Microsoft.AspNetCore.Authentication/DataHandler/PropertiesSerializer.cs
rename to src/Microsoft.AspNetCore.Authentication/Data/PropertiesSerializer.cs
diff --git a/src/Microsoft.AspNetCore.Authentication/DataHandler/SecureDataFormat.cs b/src/Microsoft.AspNetCore.Authentication/Data/SecureDataFormat.cs
similarity index 100%
rename from src/Microsoft.AspNetCore.Authentication/DataHandler/SecureDataFormat.cs
rename to src/Microsoft.AspNetCore.Authentication/Data/SecureDataFormat.cs
diff --git a/src/Microsoft.AspNetCore.Authentication/DataHandler/TextEncoder.cs b/src/Microsoft.AspNetCore.Authentication/Data/TextEncoder.cs
similarity index 100%
rename from src/Microsoft.AspNetCore.Authentication/DataHandler/TextEncoder.cs
rename to src/Microsoft.AspNetCore.Authentication/Data/TextEncoder.cs
diff --git a/src/Microsoft.AspNetCore.Authentication/DataHandler/TicketDataFormat.cs b/src/Microsoft.AspNetCore.Authentication/Data/TicketDataFormat.cs
similarity index 100%
rename from src/Microsoft.AspNetCore.Authentication/DataHandler/TicketDataFormat.cs
rename to src/Microsoft.AspNetCore.Authentication/Data/TicketDataFormat.cs
diff --git a/src/Microsoft.AspNetCore.Authentication/DataHandler/TicketSerializer.cs b/src/Microsoft.AspNetCore.Authentication/Data/TicketSerializer.cs
similarity index 100%
rename from src/Microsoft.AspNetCore.Authentication/DataHandler/TicketSerializer.cs
rename to src/Microsoft.AspNetCore.Authentication/Data/TicketSerializer.cs
diff --git a/src/Microsoft.AspNetCore.Authentication/Events/BaseContext.cs b/src/Microsoft.AspNetCore.Authentication/Events/BaseContext.cs
deleted file mode 100644
index 10b3325d4..000000000
--- a/src/Microsoft.AspNetCore.Authentication/Events/BaseContext.cs
+++ /dev/null
@@ -1,27 +0,0 @@
-// 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 Microsoft.AspNetCore.Http;
-
-namespace Microsoft.AspNetCore.Authentication
-{
- public abstract class BaseContext
- {
- protected BaseContext(HttpContext context)
- {
- HttpContext = context;
- }
-
- public HttpContext HttpContext { get; private set; }
-
- public HttpRequest Request
- {
- get { return HttpContext.Request; }
- }
-
- public HttpResponse Response
- {
- get { return HttpContext.Response; }
- }
- }
-}
diff --git a/src/Microsoft.AspNetCore.Authentication/Events/BaseControlContext.cs b/src/Microsoft.AspNetCore.Authentication/Events/BaseControlContext.cs
index 4039a0560..5886fca6d 100644
--- a/src/Microsoft.AspNetCore.Authentication/Events/BaseControlContext.cs
+++ b/src/Microsoft.AspNetCore.Authentication/Events/BaseControlContext.cs
@@ -34,10 +34,10 @@ public void HandleResponse()
}
///
- /// Discontinue processing the request in the current middleware and pass control to the next one.
+ /// Discontinue processing the request in the current handler.
/// SignIn will not be called.
///
- public void SkipToNextMiddleware()
+ public void Skip()
{
State = EventResultState.Skipped;
}
@@ -47,7 +47,12 @@ public void SkipToNextMiddleware()
///
public AuthenticationTicket Ticket { get; set; }
- public bool CheckEventResult(out AuthenticateResult result)
+ ///
+ /// Returns true if the handler should be done processing.
+ ///
+ /// The result.
+ /// Whether the handler should be done processing.
+ public bool ProcessingCompleted(out AuthenticateResult result)
{
if (HandledResponse)
{
@@ -63,7 +68,7 @@ public bool CheckEventResult(out AuthenticateResult result)
}
else if (Skipped)
{
- result = AuthenticateResult.Skip();
+ result = AuthenticateResult.None();
return true;
}
result = null;
diff --git a/src/Microsoft.AspNetCore.Authentication/Events/EventResultState.cs b/src/Microsoft.AspNetCore.Authentication/Events/EventResultState.cs
index b11dec93f..dad4c40fe 100644
--- a/src/Microsoft.AspNetCore.Authentication/Events/EventResultState.cs
+++ b/src/Microsoft.AspNetCore.Authentication/Events/EventResultState.cs
@@ -11,7 +11,7 @@ public enum EventResultState
Continue,
///
- /// Discontinue processing the request in the current middleware and pass control to the next one.
+ /// Discontinue processing the request.
///
Skipped,
diff --git a/src/Microsoft.AspNetCore.Authentication/Events/IRemoteAuthenticationEvents.cs b/src/Microsoft.AspNetCore.Authentication/Events/IRemoteAuthenticationEvents.cs
deleted file mode 100644
index e2109a065..000000000
--- a/src/Microsoft.AspNetCore.Authentication/Events/IRemoteAuthenticationEvents.cs
+++ /dev/null
@@ -1,20 +0,0 @@
-// 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.Threading.Tasks;
-
-namespace Microsoft.AspNetCore.Authentication
-{
- public interface IRemoteAuthenticationEvents
- {
- ///
- /// Invoked when the remote authentication process has an error.
- ///
- Task RemoteFailure(FailureContext context);
-
- ///
- /// Invoked before sign in.
- ///
- Task TicketReceived(TicketReceivedContext context);
- }
-}
\ No newline at end of file
diff --git a/src/Microsoft.AspNetCore.Authentication/Events/RemoteAuthenticationEvents.cs b/src/Microsoft.AspNetCore.Authentication/Events/RemoteAuthenticationEvents.cs
index 6e7d6a35c..a130c1b14 100644
--- a/src/Microsoft.AspNetCore.Authentication/Events/RemoteAuthenticationEvents.cs
+++ b/src/Microsoft.AspNetCore.Authentication/Events/RemoteAuthenticationEvents.cs
@@ -7,7 +7,7 @@
namespace Microsoft.AspNetCore.Authentication
{
- public class RemoteAuthenticationEvents : IRemoteAuthenticationEvents
+ public class RemoteAuthenticationEvents
{
public Func OnRemoteFailure { get; set; } = context => TaskCache.CompletedTask;
diff --git a/src/Microsoft.AspNetCore.Authentication/Events/TicketReceivedContext.cs b/src/Microsoft.AspNetCore.Authentication/Events/TicketReceivedContext.cs
index 5d5fd4883..00de27578 100644
--- a/src/Microsoft.AspNetCore.Authentication/Events/TicketReceivedContext.cs
+++ b/src/Microsoft.AspNetCore.Authentication/Events/TicketReceivedContext.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.Builder;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.Authentication;
diff --git a/src/Microsoft.AspNetCore.Authentication/HttpContextExtensions.cs b/src/Microsoft.AspNetCore.Authentication/HttpContextExtensions.cs
deleted file mode 100644
index 0d245cf0a..000000000
--- a/src/Microsoft.AspNetCore.Authentication/HttpContextExtensions.cs
+++ /dev/null
@@ -1,22 +0,0 @@
-// 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 Microsoft.AspNetCore.Http;
-using Microsoft.AspNetCore.Http.Features.Authentication;
-
-namespace Microsoft.AspNetCore.Authentication
-{
- internal static class HttpContextExtensions
- {
- internal static IHttpAuthenticationFeature GetAuthentication(this HttpContext context)
- {
- var auth = context.Features.Get();
- if (auth == null)
- {
- auth = new HttpAuthenticationFeature();
- context.Features.Set(auth);
- }
- return auth;
- }
- }
-}
diff --git a/src/Microsoft.AspNetCore.Authentication/IClaimsTransformer.cs b/src/Microsoft.AspNetCore.Authentication/IClaimsTransformer.cs
deleted file mode 100644
index cd42915c0..000000000
--- a/src/Microsoft.AspNetCore.Authentication/IClaimsTransformer.cs
+++ /dev/null
@@ -1,21 +0,0 @@
-// 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.Security.Claims;
-using System.Threading.Tasks;
-
-namespace Microsoft.AspNetCore.Authentication
-{
- ///
- /// Used for claims transformation.
- ///
- public interface IClaimsTransformer
- {
- ///
- /// Provides a central transformation point to change the specified principal.
- ///
- /// containing principal to transform and current HttpContext.
- /// The transformed principal.
- Task TransformAsync(ClaimsTransformationContext context);
- }
-}
diff --git a/src/Microsoft.AspNetCore.Authentication/Microsoft.AspNetCore.Authentication.csproj b/src/Microsoft.AspNetCore.Authentication/Microsoft.AspNetCore.Authentication.csproj
index 316defc43..794f04c50 100644
--- a/src/Microsoft.AspNetCore.Authentication/Microsoft.AspNetCore.Authentication.csproj
+++ b/src/Microsoft.AspNetCore.Authentication/Microsoft.AspNetCore.Authentication.csproj
@@ -11,11 +11,13 @@
+
+
+
+
+
-
-
-
diff --git a/src/Microsoft.AspNetCore.Authentication/Properties/Resources.Designer.cs b/src/Microsoft.AspNetCore.Authentication/Properties/Resources.Designer.cs
index a6cf91046..11e2e4586 100644
--- a/src/Microsoft.AspNetCore.Authentication/Properties/Resources.Designer.cs
+++ b/src/Microsoft.AspNetCore.Authentication/Properties/Resources.Designer.cs
@@ -1,6 +1,7 @@
//
namespace Microsoft.AspNetCore.Authentication
{
+ using System.Globalization;
using System.Reflection;
using System.Resources;
@@ -57,6 +58,22 @@ internal static string FormatException_AuthenticationTokenDoesNotProvideSyncMeth
return GetString("Exception_AuthenticationTokenDoesNotProvideSyncMethods");
}
+ ///
+ /// The '{0}' option must be provided.
+ ///
+ internal static string Exception_OptionMustBeProvided
+ {
+ get { return GetString("Exception_OptionMustBeProvided"); }
+ }
+
+ ///
+ /// The '{0}' option must be provided.
+ ///
+ internal static string FormatException_OptionMustBeProvided(object p0)
+ {
+ return string.Format(CultureInfo.CurrentCulture, GetString("Exception_OptionMustBeProvided"), p0);
+ }
+
private static string GetString(string name, params string[] formatterNames)
{
var value = _resourceManager.GetString(name);
diff --git a/src/Microsoft.AspNetCore.Authentication/RemoteAuthenticationHandler.cs b/src/Microsoft.AspNetCore.Authentication/RemoteAuthenticationHandler.cs
index 1e41fb0b5..7f41cc381 100644
--- a/src/Microsoft.AspNetCore.Authentication/RemoteAuthenticationHandler.cs
+++ b/src/Microsoft.AspNetCore.Authentication/RemoteAuthenticationHandler.cs
@@ -3,16 +3,16 @@
using System;
using System.Security.Cryptography;
+using System.Text.Encodings.Web;
using System.Threading.Tasks;
-using Microsoft.AspNetCore.Builder;
+using Microsoft.AspNetCore.DataProtection;
using Microsoft.AspNetCore.Http;
-using Microsoft.AspNetCore.Http.Features.Authentication;
-using Microsoft.AspNetCore.Http.Authentication;
using Microsoft.Extensions.Logging;
+using Microsoft.Extensions.Options;
namespace Microsoft.AspNetCore.Authentication
{
- public abstract class RemoteAuthenticationHandler : AuthenticationHandler where TOptions : RemoteAuthenticationOptions
+ public abstract class RemoteAuthenticationHandler : AuthenticationHandler, IAuthenticationRequestHandler where TOptions : RemoteAuthenticationOptions, new()
{
private const string CorrelationPrefix = ".AspNetCore.Correlation.";
private const string CorrelationProperty = ".xsrf";
@@ -21,23 +21,52 @@ public abstract class RemoteAuthenticationHandler : AuthenticationHand
private static readonly RandomNumberGenerator CryptoRandom = RandomNumberGenerator.Create();
- public override async Task HandleRequestAsync()
+ protected string SignInScheme { get; set; }
+
+ protected IDataProtectionProvider DataProtection { get; set; }
+
+ private readonly AuthenticationOptions _sharedOptions;
+
+ protected RemoteAuthenticationHandler(IOptions sharedOptions, IOptionsSnapshot options, IDataProtectionProvider dataProtection, ILoggerFactory logger, UrlEncoder encoder, ISystemClock clock)
+ : base(options, logger, encoder, clock)
+ {
+ _sharedOptions = sharedOptions.Value;
+ DataProtection = dataProtection;
+ }
+
+ public override async Task InitializeAsync(AuthenticationScheme scheme, HttpContext context)
{
- if (Options.CallbackPath == Request.Path)
+ await base.InitializeAsync(scheme, context);
+ Events = Events ?? new RemoteAuthenticationEvents();
+ DataProtection = Options.DataProtectionProvider ?? DataProtection;
+
+ // TODO: this needs to be done once (but we don't have access to scheme data in ext method)
+ SignInScheme = Options.SignInScheme ?? _sharedOptions.DefaultSignInScheme;
+
+ if (string.IsNullOrEmpty(SignInScheme))
{
- return await HandleRemoteCallbackAsync();
+ throw new ArgumentException(Resources.FormatException_OptionMustBeProvided(nameof(Options.SignInScheme)), nameof(Options.SignInScheme));
}
+ }
- return false;
+ public virtual Task ShouldHandleRequestAsync()
+ {
+ return Task.FromResult(Options.CallbackPath == Request.Path);
}
- protected virtual async Task HandleRemoteCallbackAsync()
+ public virtual async Task HandleRequestAsync()
{
+ if (!await ShouldHandleRequestAsync())
+ {
+ return false;
+ }
+
AuthenticationTicket ticket = null;
Exception exception = null;
try
{
+
var authResult = await HandleRemoteAuthenticateAsync();
if (authResult == null)
{
@@ -47,7 +76,7 @@ protected virtual async Task HandleRemoteCallbackAsync()
{
return true;
}
- else if (authResult.Skipped)
+ else if (authResult.Nothing)
{
return false;
}
@@ -74,8 +103,7 @@ protected virtual async Task HandleRemoteCallbackAsync()
{
return true;
}
-
- if (errorContext.Skipped)
+ else if (errorContext.Skipped)
{
return false;
}
@@ -84,7 +112,7 @@ protected virtual async Task HandleRemoteCallbackAsync()
}
// We have a ticket if we get here
- var context = new TicketReceivedContext(Context, Options, ticket)
+ var ticketContext = new TicketReceivedContext(Context, Options, ticket)
{
ReturnUri = ticket.Properties.RedirectUri,
};
@@ -92,30 +120,30 @@ protected virtual async Task HandleRemoteCallbackAsync()
ticket.Properties.RedirectUri = null;
// Mark which provider produced this identity so we can cross-check later in HandleAuthenticateAsync
- context.Properties.Items[AuthSchemeKey] = Options.AuthenticationScheme;
+ ticketContext.Properties.Items[AuthSchemeKey] = Scheme.Name;
- await Options.Events.TicketReceived(context);
+ await Options.Events.TicketReceived(ticketContext);
- if (context.HandledResponse)
+ if (ticketContext.HandledResponse)
{
Logger.SigninHandled();
return true;
}
- else if (context.Skipped)
+ else if (ticketContext.Skipped)
{
Logger.SigninSkipped();
return false;
- }
+ };
- await Context.Authentication.SignInAsync(Options.SignInScheme, context.Principal, context.Properties);
+ await Context.SignInAsync(SignInScheme, ticketContext.Principal, ticketContext.Properties);
// Default redirect path is the base path
- if (string.IsNullOrEmpty(context.ReturnUri))
+ if (string.IsNullOrEmpty(ticketContext.ReturnUri))
{
- context.ReturnUri = "/";
+ ticketContext.ReturnUri = "/";
}
- Response.Redirect(context.ReturnUri);
+ Response.Redirect(ticketContext.ReturnUri);
return true;
}
@@ -128,51 +156,48 @@ protected virtual async Task HandleRemoteCallbackAsync()
protected override async Task HandleAuthenticateAsync()
{
- // Most RemoteAuthenticationHandlers will have a PriorHandler, but it might not be set up during unit tests.
- if (PriorHandler != null)
+ var result = await Context.AuthenticateAsync(SignInScheme);
+ if (result != null)
{
- var authenticateContext = new AuthenticateContext(Options.SignInScheme);
- await PriorHandler.AuthenticateAsync(authenticateContext);
- if (authenticateContext.Accepted)
+ // todo error
+ if (result.Failure != null)
+ {
+ return AuthenticateResult.Fail(result.Failure);
+ }
+
+ // The SignInScheme may be shared with multiple providers, make sure this provider issued the identity.
+ string authenticatedScheme;
+ var ticket = result.Ticket;
+ if (ticket != null && ticket.Principal != null && ticket.Properties != null
+ && ticket.Properties.Items.TryGetValue(AuthSchemeKey, out authenticatedScheme)
+ && string.Equals(Scheme.Name, authenticatedScheme, StringComparison.Ordinal))
{
- if (authenticateContext.Error != null)
- {
- return AuthenticateResult.Fail(authenticateContext.Error);
- }
-
- // The SignInScheme may be shared with multiple providers, make sure this middleware issued the identity.
- string authenticatedScheme;
- if (authenticateContext.Principal != null && authenticateContext.Properties != null
- && authenticateContext.Properties.TryGetValue(AuthSchemeKey, out authenticatedScheme)
- && string.Equals(Options.AuthenticationScheme, authenticatedScheme, StringComparison.Ordinal))
- {
- return AuthenticateResult.Success(new AuthenticationTicket(authenticateContext.Principal,
- new AuthenticationProperties(authenticateContext.Properties), Options.AuthenticationScheme));
- }
-
- return AuthenticateResult.Fail("Not authenticated");
+ return AuthenticateResult.Success(new AuthenticationTicket(ticket.Principal,
+ ticket.Properties, Scheme.Name));
}
+ return AuthenticateResult.Fail("Not authenticated");
}
return AuthenticateResult.Fail("Remote authentication does not directly support authenticate");
}
+ // REVIEW: should this forward to sign in scheme as well?
protected override Task HandleSignOutAsync(SignOutContext context)
{
throw new NotSupportedException();
}
+ // REVIEW: should this forward to sign in scheme as well?
protected override Task HandleSignInAsync(SignInContext context)
{
throw new NotSupportedException();
}
- protected override async Task HandleForbiddenAsync(ChallengeContext context)
+ // REVIEW: This behaviour needs a test (forwarding of forbidden to sign in scheme)
+ protected override Task HandleForbiddenAsync(ChallengeContext context)
{
- var challengeContext = new ChallengeContext(Options.SignInScheme, context.Properties, ChallengeBehavior.Forbidden);
- await PriorHandler.ChallengeAsync(challengeContext);
- return challengeContext.Accepted;
+ return Context.ForbidAsync(SignInScheme);
}
protected virtual void GenerateCorrelationId(AuthenticationProperties properties)
@@ -190,12 +215,12 @@ protected virtual void GenerateCorrelationId(AuthenticationProperties properties
{
HttpOnly = true,
Secure = Request.IsHttps,
- Expires = Options.SystemClock.UtcNow.Add(Options.RemoteAuthenticationTimeout),
+ Expires = Clock.UtcNow.Add(Options.RemoteAuthenticationTimeout),
};
properties.Items[CorrelationProperty] = correlationId;
- var cookieName = CorrelationPrefix + Options.AuthenticationScheme + "." + correlationId;
+ var cookieName = CorrelationPrefix + Scheme.Name + "." + correlationId;
Response.Cookies.Append(cookieName, CorrelationMarker, cookieOptions);
}
@@ -216,7 +241,7 @@ protected virtual bool ValidateCorrelationId(AuthenticationProperties properties
properties.Items.Remove(CorrelationProperty);
- var cookieName = CorrelationPrefix + Options.AuthenticationScheme + "." + correlationId;
+ var cookieName = CorrelationPrefix + Scheme.Name + "." + correlationId;
var correlationCookie = Request.Cookies[cookieName];
if (string.IsNullOrEmpty(correlationCookie))
diff --git a/src/Microsoft.AspNetCore.Authentication/RemoteAuthenticationOptions.cs b/src/Microsoft.AspNetCore.Authentication/RemoteAuthenticationOptions.cs
index e990abd05..28f91a22c 100644
--- a/src/Microsoft.AspNetCore.Authentication/RemoteAuthenticationOptions.cs
+++ b/src/Microsoft.AspNetCore.Authentication/RemoteAuthenticationOptions.cs
@@ -3,16 +3,29 @@
using System;
using System.Net.Http;
+using Microsoft.AspNetCore.DataProtection;
using Microsoft.AspNetCore.Http;
-using Microsoft.AspNetCore.Authentication;
+using Microsoft.Extensions.Options;
-namespace Microsoft.AspNetCore.Builder
+namespace Microsoft.AspNetCore.Authentication
{
///
/// Contains the options used by the .
///
- public class RemoteAuthenticationOptions : AuthenticationOptions
+ public class RemoteAuthenticationOptions : AuthenticationSchemeOptions
{
+ ///
+ /// Check that the options are valid. Should throw an exception if things are not ok.
+ ///
+ public override void Validate()
+ {
+ base.Validate();
+ if (CallbackPath == null || !CallbackPath.HasValue)
+ {
+ throw new ArgumentException(Resources.FormatException_OptionMustBeProvided(nameof(CallbackPath)), nameof(CallbackPath));
+ }
+ }
+
///
/// Gets or sets timeout value in milliseconds for back channel communications with the remote identity provider.
///
@@ -28,6 +41,11 @@ public class RemoteAuthenticationOptions : AuthenticationOptions
///
public HttpMessageHandler BackchannelHttpHandler { get; set; }
+ ///
+ /// Gets or sets the type used to secure data.
+ ///
+ public IDataProtectionProvider DataProtectionProvider { get; internal set; }
+
///
/// The request path within the application's base path where the user-agent will be returned.
/// The middleware will process this request when it arrives.
@@ -38,25 +56,20 @@ public class RemoteAuthenticationOptions : AuthenticationOptions
/// Gets or sets the authentication scheme corresponding to the middleware
/// responsible of persisting user's identity after a successful authentication.
/// This value typically corresponds to a cookie middleware registered in the Startup class.
- /// When omitted, is used as a fallback value.
+ /// When omitted, is used as a fallback value.
///
public string SignInScheme { get; set; }
- ///
- /// Get or sets the text that the user can display on a sign in user interface.
- ///
- public string DisplayName
- {
- get { return Description.DisplayName; }
- set { Description.DisplayName = value; }
- }
-
///
/// Gets or sets the time limit for completing the authentication flow (15 minutes by default).
///
public TimeSpan RemoteAuthenticationTimeout { get; set; } = TimeSpan.FromMinutes(15);
- public IRemoteAuthenticationEvents Events = new RemoteAuthenticationEvents();
+ public new RemoteAuthenticationEvents Events
+ {
+ get { return (RemoteAuthenticationEvents)base.Events; }
+ set { base.Events = value; }
+ }
///
/// Defines whether access and refresh tokens should be stored in the
diff --git a/src/Microsoft.AspNetCore.Authentication/Resources.resx b/src/Microsoft.AspNetCore.Authentication/Resources.resx
index 77060045e..54d22bcc9 100644
--- a/src/Microsoft.AspNetCore.Authentication/Resources.resx
+++ b/src/Microsoft.AspNetCore.Authentication/Resources.resx
@@ -126,4 +126,7 @@
The AuthenticationTokenProvider's required synchronous events have not been registered.
+
+ The '{0}' option must be provided.
+
\ No newline at end of file
diff --git a/src/Microsoft.AspNetCore.Authentication/SharedAuthenticationOptions.cs b/src/Microsoft.AspNetCore.Authentication/SharedAuthenticationOptions.cs
deleted file mode 100644
index 8b168c9a0..000000000
--- a/src/Microsoft.AspNetCore.Authentication/SharedAuthenticationOptions.cs
+++ /dev/null
@@ -1,15 +0,0 @@
-// 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.Authentication
-{
- public class SharedAuthenticationOptions
- {
- ///
- /// Gets or sets the authentication scheme corresponding to the default middleware
- /// responsible of persisting user's identity after a successful authentication.
- /// This value typically corresponds to a cookie middleware registered in the Startup class.
- ///
- public string SignInScheme { get; set; }
- }
-}
diff --git a/src/Microsoft.AspNetCore.Authentication/SystemClock.cs b/src/Microsoft.AspNetCore.Authentication/SystemClock.cs
index e1c79192a..2320982ce 100644
--- a/src/Microsoft.AspNetCore.Authentication/SystemClock.cs
+++ b/src/Microsoft.AspNetCore.Authentication/SystemClock.cs
@@ -1,7 +1,6 @@
// 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
diff --git a/src/Microsoft.AspNetCore.Authentication/TokenExtensions.cs b/src/Microsoft.AspNetCore.Authentication/TokenExtensions.cs
deleted file mode 100644
index 9f5c96cc1..000000000
--- a/src/Microsoft.AspNetCore.Authentication/TokenExtensions.cs
+++ /dev/null
@@ -1,135 +0,0 @@
-// 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.Threading.Tasks;
-using Microsoft.AspNetCore.Http.Authentication;
-using Microsoft.AspNetCore.Http.Features.Authentication;
-
-namespace Microsoft.AspNetCore.Authentication
-{
- public static class AuthenticationTokenExtensions
- {
- private static string TokenNamesKey = ".TokenNames";
- private static string TokenKeyPrefix = ".Token.";
-
- public static void StoreTokens(this AuthenticationProperties properties, IEnumerable tokens)
- {
- if (properties == null)
- {
- throw new ArgumentNullException(nameof(properties));
- }
- if (tokens == null)
- {
- throw new ArgumentNullException(nameof(tokens));
- }
-
- // Clear old tokens first
- var oldTokens = properties.GetTokens();
- foreach (var t in oldTokens)
- {
- properties.Items.Remove(TokenKeyPrefix + t.Name);
- }
- properties.Items.Remove(TokenNamesKey);
-
- var tokenNames = new List();
- foreach (var token in tokens)
- {
- // REVIEW: should probably check that there are no ; in the token name and throw or encode
- tokenNames.Add(token.Name);
- properties.Items[TokenKeyPrefix+token.Name] = token.Value;
- }
- if (tokenNames.Count > 0)
- {
- properties.Items[TokenNamesKey] = string.Join(";", tokenNames.ToArray());
- }
- }
-
- public static string GetTokenValue(this AuthenticationProperties properties, string tokenName)
- {
- if (properties == null)
- {
- throw new ArgumentNullException(nameof(properties));
- }
- if (tokenName == null)
- {
- throw new ArgumentNullException(nameof(tokenName));
- }
-
- var tokenKey = TokenKeyPrefix + tokenName;
- return properties.Items.ContainsKey(tokenKey)
- ? properties.Items[tokenKey]
- : null;
- }
-
- public static bool UpdateTokenValue(this AuthenticationProperties properties, string tokenName, string tokenValue)
- {
- if (properties == null)
- {
- throw new ArgumentNullException(nameof(properties));
- }
- if (tokenName == null)
- {
- throw new ArgumentNullException(nameof(tokenName));
- }
-
- var tokenKey = TokenKeyPrefix + tokenName;
- if (!properties.Items.ContainsKey(tokenKey))
- {
- return false;
- }
- properties.Items[tokenKey] = tokenValue;
- return true;
- }
-
- public static IEnumerable GetTokens(this AuthenticationProperties properties)
- {
- if (properties == null)
- {
- throw new ArgumentNullException(nameof(properties));
- }
-
- var tokens = new List();
- if (properties.Items.ContainsKey(TokenNamesKey))
- {
- var tokenNames = properties.Items[TokenNamesKey].Split(';');
- foreach (var name in tokenNames)
- {
- var token = properties.GetTokenValue(name);
- if (token != null)
- {
- tokens.Add(new AuthenticationToken { Name = name, Value = token });
- }
- }
- }
-
- return tokens;
- }
-
- public static Task GetTokenAsync(this AuthenticationManager manager, string tokenName)
- {
- return manager.GetTokenAsync(AuthenticationManager.AutomaticScheme, tokenName);
- }
-
- public static async Task GetTokenAsync(this AuthenticationManager manager, string signInScheme, string tokenName)
- {
- if (manager == null)
- {
- throw new ArgumentNullException(nameof(manager));
- }
- if (signInScheme == null)
- {
- throw new ArgumentNullException(nameof(signInScheme));
- }
- if (tokenName == null)
- {
- throw new ArgumentNullException(nameof(tokenName));
- }
-
- var authContext = new AuthenticateContext(signInScheme);
- await manager.AuthenticateAsync(authContext);
- return new AuthenticationProperties(authContext.Properties).GetTokenValue(tokenName);
- }
- }
-}
\ No newline at end of file
diff --git a/src/Microsoft.AspNetCore.Authentication/baseline.net45.json b/src/Microsoft.AspNetCore.Authentication/baseline.net45.json
index 1f69da5a8..939cf588b 100644
--- a/src/Microsoft.AspNetCore.Authentication/baseline.net45.json
+++ b/src/Microsoft.AspNetCore.Authentication/baseline.net45.json
@@ -2474,7 +2474,7 @@
},
{
"Kind": "Method",
- "Name": "SkipToNextMiddleware",
+ "Name": "StopProcessing",
"Parameters": [],
"ReturnType": "System.Void",
"Visibility": "Public",
diff --git a/src/Microsoft.AspNetCore.Authentication/baseline.netcore.json b/src/Microsoft.AspNetCore.Authentication/baseline.netcore.json
index 1f69da5a8..939cf588b 100644
--- a/src/Microsoft.AspNetCore.Authentication/baseline.netcore.json
+++ b/src/Microsoft.AspNetCore.Authentication/baseline.netcore.json
@@ -2474,7 +2474,7 @@
},
{
"Kind": "Method",
- "Name": "SkipToNextMiddleware",
+ "Name": "StopProcessing",
"Parameters": [],
"ReturnType": "System.Void",
"Visibility": "Public",
diff --git a/test/Microsoft.AspNetCore.Authentication.Test/AuthenticationHandlerFacts.cs b/test/Microsoft.AspNetCore.Authentication.Test/AuthenticationHandlerFacts.cs
deleted file mode 100644
index fade43716..000000000
--- a/test/Microsoft.AspNetCore.Authentication.Test/AuthenticationHandlerFacts.cs
+++ /dev/null
@@ -1,282 +0,0 @@
-// 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.IO;
-using System.Security.Claims;
-using System.Text.Encodings.Web;
-using System.Threading.Tasks;
-using Microsoft.AspNetCore.Builder;
-using Microsoft.AspNetCore.Http;
-using Microsoft.AspNetCore.Http.Authentication;
-using Microsoft.AspNetCore.Http.Features;
-using Microsoft.AspNetCore.Http.Features.Authentication;
-using Microsoft.Extensions.Logging;
-using Xunit;
-
-namespace Microsoft.AspNetCore.Authentication
-{
- public class AuthenticationHandlerFacts
- {
- [Fact]
- public async Task ShouldHandleSchemeAreDeterminedOnlyByMatchingAuthenticationScheme()
- {
- var handler = await TestHandler.Create("Alpha");
- var passiveNoMatch = handler.ShouldHandleScheme("Beta", handleAutomatic: false);
-
- handler = await TestHandler.Create("Alpha");
- var passiveWithMatch = handler.ShouldHandleScheme("Alpha", handleAutomatic: false);
-
- Assert.False(passiveNoMatch);
- Assert.True(passiveWithMatch);
- }
-
- [Fact]
- public async Task AutomaticHandlerInAutomaticModeHandlesEmptyChallenges()
- {
- var handler = await TestAutoHandler.Create("ignored", true);
- Assert.True(handler.ShouldHandleScheme(AuthenticationManager.AutomaticScheme, handleAutomatic: true));
- }
-
- [Theory]
- [InlineData(null)]
- [InlineData("")]
- [InlineData(" ")]
- [InlineData("notmatched")]
- public async Task AutomaticHandlerDoesNotHandleSchemes(string scheme)
- {
- var handler = await TestAutoHandler.Create("ignored", true);
- Assert.False(handler.ShouldHandleScheme(scheme, handleAutomatic: true));
- }
-
- [Fact]
- public async Task AutomaticHandlerShouldHandleSchemeWhenSchemeMatches()
- {
- var handler = await TestAutoHandler.Create("Alpha", true);
- Assert.True(handler.ShouldHandleScheme("Alpha", handleAutomatic: true));
- }
-
- [Fact]
- public async Task AutomaticHandlerShouldNotHandleChallengeWhenSchemesNotEmpty()
- {
- var handler = await TestAutoHandler.Create(null, true);
- Assert.False(handler.ShouldHandleScheme("Alpha", handleAutomatic: true));
- }
-
- [Theory]
- [InlineData("Alpha")]
- [InlineData("Automatic")]
- public async Task AuthHandlerAuthenticateCachesTicket(string scheme)
- {
- var handler = await CountHandler.Create(scheme);
- var context = new AuthenticateContext(scheme);
- await handler.AuthenticateAsync(context);
- await handler.AuthenticateAsync(context);
- Assert.Equal(1, handler.AuthCount);
- }
-
- [Theory]
- [InlineData("Alpha", false)]
- [InlineData("Bravo", true)]
- public async Task AuthHandlerChallengeCallsPriorHandlerIfNotHandled(string challenge, bool passedThrough)
- {
- var handler = await TestHandler.Create("Alpha");
- var previous = new PreviousHandler();
-
- handler.PriorHandler = previous;
- await handler.ChallengeAsync(new ChallengeContext(challenge));
- Assert.Equal(passedThrough, previous.ChallengeCalled);
- }
-
- private class PreviousHandler : IAuthenticationHandler
- {
- public bool ChallengeCalled = false;
-
- public Task AuthenticateAsync(AuthenticateContext context)
- {
- throw new NotImplementedException();
- }
-
- public Task ChallengeAsync(ChallengeContext context)
- {
- ChallengeCalled = true;
- return Task.FromResult(0);
- }
-
- public void GetDescriptions(DescribeSchemesContext context)
- {
- throw new NotImplementedException();
- }
-
- public Task SignInAsync(SignInContext context)
- {
- throw new NotImplementedException();
- }
-
- public Task SignOutAsync(SignOutContext context)
- {
- throw new NotImplementedException();
- }
- }
-
- private class CountOptions : AuthenticationOptions { }
-
- private class CountHandler : AuthenticationHandler
- {
- public int AuthCount = 0;
-
- private CountHandler() { }
-
- public static async Task Create(string scheme)
- {
- var handler = new CountHandler();
- var context = new DefaultHttpContext();
- context.Features.Set(new TestResponse());
- await handler.InitializeAsync(
- new CountOptions(), context,
- new LoggerFactory().CreateLogger("CountHandler"),
- UrlEncoder.Default);
- handler.Options.AuthenticationScheme = scheme;
- handler.Options.AutomaticAuthenticate = true;
- return handler;
- }
-
- protected override Task HandleAuthenticateAsync()
- {
- AuthCount++;
- return Task.FromResult(AuthenticateResult.Success(new AuthenticationTicket(new ClaimsPrincipal(), new AuthenticationProperties(), "whatever")));
- }
-
- }
-
- private class TestHandler : AuthenticationHandler
- {
- private TestHandler() { }
-
- public AuthenticateResult Result = AuthenticateResult.Success(new AuthenticationTicket(new ClaimsPrincipal(), new AuthenticationProperties(), "whatever"));
-
- public static async Task Create(string scheme)
- {
- var handler = new TestHandler();
- var context = new DefaultHttpContext();
- context.Features.Set(new TestResponse());
- await handler.InitializeAsync(
- new TestOptions(), context,
- new LoggerFactory().CreateLogger("TestHandler"),
- UrlEncoder.Default);
- handler.Options.AuthenticationScheme = scheme;
- return handler;
- }
-
- protected override Task HandleAuthenticateAsync()
- {
- return Task.FromResult(Result);
- }
- }
-
- private class TestOptions : AuthenticationOptions { }
-
- private class TestAutoOptions : AuthenticationOptions
- {
- public TestAutoOptions()
- {
- AutomaticAuthenticate = true;
- }
- }
-
- private class TestAutoHandler : AuthenticationHandler
- {
- private TestAutoHandler() { }
-
- public static async Task Create(string scheme, bool auto)
- {
- var handler = new TestAutoHandler();
- var context = new DefaultHttpContext();
- context.Features.Set(new TestResponse());
- await handler.InitializeAsync(
- new TestAutoOptions(), context,
- new LoggerFactory().CreateLogger("TestAutoHandler"),
- UrlEncoder.Default);
- handler.Options.AuthenticationScheme = scheme;
- handler.Options.AutomaticAuthenticate = auto;
- return handler;
- }
-
- protected override Task HandleAuthenticateAsync()
- {
- return Task.FromResult(AuthenticateResult.Success(new AuthenticationTicket(new ClaimsPrincipal(), new AuthenticationProperties(), "whatever")));
- }
- }
-
- private class TestResponse : IHttpResponseFeature
- {
- public Stream Body
- {
- get
- {
- throw new NotImplementedException();
- }
-
- set
- {
- throw new NotImplementedException();
- }
- }
-
- public bool HasStarted
- {
- get
- {
- throw new NotImplementedException();
- }
- }
-
- public IHeaderDictionary Headers
- {
- get
- {
- throw new NotImplementedException();
- }
-
- set
- {
- throw new NotImplementedException();
- }
- }
-
- public string ReasonPhrase
- {
- get
- {
- throw new NotImplementedException();
- }
-
- set
- {
- throw new NotImplementedException();
- }
- }
-
- public int StatusCode
- {
- get
- {
- throw new NotImplementedException();
- }
-
- set
- {
- }
- }
-
- public void OnCompleted(Func