Auth 2.0
This commit is contained in:
parent
2d7cd6038f
commit
99aa3bd35d
124
Security.sln
124
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,7 +18,7 @@ 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}"
|
||||
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.AspNetCore.Authentication.Facebook", "src\Microsoft.AspNetCore.Authentication.Facebook\Microsoft.AspNetCore.Authentication.Facebook.csproj", "{EEAAEE68-607B-4E33-AF3E-45C66B4DBA5A}"
|
||||
EndProject
|
||||
|
|
@ -58,9 +58,11 @@ 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 +70,364 @@ 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
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
|
@ -344,7 +438,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 +455,6 @@ 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}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
|
|
|
|||
|
|
@ -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 @@ namespace CookieSample
|
|||
{
|
||||
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");
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ using System.Security.Claims;
|
|||
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 @@ namespace CookieSessionSample
|
|||
{
|
||||
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 @@ namespace CookieSessionSample
|
|||
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";
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@
|
|||
<PackageReference Include="Microsoft.AspNetCore.StaticFiles" Version="$(AspNetCoreVersion)" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="$(AspNetCoreVersion)" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" Version="$(AspNetCoreVersion)" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Diagnostics" Version="$(AspNetCoreVersion)" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
|
|||
|
|
@ -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,39 +43,12 @@ namespace JwtBearerSample
|
|||
// For more information on how to configure your application, visit http://go.microsoft.com/fwlink/?LinkID=398940
|
||||
public void ConfigureServices(IServiceCollection services)
|
||||
{
|
||||
services.AddAuthentication();
|
||||
}
|
||||
|
||||
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
|
||||
public void Configure(IApplicationBuilder app)
|
||||
{
|
||||
// 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.UseDefaultFiles();
|
||||
app.UseStaticFiles();
|
||||
|
||||
app.UseJwtBearerAuthentication(new JwtBearerOptions
|
||||
services.AddJwtBearerAuthentication(o =>
|
||||
{
|
||||
// You also need to update /wwwroot/app/scripts/app.js
|
||||
Authority = Configuration["jwt:authority"],
|
||||
Audience = Configuration["jwt:audience"],
|
||||
Events = new JwtBearerEvents()
|
||||
o.Authority = Configuration["jwt:authority"];
|
||||
o.Audience = Configuration["jwt:audience"];
|
||||
o.Events = new JwtBearerEvents()
|
||||
{
|
||||
OnAuthenticationFailed = c =>
|
||||
{
|
||||
|
|
@ -89,24 +63,34 @@ namespace JwtBearerSample
|
|||
}
|
||||
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.
|
||||
public void Configure(IApplicationBuilder app)
|
||||
{
|
||||
app.UseDeveloperExceptionPage();
|
||||
|
||||
app.UseDefaultFiles();
|
||||
app.UseStaticFiles();
|
||||
|
||||
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();
|
||||
}
|
||||
});
|
||||
|
||||
|
|
@ -135,5 +119,4 @@ namespace JwtBearerSample
|
|||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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 @@ namespace OpenIdConnect.AzureAdSample
|
|||
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 @@ namespace OpenIdConnect.AzureAdSample
|
|||
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();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@
|
|||
<PackageReference Include="Microsoft.AspNetCore.Server.Kestrel" Version="$(AspNetCoreVersion)" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="$(AspNetCoreVersion)" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" Version="$(AspNetCoreVersion)" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Diagnostics" Version="$(AspNetCoreVersion)" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="$(AspNetCoreVersion)" />
|
||||
<PackageReference Include="Microsoft.IdentityModel.Clients.ActiveDirectory" Version="$(IdentityModelActiveDirectoryVersion)" />
|
||||
<DotNetCliToolReference Include="Microsoft.Extensions.SecretManager.Tools" Version="$(AspNetCoreVersion)" />
|
||||
|
|
|
|||
|
|
@ -3,12 +3,12 @@ using System.Collections.Generic;
|
|||
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,68 +37,55 @@ namespace OpenIdConnect.AzureAdSample
|
|||
|
||||
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.AddAuthentication(sharedOptions =>
|
||||
sharedOptions.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme);
|
||||
{
|
||||
sharedOptions.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
|
||||
sharedOptions.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
|
||||
sharedOptions.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
|
||||
});
|
||||
|
||||
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);
|
||||
}
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
public void Configure(IApplicationBuilder app, ILoggerFactory loggerfactory)
|
||||
{
|
||||
loggerfactory.AddConsole(Microsoft.Extensions.Logging.LogLevel.Information);
|
||||
|
||||
// Simple error page
|
||||
app.Use(async (context, next) =>
|
||||
{
|
||||
try
|
||||
{
|
||||
await next();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (!context.Response.HasStarted)
|
||||
{
|
||||
context.Response.Clear();
|
||||
context.Response.StatusCode = 500;
|
||||
await context.Response.WriteAsync(ex.ToString());
|
||||
}
|
||||
else
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
});
|
||||
app.UseDeveloperExceptionPage();
|
||||
|
||||
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 +98,11 @@ namespace OpenIdConnect.AzureAdSample
|
|||
return;
|
||||
}
|
||||
|
||||
await context.Authentication.ChallengeAsync(
|
||||
OpenIdConnectDefaults.AuthenticationScheme,
|
||||
new AuthenticationProperties { RedirectUri = "/" });
|
||||
await context.ChallengeAsync(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 +112,8 @@ namespace OpenIdConnect.AzureAdSample
|
|||
}
|
||||
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 +126,7 @@ namespace OpenIdConnect.AzureAdSample
|
|||
}
|
||||
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 +138,7 @@ namespace OpenIdConnect.AzureAdSample
|
|||
{
|
||||
if (!context.User.Identities.Any(identity => identity.IsAuthenticated))
|
||||
{
|
||||
await context.Authentication.ChallengeAsync(OpenIdConnectDefaults.AuthenticationScheme, new AuthenticationProperties { RedirectUri = "/" });
|
||||
await context.ChallengeAsync(new AuthenticationProperties { RedirectUri = "/" });
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -170,10 +155,10 @@ namespace OpenIdConnect.AzureAdSample
|
|||
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($"<h3>access_token</h3><code>{HtmlEncode(result.AccessToken)}</code><br>");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@
|
|||
<PackageReference Include="Microsoft.AspNetCore.Server.Kestrel.Https" Version="$(AspNetCoreVersion)" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="$(AspNetCoreVersion)" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" Version="$(AspNetCoreVersion)" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Diagnostics" Version="$(AspNetCoreVersion)" />
|
||||
<PackageReference Include="Microsoft.Extensions.FileProviders.Embedded" Version="$(AspNetCoreVersion)" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="$(AspNetCoreVersion)" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="$(AspNetCoreVersion)" />
|
||||
|
|
|
|||
|
|
@ -3,12 +3,12 @@ using System.Collections.Generic;
|
|||
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;
|
||||
|
|
@ -42,46 +42,22 @@ namespace OpenIdConnectSample
|
|||
public void ConfigureServices(IServiceCollection services)
|
||||
{
|
||||
services.AddAuthentication(sharedOptions =>
|
||||
sharedOptions.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme);
|
||||
}
|
||||
|
||||
public void Configure(IApplicationBuilder app, ILoggerFactory loggerfactory)
|
||||
{
|
||||
loggerfactory.AddConsole(LogLevel.Information);
|
||||
loggerfactory.AddDebug(LogLevel.Information);
|
||||
|
||||
// Simple error page
|
||||
app.Use(async (context, next) =>
|
||||
{
|
||||
try
|
||||
{
|
||||
await next();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (!context.Response.HasStarted)
|
||||
{
|
||||
context.Response.Clear();
|
||||
context.Response.StatusCode = 500;
|
||||
await context.Response.WriteAsync(ex.ToString());
|
||||
}
|
||||
else
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
sharedOptions.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
|
||||
sharedOptions.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
|
||||
sharedOptions.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
|
||||
});
|
||||
|
||||
app.UseCookieAuthentication(new CookieAuthenticationOptions());
|
||||
services.AddCookieAuthentication();
|
||||
|
||||
app.UseOpenIdConnectAuthentication(new OpenIdConnectOptions
|
||||
services.AddOpenIdConnectAuthentication(o =>
|
||||
{
|
||||
ClientId = Configuration["oidc:clientid"],
|
||||
ClientSecret = Configuration["oidc:clientsecret"], // for code flow
|
||||
Authority = Configuration["oidc:authority"],
|
||||
ResponseType = OpenIdConnectResponseType.CodeIdToken,
|
||||
GetClaimsFromUserInfoEndpoint = true,
|
||||
Events = new OpenIdConnectEvents()
|
||||
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 =>
|
||||
{
|
||||
|
|
@ -96,8 +72,17 @@ namespace OpenIdConnectSample
|
|||
}
|
||||
return c.Response.WriteAsync("An error occurred processing your authentication.");
|
||||
}
|
||||
}
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
public void Configure(IApplicationBuilder app, ILoggerFactory loggerfactory)
|
||||
{
|
||||
loggerfactory.AddConsole(LogLevel.Information);
|
||||
loggerfactory.AddDebug(LogLevel.Information);
|
||||
|
||||
app.UseDeveloperExceptionPage();
|
||||
app.UseAuthentication();
|
||||
|
||||
app.Run(async context =>
|
||||
{
|
||||
|
|
@ -113,7 +98,7 @@ namespace OpenIdConnectSample
|
|||
|
||||
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($"<h1>Signed out {HtmlEncode(context.User.Identity.Name)}</h1>");
|
||||
|
|
@ -125,8 +110,8 @@ namespace OpenIdConnectSample
|
|||
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 +120,7 @@ namespace OpenIdConnectSample
|
|||
|
||||
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($"<h1>Access Denied for user {HtmlEncode(context.User.Identity.Name)} to resource '{HtmlEncode(context.Request.Query["ReturnUrl"])}'</h1>");
|
||||
|
|
@ -144,24 +129,23 @@ namespace OpenIdConnectSample
|
|||
return;
|
||||
}
|
||||
|
||||
// CookieAuthenticationOptions.AutomaticAuthenticate = true (default) causes User to be set
|
||||
// DefaultAuthenticateScheme causes User to be set
|
||||
var user = context.User;
|
||||
|
||||
// This is what [Authorize] calls
|
||||
// var user = await context.Authentication.AuthenticateAsync(AuthenticationManager.AutomaticScheme);
|
||||
// var user = await context.AuthenticateAsync();
|
||||
|
||||
// This is what [Authorize(ActiveAuthenticationSchemes = OpenIdConnectDefaults.AuthenticationScheme)] calls
|
||||
// var user = await context.Authentication.AuthenticateAsync(OpenIdConnectDefaults.AuthenticationScheme);
|
||||
// var user = await context.AuthenticateAsync(OpenIdConnectDefaults.AuthenticationScheme);
|
||||
|
||||
// Not authenticated
|
||||
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();
|
||||
|
||||
// This is what [Authorize(ActiveAuthenticationSchemes = OpenIdConnectDefaults.AuthenticationScheme)] calls
|
||||
// await context.Authentication.ChallengeAsync(OpenIdConnectDefaults.AuthenticationScheme);
|
||||
// await context.ChallengeAsync(OpenIdConnectDefaults.AuthenticationScheme);
|
||||
|
||||
return;
|
||||
}
|
||||
|
|
@ -169,11 +153,10 @@ namespace OpenIdConnectSample
|
|||
// 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();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
await WriteHtmlAsync(context.Response, async response =>
|
||||
{
|
||||
await response.WriteAsync($"<h1>Hello Authenticated User {HtmlEncode(user.Identity.Name)}</h1>");
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@
|
|||
<PackageReference Include="Microsoft.AspNetCore.Server.Kestrel.Https" Version="$(AspNetCoreVersion)" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="$(AspNetCoreVersion)" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" Version="$(AspNetCoreVersion)" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Diagnostics" Version="$(AspNetCoreVersion)" />
|
||||
<PackageReference Include="Microsoft.Extensions.FileProviders.Embedded" Version="$(AspNetCoreVersion)" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="$(AspNetCoreVersion)" />
|
||||
</ItemGroup>
|
||||
|
|
|
|||
|
|
@ -14,7 +14,6 @@ using Microsoft.AspNetCore.Authentication.Twitter;
|
|||
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 @@ namespace SocialSample
|
|||
|
||||
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,51 @@ namespace SocialSample
|
|||
throw new InvalidOperationException("User secrets must be configured for each authentication provider.");
|
||||
}
|
||||
|
||||
services.AddAuthentication(options =>
|
||||
{
|
||||
options.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
|
||||
options.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
|
||||
options.DefaultChallengeScheme = CookieAuthenticationDefaults.AuthenticationScheme;
|
||||
});
|
||||
|
||||
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 +103,23 @@ namespace SocialSample
|
|||
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 +127,8 @@ namespace SocialSample
|
|||
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 +136,60 @@ namespace SocialSample
|
|||
*/
|
||||
// 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 +205,17 @@ namespace SocialSample
|
|||
|
||||
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);
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
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 +227,18 @@ namespace SocialSample
|
|||
{
|
||||
// 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("<html><body>");
|
||||
await context.Response.WriteAsync("Choose an authentication scheme: <br>");
|
||||
foreach (var type in context.Authentication.GetAuthenticationSchemes())
|
||||
var schemeProvider = context.RequestServices.GetRequiredService<IAuthenticationSchemeProvider>();
|
||||
foreach (var provider in await schemeProvider.GetAllSchemesAsync())
|
||||
{
|
||||
await context.Response.WriteAsync("<a href=\"?authscheme=" + type.AuthenticationScheme + "\">" + (type.DisplayName ?? "(suppressed)") + "</a><br>");
|
||||
// REVIEW: we lost access to display name (which is buried in the handler options)
|
||||
await context.Response.WriteAsync("<a href=\"?authscheme=" + provider.Name + "\">" + (provider.Name ?? "(suppressed)") + "</a><br>");
|
||||
}
|
||||
await context.Response.WriteAsync("</body></html>");
|
||||
});
|
||||
|
|
@ -268,7 +250,7 @@ namespace SocialSample
|
|||
signoutApp.Run(async context =>
|
||||
{
|
||||
context.Response.ContentType = "text/html";
|
||||
await context.Authentication.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
|
||||
await context.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
|
||||
await context.Response.WriteAsync("<html><body>");
|
||||
await context.Response.WriteAsync("You have been logged out. Goodbye " + context.User.Identity.Name + "<br>");
|
||||
await context.Response.WriteAsync("<a href=\"/\">Home</a>");
|
||||
|
|
@ -292,24 +274,24 @@ namespace SocialSample
|
|||
|
||||
app.Run(async context =>
|
||||
{
|
||||
// CookieAuthenticationOptions.AutomaticAuthenticate = true (default) causes User to be set
|
||||
// Setting DefaultAuthenticateScheme causes User to be set
|
||||
var user = context.User;
|
||||
|
||||
// This is what [Authorize] calls
|
||||
// var user = await context.Authentication.AuthenticateAsync(AuthenticationManager.AutomaticScheme);
|
||||
// var user = await context.AuthenticateAsync();
|
||||
|
||||
// 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();
|
||||
|
||||
// This is what [Authorize(ActiveAuthenticationSchemes = MicrosoftAccountDefaults.AuthenticationScheme)] calls
|
||||
// await context.Authentication.ChallengeAsync(MicrosoftAccountDefaults.AuthenticationScheme);
|
||||
// await context.ChallengeAsync(MicrosoftAccountDefaults.AuthenticationScheme);
|
||||
|
||||
return;
|
||||
}
|
||||
|
|
@ -324,11 +306,11 @@ namespace SocialSample
|
|||
}
|
||||
|
||||
await context.Response.WriteAsync("Tokens:<br>");
|
||||
|
||||
await context.Response.WriteAsync("Access Token: " + await context.Authentication.GetTokenAsync("access_token") + "<br>");
|
||||
await context.Response.WriteAsync("Refresh Token: " + await context.Authentication.GetTokenAsync("refresh_token") + "<br>");
|
||||
await context.Response.WriteAsync("Token Type: " + await context.Authentication.GetTokenAsync("token_type") + "<br>");
|
||||
await context.Response.WriteAsync("expires_at: " + await context.Authentication.GetTokenAsync("expires_at") + "<br>");
|
||||
|
||||
await context.Response.WriteAsync("Access Token: " + await context.GetTokenAsync("access_token") + "<br>");
|
||||
await context.Response.WriteAsync("Refresh Token: " + await context.GetTokenAsync("refresh_token") + "<br>");
|
||||
await context.Response.WriteAsync("Token Type: " + await context.GetTokenAsync("token_type") + "<br>");
|
||||
await context.Response.WriteAsync("expires_at: " + await context.GetTokenAsync("expires_at") + "<br>");
|
||||
await context.Response.WriteAsync("<a href=\"/logout\">Logout</a><br>");
|
||||
await context.Response.WriteAsync("</body></html>");
|
||||
});
|
||||
|
|
|
|||
|
|
@ -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
|
||||
{
|
||||
/// <summary>
|
||||
/// Adds the <see cref="CookieAuthenticationMiddleware"/> middleware to the specified <see cref="IApplicationBuilder"/>, which enables cookie authentication capabilities.
|
||||
/// Obsolete, see https://go.microsoft.com/fwlink/?linkid=845470
|
||||
/// </summary>
|
||||
/// <param name="app">The <see cref="IApplicationBuilder"/> to add the middleware to.</param>
|
||||
/// <param name="app">The <see cref="IApplicationBuilder"/> to add the handler to.</param>
|
||||
/// <returns>A reference to this instance after the operation has completed.</returns>
|
||||
[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<CookieAuthenticationMiddleware>();
|
||||
throw new NotSupportedException("This method is no longer supported, see https://go.microsoft.com/fwlink/?linkid=845470");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds the <see cref="CookieAuthenticationMiddleware"/> middleware to the specified <see cref="IApplicationBuilder"/>, which enables cookie authentication capabilities.
|
||||
/// Obsolete, see https://go.microsoft.com/fwlink/?linkid=845470
|
||||
/// </summary>
|
||||
/// <param name="app">The <see cref="IApplicationBuilder"/> to add the middleware to.</param>
|
||||
/// <param name="options">A <see cref="CookieAuthenticationOptions"/> that specifies options for the middleware.</param>
|
||||
/// <param name="app">The <see cref="IApplicationBuilder"/> to add the handler to.</param>
|
||||
/// <param name="options">A <see cref="CookieAuthenticationOptions"/> that specifies options for the handler.</param>
|
||||
/// <returns>A reference to this instance after the operation has completed.</returns>
|
||||
[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<CookieAuthenticationMiddleware>(Options.Create(options));
|
||||
throw new NotSupportedException("This method is no longer supported, see https://go.microsoft.com/fwlink/?linkid=845470");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -6,7 +6,7 @@ using Microsoft.AspNetCore.Http;
|
|||
namespace Microsoft.AspNetCore.Authentication.Cookies
|
||||
{
|
||||
/// <summary>
|
||||
/// Default values related to cookie-based authentication middleware
|
||||
/// Default values related to cookie-based authentication handler
|
||||
/// </summary>
|
||||
public static class CookieAuthenticationDefaults
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,32 +1,97 @@
|
|||
// 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.Internal;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Microsoft.Net.Http.Headers;
|
||||
|
||||
namespace Microsoft.AspNetCore.Authentication.Cookies
|
||||
{
|
||||
internal class CookieAuthenticationHandler : AuthenticationHandler<CookieAuthenticationOptions>
|
||||
public class CookieAuthenticationHandler : AuthenticationHandler<CookieAuthenticationOptions>
|
||||
{
|
||||
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<AuthenticateResult> _readCookieTask;
|
||||
|
||||
public CookieAuthenticationHandler(IOptionsSnapshot<CookieAuthenticationOptions> options, ILoggerFactory logger, UrlEncoder encoder, ISystemClock clock)
|
||||
: base(options, logger, encoder, clock)
|
||||
{ }
|
||||
|
||||
/// <summary>
|
||||
/// 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.
|
||||
/// </summary>
|
||||
protected new CookieAuthenticationEvents Events
|
||||
{
|
||||
get { return (CookieAuthenticationEvents)base.Events; }
|
||||
set { base.Events = value; }
|
||||
}
|
||||
|
||||
protected override Task InitializeHandlerAsync()
|
||||
{
|
||||
// Cookies needs to finish the response
|
||||
Context.Response.OnStarting(FinishResponseAsync);
|
||||
return TaskCache.CompletedTask;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of the events instance.
|
||||
/// </summary>
|
||||
/// <returns>A new instance of the events instance.</returns>
|
||||
protected override Task<object> CreateEventsAsync() => Task.FromResult<object>(new CookieAuthenticationEvents());
|
||||
|
||||
protected override void InitializeOptions()
|
||||
{
|
||||
base.InitializeOptions();
|
||||
|
||||
if (String.IsNullOrEmpty(Options.CookieName))
|
||||
{
|
||||
Options.CookieName = CookieAuthenticationDefaults.CookiePrefix + Scheme.Name;
|
||||
}
|
||||
if (Options.TicketDataFormat == null)
|
||||
{
|
||||
var provider = Options.DataProtectionProvider ?? Context.RequestServices.GetRequiredService<IDataProtectionProvider>();
|
||||
// Note: the purpose for the data protector must remain fixed for interop to work.
|
||||
var dataProtector = provider.CreateProtector("Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationMiddleware", 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<AuthenticateResult> EnsureCookieTicket()
|
||||
{
|
||||
// We only need to read the ticket once
|
||||
|
|
@ -39,7 +104,7 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
|
|||
|
||||
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 +128,7 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
|
|||
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 +140,7 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
|
|||
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 +164,7 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
|
|||
}
|
||||
}
|
||||
|
||||
var currentUtc = Options.SystemClock.UtcNow;
|
||||
var currentUtc = Clock.UtcNow;
|
||||
var issuedUtc = ticket.Properties.IssuedUtc;
|
||||
var expiresUtc = ticket.Properties.ExpiresUtc;
|
||||
|
||||
|
|
@ -126,8 +191,8 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
|
|||
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 +204,7 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
|
|||
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 +228,10 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
|
|||
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 +257,8 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
|
|||
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 +281,18 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
|
|||
|
||||
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 +302,7 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
|
|||
}
|
||||
else
|
||||
{
|
||||
issuedUtc = Options.SystemClock.UtcNow;
|
||||
issuedUtc = Clock.UtcNow;
|
||||
signInContext.Properties.IssuedUtc = issuedUtc;
|
||||
}
|
||||
|
||||
|
|
@ -244,7 +311,7 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
|
|||
signInContext.Properties.ExpiresUtc = issuedUtc.Add(Options.ExpireTimeSpan);
|
||||
}
|
||||
|
||||
await Options.Events.SigningIn(signInContext);
|
||||
await Events.SigningIn(signInContext);
|
||||
|
||||
if (signInContext.Properties.IsPersistent)
|
||||
{
|
||||
|
|
@ -264,7 +331,7 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
|
|||
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 +344,13 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
|
|||
|
||||
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 +359,8 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
|
|||
|
||||
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 +371,12 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
|
|||
|
||||
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 +414,8 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
|
|||
|
||||
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 +433,27 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
|
|||
return path[0] == '/' && path[1] != '/' && path[1] != '\\';
|
||||
}
|
||||
|
||||
protected override async Task<bool> 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<bool> 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 +461,8 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
|
|||
}
|
||||
|
||||
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()
|
||||
|
|
|
|||
|
|
@ -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<CookieAuthenticationOptions>
|
||||
{
|
||||
public CookieAuthenticationMiddleware(
|
||||
RequestDelegate next,
|
||||
IDataProtectionProvider dataProtectionProvider,
|
||||
ILoggerFactory loggerFactory,
|
||||
UrlEncoder urlEncoder,
|
||||
IOptions<CookieAuthenticationOptions> 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<CookieAuthenticationOptions> CreateHandler()
|
||||
{
|
||||
return new CookieAuthenticationHandler();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
||||
{
|
||||
/// <summary>
|
||||
/// Configuration options for <see cref="CookieAuthenticationMiddleware"/>.
|
||||
/// Configuration options for <see cref="CookieAuthenticationOptions"/>.
|
||||
/// </summary>
|
||||
public class CookieAuthenticationOptions : AuthenticationOptions, IOptions<CookieAuthenticationOptions>
|
||||
public class CookieAuthenticationOptions : AuthenticationSchemeOptions
|
||||
{
|
||||
private string _cookieName;
|
||||
|
||||
|
|
@ -23,21 +19,18 @@ namespace Microsoft.AspNetCore.Builder
|
|||
/// </summary>
|
||||
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();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines the cookie name used to persist the identity. The default value is ".AspNetCore.Cookies".
|
||||
/// This value should be changed if you change the name of the AuthenticationScheme, especially if your
|
||||
/// system uses the cookie authentication middleware multiple times.
|
||||
/// system uses the cookie authentication handler multiple times.
|
||||
/// </summary>
|
||||
public string CookieName
|
||||
{
|
||||
|
|
@ -90,13 +83,13 @@ namespace Microsoft.AspNetCore.Builder
|
|||
public TimeSpan ExpireTimeSpan { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The SlidingExpiration is set to true to instruct the middleware to re-issue a new cookie with a new
|
||||
/// The SlidingExpiration is set to true to instruct the handler to re-issue a new cookie with a new
|
||||
/// expiration time any time it processes a request which is more than halfway through the expiration window.
|
||||
/// </summary>
|
||||
public bool SlidingExpiration { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The LoginPath property informs the middleware that it should change an outgoing 401 Unauthorized status
|
||||
/// The LoginPath property informs the handler that it should change an outgoing 401 Unauthorized status
|
||||
/// code into a 302 redirection onto the given login path. The current url which generated the 401 is added
|
||||
/// to the LoginPath as a query string parameter named by the ReturnUrlParameter. Once a request to the
|
||||
/// LoginPath grants a new SignIn identity, the ReturnUrlParameter value is used to redirect the browser back
|
||||
|
|
@ -105,18 +98,18 @@ namespace Microsoft.AspNetCore.Builder
|
|||
public PathString LoginPath { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// If the LogoutPath is provided the middleware then a request to that path will redirect based on the ReturnUrlParameter.
|
||||
/// If the LogoutPath is provided the handler then a request to that path will redirect based on the ReturnUrlParameter.
|
||||
/// </summary>
|
||||
public PathString LogoutPath { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The AccessDeniedPath property informs the middleware that it should change an outgoing 403 Forbidden status
|
||||
/// The AccessDeniedPath property informs the handler that it should change an outgoing 403 Forbidden status
|
||||
/// code into a 302 redirection onto the given path.
|
||||
/// </summary>
|
||||
public PathString AccessDeniedPath { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The ReturnUrlParameter determines the name of the query string parameter which is appended by the middleware
|
||||
/// The ReturnUrlParameter determines the name of the query string parameter which is appended by the handler
|
||||
/// when a 401 Unauthorized status code is changed to a 302 redirect onto the login path. This is also the query
|
||||
/// string parameter looked for when a request arrives on the login path or logout path, in order to return to the
|
||||
/// original url after the action is performed.
|
||||
|
|
@ -124,11 +117,15 @@ namespace Microsoft.AspNetCore.Builder
|
|||
public string ReturnUrlParameter { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The Provider may be assigned to an instance of an object created by the application at startup time. The middleware
|
||||
/// The Provider may be assigned to an instance of an object created by the application at startup time. The handler
|
||||
/// 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.
|
||||
/// </summary>
|
||||
public ICookieAuthenticationEvents Events { get; set; }
|
||||
public new CookieAuthenticationEvents Events
|
||||
{
|
||||
get { return (CookieAuthenticationEvents)base.Events; }
|
||||
set { base.Events = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The TicketDataFormat is used to protect and unprotect the identity and other properties which are stored in the
|
||||
|
|
@ -150,13 +147,5 @@ namespace Microsoft.AspNetCore.Builder
|
|||
/// to the client. This can be used to mitigate potential problems with very large identities.
|
||||
/// </summary>
|
||||
public ITicketStore SessionStore { get; set; }
|
||||
|
||||
CookieAuthenticationOptions IOptions<CookieAuthenticationOptions>.Value
|
||||
{
|
||||
get
|
||||
{
|
||||
return this;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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<CookieAuthenticationOptions> configureOptions) =>
|
||||
services.AddCookieAuthentication(CookieAuthenticationDefaults.AuthenticationScheme, configureOptions);
|
||||
|
||||
public static IServiceCollection AddCookieAuthentication(this IServiceCollection services, string authenticationScheme, Action<CookieAuthenticationOptions> configureOptions) =>
|
||||
services.AddScheme<CookieAuthenticationOptions, CookieAuthenticationHandler>(authenticationScheme, configureOptions);
|
||||
}
|
||||
}
|
||||
|
|
@ -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 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
|
|||
}
|
||||
|
||||
public CookieAuthenticationOptions Options { get; }
|
||||
|
||||
public AuthenticationScheme Scheme { get; }
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
/// </summary>
|
||||
public class CookieAuthenticationEvents : ICookieAuthenticationEvents
|
||||
public class CookieAuthenticationEvents
|
||||
{
|
||||
/// <summary>
|
||||
/// A delegate assigned to this property will be invoked when the related method is called.
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ using Microsoft.AspNetCore.Http.Authentication;
|
|||
namespace Microsoft.AspNetCore.Authentication.Cookies
|
||||
{
|
||||
/// <summary>
|
||||
/// Context passed when a Challenge, SignIn, or SignOut causes a redirect in the cookie middleware
|
||||
/// Context passed when a Challenge, SignIn, or SignOut causes a redirect in the cookie handler
|
||||
/// </summary>
|
||||
public class CookieRedirectContext : BaseCookieContext
|
||||
{
|
||||
|
|
@ -16,21 +16,19 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
|
|||
/// Creates a new context object.
|
||||
/// </summary>
|
||||
/// <param name="context">The HTTP request context</param>
|
||||
/// <param name="options">The cookie middleware options</param>
|
||||
/// <param name="scheme">The scheme data</param>
|
||||
/// <param name="options">The cookie handler options</param>
|
||||
/// <param name="redirectUri">The initial redirect URI</param>
|
||||
/// <param name="properties">The <see cref="AuthenticationProperties"/>.</param>
|
||||
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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or Sets the URI used for the redirect operation.
|
||||
/// </summary>
|
||||
public string RedirectUri { get; set; }
|
||||
|
||||
public AuthenticationProperties Properties { get; }
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
|
|||
/// Creates a new instance of the context object.
|
||||
/// </summary>
|
||||
/// <param name="context">The HTTP request context</param>
|
||||
/// <param name="options">The middleware options</param>
|
||||
/// <param name="scheme">The scheme data</param>
|
||||
/// <param name="options">The handler options</param>
|
||||
/// <param name="authenticationScheme">Initializes AuthenticationScheme property</param>
|
||||
/// <param name="principal">Initializes Principal property</param>
|
||||
/// <param name="properties">Initializes Properties property</param>
|
||||
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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The name of the AuthenticationScheme creating a cookie
|
||||
/// </summary>
|
||||
public string AuthenticationScheme { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Contains the claims that were converted into the outgoing cookie.
|
||||
/// </summary>
|
||||
public ClaimsPrincipal Principal { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Contains the extra data that was contained in the outgoing cookie.
|
||||
/// </summary>
|
||||
public AuthenticationProperties Properties { get; }
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
|
|||
/// Creates a new instance of the context object.
|
||||
/// </summary>
|
||||
/// <param name="context">The HTTP request context</param>
|
||||
/// <param name="options">The middleware options</param>
|
||||
/// <param name="authenticationScheme">Initializes AuthenticationScheme property</param>
|
||||
/// <param name="scheme">The scheme data</param>
|
||||
/// <param name="options">The handler options</param>
|
||||
/// <param name="principal">Initializes Principal property</param>
|
||||
/// <param name="properties">Initializes Extra property</param>
|
||||
/// <param name="cookieOptions">Initializes options for the authentication cookie.</param>
|
||||
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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The name of the AuthenticationScheme creating a cookie
|
||||
/// </summary>
|
||||
public string AuthenticationScheme { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Contains the claims about to be converted into the outgoing cookie.
|
||||
/// May be replaced or altered during the SigningIn call.
|
||||
/// </summary>
|
||||
public ClaimsPrincipal Principal { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Contains the extra data about to be contained in the outgoing cookie.
|
||||
/// May be replaced or altered during the SigningIn call.
|
||||
/// </summary>
|
||||
public AuthenticationProperties Properties { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The options for creating the outgoing cookie.
|
||||
/// May be replace or altered during the SigningIn call.
|
||||
|
|
|
|||
|
|
@ -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 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
|
|||
///
|
||||
/// </summary>
|
||||
/// <param name="context"></param>
|
||||
/// <param name="scheme"></param>
|
||||
/// <param name="options"></param>
|
||||
/// <param name="properties"></param>
|
||||
/// <param name="cookieOptions"></param>
|
||||
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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -35,7 +34,5 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
|
|||
/// May be replace or altered during the SigningOut call.
|
||||
/// </summary>
|
||||
public CookieOptions CookieOptions { get; set; }
|
||||
|
||||
public AuthenticationProperties Properties { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
{
|
||||
/// <summary>
|
||||
/// Context object passed to the ICookieAuthenticationProvider method ValidatePrincipal.
|
||||
/// Context object passed to the CookieAuthenticationEvents ValidatePrincipal method.
|
||||
/// </summary>
|
||||
public class CookieValidatePrincipalContext : BaseCookieContext
|
||||
{
|
||||
|
|
@ -18,10 +16,11 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
|
|||
/// Creates a new instance of the context object.
|
||||
/// </summary>
|
||||
/// <param name="context"></param>
|
||||
/// <param name="scheme"></param>
|
||||
/// <param name="ticket">Contains the initial values for identity and extra data</param>
|
||||
/// <param name="options"></param>
|
||||
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 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
|
|||
}
|
||||
|
||||
Principal = ticket.Principal;
|
||||
Properties = ticket.Properties;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -48,11 +46,6 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
|
|||
/// </summary>
|
||||
public ClaimsPrincipal Principal { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Contains the extra meta-data arriving with the request ticket. May be altered.
|
||||
/// </summary>
|
||||
public AuthenticationProperties Properties { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// If true, the cookie will be renewed
|
||||
/// </summary>
|
||||
|
|
|
|||
|
|
@ -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
|
||||
{
|
||||
/// <summary>
|
||||
/// Specifies callback methods which the <see cref="CookieAuthenticationMiddleware"></see> invokes to enable developer control over the authentication process. />
|
||||
/// </summary>
|
||||
public interface ICookieAuthenticationEvents
|
||||
{
|
||||
/// <summary>
|
||||
/// 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.
|
||||
/// </summary>
|
||||
/// <param name="context">Contains information about the login session as well as the user <see cref="System.Security.Claims.ClaimsIdentity"/>.</param>
|
||||
/// <returns>A <see cref="Task"/> representing the completed operation.</returns>
|
||||
Task ValidatePrincipal(CookieValidatePrincipalContext context);
|
||||
|
||||
/// <summary>
|
||||
/// 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.
|
||||
/// </summary>
|
||||
/// <param name="context">Contains information about the login session as well as the user <see cref="System.Security.Claims.ClaimsIdentity"/>.</param>
|
||||
Task SigningIn(CookieSigningInContext context);
|
||||
|
||||
/// <summary>
|
||||
/// Called when an endpoint has provided sign in information after it is converted into a cookie.
|
||||
/// </summary>
|
||||
/// <param name="context">Contains information about the login session as well as the user <see cref="System.Security.Claims.ClaimsIdentity"/>.</param>
|
||||
Task SignedIn(CookieSignedInContext context);
|
||||
|
||||
/// <summary>
|
||||
/// Called when a SignOut causes a redirect in the cookie middleware.
|
||||
/// </summary>
|
||||
/// <param name="context">Contains information about the event</param>
|
||||
Task RedirectToLogout(CookieRedirectContext context);
|
||||
|
||||
/// <summary>
|
||||
/// Called when a SignIn causes a redirect in the cookie middleware.
|
||||
/// </summary>
|
||||
/// <param name="context">Contains information about the event</param>
|
||||
Task RedirectToLogin(CookieRedirectContext context);
|
||||
|
||||
/// <summary>
|
||||
/// Called when redirecting back to the return url in the cookie middleware.
|
||||
/// </summary>
|
||||
/// <param name="context">Contains information about the event</param>
|
||||
Task RedirectToReturnUrl(CookieRedirectContext context);
|
||||
|
||||
/// <summary>
|
||||
/// Called when an access denied causes a redirect in the cookie middleware.
|
||||
/// </summary>
|
||||
/// <param name="context">Contains information about the event</param>
|
||||
Task RedirectToAccessDenied(CookieRedirectContext context);
|
||||
|
||||
/// <summary>
|
||||
/// Called during the sign-out flow to augment the cookie cleanup process.
|
||||
/// </summary>
|
||||
/// <param name="context">Contains information about the login session as well as information about the authentication cookie.</param>
|
||||
Task SigningOut(CookieSigningOutContext context);
|
||||
}
|
||||
}
|
||||
|
|
@ -17,9 +17,7 @@
|
|||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Microsoft.AspNetCore.Authentication\Microsoft.AspNetCore.Authentication.csproj" />
|
||||
<PackageReference Include="Microsoft.Extensions.Options" Version="$(AspNetCoreVersion)" />
|
||||
<PackageReference Include="Microsoft.Extensions.TaskCache.Sources" Version="$(AspNetCoreVersion)" PrivateAssets="All" />
|
||||
<PackageReference Include="Microsoft.Extensions.WebEncoders" Version="$(AspNetCoreVersion)" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
|
|||
|
|
@ -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
|
||||
{
|
||||
/// <summary>
|
||||
/// Adds the <see cref="FacebookMiddleware"/> middleware to the specified <see cref="IApplicationBuilder"/>, which enables Facebook authentication capabilities.
|
||||
/// Obsolete, see https://go.microsoft.com/fwlink/?linkid=845470
|
||||
/// </summary>
|
||||
/// <param name="app">The <see cref="IApplicationBuilder"/> to add the middleware to.</param>
|
||||
/// <param name="app">The <see cref="IApplicationBuilder"/> to add the handler to.</param>
|
||||
/// <returns>A reference to this instance after the operation has completed.</returns>
|
||||
[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<FacebookMiddleware>();
|
||||
throw new NotSupportedException("This method is no longer supported, see https://go.microsoft.com/fwlink/?linkid=845470");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds the <see cref="FacebookMiddleware"/> middleware to the specified <see cref="IApplicationBuilder"/>, which enables Facebook authentication capabilities.
|
||||
/// Obsolete, see https://go.microsoft.com/fwlink/?linkid=845470
|
||||
/// </summary>
|
||||
/// <param name="app">The <see cref="IApplicationBuilder"/> to add the middleware to.</param>
|
||||
/// <param name="options">A <see cref="FacebookOptions"/> that specifies options for the middleware.</param>
|
||||
/// <param name="app">The <see cref="IApplicationBuilder"/> to add the handler to.</param>
|
||||
/// <param name="options">A <see cref="FacebookOptions"/> that specifies options for the handler.</param>
|
||||
/// <returns>A reference to this instance after the operation has completed.</returns>
|
||||
[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<FacebookMiddleware>(Options.Create(options));
|
||||
throw new NotSupportedException("This method is no longer supported, see https://go.microsoft.com/fwlink/?linkid=845470");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
// 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.Extensions.Configuration;
|
||||
using Microsoft.Extensions.Options;
|
||||
|
||||
namespace Microsoft.AspNetCore.Authentication.Facebook
|
||||
{
|
||||
internal class FacebookConfigureOptions : ConfigureNamedOptions<FacebookOptions>
|
||||
{
|
||||
public FacebookConfigureOptions(IConfiguration config) :
|
||||
base(FacebookDefaults.AuthenticationScheme,
|
||||
options => config.GetSection(FacebookDefaults.AuthenticationScheme).Bind(options))
|
||||
{ }
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
// 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.Extensions.DependencyInjection
|
||||
{
|
||||
public static class FacebookAuthenticationOptionsExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Adds facebook authentication with options bound against the "Facebook" section
|
||||
/// from the IConfiguration in the service container.
|
||||
/// </summary>
|
||||
/// <param name="services"></param>
|
||||
/// <returns></returns>
|
||||
public static IServiceCollection AddFacebookAuthentication(this IServiceCollection services)
|
||||
{
|
||||
services.AddSingleton<IConfigureOptions<FacebookOptions>, FacebookConfigureOptions>();
|
||||
return services.AddFacebookAuthentication(FacebookDefaults.AuthenticationScheme, _ => { });
|
||||
}
|
||||
|
||||
public static IServiceCollection AddFacebookAuthentication(this IServiceCollection services, Action<FacebookOptions> configureOptions)
|
||||
=> services.AddFacebookAuthentication(FacebookDefaults.AuthenticationScheme, configureOptions);
|
||||
|
||||
public static IServiceCollection AddFacebookAuthentication(this IServiceCollection services, string authenticationScheme, Action<FacebookOptions> configureOptions)
|
||||
{
|
||||
return services.AddScheme<FacebookOptions, FacebookHandler>(authenticationScheme, configureOptions);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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<FacebookOptions>
|
||||
{
|
||||
public FacebookHandler(HttpClient httpClient)
|
||||
: base(httpClient)
|
||||
{
|
||||
}
|
||||
public FacebookHandler(IOptions<AuthenticationOptions> sharedOptions, IOptionsSnapshot<FacebookOptions> options, ILoggerFactory logger, UrlEncoder encoder, IDataProtectionProvider dataProtection, ISystemClock clock)
|
||||
: base(sharedOptions, options, logger, encoder, dataProtection, clock)
|
||||
{ }
|
||||
|
||||
protected override async Task<AuthenticationTicket> CreateTicketAsync(ClaimsIdentity identity, AuthenticationProperties properties, OAuthTokenResponse tokens)
|
||||
{
|
||||
|
|
@ -43,11 +43,11 @@ namespace Microsoft.AspNetCore.Authentication.Facebook
|
|||
|
||||
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);
|
||||
await Events.CreatingTicket(context);
|
||||
|
||||
return context.Ticket;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
{
|
||||
/// <summary>
|
||||
/// An ASP.NET Core middleware for authenticating users using Facebook.
|
||||
/// </summary>
|
||||
public class FacebookMiddleware : OAuthMiddleware<FacebookOptions>
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new <see cref="FacebookMiddleware"/>.
|
||||
/// </summary>
|
||||
/// <param name="next">The next middleware in the HTTP pipeline to invoke.</param>
|
||||
/// <param name="dataProtectionProvider"></param>
|
||||
/// <param name="loggerFactory"></param>
|
||||
/// <param name="encoder"></param>
|
||||
/// <param name="sharedOptions"></param>
|
||||
/// <param name="options">Configuration options for the middleware.</param>
|
||||
public FacebookMiddleware(
|
||||
RequestDelegate next,
|
||||
IDataProtectionProvider dataProtectionProvider,
|
||||
ILoggerFactory loggerFactory,
|
||||
UrlEncoder encoder,
|
||||
IOptions<SharedAuthenticationOptions> sharedOptions,
|
||||
IOptions<FacebookOptions> 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)));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Provides the <see cref="AuthenticationHandler{T}"/> object for processing authentication-related requests.
|
||||
/// </summary>
|
||||
/// <returns>An <see cref="AuthenticationHandler{T}"/> configured with the <see cref="FacebookOptions"/> supplied to the constructor.</returns>
|
||||
protected override AuthenticationHandler<FacebookOptions> CreateHandler()
|
||||
{
|
||||
return new FacebookHandler(Backchannel);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
||||
{
|
||||
/// <summary>
|
||||
/// Configuration options for <see cref="FacebookMiddleware"/>.
|
||||
/// Configuration options for <see cref="FacebookHandler"/>.
|
||||
/// </summary>
|
||||
public class FacebookOptions : OAuthOptions
|
||||
{
|
||||
|
|
@ -19,8 +21,6 @@ namespace Microsoft.AspNetCore.Builder
|
|||
/// </summary>
|
||||
public FacebookOptions()
|
||||
{
|
||||
AuthenticationScheme = FacebookDefaults.AuthenticationScheme;
|
||||
DisplayName = AuthenticationScheme;
|
||||
CallbackPath = new PathString("/signin-facebook");
|
||||
SendAppSecretProof = true;
|
||||
AuthorizationEndpoint = FacebookDefaults.AuthorizationEndpoint;
|
||||
|
|
@ -49,6 +49,24 @@ namespace Microsoft.AspNetCore.Builder
|
|||
ClaimActions.MapJsonKey("urn:facebook:timezone", "timezone");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Check that the options are valid. Should throw an exception if things are not ok.
|
||||
/// </summary>
|
||||
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.
|
||||
/// <summary>
|
||||
/// Gets or sets the Facebook-assigned appId.
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@
|
|||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Microsoft.AspNetCore.Authentication.OAuth\Microsoft.AspNetCore.Authentication.OAuth.csproj" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="$(AspNetCoreVersion)" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
|
|||
|
|
@ -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
|
||||
{
|
||||
/// <summary>
|
||||
/// Adds the <see cref="GoogleMiddleware"/> middleware to the specified <see cref="IApplicationBuilder"/>,
|
||||
/// which enables Google authentication capabilities.
|
||||
/// Obsolete, see https://go.microsoft.com/fwlink/?linkid=845470
|
||||
/// </summary>
|
||||
/// <param name="app">The <see cref="IApplicationBuilder"/> to add the middleware to.</param>
|
||||
/// <param name="app">The <see cref="IApplicationBuilder"/> to add the handler to.</param>
|
||||
/// <returns>A reference to this instance after the operation has completed.</returns>
|
||||
public static IApplicationBuilder UseGoogleAuthentication(this IApplicationBuilder app)
|
||||
{
|
||||
if (app == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(app));
|
||||
}
|
||||
|
||||
return app.UseMiddleware<GoogleMiddleware>();
|
||||
throw new NotSupportedException("This method is no longer supported, see https://go.microsoft.com/fwlink/?linkid=845470");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds the <see cref="GoogleMiddleware"/> middleware to the specified <see cref="IApplicationBuilder"/>,
|
||||
/// which enables Google authentication capabilities.
|
||||
/// Obsolete, see https://go.microsoft.com/fwlink/?linkid=845470
|
||||
/// </summary>
|
||||
/// <param name="app">The <see cref="IApplicationBuilder"/> to add the middleware to.</param>
|
||||
/// <param name="options">A <see cref="GoogleOptions"/> that specifies options for the middleware.</param>
|
||||
/// <param name="app">The <see cref="IApplicationBuilder"/> to add the handler to.</param>
|
||||
/// <param name="options">A <see cref="GoogleOptions"/> that specifies options for the handler.</param>
|
||||
/// <returns>A reference to this instance after the operation has completed.</returns>
|
||||
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<GoogleMiddleware>(Options.Create(options));
|
||||
throw new NotSupportedException("This method is no longer supported, see https://go.microsoft.com/fwlink/?linkid=845470");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,16 @@
|
|||
// 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.Extensions.Configuration;
|
||||
using Microsoft.Extensions.Options;
|
||||
|
||||
namespace Microsoft.AspNetCore.Authentication.Google
|
||||
{
|
||||
internal class GoogleConfigureOptions : ConfigureNamedOptions<GoogleOptions>
|
||||
{
|
||||
public GoogleConfigureOptions(IConfiguration config) :
|
||||
base(GoogleDefaults.AuthenticationScheme,
|
||||
options => config.GetSection(GoogleDefaults.AuthenticationScheme).Bind(options))
|
||||
{ }
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
// 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;
|
||||
using Microsoft.Extensions.Options;
|
||||
|
||||
namespace Microsoft.Extensions.DependencyInjection
|
||||
{
|
||||
public static class GoogleExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Adds google authentication with options bound against the "Google" section
|
||||
/// from the IConfiguration in the service container.
|
||||
/// </summary>
|
||||
/// <param name="services"></param>
|
||||
/// <returns></returns>
|
||||
public static IServiceCollection AddGoogleAuthentication(this IServiceCollection services)
|
||||
{
|
||||
services.AddSingleton<IConfigureOptions<GoogleOptions>, GoogleConfigureOptions>();
|
||||
return services.AddGoogleAuthentication(GoogleDefaults.AuthenticationScheme, _ => { });
|
||||
}
|
||||
|
||||
public static IServiceCollection AddGoogleAuthentication(this IServiceCollection services, Action<GoogleOptions> configureOptions)
|
||||
=> services.AddGoogleAuthentication(GoogleDefaults.AuthenticationScheme, configureOptions);
|
||||
|
||||
public static IServiceCollection AddGoogleAuthentication(this IServiceCollection services, string authenticationScheme, Action<GoogleOptions> configureOptions)
|
||||
{
|
||||
return services.AddScheme<GoogleOptions, GoogleHandler>(authenticationScheme, configureOptions);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -6,21 +6,22 @@ using System.Collections.Generic;
|
|||
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<GoogleOptions>
|
||||
{
|
||||
public GoogleHandler(HttpClient httpClient)
|
||||
: base(httpClient)
|
||||
{
|
||||
}
|
||||
public GoogleHandler(IOptions<AuthenticationOptions> sharedOptions, IOptionsSnapshot<GoogleOptions> options, ILoggerFactory logger, UrlEncoder encoder, IDataProtectionProvider dataProtection, ISystemClock clock)
|
||||
: base(sharedOptions, options, logger, encoder, dataProtection, clock)
|
||||
{ }
|
||||
|
||||
protected override async Task<AuthenticationTicket> CreateTicketAsync(
|
||||
ClaimsIdentity identity,
|
||||
|
|
@ -40,11 +41,11 @@ namespace Microsoft.AspNetCore.Authentication.Google
|
|||
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);
|
||||
await Events.CreatingTicket(context);
|
||||
|
||||
return context.Ticket;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
{
|
||||
/// <summary>
|
||||
/// An ASP.NET Core middleware for authenticating users using Google OAuth 2.0.
|
||||
/// </summary>
|
||||
public class GoogleMiddleware : OAuthMiddleware<GoogleOptions>
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new <see cref="GoogleMiddleware"/>.
|
||||
/// </summary>
|
||||
/// <param name="next">The next middleware in the HTTP pipeline to invoke.</param>
|
||||
/// <param name="dataProtectionProvider"></param>
|
||||
/// <param name="loggerFactory"></param>
|
||||
/// <param name="encoder"></param>
|
||||
/// <param name="sharedOptions"></param>
|
||||
/// <param name="options">Configuration options for the middleware.</param>
|
||||
public GoogleMiddleware(
|
||||
RequestDelegate next,
|
||||
IDataProtectionProvider dataProtectionProvider,
|
||||
ILoggerFactory loggerFactory,
|
||||
UrlEncoder encoder,
|
||||
IOptions<SharedAuthenticationOptions> sharedOptions,
|
||||
IOptions<GoogleOptions> 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));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Provides the <see cref="AuthenticationHandler{T}"/> object for processing authentication-related requests.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// An <see cref="AuthenticationHandler{T}"/> configured with the <see cref="GoogleOptions"/>
|
||||
/// supplied to the constructor.
|
||||
/// </returns>
|
||||
protected override AuthenticationHandler<GoogleOptions> CreateHandler()
|
||||
{
|
||||
return new GoogleHandler(Backchannel);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
||||
{
|
||||
/// <summary>
|
||||
/// Configuration options for <see cref="GoogleMiddleware"/>.
|
||||
/// Configuration options for <see cref="GoogleHandler"/>.
|
||||
/// </summary>
|
||||
public class GoogleOptions : OAuthOptions
|
||||
{
|
||||
|
|
@ -18,8 +18,6 @@ namespace Microsoft.AspNetCore.Builder
|
|||
/// </summary>
|
||||
public GoogleOptions()
|
||||
{
|
||||
AuthenticationScheme = GoogleDefaults.AuthenticationScheme;
|
||||
DisplayName = AuthenticationScheme;
|
||||
CallbackPath = new PathString("/signin-google");
|
||||
AuthorizationEndpoint = GoogleDefaults.AuthorizationEndpoint;
|
||||
TokenEndpoint = GoogleDefaults.TokenEndpoint;
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@
|
|||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Microsoft.AspNetCore.Authentication.OAuth\Microsoft.AspNetCore.Authentication.OAuth.csproj" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="$(AspNetCoreVersion)" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,14 +2,13 @@
|
|||
// 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)
|
||||
|
|
@ -17,9 +16,17 @@ namespace Microsoft.AspNetCore.Authentication.JwtBearer
|
|||
throw new ArgumentNullException(nameof(options));
|
||||
}
|
||||
|
||||
if (scheme == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(scheme));
|
||||
}
|
||||
|
||||
Options = options;
|
||||
Scheme = scheme;
|
||||
}
|
||||
|
||||
public JwtBearerOptions Options { get; }
|
||||
|
||||
public AuthenticationScheme Scheme { get; }
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
||||
{
|
||||
/// <summary>
|
||||
/// Specifies events which the <see cref="JwtBearerMiddleware"/> invokes to enable developer control over the authentication process.
|
||||
/// </summary>
|
||||
public interface IJwtBearerEvents
|
||||
{
|
||||
/// <summary>
|
||||
/// Invoked if exceptions are thrown during request processing. The exceptions will be re-thrown after this event unless suppressed.
|
||||
/// </summary>
|
||||
Task AuthenticationFailed(AuthenticationFailedContext context);
|
||||
|
||||
/// <summary>
|
||||
/// Invoked when a protocol message is first received.
|
||||
/// </summary>
|
||||
Task MessageReceived(MessageReceivedContext context);
|
||||
|
||||
/// <summary>
|
||||
/// Invoked after the security token has passed validation and a ClaimsIdentity has been generated.
|
||||
/// </summary>
|
||||
Task TokenValidated(TokenValidatedContext context);
|
||||
|
||||
/// <summary>
|
||||
/// Invoked to apply a challenge sent back to the caller.
|
||||
/// </summary>
|
||||
Task Challenge(JwtBearerChallengeContext context);
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,9 +8,9 @@ using Microsoft.Extensions.Internal;
|
|||
namespace Microsoft.AspNetCore.Authentication.JwtBearer
|
||||
{
|
||||
/// <summary>
|
||||
/// Specifies events which the <see cref="JwtBearerMiddleware"/> invokes to enable developer control over the authentication process.
|
||||
/// Specifies events which the <see cref="JwtBearerHandler"/> invokes to enable developer control over the authentication process.
|
||||
/// </summary>
|
||||
public class JwtBearerEvents : IJwtBearerEvents
|
||||
public class JwtBearerEvents
|
||||
{
|
||||
/// <summary>
|
||||
/// Invoked if exceptions are thrown during request processing. The exceptions will be re-thrown after this event unless suppressed.
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
{
|
||||
/// <summary>
|
||||
/// Adds the <see cref="JwtBearerMiddleware"/> middleware to the specified <see cref="IApplicationBuilder"/>, 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
|
||||
/// </summary>
|
||||
/// <param name="app">The <see cref="IApplicationBuilder"/> to add the middleware to.</param>
|
||||
/// <param name="app">The <see cref="IApplicationBuilder"/> to add the handler to.</param>
|
||||
/// <returns>A reference to this instance after the operation has completed.</returns>
|
||||
[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<JwtBearerMiddleware>();
|
||||
throw new NotSupportedException("This method is no longer supported, see https://go.microsoft.com/fwlink/?linkid=845470");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds the <see cref="JwtBearerMiddleware"/> middleware to the specified <see cref="IApplicationBuilder"/>, 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
|
||||
/// </summary>
|
||||
/// <param name="app">The <see cref="IApplicationBuilder"/> to add the middleware to.</param>
|
||||
/// <param name="options">A <see cref="JwtBearerOptions"/> that specifies options for the middleware.</param>
|
||||
/// <param name="app">The <see cref="IApplicationBuilder"/> to add the handler to.</param>
|
||||
/// <param name="options">A <see cref="JwtBearerOptions"/> that specifies options for the handler.</param>
|
||||
/// <returns>A reference to this instance after the operation has completed.</returns>
|
||||
[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<JwtBearerMiddleware>(Options.Create(options));
|
||||
throw new NotSupportedException("This method is no longer supported, see https://go.microsoft.com/fwlink/?linkid=845470");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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 Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.Options;
|
||||
|
||||
namespace Microsoft.AspNetCore.Authentication.JwtBearer
|
||||
{
|
||||
internal class JwtBearerConfigureOptions : ConfigureNamedOptions<JwtBearerOptions>
|
||||
{
|
||||
// Bind to "Bearer" section by default
|
||||
public JwtBearerConfigureOptions(IConfiguration config) :
|
||||
base(JwtBearerDefaults.AuthenticationScheme,
|
||||
options => config.GetSection(JwtBearerDefaults.AuthenticationScheme).Bind(options))
|
||||
{ }
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
// 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;
|
||||
using Microsoft.Extensions.Options;
|
||||
|
||||
namespace Microsoft.Extensions.DependencyInjection
|
||||
{
|
||||
public static class JwtBearerExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Adds JwtBearer authentication with options bound against the "Bearer" section
|
||||
/// from the IConfiguration in the service container.
|
||||
/// </summary>
|
||||
/// <param name="services"></param>
|
||||
/// <returns></returns>
|
||||
public static IServiceCollection AddJwtBearerAuthentication(this IServiceCollection services)
|
||||
{
|
||||
services.AddSingleton<IConfigureOptions<JwtBearerOptions>, JwtBearerConfigureOptions>();
|
||||
return services.AddJwtBearerAuthentication(JwtBearerDefaults.AuthenticationScheme, _ => { });
|
||||
}
|
||||
|
||||
public static IServiceCollection AddJwtBearerAuthentication(this IServiceCollection services, Action<JwtBearerOptions> configureOptions)
|
||||
=> services.AddJwtBearerAuthentication(JwtBearerDefaults.AuthenticationScheme, configureOptions);
|
||||
|
||||
public static IServiceCollection AddJwtBearerAuthentication(this IServiceCollection services, string authenticationScheme, Action<JwtBearerOptions> configureOptions)
|
||||
{
|
||||
return services.AddScheme<JwtBearerOptions, JwtBearerHandler>(authenticationScheme, configureOptions);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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,65 @@ namespace Microsoft.AspNetCore.Authentication.JwtBearer
|
|||
{
|
||||
private OpenIdConnectConfiguration _configuration;
|
||||
|
||||
public JwtBearerHandler(IOptionsSnapshot<JwtBearerOptions> options, ILoggerFactory logger, UrlEncoder encoder, IDataProtectionProvider dataProtection, ISystemClock clock)
|
||||
: base(options, logger, encoder, clock)
|
||||
{ }
|
||||
|
||||
/// <summary>
|
||||
/// 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.
|
||||
/// </summary>
|
||||
protected new JwtBearerEvents Events
|
||||
{
|
||||
get { return (JwtBearerEvents)base.Events; }
|
||||
set { base.Events = value; }
|
||||
}
|
||||
|
||||
protected override Task<object> CreateEventsAsync() => Task.FromResult<object>(new JwtBearerEvents());
|
||||
|
||||
protected override void InitializeOptions()
|
||||
{
|
||||
base.InitializeOptions();
|
||||
|
||||
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<OpenIdConnectConfiguration>(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<OpenIdConnectConfiguration>(Options.MetadataAddress, new OpenIdConnectConfigurationRetriever(),
|
||||
new HttpDocumentRetriever(httpClient) { RequireHttps = Options.RequireHttpsMetadata });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Searches the 'Authorization' header for a 'Bearer' token. If the 'Bearer' token is found, it is validated using <see cref="TokenValidationParameters"/> set in the options.
|
||||
/// </summary>
|
||||
|
|
@ -33,11 +94,11 @@ namespace Microsoft.AspNetCore.Authentication.JwtBearer
|
|||
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.IsProcessingComplete(out result))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
|
@ -52,7 +113,7 @@ namespace Microsoft.AspNetCore.Authentication.JwtBearer
|
|||
// 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 +124,7 @@ namespace Microsoft.AspNetCore.Authentication.JwtBearer
|
|||
// If no token found, no further work possible
|
||||
if (string.IsNullOrEmpty(token))
|
||||
{
|
||||
return AuthenticateResult.Skip();
|
||||
return AuthenticateResult.None();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -120,15 +181,15 @@ namespace Microsoft.AspNetCore.Authentication.JwtBearer
|
|||
|
||||
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.IsProcessingComplete(out result))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
|
@ -148,13 +209,13 @@ namespace Microsoft.AspNetCore.Authentication.JwtBearer
|
|||
|
||||
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.IsProcessingComplete(out result))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
|
@ -168,13 +229,13 @@ namespace Microsoft.AspNetCore.Authentication.JwtBearer
|
|||
{
|
||||
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.IsProcessingComplete(out result))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
|
@ -183,11 +244,10 @@ namespace Microsoft.AspNetCore.Authentication.JwtBearer
|
|||
}
|
||||
}
|
||||
|
||||
protected override async Task<bool> 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 +259,10 @@ namespace Microsoft.AspNetCore.Authentication.JwtBearer
|
|||
eventContext.ErrorDescription = CreateErrorDescription(eventContext.AuthenticateFailure);
|
||||
}
|
||||
|
||||
await Options.Events.Challenge(eventContext);
|
||||
if (eventContext.HandledResponse)
|
||||
await Events.Challenge(eventContext);
|
||||
if (eventContext.IsProcessingComplete(out var ignored))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if (eventContext.Skipped)
|
||||
{
|
||||
return false;
|
||||
return;
|
||||
}
|
||||
|
||||
Response.StatusCode = 401;
|
||||
|
|
@ -259,8 +315,6 @@ namespace Microsoft.AspNetCore.Authentication.JwtBearer
|
|||
|
||||
Response.Headers.Append(HeaderNames.WWWAuthenticate, builder.ToString());
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private static string CreateErrorDescription(Exception authFailure)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
{
|
||||
/// <summary>
|
||||
/// 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.
|
||||
/// </summary>
|
||||
public class JwtBearerMiddleware : AuthenticationMiddleware<JwtBearerOptions>
|
||||
{
|
||||
/// <summary>
|
||||
/// 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.
|
||||
/// </summary>
|
||||
public JwtBearerMiddleware(
|
||||
RequestDelegate next,
|
||||
ILoggerFactory loggerFactory,
|
||||
UrlEncoder encoder,
|
||||
IOptions<JwtBearerOptions> 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<OpenIdConnectConfiguration>(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<OpenIdConnectConfiguration>(Options.MetadataAddress, new OpenIdConnectConfigurationRetriever(),
|
||||
new HttpDocumentRetriever(httpClient) { RequireHttps = Options.RequireHttpsMetadata });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Called by the AuthenticationMiddleware base class to create a per-request handler.
|
||||
/// </summary>
|
||||
/// <returns>A new instance of the request handler</returns>
|
||||
protected override AuthenticationHandler<JwtBearerOptions> CreateHandler()
|
||||
{
|
||||
return new JwtBearerHandler();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
||||
{
|
||||
/// <summary>
|
||||
/// Options class provides information needed to control Bearer Authentication middleware behavior
|
||||
/// Options class provides information needed to control Bearer Authentication handler behavior
|
||||
/// </summary>
|
||||
public class JwtBearerOptions : AuthenticationOptions
|
||||
public class JwtBearerOptions : AuthenticationSchemeOptions
|
||||
{
|
||||
/// <summary>
|
||||
/// Creates an instance of bearer authentication options with default values.
|
||||
/// </summary>
|
||||
public JwtBearerOptions() : base()
|
||||
{
|
||||
AuthenticationScheme = JwtBearerDefaults.AuthenticationScheme;
|
||||
AutomaticAuthenticate = true;
|
||||
AutomaticChallenge = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 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.
|
||||
|
|
@ -59,11 +46,15 @@ namespace Microsoft.AspNetCore.Builder
|
|||
public string Challenge { get; set; } = JwtBearerDefaults.AuthenticationScheme;
|
||||
|
||||
/// <summary>
|
||||
/// The object provided by the application to process events raised by the bearer authentication middleware.
|
||||
/// The object provided by the application to process events raised by the bearer authentication handler.
|
||||
/// 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.
|
||||
/// </summary>
|
||||
public IJwtBearerEvents Events { get; set; } = new JwtBearerEvents();
|
||||
public new JwtBearerEvents Events
|
||||
{
|
||||
get { return (JwtBearerEvents)base.Events; }
|
||||
set { base.Events = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The HttpMessageHandler used to retrieve metadata.
|
||||
|
|
@ -115,7 +106,7 @@ namespace Microsoft.AspNetCore.Builder
|
|||
|
||||
/// <summary>
|
||||
/// Defines whether the token validation errors should be returned to the caller.
|
||||
/// Enabled by default, this option can be disabled to prevent the JWT middleware
|
||||
/// Enabled by default, this option can be disabled to prevent the JWT handler
|
||||
/// from returning an error and an error_description in the WWW-Authenticate header.
|
||||
/// </summary>
|
||||
public bool IncludeErrorDetails { get; set; } = true;
|
||||
|
|
|
|||
|
|
@ -9,8 +9,9 @@
|
|||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Microsoft.AspNetCore.Authentication\Microsoft.AspNetCore.Authentication.csproj" />
|
||||
<PackageReference Include="Microsoft.Extensions.TaskCache.Sources" Version="$(AspNetCoreVersion)" PrivateAssets="All" />
|
||||
<PackageReference Include="Microsoft.IdentityModel.Protocols.OpenIdConnect" Version="$(IdentityModelOpenIdVersion)" />
|
||||
<PackageReference Include="System.Security.Claims" Version="$(CoreFxVersion)" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="$(AspNetCoreVersion)" />
|
||||
<PackageReference Include="Microsoft.Extensions.TaskCache.Sources" Version="$(AspNetCoreVersion)" PrivateAssets="All" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@
|
|||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Microsoft.AspNetCore.Authentication.OAuth\Microsoft.AspNetCore.Authentication.OAuth.csproj" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="$(AspNetCoreVersion)" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
|
|||
|
|
@ -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
|
||||
{
|
||||
/// <summary>
|
||||
/// Adds the <see cref="MicrosoftAccountMiddleware"/> middleware to the specified <see cref="IApplicationBuilder"/>, which enables Microsoft Account authentication capabilities.
|
||||
/// Obsolete, see https://go.microsoft.com/fwlink/?linkid=845470
|
||||
/// </summary>
|
||||
/// <param name="app">The <see cref="IApplicationBuilder"/> to add the middleware to.</param>
|
||||
/// <param name="app">The <see cref="IApplicationBuilder"/> to add the handler to.</param>
|
||||
/// <returns>A reference to this instance after the operation has completed.</returns>
|
||||
[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<MicrosoftAccountMiddleware>();
|
||||
throw new NotSupportedException("This method is no longer supported, see https://go.microsoft.com/fwlink/?linkid=845470");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds the <see cref="MicrosoftAccountMiddleware"/> middleware to the specified <see cref="IApplicationBuilder"/>, which enables Microsoft Account authentication capabilities.
|
||||
/// Obsolete, see https://go.microsoft.com/fwlink/?linkid=845470
|
||||
/// </summary>
|
||||
/// <param name="app">The <see cref="IApplicationBuilder"/> to add the middleware to.</param>
|
||||
/// <param name="options">A <see cref="MicrosoftAccountOptions"/> that specifies options for the middleware.</param>
|
||||
/// <param name="app">The <see cref="IApplicationBuilder"/> to add the handler to.</param>
|
||||
/// <param name="options">A <see cref="MicrosoftAccountOptions"/> that specifies options for the handler.</param>
|
||||
/// <returns>A reference to this instance after the operation has completed.</returns>
|
||||
[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<MicrosoftAccountMiddleware>(Options.Create(options));
|
||||
throw new NotSupportedException("This method is no longer supported, see https://go.microsoft.com/fwlink/?linkid=845470");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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 Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.Options;
|
||||
|
||||
namespace Microsoft.AspNetCore.Authentication.MicrosoftAccount
|
||||
{
|
||||
internal class MicrosoftAccountConfigureOptions : ConfigureNamedOptions<MicrosoftAccountOptions>
|
||||
{
|
||||
// Bind to "Microsoft" section by default
|
||||
public MicrosoftAccountConfigureOptions(IConfiguration config) :
|
||||
base(MicrosoftAccountDefaults.AuthenticationScheme,
|
||||
options => config.GetSection(MicrosoftAccountDefaults.AuthenticationScheme).Bind(options))
|
||||
{ }
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
// 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.Extensions.DependencyInjection
|
||||
{
|
||||
public static class MicrosoftAccountExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Adds MicrosoftAccount authentication with options bound against the "Microsoft" section
|
||||
/// from the IConfiguration in the service container.
|
||||
/// </summary>
|
||||
/// <param name="services"></param>
|
||||
/// <returns></returns>
|
||||
public static IServiceCollection AddMicrosoftAccountAuthentication(this IServiceCollection services)
|
||||
{
|
||||
services.AddSingleton<IConfigureOptions<MicrosoftAccountOptions>, MicrosoftAccountConfigureOptions>();
|
||||
return services.AddMicrosoftAccountAuthentication(MicrosoftAccountDefaults.AuthenticationScheme, o => { });
|
||||
}
|
||||
|
||||
public static IServiceCollection AddMicrosoftAccountAuthentication(this IServiceCollection services, Action<MicrosoftAccountOptions> configureOptions) =>
|
||||
services.AddMicrosoftAccountAuthentication(MicrosoftAccountDefaults.AuthenticationScheme, configureOptions);
|
||||
|
||||
public static IServiceCollection AddMicrosoftAccountAuthentication(this IServiceCollection services, string authenticationScheme, Action<MicrosoftAccountOptions> configureOptions)
|
||||
{
|
||||
return services.AddScheme<MicrosoftAccountOptions, MicrosoftAccountHandler>(authenticationScheme, configureOptions);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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<MicrosoftAccountOptions>
|
||||
{
|
||||
public MicrosoftAccountHandler(HttpClient httpClient)
|
||||
: base(httpClient)
|
||||
{
|
||||
}
|
||||
public MicrosoftAccountHandler(IOptions<AuthenticationOptions> sharedOptions, IOptionsSnapshot<MicrosoftAccountOptions> options, ILoggerFactory logger, UrlEncoder encoder, IDataProtectionProvider dataProtection, ISystemClock clock)
|
||||
: base(sharedOptions, options, logger, encoder, dataProtection, clock)
|
||||
{ }
|
||||
|
||||
protected override async Task<AuthenticationTicket> CreateTicketAsync(ClaimsIdentity identity, AuthenticationProperties properties, OAuthTokenResponse tokens)
|
||||
{
|
||||
|
|
@ -33,11 +33,11 @@ namespace Microsoft.AspNetCore.Authentication.MicrosoftAccount
|
|||
|
||||
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);
|
||||
await Events.CreatingTicket(context);
|
||||
return context.Ticket;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
{
|
||||
/// <summary>
|
||||
/// An ASP.NET Core middleware for authenticating users using the Microsoft Account service.
|
||||
/// </summary>
|
||||
public class MicrosoftAccountMiddleware : OAuthMiddleware<MicrosoftAccountOptions>
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new <see cref="MicrosoftAccountMiddleware"/>.
|
||||
/// </summary>
|
||||
/// <param name="next">The next middleware in the HTTP pipeline to invoke.</param>
|
||||
/// <param name="dataProtectionProvider"></param>
|
||||
/// <param name="loggerFactory"></param>
|
||||
/// <param name="encoder"></param>
|
||||
/// <param name="sharedOptions"></param>
|
||||
/// <param name="options">Configuration options for the middleware.</param>
|
||||
public MicrosoftAccountMiddleware(
|
||||
RequestDelegate next,
|
||||
IDataProtectionProvider dataProtectionProvider,
|
||||
ILoggerFactory loggerFactory,
|
||||
UrlEncoder encoder,
|
||||
IOptions<SharedAuthenticationOptions> sharedOptions,
|
||||
IOptions<MicrosoftAccountOptions> 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));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Provides the <see cref="AuthenticationHandler{T}"/> object for processing authentication-related requests.
|
||||
/// </summary>
|
||||
/// <returns>An <see cref="AuthenticationHandler{T}"/> configured with the <see cref="MicrosoftAccountOptions"/> supplied to the constructor.</returns>
|
||||
protected override AuthenticationHandler<MicrosoftAccountOptions> CreateHandler()
|
||||
{
|
||||
return new MicrosoftAccountHandler(Backchannel);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -5,11 +5,12 @@ using System.Security.Claims;
|
|||
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
|
||||
{
|
||||
/// <summary>
|
||||
/// Configuration options for <see cref="MicrosoftAccountMiddleware"/>.
|
||||
/// Configuration options for <see cref="MicrosoftAccountHandler"/>.
|
||||
/// </summary>
|
||||
public class MicrosoftAccountOptions : OAuthOptions
|
||||
{
|
||||
|
|
@ -18,8 +19,6 @@ namespace Microsoft.AspNetCore.Builder
|
|||
/// </summary>
|
||||
public MicrosoftAccountOptions()
|
||||
{
|
||||
AuthenticationScheme = MicrosoftAccountDefaults.AuthenticationScheme;
|
||||
DisplayName = AuthenticationScheme;
|
||||
CallbackPath = new PathString("/signin-microsoft");
|
||||
AuthorizationEndpoint = MicrosoftAccountDefaults.AuthorizationEndpoint;
|
||||
TokenEndpoint = MicrosoftAccountDefaults.TokenEndpoint;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
{
|
||||
/// <summary>
|
||||
/// Specifies callback methods which the <see cref="OAuthMiddleware{T}"/> invokes to enable developer control over the authentication process.
|
||||
/// </summary>
|
||||
public interface IOAuthEvents : IRemoteAuthenticationEvents
|
||||
{
|
||||
/// <summary>
|
||||
/// 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.
|
||||
/// </summary>
|
||||
/// <param name="context">Contains information about the login session.</param>
|
||||
/// <returns>A <see cref="Task"/> representing the completed operation.</returns>
|
||||
Task CreatingTicket(OAuthCreatingTicketContext context);
|
||||
|
||||
/// <summary>
|
||||
/// Called when a Challenge causes a redirect to the authorize endpoint.
|
||||
/// </summary>
|
||||
/// <param name="context">Contains redirect URI and <see cref="Http.Authentication.AuthenticationProperties"/> of the challenge.</param>
|
||||
Task RedirectToAuthorizationEndpoint(OAuthRedirectToAuthorizationContext context);
|
||||
}
|
||||
}
|
||||
|
|
@ -5,7 +5,6 @@ using System;
|
|||
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
|
|||
/// <summary>
|
||||
/// Contains information about the login session as well as the user <see cref="System.Security.Claims.ClaimsIdentity"/>.
|
||||
/// </summary>
|
||||
public class OAuthCreatingTicketContext : BaseContext
|
||||
public class OAuthCreatingTicketContext : BaseAuthenticationContext
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new <see cref="OAuthCreatingTicketContext"/>.
|
||||
/// </summary>
|
||||
/// <param name="ticket">The <see cref="AuthenticationTicket"/>.</param>
|
||||
/// <param name="context">The HTTP environment.</param>
|
||||
/// <param name="scheme">The authentication scheme.</param>
|
||||
/// <param name="options">The options used by the authentication middleware.</param>
|
||||
/// <param name="backchannel">The HTTP client used by the authentication middleware</param>
|
||||
/// <param name="tokens">The tokens returned from the token endpoint.</param>
|
||||
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 @@ namespace Microsoft.AspNetCore.Authentication.OAuth
|
|||
/// </summary>
|
||||
/// <param name="ticket">The <see cref="AuthenticationTicket"/>.</param>
|
||||
/// <param name="context">The HTTP environment.</param>
|
||||
/// <param name="scheme">The authentication scheme.</param>
|
||||
/// <param name="options">The options used by the authentication middleware.</param>
|
||||
/// <param name="backchannel">The HTTP client used by the authentication middleware</param>
|
||||
/// <param name="tokens">The tokens returned from the token endpoint.</param>
|
||||
|
|
@ -46,11 +48,12 @@ namespace Microsoft.AspNetCore.Authentication.OAuth
|
|||
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)
|
||||
{
|
||||
|
|
@ -77,15 +80,23 @@ namespace Microsoft.AspNetCore.Authentication.OAuth
|
|||
throw new ArgumentNullException(nameof(user));
|
||||
}
|
||||
|
||||
if (scheme == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(scheme));
|
||||
}
|
||||
|
||||
TokenResponse = tokens;
|
||||
Backchannel = backchannel;
|
||||
User = user;
|
||||
Options = options;
|
||||
Scheme = scheme;
|
||||
Ticket = ticket;
|
||||
}
|
||||
|
||||
public OAuthOptions Options { get; }
|
||||
|
||||
public AuthenticationScheme Scheme { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the JSON-serialized user or an empty
|
||||
/// <see cref="JObject"/> if it is not available.
|
||||
|
|
|
|||
|
|
@ -8,9 +8,9 @@ using Microsoft.Extensions.Internal;
|
|||
namespace Microsoft.AspNetCore.Authentication.OAuth
|
||||
{
|
||||
/// <summary>
|
||||
/// Default <see cref="IOAuthEvents"/> implementation.
|
||||
/// Default implementation.
|
||||
/// </summary>
|
||||
public class OAuthEvents : RemoteAuthenticationEvents, IOAuthEvents
|
||||
public class OAuthEvents : RemoteAuthenticationEvents
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the function that is invoked when the CreatingTicket method is invoked.
|
||||
|
|
@ -34,7 +34,7 @@ namespace Microsoft.AspNetCore.Authentication.OAuth
|
|||
public virtual Task CreatingTicket(OAuthCreatingTicketContext context) => OnCreatingTicket(context);
|
||||
|
||||
/// <summary>
|
||||
/// Called when a Challenge causes a redirect to authorize endpoint in the OAuth middleware.
|
||||
/// Called when a Challenge causes a redirect to authorize endpoint in the OAuth handler.
|
||||
/// </summary>
|
||||
/// <param name="context">Contains redirect URI and <see cref="Http.Authentication.AuthenticationProperties"/> of the challenge.</param>
|
||||
public virtual Task RedirectToAuthorizationEndpoint(OAuthRedirectToAuthorizationContext context) => OnRedirectToAuthorizationEndpoint(context);
|
||||
|
|
|
|||
|
|
@ -3,12 +3,11 @@
|
|||
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Http.Authentication;
|
||||
|
||||
namespace Microsoft.AspNetCore.Authentication.OAuth
|
||||
{
|
||||
/// <summary>
|
||||
/// Context passed when a Challenge causes a redirect to authorize endpoint in the middleware.
|
||||
/// Context passed when a Challenge causes a redirect to authorize endpoint in the handler.
|
||||
/// </summary>
|
||||
public class OAuthRedirectToAuthorizationContext : BaseContext
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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
|
||||
{
|
||||
/// <summary>
|
||||
/// Adds the <see cref="OAuthMiddleware{TOptions}"/> middleware to the specified <see cref="IApplicationBuilder"/>, which enables OAuth 2.0 authentication capabilities.
|
||||
/// Obsolete, see https://go.microsoft.com/fwlink/?linkid=845470
|
||||
/// </summary>
|
||||
/// <param name="app">The <see cref="IApplicationBuilder"/> to add the middleware to.</param>
|
||||
/// <param name="app">The <see cref="IApplicationBuilder"/> to add the handler to.</param>
|
||||
/// <returns>A reference to this instance after the operation has completed.</returns>
|
||||
[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<OAuthMiddleware<OAuthOptions>>();
|
||||
throw new NotSupportedException("This method is no longer supported, see https://go.microsoft.com/fwlink/?linkid=845470");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds the <see cref="OAuthMiddleware{TOptions}"/> middleware to the specified <see cref="IApplicationBuilder"/>, which enables OAuth 2.0 authentication capabilities.
|
||||
/// Obsolete, see https://go.microsoft.com/fwlink/?linkid=845470
|
||||
/// </summary>
|
||||
/// <param name="app">The <see cref="IApplicationBuilder"/> to add the middleware to.</param>
|
||||
/// <param name="options">A <see cref="OAuthOptions"/> that specifies options for the middleware.</param>
|
||||
/// <param name="app">The <see cref="IApplicationBuilder"/> to add the handler to.</param>
|
||||
/// <param name="options">A <see cref="OAuthOptions"/> that specifies options for the handler.</param>
|
||||
/// <returns>A reference to this instance after the operation has completed.</returns>
|
||||
[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<OAuthMiddleware<OAuthOptions>>(Options.Create(options));
|
||||
throw new NotSupportedException("This method is no longer supported, see https://go.microsoft.com/fwlink/?linkid=845470");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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<OAuthOptions> configureOptions) =>
|
||||
services.AddScheme<OAuthOptions, OAuthHandler<OAuthOptions>>(authenticationScheme, configureOptions);
|
||||
}
|
||||
}
|
||||
|
|
@ -8,24 +8,60 @@ using System.Net.Http;
|
|||
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.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<TOptions> : RemoteAuthenticationHandler<TOptions> where TOptions : OAuthOptions
|
||||
public class OAuthHandler<TOptions> : RemoteAuthenticationHandler<TOptions> where TOptions : OAuthOptions, new()
|
||||
{
|
||||
public OAuthHandler(HttpClient backchannel)
|
||||
protected HttpClient Backchannel => Options.Backchannel;
|
||||
|
||||
/// <summary>
|
||||
/// 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.
|
||||
/// </summary>
|
||||
protected new OAuthEvents Events
|
||||
{
|
||||
Backchannel = backchannel;
|
||||
get { return (OAuthEvents)base.Events; }
|
||||
set { base.Events = value; }
|
||||
}
|
||||
|
||||
protected HttpClient Backchannel { get; private set; }
|
||||
public OAuthHandler(IOptions<AuthenticationOptions> sharedOptions, IOptionsSnapshot<TOptions> options, ILoggerFactory logger, UrlEncoder encoder, IDataProtectionProvider dataProtection, ISystemClock clock)
|
||||
: base(sharedOptions, options, dataProtection, logger, encoder, clock)
|
||||
{ }
|
||||
|
||||
protected override void InitializeOptions()
|
||||
{
|
||||
base.InitializeOptions();
|
||||
|
||||
if (Options.Backchannel == null)
|
||||
{
|
||||
Options.Backchannel = new HttpClient(Options.BackchannelHttpHandler ?? new HttpClientHandler());
|
||||
Options.Backchannel.DefaultRequestHeaders.UserAgent.ParseAdd("Microsoft ASP.NET Core OAuth handler");
|
||||
Options.Backchannel.Timeout = Options.BackchannelTimeout;
|
||||
Options.Backchannel.MaxResponseContentBufferSize = 1024 * 1024 * 10; // 10 MB
|
||||
}
|
||||
|
||||
if (Options.StateDataFormat == null)
|
||||
{
|
||||
var dataProtector = DataProtection.CreateProtector(
|
||||
GetType().FullName, Scheme.Name, "v1");
|
||||
Options.StateDataFormat = new PropertiesDataFormat(dataProtector);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of the events instance.
|
||||
/// </summary>
|
||||
/// <returns>A new instance of the events instance.</returns>
|
||||
protected override Task<object> CreateEventsAsync() => Task.FromResult<object>(new OAuthEvents());
|
||||
|
||||
protected override async Task<AuthenticateResult> HandleRemoteAuthenticateAsync()
|
||||
{
|
||||
|
|
@ -107,7 +143,7 @@ namespace Microsoft.AspNetCore.Authentication.OAuth
|
|||
{
|
||||
// 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 +206,20 @@ namespace Microsoft.AspNetCore.Authentication.OAuth
|
|||
|
||||
protected virtual async Task<AuthenticationTicket> 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<bool> 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 +232,7 @@ namespace Microsoft.AspNetCore.Authentication.OAuth
|
|||
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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
{
|
||||
/// <summary>
|
||||
/// An ASP.NET Core middleware for authenticating users using OAuth services.
|
||||
/// </summary>
|
||||
public class OAuthMiddleware<TOptions> : AuthenticationMiddleware<TOptions> where TOptions : OAuthOptions, new()
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new <see cref="OAuthMiddleware{T}"/>.
|
||||
/// </summary>
|
||||
/// <param name="next">The next middleware in the HTTP pipeline to invoke.</param>
|
||||
/// <param name="dataProtectionProvider"></param>
|
||||
/// <param name="loggerFactory"></param>
|
||||
/// <param name="encoder">The <see cref="UrlEncoder"/>.</param>
|
||||
/// <param name="sharedOptions">The <see cref="SharedAuthenticationOptions"/> configuration options for this middleware.</param>
|
||||
/// <param name="options">Configuration options for the middleware.</param>
|
||||
public OAuthMiddleware(
|
||||
RequestDelegate next,
|
||||
IDataProtectionProvider dataProtectionProvider,
|
||||
ILoggerFactory loggerFactory,
|
||||
UrlEncoder encoder,
|
||||
IOptions<SharedAuthenticationOptions> sharedOptions,
|
||||
IOptions<TOptions> 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; }
|
||||
|
||||
/// <summary>
|
||||
/// Provides the <see cref="AuthenticationHandler{T}"/> object for processing authentication-related requests.
|
||||
/// </summary>
|
||||
/// <returns>An <see cref="AuthenticationHandler{T}"/> configured with the <see cref="OAuthOptions"/> supplied to the constructor.</returns>
|
||||
protected override AuthenticationHandler<TOptions> CreateHandler()
|
||||
{
|
||||
return new OAuthHandler<TOptions>(Backchannel);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
||||
{
|
||||
/// <summary>
|
||||
/// Configuration options for <see cref="OAuthMiddleware{T}"/>.
|
||||
/// Configuration options OAuth.
|
||||
/// </summary>
|
||||
public class OAuthOptions : RemoteAuthenticationOptions
|
||||
{
|
||||
|
|
@ -19,6 +21,39 @@ namespace Microsoft.AspNetCore.Builder
|
|||
Events = new OAuthEvents();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Check that the options are valid. Should throw an exception if things are not ok.
|
||||
/// </summary>
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the provider-assigned client id.
|
||||
/// </summary>
|
||||
|
|
@ -47,11 +82,11 @@ namespace Microsoft.AspNetCore.Builder
|
|||
public string UserInformationEndpoint { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the <see cref="IOAuthEvents"/> used to handle authentication events.
|
||||
/// Gets or sets the <see cref="OAuthEvents"/> used to handle authentication events.
|
||||
/// </summary>
|
||||
public new IOAuthEvents Events
|
||||
public new OAuthEvents Events
|
||||
{
|
||||
get { return (IOAuthEvents)base.Events; }
|
||||
get { return (OAuthEvents)base.Events; }
|
||||
set { base.Events = value; }
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -18,8 +18,8 @@ namespace Microsoft.AspNetCore.Authentication.OpenIdConnect
|
|||
/// <summary>
|
||||
/// Creates a <see cref="AuthorizationCodeReceivedContext"/>
|
||||
/// </summary>
|
||||
public AuthorizationCodeReceivedContext(HttpContext context, OpenIdConnectOptions options)
|
||||
: base(context, options)
|
||||
public AuthorizationCodeReceivedContext(HttpContext context, AuthenticationScheme scheme, OpenIdConnectOptions options)
|
||||
: base(context, scheme, options)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -42,23 +42,23 @@ namespace Microsoft.AspNetCore.Authentication.OpenIdConnect
|
|||
|
||||
/// <summary>
|
||||
/// If the developer chooses to redeem the code themselves then they can provide the resulting tokens here. This is the
|
||||
/// same as calling HandleCodeRedemption. If set then the middleware will not attempt to redeem the code. An IdToken
|
||||
/// same as calling HandleCodeRedemption. If set then the handler will not attempt to redeem the code. An IdToken
|
||||
/// is required if one had not been previously received in the authorization response. An access token is optional
|
||||
/// if the middleware is to contact the user-info endpoint.
|
||||
/// if the handler is to contact the user-info endpoint.
|
||||
/// </summary>
|
||||
public OpenIdConnectMessage TokenEndpointResponse { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates if the developer choose to handle (or skip) the code redemption. If true then the middleware will not attempt
|
||||
/// Indicates if the developer choose to handle (or skip) the code redemption. If true then the handler will not attempt
|
||||
/// to redeem the code. See HandleCodeRedemption and TokenEndpointResponse.
|
||||
/// </summary>
|
||||
public bool HandledCodeRedemption => TokenEndpointResponse != null;
|
||||
|
||||
/// <summary>
|
||||
/// Tells the middleware to skip the code redemption process. The developer may have redeemed the code themselves, or
|
||||
/// Tells the handler to skip the code redemption process. The developer may have redeemed the code themselves, or
|
||||
/// decided that the redemption was not required. If tokens were retrieved that are needed for further processing then
|
||||
/// call one of the overloads that allows providing tokens. An IdToken is required if one had not been previously received
|
||||
/// in the authorization response. An access token can optionally be provided for the middleware to contact the
|
||||
/// in the authorization response. An access token can optionally be provided for the handler to contact the
|
||||
/// user-info endpoint. Calling this is the same as setting TokenEndpointResponse.
|
||||
/// </summary>
|
||||
public void HandleCodeRedemption()
|
||||
|
|
@ -67,10 +67,10 @@ namespace Microsoft.AspNetCore.Authentication.OpenIdConnect
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tells the middleware to skip the code redemption process. The developer may have redeemed the code themselves, or
|
||||
/// Tells the handler to skip the code redemption process. The developer may have redeemed the code themselves, or
|
||||
/// decided that the redemption was not required. If tokens were retrieved that are needed for further processing then
|
||||
/// call one of the overloads that allows providing tokens. An IdToken is required if one had not been previously received
|
||||
/// in the authorization response. An access token can optionally be provided for the middleware to contact the
|
||||
/// in the authorization response. An access token can optionally be provided for the handler to contact the
|
||||
/// user-info endpoint. Calling this is the same as setting TokenEndpointResponse.
|
||||
/// </summary>
|
||||
public void HandleCodeRedemption(string accessToken, string idToken)
|
||||
|
|
@ -79,10 +79,10 @@ namespace Microsoft.AspNetCore.Authentication.OpenIdConnect
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tells the middleware to skip the code redemption process. The developer may have redeemed the code themselves, or
|
||||
/// Tells the handler to skip the code redemption process. The developer may have redeemed the code themselves, or
|
||||
/// decided that the redemption was not required. If tokens were retrieved that are needed for further processing then
|
||||
/// call one of the overloads that allows providing tokens. An IdToken is required if one had not been previously received
|
||||
/// in the authorization response. An access token can optionally be provided for the middleware to contact the
|
||||
/// in the authorization response. An access token can optionally be provided for the handler to contact the
|
||||
/// user-info endpoint. Calling this is the same as setting TokenEndpointResponse.
|
||||
/// </summary>
|
||||
public void HandleCodeRedemption(OpenIdConnectMessage tokenEndpointResponse)
|
||||
|
|
|
|||
|
|
@ -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; }
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
||||
{
|
||||
/// <summary>
|
||||
/// Specifies events which the <see cref="OpenIdConnectMiddleware" />invokes to enable developer control over the authentication process.
|
||||
/// </summary>
|
||||
public interface IOpenIdConnectEvents : IRemoteAuthenticationEvents
|
||||
{
|
||||
/// <summary>
|
||||
/// Invoked if exceptions are thrown during request processing. The exceptions will be re-thrown after this event unless suppressed.
|
||||
/// </summary>
|
||||
Task AuthenticationFailed(AuthenticationFailedContext context);
|
||||
|
||||
/// <summary>
|
||||
/// Invoked after security token validation if an authorization code is present in the protocol message.
|
||||
/// </summary>
|
||||
Task AuthorizationCodeReceived(AuthorizationCodeReceivedContext context);
|
||||
|
||||
/// <summary>
|
||||
/// Invoked when a protocol message is first received.
|
||||
/// </summary>
|
||||
Task MessageReceived(MessageReceivedContext context);
|
||||
|
||||
/// <summary>
|
||||
/// Invoked before redirecting to the identity provider to authenticate.
|
||||
/// </summary>
|
||||
Task RedirectToIdentityProvider(RedirectContext context);
|
||||
|
||||
/// <summary>
|
||||
/// Invoked before redirecting to the identity provider to sign out.
|
||||
/// </summary>
|
||||
Task RedirectToIdentityProviderForSignOut(RedirectContext context);
|
||||
|
||||
/// <summary>
|
||||
/// Invoked when a request is received on the RemoteSignOutPath.
|
||||
/// </summary>
|
||||
Task RemoteSignOut(RemoteSignOutContext context);
|
||||
|
||||
/// <summary>
|
||||
/// Invoked after "authorization code" is redeemed for tokens at the token endpoint.
|
||||
/// </summary>
|
||||
Task TokenResponseReceived(TokenResponseReceivedContext context);
|
||||
|
||||
/// <summary>
|
||||
/// Invoked when an IdToken has been validated and produced an AuthenticationTicket.
|
||||
/// </summary>
|
||||
Task TokenValidated(TokenValidatedContext context);
|
||||
|
||||
/// <summary>
|
||||
/// Invoked when user information is retrieved from the UserInfoEndpoint.
|
||||
/// </summary>
|
||||
Task UserInformationReceived(UserInformationReceivedContext context);
|
||||
}
|
||||
}
|
||||
|
|
@ -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)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -8,9 +8,9 @@ using Microsoft.Extensions.Internal;
|
|||
namespace Microsoft.AspNetCore.Authentication.OpenIdConnect
|
||||
{
|
||||
/// <summary>
|
||||
/// Specifies events which the <see cref="OpenIdConnectMiddleware" />invokes to enable developer control over the authentication process.
|
||||
/// Specifies events which the <see cref="OpenIdConnectHandler" />invokes to enable developer control over the authentication process.
|
||||
/// </summary>
|
||||
public class OpenIdConnectEvents : RemoteAuthenticationEvents, IOpenIdConnectEvents
|
||||
public class OpenIdConnectEvents : RemoteAuthenticationEvents
|
||||
{
|
||||
/// <summary>
|
||||
/// Invoked if exceptions are thrown during request processing. The exceptions will be re-thrown after this event unless suppressed.
|
||||
|
|
|
|||
|
|
@ -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
|
||||
{
|
||||
/// <summary>
|
||||
/// When a user configures the <see cref="OpenIdConnectMiddleware"/> to be notified prior to redirecting to an IdentityProvider
|
||||
/// When a user configures the <see cref="OpenIdConnectHandler"/> to be notified prior to redirecting to an IdentityProvider
|
||||
/// an instance of <see cref="RedirectContext"/> is passed to the 'RedirectToAuthenticationEndpoint' or 'RedirectToEndSessionEndpoint' events.
|
||||
/// </summary>
|
||||
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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 @@ namespace Microsoft.AspNetCore.Authentication.OpenIdConnect
|
|||
{
|
||||
public RemoteSignOutContext(
|
||||
HttpContext context,
|
||||
AuthenticationScheme scheme,
|
||||
OpenIdConnectOptions options,
|
||||
OpenIdConnectMessage message)
|
||||
: base(context, options)
|
||||
: base(context, scheme, options)
|
||||
{
|
||||
ProtocolMessage = message;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 @@ namespace Microsoft.AspNetCore.Authentication.OpenIdConnect
|
|||
/// <summary>
|
||||
/// Creates a <see cref="TokenResponseReceivedContext"/>
|
||||
/// </summary>
|
||||
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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,8 +15,8 @@ namespace Microsoft.AspNetCore.Authentication.OpenIdConnect
|
|||
/// <summary>
|
||||
/// Creates a <see cref="TokenValidatedContext"/>
|
||||
/// </summary>
|
||||
public TokenValidatedContext(HttpContext context, OpenIdConnectOptions options)
|
||||
: base(context, options)
|
||||
public TokenValidatedContext(HttpContext context, AuthenticationScheme scheme, OpenIdConnectOptions options)
|
||||
: base(context, scheme, options)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@
|
|||
<ProjectReference Include="..\Microsoft.AspNetCore.Authentication.OAuth\Microsoft.AspNetCore.Authentication.OAuth.csproj" />
|
||||
<PackageReference Include="Microsoft.Extensions.TaskCache.Sources" Version="$(AspNetCoreVersion)" PrivateAssets="All" />
|
||||
<PackageReference Include="Microsoft.IdentityModel.Protocols.OpenIdConnect" Version="$(IdentityModelOpenIdVersion)" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="$(AspNetCoreVersion)" />
|
||||
<PackageReference Include="System.Security.Claims" Version="$(CoreFxVersion)" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
|
|
|||
|
|
@ -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
|
||||
{
|
||||
/// <summary>
|
||||
/// Adds the <see cref="OpenIdConnectMiddleware"/> middleware to the specified <see cref="IApplicationBuilder"/>, which enables OpenID Connect authentication capabilities.
|
||||
/// Obsolete, see https://go.microsoft.com/fwlink/?linkid=845470
|
||||
/// </summary>
|
||||
/// <param name="app">The <see cref="IApplicationBuilder"/> to add the middleware to.</param>
|
||||
/// <param name="app">The <see cref="IApplicationBuilder"/> to add the handler to.</param>
|
||||
/// <returns>A reference to this instance after the operation has completed.</returns>
|
||||
[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<OpenIdConnectMiddleware>();
|
||||
throw new NotSupportedException("This method is no longer supported, see https://go.microsoft.com/fwlink/?linkid=845470");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds the <see cref="OpenIdConnectMiddleware"/> middleware to the specified <see cref="IApplicationBuilder"/>, which enables OpenID Connect authentication capabilities.
|
||||
/// Obsolete, see https://go.microsoft.com/fwlink/?linkid=845470
|
||||
/// </summary>
|
||||
/// <param name="app">The <see cref="IApplicationBuilder"/> to add the middleware to.</param>
|
||||
/// <param name="options">A <see cref="OpenIdConnectOptions"/> that specifies options for the middleware.</param>
|
||||
/// <param name="app">The <see cref="IApplicationBuilder"/> to add the handler to.</param>
|
||||
/// <param name="options">A <see cref="OpenIdConnectOptions"/> that specifies options for the handler.</param>
|
||||
/// <returns>A reference to this instance after the operation has completed.</returns>
|
||||
[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<OpenIdConnectMiddleware>(Options.Create(options));
|
||||
throw new NotSupportedException("This method is no longer supported, see https://go.microsoft.com/fwlink/?linkid=845470");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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 Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.Options;
|
||||
|
||||
namespace Microsoft.AspNetCore.Authentication.OpenIdConnect
|
||||
{
|
||||
internal class OpenIdConnectConfigureOptions : ConfigureNamedOptions<OpenIdConnectOptions>
|
||||
{
|
||||
// Bind to "OpenIdConnect" section by default
|
||||
public OpenIdConnectConfigureOptions(IConfiguration config) :
|
||||
base(OpenIdConnectDefaults.AuthenticationScheme,
|
||||
options => config.GetSection(OpenIdConnectDefaults.AuthenticationScheme).Bind(options))
|
||||
{ }
|
||||
}
|
||||
}
|
||||
|
|
@ -4,7 +4,7 @@
|
|||
namespace Microsoft.AspNetCore.Authentication.OpenIdConnect
|
||||
{
|
||||
/// <summary>
|
||||
/// Default values related to OpenIdConnect authentication middleware
|
||||
/// Default values related to OpenIdConnect authentication handler
|
||||
/// </summary>
|
||||
public static class OpenIdConnectDefaults
|
||||
{
|
||||
|
|
|
|||
|
|
@ -0,0 +1,32 @@
|
|||
// 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.Extensions.DependencyInjection
|
||||
{
|
||||
public static class OpenIdConnectExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Adds OpenIdConnect authentication with options bound against the "OpenIdConnect" section
|
||||
/// from the IConfiguration in the service container.
|
||||
/// </summary>
|
||||
/// <param name="services"></param>
|
||||
/// <returns></returns>
|
||||
public static IServiceCollection AddOpenIdConnectAuthentication(this IServiceCollection services)
|
||||
{
|
||||
services.AddSingleton<IConfigureOptions<OpenIdConnectOptions>, OpenIdConnectConfigureOptions>();
|
||||
return services.AddOpenIdConnectAuthentication(OpenIdConnectDefaults.AuthenticationScheme, _ => { });
|
||||
}
|
||||
|
||||
public static IServiceCollection AddOpenIdConnectAuthentication(this IServiceCollection services, Action<OpenIdConnectOptions> configureOptions)
|
||||
=> services.AddOpenIdConnectAuthentication(OpenIdConnectDefaults.AuthenticationScheme, configureOptions);
|
||||
|
||||
public static IServiceCollection AddOpenIdConnectAuthentication(this IServiceCollection services, string authenticationScheme, Action<OpenIdConnectOptions> configureOptions)
|
||||
{
|
||||
return services.AddScheme<OpenIdConnectOptions, OpenIdConnectHandler>(authenticationScheme, configureOptions);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -13,12 +13,12 @@ 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.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;
|
||||
|
|
@ -53,28 +53,110 @@ namespace Microsoft.AspNetCore.Authentication.OpenIdConnect
|
|||
|
||||
private OpenIdConnectConfiguration _configuration;
|
||||
|
||||
protected HttpClient Backchannel { get; private set; }
|
||||
protected HttpClient Backchannel => Options.Backchannel;
|
||||
|
||||
protected HtmlEncoder HtmlEncoder { get; private set; }
|
||||
protected HtmlEncoder HtmlEncoder { get; }
|
||||
|
||||
public OpenIdConnectHandler(HttpClient backchannel, HtmlEncoder htmlEncoder)
|
||||
public OpenIdConnectHandler(IOptions<AuthenticationOptions> sharedOptions, IOptionsSnapshot<OpenIdConnectOptions> 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<bool> HandleRequestAsync()
|
||||
/// <summary>
|
||||
/// 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.
|
||||
/// </summary>
|
||||
protected new OpenIdConnectEvents Events
|
||||
{
|
||||
get { return (OpenIdConnectEvents)base.Events; }
|
||||
set { base.Events = value; }
|
||||
}
|
||||
|
||||
protected override Task<object> CreateEventsAsync() => Task.FromResult<object>(new OpenIdConnectEvents());
|
||||
|
||||
protected override void InitializeOptions()
|
||||
{
|
||||
base.InitializeOptions();
|
||||
|
||||
if (string.IsNullOrEmpty(Options.SignOutScheme))
|
||||
{
|
||||
Options.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<string>(new StringSerializer(), dataProtector);
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(Options.TokenValidationParameters.ValidAudience) && !string.IsNullOrEmpty(Options.ClientId))
|
||||
{
|
||||
Options.TokenValidationParameters.ValidAudience = Options.ClientId;
|
||||
}
|
||||
|
||||
if (Options.Backchannel == null)
|
||||
{
|
||||
Options.Backchannel = new HttpClient(Options.BackchannelHttpHandler ?? new HttpClientHandler());
|
||||
Options.Backchannel.DefaultRequestHeaders.UserAgent.ParseAdd("Microsoft ASP.NET Core OpenIdConnect handler");
|
||||
Options.Backchannel.Timeout = Options.BackchannelTimeout;
|
||||
Options.Backchannel.MaxResponseContentBufferSize = 1024 * 1024 * 10; // 10 MB
|
||||
}
|
||||
|
||||
if (Options.ConfigurationManager == null)
|
||||
{
|
||||
if (Options.Configuration != null)
|
||||
{
|
||||
Options.ConfigurationManager = new StaticConfigurationManager<OpenIdConnectConfiguration>(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<OpenIdConnectConfiguration>(Options.MetadataAddress, new OpenIdConnectConfigurationRetriever(),
|
||||
new HttpDocumentRetriever(Backchannel) { RequireHttps = Options.RequireHttpsMetadata });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override Task<bool> 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<bool> HandleRemoteSignOutAsync()
|
||||
|
|
@ -97,8 +179,8 @@ namespace Microsoft.AspNetCore.Authentication.OpenIdConnect
|
|||
message = new OpenIdConnectMessage(form.Select(pair => new KeyValuePair<string, string[]>(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 +202,8 @@ namespace Microsoft.AspNetCore.Authentication.OpenIdConnect
|
|||
// 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(Options.SignOutScheme))
|
||||
?.Principal
|
||||
?.FindFirst(JwtRegisteredClaimNames.Sid)
|
||||
?.Value;
|
||||
if (!string.IsNullOrEmpty(sid))
|
||||
|
|
@ -142,7 +225,7 @@ namespace Microsoft.AspNetCore.Authentication.OpenIdConnect
|
|||
Logger.RemoteSignOut();
|
||||
|
||||
// We've received a remote sign-out request
|
||||
await Context.Authentication.SignOutAsync(Options.SignOutScheme);
|
||||
await Context.SignOutAsync(Options.SignOutScheme);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -169,7 +252,7 @@ namespace Microsoft.AspNetCore.Authentication.OpenIdConnect
|
|||
};
|
||||
|
||||
// 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 +264,14 @@ namespace Microsoft.AspNetCore.Authentication.OpenIdConnect
|
|||
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(Options.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 +354,6 @@ namespace Microsoft.AspNetCore.Authentication.OpenIdConnect
|
|||
if (!string.IsNullOrEmpty(properties?.RedirectUri))
|
||||
{
|
||||
Response.Redirect(properties.RedirectUri);
|
||||
return Task.FromResult(true);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -282,7 +364,7 @@ namespace Microsoft.AspNetCore.Authentication.OpenIdConnect
|
|||
/// Responds to a 401 Challenge. Sends an OpenIdConnect message to the 'identity authority' to obtain an identity.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
protected override async Task<bool> HandleUnauthorizedAsync(ChallengeContext context)
|
||||
protected override async Task HandleUnauthorizedAsync(ChallengeContext context)
|
||||
{
|
||||
if (context == null)
|
||||
{
|
||||
|
|
@ -294,8 +376,7 @@ namespace Microsoft.AspNetCore.Authentication.OpenIdConnect
|
|||
// 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 +416,21 @@ namespace Microsoft.AspNetCore.Authentication.OpenIdConnect
|
|||
|
||||
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 +460,7 @@ namespace Microsoft.AspNetCore.Authentication.OpenIdConnect
|
|||
}
|
||||
|
||||
Response.Redirect(redirectUri);
|
||||
return true;
|
||||
return;
|
||||
}
|
||||
else if (Options.AuthenticationMethod == OpenIdConnectRedirectBehavior.FormPost)
|
||||
{
|
||||
|
|
@ -407,7 +488,7 @@ namespace Microsoft.AspNetCore.Authentication.OpenIdConnect
|
|||
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 +516,7 @@ namespace Microsoft.AspNetCore.Authentication.OpenIdConnect
|
|||
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 +538,7 @@ namespace Microsoft.AspNetCore.Authentication.OpenIdConnect
|
|||
if (Options.SkipUnrecognizedRequests)
|
||||
{
|
||||
// Not for us?
|
||||
return AuthenticateResult.Skip();
|
||||
return AuthenticateResult.None();
|
||||
}
|
||||
return AuthenticateResult.Fail("No message.");
|
||||
}
|
||||
|
|
@ -473,7 +554,7 @@ namespace Microsoft.AspNetCore.Authentication.OpenIdConnect
|
|||
}
|
||||
|
||||
var messageReceivedContext = await RunMessageReceivedEventAsync(authorizationResponse, properties);
|
||||
if (messageReceivedContext.CheckEventResult(out result))
|
||||
if (messageReceivedContext.IsProcessingComplete(out result))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
|
@ -489,7 +570,7 @@ namespace Microsoft.AspNetCore.Authentication.OpenIdConnect
|
|||
Logger.NullOrEmptyAuthorizationResponseState();
|
||||
if (Options.SkipUnrecognizedRequests)
|
||||
{
|
||||
return AuthenticateResult.Skip();
|
||||
return AuthenticateResult.None();
|
||||
}
|
||||
return AuthenticateResult.Fail(Resources.MessageStateIsNullOrEmpty);
|
||||
}
|
||||
|
|
@ -504,7 +585,7 @@ namespace Microsoft.AspNetCore.Authentication.OpenIdConnect
|
|||
if (Options.SkipUnrecognizedRequests)
|
||||
{
|
||||
// Not for us?
|
||||
return AuthenticateResult.Skip();
|
||||
return AuthenticateResult.None();
|
||||
}
|
||||
return AuthenticateResult.Fail(Resources.MessageStateIsInvalid);
|
||||
}
|
||||
|
|
@ -550,7 +631,7 @@ namespace Microsoft.AspNetCore.Authentication.OpenIdConnect
|
|||
}
|
||||
|
||||
var tokenValidatedContext = await RunTokenValidatedEventAsync(authorizationResponse, null, properties, ticket, jwt, nonce);
|
||||
if (tokenValidatedContext.CheckEventResult(out result))
|
||||
if (tokenValidatedContext.IsProcessingComplete(out result))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
|
@ -575,7 +656,7 @@ namespace Microsoft.AspNetCore.Authentication.OpenIdConnect
|
|||
if (!string.IsNullOrEmpty(authorizationResponse.Code))
|
||||
{
|
||||
var authorizationCodeReceivedContext = await RunAuthorizationCodeReceivedEventAsync(authorizationResponse, properties, ticket, jwt);
|
||||
if (authorizationCodeReceivedContext.CheckEventResult(out result))
|
||||
if (authorizationCodeReceivedContext.IsProcessingComplete(out result))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
|
@ -593,7 +674,7 @@ namespace Microsoft.AspNetCore.Authentication.OpenIdConnect
|
|||
}
|
||||
|
||||
var tokenResponseReceivedContext = await RunTokenResponseReceivedEventAsync(authorizationResponse, tokenEndpointResponse, properties, ticket);
|
||||
if (tokenResponseReceivedContext.CheckEventResult(out result))
|
||||
if (tokenResponseReceivedContext.IsProcessingComplete(out result))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
|
@ -620,7 +701,7 @@ namespace Microsoft.AspNetCore.Authentication.OpenIdConnect
|
|||
}
|
||||
|
||||
var tokenValidatedContext = await RunTokenValidatedEventAsync(authorizationResponse, tokenEndpointResponse, properties, tokenEndpointTicket, tokenEndpointJwt, nonce);
|
||||
if (tokenValidatedContext.CheckEventResult(out result))
|
||||
if (tokenValidatedContext.IsProcessingComplete(out result))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
|
@ -689,7 +770,7 @@ namespace Microsoft.AspNetCore.Authentication.OpenIdConnect
|
|||
}
|
||||
|
||||
var authenticationFailedContext = await RunAuthenticationFailedEventAsync(authorizationResponse, exception);
|
||||
if (authenticationFailedContext.CheckEventResult(out result))
|
||||
if (authenticationFailedContext.IsProcessingComplete(out result))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
|
@ -804,7 +885,7 @@ namespace Microsoft.AspNetCore.Authentication.OpenIdConnect
|
|||
|
||||
var userInformationReceivedContext = await RunUserInformationReceivedEventAsync(ticket, message, user);
|
||||
AuthenticateResult result;
|
||||
if (userInformationReceivedContext.CheckEventResult(out result))
|
||||
if (userInformationReceivedContext.IsProcessingComplete(out result))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
|
@ -861,7 +942,7 @@ namespace Microsoft.AspNetCore.Authentication.OpenIdConnect
|
|||
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 +972,7 @@ namespace Microsoft.AspNetCore.Authentication.OpenIdConnect
|
|||
{
|
||||
HttpOnly = true,
|
||||
Secure = Request.IsHttps,
|
||||
Expires = Options.SystemClock.UtcNow.Add(Options.ProtocolValidator.NonceLifetime)
|
||||
Expires = Clock.UtcNow.Add(Options.ProtocolValidator.NonceLifetime)
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -971,13 +1052,13 @@ namespace Microsoft.AspNetCore.Authentication.OpenIdConnect
|
|||
private async Task<MessageReceivedContext> 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 +1073,7 @@ namespace Microsoft.AspNetCore.Authentication.OpenIdConnect
|
|||
|
||||
private async Task<TokenValidatedContext> 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 +1083,7 @@ namespace Microsoft.AspNetCore.Authentication.OpenIdConnect
|
|||
Nonce = nonce,
|
||||
};
|
||||
|
||||
await Options.Events.TokenValidated(tokenValidatedContext);
|
||||
await Events.TokenValidated(tokenValidatedContext);
|
||||
if (tokenValidatedContext.HandledResponse)
|
||||
{
|
||||
Logger.TokenValidatedHandledResponse();
|
||||
|
|
@ -1029,7 +1110,7 @@ namespace Microsoft.AspNetCore.Authentication.OpenIdConnect
|
|||
RedirectUri = properties.Items[OpenIdConnectDefaults.RedirectUriForCodePropertiesKey]
|
||||
};
|
||||
|
||||
var authorizationCodeReceivedContext = new AuthorizationCodeReceivedContext(Context, Options)
|
||||
var authorizationCodeReceivedContext = new AuthorizationCodeReceivedContext(Context, Scheme, Options)
|
||||
{
|
||||
ProtocolMessage = authorizationResponse,
|
||||
Properties = properties,
|
||||
|
|
@ -1039,7 +1120,7 @@ namespace Microsoft.AspNetCore.Authentication.OpenIdConnect
|
|||
Backchannel = Backchannel,
|
||||
};
|
||||
|
||||
await Options.Events.AuthorizationCodeReceived(authorizationCodeReceivedContext);
|
||||
await Events.AuthorizationCodeReceived(authorizationCodeReceivedContext);
|
||||
if (authorizationCodeReceivedContext.HandledResponse)
|
||||
{
|
||||
Logger.AuthorizationCodeReceivedContextHandledResponse();
|
||||
|
|
@ -1059,14 +1140,14 @@ namespace Microsoft.AspNetCore.Authentication.OpenIdConnect
|
|||
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 +1164,14 @@ namespace Microsoft.AspNetCore.Authentication.OpenIdConnect
|
|||
{
|
||||
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 +1186,13 @@ namespace Microsoft.AspNetCore.Authentication.OpenIdConnect
|
|||
|
||||
private async Task<AuthenticationFailedContext> 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 +1242,7 @@ namespace Microsoft.AspNetCore.Authentication.OpenIdConnect
|
|||
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 +1301,18 @@ namespace Microsoft.AspNetCore.Authentication.OpenIdConnect
|
|||
description,
|
||||
errorUri));
|
||||
}
|
||||
|
||||
private class StringSerializer : IDataSerializer<string>
|
||||
{
|
||||
public string Deserialize(byte[] data)
|
||||
{
|
||||
return Encoding.UTF8.GetString(data);
|
||||
}
|
||||
|
||||
public byte[] Serialize(string model)
|
||||
{
|
||||
return Encoding.UTF8.GetBytes(model);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
{
|
||||
/// <summary>
|
||||
/// ASP.NET Core middleware for obtaining identities using OpenIdConnect protocol.
|
||||
/// </summary>
|
||||
public class OpenIdConnectMiddleware : AuthenticationMiddleware<OpenIdConnectOptions>
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a <see cref="OpenIdConnectMiddleware"/>
|
||||
/// </summary>
|
||||
/// <param name="next">The next middleware in the middleware pipeline to invoke.</param>
|
||||
/// <param name="dataProtectionProvider"> provider for creating a data protector.</param>
|
||||
/// <param name="loggerFactory">factory for creating a <see cref="ILogger"/>.</param>
|
||||
/// <param name="encoder"></param>
|
||||
/// <param name="services"></param>
|
||||
/// <param name="sharedOptions"></param>
|
||||
/// <param name="options"></param>
|
||||
/// <param name="htmlEncoder">The <see cref="HtmlEncoder"/>.</param>
|
||||
public OpenIdConnectMiddleware(
|
||||
RequestDelegate next,
|
||||
IDataProtectionProvider dataProtectionProvider,
|
||||
ILoggerFactory loggerFactory,
|
||||
UrlEncoder encoder,
|
||||
IServiceProvider services,
|
||||
IOptions<SharedAuthenticationOptions> sharedOptions,
|
||||
IOptions<OpenIdConnectOptions> 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<string>(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<OpenIdConnectConfiguration>(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<OpenIdConnectConfiguration>(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; }
|
||||
|
||||
/// <summary>
|
||||
/// Provides the <see cref="AuthenticationHandler{T}"/> object for processing authentication-related requests.
|
||||
/// </summary>
|
||||
/// <returns>An <see cref="AuthenticationHandler{T}"/> configured with the <see cref="OpenIdConnectOptions"/> supplied to the constructor.</returns>
|
||||
protected override AuthenticationHandler<OpenIdConnectOptions> CreateHandler()
|
||||
{
|
||||
return new OpenIdConnectHandler(Backchannel, HtmlEncoder);
|
||||
}
|
||||
|
||||
private class StringSerializer : IDataSerializer<string>
|
||||
{
|
||||
public string Deserialize(byte[] data)
|
||||
{
|
||||
return Encoding.UTF8.GetString(data);
|
||||
}
|
||||
|
||||
public byte[] Serialize(string model)
|
||||
{
|
||||
return Encoding.UTF8.GetBytes(model);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -8,27 +8,20 @@ using System.Security.Claims;
|
|||
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
|
||||
{
|
||||
/// <summary>
|
||||
/// Configuration options for <see cref="OpenIdConnectMiddleware"/>
|
||||
/// Configuration options for <see cref="OpenIdConnectHandler"/>
|
||||
/// </summary>
|
||||
public class OpenIdConnectOptions : RemoteAuthenticationOptions
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new <see cref="OpenIdConnectOptions"/>
|
||||
/// </summary>
|
||||
public OpenIdConnectOptions()
|
||||
: this(OpenIdConnectDefaults.AuthenticationScheme)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new <see cref="OpenIdConnectOptions"/>
|
||||
/// </summary>
|
||||
|
|
@ -44,11 +37,8 @@ namespace Microsoft.AspNetCore.Builder
|
|||
/// <para>TokenValidationParameters: new <see cref="TokenValidationParameters"/> with AuthenticationScheme = authenticationScheme.</para>
|
||||
/// <para>UseTokenLifetime: false.</para>
|
||||
/// </remarks>
|
||||
/// <param name="authenticationScheme"> will be used to when creating the <see cref="System.Security.Claims.ClaimsIdentity"/> for the AuthenticationScheme property.</param>
|
||||
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,30 @@ namespace Microsoft.AspNetCore.Builder
|
|||
ClaimActions.MapUniqueJsonKey("email", "email");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Check that the options are valid. Should throw an exception if things are not ok.
|
||||
/// </summary>
|
||||
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));
|
||||
}
|
||||
|
||||
if (ConfigurationManager == null)
|
||||
{
|
||||
throw new InvalidOperationException($"Provide {nameof(Authority)}, {nameof(MetadataAddress)}, "
|
||||
+ $"{nameof(Configuration)}, or {nameof(ConfigurationManager)} to {nameof(OpenIdConnectOptions)}");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the Authority to use when making OpenIdConnect calls.
|
||||
/// </summary>
|
||||
|
|
@ -111,7 +125,7 @@ namespace Microsoft.AspNetCore.Builder
|
|||
public IConfigurationManager<OpenIdConnectConfiguration> ConfigurationManager { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Boolean to set whether the middleware should go to user info endpoint to retrieve additional claims or not after creating an identity from id_token received from token endpoint.
|
||||
/// Boolean to set whether the handler should go to user info endpoint to retrieve additional claims or not after creating an identity from id_token received from token endpoint.
|
||||
/// The default is 'false'.
|
||||
/// </summary>
|
||||
public bool GetClaimsFromUserInfoEndpoint { get; set; }
|
||||
|
|
@ -133,11 +147,11 @@ namespace Microsoft.AspNetCore.Builder
|
|||
public string MetadataAddress { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the <see cref="IOpenIdConnectEvents"/> to notify when processing OpenIdConnect messages.
|
||||
/// Gets or sets the <see cref="OpenIdConnectEvents"/> to notify when processing OpenIdConnect messages.
|
||||
/// </summary>
|
||||
public new IOpenIdConnectEvents Events
|
||||
public new OpenIdConnectEvents Events
|
||||
{
|
||||
get { return (IOpenIdConnectEvents)base.Events; }
|
||||
get { return (OpenIdConnectEvents)base.Events; }
|
||||
set { base.Events = value; }
|
||||
}
|
||||
|
||||
|
|
@ -196,7 +210,7 @@ namespace Microsoft.AspNetCore.Builder
|
|||
public ICollection<string> Scope { get; } = new HashSet<string>();
|
||||
|
||||
/// <summary>
|
||||
/// Requests received on this path will cause the middleware to invoke SignOut using the SignInScheme.
|
||||
/// Requests received on this path will cause the handler to invoke SignOut using the SignInScheme.
|
||||
/// </summary>
|
||||
public PathString RemoteSignOutPath { get; set; }
|
||||
|
||||
|
|
@ -207,12 +221,12 @@ namespace Microsoft.AspNetCore.Builder
|
|||
public string SignOutScheme { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the type used to secure data handled by the middleware.
|
||||
/// Gets or sets the type used to secure data handled by the handler.
|
||||
/// </summary>
|
||||
public ISecureDataFormat<AuthenticationProperties> StateDataFormat { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the type used to secure strings used by the middleware.
|
||||
/// Gets or sets the type used to secure strings used by the handler.
|
||||
/// </summary>
|
||||
public ISecureDataFormat<string> StringDataFormat { get; set; }
|
||||
|
||||
|
|
@ -235,7 +249,7 @@ namespace Microsoft.AspNetCore.Builder
|
|||
public bool UseTokenLifetime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates if requests to the CallbackPath may also be for other components. If enabled the middleware will pass
|
||||
/// Indicates if requests to the CallbackPath may also be for other components. If enabled the handler will pass
|
||||
/// requests through that do not contain OpenIdConnect authentication responses. Disabling this and setting the
|
||||
/// CallbackPath to a dedicated endpoint may provide better error handling.
|
||||
/// This is disabled by default.
|
||||
|
|
|
|||
|
|
@ -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
|
|||
/// <summary>
|
||||
/// Base class for other Twitter contexts.
|
||||
/// </summary>
|
||||
public class BaseTwitterContext : BaseContext
|
||||
public class BaseTwitterContext : BaseAuthenticationContext
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a <see cref="BaseTwitterContext"/>
|
||||
/// </summary>
|
||||
/// <param name="context">The HTTP environment</param>
|
||||
/// <param name="scheme">The scheme data</param>
|
||||
/// <param name="options">The options for Twitter</param>
|
||||
public BaseTwitterContext(HttpContext context, TwitterOptions options)
|
||||
: base(context)
|
||||
/// <param name="properties">The AuthenticationProperties</param>
|
||||
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; }
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
{
|
||||
/// <summary>
|
||||
/// Specifies callback methods which the <see cref="TwitterMiddleware"></see> invokes to enable developer control over the authentication process. />
|
||||
/// </summary>
|
||||
public interface ITwitterEvents : IRemoteAuthenticationEvents
|
||||
{
|
||||
/// <summary>
|
||||
/// Invoked whenever Twitter succesfully authenticates a user
|
||||
/// </summary>
|
||||
/// <param name="context">Contains information about the login session as well as the user <see cref="System.Security.Claims.ClaimsIdentity"/>.</param>
|
||||
/// <returns>A <see cref="Task"/> representing the completed operation.</returns>
|
||||
Task CreatingTicket(TwitterCreatingTicketContext context);
|
||||
|
||||
/// <summary>
|
||||
/// Called when a Challenge causes a redirect to authorize endpoint in the Twitter middleware
|
||||
/// </summary>
|
||||
/// <param name="context">Contains redirect URI and <see cref="Http.Authentication.AuthenticationProperties"/> of the challenge </param>
|
||||
Task RedirectToAuthorizationEndpoint(TwitterRedirectToAuthorizationEndpointContext context);
|
||||
}
|
||||
}
|
||||
|
|
@ -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 @@ namespace Microsoft.AspNetCore.Authentication.Twitter
|
|||
/// Initializes a <see cref="TwitterCreatingTicketContext"/>
|
||||
/// </summary>
|
||||
/// <param name="context">The HTTP environment</param>
|
||||
/// <param name="scheme">The scheme data</param>
|
||||
/// <param name="options">The options for Twitter</param>
|
||||
/// <param name="userId">Twitter user ID</param>
|
||||
/// <param name="screenName">Twitter screen name</param>
|
||||
/// <param name="accessToken">Twitter access token</param>
|
||||
/// <param name="accessTokenSecret">Twitter access token secret</param>
|
||||
/// <param name="user">User details</param>
|
||||
/// <param name="properties">AuthenticationProperties.</param>
|
||||
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 @@ namespace Microsoft.AspNetCore.Authentication.Twitter
|
|||
/// Gets the <see cref="ClaimsPrincipal"/> representing the user
|
||||
/// </summary>
|
||||
public ClaimsPrincipal Principal { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a property bag for common authentication properties
|
||||
/// </summary>
|
||||
public AuthenticationProperties Properties { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,9 +8,9 @@ using Microsoft.Extensions.Internal;
|
|||
namespace Microsoft.AspNetCore.Authentication.Twitter
|
||||
{
|
||||
/// <summary>
|
||||
/// Default <see cref="ITwitterEvents"/> implementation.
|
||||
/// Default <see cref="TwitterEvents"/> implementation.
|
||||
/// </summary>
|
||||
public class TwitterEvents : RemoteAuthenticationEvents, ITwitterEvents
|
||||
public class TwitterEvents : RemoteAuthenticationEvents
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the function that is invoked when the Authenticated method is invoked.
|
||||
|
|
@ -34,7 +34,7 @@ namespace Microsoft.AspNetCore.Authentication.Twitter
|
|||
public virtual Task CreatingTicket(TwitterCreatingTicketContext context) => OnCreatingTicket(context);
|
||||
|
||||
/// <summary>
|
||||
/// Called when a Challenge causes a redirect to authorize endpoint in the Twitter middleware
|
||||
/// Called when a Challenge causes a redirect to authorize endpoint in the Twitter handler
|
||||
/// </summary>
|
||||
/// <param name="context">Contains redirect URI and <see cref="Http.Authentication.AuthenticationProperties"/> of the challenge </param>
|
||||
public virtual Task RedirectToAuthorizationEndpoint(TwitterRedirectToAuthorizationEndpointContext context) => OnRedirectToAuthorizationEndpoint(context);
|
||||
|
|
|
|||
|
|
@ -1,14 +1,12 @@
|
|||
// 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
|
||||
{
|
||||
/// <summary>
|
||||
/// The Context passed when a Challenge causes a redirect to authorize endpoint in the Twitter middleware.
|
||||
/// The Context passed when a Challenge causes a redirect to authorize endpoint in the Twitter handler.
|
||||
/// </summary>
|
||||
public class TwitterRedirectToAuthorizationEndpointContext : BaseTwitterContext
|
||||
{
|
||||
|
|
@ -16,12 +14,14 @@ namespace Microsoft.AspNetCore.Authentication.Twitter
|
|||
/// Creates a new context object.
|
||||
/// </summary>
|
||||
/// <param name="context">The HTTP request context.</param>
|
||||
/// <param name="options">The Twitter middleware options.</param>
|
||||
/// <param name="scheme">The scheme data</param>
|
||||
/// <param name="options">The Twitter handler options.</param>
|
||||
/// <param name="properties">The authentication properties of the challenge.</param>
|
||||
/// <param name="redirectUri">The initial redirect URI.</param>
|
||||
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 @@ namespace Microsoft.AspNetCore.Authentication.Twitter
|
|||
/// Gets the URI used for the redirect operation.
|
||||
/// </summary>
|
||||
public string RedirectUri { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the authentication properties of the challenge.
|
||||
/// </summary>
|
||||
public AuthenticationProperties Properties { get; private set; }
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@
|
|||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Microsoft.AspNetCore.Authentication.OAuth\Microsoft.AspNetCore.Authentication.OAuth.csproj" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="$(AspNetCoreVersion)" />
|
||||
<PackageReference Include="Microsoft.Extensions.TaskCache.Sources" Version="$(AspNetCoreVersion)" PrivateAssets="All" />
|
||||
</ItemGroup>
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
{
|
||||
/// <summary>
|
||||
/// Adds the <see cref="TwitterMiddleware"/> middleware to the specified <see cref="IApplicationBuilder"/>, which enables Twitter authentication capabilities.
|
||||
/// Obsolete, see https://go.microsoft.com/fwlink/?linkid=845470
|
||||
/// </summary>
|
||||
/// <param name="app">The <see cref="IApplicationBuilder"/> to add the middleware to.</param>
|
||||
/// <param name="app">The <see cref="IApplicationBuilder"/> to add the handler to.</param>
|
||||
/// <returns>A reference to this instance after the operation has completed.</returns>
|
||||
[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<TwitterMiddleware>();
|
||||
throw new NotSupportedException("This method is no longer supported, see https://go.microsoft.com/fwlink/?linkid=845470");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds the <see cref="TwitterMiddleware"/> middleware to the specified <see cref="IApplicationBuilder"/>, which enables Twitter authentication capabilities.
|
||||
/// Obsolete, see https://go.microsoft.com/fwlink/?linkid=845470
|
||||
/// </summary>
|
||||
/// <param name="app">The <see cref="IApplicationBuilder"/> to add the middleware to.</param>
|
||||
/// <param name="app">The <see cref="IApplicationBuilder"/> to add the handler to.</param>
|
||||
/// <param name="options">An action delegate to configure the provided <see cref="TwitterOptions"/>.</param>
|
||||
/// <returns>A reference to this instance after the operation has completed.</returns>
|
||||
[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<TwitterMiddleware>(Options.Create(options));
|
||||
throw new NotSupportedException("This method is no longer supported, see https://go.microsoft.com/fwlink/?linkid=845470");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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 Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.Options;
|
||||
|
||||
namespace Microsoft.AspNetCore.Authentication.Twitter
|
||||
{
|
||||
internal class TwitterConfigureOptions : ConfigureNamedOptions<TwitterOptions>
|
||||
{
|
||||
// Bind to "Twitter" section by default
|
||||
public TwitterConfigureOptions(IConfiguration config) :
|
||||
base(TwitterDefaults.AuthenticationScheme,
|
||||
options => config.GetSection(TwitterDefaults.AuthenticationScheme).Bind(options))
|
||||
{ }
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
// 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.Extensions.DependencyInjection
|
||||
{
|
||||
public static class TwitterExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Adds Twitter authentication with options bound against the "Twitter" section
|
||||
/// from the IConfiguration in the service container.
|
||||
/// </summary>
|
||||
/// <param name="services"></param>
|
||||
/// <returns></returns>
|
||||
public static IServiceCollection AddTwitterAuthentication(this IServiceCollection services)
|
||||
{
|
||||
services.AddSingleton<IConfigureOptions<TwitterOptions>, TwitterConfigureOptions>();
|
||||
return services.AddTwitterAuthentication(TwitterDefaults.AuthenticationScheme, _ => { });
|
||||
}
|
||||
|
||||
public static IServiceCollection AddTwitterAuthentication(this IServiceCollection services, Action<TwitterOptions> configureOptions)
|
||||
=> services.AddTwitterAuthentication(TwitterDefaults.AuthenticationScheme, configureOptions);
|
||||
|
||||
public static IServiceCollection AddTwitterAuthentication(this IServiceCollection services, string authenticationScheme, Action<TwitterOptions> configureOptions)
|
||||
{
|
||||
return services.AddScheme<TwitterOptions, TwitterHandler>(authenticationScheme, configureOptions);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -8,13 +8,13 @@ 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.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,46 @@ namespace Microsoft.AspNetCore.Authentication.Twitter
|
|||
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 Backchannel => Options.Backchannel;
|
||||
|
||||
public TwitterHandler(HttpClient httpClient)
|
||||
/// <summary>
|
||||
/// 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.
|
||||
/// </summary>
|
||||
protected new TwitterEvents Events
|
||||
{
|
||||
_httpClient = httpClient;
|
||||
get { return (TwitterEvents)base.Events; }
|
||||
set { base.Events = value; }
|
||||
}
|
||||
|
||||
public TwitterHandler(IOptions<AuthenticationOptions> sharedOptions, IOptionsSnapshot<TwitterOptions> options, ILoggerFactory logger, UrlEncoder encoder, IDataProtectionProvider dataProtection, ISystemClock clock)
|
||||
: base(sharedOptions, options, dataProtection, logger, encoder, clock)
|
||||
{ }
|
||||
|
||||
protected override Task<object> CreateEventsAsync() => Task.FromResult<object>(new TwitterEvents());
|
||||
|
||||
protected override void InitializeOptions()
|
||||
{
|
||||
base.InitializeOptions();
|
||||
|
||||
if (Options.StateDataFormat == null)
|
||||
{
|
||||
var dataProtector = DataProtection.CreateProtector(
|
||||
GetType().FullName, Scheme.Name, "v1");
|
||||
Options.StateDataFormat = new SecureDataFormat<RequestToken>(
|
||||
new RequestTokenSerializer(),
|
||||
dataProtector);
|
||||
}
|
||||
|
||||
if (Options.Backchannel == null)
|
||||
{
|
||||
Options.Backchannel = new HttpClient(Options.BackchannelHttpHandler ?? new HttpClientHandler());
|
||||
Options.Backchannel.Timeout = Options.BackchannelTimeout;
|
||||
Options.Backchannel.MaxResponseContentBufferSize = 1024 * 1024 * 10; // 10 MB
|
||||
Options.Backchannel.DefaultRequestHeaders.Accept.ParseAdd("*/*");
|
||||
Options.Backchannel.DefaultRequestHeaders.UserAgent.ParseAdd("Microsoft ASP.NET Core Twitter handler");
|
||||
Options.Backchannel.DefaultRequestHeaders.ExpectContinue = false;
|
||||
}
|
||||
}
|
||||
|
||||
protected override async Task<AuthenticateResult> HandleRemoteAuthenticateAsync()
|
||||
|
|
@ -113,30 +148,29 @@ namespace Microsoft.AspNetCore.Authentication.Twitter
|
|||
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<bool> 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 +185,13 @@ namespace Microsoft.AspNetCore.Authentication.Twitter
|
|||
{
|
||||
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<RequestToken> ObtainRequestTokenAsync(string callBackUri, AuthenticationProperties properties)
|
||||
|
|
@ -209,7 +240,7 @@ namespace Microsoft.AspNetCore.Authentication.Twitter
|
|||
var request = new HttpRequestMessage(HttpMethod.Post, RequestTokenEndpoint);
|
||||
request.Headers.Add("Authorization", authorizationHeaderBuilder.ToString());
|
||||
|
||||
var response = await _httpClient.SendAsync(request, Context.RequestAborted);
|
||||
var response = await Backchannel.SendAsync(request, Context.RequestAborted);
|
||||
response.EnsureSuccessStatusCode();
|
||||
var responseText = await response.Content.ReadAsStringAsync();
|
||||
|
||||
|
|
@ -279,7 +310,7 @@ namespace Microsoft.AspNetCore.Authentication.Twitter
|
|||
|
||||
request.Content = new FormUrlEncodedContent(formPairs);
|
||||
|
||||
var response = await _httpClient.SendAsync(request, Context.RequestAborted);
|
||||
var response = await Backchannel.SendAsync(request, Context.RequestAborted);
|
||||
|
||||
if (!response.IsSuccessStatusCode)
|
||||
{
|
||||
|
|
@ -350,7 +381,7 @@ namespace Microsoft.AspNetCore.Authentication.Twitter
|
|||
var request = new HttpRequestMessage(HttpMethod.Get, resource_url + "?include_email=true");
|
||||
request.Headers.Add("Authorization", authorizationHeaderBuilder.ToString());
|
||||
|
||||
var response = await _httpClient.SendAsync(request, Context.RequestAborted);
|
||||
var response = await Backchannel.SendAsync(request, Context.RequestAborted);
|
||||
if (!response.IsSuccessStatusCode)
|
||||
{
|
||||
Logger.LogError("Email request failed with a status code of " + response.StatusCode);
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue