From b1acd991979c44367aeea12912b852c4f5d64d18 Mon Sep 17 00:00:00 2001 From: Chris Ross Date: Wed, 7 May 2014 11:35:42 -0700 Subject: [PATCH 001/216] Remove NullLoggerFactory workaround from the sample. --- samples/CookieSample/Startup.cs | 25 ------------------------- samples/CookieSample/project.json | 3 +-- 2 files changed, 1 insertion(+), 27 deletions(-) diff --git a/samples/CookieSample/Startup.cs b/samples/CookieSample/Startup.cs index 71386c068..cd8bf7621 100644 --- a/samples/CookieSample/Startup.cs +++ b/samples/CookieSample/Startup.cs @@ -7,7 +7,6 @@ using Microsoft.AspNet.Builder; using Microsoft.Framework.DependencyInjection; using Microsoft.Framework.DependencyInjection.Fallback; -using Microsoft.Framework.Logging; namespace CookieSample { @@ -15,12 +14,6 @@ public class Startup { public void Configuration(IBuilder app) { - app.UseServices(services => - { - // TODO: Move to host. - services.AddInstance(new NullLoggerFactory()); - }); - app.UseCookieAuthentication(new CookieAuthenticationOptions() { @@ -41,23 +34,5 @@ public void Configuration(IBuilder app) await context.Response.WriteAsync("Hello old timer"); }); } - - // TODO: Temp workaround until the host reliably provides logging. - // If ILoggerFactory is never guaranteed, move this fallback into Microsoft.Framework.Logging. - private class NullLoggerFactory : ILoggerFactory - { - public ILogger Create(string name) - { - return new NullLongger(); - } - } - - private class NullLongger : ILogger - { - public bool WriteCore(TraceType eventType, int eventId, object state, Exception exception, Func formatter) - { - return false; - } - } } } \ No newline at end of file diff --git a/samples/CookieSample/project.json b/samples/CookieSample/project.json index 22f33b30b..81321a825 100644 --- a/samples/CookieSample/project.json +++ b/samples/CookieSample/project.json @@ -10,8 +10,7 @@ "Microsoft.AspNet.FeatureModel": "0.1-alpha-*", "Microsoft.AspNet.HttpFeature": "0.1-alpha-*", "Microsoft.AspNet.Server.WebListener": "0.1-alpha-*", - "Microsoft.Framework.DependencyInjection": "0.1-alpha-*", - "Microsoft.Framework.Logging": "0.1-alpha-*" + "Microsoft.Framework.DependencyInjection": "0.1-alpha-*" }, "commands": { "web": "Microsoft.AspNet.Hosting server.name=Microsoft.AspNet.Server.WebListener server.urls=http://localhost:12345" }, "configurations": { From f8f3e3498672b73753034b1552bb4cedd5f730d1 Mon Sep 17 00:00:00 2001 From: Wei Wang Date: Wed, 7 May 2014 18:04:18 -0700 Subject: [PATCH 002/216] Sort dependencies and remove duplicates in dependencies --- samples/CookieSample/project.json | 12 ++++++------ src/Microsoft.AspNet.Security.Cookies/project.json | 12 ++++++------ src/Microsoft.AspNet.Security/project.json | 6 +++--- test/Microsoft.AspNet.Security.Test/project.json | 4 ++-- 4 files changed, 17 insertions(+), 17 deletions(-) diff --git a/samples/CookieSample/project.json b/samples/CookieSample/project.json index 81321a825..5b4245f7c 100644 --- a/samples/CookieSample/project.json +++ b/samples/CookieSample/project.json @@ -1,14 +1,14 @@ { "version": "0.1-alpha-*", "dependencies": { + "Microsoft.AspNet.FeatureModel": "0.1-alpha-*", + "Microsoft.AspNet.Hosting": "0.1-alpha-*", "Microsoft.AspNet.Http": "0.1-alpha-*", + "Microsoft.AspNet.HttpFeature": "0.1-alpha-*", + "Microsoft.AspNet.PipelineCore": "0.1-alpha-*", + "Microsoft.AspNet.RequestContainer": "0.1-alpha-*", "Microsoft.AspNet.Security": "", "Microsoft.AspNet.Security.Cookies": "", - "Microsoft.AspNet.Hosting": "0.1-alpha-*", - "Microsoft.AspNet.RequestContainer": "0.1-alpha-*", - "Microsoft.AspNet.PipelineCore": "0.1-alpha-*", - "Microsoft.AspNet.FeatureModel": "0.1-alpha-*", - "Microsoft.AspNet.HttpFeature": "0.1-alpha-*", "Microsoft.AspNet.Server.WebListener": "0.1-alpha-*", "Microsoft.Framework.DependencyInjection": "0.1-alpha-*" }, @@ -18,8 +18,8 @@ }, "k10": { "dependencies": { - "System.Console": "4.0.0.0", "System.Collections": "4.0.0.0", + "System.Console": "4.0.0.0", "System.Diagnostics.Debug": "4.0.10.0", "System.Diagnostics.Tools": "4.0.0.0", "System.Globalization": "4.0.10.0", diff --git a/src/Microsoft.AspNet.Security.Cookies/project.json b/src/Microsoft.AspNet.Security.Cookies/project.json index 98cfc52a3..f16f0f5d0 100644 --- a/src/Microsoft.AspNet.Security.Cookies/project.json +++ b/src/Microsoft.AspNet.Security.Cookies/project.json @@ -1,23 +1,23 @@ { "version": "0.1-alpha-*", "dependencies": { - "Newtonsoft.Json": "5.0.8", - "Microsoft.AspNet.Security": "0.1-alpha-*", - "Microsoft.AspNet.PipelineCore": "0.1-alpha-*", - "Microsoft.AspNet.Http": "0.1-alpha-*", "Microsoft.AspNet.FeatureModel": "0.1-alpha-*", + "Microsoft.AspNet.Http": "0.1-alpha-*", "Microsoft.AspNet.HttpFeature": "0.1-alpha-*", + "Microsoft.AspNet.PipelineCore": "0.1-alpha-*", + "Microsoft.AspNet.Security": "0.1-alpha-*", "Microsoft.AspNet.Security.DataProtection": "0.1-alpha-*", "Microsoft.Framework.DependencyInjection": "0.1-alpha-*", - "Microsoft.Framework.Logging": "0.1-alpha-*" + "Microsoft.Framework.Logging": "0.1-alpha-*", + "Newtonsoft.Json": "5.0.8" }, "configurations": { "net45": {}, "k10": { "dependencies": { "System.Collections": "4.0.0.0", - "System.Console": "4.0.0.0", "System.ComponentModel": "4.0.0.0", + "System.Console": "4.0.0.0", "System.Diagnostics.Debug": "4.0.10.0", "System.Diagnostics.Tools": "4.0.0.0", "System.Globalization": "4.0.10.0", diff --git a/src/Microsoft.AspNet.Security/project.json b/src/Microsoft.AspNet.Security/project.json index 6501b3e77..b790dc942 100644 --- a/src/Microsoft.AspNet.Security/project.json +++ b/src/Microsoft.AspNet.Security/project.json @@ -1,10 +1,10 @@ { "version": "0.1-alpha-*", "dependencies": { - "Microsoft.AspNet.PipelineCore": "0.1-alpha-*", - "Microsoft.AspNet.Http": "0.1-alpha-*", "Microsoft.AspNet.FeatureModel": "0.1-alpha-*", + "Microsoft.AspNet.Http": "0.1-alpha-*", "Microsoft.AspNet.HttpFeature": "0.1-alpha-*", + "Microsoft.AspNet.PipelineCore": "0.1-alpha-*", "Microsoft.AspNet.Security.DataProtection": "0.1-alpha-*", "Microsoft.Framework.DependencyInjection": "0.1-alpha-*", "Microsoft.Framework.Logging": "0.1-alpha-*" @@ -14,8 +14,8 @@ "k10": { "dependencies": { "System.Collections": "4.0.0.0", - "System.Console": "4.0.0.0", "System.ComponentModel": "4.0.0.0", + "System.Console": "4.0.0.0", "System.Diagnostics.Debug": "4.0.10.0", "System.Diagnostics.Tools": "4.0.0.0", "System.Globalization": "4.0.10.0", diff --git a/test/Microsoft.AspNet.Security.Test/project.json b/test/Microsoft.AspNet.Security.Test/project.json index cfdc5ed7f..a7587932d 100644 --- a/test/Microsoft.AspNet.Security.Test/project.json +++ b/test/Microsoft.AspNet.Security.Test/project.json @@ -6,11 +6,11 @@ "dependencies": { "Microsoft.AspNet.Security" : "0.1-alpha-*", "Moq": "4.2.1312.1622", - "Xunit.KRunner": "0.1-alpha-*", "xunit.abstractions": "2.0.0-aspnet-*", "xunit.assert": "2.0.0-aspnet-*", "xunit.core": "2.0.0-aspnet-*", - "xunit.execution": "2.0.0-aspnet-*" + "xunit.execution": "2.0.0-aspnet-*", + "Xunit.KRunner": "0.1-alpha-*" }, "commands": { "test": "Xunit.KRunner" From 9d0de16073b74a7df11ac3f6d502a2a7abfa4d46 Mon Sep 17 00:00:00 2001 From: Eilon Lipton Date: Thu, 8 May 2014 16:35:28 -0700 Subject: [PATCH 003/216] Create LICENSE.txt --- LICENSE.txt | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 LICENSE.txt diff --git a/LICENSE.txt b/LICENSE.txt new file mode 100644 index 000000000..d85a1524a --- /dev/null +++ b/LICENSE.txt @@ -0,0 +1,12 @@ +Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); you may not use +these files except in compliance with the License. You may obtain a copy of the +License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software distributed +under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +CONDITIONS OF ANY KIND, either express or implied. See the License for the +specific language governing permissions and limitations under the License. From d02f76a2fd11508dc3eccdc99c4610fefb17e66d Mon Sep 17 00:00:00 2001 From: Andrew Peters Date: Thu, 8 May 2014 23:01:33 -0700 Subject: [PATCH 004/216] Updating copyright headers --- .../CookieAuthenticationDefaults.cs | 4 +++- .../CookieAuthenticationExtensions.cs | 4 +++- .../CookieAuthenticationHandler.cs | 4 +++- .../CookieAuthenticationMiddleware.cs | 4 +++- .../CookieAuthenticationOptions.cs | 4 +++- .../CookieSecureOption.cs | 4 +++- .../NotNullAttribute.cs | 5 ++++- .../CookieApplyRedirectContext.cs | 4 +++- .../CookieAuthenticationNotifications.cs | 4 +++- .../CookieResponseSignInContext.cs | 4 +++- .../CookieResponseSignOutContext.cs | 4 +++- .../CookieValidateIdentityContext.cs | 4 +++- .../Notifications/DefaultBehavior.cs | 4 +++- .../ICookieAuthenticationNotifications.cs | 4 +++- .../AppBuilderSecurityExtensions.cs | 4 +++- .../AuthenticationMode.cs | 4 +++- .../AuthenticationOptions.cs | 4 +++- .../AuthenticationTicket.cs | 4 +++- .../AuthorizationPolicy.cs | 18 ++---------------- .../AuthorizationPolicyContext.cs | 18 ++---------------- .../AuthorizationServiceExtensions.cs | 18 ++---------------- ...CertificateSubjectKeyIdentifierValidator.cs | 4 +++- ...CertificateSubjectPublicKeyInfoValidator.cs | 4 +++- .../CertificateThumbprintValidator.cs | 4 +++- src/Microsoft.AspNet.Security/Constants.cs | 4 +++- .../DataHandler/Encoder/Base64TextEncoder.cs | 4 +++- .../Encoder/Base64UrlTextEncoder.cs | 4 +++- .../DataHandler/Encoder/ITextEncoder.cs | 4 +++- .../DataHandler/Encoder/TextEncodings.cs | 4 +++- .../DataHandler/ISecureDataFormat.cs | 4 +++- .../DataHandler/PropertiesDataFormat.cs | 4 +++- .../DataHandler/SecureDataFormat.cs | 4 +++- .../DataHandler/Serializer/DataSerializers.cs | 4 +++- .../DataHandler/Serializer/IDataSerializer.cs | 4 +++- .../Serializer/PropertiesSerializer.cs | 4 +++- .../DataHandler/Serializer/TicketSerializer.cs | 4 +++- .../DataHandler/TicketDataFormat.cs | 4 +++- .../DataProtection/DataProtectionHelpers.cs | 4 +++- .../DefaultAuthorizationService.cs | 18 ++---------------- .../IAuthorizationPolicy.cs | 18 ++---------------- .../IAuthorizationService.cs | 18 ++---------------- .../ICertificateValidator.cs | 4 +++- .../Infrastructure/AuthenticationHandler.cs | 4 +++- .../Infrastructure/AuthenticationHandler`1.cs | 4 +++- .../Infrastructure/AuthenticationMiddleware.cs | 4 +++- .../AuthenticationTokenCreateContext.cs | 4 +++- .../AuthenticationTokenProvider.cs | 4 +++- .../AuthenticationTokenReceiveContext.cs | 4 +++- .../Infrastructure/Constants.cs | 4 +++- .../Infrastructure/HttpContextExtensions.cs | 5 ++++- .../IAuthenticationTokenProvider.cs | 4 +++- .../Infrastructure/ISystemClock.cs | 4 +++- .../Infrastructure/NotNullAttribute.cs | 5 ++++- .../Infrastructure/SecurityHelper.cs | 4 +++- .../Infrastructure/SignInIdentityContext.cs | 5 ++++- .../Infrastructure/SystemClock.cs | 4 +++- .../AuthenticationFailedNotification.cs | 4 +++- .../Notifications/BaseContext.cs | 4 +++- .../Notifications/BaseContext`1.cs | 4 +++- .../Notifications/EndpointContext.cs | 4 +++- .../Notifications/EndpointContext`1.cs | 4 +++- .../MessageReceivedNotification.cs | 4 +++- ...RedirectFromIdentityProviderNotification.cs | 4 +++- .../RedirectToIdentityProviderNotification.cs | 4 +++- .../Notifications/ReturnEndpointContext.cs | 4 +++- .../SecurityTokenReceivedNotification.cs | 4 +++- .../SecurityTokenValidatedNotification.cs | 4 +++- .../SubjectPublicKeyInfoAlgorithm.cs | 4 +++- src/Microsoft.AspNet.Security/Win32.cs | 4 +++- .../DefaultAuthorizationServiceTests.cs | 5 ++++- .../FakePolicy.cs | 3 +++ 71 files changed, 212 insertions(+), 160 deletions(-) diff --git a/src/Microsoft.AspNet.Security.Cookies/CookieAuthenticationDefaults.cs b/src/Microsoft.AspNet.Security.Cookies/CookieAuthenticationDefaults.cs index 3ea10afb9..6ee3c8c5b 100644 --- a/src/Microsoft.AspNet.Security.Cookies/CookieAuthenticationDefaults.cs +++ b/src/Microsoft.AspNet.Security.Cookies/CookieAuthenticationDefaults.cs @@ -1,4 +1,6 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + using System.Diagnostics.CodeAnalysis; using Microsoft.AspNet.Http; diff --git a/src/Microsoft.AspNet.Security.Cookies/CookieAuthenticationExtensions.cs b/src/Microsoft.AspNet.Security.Cookies/CookieAuthenticationExtensions.cs index 5df523161..91109f4ce 100644 --- a/src/Microsoft.AspNet.Security.Cookies/CookieAuthenticationExtensions.cs +++ b/src/Microsoft.AspNet.Security.Cookies/CookieAuthenticationExtensions.cs @@ -1,4 +1,6 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + using Microsoft.AspNet.Http; using Microsoft.AspNet.Security.Cookies; diff --git a/src/Microsoft.AspNet.Security.Cookies/CookieAuthenticationHandler.cs b/src/Microsoft.AspNet.Security.Cookies/CookieAuthenticationHandler.cs index 03ad97927..44d81db7f 100644 --- a/src/Microsoft.AspNet.Security.Cookies/CookieAuthenticationHandler.cs +++ b/src/Microsoft.AspNet.Security.Cookies/CookieAuthenticationHandler.cs @@ -1,4 +1,6 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + using System; using System.Threading.Tasks; diff --git a/src/Microsoft.AspNet.Security.Cookies/CookieAuthenticationMiddleware.cs b/src/Microsoft.AspNet.Security.Cookies/CookieAuthenticationMiddleware.cs index 9fde9e7d8..423ec040b 100644 --- a/src/Microsoft.AspNet.Security.Cookies/CookieAuthenticationMiddleware.cs +++ b/src/Microsoft.AspNet.Security.Cookies/CookieAuthenticationMiddleware.cs @@ -1,4 +1,6 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + using System; using Microsoft.AspNet.Builder; diff --git a/src/Microsoft.AspNet.Security.Cookies/CookieAuthenticationOptions.cs b/src/Microsoft.AspNet.Security.Cookies/CookieAuthenticationOptions.cs index 3fa5cb5e8..60565c812 100644 --- a/src/Microsoft.AspNet.Security.Cookies/CookieAuthenticationOptions.cs +++ b/src/Microsoft.AspNet.Security.Cookies/CookieAuthenticationOptions.cs @@ -1,4 +1,6 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + using System; using System.Diagnostics.CodeAnalysis; diff --git a/src/Microsoft.AspNet.Security.Cookies/CookieSecureOption.cs b/src/Microsoft.AspNet.Security.Cookies/CookieSecureOption.cs index 19efae749..c98ae0751 100644 --- a/src/Microsoft.AspNet.Security.Cookies/CookieSecureOption.cs +++ b/src/Microsoft.AspNet.Security.Cookies/CookieSecureOption.cs @@ -1,4 +1,6 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + namespace Microsoft.AspNet.Security.Cookies { diff --git a/src/Microsoft.AspNet.Security.Cookies/NotNullAttribute.cs b/src/Microsoft.AspNet.Security.Cookies/NotNullAttribute.cs index b3b1edcbd..0460d0016 100644 --- a/src/Microsoft.AspNet.Security.Cookies/NotNullAttribute.cs +++ b/src/Microsoft.AspNet.Security.Cookies/NotNullAttribute.cs @@ -1,4 +1,7 @@ -using System; +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; namespace Microsoft.AspNet.Security.Cookies { diff --git a/src/Microsoft.AspNet.Security.Cookies/Notifications/CookieApplyRedirectContext.cs b/src/Microsoft.AspNet.Security.Cookies/Notifications/CookieApplyRedirectContext.cs index 9d0aca22c..28cdf713c 100644 --- a/src/Microsoft.AspNet.Security.Cookies/Notifications/CookieApplyRedirectContext.cs +++ b/src/Microsoft.AspNet.Security.Cookies/Notifications/CookieApplyRedirectContext.cs @@ -1,4 +1,6 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + using System.Diagnostics.CodeAnalysis; using Microsoft.AspNet.Http; diff --git a/src/Microsoft.AspNet.Security.Cookies/Notifications/CookieAuthenticationNotifications.cs b/src/Microsoft.AspNet.Security.Cookies/Notifications/CookieAuthenticationNotifications.cs index f3496bbc7..79b7e5bd9 100644 --- a/src/Microsoft.AspNet.Security.Cookies/Notifications/CookieAuthenticationNotifications.cs +++ b/src/Microsoft.AspNet.Security.Cookies/Notifications/CookieAuthenticationNotifications.cs @@ -1,4 +1,6 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + using System; using System.Threading.Tasks; diff --git a/src/Microsoft.AspNet.Security.Cookies/Notifications/CookieResponseSignInContext.cs b/src/Microsoft.AspNet.Security.Cookies/Notifications/CookieResponseSignInContext.cs index 375c85181..598f985f5 100644 --- a/src/Microsoft.AspNet.Security.Cookies/Notifications/CookieResponseSignInContext.cs +++ b/src/Microsoft.AspNet.Security.Cookies/Notifications/CookieResponseSignInContext.cs @@ -1,4 +1,6 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + using System.Security.Claims; using Microsoft.AspNet.Http; diff --git a/src/Microsoft.AspNet.Security.Cookies/Notifications/CookieResponseSignOutContext.cs b/src/Microsoft.AspNet.Security.Cookies/Notifications/CookieResponseSignOutContext.cs index 7dbd45137..b484b7436 100644 --- a/src/Microsoft.AspNet.Security.Cookies/Notifications/CookieResponseSignOutContext.cs +++ b/src/Microsoft.AspNet.Security.Cookies/Notifications/CookieResponseSignOutContext.cs @@ -1,4 +1,6 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + using Microsoft.AspNet.Http; using Microsoft.AspNet.Security.Notifications; diff --git a/src/Microsoft.AspNet.Security.Cookies/Notifications/CookieValidateIdentityContext.cs b/src/Microsoft.AspNet.Security.Cookies/Notifications/CookieValidateIdentityContext.cs index 3996a9585..ea1682204 100644 --- a/src/Microsoft.AspNet.Security.Cookies/Notifications/CookieValidateIdentityContext.cs +++ b/src/Microsoft.AspNet.Security.Cookies/Notifications/CookieValidateIdentityContext.cs @@ -1,4 +1,6 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + using System; using System.Security.Claims; diff --git a/src/Microsoft.AspNet.Security.Cookies/Notifications/DefaultBehavior.cs b/src/Microsoft.AspNet.Security.Cookies/Notifications/DefaultBehavior.cs index 98b7da1c8..65515c329 100644 --- a/src/Microsoft.AspNet.Security.Cookies/Notifications/DefaultBehavior.cs +++ b/src/Microsoft.AspNet.Security.Cookies/Notifications/DefaultBehavior.cs @@ -1,4 +1,6 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + using System; using Microsoft.AspNet.Http; diff --git a/src/Microsoft.AspNet.Security.Cookies/Notifications/ICookieAuthenticationNotifications.cs b/src/Microsoft.AspNet.Security.Cookies/Notifications/ICookieAuthenticationNotifications.cs index c9c07d227..f97a4546e 100644 --- a/src/Microsoft.AspNet.Security.Cookies/Notifications/ICookieAuthenticationNotifications.cs +++ b/src/Microsoft.AspNet.Security.Cookies/Notifications/ICookieAuthenticationNotifications.cs @@ -1,4 +1,6 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + using System.Threading.Tasks; diff --git a/src/Microsoft.AspNet.Security/AppBuilderSecurityExtensions.cs b/src/Microsoft.AspNet.Security/AppBuilderSecurityExtensions.cs index 077cdbd53..ca9c39427 100644 --- a/src/Microsoft.AspNet.Security/AppBuilderSecurityExtensions.cs +++ b/src/Microsoft.AspNet.Security/AppBuilderSecurityExtensions.cs @@ -1,4 +1,6 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + /* TODO: using System; using Owin; diff --git a/src/Microsoft.AspNet.Security/AuthenticationMode.cs b/src/Microsoft.AspNet.Security/AuthenticationMode.cs index ba7aff904..2b36dc973 100644 --- a/src/Microsoft.AspNet.Security/AuthenticationMode.cs +++ b/src/Microsoft.AspNet.Security/AuthenticationMode.cs @@ -1,4 +1,6 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + namespace Microsoft.AspNet.Security { diff --git a/src/Microsoft.AspNet.Security/AuthenticationOptions.cs b/src/Microsoft.AspNet.Security/AuthenticationOptions.cs index 719132212..77e8fa03a 100644 --- a/src/Microsoft.AspNet.Security/AuthenticationOptions.cs +++ b/src/Microsoft.AspNet.Security/AuthenticationOptions.cs @@ -1,4 +1,6 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + using System; using System.Collections.Generic; diff --git a/src/Microsoft.AspNet.Security/AuthenticationTicket.cs b/src/Microsoft.AspNet.Security/AuthenticationTicket.cs index 5adb20b7e..b9457aa91 100644 --- a/src/Microsoft.AspNet.Security/AuthenticationTicket.cs +++ b/src/Microsoft.AspNet.Security/AuthenticationTicket.cs @@ -1,4 +1,6 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + using System; using System.Collections.Generic; diff --git a/src/Microsoft.AspNet.Security/AuthorizationPolicy.cs b/src/Microsoft.AspNet.Security/AuthorizationPolicy.cs index 157b71047..a58ae858a 100644 --- a/src/Microsoft.AspNet.Security/AuthorizationPolicy.cs +++ b/src/Microsoft.AspNet.Security/AuthorizationPolicy.cs @@ -1,19 +1,5 @@ -// Copyright (c) Microsoft Open Technologies, Inc. -// All Rights Reserved -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR -// CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING -// WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR CONDITIONS OF -// TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR -// NON-INFRINGEMENT. -// See the Apache 2 License for the specific language governing -// permissions and limitations under the License. +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System.Collections.Generic; using System.Security.Claims; diff --git a/src/Microsoft.AspNet.Security/AuthorizationPolicyContext.cs b/src/Microsoft.AspNet.Security/AuthorizationPolicyContext.cs index 4055fddbd..b394bfcb6 100644 --- a/src/Microsoft.AspNet.Security/AuthorizationPolicyContext.cs +++ b/src/Microsoft.AspNet.Security/AuthorizationPolicyContext.cs @@ -1,19 +1,5 @@ -// Copyright (c) Microsoft Open Technologies, Inc. -// All Rights Reserved -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR -// CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING -// WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR CONDITIONS OF -// TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR -// NON-INFRINGEMENT. -// See the Apache 2 License for the specific language governing -// permissions and limitations under the License. +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System.Collections.Generic; using System.Security.Claims; diff --git a/src/Microsoft.AspNet.Security/AuthorizationServiceExtensions.cs b/src/Microsoft.AspNet.Security/AuthorizationServiceExtensions.cs index 158314a15..b26c636e7 100644 --- a/src/Microsoft.AspNet.Security/AuthorizationServiceExtensions.cs +++ b/src/Microsoft.AspNet.Security/AuthorizationServiceExtensions.cs @@ -1,19 +1,5 @@ -// Copyright (c) Microsoft Open Technologies, Inc. -// All Rights Reserved -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR -// CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING -// WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR CONDITIONS OF -// TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR -// NON-INFRINGEMENT. -// See the Apache 2 License for the specific language governing -// permissions and limitations under the License. +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; using System.Collections.Generic; diff --git a/src/Microsoft.AspNet.Security/CertificateSubjectKeyIdentifierValidator.cs b/src/Microsoft.AspNet.Security/CertificateSubjectKeyIdentifierValidator.cs index d25bb7223..d91311202 100644 --- a/src/Microsoft.AspNet.Security/CertificateSubjectKeyIdentifierValidator.cs +++ b/src/Microsoft.AspNet.Security/CertificateSubjectKeyIdentifierValidator.cs @@ -1,4 +1,6 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + #if NET45 using System; using System.Collections.Generic; diff --git a/src/Microsoft.AspNet.Security/CertificateSubjectPublicKeyInfoValidator.cs b/src/Microsoft.AspNet.Security/CertificateSubjectPublicKeyInfoValidator.cs index 79645c50d..a0ba22310 100644 --- a/src/Microsoft.AspNet.Security/CertificateSubjectPublicKeyInfoValidator.cs +++ b/src/Microsoft.AspNet.Security/CertificateSubjectPublicKeyInfoValidator.cs @@ -1,4 +1,6 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + #if NET45 using System; using System.Collections.Generic; diff --git a/src/Microsoft.AspNet.Security/CertificateThumbprintValidator.cs b/src/Microsoft.AspNet.Security/CertificateThumbprintValidator.cs index 5661d5591..9a9dadf60 100644 --- a/src/Microsoft.AspNet.Security/CertificateThumbprintValidator.cs +++ b/src/Microsoft.AspNet.Security/CertificateThumbprintValidator.cs @@ -1,4 +1,6 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + #if NET45 using System; using System.Collections.Generic; diff --git a/src/Microsoft.AspNet.Security/Constants.cs b/src/Microsoft.AspNet.Security/Constants.cs index 50d4dfe0a..1758c8480 100644 --- a/src/Microsoft.AspNet.Security/Constants.cs +++ b/src/Microsoft.AspNet.Security/Constants.cs @@ -1,4 +1,6 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + namespace Microsoft.AspNet.Security { diff --git a/src/Microsoft.AspNet.Security/DataHandler/Encoder/Base64TextEncoder.cs b/src/Microsoft.AspNet.Security/DataHandler/Encoder/Base64TextEncoder.cs index 29acfcb20..9a208979d 100644 --- a/src/Microsoft.AspNet.Security/DataHandler/Encoder/Base64TextEncoder.cs +++ b/src/Microsoft.AspNet.Security/DataHandler/Encoder/Base64TextEncoder.cs @@ -1,4 +1,6 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + using System; diff --git a/src/Microsoft.AspNet.Security/DataHandler/Encoder/Base64UrlTextEncoder.cs b/src/Microsoft.AspNet.Security/DataHandler/Encoder/Base64UrlTextEncoder.cs index 250ea7019..b57fb51d9 100644 --- a/src/Microsoft.AspNet.Security/DataHandler/Encoder/Base64UrlTextEncoder.cs +++ b/src/Microsoft.AspNet.Security/DataHandler/Encoder/Base64UrlTextEncoder.cs @@ -1,4 +1,6 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + using System; diff --git a/src/Microsoft.AspNet.Security/DataHandler/Encoder/ITextEncoder.cs b/src/Microsoft.AspNet.Security/DataHandler/Encoder/ITextEncoder.cs index ce61e8fb9..6ee681475 100644 --- a/src/Microsoft.AspNet.Security/DataHandler/Encoder/ITextEncoder.cs +++ b/src/Microsoft.AspNet.Security/DataHandler/Encoder/ITextEncoder.cs @@ -1,4 +1,6 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + namespace Microsoft.AspNet.Security.DataHandler.Encoder { diff --git a/src/Microsoft.AspNet.Security/DataHandler/Encoder/TextEncodings.cs b/src/Microsoft.AspNet.Security/DataHandler/Encoder/TextEncodings.cs index 45b29107d..67b233376 100644 --- a/src/Microsoft.AspNet.Security/DataHandler/Encoder/TextEncodings.cs +++ b/src/Microsoft.AspNet.Security/DataHandler/Encoder/TextEncodings.cs @@ -1,4 +1,6 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + namespace Microsoft.AspNet.Security.DataHandler.Encoder { diff --git a/src/Microsoft.AspNet.Security/DataHandler/ISecureDataFormat.cs b/src/Microsoft.AspNet.Security/DataHandler/ISecureDataFormat.cs index f239150ba..eae66197f 100644 --- a/src/Microsoft.AspNet.Security/DataHandler/ISecureDataFormat.cs +++ b/src/Microsoft.AspNet.Security/DataHandler/ISecureDataFormat.cs @@ -1,4 +1,6 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + namespace Microsoft.AspNet.Security { diff --git a/src/Microsoft.AspNet.Security/DataHandler/PropertiesDataFormat.cs b/src/Microsoft.AspNet.Security/DataHandler/PropertiesDataFormat.cs index 4c4122350..42f71728c 100644 --- a/src/Microsoft.AspNet.Security/DataHandler/PropertiesDataFormat.cs +++ b/src/Microsoft.AspNet.Security/DataHandler/PropertiesDataFormat.cs @@ -1,4 +1,6 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + using Microsoft.AspNet.Http.Security; using Microsoft.AspNet.Security.DataHandler.Encoder; diff --git a/src/Microsoft.AspNet.Security/DataHandler/SecureDataFormat.cs b/src/Microsoft.AspNet.Security/DataHandler/SecureDataFormat.cs index fa045e780..e10d17db1 100644 --- a/src/Microsoft.AspNet.Security/DataHandler/SecureDataFormat.cs +++ b/src/Microsoft.AspNet.Security/DataHandler/SecureDataFormat.cs @@ -1,4 +1,6 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + using System.Diagnostics.CodeAnalysis; using Microsoft.AspNet.Security.DataHandler.Encoder; diff --git a/src/Microsoft.AspNet.Security/DataHandler/Serializer/DataSerializers.cs b/src/Microsoft.AspNet.Security/DataHandler/Serializer/DataSerializers.cs index faf395aab..476fe7bb7 100644 --- a/src/Microsoft.AspNet.Security/DataHandler/Serializer/DataSerializers.cs +++ b/src/Microsoft.AspNet.Security/DataHandler/Serializer/DataSerializers.cs @@ -1,4 +1,6 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + using Microsoft.AspNet.Http.Security; diff --git a/src/Microsoft.AspNet.Security/DataHandler/Serializer/IDataSerializer.cs b/src/Microsoft.AspNet.Security/DataHandler/Serializer/IDataSerializer.cs index 8b9b77ae0..60bd25bda 100644 --- a/src/Microsoft.AspNet.Security/DataHandler/Serializer/IDataSerializer.cs +++ b/src/Microsoft.AspNet.Security/DataHandler/Serializer/IDataSerializer.cs @@ -1,4 +1,6 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + namespace Microsoft.AspNet.Security.DataHandler.Serializer { diff --git a/src/Microsoft.AspNet.Security/DataHandler/Serializer/PropertiesSerializer.cs b/src/Microsoft.AspNet.Security/DataHandler/Serializer/PropertiesSerializer.cs index d8bfc7209..66dcdfe3a 100644 --- a/src/Microsoft.AspNet.Security/DataHandler/Serializer/PropertiesSerializer.cs +++ b/src/Microsoft.AspNet.Security/DataHandler/Serializer/PropertiesSerializer.cs @@ -1,4 +1,6 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + using System; using System.Collections.Generic; diff --git a/src/Microsoft.AspNet.Security/DataHandler/Serializer/TicketSerializer.cs b/src/Microsoft.AspNet.Security/DataHandler/Serializer/TicketSerializer.cs index 70406d1d9..c6dbfc132 100644 --- a/src/Microsoft.AspNet.Security/DataHandler/Serializer/TicketSerializer.cs +++ b/src/Microsoft.AspNet.Security/DataHandler/Serializer/TicketSerializer.cs @@ -1,4 +1,6 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + using System; using System.Collections.Generic; diff --git a/src/Microsoft.AspNet.Security/DataHandler/TicketDataFormat.cs b/src/Microsoft.AspNet.Security/DataHandler/TicketDataFormat.cs index 8d0d0c69f..acc731e0b 100644 --- a/src/Microsoft.AspNet.Security/DataHandler/TicketDataFormat.cs +++ b/src/Microsoft.AspNet.Security/DataHandler/TicketDataFormat.cs @@ -1,4 +1,6 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + using Microsoft.AspNet.Security.DataHandler.Encoder; using Microsoft.AspNet.Security.DataHandler.Serializer; diff --git a/src/Microsoft.AspNet.Security/DataProtection/DataProtectionHelpers.cs b/src/Microsoft.AspNet.Security/DataProtection/DataProtectionHelpers.cs index 96b151e81..a043bb83b 100644 --- a/src/Microsoft.AspNet.Security/DataProtection/DataProtectionHelpers.cs +++ b/src/Microsoft.AspNet.Security/DataProtection/DataProtectionHelpers.cs @@ -1,4 +1,6 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + using System; using Microsoft.AspNet.Http; diff --git a/src/Microsoft.AspNet.Security/DefaultAuthorizationService.cs b/src/Microsoft.AspNet.Security/DefaultAuthorizationService.cs index 129290152..578671e95 100644 --- a/src/Microsoft.AspNet.Security/DefaultAuthorizationService.cs +++ b/src/Microsoft.AspNet.Security/DefaultAuthorizationService.cs @@ -1,19 +1,5 @@ -// Copyright (c) Microsoft Open Technologies, Inc. -// All Rights Reserved -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR -// CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING -// WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR CONDITIONS OF -// TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR -// NON-INFRINGEMENT. -// See the Apache 2 License for the specific language governing -// permissions and limitations under the License. +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; using System.Collections.Generic; diff --git a/src/Microsoft.AspNet.Security/IAuthorizationPolicy.cs b/src/Microsoft.AspNet.Security/IAuthorizationPolicy.cs index 395549065..0f121d558 100644 --- a/src/Microsoft.AspNet.Security/IAuthorizationPolicy.cs +++ b/src/Microsoft.AspNet.Security/IAuthorizationPolicy.cs @@ -1,19 +1,5 @@ -// Copyright (c) Microsoft Open Technologies, Inc. -// All Rights Reserved -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR -// CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING -// WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR CONDITIONS OF -// TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR -// NON-INFRINGEMENT. -// See the Apache 2 License for the specific language governing -// permissions and limitations under the License. +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System.Threading.Tasks; diff --git a/src/Microsoft.AspNet.Security/IAuthorizationService.cs b/src/Microsoft.AspNet.Security/IAuthorizationService.cs index cbd705c8f..2063ae646 100644 --- a/src/Microsoft.AspNet.Security/IAuthorizationService.cs +++ b/src/Microsoft.AspNet.Security/IAuthorizationService.cs @@ -1,19 +1,5 @@ -// Copyright (c) Microsoft Open Technologies, Inc. -// All Rights Reserved -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR -// CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING -// WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR CONDITIONS OF -// TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR -// NON-INFRINGEMENT. -// See the Apache 2 License for the specific language governing -// permissions and limitations under the License. +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System.Collections.Generic; using System.Security.Claims; diff --git a/src/Microsoft.AspNet.Security/ICertificateValidator.cs b/src/Microsoft.AspNet.Security/ICertificateValidator.cs index 3b84fb485..3157a5c5a 100644 --- a/src/Microsoft.AspNet.Security/ICertificateValidator.cs +++ b/src/Microsoft.AspNet.Security/ICertificateValidator.cs @@ -1,4 +1,6 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + #if NET45 using System; using System.Net.Security; diff --git a/src/Microsoft.AspNet.Security/Infrastructure/AuthenticationHandler.cs b/src/Microsoft.AspNet.Security/Infrastructure/AuthenticationHandler.cs index 313038e26..45dadda9e 100644 --- a/src/Microsoft.AspNet.Security/Infrastructure/AuthenticationHandler.cs +++ b/src/Microsoft.AspNet.Security/Infrastructure/AuthenticationHandler.cs @@ -1,4 +1,6 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + using System; using System.Collections.Generic; diff --git a/src/Microsoft.AspNet.Security/Infrastructure/AuthenticationHandler`1.cs b/src/Microsoft.AspNet.Security/Infrastructure/AuthenticationHandler`1.cs index 80944261c..7d8fb0726 100644 --- a/src/Microsoft.AspNet.Security/Infrastructure/AuthenticationHandler`1.cs +++ b/src/Microsoft.AspNet.Security/Infrastructure/AuthenticationHandler`1.cs @@ -1,4 +1,6 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + using System.Threading.Tasks; using Microsoft.AspNet.Http; diff --git a/src/Microsoft.AspNet.Security/Infrastructure/AuthenticationMiddleware.cs b/src/Microsoft.AspNet.Security/Infrastructure/AuthenticationMiddleware.cs index 726028c6d..8077b22d6 100644 --- a/src/Microsoft.AspNet.Security/Infrastructure/AuthenticationMiddleware.cs +++ b/src/Microsoft.AspNet.Security/Infrastructure/AuthenticationMiddleware.cs @@ -1,4 +1,6 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + using System; using System.Threading.Tasks; diff --git a/src/Microsoft.AspNet.Security/Infrastructure/AuthenticationTokenCreateContext.cs b/src/Microsoft.AspNet.Security/Infrastructure/AuthenticationTokenCreateContext.cs index 3a96006c5..47815bbcd 100644 --- a/src/Microsoft.AspNet.Security/Infrastructure/AuthenticationTokenCreateContext.cs +++ b/src/Microsoft.AspNet.Security/Infrastructure/AuthenticationTokenCreateContext.cs @@ -1,4 +1,6 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + using System; using Microsoft.AspNet.Http; diff --git a/src/Microsoft.AspNet.Security/Infrastructure/AuthenticationTokenProvider.cs b/src/Microsoft.AspNet.Security/Infrastructure/AuthenticationTokenProvider.cs index c8beb6f0b..7fb4fb498 100644 --- a/src/Microsoft.AspNet.Security/Infrastructure/AuthenticationTokenProvider.cs +++ b/src/Microsoft.AspNet.Security/Infrastructure/AuthenticationTokenProvider.cs @@ -1,4 +1,6 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + using System; using System.Threading.Tasks; diff --git a/src/Microsoft.AspNet.Security/Infrastructure/AuthenticationTokenReceiveContext.cs b/src/Microsoft.AspNet.Security/Infrastructure/AuthenticationTokenReceiveContext.cs index 0f6d6bce0..af077b551 100644 --- a/src/Microsoft.AspNet.Security/Infrastructure/AuthenticationTokenReceiveContext.cs +++ b/src/Microsoft.AspNet.Security/Infrastructure/AuthenticationTokenReceiveContext.cs @@ -1,4 +1,6 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + using System; using Microsoft.AspNet.Http; diff --git a/src/Microsoft.AspNet.Security/Infrastructure/Constants.cs b/src/Microsoft.AspNet.Security/Infrastructure/Constants.cs index 73a8f7958..26cfa103c 100644 --- a/src/Microsoft.AspNet.Security/Infrastructure/Constants.cs +++ b/src/Microsoft.AspNet.Security/Infrastructure/Constants.cs @@ -1,4 +1,6 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + namespace Microsoft.AspNet.Security.Infrastructure { diff --git a/src/Microsoft.AspNet.Security/Infrastructure/HttpContextExtensions.cs b/src/Microsoft.AspNet.Security/Infrastructure/HttpContextExtensions.cs index 4336544d3..59c29fe82 100644 --- a/src/Microsoft.AspNet.Security/Infrastructure/HttpContextExtensions.cs +++ b/src/Microsoft.AspNet.Security/Infrastructure/HttpContextExtensions.cs @@ -1,4 +1,7 @@ -using Microsoft.AspNet.Http; +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using Microsoft.AspNet.Http; using Microsoft.AspNet.HttpFeature.Security; using Microsoft.AspNet.PipelineCore.Security; diff --git a/src/Microsoft.AspNet.Security/Infrastructure/IAuthenticationTokenProvider.cs b/src/Microsoft.AspNet.Security/Infrastructure/IAuthenticationTokenProvider.cs index 7bda97d3a..2edcb42b2 100644 --- a/src/Microsoft.AspNet.Security/Infrastructure/IAuthenticationTokenProvider.cs +++ b/src/Microsoft.AspNet.Security/Infrastructure/IAuthenticationTokenProvider.cs @@ -1,4 +1,6 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + using System.Threading.Tasks; diff --git a/src/Microsoft.AspNet.Security/Infrastructure/ISystemClock.cs b/src/Microsoft.AspNet.Security/Infrastructure/ISystemClock.cs index cca20fbcb..4f799dc98 100644 --- a/src/Microsoft.AspNet.Security/Infrastructure/ISystemClock.cs +++ b/src/Microsoft.AspNet.Security/Infrastructure/ISystemClock.cs @@ -1,4 +1,6 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + using System; diff --git a/src/Microsoft.AspNet.Security/Infrastructure/NotNullAttribute.cs b/src/Microsoft.AspNet.Security/Infrastructure/NotNullAttribute.cs index 131cec58e..24f550945 100644 --- a/src/Microsoft.AspNet.Security/Infrastructure/NotNullAttribute.cs +++ b/src/Microsoft.AspNet.Security/Infrastructure/NotNullAttribute.cs @@ -1,4 +1,7 @@ -using System; +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; namespace Microsoft.AspNet.Security { diff --git a/src/Microsoft.AspNet.Security/Infrastructure/SecurityHelper.cs b/src/Microsoft.AspNet.Security/Infrastructure/SecurityHelper.cs index 436101fa9..7a8456d5e 100644 --- a/src/Microsoft.AspNet.Security/Infrastructure/SecurityHelper.cs +++ b/src/Microsoft.AspNet.Security/Infrastructure/SecurityHelper.cs @@ -1,4 +1,6 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + using System; using System.Collections.Generic; diff --git a/src/Microsoft.AspNet.Security/Infrastructure/SignInIdentityContext.cs b/src/Microsoft.AspNet.Security/Infrastructure/SignInIdentityContext.cs index 52c2ddff1..309e04892 100644 --- a/src/Microsoft.AspNet.Security/Infrastructure/SignInIdentityContext.cs +++ b/src/Microsoft.AspNet.Security/Infrastructure/SignInIdentityContext.cs @@ -1,4 +1,7 @@ -using System.Security.Claims; +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System.Security.Claims; using Microsoft.AspNet.Http.Security; namespace Microsoft.AspNet.Security.Infrastructure diff --git a/src/Microsoft.AspNet.Security/Infrastructure/SystemClock.cs b/src/Microsoft.AspNet.Security/Infrastructure/SystemClock.cs index 2dcbca0fe..0c800d3fd 100644 --- a/src/Microsoft.AspNet.Security/Infrastructure/SystemClock.cs +++ b/src/Microsoft.AspNet.Security/Infrastructure/SystemClock.cs @@ -1,4 +1,6 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + using System; diff --git a/src/Microsoft.AspNet.Security/Notifications/AuthenticationFailedNotification.cs b/src/Microsoft.AspNet.Security/Notifications/AuthenticationFailedNotification.cs index 77c193bb4..9e50ecf4f 100644 --- a/src/Microsoft.AspNet.Security/Notifications/AuthenticationFailedNotification.cs +++ b/src/Microsoft.AspNet.Security/Notifications/AuthenticationFailedNotification.cs @@ -1,4 +1,6 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + using System; diff --git a/src/Microsoft.AspNet.Security/Notifications/BaseContext.cs b/src/Microsoft.AspNet.Security/Notifications/BaseContext.cs index 2ad464e37..3ae13a76d 100644 --- a/src/Microsoft.AspNet.Security/Notifications/BaseContext.cs +++ b/src/Microsoft.AspNet.Security/Notifications/BaseContext.cs @@ -1,4 +1,6 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + using Microsoft.AspNet.Http; diff --git a/src/Microsoft.AspNet.Security/Notifications/BaseContext`1.cs b/src/Microsoft.AspNet.Security/Notifications/BaseContext`1.cs index 5073cd183..e0ad30626 100644 --- a/src/Microsoft.AspNet.Security/Notifications/BaseContext`1.cs +++ b/src/Microsoft.AspNet.Security/Notifications/BaseContext`1.cs @@ -1,4 +1,6 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + using Microsoft.AspNet.Http; diff --git a/src/Microsoft.AspNet.Security/Notifications/EndpointContext.cs b/src/Microsoft.AspNet.Security/Notifications/EndpointContext.cs index 214a724a4..fd8251e13 100644 --- a/src/Microsoft.AspNet.Security/Notifications/EndpointContext.cs +++ b/src/Microsoft.AspNet.Security/Notifications/EndpointContext.cs @@ -1,4 +1,6 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + using Microsoft.AspNet.Http; diff --git a/src/Microsoft.AspNet.Security/Notifications/EndpointContext`1.cs b/src/Microsoft.AspNet.Security/Notifications/EndpointContext`1.cs index 80b5c2c55..7b0b415e8 100644 --- a/src/Microsoft.AspNet.Security/Notifications/EndpointContext`1.cs +++ b/src/Microsoft.AspNet.Security/Notifications/EndpointContext`1.cs @@ -1,4 +1,6 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + using Microsoft.AspNet.Http; diff --git a/src/Microsoft.AspNet.Security/Notifications/MessageReceivedNotification.cs b/src/Microsoft.AspNet.Security/Notifications/MessageReceivedNotification.cs index af81a2dbf..e27028917 100644 --- a/src/Microsoft.AspNet.Security/Notifications/MessageReceivedNotification.cs +++ b/src/Microsoft.AspNet.Security/Notifications/MessageReceivedNotification.cs @@ -1,4 +1,6 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + namespace Microsoft.AspNet.Security.Notifications { diff --git a/src/Microsoft.AspNet.Security/Notifications/RedirectFromIdentityProviderNotification.cs b/src/Microsoft.AspNet.Security/Notifications/RedirectFromIdentityProviderNotification.cs index a8a1dcfd5..d0bd97a76 100644 --- a/src/Microsoft.AspNet.Security/Notifications/RedirectFromIdentityProviderNotification.cs +++ b/src/Microsoft.AspNet.Security/Notifications/RedirectFromIdentityProviderNotification.cs @@ -1,4 +1,6 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + namespace Microsoft.AspNet.Security.Notifications { diff --git a/src/Microsoft.AspNet.Security/Notifications/RedirectToIdentityProviderNotification.cs b/src/Microsoft.AspNet.Security/Notifications/RedirectToIdentityProviderNotification.cs index 91dfb8793..467731fa0 100644 --- a/src/Microsoft.AspNet.Security/Notifications/RedirectToIdentityProviderNotification.cs +++ b/src/Microsoft.AspNet.Security/Notifications/RedirectToIdentityProviderNotification.cs @@ -1,4 +1,6 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + namespace Microsoft.AspNet.Security.Notifications { diff --git a/src/Microsoft.AspNet.Security/Notifications/ReturnEndpointContext.cs b/src/Microsoft.AspNet.Security/Notifications/ReturnEndpointContext.cs index ff88098f5..6d15d02fa 100644 --- a/src/Microsoft.AspNet.Security/Notifications/ReturnEndpointContext.cs +++ b/src/Microsoft.AspNet.Security/Notifications/ReturnEndpointContext.cs @@ -1,4 +1,6 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + using System.Diagnostics.CodeAnalysis; using System.Security.Claims; diff --git a/src/Microsoft.AspNet.Security/Notifications/SecurityTokenReceivedNotification.cs b/src/Microsoft.AspNet.Security/Notifications/SecurityTokenReceivedNotification.cs index 2ac5c3368..f8aa2adef 100644 --- a/src/Microsoft.AspNet.Security/Notifications/SecurityTokenReceivedNotification.cs +++ b/src/Microsoft.AspNet.Security/Notifications/SecurityTokenReceivedNotification.cs @@ -1,4 +1,6 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + namespace Microsoft.AspNet.Security.Notifications { diff --git a/src/Microsoft.AspNet.Security/Notifications/SecurityTokenValidatedNotification.cs b/src/Microsoft.AspNet.Security/Notifications/SecurityTokenValidatedNotification.cs index 963266e93..400b8b581 100644 --- a/src/Microsoft.AspNet.Security/Notifications/SecurityTokenValidatedNotification.cs +++ b/src/Microsoft.AspNet.Security/Notifications/SecurityTokenValidatedNotification.cs @@ -1,4 +1,6 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + namespace Microsoft.AspNet.Security.Notifications { diff --git a/src/Microsoft.AspNet.Security/SubjectPublicKeyInfoAlgorithm.cs b/src/Microsoft.AspNet.Security/SubjectPublicKeyInfoAlgorithm.cs index 2987f6874..aefe5ef76 100644 --- a/src/Microsoft.AspNet.Security/SubjectPublicKeyInfoAlgorithm.cs +++ b/src/Microsoft.AspNet.Security/SubjectPublicKeyInfoAlgorithm.cs @@ -1,4 +1,6 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + namespace Microsoft.AspNet.Security { diff --git a/src/Microsoft.AspNet.Security/Win32.cs b/src/Microsoft.AspNet.Security/Win32.cs index fe26feb7b..fe817e92d 100644 --- a/src/Microsoft.AspNet.Security/Win32.cs +++ b/src/Microsoft.AspNet.Security/Win32.cs @@ -1,4 +1,6 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + using System; using System.ComponentModel; diff --git a/test/Microsoft.AspNet.Security.Test/DefaultAuthorizationServiceTests.cs b/test/Microsoft.AspNet.Security.Test/DefaultAuthorizationServiceTests.cs index 7d439897b..7fbacd02a 100644 --- a/test/Microsoft.AspNet.Security.Test/DefaultAuthorizationServiceTests.cs +++ b/test/Microsoft.AspNet.Security.Test/DefaultAuthorizationServiceTests.cs @@ -1,4 +1,7 @@ -using System; +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; using System.Collections.Generic; using System.Linq; using System.Security.Claims; diff --git a/test/Microsoft.AspNet.Security.Test/FakePolicy.cs b/test/Microsoft.AspNet.Security.Test/FakePolicy.cs index 3e365cde2..be9139b89 100644 --- a/test/Microsoft.AspNet.Security.Test/FakePolicy.cs +++ b/test/Microsoft.AspNet.Security.Test/FakePolicy.cs @@ -1,3 +1,6 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + using System; using System.Threading.Tasks; using Microsoft.AspNet.Security; From e2d359843840837533ee35426cdf907ffd1cb7ee Mon Sep 17 00:00:00 2001 From: Chris Ross Date: Thu, 8 May 2014 15:05:38 -0700 Subject: [PATCH 005/216] Create cookie auth middleware with DI. --- .../CookieAuthenticationExtensions.cs | 7 ++----- src/Microsoft.AspNet.Security.Cookies/project.json | 3 ++- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/src/Microsoft.AspNet.Security.Cookies/CookieAuthenticationExtensions.cs b/src/Microsoft.AspNet.Security.Cookies/CookieAuthenticationExtensions.cs index 91109f4ce..ad683ac21 100644 --- a/src/Microsoft.AspNet.Security.Cookies/CookieAuthenticationExtensions.cs +++ b/src/Microsoft.AspNet.Security.Cookies/CookieAuthenticationExtensions.cs @@ -18,15 +18,12 @@ public static class CookieAuthenticationExtensions /// /// Adds a cookie-based authentication middleware to your web application pipeline. /// - /// The IAppBuilder passed to your configuration method + /// The IBuilder passed to your configuration method /// An options class that controls the middleware behavior /// The original app parameter public static IBuilder UseCookieAuthentication([NotNull] this IBuilder app, [NotNull] CookieAuthenticationOptions options) { - // TODO: Use UseMiddleware to inject dependencies once it can discover Invoke from a base class. - var dataProtectionProvider = app.ApplicationServices.GetService(); - var loggerFactory = app.ApplicationServices.GetService(); - return app.Use(next => new CookieAuthenticationMiddleware(next, dataProtectionProvider, loggerFactory, options).Invoke); + return app.UseMiddleware(options); } } } \ No newline at end of file diff --git a/src/Microsoft.AspNet.Security.Cookies/project.json b/src/Microsoft.AspNet.Security.Cookies/project.json index f16f0f5d0..01d75ff08 100644 --- a/src/Microsoft.AspNet.Security.Cookies/project.json +++ b/src/Microsoft.AspNet.Security.Cookies/project.json @@ -5,7 +5,8 @@ "Microsoft.AspNet.Http": "0.1-alpha-*", "Microsoft.AspNet.HttpFeature": "0.1-alpha-*", "Microsoft.AspNet.PipelineCore": "0.1-alpha-*", - "Microsoft.AspNet.Security": "0.1-alpha-*", + "Microsoft.AspNet.RequestContainer": "0.1-alpha-*", + "Microsoft.AspNet.Security": "", "Microsoft.AspNet.Security.DataProtection": "0.1-alpha-*", "Microsoft.Framework.DependencyInjection": "0.1-alpha-*", "Microsoft.Framework.Logging": "0.1-alpha-*", From cf7ffe1a75a29f77f578c7f789a5053155693a3f Mon Sep 17 00:00:00 2001 From: Chris Ross Date: Fri, 9 May 2014 11:19:54 -0700 Subject: [PATCH 006/216] Fix sample. --- samples/CookieSample/Startup.cs | 10 ++-------- samples/CookieSample/project.json | 2 +- 2 files changed, 3 insertions(+), 9 deletions(-) diff --git a/samples/CookieSample/Startup.cs b/samples/CookieSample/Startup.cs index cd8bf7621..d648a1523 100644 --- a/samples/CookieSample/Startup.cs +++ b/samples/CookieSample/Startup.cs @@ -1,18 +1,12 @@ -using System; using System.Security.Claims; -using Microsoft.AspNet; -using Microsoft.AspNet.Http; -using Microsoft.AspNet.Security.Cookies; -using Microsoft.AspNet.RequestContainer; using Microsoft.AspNet.Builder; -using Microsoft.Framework.DependencyInjection; -using Microsoft.Framework.DependencyInjection.Fallback; +using Microsoft.AspNet.Security.Cookies; namespace CookieSample { public class Startup { - public void Configuration(IBuilder app) + public void Configure(IBuilder app) { app.UseCookieAuthentication(new CookieAuthenticationOptions() { diff --git a/samples/CookieSample/project.json b/samples/CookieSample/project.json index 5b4245f7c..c3378914b 100644 --- a/samples/CookieSample/project.json +++ b/samples/CookieSample/project.json @@ -12,7 +12,7 @@ "Microsoft.AspNet.Server.WebListener": "0.1-alpha-*", "Microsoft.Framework.DependencyInjection": "0.1-alpha-*" }, - "commands": { "web": "Microsoft.AspNet.Hosting server.name=Microsoft.AspNet.Server.WebListener server.urls=http://localhost:12345" }, + "commands": { "web": "Microsoft.AspNet.Hosting server=Microsoft.AspNet.Server.WebListener server.urls=http://localhost:12345" }, "configurations": { "net45": { }, From d9502923f892a8f80ff71ed586070f406e75ff10 Mon Sep 17 00:00:00 2001 From: Sebastien Ros Date: Mon, 5 May 2014 15:38:49 -0700 Subject: [PATCH 007/216] Moving interface members to extension methods --- .../AuthorizationServiceExtensions.cs | 30 ++++++++++++++++--- .../DefaultAuthorizationService.cs | 10 ------- .../IAuthorizationService.cs | 16 ---------- .../DefaultAuthorizationServiceTests.cs | 8 ++--- 4 files changed, 30 insertions(+), 34 deletions(-) diff --git a/src/Microsoft.AspNet.Security/AuthorizationServiceExtensions.cs b/src/Microsoft.AspNet.Security/AuthorizationServiceExtensions.cs index b26c636e7..17ec58196 100644 --- a/src/Microsoft.AspNet.Security/AuthorizationServiceExtensions.cs +++ b/src/Microsoft.AspNet.Security/AuthorizationServiceExtensions.cs @@ -17,7 +17,7 @@ public static class AuthorizationServiceExtensions /// The claim to check against a specific user. /// The user to check claims against. /// true when the user fulfills one of the claims, false otherwise. - public static Task AuthorizeAsync(this IAuthorizationService service, Claim claim, ClaimsPrincipal user) + public static Task AuthorizeAsync([NotNull] this IAuthorizationService service, Claim claim, ClaimsPrincipal user) { return service.AuthorizeAsync(new Claim[] { claim }, user); } @@ -28,7 +28,7 @@ public static Task AuthorizeAsync(this IAuthorizationService service, Clai /// The claim to check against a specific user. /// The user to check claims against. /// true when the user fulfills one of the claims, false otherwise. - public static bool Authorize(this IAuthorizationService service, Claim claim, ClaimsPrincipal user) + public static bool Authorize([NotNull] this IAuthorizationService service, Claim claim, ClaimsPrincipal user) { return service.Authorize(new Claim[] { claim }, user); } @@ -40,7 +40,7 @@ public static bool Authorize(this IAuthorizationService service, Claim claim, Cl /// The user to check claims against. /// The resource the claims should be check with. /// true when the user fulfills one of the claims, false otherwise. - public static Task AuthorizeAsync(this IAuthorizationService service, Claim claim, ClaimsPrincipal user, object resource) + public static Task AuthorizeAsync([NotNull] this IAuthorizationService service, Claim claim, ClaimsPrincipal user, object resource) { return service.AuthorizeAsync(new Claim[] { claim }, user, resource); } @@ -52,9 +52,31 @@ public static Task AuthorizeAsync(this IAuthorizationService service, Clai /// The user to check claims against. /// The resource the claims should be check with. /// true when the user fulfills one of the claims, false otherwise. - public static bool Authorize(this IAuthorizationService service, Claim claim, ClaimsPrincipal user, object resource) + public static bool Authorize([NotNull] this IAuthorizationService service, Claim claim, ClaimsPrincipal user, object resource) { return service.Authorize(new Claim[] { claim }, user, resource); } + + /// + /// Checks if a user has specific claims. + /// + /// The claims to check against a specific user. + /// The user to check claims against. + /// true when the user fulfills one of the claims, false otherwise. + public static Task AuthorizeAsync([NotNull] this IAuthorizationService service, IEnumerable claims, ClaimsPrincipal user) + { + return service.AuthorizeAsync(claims, user, null); + } + + /// + /// Checks if a user has specific claims. + /// + /// The claims to check against a specific user. + /// The user to check claims against. + /// true when the user fulfills one of the claims, false otherwise. + public static bool Authorize([NotNull] this IAuthorizationService service, IEnumerable claims, ClaimsPrincipal user) + { + return service.Authorize(claims, user, null); + } } } \ No newline at end of file diff --git a/src/Microsoft.AspNet.Security/DefaultAuthorizationService.cs b/src/Microsoft.AspNet.Security/DefaultAuthorizationService.cs index 578671e95..aaa1dbc10 100644 --- a/src/Microsoft.AspNet.Security/DefaultAuthorizationService.cs +++ b/src/Microsoft.AspNet.Security/DefaultAuthorizationService.cs @@ -26,16 +26,6 @@ public DefaultAuthorizationService(IEnumerable policies) } } - public async Task AuthorizeAsync(IEnumerable claims, ClaimsPrincipal user) - { - return await AuthorizeAsync(claims, user, null); - } - - public bool Authorize(IEnumerable claims, ClaimsPrincipal user) - { - return AuthorizeAsync(claims, user, null).Result; - } - public async Task AuthorizeAsync(IEnumerable claims, ClaimsPrincipal user, object resource) { var context = new AuthorizationPolicyContext(claims, user, resource); diff --git a/src/Microsoft.AspNet.Security/IAuthorizationService.cs b/src/Microsoft.AspNet.Security/IAuthorizationService.cs index 2063ae646..9fcef75a2 100644 --- a/src/Microsoft.AspNet.Security/IAuthorizationService.cs +++ b/src/Microsoft.AspNet.Security/IAuthorizationService.cs @@ -12,22 +12,6 @@ namespace Microsoft.AspNet.Security /// public interface IAuthorizationService { - /// - /// Checks if a user has specific claims. - /// - /// The claims to check against a specific user. - /// The user to check claims against. - /// true when the user fulfills one of the claims, false otherwise. - Task AuthorizeAsync(IEnumerable claims, ClaimsPrincipal user); - - /// - /// Checks if a user has specific claims. - /// - /// The claims to check against a specific user. - /// The user to check claims against. - /// true when the user fulfills one of the claims, false otherwise. - bool Authorize(IEnumerable claims, ClaimsPrincipal user); - /// /// Checks if a user has specific claims for a specific context obj. /// diff --git a/test/Microsoft.AspNet.Security.Test/DefaultAuthorizationServiceTests.cs b/test/Microsoft.AspNet.Security.Test/DefaultAuthorizationServiceTests.cs index 7fbacd02a..fd3a668a2 100644 --- a/test/Microsoft.AspNet.Security.Test/DefaultAuthorizationServiceTests.cs +++ b/test/Microsoft.AspNet.Security.Test/DefaultAuthorizationServiceTests.cs @@ -165,7 +165,7 @@ public void Check_ShouldApplyPoliciesInOrder() var authorizationService = new DefaultAuthorizationService(policies); // Act - var allowed = authorizationService.Authorize(null, null); + var allowed = authorizationService.Authorize(Enumerable.Empty(), null); // Assert Assert.Equal("-12030", result); @@ -200,7 +200,7 @@ public void Check_ShouldInvokeApplyingApplyAppliedInOrder() var authorizationService = new DefaultAuthorizationService(policies); // Act - var allowed = authorizationService.Authorize(null, null); + var allowed = authorizationService.Authorize(Enumerable.Empty(), null); // Assert Assert.Equal("Applying-1Applying20Applying30Apply-1Apply20Apply30Applied-1Applied20Applied30", result); @@ -221,7 +221,7 @@ public void Check_ShouldConvertNullClaimsToEmptyList() var authorizationService = new DefaultAuthorizationService(policies); // Act - var allowed = authorizationService.Authorize(null, null); + var allowed = authorizationService.Authorize(Enumerable.Empty(), null); // Assert Assert.NotNull(claims); @@ -242,7 +242,7 @@ public void Check_ShouldThrowWhenPoliciesDontStop() // Act // Assert - Exception ex = Assert.Throws(() => authorizationService.Authorize(null, null)); + Exception ex = Assert.Throws(() => authorizationService.Authorize(Enumerable.Empty(), null)); } [Fact] From de9769baa5fa9e2d09d5cc490da65c0630c5ca16 Mon Sep 17 00:00:00 2001 From: Glenn Date: Mon, 12 May 2014 17:52:35 -0700 Subject: [PATCH 008/216] Create README.md --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 000000000..ab7b29e97 --- /dev/null +++ b/README.md @@ -0,0 +1,6 @@ +ASP.NET Security +======== + +ASP.NET Security contains the security and authorization middlewares for ASP.NET vNext. + +This project is part of ASP.NET vNext. You can find samples, documentation and getting started instructions for ASP.NET vNext at the [Home](https://github.com/aspnet/home) repo. From 823eead066fbec468608386b14038ac1b369b44a Mon Sep 17 00:00:00 2001 From: Eilon Lipton Date: Tue, 13 May 2014 01:02:53 -0700 Subject: [PATCH 009/216] Create CONTRIBUTING.md --- CONTRIBUTING.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 CONTRIBUTING.md diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 000000000..eac4268e4 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,4 @@ +Contributing +====== + +Information on contributing to this repo is in the [Contributing Guide](https://github.com/aspnet/Home/blob/master/CONTRIBUTING.md) in the Home repo. From 75759dae9c7da2e4f32942633f58fa91171a244e Mon Sep 17 00:00:00 2001 From: Pranav K Date: Sun, 18 May 2014 20:13:57 -0700 Subject: [PATCH 010/216] Updating kproj file to match tooling changes --- .gitignore | 3 ++- samples/CookieSample/CookieSample.kproj | 6 +++--- .../Microsoft.AspNet.Security.Cookies.kproj | 6 +++--- .../Microsoft.AspNet.Security.kproj | 6 +++--- .../Microsoft.AspNet.Security.kproj | 6 +++--- 5 files changed, 14 insertions(+), 13 deletions(-) diff --git a/.gitignore b/.gitignore index aba9c594d..08e21e25b 100644 --- a/.gitignore +++ b/.gitignore @@ -22,4 +22,5 @@ nuget.exe *DS_Store *.ncrunchsolution *.*sdf -*.ipch \ No newline at end of file +*.ipch +*.sln.ide \ No newline at end of file diff --git a/samples/CookieSample/CookieSample.kproj b/samples/CookieSample/CookieSample.kproj index 7d88de92e..e72eaf649 100644 --- a/samples/CookieSample/CookieSample.kproj +++ b/samples/CookieSample/CookieSample.kproj @@ -1,10 +1,10 @@ - + 12.0 $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) - + 558c2c2a-aed8-49de-bb60-d5f8ae06c714 Library @@ -22,5 +22,5 @@ - + \ No newline at end of file diff --git a/src/Microsoft.AspNet.Security.Cookies/Microsoft.AspNet.Security.Cookies.kproj b/src/Microsoft.AspNet.Security.Cookies/Microsoft.AspNet.Security.Cookies.kproj index b5ae96ed0..5319a794e 100644 --- a/src/Microsoft.AspNet.Security.Cookies/Microsoft.AspNet.Security.Cookies.kproj +++ b/src/Microsoft.AspNet.Security.Cookies/Microsoft.AspNet.Security.Cookies.kproj @@ -1,10 +1,10 @@ - + 12.0 $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) - + 15f1211b-b695-4a1c-b730-1ac58fc91090 Library @@ -35,5 +35,5 @@ - + \ No newline at end of file diff --git a/src/Microsoft.AspNet.Security/Microsoft.AspNet.Security.kproj b/src/Microsoft.AspNet.Security/Microsoft.AspNet.Security.kproj index fa845e638..5b1563b50 100644 --- a/src/Microsoft.AspNet.Security/Microsoft.AspNet.Security.kproj +++ b/src/Microsoft.AspNet.Security/Microsoft.AspNet.Security.kproj @@ -1,10 +1,10 @@ - + 12.0 $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) - + 0f174c63-1898-4024-9a3c-3fdf5cae5c68 Library @@ -78,5 +78,5 @@ - + \ No newline at end of file diff --git a/test/Microsoft.AspNet.Security.Test/Microsoft.AspNet.Security.kproj b/test/Microsoft.AspNet.Security.Test/Microsoft.AspNet.Security.kproj index 3a317e7f3..8e155aa9a 100644 --- a/test/Microsoft.AspNet.Security.Test/Microsoft.AspNet.Security.kproj +++ b/test/Microsoft.AspNet.Security.Test/Microsoft.AspNet.Security.kproj @@ -1,10 +1,10 @@ - + 12.0 $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) - + 8da26cd1-1302-4cfd-9270-9fa1b7c6138b Library @@ -23,5 +23,5 @@ - + \ No newline at end of file From ba6488fb6a8095c18284f680c6f3ac43f4293eff Mon Sep 17 00:00:00 2001 From: David Fowler Date: Mon, 26 May 2014 02:52:29 -0700 Subject: [PATCH 011/216] Fixed project.json casing --- samples/CookieSample/CookieSample.kproj | 6 +++--- .../Microsoft.AspNet.Security.Cookies.kproj | 6 +++--- .../Microsoft.AspNet.Security.kproj | 6 +++--- .../Microsoft.AspNet.Security.kproj | 6 +++--- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/samples/CookieSample/CookieSample.kproj b/samples/CookieSample/CookieSample.kproj index e72eaf649..efb2d4d77 100644 --- a/samples/CookieSample/CookieSample.kproj +++ b/samples/CookieSample/CookieSample.kproj @@ -1,4 +1,4 @@ - + 12.0 @@ -17,10 +17,10 @@ 2.0 - + - \ No newline at end of file + diff --git a/src/Microsoft.AspNet.Security.Cookies/Microsoft.AspNet.Security.Cookies.kproj b/src/Microsoft.AspNet.Security.Cookies/Microsoft.AspNet.Security.Cookies.kproj index 5319a794e..1b82715c3 100644 --- a/src/Microsoft.AspNet.Security.Cookies/Microsoft.AspNet.Security.Cookies.kproj +++ b/src/Microsoft.AspNet.Security.Cookies/Microsoft.AspNet.Security.Cookies.kproj @@ -1,4 +1,4 @@ - + 12.0 @@ -17,7 +17,7 @@ 2.0 - + @@ -36,4 +36,4 @@ - \ No newline at end of file + diff --git a/src/Microsoft.AspNet.Security/Microsoft.AspNet.Security.kproj b/src/Microsoft.AspNet.Security/Microsoft.AspNet.Security.kproj index 5b1563b50..c774d797e 100644 --- a/src/Microsoft.AspNet.Security/Microsoft.AspNet.Security.kproj +++ b/src/Microsoft.AspNet.Security/Microsoft.AspNet.Security.kproj @@ -1,4 +1,4 @@ - + 12.0 @@ -17,7 +17,7 @@ 2.0 - + @@ -79,4 +79,4 @@ - \ No newline at end of file + diff --git a/test/Microsoft.AspNet.Security.Test/Microsoft.AspNet.Security.kproj b/test/Microsoft.AspNet.Security.Test/Microsoft.AspNet.Security.kproj index 8e155aa9a..62a9b7453 100644 --- a/test/Microsoft.AspNet.Security.Test/Microsoft.AspNet.Security.kproj +++ b/test/Microsoft.AspNet.Security.Test/Microsoft.AspNet.Security.kproj @@ -1,4 +1,4 @@ - + 12.0 @@ -17,11 +17,11 @@ 2.0 - + - \ No newline at end of file + From 8d43a4fac2f22532b0b62230c729e4208e4010e8 Mon Sep 17 00:00:00 2001 From: Pranav K Date: Tue, 3 Jun 2014 10:16:50 -0700 Subject: [PATCH 012/216] Adding switch to build.cmd to skip KRE install --- build.cmd | 2 ++ 1 file changed, 2 insertions(+) diff --git a/build.cmd b/build.cmd index 903d532df..3aaf95758 100644 --- a/build.cmd +++ b/build.cmd @@ -18,6 +18,8 @@ copy %CACHED_NUGET% .nuget\nuget.exe > nul IF EXIST packages\KoreBuild goto run .nuget\NuGet.exe install KoreBuild -ExcludeVersion -o packages -nocache -pre .nuget\NuGet.exe install Sake -version 0.2 -o packages -ExcludeVersion + +IF "%SKIP_KRE_INSTALL%"=="1" goto run CALL packages\KoreBuild\build\kvm upgrade -svr50 -x86 CALL packages\KoreBuild\build\kvm install default -svrc50 -x86 From e740d0799ff75ddc9e0f4d4f188452f4db6ae031 Mon Sep 17 00:00:00 2001 From: Pranav K Date: Tue, 10 Jun 2014 17:24:24 -0700 Subject: [PATCH 013/216] Updating build.sh based on KRuntime changes --- build.sh | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/build.sh b/build.sh index db1e0c3dd..4323aefc4 100644 --- a/build.sh +++ b/build.sh @@ -3,10 +3,10 @@ if test `uname` = Darwin; then cachedir=~/Library/Caches/KBuild else - if x$XDG_DATA_HOME = x; then - cachedir=$HOME/.local/share + if [ -z $XDG_DATA_HOME ]; then + cachedir=$HOME/.local/share else - cachedir=$XDG_DATA_HOME; + cachedir=$XDG_DATA_HOME; fi fi mkdir -p $cachedir @@ -14,12 +14,12 @@ mkdir -p $cachedir url=https://www.nuget.org/nuget.exe if test ! -f $cachedir/nuget.exe; then - wget -o $cachedir/nuget.exe $url 2>/dev/null || curl -o $cachedir/nuget.exe --location $url /dev/null + wget -O $cachedir/nuget.exe $url 2>/dev/null || curl -o $cachedir/nuget.exe --location $url /dev/null fi if test ! -e .nuget; then mkdir .nuget - cp $cachedir/nuget.exe .nuget + cp $cachedir/nuget.exe .nuget/nuget.exe fi if test ! -d packages/KoreBuild; then @@ -27,4 +27,12 @@ if test ! -d packages/KoreBuild; then mono .nuget/nuget.exe install Sake -version 0.2 -o packages -ExcludeVersion fi -mono packages/Sake/tools/Sake.exe -I packages/KoreBuild/build -f makefile.shade "$@" \ No newline at end of file +if ! type k > /dev/null 2>&1; then + source setup/kvm.sh +fi + +if ! type k > /dev/null 2>&1; then + kvm upgrade +fi + +mono packages/Sake/tools/Sake.exe -I packages/KoreBuild/build -f makefile.shade "$@" From 8841f642fb2e435c3f406d3f0eb1447ca4928c2f Mon Sep 17 00:00:00 2001 From: Wei Wang Date: Wed, 18 Jun 2014 16:42:27 -0700 Subject: [PATCH 014/216] Change the default author in makefile.shade --- makefile.shade | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/makefile.shade b/makefile.shade index 6357ea284..562494d14 100644 --- a/makefile.shade +++ b/makefile.shade @@ -1,7 +1,7 @@ var VERSION='0.1' var FULL_VERSION='0.1' -var AUTHORS='Microsoft' +var AUTHORS='Microsoft Open Technologies, Inc.' use-standard-lifecycle k-standard-goals From faf98f8bb0dd304aa25e59e5eb08682acd8a92ce Mon Sep 17 00:00:00 2001 From: Brice Lambson Date: Thu, 19 Jun 2014 11:36:56 -0700 Subject: [PATCH 015/216] Bump version to 1.0.0-* --- samples/CookieSample/project.json | 17 ++++++++-------- .../project.json | 20 +++++++++---------- src/Microsoft.AspNet.Security/project.json | 18 ++++++++--------- .../project.json | 9 ++------- 4 files changed, 29 insertions(+), 35 deletions(-) diff --git a/samples/CookieSample/project.json b/samples/CookieSample/project.json index c3378914b..bf8d85053 100644 --- a/samples/CookieSample/project.json +++ b/samples/CookieSample/project.json @@ -1,16 +1,15 @@ { - "version": "0.1-alpha-*", "dependencies": { - "Microsoft.AspNet.FeatureModel": "0.1-alpha-*", - "Microsoft.AspNet.Hosting": "0.1-alpha-*", - "Microsoft.AspNet.Http": "0.1-alpha-*", - "Microsoft.AspNet.HttpFeature": "0.1-alpha-*", - "Microsoft.AspNet.PipelineCore": "0.1-alpha-*", - "Microsoft.AspNet.RequestContainer": "0.1-alpha-*", + "Microsoft.AspNet.FeatureModel": "1.0.0-*", + "Microsoft.AspNet.Hosting": "1.0.0-*", + "Microsoft.AspNet.Http": "1.0.0-*", + "Microsoft.AspNet.HttpFeature": "1.0.0-*", + "Microsoft.AspNet.PipelineCore": "1.0.0-*", + "Microsoft.AspNet.RequestContainer": "1.0.0-*", "Microsoft.AspNet.Security": "", "Microsoft.AspNet.Security.Cookies": "", - "Microsoft.AspNet.Server.WebListener": "0.1-alpha-*", - "Microsoft.Framework.DependencyInjection": "0.1-alpha-*" + "Microsoft.AspNet.Server.WebListener": "1.0.0-*", + "Microsoft.Framework.DependencyInjection": "1.0.0-*" }, "commands": { "web": "Microsoft.AspNet.Hosting server=Microsoft.AspNet.Server.WebListener server.urls=http://localhost:12345" }, "configurations": { diff --git a/src/Microsoft.AspNet.Security.Cookies/project.json b/src/Microsoft.AspNet.Security.Cookies/project.json index 01d75ff08..ebf68d564 100644 --- a/src/Microsoft.AspNet.Security.Cookies/project.json +++ b/src/Microsoft.AspNet.Security.Cookies/project.json @@ -1,15 +1,15 @@ { - "version": "0.1-alpha-*", + "version": "1.0.0-*", "dependencies": { - "Microsoft.AspNet.FeatureModel": "0.1-alpha-*", - "Microsoft.AspNet.Http": "0.1-alpha-*", - "Microsoft.AspNet.HttpFeature": "0.1-alpha-*", - "Microsoft.AspNet.PipelineCore": "0.1-alpha-*", - "Microsoft.AspNet.RequestContainer": "0.1-alpha-*", + "Microsoft.AspNet.FeatureModel": "1.0.0-*", + "Microsoft.AspNet.Http": "1.0.0-*", + "Microsoft.AspNet.HttpFeature": "1.0.0-*", + "Microsoft.AspNet.PipelineCore": "1.0.0-*", + "Microsoft.AspNet.RequestContainer": "1.0.0-*", "Microsoft.AspNet.Security": "", - "Microsoft.AspNet.Security.DataProtection": "0.1-alpha-*", - "Microsoft.Framework.DependencyInjection": "0.1-alpha-*", - "Microsoft.Framework.Logging": "0.1-alpha-*", + "Microsoft.AspNet.Security.DataProtection": "1.0.0-*", + "Microsoft.Framework.DependencyInjection": "1.0.0-*", + "Microsoft.Framework.Logging": "1.0.0-*", "Newtonsoft.Json": "5.0.8" }, "configurations": { @@ -30,7 +30,7 @@ "System.Runtime": "4.0.20.0", "System.Runtime.Extensions": "4.0.10.0", "System.Runtime.InteropServices": "4.0.20.0", - "System.Security.Claims": "0.1-alpha-*", + "System.Security.Claims": "1.0.0-*", "System.Security.Principal" : "4.0.0.0", "System.Threading": "4.0.0.0", "System.Threading.Tasks": "4.0.10.0" diff --git a/src/Microsoft.AspNet.Security/project.json b/src/Microsoft.AspNet.Security/project.json index b790dc942..ee4318a1d 100644 --- a/src/Microsoft.AspNet.Security/project.json +++ b/src/Microsoft.AspNet.Security/project.json @@ -1,13 +1,13 @@ { - "version": "0.1-alpha-*", + "version": "1.0.0-*", "dependencies": { - "Microsoft.AspNet.FeatureModel": "0.1-alpha-*", - "Microsoft.AspNet.Http": "0.1-alpha-*", - "Microsoft.AspNet.HttpFeature": "0.1-alpha-*", - "Microsoft.AspNet.PipelineCore": "0.1-alpha-*", - "Microsoft.AspNet.Security.DataProtection": "0.1-alpha-*", - "Microsoft.Framework.DependencyInjection": "0.1-alpha-*", - "Microsoft.Framework.Logging": "0.1-alpha-*" + "Microsoft.AspNet.FeatureModel": "1.0.0-*", + "Microsoft.AspNet.Http": "1.0.0-*", + "Microsoft.AspNet.HttpFeature": "1.0.0-*", + "Microsoft.AspNet.PipelineCore": "1.0.0-*", + "Microsoft.AspNet.Security.DataProtection": "1.0.0-*", + "Microsoft.Framework.DependencyInjection": "1.0.0-*", + "Microsoft.Framework.Logging": "1.0.0-*" }, "configurations": { "net45": {}, @@ -27,7 +27,7 @@ "System.Runtime": "4.0.20.0", "System.Runtime.Extensions": "4.0.10.0", "System.Runtime.InteropServices": "4.0.20.0", - "System.Security.Claims": "0.1-alpha-*", + "System.Security.Claims": "1.0.0-*", "System.Security.Cryptography.RandomNumberGenerator" : "4.0.0.0", "System.Security.Principal" : "4.0.0.0", "System.Threading": "4.0.0.0", diff --git a/test/Microsoft.AspNet.Security.Test/project.json b/test/Microsoft.AspNet.Security.Test/project.json index a7587932d..0341eef07 100644 --- a/test/Microsoft.AspNet.Security.Test/project.json +++ b/test/Microsoft.AspNet.Security.Test/project.json @@ -1,16 +1,11 @@ { - "version" : "0.1-alpha-*", "compilationOptions": { "warningsAsErrors": true }, "dependencies": { - "Microsoft.AspNet.Security" : "0.1-alpha-*", + "Microsoft.AspNet.Security" : "", "Moq": "4.2.1312.1622", - "xunit.abstractions": "2.0.0-aspnet-*", - "xunit.assert": "2.0.0-aspnet-*", - "xunit.core": "2.0.0-aspnet-*", - "xunit.execution": "2.0.0-aspnet-*", - "Xunit.KRunner": "0.1-alpha-*" + "Xunit.KRunner": "1.0.0-*" }, "commands": { "test": "Xunit.KRunner" From 4ca0a78bbd54fac1a027ae2adbb793ef262a1f30 Mon Sep 17 00:00:00 2001 From: Brice Lambson Date: Fri, 20 Jun 2014 14:33:41 -0700 Subject: [PATCH 016/216] Updating release Nuget.config --- NuGet.Config | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/NuGet.Config b/NuGet.Config index a059188b0..1ce6b9e25 100644 --- a/NuGet.Config +++ b/NuGet.Config @@ -1,13 +1,7 @@ - + - + - - - - - - - \ No newline at end of file + From 779de7ae36671dfe6f2870d4c9f682c1c17bd5aa Mon Sep 17 00:00:00 2001 From: Brice Lambson Date: Fri, 20 Jun 2014 14:33:42 -0700 Subject: [PATCH 017/216] Updating dev Nuget.config --- NuGet.Config | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/NuGet.Config b/NuGet.Config index 1ce6b9e25..f41e9c631 100644 --- a/NuGet.Config +++ b/NuGet.Config @@ -1,7 +1,7 @@ - + - + From 81c06fa558926118e966e6b89092ecb64e45a2a4 Mon Sep 17 00:00:00 2001 From: Chris Ross Date: Mon, 30 Jun 2014 14:12:55 -0700 Subject: [PATCH 018/216] Make middleware report when auth fails. --- .../Infrastructure/AuthenticationHandler.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Microsoft.AspNet.Security/Infrastructure/AuthenticationHandler.cs b/src/Microsoft.AspNet.Security/Infrastructure/AuthenticationHandler.cs index 45dadda9e..6c8da45c6 100644 --- a/src/Microsoft.AspNet.Security/Infrastructure/AuthenticationHandler.cs +++ b/src/Microsoft.AspNet.Security/Infrastructure/AuthenticationHandler.cs @@ -141,6 +141,10 @@ public virtual void Authenticate(IAuthenticateContext context) { context.Authenticated(ticket.Identity, ticket.Properties.Dictionary, BaseOptions.Description.Dictionary); } + else + { + context.NotAuthenticated(BaseOptions.AuthenticationType, properties: null, description: BaseOptions.Description.Dictionary); + } } if (PriorHandler != null) From 287eebe2442d25ee4ba1d9d55f66363507df8bfd Mon Sep 17 00:00:00 2001 From: Chris Ross Date: Thu, 3 Jul 2014 10:12:15 -0700 Subject: [PATCH 019/216] Handle change from IList to IEnumerable. --- .../Infrastructure/SecurityHelper.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Microsoft.AspNet.Security/Infrastructure/SecurityHelper.cs b/src/Microsoft.AspNet.Security/Infrastructure/SecurityHelper.cs index 7a8456d5e..876d5342f 100644 --- a/src/Microsoft.AspNet.Security/Infrastructure/SecurityHelper.cs +++ b/src/Microsoft.AspNet.Security/Infrastructure/SecurityHelper.cs @@ -38,7 +38,7 @@ public static void AddUserIdentity([NotNull] HttpContext context, [NotNull] IIde context.User = newClaimsPrincipal; } - public static bool LookupChallenge(IList authenticationTypes, string authenticationType, AuthenticationMode authenticationMode) + public static bool LookupChallenge(IEnumerable authenticationTypes, string authenticationType, AuthenticationMode authenticationMode) { bool challengeHasAuthenticationTypes = authenticationTypes != null && authenticationTypes.Any(); if (!challengeHasAuthenticationTypes) @@ -52,7 +52,7 @@ public static bool LookupChallenge(IList authenticationTypes, string aut /// Find response sign-in details for a specific authentication middleware /// /// The authentication type to look for - public static bool LookupSignIn(IList identities, string authenticationType, out ClaimsIdentity identity) + public static bool LookupSignIn(IEnumerable identities, string authenticationType, out ClaimsIdentity identity) { identity = null; foreach (var claimsIdentity in identities) @@ -71,7 +71,7 @@ public static bool LookupSignIn(IList identities, string authent /// /// The authentication type to look for /// The authentication mode the middleware is running under - public static bool LookupSignOut(IList authenticationTypes, string authenticationType, AuthenticationMode authenticationMode) + public static bool LookupSignOut(IEnumerable authenticationTypes, string authenticationType, AuthenticationMode authenticationMode) { bool singOutHasAuthenticationTypes = authenticationTypes != null && authenticationTypes.Any(); if (!singOutHasAuthenticationTypes) From ea98a50e43759da81c61af1d9a461cb8484a93f3 Mon Sep 17 00:00:00 2001 From: David Fowler Date: Sun, 13 Jul 2014 22:01:33 -0700 Subject: [PATCH 020/216] Renamed configurations to frameworks in project.json --- samples/CookieSample/project.json | 6 +++--- src/Microsoft.AspNet.Security.Cookies/project.json | 6 +++--- src/Microsoft.AspNet.Security/project.json | 6 +++--- test/Microsoft.AspNet.Security.Test/project.json | 4 ++-- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/samples/CookieSample/project.json b/samples/CookieSample/project.json index bf8d85053..ca0d99be0 100644 --- a/samples/CookieSample/project.json +++ b/samples/CookieSample/project.json @@ -1,4 +1,4 @@ -{ +{ "dependencies": { "Microsoft.AspNet.FeatureModel": "1.0.0-*", "Microsoft.AspNet.Hosting": "1.0.0-*", @@ -12,7 +12,7 @@ "Microsoft.Framework.DependencyInjection": "1.0.0-*" }, "commands": { "web": "Microsoft.AspNet.Hosting server=Microsoft.AspNet.Server.WebListener server.urls=http://localhost:12345" }, - "configurations": { + "frameworks": { "net45": { }, "k10": { @@ -33,4 +33,4 @@ } } } -} \ No newline at end of file +} diff --git a/src/Microsoft.AspNet.Security.Cookies/project.json b/src/Microsoft.AspNet.Security.Cookies/project.json index ebf68d564..00ff14a94 100644 --- a/src/Microsoft.AspNet.Security.Cookies/project.json +++ b/src/Microsoft.AspNet.Security.Cookies/project.json @@ -1,4 +1,4 @@ -{ +{ "version": "1.0.0-*", "dependencies": { "Microsoft.AspNet.FeatureModel": "1.0.0-*", @@ -12,7 +12,7 @@ "Microsoft.Framework.Logging": "1.0.0-*", "Newtonsoft.Json": "5.0.8" }, - "configurations": { + "frameworks": { "net45": {}, "k10": { "dependencies": { @@ -37,4 +37,4 @@ } } } -} \ No newline at end of file +} diff --git a/src/Microsoft.AspNet.Security/project.json b/src/Microsoft.AspNet.Security/project.json index ee4318a1d..6bbc65fc8 100644 --- a/src/Microsoft.AspNet.Security/project.json +++ b/src/Microsoft.AspNet.Security/project.json @@ -1,4 +1,4 @@ -{ +{ "version": "1.0.0-*", "dependencies": { "Microsoft.AspNet.FeatureModel": "1.0.0-*", @@ -9,7 +9,7 @@ "Microsoft.Framework.DependencyInjection": "1.0.0-*", "Microsoft.Framework.Logging": "1.0.0-*" }, - "configurations": { + "frameworks": { "net45": {}, "k10": { "dependencies": { @@ -35,4 +35,4 @@ } } } -} \ No newline at end of file +} diff --git a/test/Microsoft.AspNet.Security.Test/project.json b/test/Microsoft.AspNet.Security.Test/project.json index 0341eef07..68837d5be 100644 --- a/test/Microsoft.AspNet.Security.Test/project.json +++ b/test/Microsoft.AspNet.Security.Test/project.json @@ -1,4 +1,4 @@ -{ +{ "compilationOptions": { "warningsAsErrors": true }, @@ -10,7 +10,7 @@ "commands": { "test": "Xunit.KRunner" }, - "configurations": { + "frameworks": { "net45": { "dependencies": { "System.Runtime": "" From 8307e9b1f3a2d7cdf148967a7485e9dc5f1ec2b3 Mon Sep 17 00:00:00 2001 From: Pranav K Date: Mon, 14 Jul 2014 16:48:04 -0700 Subject: [PATCH 021/216] Reacting to System.Collections versioning change --- samples/CookieSample/project.json | 4 ++-- src/Microsoft.AspNet.Security.Cookies/project.json | 4 ++-- src/Microsoft.AspNet.Security/project.json | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/samples/CookieSample/project.json b/samples/CookieSample/project.json index ca0d99be0..e51b35e48 100644 --- a/samples/CookieSample/project.json +++ b/samples/CookieSample/project.json @@ -1,4 +1,4 @@ -{ +{ "dependencies": { "Microsoft.AspNet.FeatureModel": "1.0.0-*", "Microsoft.AspNet.Hosting": "1.0.0-*", @@ -17,7 +17,7 @@ }, "k10": { "dependencies": { - "System.Collections": "4.0.0.0", + "System.Collections": "4.0.10.0", "System.Console": "4.0.0.0", "System.Diagnostics.Debug": "4.0.10.0", "System.Diagnostics.Tools": "4.0.0.0", diff --git a/src/Microsoft.AspNet.Security.Cookies/project.json b/src/Microsoft.AspNet.Security.Cookies/project.json index 00ff14a94..01a7751fb 100644 --- a/src/Microsoft.AspNet.Security.Cookies/project.json +++ b/src/Microsoft.AspNet.Security.Cookies/project.json @@ -1,4 +1,4 @@ -{ +{ "version": "1.0.0-*", "dependencies": { "Microsoft.AspNet.FeatureModel": "1.0.0-*", @@ -16,7 +16,7 @@ "net45": {}, "k10": { "dependencies": { - "System.Collections": "4.0.0.0", + "System.Collections": "4.0.10.0", "System.ComponentModel": "4.0.0.0", "System.Console": "4.0.0.0", "System.Diagnostics.Debug": "4.0.10.0", diff --git a/src/Microsoft.AspNet.Security/project.json b/src/Microsoft.AspNet.Security/project.json index 6bbc65fc8..4eae846bf 100644 --- a/src/Microsoft.AspNet.Security/project.json +++ b/src/Microsoft.AspNet.Security/project.json @@ -1,4 +1,4 @@ -{ +{ "version": "1.0.0-*", "dependencies": { "Microsoft.AspNet.FeatureModel": "1.0.0-*", @@ -13,7 +13,7 @@ "net45": {}, "k10": { "dependencies": { - "System.Collections": "4.0.0.0", + "System.Collections": "4.0.10.0", "System.ComponentModel": "4.0.0.0", "System.Console": "4.0.0.0", "System.Diagnostics.Debug": "4.0.10.0", From 8b46d43dcba91b385a7e0393d858d114ee1e9622 Mon Sep 17 00:00:00 2001 From: Chris Ross Date: Wed, 16 Jul 2014 14:44:42 -0700 Subject: [PATCH 022/216] Make middleware report when auth fails (async). --- .../Infrastructure/AuthenticationHandler.cs | 32 +++++++++++-------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/src/Microsoft.AspNet.Security/Infrastructure/AuthenticationHandler.cs b/src/Microsoft.AspNet.Security/Infrastructure/AuthenticationHandler.cs index 6c8da45c6..3526d1e5b 100644 --- a/src/Microsoft.AspNet.Security/Infrastructure/AuthenticationHandler.cs +++ b/src/Microsoft.AspNet.Security/Infrastructure/AuthenticationHandler.cs @@ -153,20 +153,6 @@ public virtual void Authenticate(IAuthenticateContext context) } } - public AuthenticationTicket Authenticate() - { - return LazyInitializer.EnsureInitialized( - ref _authenticate, - ref _authenticateInitialized, - ref _authenticateSyncLock, - () => - { - return Task.FromResult(AuthenticateCore()); - }).Result; - } - - protected abstract AuthenticationTicket AuthenticateCore(); - public virtual async Task AuthenticateAsync(IAuthenticateContext context) { if (context.AuthenticationTypes.Contains(BaseOptions.AuthenticationType, StringComparer.Ordinal)) @@ -176,6 +162,10 @@ public virtual async Task AuthenticateAsync(IAuthenticateContext context) { context.Authenticated(ticket.Identity, ticket.Properties.Dictionary, BaseOptions.Description.Dictionary); } + else + { + context.NotAuthenticated(BaseOptions.AuthenticationType, properties: null, description: BaseOptions.Description.Dictionary); + } } if (PriorHandler != null) @@ -184,6 +174,20 @@ public virtual async Task AuthenticateAsync(IAuthenticateContext context) } } + public AuthenticationTicket Authenticate() + { + return LazyInitializer.EnsureInitialized( + ref _authenticate, + ref _authenticateInitialized, + ref _authenticateSyncLock, + () => + { + return Task.FromResult(AuthenticateCore()); + }).Result; + } + + protected abstract AuthenticationTicket AuthenticateCore(); + /// /// Causes the authentication logic in AuthenticateCore to be performed for the current request /// at most once and returns the results. Calling Authenticate more than once will always return From fadf6ae5e2bc4d19eff47d1a4e92412f116301eb Mon Sep 17 00:00:00 2001 From: Chris Ross Date: Wed, 16 Jul 2014 14:44:57 -0700 Subject: [PATCH 023/216] Add missing sample namespace. --- samples/CookieSample/Startup.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/samples/CookieSample/Startup.cs b/samples/CookieSample/Startup.cs index d648a1523..2a01fc0b2 100644 --- a/samples/CookieSample/Startup.cs +++ b/samples/CookieSample/Startup.cs @@ -1,5 +1,6 @@ using System.Security.Claims; using Microsoft.AspNet.Builder; +using Microsoft.AspNet.Http; using Microsoft.AspNet.Security.Cookies; namespace CookieSample From e09448a3831baf99da53dd87f3e1128579daaab7 Mon Sep 17 00:00:00 2001 From: Chris Ross Date: Wed, 16 Jul 2014 14:45:13 -0700 Subject: [PATCH 024/216] Update solution. --- Security.sln | 84 ++++++++++++++++++++++++++-------------------------- 1 file changed, 42 insertions(+), 42 deletions(-) diff --git a/Security.sln b/Security.sln index 752ce9ab0..39d830ee2 100644 --- a/Security.sln +++ b/Security.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 2013 -VisualStudioVersion = 12.0.30411.0 +# Visual Studio 14 +VisualStudioVersion = 14.0.21813.0 MinimumVisualStudioVersion = 10.0.40219.1 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{4D2B6A51-2F9F-44F5-8131-EA5CAC053652}" EndProject @@ -27,46 +27,46 @@ Global Release|x86 = Release|x86 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {0F174C63-1898-4024-9A3C-3FDF5CAE5C68}.Debug|Any CPU.ActiveCfg = Debug|x86 - {0F174C63-1898-4024-9A3C-3FDF5CAE5C68}.Debug|Mixed Platforms.ActiveCfg = Debug|x86 - {0F174C63-1898-4024-9A3C-3FDF5CAE5C68}.Debug|Mixed Platforms.Build.0 = Debug|x86 - {0F174C63-1898-4024-9A3C-3FDF5CAE5C68}.Debug|x86.ActiveCfg = Debug|x86 - {0F174C63-1898-4024-9A3C-3FDF5CAE5C68}.Debug|x86.Build.0 = Debug|x86 - {0F174C63-1898-4024-9A3C-3FDF5CAE5C68}.Release|Any CPU.ActiveCfg = Release|x86 - {0F174C63-1898-4024-9A3C-3FDF5CAE5C68}.Release|Mixed Platforms.ActiveCfg = Release|x86 - {0F174C63-1898-4024-9A3C-3FDF5CAE5C68}.Release|Mixed Platforms.Build.0 = Release|x86 - {0F174C63-1898-4024-9A3C-3FDF5CAE5C68}.Release|x86.ActiveCfg = Release|x86 - {0F174C63-1898-4024-9A3C-3FDF5CAE5C68}.Release|x86.Build.0 = Release|x86 - {15F1211B-B695-4A1C-B730-1AC58FC91090}.Debug|Any CPU.ActiveCfg = Debug|x86 - {15F1211B-B695-4A1C-B730-1AC58FC91090}.Debug|Mixed Platforms.ActiveCfg = Debug|x86 - {15F1211B-B695-4A1C-B730-1AC58FC91090}.Debug|Mixed Platforms.Build.0 = Debug|x86 - {15F1211B-B695-4A1C-B730-1AC58FC91090}.Debug|x86.ActiveCfg = Debug|x86 - {15F1211B-B695-4A1C-B730-1AC58FC91090}.Debug|x86.Build.0 = Debug|x86 - {15F1211B-B695-4A1C-B730-1AC58FC91090}.Release|Any CPU.ActiveCfg = Release|x86 - {15F1211B-B695-4A1C-B730-1AC58FC91090}.Release|Mixed Platforms.ActiveCfg = Release|x86 - {15F1211B-B695-4A1C-B730-1AC58FC91090}.Release|Mixed Platforms.Build.0 = Release|x86 - {15F1211B-B695-4A1C-B730-1AC58FC91090}.Release|x86.ActiveCfg = Release|x86 - {15F1211B-B695-4A1C-B730-1AC58FC91090}.Release|x86.Build.0 = Release|x86 - {558C2C2A-AED8-49DE-BB60-D5F8AE06C714}.Debug|Any CPU.ActiveCfg = Debug|x86 - {558C2C2A-AED8-49DE-BB60-D5F8AE06C714}.Debug|Mixed Platforms.ActiveCfg = Debug|x86 - {558C2C2A-AED8-49DE-BB60-D5F8AE06C714}.Debug|Mixed Platforms.Build.0 = Debug|x86 - {558C2C2A-AED8-49DE-BB60-D5F8AE06C714}.Debug|x86.ActiveCfg = Debug|x86 - {558C2C2A-AED8-49DE-BB60-D5F8AE06C714}.Debug|x86.Build.0 = Debug|x86 - {558C2C2A-AED8-49DE-BB60-D5F8AE06C714}.Release|Any CPU.ActiveCfg = Release|x86 - {558C2C2A-AED8-49DE-BB60-D5F8AE06C714}.Release|Mixed Platforms.ActiveCfg = Release|x86 - {558C2C2A-AED8-49DE-BB60-D5F8AE06C714}.Release|Mixed Platforms.Build.0 = Release|x86 - {558C2C2A-AED8-49DE-BB60-D5F8AE06C714}.Release|x86.ActiveCfg = Release|x86 - {558C2C2A-AED8-49DE-BB60-D5F8AE06C714}.Release|x86.Build.0 = Release|x86 - {8DA26CD1-1302-4CFD-9270-9FA1B7C6138B}.Debug|Any CPU.ActiveCfg = Debug|x86 - {8DA26CD1-1302-4CFD-9270-9FA1B7C6138B}.Debug|Mixed Platforms.ActiveCfg = Debug|x86 - {8DA26CD1-1302-4CFD-9270-9FA1B7C6138B}.Debug|Mixed Platforms.Build.0 = Debug|x86 - {8DA26CD1-1302-4CFD-9270-9FA1B7C6138B}.Debug|x86.ActiveCfg = Debug|x86 - {8DA26CD1-1302-4CFD-9270-9FA1B7C6138B}.Debug|x86.Build.0 = Debug|x86 - {8DA26CD1-1302-4CFD-9270-9FA1B7C6138B}.Release|Any CPU.ActiveCfg = Release|x86 - {8DA26CD1-1302-4CFD-9270-9FA1B7C6138B}.Release|Mixed Platforms.ActiveCfg = Release|x86 - {8DA26CD1-1302-4CFD-9270-9FA1B7C6138B}.Release|Mixed Platforms.Build.0 = Release|x86 - {8DA26CD1-1302-4CFD-9270-9FA1B7C6138B}.Release|x86.ActiveCfg = Release|x86 - {8DA26CD1-1302-4CFD-9270-9FA1B7C6138B}.Release|x86.Build.0 = Release|x86 + {0F174C63-1898-4024-9A3C-3FDF5CAE5C68}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {0F174C63-1898-4024-9A3C-3FDF5CAE5C68}.Debug|Any CPU.Build.0 = Debug|Any CPU + {0F174C63-1898-4024-9A3C-3FDF5CAE5C68}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {0F174C63-1898-4024-9A3C-3FDF5CAE5C68}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {0F174C63-1898-4024-9A3C-3FDF5CAE5C68}.Debug|x86.ActiveCfg = Debug|Any CPU + {0F174C63-1898-4024-9A3C-3FDF5CAE5C68}.Release|Any CPU.ActiveCfg = Release|Any CPU + {0F174C63-1898-4024-9A3C-3FDF5CAE5C68}.Release|Any CPU.Build.0 = Release|Any CPU + {0F174C63-1898-4024-9A3C-3FDF5CAE5C68}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {0F174C63-1898-4024-9A3C-3FDF5CAE5C68}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {0F174C63-1898-4024-9A3C-3FDF5CAE5C68}.Release|x86.ActiveCfg = Release|Any CPU + {15F1211B-B695-4A1C-B730-1AC58FC91090}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {15F1211B-B695-4A1C-B730-1AC58FC91090}.Debug|Any CPU.Build.0 = Debug|Any CPU + {15F1211B-B695-4A1C-B730-1AC58FC91090}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {15F1211B-B695-4A1C-B730-1AC58FC91090}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {15F1211B-B695-4A1C-B730-1AC58FC91090}.Debug|x86.ActiveCfg = Debug|Any CPU + {15F1211B-B695-4A1C-B730-1AC58FC91090}.Release|Any CPU.ActiveCfg = Release|Any CPU + {15F1211B-B695-4A1C-B730-1AC58FC91090}.Release|Any CPU.Build.0 = Release|Any CPU + {15F1211B-B695-4A1C-B730-1AC58FC91090}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {15F1211B-B695-4A1C-B730-1AC58FC91090}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {15F1211B-B695-4A1C-B730-1AC58FC91090}.Release|x86.ActiveCfg = Release|Any CPU + {558C2C2A-AED8-49DE-BB60-D5F8AE06C714}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {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|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|x86.ActiveCfg = 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|x86.ActiveCfg = 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|x86.ActiveCfg = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE From 8b0500dacfb81470eb97c7432cdb722b52ace757 Mon Sep 17 00:00:00 2001 From: Pranav K Date: Thu, 17 Jul 2014 09:19:22 -0700 Subject: [PATCH 025/216] Replace RNGCryptoServiceProvider with RandomNumberGenerator --- .../Infrastructure/AuthenticationHandler.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Microsoft.AspNet.Security/Infrastructure/AuthenticationHandler.cs b/src/Microsoft.AspNet.Security/Infrastructure/AuthenticationHandler.cs index 3526d1e5b..57c1931f9 100644 --- a/src/Microsoft.AspNet.Security/Infrastructure/AuthenticationHandler.cs +++ b/src/Microsoft.AspNet.Security/Infrastructure/AuthenticationHandler.cs @@ -23,7 +23,7 @@ namespace Microsoft.AspNet.Security.Infrastructure /// public abstract class AuthenticationHandler : IAuthenticationHandler { - private static readonly RNGCryptoServiceProvider CryptoRandom = new RNGCryptoServiceProvider(); + private static readonly RandomNumberGenerator CryptoRandom = RandomNumberGenerator.Create(); private Task _authenticate; private bool _authenticateInitialized; From c733aa880478ba45029a4686b62d174bade3ab23 Mon Sep 17 00:00:00 2001 From: Chris Ross Date: Fri, 25 Jul 2014 15:43:38 -0700 Subject: [PATCH 026/216] #28 - Use a GZipStream constructor that's supported on Mono. --- .../DataHandler/Serializer/TicketSerializer.cs | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/Microsoft.AspNet.Security/DataHandler/Serializer/TicketSerializer.cs b/src/Microsoft.AspNet.Security/DataHandler/Serializer/TicketSerializer.cs index c6dbfc132..7bfa9a1e6 100644 --- a/src/Microsoft.AspNet.Security/DataHandler/Serializer/TicketSerializer.cs +++ b/src/Microsoft.AspNet.Security/DataHandler/Serializer/TicketSerializer.cs @@ -13,6 +13,7 @@ namespace Microsoft.AspNet.Security.DataHandler.Serializer { public class TicketSerializer : IDataSerializer { + private static readonly bool IsMono = Type.GetType("Mono.Runtime") != null; private const int FormatVersion = 2; [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2202:Do not dispose objects multiple times", Justification = "Dispose is idempotent")] @@ -20,7 +21,17 @@ public virtual byte[] Serialize(AuthenticationTicket model) { using (var memory = new MemoryStream()) { - using (var compression = new GZipStream(memory, CompressionLevel.Optimal)) + GZipStream compression; + if (IsMono) + { + // The other constructor is not currently supported on Mono. + compression = new GZipStream(memory, CompressionMode.Compress); + } + else + { + compression = new GZipStream(memory, CompressionLevel.Optimal); + } + using (compression) { using (var writer = new BinaryWriter(compression)) { From 382573a6dc5e44692b6038299b7d97702ca39e2a Mon Sep 17 00:00:00 2001 From: Pranav K Date: Tue, 5 Aug 2014 15:50:34 -0700 Subject: [PATCH 027/216] Updating release Nuget.config --- NuGet.Config | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/NuGet.Config b/NuGet.Config index f41e9c631..1ce6b9e25 100644 --- a/NuGet.Config +++ b/NuGet.Config @@ -1,7 +1,7 @@ - + - + From d5ce9fe736f7e5b9f54b40a7b8271409133b561d Mon Sep 17 00:00:00 2001 From: Pranav K Date: Wed, 6 Aug 2014 12:30:49 -0700 Subject: [PATCH 028/216] Updating dev Nuget.config --- NuGet.Config | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/NuGet.Config b/NuGet.Config index 1ce6b9e25..f41e9c631 100644 --- a/NuGet.Config +++ b/NuGet.Config @@ -1,7 +1,7 @@ - + - + From 05804c78dbdf70da1f201ca7008a93f4720148c2 Mon Sep 17 00:00:00 2001 From: Chris Ross Date: Wed, 6 Aug 2014 15:28:09 -0700 Subject: [PATCH 029/216] Port more security tests from Katana. --- Security.sln | 10 +- .../CookieAuthenticationHandler.cs | 55 +- ...icateSubjectKeyIdentifierValidatorTests.cs | 123 +++++ ...icateSubjectPublicKeyInfoValidatorTests.cs | 173 +++++++ .../CertificateThumbprintValidatorTests.cs | 121 +++++ .../Cookies/CookieMiddlewareTests.cs | 479 ++++++++++++++++++ .../Encoder/Base64UrlTextEncoderTests.cs | 32 ++ ... => Microsoft.AspNet.Security.Tests.kproj} | 11 +- .../SecurityHelperTests.cs | 103 ++++ .../TestClock.cs | 23 + .../katanatest.redmond.corp.microsoft.com.cer | Bin 0 -> 1462 bytes .../project.json | 8 +- .../selfSigned.cer | Bin 0 -> 762 bytes 13 files changed, 1117 insertions(+), 21 deletions(-) create mode 100644 test/Microsoft.AspNet.Security.Test/CertificateSubjectKeyIdentifierValidatorTests.cs create mode 100644 test/Microsoft.AspNet.Security.Test/CertificateSubjectPublicKeyInfoValidatorTests.cs create mode 100644 test/Microsoft.AspNet.Security.Test/CertificateThumbprintValidatorTests.cs create mode 100644 test/Microsoft.AspNet.Security.Test/Cookies/CookieMiddlewareTests.cs create mode 100644 test/Microsoft.AspNet.Security.Test/DataHandler/Encoder/Base64UrlTextEncoderTests.cs rename test/Microsoft.AspNet.Security.Test/{Microsoft.AspNet.Security.kproj => Microsoft.AspNet.Security.Tests.kproj} (70%) create mode 100644 test/Microsoft.AspNet.Security.Test/SecurityHelperTests.cs create mode 100644 test/Microsoft.AspNet.Security.Test/TestClock.cs create mode 100644 test/Microsoft.AspNet.Security.Test/katanatest.redmond.corp.microsoft.com.cer create mode 100644 test/Microsoft.AspNet.Security.Test/selfSigned.cer diff --git a/Security.sln b/Security.sln index 39d830ee2..268ecf4a6 100644 --- a/Security.sln +++ b/Security.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 14 -VisualStudioVersion = 14.0.21813.0 +VisualStudioVersion = 14.0.21916.0 MinimumVisualStudioVersion = 10.0.40219.1 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{4D2B6A51-2F9F-44F5-8131-EA5CAC053652}" EndProject @@ -15,7 +15,13 @@ Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "CookieSample", "samples\Coo EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{7BF11F3A-60B6-4796-B504-579C67FFBA34}" EndProject -Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNet.Security", "test\Microsoft.AspNet.Security.Test\Microsoft.AspNet.Security.kproj", "{8DA26CD1-1302-4CFD-9270-9FA1B7C6138B}" +Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNet.Security.Tests", "test\Microsoft.AspNet.Security.Test\Microsoft.AspNet.Security.Tests.kproj", "{8DA26CD1-1302-4CFD-9270-9FA1B7C6138B}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{C40A5A3B-ABA3-4819-9C44-D821E6DA1BA1}" + ProjectSection(SolutionItems) = preProject + global.json = global.json + EndProjectSection +EndProject EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution diff --git a/src/Microsoft.AspNet.Security.Cookies/CookieAuthenticationHandler.cs b/src/Microsoft.AspNet.Security.Cookies/CookieAuthenticationHandler.cs index 44d81db7f..1e21937fa 100644 --- a/src/Microsoft.AspNet.Security.Cookies/CookieAuthenticationHandler.cs +++ b/src/Microsoft.AspNet.Security.Cookies/CookieAuthenticationHandler.cs @@ -5,6 +5,7 @@ using System; using System.Threading.Tasks; using Microsoft.AspNet.Http; +using Microsoft.AspNet.Http.Security; using Microsoft.AspNet.Security.Infrastructure; using Microsoft.Framework.Logging; @@ -120,17 +121,28 @@ protected override async Task ApplyResponseGrantAsync() signin.Properties, cookieOptions); - DateTimeOffset issuedUtc = Options.SystemClock.UtcNow; - DateTimeOffset expiresUtc = issuedUtc.Add(Options.ExpireTimeSpan); + DateTimeOffset issuedUtc; + if (signin.Properties.IssuedUtc.HasValue) + { + issuedUtc = signin.Properties.IssuedUtc.Value; + } + else + { + issuedUtc = Options.SystemClock.UtcNow; + signin.Properties.IssuedUtc = issuedUtc; + } - context.Properties.IssuedUtc = issuedUtc; - context.Properties.ExpiresUtc = expiresUtc; + if (!signin.Properties.ExpiresUtc.HasValue) + { + signin.Properties.ExpiresUtc = issuedUtc.Add(Options.ExpireTimeSpan); + } Options.Notifications.ResponseSignIn(context); if (context.Properties.IsPersistent) { - cookieOptions.Expires = expiresUtc.ToUniversalTime().DateTime; + DateTimeOffset expiresUtc = context.Properties.ExpiresUtc ?? issuedUtc.Add(Options.ExpireTimeSpan); + context.CookieOptions.Expires = expiresUtc.ToUniversalTime().DateTime; } var model = new AuthenticationTicket(context.Identity, context.Properties); @@ -229,18 +241,27 @@ protected override void ApplyResponseChallenge() return; } - string currentUri = - Request.PathBase + - Request.Path + - Request.QueryString; - - string loginUri = - Request.Scheme + - "://" + - Request.Host + - Request.PathBase + - Options.LoginPath + - new QueryString(Options.ReturnUrlParameter, currentUri); + string loginUri = string.Empty; + if (ChallengeContext != null) + { + loginUri = new AuthenticationProperties(ChallengeContext.Properties).RedirectUri; + } + + if (string.IsNullOrWhiteSpace(loginUri)) + { + string currentUri = + Request.PathBase + + Request.Path + + Request.QueryString; + + loginUri = + Request.Scheme + + "://" + + Request.Host + + Request.PathBase + + Options.LoginPath + + new QueryString(Options.ReturnUrlParameter, currentUri); + } var redirectContext = new CookieApplyRedirectContext(Context, Options, loginUri); Options.Notifications.ApplyRedirect(redirectContext); diff --git a/test/Microsoft.AspNet.Security.Test/CertificateSubjectKeyIdentifierValidatorTests.cs b/test/Microsoft.AspNet.Security.Test/CertificateSubjectKeyIdentifierValidatorTests.cs new file mode 100644 index 000000000..4771b9830 --- /dev/null +++ b/test/Microsoft.AspNet.Security.Test/CertificateSubjectKeyIdentifierValidatorTests.cs @@ -0,0 +1,123 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Net.Security; +using System.Security.Cryptography.X509Certificates; +using Shouldly; +using Xunit; + +namespace Microsoft.AspNet.Security +{ + public class CertificateSubjectKeyIdentifierValidatorTests + { + private static readonly X509Certificate2 SelfSigned = new X509Certificate2("selfSigned.cer"); + private static readonly X509Certificate2 Chained = new X509Certificate2("katanatest.redmond.corp.microsoft.com.cer"); + + // The Katana test cert has a valid full chain + // katanatest.redmond.corp.microsoft.com -> MSIT Machine Auth CA2 -> Microsoft Internet Authority -> Baltimore CyberTrustRoot + + private const string KatanaTestKeyIdentifier = "d964b2941aaf3e62761041b1f3db098edfa3270a"; + private const string MicrosoftInternetAuthorityKeyIdentifier = "2a4d97955d347e9db6e633be9c27c1707e67dbc1"; + + [Fact] + public void ConstructorShouldNotThrowWithValidValues() + { + var instance = new CertificateSubjectKeyIdentifierValidator(new[] { string.Empty }); + + instance.ShouldNotBe(null); + } + + [Fact] + public void ConstructorShouldThrownWhenTheValidHashEnumerableIsNull() + { + Should.Throw(() => + new CertificateSubjectKeyIdentifierValidator(null)); + } + + [Fact] + public void ValidatorShouldReturnFalseWhenSslPolicyErrorsIsRemoteCertificateChainErrors() + { + var instance = new CertificateSubjectKeyIdentifierValidator(new[] { string.Empty }); + bool result = instance.Validate(null, null, null, SslPolicyErrors.RemoteCertificateChainErrors); + result.ShouldBe(false); + } + + [Fact] + public void ValidatorShouldReturnFalseWhenSslPolicyErrorsIsRemoteCertificateNameMismatch() + { + var instance = new CertificateSubjectKeyIdentifierValidator(new[] { string.Empty }); + bool result = instance.Validate(null, null, null, SslPolicyErrors.RemoteCertificateNameMismatch); + result.ShouldBe(false); + } + + [Fact] + public void ValidatorShouldReturnFalseWhenSslPolicyErrorsIsRemoteCertificateNotAvailable() + { + var instance = new CertificateSubjectKeyIdentifierValidator(new[] { string.Empty }); + bool result = instance.Validate(null, null, null, SslPolicyErrors.RemoteCertificateNotAvailable); + result.ShouldBe(false); + } + + [Fact] + public void ValidatorShouldReturnFalseWhenPassedASelfSignedCertificate() + { + var instance = new CertificateSubjectKeyIdentifierValidator(new[] { string.Empty }); + var certificateChain = new X509Chain(); + certificateChain.Build(SelfSigned); + certificateChain.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck; + + bool result = instance.Validate(null, SelfSigned, certificateChain, SslPolicyErrors.None); + + result.ShouldBe(false); + } + + [Fact] + public void ValidatorShouldReturnFalseWhenPassedATrustedCertificateWhichDoesNotHaveAWhitelistedSubjectKeyIdentifier() + { + var instance = new CertificateSubjectKeyIdentifierValidator(new[] { string.Empty }); + var certificateChain = new X509Chain(); + certificateChain.Build(Chained); + certificateChain.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck; + + bool result = instance.Validate(null, Chained, certificateChain, SslPolicyErrors.None); + + result.ShouldBe(false); + } + + [Fact] + public void ValidatorShouldReturnTrueWhenPassedATrustedCertificateWhichHasItsSubjectKeyIdentifierWhiteListed() + { + var instance = new CertificateSubjectKeyIdentifierValidator( + new[] + { + KatanaTestKeyIdentifier + }); + + var certificateChain = new X509Chain(); + certificateChain.Build(Chained); + certificateChain.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck; + + bool result = instance.Validate(null, Chained, certificateChain, SslPolicyErrors.None); + + result.ShouldBe(true); + } + + [Fact] + public void ValidatorShouldReturnTrueWhenPassedATrustedCertificateWhichHasAChainElementSubjectKeyIdentifierWhiteListed() + { + var instance = new CertificateSubjectKeyIdentifierValidator( + new[] + { + MicrosoftInternetAuthorityKeyIdentifier + }); + var certificateChain = new X509Chain(); + certificateChain.Build(Chained); + certificateChain.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck; + + bool result = instance.Validate(null, Chained, certificateChain, SslPolicyErrors.None); + + result.ShouldBe(true); + } + } +} diff --git a/test/Microsoft.AspNet.Security.Test/CertificateSubjectPublicKeyInfoValidatorTests.cs b/test/Microsoft.AspNet.Security.Test/CertificateSubjectPublicKeyInfoValidatorTests.cs new file mode 100644 index 000000000..28270cd48 --- /dev/null +++ b/test/Microsoft.AspNet.Security.Test/CertificateSubjectPublicKeyInfoValidatorTests.cs @@ -0,0 +1,173 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Net.Security; +using System.Security.Cryptography.X509Certificates; +using Shouldly; +using Xunit; + +namespace Microsoft.AspNet.Security +{ + public class CertificateSubjectPublicKeyInfoValidatorTests + { + private static readonly X509Certificate2 SelfSigned = new X509Certificate2("selfSigned.cer"); + private static readonly X509Certificate2 Chained = new X509Certificate2("katanatest.redmond.corp.microsoft.com.cer"); + + // The Katana test cert has a valid full chain + // katanatest.redmond.corp.microsoft.com -> MSIT Machine Auth CA2 -> Microsoft Internet Authority -> Baltimore CyberTrustRoot + + // The following fingerprints were generated using the go program in appendix A of the Public Key Pinning Extension for HTTP + // draft-ietf-websec-key-pinning-05 + + private const string KatanaTestSha1Hash = "xvNsCWwxvL3qsCYChZLiwNm1D6o="; + private const string KatanaTestSha256Hash = "AhR1Y/xhxK2uD7YJ0xKUPq8tYrWm4+F7DgO2wUOqB+4="; + + private const string MicrosoftInternetAuthoritySha1Hash = "Z3HnseSVDEPu5hZoj05/bBSnT/s="; + private const string MicrosoftInternetAuthoritySha256Hash = "UQTPeq/Tlg/vLt2ijtl7qlMFBFkbGG9aAWJbQMOMWFg="; + + [Fact] + public void ConstructorShouldNotThrowWithValidValues() + { + var instance = new CertificateSubjectPublicKeyInfoValidator(new string[1], SubjectPublicKeyInfoAlgorithm.Sha1); + + instance.ShouldNotBe(null); + } + + [Fact] + public void ConstructorShouldThrownWhenTheValidHashEnumerableIsNull() + { + Should.Throw(() => + new CertificateSubjectPublicKeyInfoValidator(null, SubjectPublicKeyInfoAlgorithm.Sha1)); + } + + [Fact] + public void ConstructorShouldThrowWhenTheHashEnumerableContainsNoHashes() + { + Should.Throw(() => + new CertificateSubjectPublicKeyInfoValidator(new string[0], SubjectPublicKeyInfoAlgorithm.Sha1)); + } + + [Fact] + public void ConstructorShouldThrowIfAnInvalidAlgorithmIsPassed() + { + Should.Throw(() => + new CertificateSubjectPublicKeyInfoValidator(new string[0], (SubjectPublicKeyInfoAlgorithm)2)); + } + + [Fact] + public void ValidatorShouldReturnFalseWhenSslPolicyErrorsIsRemoteCertificateChainErrors() + { + var instance = new CertificateSubjectPublicKeyInfoValidator(new string[1], SubjectPublicKeyInfoAlgorithm.Sha1); + bool result = instance.Validate(null, null, null, SslPolicyErrors.RemoteCertificateChainErrors); + result.ShouldBe(false); + } + + [Fact] + public void ValidatorShouldReturnFalseWhenSslPolicyErrorsIsRemoteCertificateNameMismatch() + { + var instance = new CertificateSubjectPublicKeyInfoValidator(new string[1], SubjectPublicKeyInfoAlgorithm.Sha1); + bool result = instance.Validate(null, null, null, SslPolicyErrors.RemoteCertificateNameMismatch); + result.ShouldBe(false); + } + + [Fact] + public void ValidatorShouldReturnFalseWhenSslPolicyErrorsIsRemoteCertificateNotAvailable() + { + var instance = new CertificateSubjectPublicKeyInfoValidator(new string[1], SubjectPublicKeyInfoAlgorithm.Sha1); + bool result = instance.Validate(null, null, null, SslPolicyErrors.RemoteCertificateNotAvailable); + result.ShouldBe(false); + } + + [Fact] + public void ValidatorShouldReturnFalseWhenPassedASelfSignedCertificate() + { + var instance = new CertificateSubjectPublicKeyInfoValidator(new string[1], SubjectPublicKeyInfoAlgorithm.Sha1); + var certificateChain = new X509Chain(); + certificateChain.Build(SelfSigned); + certificateChain.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck; + + bool result = instance.Validate(null, SelfSigned, certificateChain, SslPolicyErrors.None); + + result.ShouldBe(false); + } + + [Fact] + public void ValidatorShouldReturnFalseWhenPassedATrustedCertificateWhichDoesNotHaveAWhitelistedSha1Spki() + { + var instance = new CertificateSubjectPublicKeyInfoValidator(new string[1], SubjectPublicKeyInfoAlgorithm.Sha1); + var certificateChain = new X509Chain(); + certificateChain.Build(Chained); + certificateChain.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck; + + bool result = instance.Validate(null, Chained, certificateChain, SslPolicyErrors.None); + + result.ShouldBe(false); + } + + [Fact] + public void ValidatorShouldReturnTrueWhenPassedATrustedCertificateWhichHasItsSha1SpkiWhiteListed() + { + var instance = new CertificateSubjectPublicKeyInfoValidator(new[] { KatanaTestSha1Hash }, SubjectPublicKeyInfoAlgorithm.Sha1); + var certificateChain = new X509Chain(); + certificateChain.Build(Chained); + certificateChain.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck; + + bool result = instance.Validate(null, Chained, certificateChain, SslPolicyErrors.None); + + result.ShouldBe(true); + } + + [Fact] + public void ValidatorShouldReturnTrueWhenPassedATrustedCertificateWhichHasAChainElementSha1SpkiWhiteListed() + { + var instance = new CertificateSubjectPublicKeyInfoValidator(new[] { MicrosoftInternetAuthoritySha1Hash }, SubjectPublicKeyInfoAlgorithm.Sha1); + var certificateChain = new X509Chain(); + certificateChain.Build(Chained); + certificateChain.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck; + + bool result = instance.Validate(null, Chained, certificateChain, SslPolicyErrors.None); + + result.ShouldBe(true); + } + + [Fact] + public void ValidatorShouldReturnFalseWhenPassedATrustedCertificateWhichDoesNotHaveAWhitelistedSha256Spki() + { + var instance = new CertificateSubjectPublicKeyInfoValidator(new string[1], SubjectPublicKeyInfoAlgorithm.Sha256); + var certificateChain = new X509Chain(); + certificateChain.Build(Chained); + certificateChain.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck; + + bool result = instance.Validate(null, Chained, certificateChain, SslPolicyErrors.None); + + result.ShouldBe(false); + } + + [Fact] + public void ValidatorShouldReturnTrueWhenPassedATrustedCertificateWhichHasItsSha256SpkiWhiteListed() + { + var instance = new CertificateSubjectPublicKeyInfoValidator(new[] { KatanaTestSha256Hash }, SubjectPublicKeyInfoAlgorithm.Sha256); + var certificateChain = new X509Chain(); + certificateChain.Build(Chained); + certificateChain.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck; + + bool result = instance.Validate(null, Chained, certificateChain, SslPolicyErrors.None); + + result.ShouldBe(true); + } + + [Fact] + public void ValidatorShouldReturnTrueWhenPassedATrustedCertificateWhichHasAChainElementSha256SpkiWhiteListed() + { + var instance = new CertificateSubjectPublicKeyInfoValidator(new[] { MicrosoftInternetAuthoritySha256Hash }, SubjectPublicKeyInfoAlgorithm.Sha256); + var certificateChain = new X509Chain(); + certificateChain.Build(Chained); + certificateChain.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck; + + bool result = instance.Validate(null, Chained, certificateChain, SslPolicyErrors.None); + + result.ShouldBe(true); + } + } +} diff --git a/test/Microsoft.AspNet.Security.Test/CertificateThumbprintValidatorTests.cs b/test/Microsoft.AspNet.Security.Test/CertificateThumbprintValidatorTests.cs new file mode 100644 index 000000000..82e4a3a3d --- /dev/null +++ b/test/Microsoft.AspNet.Security.Test/CertificateThumbprintValidatorTests.cs @@ -0,0 +1,121 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Net.Security; +using System.Security.Cryptography.X509Certificates; +using Shouldly; +using Xunit; + +namespace Microsoft.AspNet.Security +{ + public class CertificateThumbprintValidatorTests + { + private static readonly X509Certificate2 SelfSigned = new X509Certificate2("selfSigned.cer"); + private static readonly X509Certificate2 Chained = new X509Certificate2("katanatest.redmond.corp.microsoft.com.cer"); + + // The Katana test cert has a valid full chain + // katanatest.redmond.corp.microsoft.com -> MSIT Machine Auth CA2 -> Microsoft Internet Authority -> Baltimore CyberTrustRoot + + private const string KatanaTestThumbprint = "a9894c464b260cac3f5b91cece33b3c55e82e61c"; + private const string MicrosoftInternetAuthorityThumbprint = "992ad44d7dce298de17e6f2f56a7b9caa41db93f"; + + [Fact] + public void ConstructorShouldNotThrowWithValidValues() + { + var instance = new CertificateThumbprintValidator(new string[1]); + + instance.ShouldNotBe(null); + } + + [Fact] + public void ConstructorShouldThrownWhenTheValidHashEnumerableIsNull() + { + Should.Throw(() => + new CertificateThumbprintValidator(null)); + } + + [Fact] + public void ConstructorShouldThrowWhenTheHashEnumerableContainsNoHashes() + { + Should.Throw(() => + new CertificateThumbprintValidator(new string[0])); + } + + [Fact] + public void ValidatorShouldReturnFalseWhenSslPolicyErrorsIsRemoteCertificateChainErrors() + { + var instance = new CertificateThumbprintValidator(new string[1]); + bool result = instance.Validate(null, null, null, SslPolicyErrors.RemoteCertificateChainErrors); + result.ShouldBe(false); + } + + [Fact] + public void ValidatorShouldReturnFalseWhenSslPolicyErrorsIsRemoteCertificateNameMismatch() + { + var instance = new CertificateThumbprintValidator(new string[1]); + bool result = instance.Validate(null, null, null, SslPolicyErrors.RemoteCertificateNameMismatch); + result.ShouldBe(false); + } + + [Fact] + public void ValidatorShouldReturnFalseWhenSslPolicyErrorsIsRemoteCertificateNotAvailable() + { + var instance = new CertificateThumbprintValidator(new string[1]); + bool result = instance.Validate(null, null, null, SslPolicyErrors.RemoteCertificateNotAvailable); + result.ShouldBe(false); + } + + [Fact] + public void ValidatorShouldReturnFalseWhenPassedASelfSignedCertificate() + { + var instance = new CertificateThumbprintValidator(new string[1]); + var certificateChain = new X509Chain(); + certificateChain.Build(SelfSigned); + certificateChain.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck; + + bool result = instance.Validate(null, SelfSigned, certificateChain, SslPolicyErrors.None); + + result.ShouldBe(false); + } + + [Fact] + public void ValidatorShouldReturnFalseWhenPassedATrustedCertificateWhichDoesNotHaveAWhitelistedThumbprint() + { + var instance = new CertificateThumbprintValidator(new string[1]); + var certificateChain = new X509Chain(); + certificateChain.Build(Chained); + certificateChain.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck; + + bool result = instance.Validate(null, Chained, certificateChain, SslPolicyErrors.None); + + result.ShouldBe(false); + } + + [Fact] + public void ValidatorShouldReturnTrueWhenPassedATrustedCertificateWhichHasItsThumbprintWhiteListed() + { + var instance = new CertificateThumbprintValidator(new[] { KatanaTestThumbprint }); + var certificateChain = new X509Chain(); + certificateChain.Build(Chained); + certificateChain.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck; + + bool result = instance.Validate(null, Chained, certificateChain, SslPolicyErrors.None); + + result.ShouldBe(true); + } + + [Fact] + public void ValidatorShouldReturnTrueWhenPassedATrustedCertificateWhichHasAChainElementThumbprintWhiteListed() + { + var instance = new CertificateThumbprintValidator(new[] { MicrosoftInternetAuthorityThumbprint }); + var certificateChain = new X509Chain(); + certificateChain.Build(Chained); + certificateChain.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck; + + bool result = instance.Validate(null, Chained, certificateChain, SslPolicyErrors.None); + + result.ShouldBe(true); + } + } +} diff --git a/test/Microsoft.AspNet.Security.Test/Cookies/CookieMiddlewareTests.cs b/test/Microsoft.AspNet.Security.Test/Cookies/CookieMiddlewareTests.cs new file mode 100644 index 000000000..6578ba600 --- /dev/null +++ b/test/Microsoft.AspNet.Security.Test/Cookies/CookieMiddlewareTests.cs @@ -0,0 +1,479 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.IO; +using System.Linq; +using System.Net; +using System.Net.Http; +using System.Security.Claims; +using System.Security.Principal; +using System.Text; +using System.Threading.Tasks; +using System.Xml; +using System.Xml.Linq; +using Microsoft.AspNet.Builder; +using Microsoft.AspNet.Http; +using Microsoft.AspNet.Http.Security; +using Microsoft.AspNet.TestHost; +using Shouldly; +using Xunit; + +namespace Microsoft.AspNet.Security.Cookies +{ + public class CookieMiddlewareTests + { + [Fact] + public async Task NormalRequestPassesThrough() + { + TestServer server = CreateServer(new CookieAuthenticationOptions + { + }); + HttpResponseMessage response = await server.CreateClient().GetAsync("http://example.com/normal"); + response.StatusCode.ShouldBe(HttpStatusCode.OK); + } + + [Fact] + public async Task ProtectedRequestShouldRedirectToLogin() + { + TestServer server = CreateServer(new CookieAuthenticationOptions + { + LoginPath = new PathString("/login") + }); + + Transaction transaction = await SendAsync(server, "http://example.com/protected"); + + transaction.Response.StatusCode.ShouldBe(HttpStatusCode.Redirect); + + Uri location = transaction.Response.Headers.Location; + location.LocalPath.ShouldBe("/login"); + location.Query.ShouldBe("?ReturnUrl=%2Fprotected"); + } + + [Fact] + public async Task ProtectedCustomRequestShouldRedirectToCustomLogin() + { + TestServer server = CreateServer(new CookieAuthenticationOptions + { + LoginPath = new PathString("/login") + }); + + Transaction transaction = await SendAsync(server, "http://example.com/protected/CustomRedirect"); + + transaction.Response.StatusCode.ShouldBe(HttpStatusCode.Redirect); + + Uri location = transaction.Response.Headers.Location; + location.ToString().ShouldBe("/CustomRedirect"); + } + + private Task SignInAsAlice(HttpContext context) + { + context.Response.SignIn( + new AuthenticationProperties(), + new ClaimsIdentity(new GenericIdentity("Alice", "Cookies"))); + return Task.FromResult(null); + } + + [Fact] + public async Task SignInCausesDefaultCookieToBeCreated() + { + TestServer server = CreateServer(new CookieAuthenticationOptions + { + LoginPath = new PathString("/login"), + CookieName = "TestCookie", + }, SignInAsAlice); + + Transaction transaction = await SendAsync(server, "http://example.com/testpath"); + + string setCookie = transaction.SetCookie; + setCookie.ShouldStartWith("TestCookie="); + setCookie.ShouldContain("; path=/"); + setCookie.ShouldContain("; HttpOnly"); + setCookie.ShouldNotContain("; expires="); + setCookie.ShouldNotContain("; domain="); + setCookie.ShouldNotContain("; secure"); + } + + [Theory] + [InlineData(CookieSecureOption.Always, "http://example.com/testpath", true)] + [InlineData(CookieSecureOption.Always, "https://example.com/testpath", true)] + [InlineData(CookieSecureOption.Never, "http://example.com/testpath", false)] + [InlineData(CookieSecureOption.Never, "https://example.com/testpath", false)] + [InlineData(CookieSecureOption.SameAsRequest, "http://example.com/testpath", false)] + [InlineData(CookieSecureOption.SameAsRequest, "https://example.com/testpath", true)] + public async Task SecureSignInCausesSecureOnlyCookieByDefault( + CookieSecureOption cookieSecureOption, + string requestUri, + bool shouldBeSecureOnly) + { + TestServer server = CreateServer(new CookieAuthenticationOptions + { + LoginPath = new PathString("/login"), + CookieName = "TestCookie", + CookieSecure = cookieSecureOption + }, SignInAsAlice); + + Transaction transaction = await SendAsync(server, requestUri); + string setCookie = transaction.SetCookie; + + if (shouldBeSecureOnly) + { + setCookie.ShouldContain("; secure"); + } + else + { + setCookie.ShouldNotContain("; secure"); + } + } + + [Fact] + public async Task CookieOptionsAlterSetCookieHeader() + { + TestServer server1 = CreateServer(new CookieAuthenticationOptions + { + CookieName = "TestCookie", + CookiePath = "/foo", + CookieDomain = "another.com", + CookieSecure = CookieSecureOption.Always, + CookieHttpOnly = true, + }, SignInAsAlice); + + Transaction transaction1 = await SendAsync(server1, "http://example.com/testpath"); + + TestServer server2 = CreateServer(new CookieAuthenticationOptions + { + CookieName = "SecondCookie", + CookieSecure = CookieSecureOption.Never, + CookieHttpOnly = false, + }, SignInAsAlice); + + Transaction transaction2 = await SendAsync(server2, "http://example.com/testpath"); + + string setCookie1 = transaction1.SetCookie; + string setCookie2 = transaction2.SetCookie; + + setCookie1.ShouldContain("TestCookie="); + setCookie1.ShouldContain(" path=/foo"); + setCookie1.ShouldContain(" domain=another.com"); + setCookie1.ShouldContain(" secure"); + setCookie1.ShouldContain(" HttpOnly"); + + setCookie2.ShouldContain("SecondCookie="); + setCookie2.ShouldNotContain(" domain="); + setCookie2.ShouldNotContain(" secure"); + setCookie2.ShouldNotContain(" HttpOnly"); + } + + [Fact] + public async Task CookieContainsIdentity() + { + var clock = new TestClock(); + TestServer server = CreateServer(new CookieAuthenticationOptions + { + SystemClock = clock + }, SignInAsAlice); + + Transaction transaction1 = await SendAsync(server, "http://example.com/testpath"); + + Transaction transaction2 = await SendAsync(server, "http://example.com/me/Cookies", transaction1.CookieNameValue); + + FindClaimValue(transaction2, ClaimTypes.Name).ShouldBe("Alice"); + } + + [Fact] + public async Task CookieStopsWorkingAfterExpiration() + { + var clock = new TestClock(); + TestServer server = CreateServer(new CookieAuthenticationOptions + { + SystemClock = clock, + ExpireTimeSpan = TimeSpan.FromMinutes(10), + SlidingExpiration = false, + }, SignInAsAlice); + + Transaction transaction1 = await SendAsync(server, "http://example.com/testpath"); + + Transaction transaction2 = await SendAsync(server, "http://example.com/me/Cookies", transaction1.CookieNameValue); + + clock.Add(TimeSpan.FromMinutes(7)); + + Transaction transaction3 = await SendAsync(server, "http://example.com/me/Cookies", transaction1.CookieNameValue); + + clock.Add(TimeSpan.FromMinutes(7)); + + Transaction transaction4 = await SendAsync(server, "http://example.com/me/Cookies", transaction1.CookieNameValue); + + transaction2.SetCookie.ShouldBe(null); + FindClaimValue(transaction2, ClaimTypes.Name).ShouldBe("Alice"); + transaction3.SetCookie.ShouldBe(null); + FindClaimValue(transaction3, ClaimTypes.Name).ShouldBe("Alice"); + transaction4.SetCookie.ShouldBe(null); + FindClaimValue(transaction4, ClaimTypes.Name).ShouldBe(null); + } + + [Fact] + public async Task CookieExpirationCanBeOverridenInSignin() + { + var clock = new TestClock(); + TestServer server = CreateServer(new CookieAuthenticationOptions + { + SystemClock = clock, + ExpireTimeSpan = TimeSpan.FromMinutes(10), + SlidingExpiration = false, + }, + context => + { + context.Response.SignIn( + new AuthenticationProperties() { ExpiresUtc = clock.UtcNow.Add(TimeSpan.FromMinutes(5)) }, + new ClaimsIdentity(new GenericIdentity("Alice", "Cookies"))); + return Task.FromResult(null); + }); + + Transaction transaction1 = await SendAsync(server, "http://example.com/testpath"); + + Transaction transaction2 = await SendAsync(server, "http://example.com/me/Cookies", transaction1.CookieNameValue); + + clock.Add(TimeSpan.FromMinutes(3)); + + Transaction transaction3 = await SendAsync(server, "http://example.com/me/Cookies", transaction1.CookieNameValue); + + clock.Add(TimeSpan.FromMinutes(3)); + + Transaction transaction4 = await SendAsync(server, "http://example.com/me/Cookies", transaction1.CookieNameValue); + + transaction2.SetCookie.ShouldBe(null); + FindClaimValue(transaction2, ClaimTypes.Name).ShouldBe("Alice"); + transaction3.SetCookie.ShouldBe(null); + FindClaimValue(transaction3, ClaimTypes.Name).ShouldBe("Alice"); + transaction4.SetCookie.ShouldBe(null); + FindClaimValue(transaction4, ClaimTypes.Name).ShouldBe(null); + } + + [Fact] + public async Task CookieExpirationCanBeOverridenInEvent() + { + var clock = new TestClock(); + TestServer server = CreateServer(new CookieAuthenticationOptions + { + SystemClock = clock, + ExpireTimeSpan = TimeSpan.FromMinutes(10), + SlidingExpiration = false, + Notifications = new CookieAuthenticationNotifications() + { + OnResponseSignIn = context => + { + context.Properties.ExpiresUtc = clock.UtcNow.Add(TimeSpan.FromMinutes(5)); + } + } + }, SignInAsAlice); + + Transaction transaction1 = await SendAsync(server, "http://example.com/testpath"); + + Transaction transaction2 = await SendAsync(server, "http://example.com/me/Cookies", transaction1.CookieNameValue); + + clock.Add(TimeSpan.FromMinutes(3)); + + Transaction transaction3 = await SendAsync(server, "http://example.com/me/Cookies", transaction1.CookieNameValue); + + clock.Add(TimeSpan.FromMinutes(3)); + + Transaction transaction4 = await SendAsync(server, "http://example.com/me/Cookies", transaction1.CookieNameValue); + + transaction2.SetCookie.ShouldBe(null); + FindClaimValue(transaction2, ClaimTypes.Name).ShouldBe("Alice"); + transaction3.SetCookie.ShouldBe(null); + FindClaimValue(transaction3, ClaimTypes.Name).ShouldBe("Alice"); + transaction4.SetCookie.ShouldBe(null); + FindClaimValue(transaction4, ClaimTypes.Name).ShouldBe(null); + } + + [Fact] + public async Task CookieIsRenewedWithSlidingExpiration() + { + var clock = new TestClock(); + TestServer server = CreateServer(new CookieAuthenticationOptions + { + SystemClock = clock, + ExpireTimeSpan = TimeSpan.FromMinutes(10), + SlidingExpiration = true, + }, SignInAsAlice); + + Transaction transaction1 = await SendAsync(server, "http://example.com/testpath"); + + Transaction transaction2 = await SendAsync(server, "http://example.com/me/Cookies", transaction1.CookieNameValue); + + clock.Add(TimeSpan.FromMinutes(4)); + + Transaction transaction3 = await SendAsync(server, "http://example.com/me/Cookies", transaction1.CookieNameValue); + + clock.Add(TimeSpan.FromMinutes(4)); + + // transaction4 should arrive with a new SetCookie value + Transaction transaction4 = await SendAsync(server, "http://example.com/me/Cookies", transaction1.CookieNameValue); + + clock.Add(TimeSpan.FromMinutes(4)); + + Transaction transaction5 = await SendAsync(server, "http://example.com/me/Cookies", transaction4.CookieNameValue); + + transaction2.SetCookie.ShouldBe(null); + FindClaimValue(transaction2, ClaimTypes.Name).ShouldBe("Alice"); + transaction3.SetCookie.ShouldBe(null); + FindClaimValue(transaction3, ClaimTypes.Name).ShouldBe("Alice"); + transaction4.SetCookie.ShouldNotBe(null); + FindClaimValue(transaction4, ClaimTypes.Name).ShouldBe("Alice"); + transaction5.SetCookie.ShouldBe(null); + FindClaimValue(transaction5, ClaimTypes.Name).ShouldBe("Alice"); + } + + [Fact] + public async Task AjaxRedirectsAsExtraHeaderOnTwoHundred() + { + TestServer server = CreateServer(new CookieAuthenticationOptions + { + LoginPath = new PathString("/login") + }); + + Transaction transaction = await SendAsync(server, "http://example.com/protected", ajaxRequest: true); + + transaction.Response.StatusCode.ShouldBe(HttpStatusCode.OK); + var responded = transaction.Response.Headers.GetValues("X-Responded-JSON"); + + responded.Count().ShouldBe(1); + responded.Single().ShouldContain("\"location\""); + } + + private static string FindClaimValue(Transaction transaction, string claimType) + { + XElement claim = transaction.ResponseElement.Elements("claim").SingleOrDefault(elt => elt.Attribute("type").Value == claimType); + if (claim == null) + { + return null; + } + return claim.Attribute("value").Value; + } + + private static async Task GetAuthData(TestServer server, string url, string cookie) + { + var request = new HttpRequestMessage(HttpMethod.Get, url); + request.Headers.Add("Cookie", cookie); + + HttpResponseMessage response2 = await server.CreateClient().SendAsync(request); + string text = await response2.Content.ReadAsStringAsync(); + XElement me = XElement.Parse(text); + return me; + } + + private static TestServer CreateServer(CookieAuthenticationOptions options, Func testpath = null) + { + return TestServer.Create(app => + { + app.UseCookieAuthentication(options); + app.Use(async (context, next) => + { + var req = context.Request; + var res = context.Response; + PathString remainder; + if (req.Path == new PathString("/normal")) + { + res.StatusCode = 200; + } + else if (req.Path == new PathString("/protected")) + { + res.StatusCode = 401; + } + else if (req.Path == new PathString("/protected/CustomRedirect")) + { + context.Response.Challenge(new AuthenticationProperties() { RedirectUri = "/CustomRedirect" }); + } + else if (req.Path == new PathString("/me")) + { + Describe(res, new AuthenticationResult(context.User.Identity, new AuthenticationProperties(), new AuthenticationDescription())); + } + else if (req.Path.StartsWithSegments(new PathString("/me"), out remainder)) + { + var result = await context.AuthenticateAsync(remainder.Value.Substring(1)); + Describe(res, result); + } + else if (req.Path == new PathString("/testpath") && testpath != null) + { + await testpath(context); + } + else + { + await next(); + } + }); + }); + } + + private static void Describe(HttpResponse res, AuthenticationResult result) + { + res.StatusCode = 200; + res.ContentType = "text/xml"; + var xml = new XElement("xml"); + if (result != null && result.Identity != null) + { + xml.Add(result.Identity.Claims.Select(claim => new XElement("claim", new XAttribute("type", claim.Type), new XAttribute("value", claim.Value)))); + } + if (result != null && result.Properties != null) + { + xml.Add(result.Properties.Dictionary.Select(extra => new XElement("extra", new XAttribute("type", extra.Key), new XAttribute("value", extra.Value)))); + } + using (var memory = new MemoryStream()) + { + using (var writer = new XmlTextWriter(memory, Encoding.UTF8)) + { + xml.WriteTo(writer); + } + res.Body.Write(memory.ToArray(), 0, memory.ToArray().Length); + } + } + + private static async Task SendAsync(TestServer server, string uri, string cookieHeader = null, bool ajaxRequest = false) + { + var request = new HttpRequestMessage(HttpMethod.Get, uri); + if (!string.IsNullOrEmpty(cookieHeader)) + { + request.Headers.Add("Cookie", cookieHeader); + } + if (ajaxRequest) + { + request.Headers.Add("X-Requested-With", "XMLHttpRequest"); + } + var transaction = new Transaction + { + Request = request, + Response = await server.CreateClient().SendAsync(request), + }; + if (transaction.Response.Headers.Contains("Set-Cookie")) + { + transaction.SetCookie = transaction.Response.Headers.GetValues("Set-Cookie").SingleOrDefault(); + } + if (!string.IsNullOrEmpty(transaction.SetCookie)) + { + transaction.CookieNameValue = transaction.SetCookie.Split(new[] { ';' }, 2).First(); + } + transaction.ResponseText = await transaction.Response.Content.ReadAsStringAsync(); + + if (transaction.Response.Content != null && + transaction.Response.Content.Headers.ContentType != null && + transaction.Response.Content.Headers.ContentType.MediaType == "text/xml") + { + transaction.ResponseElement = XElement.Parse(transaction.ResponseText); + } + return transaction; + } + + private class Transaction + { + public HttpRequestMessage Request { get; set; } + public HttpResponseMessage Response { get; set; } + + public string SetCookie { get; set; } + public string CookieNameValue { get; set; } + + public string ResponseText { get; set; } + public XElement ResponseElement { get; set; } + } + } +} diff --git a/test/Microsoft.AspNet.Security.Test/DataHandler/Encoder/Base64UrlTextEncoderTests.cs b/test/Microsoft.AspNet.Security.Test/DataHandler/Encoder/Base64UrlTextEncoderTests.cs new file mode 100644 index 000000000..be97f2f12 --- /dev/null +++ b/test/Microsoft.AspNet.Security.Test/DataHandler/Encoder/Base64UrlTextEncoderTests.cs @@ -0,0 +1,32 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using Shouldly; +using Xunit; + +namespace Microsoft.AspNet.Security.DataHandler.Encoder +{ + public class Base64UrlTextEncoderTests + { + [Fact] + public void DataOfVariousLengthRoundTripCorrectly() + { + var encoder = new Base64UrlTextEncoder(); + for (int length = 0; length != 256; ++length) + { + var data = new byte[length]; + for (int index = 0; index != length; ++index) + { + data[index] = (byte)(5 + length + (index * 23)); + } + string text = encoder.Encode(data); + byte[] result = encoder.Decode(text); + + for (int index = 0; index != length; ++index) + { + result[index].ShouldBe(data[index]); + } + } + } + } +} diff --git a/test/Microsoft.AspNet.Security.Test/Microsoft.AspNet.Security.kproj b/test/Microsoft.AspNet.Security.Test/Microsoft.AspNet.Security.Tests.kproj similarity index 70% rename from test/Microsoft.AspNet.Security.Test/Microsoft.AspNet.Security.kproj rename to test/Microsoft.AspNet.Security.Test/Microsoft.AspNet.Security.Tests.kproj index 62a9b7453..903c63d85 100644 --- a/test/Microsoft.AspNet.Security.Test/Microsoft.AspNet.Security.kproj +++ b/test/Microsoft.AspNet.Security.Test/Microsoft.AspNet.Security.Tests.kproj @@ -17,11 +17,20 @@ 2.0 + + + + + + + + + - + \ No newline at end of file diff --git a/test/Microsoft.AspNet.Security.Test/SecurityHelperTests.cs b/test/Microsoft.AspNet.Security.Test/SecurityHelperTests.cs new file mode 100644 index 000000000..76f8f6e0a --- /dev/null +++ b/test/Microsoft.AspNet.Security.Test/SecurityHelperTests.cs @@ -0,0 +1,103 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System.Collections.Generic; +using System.Linq; +using System.Security.Claims; +using System.Security.Principal; +using Microsoft.AspNet.Http; +using Microsoft.AspNet.PipelineCore; +using Microsoft.AspNet.Security.Infrastructure; +using Shouldly; +using Xunit; + +namespace Microsoft.AspNet.Security +{ + public class SecurityHelperTests + { + [Fact] + public void AddingToAnonymousIdentityDoesNotKeepAnonymousIdentity() + { + HttpContext context = new DefaultHttpContext(); + context.User.ShouldNotBe(null); + context.User.Identity.IsAuthenticated.ShouldBe(false); + + SecurityHelper.AddUserIdentity(context, new GenericIdentity("Test1", "Alpha")); + + context.User.ShouldNotBe(null); + context.User.Identity.AuthenticationType.ShouldBe("Alpha"); + context.User.Identity.Name.ShouldBe("Test1"); + + context.User.ShouldBeTypeOf(); + context.User.Identity.ShouldBeTypeOf(); + + ((ClaimsPrincipal)context.User).Identities.Count().ShouldBe(1); + } + + [Fact] + public void AddingExistingIdentityChangesDefaultButPreservesPrior() + { + HttpContext context = new DefaultHttpContext(); + context.User = new GenericPrincipal(new GenericIdentity("Test1", "Alpha"), null); + + context.User.Identity.AuthenticationType.ShouldBe("Alpha"); + context.User.Identity.Name.ShouldBe("Test1"); + + SecurityHelper.AddUserIdentity(context, new GenericIdentity("Test2", "Beta")); + + context.User.Identity.AuthenticationType.ShouldBe("Beta"); + context.User.Identity.Name.ShouldBe("Test2"); + + SecurityHelper.AddUserIdentity(context, new GenericIdentity("Test3", "Gamma")); + + context.User.Identity.AuthenticationType.ShouldBe("Gamma"); + context.User.Identity.Name.ShouldBe("Test3"); + + var principal = context.User; + principal.Identities.Count().ShouldBe(3); + principal.Identities.Skip(0).First().Name.ShouldBe("Test3"); + principal.Identities.Skip(1).First().Name.ShouldBe("Test2"); + principal.Identities.Skip(2).First().Name.ShouldBe("Test1"); + } + + [Fact] + public void NoChallengesMeansLookupsAreDeterminedOnlyByActiveOrPassiveMode() + { + HttpContext context = new DefaultHttpContext(); + + bool activeNoChallenge = SecurityHelper.LookupChallenge(new string[0], "Alpha", AuthenticationMode.Active); + bool passiveNoChallenge = SecurityHelper.LookupChallenge(new string[0], "Alpha", AuthenticationMode.Passive); + + context.Response.StatusCode = 401; + + bool activeEmptyChallenge = SecurityHelper.LookupChallenge(new string[0], "Alpha", AuthenticationMode.Active); + bool passiveEmptyChallenge = SecurityHelper.LookupChallenge(new string[0], "Alpha", AuthenticationMode.Passive); + + Assert.True(activeNoChallenge); + Assert.False(passiveNoChallenge); + Assert.True(activeEmptyChallenge); + Assert.False(passiveEmptyChallenge); + } + + [Fact] + public void WithChallengesMeansLookupsAreDeterminedOnlyByMatchingAuthenticationType() + { + HttpContext context = new DefaultHttpContext(); + + IEnumerable challengeTypes = new[] { "Beta", "Gamma" }; + + bool activeNoMatch = SecurityHelper.LookupChallenge(challengeTypes, "Alpha", AuthenticationMode.Active); + bool passiveNoMatch = SecurityHelper.LookupChallenge(challengeTypes, "Alpha", AuthenticationMode.Passive); + + challengeTypes = new[] { "Beta", "Alpha" }; + + bool activeWithMatch = SecurityHelper.LookupChallenge(challengeTypes, "Alpha", AuthenticationMode.Active); + bool passiveWithMatch = SecurityHelper.LookupChallenge(challengeTypes, "Alpha", AuthenticationMode.Passive); + + Assert.False(activeNoMatch); + Assert.False(passiveNoMatch); + Assert.True(activeWithMatch); + Assert.True(passiveWithMatch); + } + } +} diff --git a/test/Microsoft.AspNet.Security.Test/TestClock.cs b/test/Microsoft.AspNet.Security.Test/TestClock.cs new file mode 100644 index 000000000..cd8f99839 --- /dev/null +++ b/test/Microsoft.AspNet.Security.Test/TestClock.cs @@ -0,0 +1,23 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using Microsoft.AspNet.Security.Infrastructure; + +namespace Microsoft.AspNet.Security +{ + public class TestClock : ISystemClock + { + public TestClock() + { + UtcNow = new DateTimeOffset(2013, 6, 11, 12, 34, 56, 789, TimeSpan.Zero); + } + + public DateTimeOffset UtcNow { get; set; } + + public void Add(TimeSpan timeSpan) + { + UtcNow = UtcNow + timeSpan; + } + } +} diff --git a/test/Microsoft.AspNet.Security.Test/katanatest.redmond.corp.microsoft.com.cer b/test/Microsoft.AspNet.Security.Test/katanatest.redmond.corp.microsoft.com.cer new file mode 100644 index 0000000000000000000000000000000000000000..bfd5220e2cf5a9f6d78145f62d2031a44ef50e59 GIT binary patch literal 1462 zcmXqLV%=oW#4>9EGZP~d6IaOeUIzw728M=S170>xtu~Lg@4SqRtgH+MjSYsv27+u{ zoRic#Cx6mOVU!eOPR`FYlr#`W5#-FxOfJeV&QB{b6fqD&kzz^CFDft;HxNY;WiLui z$<5D8F_bruWn&IyVHOti4fYIC@J&q4$jnPsa4ap!P;hosFfx!6=QT7oFf%eUv@|p~ zHj4ssO_8_;28MbDIuIjNvlB}a^Abx^i%ayN=IeoM*Mqwb$jvoqVpKx*CnGBZa}y&! z15licsfm%1;iL7N%^!0Xs~;%IKiIkMIp=T7M)sAbvfm5&d=}rTo8T~e-4vB`Z<@Tn z6m~?%cKum?@SLe?cETkEm1i*G#e7wJ^UKTx=NA{5m>C%u7dJ6g8#FPMgQG{5k420{``jI+p=AFz99ZSy-5vST-2QgE-185(Z)oBCl@?#{J-&cjH>poWDtPAGdgE zJXAMmdyi5M`oc|r{?FE7XKZDPD!V&H;gEV_FWGZTplxDo?r`#y!`~&1{>_KpwsQ2XywsY^#F)aw$OTC* zsw`p#A~5$bGr?Jm2I>g&xmctOBn-IVl1xZ!M&t|%EQo*^l#wC&=)e2#45dUlzKJv5 z`Rj3z&983bHLa%~FD?D`EY4xsTQ{$lvFl9Nx}NawQM%N_d4GZD^$zDH%lCXdVcdQv zDa^cgx{JY*=A+_En>a2Ce`)KfLw&_ciFG);W)r z(-!=F7v-`+iPTd%8 Dk#GvE literal 0 HcmV?d00001 diff --git a/test/Microsoft.AspNet.Security.Test/project.json b/test/Microsoft.AspNet.Security.Test/project.json index 68837d5be..b46b261de 100644 --- a/test/Microsoft.AspNet.Security.Test/project.json +++ b/test/Microsoft.AspNet.Security.Test/project.json @@ -4,6 +4,9 @@ }, "dependencies": { "Microsoft.AspNet.Security" : "", + "Microsoft.AspNet.Security.Cookies" : "", + "Microsoft.AspNet.TestHost": "1.0.0-*", + "System.Net.Http": "4.0.0.0", "Moq": "4.2.1312.1622", "Xunit.KRunner": "1.0.0-*" }, @@ -13,7 +16,10 @@ "frameworks": { "net45": { "dependencies": { - "System.Runtime": "" + "Shouldly": "1.1.1.1", + "System.Runtime": "", + "System.Xml": "", + "System.Xml.Linq": "" } } } diff --git a/test/Microsoft.AspNet.Security.Test/selfSigned.cer b/test/Microsoft.AspNet.Security.Test/selfSigned.cer new file mode 100644 index 0000000000000000000000000000000000000000..6acc7af5a606916b16c00aef0177b1e4858d7290 GIT binary patch literal 762 zcmXqLV)|y##Q10dGZP~dlR(?zA3ry9D6e$iICaDG9g9C1aI&##^D#5YvN9Nm8VVZ- zvN4CUFbi{eCzd4UC5EIHml(*2^BNi(7y_ZW0T4uq^BN&@acOH}R5IXYh&j54_7gG}>Bg5p{Ygf8TXGs{Hj>&cCUVOqs?tZJ;an`>l62y1kxZk6~ zuFIUiZ%3bNU>xhe=(iubQr+ix=sr_x=xJE8NI2KLQqo;fd(Gz=2b$I#RQrBm>AH-i zkKf$$tG(O&CFSU}8}lEB&lieWTW|EsKf7PUZrb(3?pt$Kb!0z}5Q&rz6-jM78g4V| zOK9EiW0L}SKCE8V|6ZL*&v??tg-6}5K9j#b@qni1DwnHlCKc7!6%DNGq>`U}x_Bt* z&8)Xu?r^5BnZzWM9eH~B>Cf(NE)%mvtAm{1mu~zL*wWUgc+@eEXB)@~?%T%FSzNdgJwziJ6gsaj}N};q$PvEvyx^x#(Bl{N+D2**46g^?wC$QZC9<=OZR2BCf#b{zy(PLnRJ+Rx zZ+pk)db%T3^V#*QS2}P! z;rBeTSMJYZ-nthS6M6nGRag%UASt!}7{?02=i_8vp Date: Fri, 15 Aug 2014 09:27:27 -0700 Subject: [PATCH 030/216] Removed source files from the project --- samples/CookieSample/CookieSample.kproj | 8 +-- .../Microsoft.AspNet.Security.Cookies.kproj | 21 +----- .../Microsoft.AspNet.Security.kproj | 64 +------------------ .../Microsoft.AspNet.Security.Tests.kproj | 16 ----- 4 files changed, 3 insertions(+), 106 deletions(-) diff --git a/samples/CookieSample/CookieSample.kproj b/samples/CookieSample/CookieSample.kproj index efb2d4d77..3f9173352 100644 --- a/samples/CookieSample/CookieSample.kproj +++ b/samples/CookieSample/CookieSample.kproj @@ -16,11 +16,5 @@ 2.0 - - - - - - - + \ No newline at end of file diff --git a/src/Microsoft.AspNet.Security.Cookies/Microsoft.AspNet.Security.Cookies.kproj b/src/Microsoft.AspNet.Security.Cookies/Microsoft.AspNet.Security.Cookies.kproj index 1b82715c3..75aae6178 100644 --- a/src/Microsoft.AspNet.Security.Cookies/Microsoft.AspNet.Security.Cookies.kproj +++ b/src/Microsoft.AspNet.Security.Cookies/Microsoft.AspNet.Security.Cookies.kproj @@ -16,24 +16,5 @@ 2.0 - - - - - - - - - - - - - - - - - - - - + \ No newline at end of file diff --git a/src/Microsoft.AspNet.Security/Microsoft.AspNet.Security.kproj b/src/Microsoft.AspNet.Security/Microsoft.AspNet.Security.kproj index c774d797e..923789fb1 100644 --- a/src/Microsoft.AspNet.Security/Microsoft.AspNet.Security.kproj +++ b/src/Microsoft.AspNet.Security/Microsoft.AspNet.Security.kproj @@ -16,67 +16,5 @@ 2.0 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + \ No newline at end of file diff --git a/test/Microsoft.AspNet.Security.Test/Microsoft.AspNet.Security.Tests.kproj b/test/Microsoft.AspNet.Security.Test/Microsoft.AspNet.Security.Tests.kproj index 903c63d85..54191c08d 100644 --- a/test/Microsoft.AspNet.Security.Test/Microsoft.AspNet.Security.Tests.kproj +++ b/test/Microsoft.AspNet.Security.Test/Microsoft.AspNet.Security.Tests.kproj @@ -16,21 +16,5 @@ 2.0 - - - - - - - - - - - - - - - - \ No newline at end of file From fabdb3b9dfcd0b678e9c04fa718af03d2d3530e8 Mon Sep 17 00:00:00 2001 From: Pranav K Date: Wed, 20 Aug 2014 06:56:36 -0700 Subject: [PATCH 031/216] Reacting to System.IO package version change --- samples/CookieSample/project.json | 2 +- src/Microsoft.AspNet.Security.Cookies/project.json | 2 +- src/Microsoft.AspNet.Security/project.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/samples/CookieSample/project.json b/samples/CookieSample/project.json index e51b35e48..85f8a1e33 100644 --- a/samples/CookieSample/project.json +++ b/samples/CookieSample/project.json @@ -22,7 +22,7 @@ "System.Diagnostics.Debug": "4.0.10.0", "System.Diagnostics.Tools": "4.0.0.0", "System.Globalization": "4.0.10.0", - "System.IO": "4.0.0.0", + "System.IO": "4.0.10.0", "System.Linq": "4.0.0.0", "System.Reflection": "4.0.10.0", "System.Resources.ResourceManager": "4.0.0.0", diff --git a/src/Microsoft.AspNet.Security.Cookies/project.json b/src/Microsoft.AspNet.Security.Cookies/project.json index 01a7751fb..59c8b666f 100644 --- a/src/Microsoft.AspNet.Security.Cookies/project.json +++ b/src/Microsoft.AspNet.Security.Cookies/project.json @@ -22,7 +22,7 @@ "System.Diagnostics.Debug": "4.0.10.0", "System.Diagnostics.Tools": "4.0.0.0", "System.Globalization": "4.0.10.0", - "System.IO": "4.0.0.0", + "System.IO": "4.0.10.0", "System.IO.Compression": "4.0.0.0", "System.Linq": "4.0.0.0", "System.Reflection": "4.0.10.0", diff --git a/src/Microsoft.AspNet.Security/project.json b/src/Microsoft.AspNet.Security/project.json index 4eae846bf..e79296344 100644 --- a/src/Microsoft.AspNet.Security/project.json +++ b/src/Microsoft.AspNet.Security/project.json @@ -19,7 +19,7 @@ "System.Diagnostics.Debug": "4.0.10.0", "System.Diagnostics.Tools": "4.0.0.0", "System.Globalization": "4.0.10.0", - "System.IO": "4.0.0.0", + "System.IO": "4.0.10.0", "System.IO.Compression": "4.0.0.0", "System.Linq": "4.0.0.0", "System.Reflection": "4.0.10.0", From 919fa0c195d3990953bc70b04db9300a11bc4c1c Mon Sep 17 00:00:00 2001 From: Chris Ross Date: Thu, 7 Aug 2014 17:19:59 -0700 Subject: [PATCH 032/216] Port Facebook middleware from Katana. --- Security.sln | 27 +- samples/SocialSample/Project.json | 33 ++ samples/SocialSample/SocialSample.kproj | 32 ++ samples/SocialSample/Startup.cs | 39 +++ .../CookieAuthenticationExtensions.cs | 5 - .../project.json | 2 +- .../FacebookAuthenticationDefaults.cs | 10 + .../FacebookAuthenticationExtensions.cs | 44 +++ .../FacebookAuthenticationHandler.cs | 293 ++++++++++++++++++ .../FacebookAuthenticationMiddleware.cs | 97 ++++++ .../FacebookAuthenticationOptions.cs | 112 +++++++ .../Microsoft.AspNet.Security.Facebook.kproj | 20 ++ .../NotNullAttribute.cs | 12 + .../FacebookApplyRedirectContext.cs | 43 +++ .../FacebookAuthenticatedContext.cs | 98 ++++++ .../FacebookAuthenticationNotifications.cs | 69 +++++ .../FacebookReturnEndpointContext.cs | 26 ++ .../IFacebookAuthenticationNotifications.cs | 33 ++ .../Project.json | 44 +++ .../Resources.Designer.cs | 81 +++++ .../Resources.resx | 126 ++++++++ ...nsions.cs => BuilderSecurityExtensions.cs} | 14 +- src/Microsoft.AspNet.Security/Constants.cs | 2 +- .../DataHandler/PropertiesDataFormat.cs | 1 - .../Facebook/FacebookMiddlewareTests.cs | 124 ++++++++ .../project.json | 3 + 26 files changed, 1373 insertions(+), 17 deletions(-) create mode 100644 samples/SocialSample/Project.json create mode 100644 samples/SocialSample/SocialSample.kproj create mode 100644 samples/SocialSample/Startup.cs create mode 100644 src/Microsoft.AspNet.Security.Facebook/FacebookAuthenticationDefaults.cs create mode 100644 src/Microsoft.AspNet.Security.Facebook/FacebookAuthenticationExtensions.cs create mode 100644 src/Microsoft.AspNet.Security.Facebook/FacebookAuthenticationHandler.cs create mode 100644 src/Microsoft.AspNet.Security.Facebook/FacebookAuthenticationMiddleware.cs create mode 100644 src/Microsoft.AspNet.Security.Facebook/FacebookAuthenticationOptions.cs create mode 100644 src/Microsoft.AspNet.Security.Facebook/Microsoft.AspNet.Security.Facebook.kproj create mode 100644 src/Microsoft.AspNet.Security.Facebook/NotNullAttribute.cs create mode 100644 src/Microsoft.AspNet.Security.Facebook/Notifications/FacebookApplyRedirectContext.cs create mode 100644 src/Microsoft.AspNet.Security.Facebook/Notifications/FacebookAuthenticatedContext.cs create mode 100644 src/Microsoft.AspNet.Security.Facebook/Notifications/FacebookAuthenticationNotifications.cs create mode 100644 src/Microsoft.AspNet.Security.Facebook/Notifications/FacebookReturnEndpointContext.cs create mode 100644 src/Microsoft.AspNet.Security.Facebook/Notifications/IFacebookAuthenticationNotifications.cs create mode 100644 src/Microsoft.AspNet.Security.Facebook/Project.json create mode 100644 src/Microsoft.AspNet.Security.Facebook/Resources.Designer.cs create mode 100644 src/Microsoft.AspNet.Security.Facebook/Resources.resx rename src/Microsoft.AspNet.Security/{AppBuilderSecurityExtensions.cs => BuilderSecurityExtensions.cs} (89%) create mode 100644 test/Microsoft.AspNet.Security.Test/Facebook/FacebookMiddlewareTests.cs diff --git a/Security.sln b/Security.sln index 268ecf4a6..0d249fe56 100644 --- a/Security.sln +++ b/Security.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 14 -VisualStudioVersion = 14.0.21916.0 +VisualStudioVersion = 14.0.22013.1 MinimumVisualStudioVersion = 10.0.40219.1 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{4D2B6A51-2F9F-44F5-8131-EA5CAC053652}" EndProject @@ -22,6 +22,9 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution global.json = global.json EndProjectSection EndProject +Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNet.Security.Facebook", "src\Microsoft.AspNet.Security.Facebook\Microsoft.AspNet.Security.Facebook.kproj", "{3984651C-FD44-4394-8793-3D14EE348C04}" +EndProject +Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "SocialSample", "samples\SocialSample\SocialSample.kproj", "{8C73D216-332D-41D8-BFD0-45BC4BC36552}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -73,6 +76,26 @@ Global {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|x86.ActiveCfg = Release|Any CPU + {3984651C-FD44-4394-8793-3D14EE348C04}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {3984651C-FD44-4394-8793-3D14EE348C04}.Debug|Any CPU.Build.0 = Debug|Any CPU + {3984651C-FD44-4394-8793-3D14EE348C04}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {3984651C-FD44-4394-8793-3D14EE348C04}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {3984651C-FD44-4394-8793-3D14EE348C04}.Debug|x86.ActiveCfg = Debug|Any CPU + {3984651C-FD44-4394-8793-3D14EE348C04}.Release|Any CPU.ActiveCfg = Release|Any CPU + {3984651C-FD44-4394-8793-3D14EE348C04}.Release|Any CPU.Build.0 = Release|Any CPU + {3984651C-FD44-4394-8793-3D14EE348C04}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {3984651C-FD44-4394-8793-3D14EE348C04}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {3984651C-FD44-4394-8793-3D14EE348C04}.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|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|x86.ActiveCfg = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -82,5 +105,7 @@ Global {15F1211B-B695-4A1C-B730-1AC58FC91090} = {4D2B6A51-2F9F-44F5-8131-EA5CAC053652} {558C2C2A-AED8-49DE-BB60-D5F8AE06C714} = {F8C0AA27-F3FB-4286-8E4C-47EF86B539FF} {8DA26CD1-1302-4CFD-9270-9FA1B7C6138B} = {7BF11F3A-60B6-4796-B504-579C67FFBA34} + {3984651C-FD44-4394-8793-3D14EE348C04} = {4D2B6A51-2F9F-44F5-8131-EA5CAC053652} + {8C73D216-332D-41D8-BFD0-45BC4BC36552} = {F8C0AA27-F3FB-4286-8E4C-47EF86B539FF} EndGlobalSection EndGlobal diff --git a/samples/SocialSample/Project.json b/samples/SocialSample/Project.json new file mode 100644 index 000000000..f5434cb1c --- /dev/null +++ b/samples/SocialSample/Project.json @@ -0,0 +1,33 @@ +{ + "dependencies": { + "Microsoft.AspNet.Hosting": "1.0.0-*", + "Microsoft.AspNet.Http": "1.0.0-*", + "Microsoft.AspNet.Diagnostics": "1.0.0-*", + "Microsoft.AspNet.Security": "1.0.0-*", + "Microsoft.AspNet.Security.Cookies": "1.0.0-*", + "Microsoft.AspNet.Security.Facebook": "1.0.0-*", + "Microsoft.AspNet.Server.WebListener": "1.0.0-*", + "Microsoft.Framework.DependencyInjection": "1.0.0-*" + }, + "commands": { "web": "Microsoft.AspNet.Hosting server=Microsoft.AspNet.Server.WebListener server.urls=http://localhost:12345" }, + "frameworks": { + "net45": { + }, + "k10": { + "dependencies": { + "System.Collections": "4.0.10.0", + "System.Console": "4.0.0.0", + "System.Diagnostics.Debug": "4.0.10.0", + "System.Diagnostics.Tools": "4.0.0.0", + "System.Globalization": "4.0.10.0", + "System.IO": "4.0.0.0", + "System.Linq": "4.0.0.0", + "System.Resources.ResourceManager": "4.0.0.0", + "System.Runtime": "4.0.20.0", + "System.Runtime.Extensions": "4.0.10.0", + "System.Runtime.InteropServices": "4.0.20.0", + "System.Threading.Tasks": "4.0.10.0" + } + } + } +} diff --git a/samples/SocialSample/SocialSample.kproj b/samples/SocialSample/SocialSample.kproj new file mode 100644 index 000000000..c4ab469bf --- /dev/null +++ b/samples/SocialSample/SocialSample.kproj @@ -0,0 +1,32 @@ + + + + 12.0 + $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) + + + + 8c73d216-332d-41d8-bfd0-45bc4bc36552 + Library + + + ConsoleDebugger + + + WebDebugger + + + + + + + 2.0 + + + + + + + + + \ No newline at end of file diff --git a/samples/SocialSample/Startup.cs b/samples/SocialSample/Startup.cs new file mode 100644 index 000000000..aec06926e --- /dev/null +++ b/samples/SocialSample/Startup.cs @@ -0,0 +1,39 @@ +using Microsoft.AspNet.Builder; +using Microsoft.AspNet.Http; +using Microsoft.AspNet.Security.Cookies; +using Microsoft.AspNet.Security.Facebook; + +namespace CookieSample +{ + public class Startup + { + public void Configure(IBuilder app) + { + app.UseErrorPage(); + + app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType); + + app.UseCookieAuthentication(new CookieAuthenticationOptions() + { + }); + + app.UseFacebookAuthentication(new FacebookAuthenticationOptions() + { + AppId = "569522623154478", + AppSecret = "a124463c4719c94b4228d9a240e5dc1a", + }); + + app.Run(async context => + { + if (!context.User.Identity.IsAuthenticated) + { + context.Response.Challenge("Facebook"); + return; + } + + context.Response.ContentType = "text/plain"; + await context.Response.WriteAsync("Hello " + context.User.Identity.Name); + }); + } + } +} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Security.Cookies/CookieAuthenticationExtensions.cs b/src/Microsoft.AspNet.Security.Cookies/CookieAuthenticationExtensions.cs index ad683ac21..eb4f64903 100644 --- a/src/Microsoft.AspNet.Security.Cookies/CookieAuthenticationExtensions.cs +++ b/src/Microsoft.AspNet.Security.Cookies/CookieAuthenticationExtensions.cs @@ -1,12 +1,7 @@ // Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using Microsoft.AspNet.Http; using Microsoft.AspNet.Security.Cookies; -using Microsoft.AspNet.Security.DataProtection; -using Microsoft.Framework.DependencyInjection; -using Microsoft.Framework.Logging; namespace Microsoft.AspNet.Builder { diff --git a/src/Microsoft.AspNet.Security.Cookies/project.json b/src/Microsoft.AspNet.Security.Cookies/project.json index 59c8b666f..0336d73e9 100644 --- a/src/Microsoft.AspNet.Security.Cookies/project.json +++ b/src/Microsoft.AspNet.Security.Cookies/project.json @@ -6,7 +6,7 @@ "Microsoft.AspNet.HttpFeature": "1.0.0-*", "Microsoft.AspNet.PipelineCore": "1.0.0-*", "Microsoft.AspNet.RequestContainer": "1.0.0-*", - "Microsoft.AspNet.Security": "", + "Microsoft.AspNet.Security": "1.0.0-*", "Microsoft.AspNet.Security.DataProtection": "1.0.0-*", "Microsoft.Framework.DependencyInjection": "1.0.0-*", "Microsoft.Framework.Logging": "1.0.0-*", diff --git a/src/Microsoft.AspNet.Security.Facebook/FacebookAuthenticationDefaults.cs b/src/Microsoft.AspNet.Security.Facebook/FacebookAuthenticationDefaults.cs new file mode 100644 index 000000000..a9d35151c --- /dev/null +++ b/src/Microsoft.AspNet.Security.Facebook/FacebookAuthenticationDefaults.cs @@ -0,0 +1,10 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +namespace Microsoft.AspNet.Security.Facebook +{ + public static class FacebookAuthenticationDefaults + { + public const string AuthenticationType = "Facebook"; + } +} diff --git a/src/Microsoft.AspNet.Security.Facebook/FacebookAuthenticationExtensions.cs b/src/Microsoft.AspNet.Security.Facebook/FacebookAuthenticationExtensions.cs new file mode 100644 index 000000000..cdaade120 --- /dev/null +++ b/src/Microsoft.AspNet.Security.Facebook/FacebookAuthenticationExtensions.cs @@ -0,0 +1,44 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using Microsoft.AspNet.Security.Facebook; + +namespace Microsoft.AspNet.Builder +{ + /// + /// Extension methods for using + /// + public static class FacebookAuthenticationExtensions + { + /// + /// Authenticate users using Facebook + /// + /// The passed to the configure method + /// The appId assigned by Facebook + /// The appSecret assigned by Facebook + /// The updated + public static IBuilder UseFacebookAuthentication([NotNull] this IBuilder app, [NotNull] string appId, [NotNull] string appSecret) + { + return app.UseFacebookAuthentication(new FacebookAuthenticationOptions() + { + AppId = appId, + AppSecret = appSecret, + }); + } + + /// + /// Authenticate users using Facebook + /// + /// The passed to the configure method + /// Middleware configuration options + /// The updated + public static IBuilder UseFacebookAuthentication([NotNull] this IBuilder app, [NotNull] FacebookAuthenticationOptions options) + { + if (string.IsNullOrEmpty(options.SignInAsAuthenticationType)) + { + options.SignInAsAuthenticationType = app.GetDefaultSignInAsAuthenticationType(); + } + return app.UseMiddleware(options); + } + } +} diff --git a/src/Microsoft.AspNet.Security.Facebook/FacebookAuthenticationHandler.cs b/src/Microsoft.AspNet.Security.Facebook/FacebookAuthenticationHandler.cs new file mode 100644 index 000000000..4dde8b75d --- /dev/null +++ b/src/Microsoft.AspNet.Security.Facebook/FacebookAuthenticationHandler.cs @@ -0,0 +1,293 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Net.Http; +using System.Security.Claims; +using System.Security.Cryptography; +using System.Text; +using System.Threading.Tasks; +using Microsoft.AspNet.Http; +using Microsoft.AspNet.Http.Security; +using Microsoft.AspNet.Security.Infrastructure; +using Microsoft.AspNet.WebUtilities; +using Microsoft.Framework.Logging; +using Newtonsoft.Json.Linq; + +namespace Microsoft.AspNet.Security.Facebook +{ + internal class FacebookAuthenticationHandler : AuthenticationHandler + { + private const string XmlSchemaString = "http://www.w3.org/2001/XMLSchema#string"; + private const string TokenEndpoint = "https://graph.facebook.com/oauth/access_token"; + private const string GraphApiEndpoint = "https://graph.facebook.com/me"; + private const string AuthorizationEndpoint = "https://www.facebook.com/dialog/oauth"; + + private readonly ILogger _logger; + private readonly HttpClient _httpClient; + + public FacebookAuthenticationHandler(HttpClient httpClient, ILogger logger) + { + _httpClient = httpClient; + _logger = logger; + } + + protected override AuthenticationTicket AuthenticateCore() + { + return AuthenticateCoreAsync().Result; + } + + protected override async Task AuthenticateCoreAsync() + { + AuthenticationProperties properties = null; + + try + { + string code = null; + string state = null; + + IReadableStringCollection query = Request.Query; + + IList values = query.GetValues("error"); + if (values != null && values.Count >= 1) + { + _logger.WriteVerbose("Remote server returned an error: " + Request.QueryString); + } + + values = query.GetValues("code"); + if (values != null && values.Count == 1) + { + code = values[0]; + } + values = query.GetValues("state"); + if (values != null && values.Count == 1) + { + state = values[0]; + } + + properties = Options.StateDataFormat.Unprotect(state); + if (properties == null) + { + return null; + } + + // OAuth2 10.12 CSRF + if (!ValidateCorrelationId(properties, _logger)) + { + return new AuthenticationTicket(null, properties); + } + + if (code == null) + { + // Null if the remote server returns an error. + return new AuthenticationTicket(null, properties); + } + + string requestPrefix = Request.Scheme + "://" + Request.Host; + string redirectUri = requestPrefix + Request.PathBase + Options.CallbackPath; + + string tokenRequest = "grant_type=authorization_code" + + "&code=" + Uri.EscapeDataString(code) + + "&redirect_uri=" + Uri.EscapeDataString(redirectUri) + + "&client_id=" + Uri.EscapeDataString(Options.AppId) + + "&client_secret=" + Uri.EscapeDataString(Options.AppSecret); + + var tokenResponse = await _httpClient.GetAsync(TokenEndpoint + "?" + tokenRequest, Context.RequestAborted); + tokenResponse.EnsureSuccessStatusCode(); + string text = await tokenResponse.Content.ReadAsStringAsync(); + IFormCollection form = FormHelpers.ParseForm(text); + + string accessToken = form["access_token"]; + string expires = form["expires"]; + string graphAddress = GraphApiEndpoint + "?access_token=" + Uri.EscapeDataString(accessToken); + if (Options.SendAppSecretProof) + { + graphAddress += "&appsecret_proof=" + GenerateAppSecretProof(accessToken); + } + + var graphResponse = await _httpClient.GetAsync(graphAddress, Context.RequestAborted); + graphResponse.EnsureSuccessStatusCode(); + text = await graphResponse.Content.ReadAsStringAsync(); + JObject user = JObject.Parse(text); + + var context = new FacebookAuthenticatedContext(Context, user, accessToken, expires); + context.Identity = new ClaimsIdentity( + Options.AuthenticationType, + ClaimsIdentity.DefaultNameClaimType, + ClaimsIdentity.DefaultRoleClaimType); + if (!string.IsNullOrEmpty(context.Id)) + { + context.Identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, context.Id, XmlSchemaString, Options.AuthenticationType)); + } + if (!string.IsNullOrEmpty(context.UserName)) + { + context.Identity.AddClaim(new Claim(ClaimsIdentity.DefaultNameClaimType, context.UserName, XmlSchemaString, Options.AuthenticationType)); + } + if (!string.IsNullOrEmpty(context.Email)) + { + context.Identity.AddClaim(new Claim(ClaimTypes.Email, context.Email, XmlSchemaString, Options.AuthenticationType)); + } + if (!string.IsNullOrEmpty(context.Name)) + { + context.Identity.AddClaim(new Claim("urn:facebook:name", context.Name, XmlSchemaString, Options.AuthenticationType)); + + // Many Facebook accounts do not set the UserName field. Fall back to the Name field instead. + if (string.IsNullOrEmpty(context.UserName)) + { + context.Identity.AddClaim(new Claim(ClaimsIdentity.DefaultNameClaimType, context.Name, XmlSchemaString, Options.AuthenticationType)); + } + } + if (!string.IsNullOrEmpty(context.Link)) + { + context.Identity.AddClaim(new Claim("urn:facebook:link", context.Link, XmlSchemaString, Options.AuthenticationType)); + } + context.Properties = properties; + + await Options.Notifications.Authenticated(context); + + return new AuthenticationTicket(context.Identity, context.Properties); + } + catch (Exception ex) + { + _logger.WriteError("Authentication failed", ex); + return new AuthenticationTicket(null, properties); + } + } + + protected override void ApplyResponseChallenge() + { + if (Response.StatusCode != 401) + { + return; + } + + // Active middleware should redirect on 401 even if there wasn't an explicit challenge. + if (ChallengeContext == null && Options.AuthenticationMode == AuthenticationMode.Passive) + { + return; + } + + string baseUri = + Request.Scheme + + "://" + + Request.Host + + Request.PathBase; + + string currentUri = + baseUri + + Request.Path + + Request.QueryString; + + string redirectUri = + baseUri + + Options.CallbackPath; + + AuthenticationProperties properties; + if (ChallengeContext == null) + { + properties = new AuthenticationProperties(); + } + else + { + properties = new AuthenticationProperties(ChallengeContext.Properties); + } + if (string.IsNullOrEmpty(properties.RedirectUri)) + { + properties.RedirectUri = currentUri; + } + + // OAuth2 10.12 CSRF + GenerateCorrelationId(properties); + + // comma separated + string scope = string.Join(",", Options.Scope); + + string state = Options.StateDataFormat.Protect(properties); + + string authorizationEndpoint = + AuthorizationEndpoint + + "?response_type=code" + + "&client_id=" + Uri.EscapeDataString(Options.AppId) + + "&redirect_uri=" + Uri.EscapeDataString(redirectUri) + + "&scope=" + Uri.EscapeDataString(scope) + + "&state=" + Uri.EscapeDataString(state); + + var redirectContext = new FacebookApplyRedirectContext(Context, Options, properties, authorizationEndpoint); + Options.Notifications.ApplyRedirect(redirectContext); + } + + protected override void ApplyResponseGrant() + { + // N/A + } + + public override async Task InvokeAsync() + { + return await InvokeReplyPathAsync(); + } + + private async Task InvokeReplyPathAsync() + { + if (Options.CallbackPath.HasValue && Options.CallbackPath == Request.Path) + { + // TODO: error responses + + AuthenticationTicket ticket = await AuthenticateAsync(); + if (ticket == null) + { + _logger.WriteWarning("Invalid return state, unable to redirect."); + Response.StatusCode = 500; + return true; + } + + var context = new FacebookReturnEndpointContext(Context, ticket); + context.SignInAsAuthenticationType = Options.SignInAsAuthenticationType; + context.RedirectUri = ticket.Properties.RedirectUri; + + await Options.Notifications.ReturnEndpoint(context); + + if (context.SignInAsAuthenticationType != null && + context.Identity != null) + { + ClaimsIdentity grantIdentity = context.Identity; + if (!string.Equals(grantIdentity.AuthenticationType, context.SignInAsAuthenticationType, StringComparison.Ordinal)) + { + grantIdentity = new ClaimsIdentity(grantIdentity.Claims, context.SignInAsAuthenticationType, grantIdentity.NameClaimType, grantIdentity.RoleClaimType); + } + Context.Response.SignIn(context.Properties, grantIdentity); + } + + if (!context.IsRequestCompleted && context.RedirectUri != null) + { + string redirectUri = context.RedirectUri; + if (context.Identity == null) + { + // add a redirect hint that sign-in failed in some way + redirectUri = QueryHelpers.AddQueryString(redirectUri, "error", "access_denied"); + } + Response.Redirect(redirectUri); + context.RequestCompleted(); + } + + return context.IsRequestCompleted; + } + return false; + } + + private string GenerateAppSecretProof(string accessToken) + { + using (HMACSHA256 algorithm = new HMACSHA256(Encoding.ASCII.GetBytes(Options.AppSecret))) + { + byte[] hash = algorithm.ComputeHash(Encoding.ASCII.GetBytes(accessToken)); + StringBuilder builder = new StringBuilder(); + for (int i = 0; i < hash.Length; i++) + { + builder.Append(hash[i].ToString("x2", CultureInfo.InvariantCulture)); + } + return builder.ToString(); + } + } + } +} diff --git a/src/Microsoft.AspNet.Security.Facebook/FacebookAuthenticationMiddleware.cs b/src/Microsoft.AspNet.Security.Facebook/FacebookAuthenticationMiddleware.cs new file mode 100644 index 000000000..895c7b08d --- /dev/null +++ b/src/Microsoft.AspNet.Security.Facebook/FacebookAuthenticationMiddleware.cs @@ -0,0 +1,97 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Diagnostics.CodeAnalysis; +using System.Globalization; +using System.Net.Http; +using Microsoft.AspNet.Builder; +using Microsoft.AspNet.Security.DataHandler; +using Microsoft.AspNet.Security.DataProtection; +using Microsoft.AspNet.Security.Infrastructure; +using Microsoft.Framework.Logging; + +namespace Microsoft.AspNet.Security.Facebook +{ + /// + /// ASP.NET middleware for authenticating users using Facebook + /// + [SuppressMessage("Microsoft.Design", "CA1001:TypesThatOwnDisposableFieldsShouldBeDisposable", Justification = "Middleware is not disposable.")] + public class FacebookAuthenticationMiddleware : AuthenticationMiddleware + { + private readonly ILogger _logger; + private readonly HttpClient _httpClient; + + /// + /// Initializes a + /// + /// The next middleware in the application pipeline to invoke + /// Configuration options for the middleware + public FacebookAuthenticationMiddleware( + RequestDelegate next, + IDataProtectionProvider dataProtectionProvider, + ILoggerFactory loggerFactory, + IServiceProvider services, + FacebookAuthenticationOptions options) + : base(next, options) + { + if (string.IsNullOrWhiteSpace(Options.AppId)) + { + throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, Resources.Exception_OptionMustBeProvided, "AppId")); + } + if (string.IsNullOrWhiteSpace(Options.AppSecret)) + { + throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, Resources.Exception_OptionMustBeProvided, "AppSecret")); + } + + _logger = loggerFactory.Create(typeof(FacebookAuthenticationMiddleware).FullName); + + if (Options.Notifications == null) + { + Options.Notifications = new FacebookAuthenticationNotifications(); + } + if (Options.StateDataFormat == null) + { + IDataProtector dataProtector = DataProtectionHelpers.CreateDataProtector(dataProtectionProvider, + typeof(FacebookAuthenticationMiddleware).FullName, options.AuthenticationType, "v1"); + Options.StateDataFormat = new PropertiesDataFormat(dataProtector); + } + + _httpClient = new HttpClient(ResolveHttpMessageHandler(Options)); + _httpClient.Timeout = Options.BackchannelTimeout; + _httpClient.MaxResponseContentBufferSize = 1024 * 1024 * 10; // 10 MB + } + + /// + /// Provides the object for processing authentication-related requests. + /// + /// An configured with the supplied to the constructor. + protected override AuthenticationHandler CreateHandler() + { + return new FacebookAuthenticationHandler(_httpClient, _logger); + } + + [SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Justification = "Managed by caller")] + private static HttpMessageHandler ResolveHttpMessageHandler(FacebookAuthenticationOptions options) + { + HttpMessageHandler handler = options.BackchannelHttpHandler ?? +#if NET45 + new WebRequestHandler(); + // If they provided a validator, apply it or fail. + if (options.BackchannelCertificateValidator != null) + { + // Set the cert validate callback + var webRequestHandler = handler as WebRequestHandler; + if (webRequestHandler == null) + { + throw new InvalidOperationException(Resources.Exception_ValidatorHandlerMismatch); + } + webRequestHandler.ServerCertificateValidationCallback = options.BackchannelCertificateValidator.Validate; + } +#else + new WinHttpHandler(); +#endif + return handler; + } + } +} diff --git a/src/Microsoft.AspNet.Security.Facebook/FacebookAuthenticationOptions.cs b/src/Microsoft.AspNet.Security.Facebook/FacebookAuthenticationOptions.cs new file mode 100644 index 000000000..983273446 --- /dev/null +++ b/src/Microsoft.AspNet.Security.Facebook/FacebookAuthenticationOptions.cs @@ -0,0 +1,112 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using System.Net.Http; +using Microsoft.AspNet.Http; +using Microsoft.AspNet.Http.Security; + +namespace Microsoft.AspNet.Security.Facebook +{ + /// + /// Configuration options for + /// + public class FacebookAuthenticationOptions : AuthenticationOptions + { + /// + /// Initializes a new + /// + [SuppressMessage("Microsoft.Globalization", "CA1303:Do not pass literals as localized parameters", + MessageId = "Microsoft.AspNet.Security.Facebook.FacebookAuthenticationOptions.set_Caption(System.String)", Justification = "Not localizable.")] + public FacebookAuthenticationOptions() + : base(FacebookAuthenticationDefaults.AuthenticationType) + { + Caption = FacebookAuthenticationDefaults.AuthenticationType; + CallbackPath = new PathString("/signin-facebook"); + AuthenticationMode = AuthenticationMode.Passive; + Scope = new List(); + BackchannelTimeout = TimeSpan.FromSeconds(60); + SendAppSecretProof = true; + } + + /// + /// Gets or sets the Facebook-assigned appId + /// + public string AppId { get; set; } + + /// + /// Gets or sets the Facebook-assigned app secret + /// + public string AppSecret { get; set; } +#if NET45 + /// + /// Gets or sets the a pinned certificate validator to use to validate the endpoints used + /// in back channel communications belong to Facebook. + /// + /// + /// The pinned certificate validator. + /// + /// If this property is null then the default certificate checks are performed, + /// validating the subject name and if the signing chain is a trusted party. + public ICertificateValidator BackchannelCertificateValidator { get; set; } +#endif + /// + /// Gets or sets timeout value in milliseconds for back channel communications with Facebook. + /// + /// + /// The back channel timeout in milliseconds. + /// + public TimeSpan BackchannelTimeout { get; set; } + + /// + /// The HttpMessageHandler used to communicate with Facebook. + /// This cannot be set at the same time as BackchannelCertificateValidator unless the value + /// can be downcast to a WebRequestHandler. + /// + public HttpMessageHandler BackchannelHttpHandler { get; set; } + + /// + /// Get or sets the text that the user can display on a sign in user interface. + /// + public string Caption + { + get { return Description.Caption; } + set { Description.Caption = value; } + } + + /// + /// The request path within the application's base path where the user-agent will be returned. + /// The middleware will process this request when it arrives. + /// Default value is "/signin-facebook". + /// + public PathString CallbackPath { get; set; } + + /// + /// Gets or sets the name of another authentication middleware which will be responsible for actually issuing a user . + /// + public string SignInAsAuthenticationType { get; set; } + + /// + /// Gets or sets the used to handle authentication events. + /// + public IFacebookAuthenticationNotifications Notifications { get; set; } + + /// + /// Gets or sets the type used to secure data handled by the middleware. + /// + public ISecureDataFormat StateDataFormat { get; set; } + + /// + /// A list of permissions to request. + /// + public IList Scope { get; private set; } + + /// + /// Gets or sets if the appsecret_proof should be generated and sent with Facebook API calls. + /// This is enabled by default. + /// + public bool SendAppSecretProof { get; set; } + } +} diff --git a/src/Microsoft.AspNet.Security.Facebook/Microsoft.AspNet.Security.Facebook.kproj b/src/Microsoft.AspNet.Security.Facebook/Microsoft.AspNet.Security.Facebook.kproj new file mode 100644 index 000000000..c576730aa --- /dev/null +++ b/src/Microsoft.AspNet.Security.Facebook/Microsoft.AspNet.Security.Facebook.kproj @@ -0,0 +1,20 @@ + + + + 12.0 + $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) + + + + 3984651c-fd44-4394-8793-3d14ee348c04 + Library + + + + + + + 2.0 + + + \ No newline at end of file diff --git a/src/Microsoft.AspNet.Security.Facebook/NotNullAttribute.cs b/src/Microsoft.AspNet.Security.Facebook/NotNullAttribute.cs new file mode 100644 index 000000000..6a4d82b16 --- /dev/null +++ b/src/Microsoft.AspNet.Security.Facebook/NotNullAttribute.cs @@ -0,0 +1,12 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; + +namespace Microsoft.AspNet.Security.Facebook +{ + [AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false)] + internal sealed class NotNullAttribute : Attribute + { + } +} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Security.Facebook/Notifications/FacebookApplyRedirectContext.cs b/src/Microsoft.AspNet.Security.Facebook/Notifications/FacebookApplyRedirectContext.cs new file mode 100644 index 000000000..020e2d32e --- /dev/null +++ b/src/Microsoft.AspNet.Security.Facebook/Notifications/FacebookApplyRedirectContext.cs @@ -0,0 +1,43 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using Microsoft.AspNet.Http; +using Microsoft.AspNet.Http.Security; +using Microsoft.AspNet.Security.Notifications; + +namespace Microsoft.AspNet.Security.Facebook +{ + /// + /// Context passed when a Challenge causes a redirect to authorize endpoint in the Facebook middleware + /// + public class FacebookApplyRedirectContext : BaseContext + { + /// + /// Creates a new context object. + /// + /// The http request context + /// The Facebook middleware options + /// The authenticaiton properties of the challenge + /// The initial redirect URI + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings", MessageId = "3#", + Justification = "Represents header value")] + public FacebookApplyRedirectContext(HttpContext context, FacebookAuthenticationOptions options, + AuthenticationProperties properties, string redirectUri) + : base(context, options) + { + RedirectUri = redirectUri; + Properties = properties; + } + + /// + /// Gets the URI used for the redirect operation. + /// + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1056:UriPropertiesShouldNotBeStrings", Justification = "Represents header value")] + public string RedirectUri { get; private set; } + + /// + /// Gets the authentication properties of the challenge + /// + public AuthenticationProperties Properties { get; private set; } + } +} diff --git a/src/Microsoft.AspNet.Security.Facebook/Notifications/FacebookAuthenticatedContext.cs b/src/Microsoft.AspNet.Security.Facebook/Notifications/FacebookAuthenticatedContext.cs new file mode 100644 index 000000000..c173dfde8 --- /dev/null +++ b/src/Microsoft.AspNet.Security.Facebook/Notifications/FacebookAuthenticatedContext.cs @@ -0,0 +1,98 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Globalization; +using System.Security.Claims; +using Microsoft.AspNet.Http; +using Microsoft.AspNet.Http.Security; +using Microsoft.AspNet.Security.Notifications; +using Newtonsoft.Json.Linq; + +namespace Microsoft.AspNet.Security.Facebook +{ + /// + /// Contains information about the login session as well as the user . + /// + public class FacebookAuthenticatedContext : BaseContext + { + /// + /// Initializes a + /// + /// The http environment + /// The JSON-serialized user + /// Facebook Access token + /// Seconds until expiration + public FacebookAuthenticatedContext(HttpContext context, JObject user, string accessToken, string expires) + : base(context) + { + User = user; + AccessToken = accessToken; + + int expiresValue; + if (Int32.TryParse(expires, NumberStyles.Integer, CultureInfo.InvariantCulture, out expiresValue)) + { + ExpiresIn = TimeSpan.FromSeconds(expiresValue); + } + + Id = TryGetValue(user, "id"); + Name = TryGetValue(user, "name"); + Link = TryGetValue(user, "link"); + UserName = TryGetValue(user, "username"); + Email = TryGetValue(user, "email"); + } + + /// + /// Gets the JSON-serialized user + /// + public JObject User { get; private set; } + + /// + /// Gets the Facebook access token + /// + public string AccessToken { get; private set; } + + /// + /// Gets the Facebook access token expiration time + /// + public TimeSpan? ExpiresIn { get; set; } + + /// + /// Gets the Facebook user ID + /// + public string Id { get; private set; } + + /// + /// Gets the user's name + /// + public string Name { get; private set; } + + public string Link { get; private set; } + + /// + /// Gets the Facebook username + /// + public string UserName { get; private set; } + + /// + /// Gets the Facebook email + /// + public string Email { get; private set; } + + /// + /// Gets the representing the user + /// + public ClaimsIdentity Identity { get; set; } + + /// + /// Gets or sets a property bag for common authentication properties + /// + public AuthenticationProperties Properties { get; set; } + + private static string TryGetValue(JObject user, string propertyName) + { + JToken value; + return user.TryGetValue(propertyName, out value) ? value.ToString() : null; + } + } +} diff --git a/src/Microsoft.AspNet.Security.Facebook/Notifications/FacebookAuthenticationNotifications.cs b/src/Microsoft.AspNet.Security.Facebook/Notifications/FacebookAuthenticationNotifications.cs new file mode 100644 index 000000000..22dbcfcc0 --- /dev/null +++ b/src/Microsoft.AspNet.Security.Facebook/Notifications/FacebookAuthenticationNotifications.cs @@ -0,0 +1,69 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Threading.Tasks; + +namespace Microsoft.AspNet.Security.Facebook +{ + /// + /// Default implementation. + /// + public class FacebookAuthenticationNotifications : IFacebookAuthenticationNotifications + { + /// + /// Initializes a + /// + public FacebookAuthenticationNotifications() + { + OnAuthenticated = context => Task.FromResult(null); + OnReturnEndpoint = context => Task.FromResult(null); + OnApplyRedirect = context => + context.Response.Redirect(context.RedirectUri); + } + + /// + /// Gets or sets the function that is invoked when the Authenticated method is invoked. + /// + public Func OnAuthenticated { get; set; } + + /// + /// Gets or sets the function that is invoked when the ReturnEndpoint method is invoked. + /// + public Func OnReturnEndpoint { get; set; } + + /// + /// Gets or sets the delegate that is invoked when the ApplyRedirect method is invoked. + /// + public Action OnApplyRedirect { get; set; } + + /// + /// Invoked whenever Facebook succesfully authenticates a user + /// + /// Contains information about the login session as well as the user . + /// A representing the completed operation. + public virtual Task Authenticated(FacebookAuthenticatedContext context) + { + return OnAuthenticated(context); + } + + /// + /// Invoked prior to the being saved in a local cookie and the browser being redirected to the originally requested URL. + /// + /// + /// A representing the completed operation. + public virtual Task ReturnEndpoint(FacebookReturnEndpointContext context) + { + return OnReturnEndpoint(context); + } + + /// + /// Called when a Challenge causes a redirect to authorize endpoint in the Facebook middleware + /// + /// Contains redirect URI and of the challenge + public virtual void ApplyRedirect(FacebookApplyRedirectContext context) + { + OnApplyRedirect(context); + } + } +} diff --git a/src/Microsoft.AspNet.Security.Facebook/Notifications/FacebookReturnEndpointContext.cs b/src/Microsoft.AspNet.Security.Facebook/Notifications/FacebookReturnEndpointContext.cs new file mode 100644 index 000000000..e32cad4ee --- /dev/null +++ b/src/Microsoft.AspNet.Security.Facebook/Notifications/FacebookReturnEndpointContext.cs @@ -0,0 +1,26 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using Microsoft.AspNet.Http; +using Microsoft.AspNet.Security.Notifications; + +namespace Microsoft.AspNet.Security.Facebook +{ + /// + /// Provides context information to middleware providers. + /// + public class FacebookReturnEndpointContext : ReturnEndpointContext + { + /// + /// Creates a new context object. + /// + /// The http environment + /// The authentication ticket + public FacebookReturnEndpointContext( + HttpContext context, + AuthenticationTicket ticket) + : base(context, ticket) + { + } + } +} diff --git a/src/Microsoft.AspNet.Security.Facebook/Notifications/IFacebookAuthenticationNotifications.cs b/src/Microsoft.AspNet.Security.Facebook/Notifications/IFacebookAuthenticationNotifications.cs new file mode 100644 index 000000000..530ea6505 --- /dev/null +++ b/src/Microsoft.AspNet.Security.Facebook/Notifications/IFacebookAuthenticationNotifications.cs @@ -0,0 +1,33 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System.Threading.Tasks; + +namespace Microsoft.AspNet.Security.Facebook +{ + /// + /// Specifies callback methods which the invokes to enable developer control over the authentication process. /> + /// + public interface IFacebookAuthenticationNotifications + { + /// + /// Invoked whenever Facebook succesfully authenticates a user + /// + /// Contains information about the login session as well as the user . + /// A representing the completed operation. + Task Authenticated(FacebookAuthenticatedContext context); + + /// + /// Invoked prior to the being saved in a local cookie and the browser being redirected to the originally requested URL. + /// + /// + /// A representing the completed operation. + Task ReturnEndpoint(FacebookReturnEndpointContext context); + + /// + /// Called when a Challenge causes a redirect to authorize endpoint in the Facebook middleware + /// + /// Contains redirect URI and of the challenge + void ApplyRedirect(FacebookApplyRedirectContext context); + } +} diff --git a/src/Microsoft.AspNet.Security.Facebook/Project.json b/src/Microsoft.AspNet.Security.Facebook/Project.json new file mode 100644 index 000000000..b70ab4b6a --- /dev/null +++ b/src/Microsoft.AspNet.Security.Facebook/Project.json @@ -0,0 +1,44 @@ +{ + "version": "1.0.0-*", + "dependencies": { + "Microsoft.AspNet.Http": "1.0.0-*", + "Microsoft.AspNet.RequestContainer": "1.0.0-*", + "Microsoft.AspNet.Security": "1.0.0-*", + "Microsoft.AspNet.Security.DataProtection": "1.0.0-*", + "Microsoft.AspNet.WebUtilities": "1.0.0-*", + "Microsoft.Framework.Logging": "1.0.0-*", + "Newtonsoft.Json": "5.0.8", + "System.Net.Http": "4.0.0.0" + }, + "frameworks": { + "net45": { + "dependencies": { + "System.Net.Http.WebRequest": "" + } + }, + "k10": { + "dependencies": { + "System.Collections": "4.0.10.0", + "System.ComponentModel": "4.0.0.0", + "System.Console": "4.0.0.0", + "System.Diagnostics.Debug": "4.0.10.0", + "System.Diagnostics.Tools": "4.0.0.0", + "System.Globalization": "4.0.10.0", + "System.IO": "4.0.0.0", + "System.IO.Compression": "4.0.0.0", + "System.Linq": "4.0.0.0", + "System.Net.Http.WinHttpHandler": "4.0.0.0", + "System.Reflection": "4.0.10.0", + "System.Resources.ResourceManager": "4.0.0.0", + "System.Runtime": "4.0.20.0", + "System.Runtime.Extensions": "4.0.10.0", + "System.Runtime.InteropServices": "4.0.20.0", + "System.Security.Claims": "1.0.0-*", + "System.Security.Cryptography.Hashing.Algorithms": "4.0.0.0", + "System.Security.Principal": "4.0.0.0", + "System.Threading": "4.0.0.0", + "System.Threading.Tasks": "4.0.10.0" + } + } + } +} diff --git a/src/Microsoft.AspNet.Security.Facebook/Resources.Designer.cs b/src/Microsoft.AspNet.Security.Facebook/Resources.Designer.cs new file mode 100644 index 000000000..dca281f82 --- /dev/null +++ b/src/Microsoft.AspNet.Security.Facebook/Resources.Designer.cs @@ -0,0 +1,81 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.32559 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace Microsoft.AspNet.Security.Facebook { + using System; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class Resources { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Resources() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Microsoft.AspNet.Security.Facebook.Resources", System.Reflection.IntrospectionExtensions.GetTypeInfo(typeof(Resources)).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + + /// + /// Looks up a localized string similar to The '{0}' option must be provided.. + /// + internal static string Exception_OptionMustBeProvided { + get { + return ResourceManager.GetString("Exception_OptionMustBeProvided", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to An ICertificateValidator cannot be specified at the same time as an HttpMessageHandler unless it is a WebRequestHandler.. + /// + internal static string Exception_ValidatorHandlerMismatch { + get { + return ResourceManager.GetString("Exception_ValidatorHandlerMismatch", resourceCulture); + } + } + } +} diff --git a/src/Microsoft.AspNet.Security.Facebook/Resources.resx b/src/Microsoft.AspNet.Security.Facebook/Resources.resx new file mode 100644 index 000000000..2a19bea96 --- /dev/null +++ b/src/Microsoft.AspNet.Security.Facebook/Resources.resx @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + The '{0}' option must be provided. + + + An ICertificateValidator cannot be specified at the same time as an HttpMessageHandler unless it is a WebRequestHandler. + + \ No newline at end of file diff --git a/src/Microsoft.AspNet.Security/AppBuilderSecurityExtensions.cs b/src/Microsoft.AspNet.Security/BuilderSecurityExtensions.cs similarity index 89% rename from src/Microsoft.AspNet.Security/AppBuilderSecurityExtensions.cs rename to src/Microsoft.AspNet.Security/BuilderSecurityExtensions.cs index ca9c39427..6043a0966 100644 --- a/src/Microsoft.AspNet.Security/AppBuilderSecurityExtensions.cs +++ b/src/Microsoft.AspNet.Security/BuilderSecurityExtensions.cs @@ -1,16 +1,15 @@ // Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -/* TODO: using System; -using Owin; +using Microsoft.AspNet.Security; -namespace Microsoft.AspNet.Security +namespace Microsoft.AspNet.Builder { /// /// Provides extensions methods for app.Property values that are only needed by implementations of authentication middleware. /// - public static class AppBuilderSecurityExtensions + public static class BuilderSecurityExtensions { /// /// Returns the previously set AuthenticationType that external sign in middleware should use when the @@ -18,7 +17,7 @@ public static class AppBuilderSecurityExtensions /// /// App builder passed to the application startup code /// - public static string GetDefaultSignInAsAuthenticationType([NotNull] this IAppBuilder app) + public static string GetDefaultSignInAsAuthenticationType([NotNull] this IBuilder app) { object value; if (app.Properties.TryGetValue(Constants.DefaultSignInAsAuthenticationType, out value)) @@ -38,10 +37,9 @@ public static string GetDefaultSignInAsAuthenticationType([NotNull] this IAppBui /// /// App builder passed to the application startup code /// AuthenticationType that external middleware should sign in as. - public static void SetDefaultSignInAsAuthenticationType([NotNull] this IAppBuilder app, [NotNull] string authenticationType) + public static void SetDefaultSignInAsAuthenticationType([NotNull] this IBuilder app, [NotNull] string authenticationType) { app.Properties[Constants.DefaultSignInAsAuthenticationType] = authenticationType; } } -} -*/ \ No newline at end of file +} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Security/Constants.cs b/src/Microsoft.AspNet.Security/Constants.cs index 1758c8480..d1bc8f01e 100644 --- a/src/Microsoft.AspNet.Security/Constants.cs +++ b/src/Microsoft.AspNet.Security/Constants.cs @@ -12,6 +12,6 @@ internal static class Constants /// /// Used by middleware extension methods to coordinate the default value Options property SignInAsAuthenticationType /// - public const string DefaultSignInAsAuthenticationType = "Microsoft.AspNet.Security.Constants.DefaultSignInAsAuthenticationType"; + internal const string DefaultSignInAsAuthenticationType = "Microsoft.AspNet.Security.DefaultSignInAsAuthenticationType"; } } diff --git a/src/Microsoft.AspNet.Security/DataHandler/PropertiesDataFormat.cs b/src/Microsoft.AspNet.Security/DataHandler/PropertiesDataFormat.cs index 42f71728c..050f9d24e 100644 --- a/src/Microsoft.AspNet.Security/DataHandler/PropertiesDataFormat.cs +++ b/src/Microsoft.AspNet.Security/DataHandler/PropertiesDataFormat.cs @@ -1,7 +1,6 @@ // Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - using Microsoft.AspNet.Http.Security; using Microsoft.AspNet.Security.DataHandler.Encoder; using Microsoft.AspNet.Security.DataHandler.Serializer; diff --git a/test/Microsoft.AspNet.Security.Test/Facebook/FacebookMiddlewareTests.cs b/test/Microsoft.AspNet.Security.Test/Facebook/FacebookMiddlewareTests.cs new file mode 100644 index 000000000..853894878 --- /dev/null +++ b/test/Microsoft.AspNet.Security.Test/Facebook/FacebookMiddlewareTests.cs @@ -0,0 +1,124 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net; +using System.Net.Http; +using System.Threading.Tasks; +using Microsoft.AspNet.Builder; +using Microsoft.AspNet.Http; +using Microsoft.AspNet.Http.Security; +using Microsoft.AspNet.Security.Cookies; +using Microsoft.AspNet.TestHost; +using Microsoft.Framework.DependencyInjection; +using Shouldly; +using Xunit; + +namespace Microsoft.AspNet.Security.Facebook +{ + public class FacebookMiddlewareTests + { + [Fact] + public async Task ChallengeWillTriggerApplyRedirectEvent() + { + var options = new FacebookAuthenticationOptions() + { + AppId = "Test App Id", + AppSecret = "Test App Secret", + Notifications = new FacebookAuthenticationNotifications + { + OnApplyRedirect = context => + { + context.Response.Redirect(context.RedirectUri + "&custom=test"); + } + } + }; + var server = CreateServer( + app => app.UseFacebookAuthentication(options), + context => + { + context.Response.Challenge("Facebook"); + return true; + }); + var transaction = await SendAsync(server, "http://example.com/challenge"); + transaction.Response.StatusCode.ShouldBe(HttpStatusCode.Redirect); + var query = transaction.Response.Headers.Location.Query; + query.ShouldContain("custom=test"); + } + + [Fact] + public async Task ChallengeWillTriggerRedirection() + { + var server = CreateServer( + app => app.UseFacebookAuthentication("Test App Id", "Test App Secret"), + context => + { + context.Response.Challenge("Facebook"); + return true; + }); + var transaction = await SendAsync(server, "http://example.com/challenge"); + transaction.Response.StatusCode.ShouldBe(HttpStatusCode.Redirect); + var location = transaction.Response.Headers.Location.AbsoluteUri; + location.ShouldContain("https://www.facebook.com/dialog/oauth"); + location.ShouldContain("?response_type=code"); + location.ShouldContain("&client_id="); + location.ShouldContain("&redirect_uri="); + location.ShouldContain("&scope="); + location.ShouldContain("&state="); + } + + private static TestServer CreateServer(Action configure, Func handler) + { + return TestServer.Create(app => + { + app.SetDefaultSignInAsAuthenticationType("External"); + app.UseCookieAuthentication(new CookieAuthenticationOptions() + { + AuthenticationType = "External" + }); + if (configure != null) + { + configure(app); + } + app.Use(async (context, next) => + { + if (handler == null || !handler(context)) + { + await next(); + } + }); + }); + } + + private static async Task SendAsync(TestServer server, string uri, string cookieHeader = null) + { + var request = new HttpRequestMessage(HttpMethod.Get, uri); + if (!string.IsNullOrEmpty(cookieHeader)) + { + request.Headers.Add("Cookie", cookieHeader); + } + var transaction = new Transaction + { + Request = request, + Response = await server.CreateClient().SendAsync(request), + }; + if (transaction.Response.Headers.Contains("Set-Cookie")) + { + transaction.SetCookie = transaction.Response.Headers.GetValues("Set-Cookie").ToList(); + } + transaction.ResponseText = await transaction.Response.Content.ReadAsStringAsync(); + + return transaction; + } + + private class Transaction + { + public HttpRequestMessage Request { get; set; } + public HttpResponseMessage Response { get; set; } + public IList SetCookie { get; set; } + public string ResponseText { get; set; } + } + } +} diff --git a/test/Microsoft.AspNet.Security.Test/project.json b/test/Microsoft.AspNet.Security.Test/project.json index b46b261de..d45c84b1f 100644 --- a/test/Microsoft.AspNet.Security.Test/project.json +++ b/test/Microsoft.AspNet.Security.Test/project.json @@ -3,9 +3,12 @@ "warningsAsErrors": true }, "dependencies": { + "Microsoft.AspNet.Http": "1.0.0-*", "Microsoft.AspNet.Security" : "", "Microsoft.AspNet.Security.Cookies" : "", + "Microsoft.AspNet.Security.Facebook" : "", "Microsoft.AspNet.TestHost": "1.0.0-*", + "Microsoft.Framework.DependencyInjection": "1.0.0-*", "System.Net.Http": "4.0.0.0", "Moq": "4.2.1312.1622", "Xunit.KRunner": "1.0.0-*" From 0cc85f687ea15dcc3878048ba7a655e1221638bb Mon Sep 17 00:00:00 2001 From: Chris Ross Date: Wed, 20 Aug 2014 15:18:29 -0700 Subject: [PATCH 033/216] Reacting to System.IO package version change --- src/Microsoft.AspNet.Security.Facebook/Project.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Microsoft.AspNet.Security.Facebook/Project.json b/src/Microsoft.AspNet.Security.Facebook/Project.json index b70ab4b6a..9f19015e3 100644 --- a/src/Microsoft.AspNet.Security.Facebook/Project.json +++ b/src/Microsoft.AspNet.Security.Facebook/Project.json @@ -24,7 +24,7 @@ "System.Diagnostics.Debug": "4.0.10.0", "System.Diagnostics.Tools": "4.0.0.0", "System.Globalization": "4.0.10.0", - "System.IO": "4.0.0.0", + "System.IO": "4.0.10.0", "System.IO.Compression": "4.0.0.0", "System.Linq": "4.0.0.0", "System.Net.Http.WinHttpHandler": "4.0.0.0", From 5577159453fd6f9313dc07aae21b12b79fb635e2 Mon Sep 17 00:00:00 2001 From: Chris Ross Date: Fri, 22 Aug 2014 13:39:47 -0700 Subject: [PATCH 034/216] #37 - Port the Google auth middleware from Katana. --- Security.sln | 13 + samples/SocialSample/Project.json | 1 + samples/SocialSample/Startup.cs | 70 ++- .../CookieApplyRedirectContext.cs | 2 +- .../CookieResponseSignInContext.cs | 2 +- .../FacebookAuthenticationMiddleware.cs | 3 +- .../GoogleAuthenticationDefaults.cs | 10 + .../GoogleAuthenticationExtensions.cs | 45 ++ .../GoogleAuthenticationHandler.cs | 313 ++++++++++ .../GoogleAuthenticationMiddleware.cs | 98 +++ .../GoogleAuthenticationOptions.cs | 110 ++++ .../Microsoft.AspNet.Security.Google.kproj | 28 + .../NotNullAttribute.cs | 12 + .../GoogleApplyRedirectContext.cs | 43 ++ .../GoogleAuthenticatedContext.cs | 158 +++++ .../GoogleAuthenticationNotifications.cs | 69 +++ .../GoogleReturnEndpointContext.cs | 26 + .../IGoogleAuthenticationNotifications.cs | 33 + .../Project.json | 44 ++ .../Resources.Designer.cs | 81 +++ .../Resources.resx | 126 ++++ .../Infrastructure/AuthenticationHandler.cs | 3 - .../Google/GoogleMiddlewareTests.cs | 570 ++++++++++++++++++ .../project.json | 7 +- 24 files changed, 1854 insertions(+), 13 deletions(-) create mode 100644 src/Microsoft.AspNet.Security.Google/GoogleAuthenticationDefaults.cs create mode 100644 src/Microsoft.AspNet.Security.Google/GoogleAuthenticationExtensions.cs create mode 100644 src/Microsoft.AspNet.Security.Google/GoogleAuthenticationHandler.cs create mode 100644 src/Microsoft.AspNet.Security.Google/GoogleAuthenticationMiddleware.cs create mode 100644 src/Microsoft.AspNet.Security.Google/GoogleAuthenticationOptions.cs create mode 100644 src/Microsoft.AspNet.Security.Google/Microsoft.AspNet.Security.Google.kproj create mode 100644 src/Microsoft.AspNet.Security.Google/NotNullAttribute.cs create mode 100644 src/Microsoft.AspNet.Security.Google/Notifications/GoogleApplyRedirectContext.cs create mode 100644 src/Microsoft.AspNet.Security.Google/Notifications/GoogleAuthenticatedContext.cs create mode 100644 src/Microsoft.AspNet.Security.Google/Notifications/GoogleAuthenticationNotifications.cs create mode 100644 src/Microsoft.AspNet.Security.Google/Notifications/GoogleReturnEndpointContext.cs create mode 100644 src/Microsoft.AspNet.Security.Google/Notifications/IGoogleAuthenticationNotifications.cs create mode 100644 src/Microsoft.AspNet.Security.Google/Project.json create mode 100644 src/Microsoft.AspNet.Security.Google/Resources.Designer.cs create mode 100644 src/Microsoft.AspNet.Security.Google/Resources.resx create mode 100644 test/Microsoft.AspNet.Security.Test/Google/GoogleMiddlewareTests.cs diff --git a/Security.sln b/Security.sln index 0d249fe56..5ae54786f 100644 --- a/Security.sln +++ b/Security.sln @@ -26,6 +26,8 @@ Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNet.Security.F EndProject Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "SocialSample", "samples\SocialSample\SocialSample.kproj", "{8C73D216-332D-41D8-BFD0-45BC4BC36552}" EndProject +Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNet.Security.Google", "src\Microsoft.AspNet.Security.Google\Microsoft.AspNet.Security.Google.kproj", "{89BF8535-A849-458E-868A-A68FCF620486}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -96,6 +98,16 @@ Global {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|x86.ActiveCfg = Release|Any CPU + {89BF8535-A849-458E-868A-A68FCF620486}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {89BF8535-A849-458E-868A-A68FCF620486}.Debug|Any CPU.Build.0 = Debug|Any CPU + {89BF8535-A849-458E-868A-A68FCF620486}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {89BF8535-A849-458E-868A-A68FCF620486}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {89BF8535-A849-458E-868A-A68FCF620486}.Debug|x86.ActiveCfg = Debug|Any CPU + {89BF8535-A849-458E-868A-A68FCF620486}.Release|Any CPU.ActiveCfg = Release|Any CPU + {89BF8535-A849-458E-868A-A68FCF620486}.Release|Any CPU.Build.0 = Release|Any CPU + {89BF8535-A849-458E-868A-A68FCF620486}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {89BF8535-A849-458E-868A-A68FCF620486}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {89BF8535-A849-458E-868A-A68FCF620486}.Release|x86.ActiveCfg = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -107,5 +119,6 @@ Global {8DA26CD1-1302-4CFD-9270-9FA1B7C6138B} = {7BF11F3A-60B6-4796-B504-579C67FFBA34} {3984651C-FD44-4394-8793-3D14EE348C04} = {4D2B6A51-2F9F-44F5-8131-EA5CAC053652} {8C73D216-332D-41D8-BFD0-45BC4BC36552} = {F8C0AA27-F3FB-4286-8E4C-47EF86B539FF} + {89BF8535-A849-458E-868A-A68FCF620486} = {4D2B6A51-2F9F-44F5-8131-EA5CAC053652} EndGlobalSection EndGlobal diff --git a/samples/SocialSample/Project.json b/samples/SocialSample/Project.json index f5434cb1c..525d9dd6a 100644 --- a/samples/SocialSample/Project.json +++ b/samples/SocialSample/Project.json @@ -6,6 +6,7 @@ "Microsoft.AspNet.Security": "1.0.0-*", "Microsoft.AspNet.Security.Cookies": "1.0.0-*", "Microsoft.AspNet.Security.Facebook": "1.0.0-*", + "Microsoft.AspNet.Security.Google": "1.0.0-*", "Microsoft.AspNet.Server.WebListener": "1.0.0-*", "Microsoft.Framework.DependencyInjection": "1.0.0-*" }, diff --git a/samples/SocialSample/Startup.cs b/samples/SocialSample/Startup.cs index aec06926e..68dd967e4 100644 --- a/samples/SocialSample/Startup.cs +++ b/samples/SocialSample/Startup.cs @@ -1,7 +1,9 @@ using Microsoft.AspNet.Builder; using Microsoft.AspNet.Http; +using Microsoft.AspNet.Http.Security; using Microsoft.AspNet.Security.Cookies; using Microsoft.AspNet.Security.Facebook; +using Microsoft.AspNet.Security.Google; namespace CookieSample { @@ -15,6 +17,7 @@ public void Configure(IBuilder app) app.UseCookieAuthentication(new CookieAuthenticationOptions() { + LoginPath = new PathString("/login"), }); app.UseFacebookAuthentication(new FacebookAuthenticationOptions() @@ -23,16 +26,75 @@ public void Configure(IBuilder app) AppSecret = "a124463c4719c94b4228d9a240e5dc1a", }); - app.Run(async context => + app.UseGoogleAuthentication(new GoogleAuthenticationOptions() + { + ClientId = "560027070069-37ldt4kfuohhu3m495hk2j4pjp92d382.apps.googleusercontent.com", + ClientSecret = "n2Q-GEw9RQjzcRbU3qhfTj8f", + }); + + // Choose an authentication type + app.Map("/login", signoutApp => + { + signoutApp.Run(async context => + { + string authType = context.Request.Query["authtype"]; + if (!string.IsNullOrEmpty(authType)) + { + // 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 (/). + context.Response.Challenge(new AuthenticationProperties() { RedirectUri = "/" }, authType); + return; + } + + context.Response.ContentType = "text/html"; + await context.Response.WriteAsync(""); + await context.Response.WriteAsync("Choose an authentication type:
"); + foreach (var type in context.GetAuthenticationTypes()) + { + await context.Response.WriteAsync("" + (type.Caption ?? "(suppressed)") + "
"); + } + await context.Response.WriteAsync(""); + }); + }); + + // Sign-out to remove the user cookie. + app.Map("/logout", signoutApp => + { + signoutApp.Run(async context => + { + context.Response.SignOut(CookieAuthenticationDefaults.AuthenticationType); + context.Response.ContentType = "text/html"; + await context.Response.WriteAsync(""); + await context.Response.WriteAsync("You have been logged out. Goodbye " + context.User.Identity.Name + "
"); + await context.Response.WriteAsync("Home"); + await context.Response.WriteAsync(""); + }); + }); + + // Deny anonymous request beyond this point. + app.Use(async (context, next) => { if (!context.User.Identity.IsAuthenticated) { - context.Response.Challenge("Facebook"); + // The cookie middleware will intercept this 401 and redirect to /login + context.Response.Challenge(); return; } + await next(); + }); - context.Response.ContentType = "text/plain"; - await context.Response.WriteAsync("Hello " + context.User.Identity.Name); + // Display user information + app.Run(async context => + { + context.Response.ContentType = "text/html"; + await context.Response.WriteAsync(""); + await context.Response.WriteAsync("Hello " + context.User.Identity.Name + "
"); + foreach (var claim in context.User.Claims) + { + await context.Response.WriteAsync(claim.Type + ": " + claim.Value + "
"); + } + await context.Response.WriteAsync("Logout"); + await context.Response.WriteAsync(""); }); } } diff --git a/src/Microsoft.AspNet.Security.Cookies/Notifications/CookieApplyRedirectContext.cs b/src/Microsoft.AspNet.Security.Cookies/Notifications/CookieApplyRedirectContext.cs index 28cdf713c..34907eaba 100644 --- a/src/Microsoft.AspNet.Security.Cookies/Notifications/CookieApplyRedirectContext.cs +++ b/src/Microsoft.AspNet.Security.Cookies/Notifications/CookieApplyRedirectContext.cs @@ -16,7 +16,7 @@ public class CookieApplyRedirectContext : BaseContext /// Creates a new context object. /// - /// The OWIN request context + /// The HTTP request context /// The cookie middleware options /// The initial redirect URI [SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings", MessageId = "2#", Justification = "Represents header value")] diff --git a/src/Microsoft.AspNet.Security.Cookies/Notifications/CookieResponseSignInContext.cs b/src/Microsoft.AspNet.Security.Cookies/Notifications/CookieResponseSignInContext.cs index 598f985f5..28b47c6fe 100644 --- a/src/Microsoft.AspNet.Security.Cookies/Notifications/CookieResponseSignInContext.cs +++ b/src/Microsoft.AspNet.Security.Cookies/Notifications/CookieResponseSignInContext.cs @@ -17,7 +17,7 @@ public class CookieResponseSignInContext : BaseContext /// Creates a new instance of the context object. /// - /// The OWIN request context + /// The HTTP request context /// The middleware options /// Initializes AuthenticationType property /// Initializes Identity property diff --git a/src/Microsoft.AspNet.Security.Facebook/FacebookAuthenticationMiddleware.cs b/src/Microsoft.AspNet.Security.Facebook/FacebookAuthenticationMiddleware.cs index 895c7b08d..5a3ef41e6 100644 --- a/src/Microsoft.AspNet.Security.Facebook/FacebookAuthenticationMiddleware.cs +++ b/src/Microsoft.AspNet.Security.Facebook/FacebookAuthenticationMiddleware.cs @@ -26,12 +26,13 @@ public class FacebookAuthenticationMiddleware : AuthenticationMiddleware /// /// The next middleware in the application pipeline to invoke + /// + /// /// Configuration options for the middleware public FacebookAuthenticationMiddleware( RequestDelegate next, IDataProtectionProvider dataProtectionProvider, ILoggerFactory loggerFactory, - IServiceProvider services, FacebookAuthenticationOptions options) : base(next, options) { diff --git a/src/Microsoft.AspNet.Security.Google/GoogleAuthenticationDefaults.cs b/src/Microsoft.AspNet.Security.Google/GoogleAuthenticationDefaults.cs new file mode 100644 index 000000000..b13506384 --- /dev/null +++ b/src/Microsoft.AspNet.Security.Google/GoogleAuthenticationDefaults.cs @@ -0,0 +1,10 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +namespace Microsoft.AspNet.Security.Google +{ + public static class GoogleAuthenticationDefaults + { + public const string AuthenticationType = "Google"; + } +} diff --git a/src/Microsoft.AspNet.Security.Google/GoogleAuthenticationExtensions.cs b/src/Microsoft.AspNet.Security.Google/GoogleAuthenticationExtensions.cs new file mode 100644 index 000000000..120373535 --- /dev/null +++ b/src/Microsoft.AspNet.Security.Google/GoogleAuthenticationExtensions.cs @@ -0,0 +1,45 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using Microsoft.AspNet.Security.Google; + +namespace Microsoft.AspNet.Builder +{ + /// + /// Extension methods for using + /// + public static class GoogleAuthenticationExtensions + { + /// + /// Authenticate users using Google OAuth 2.0 + /// + /// The passed to the configure method + /// The google assigned client id + /// The google assigned client secret + /// The updated + public static IBuilder UseGoogleAuthentication([NotNull] this IBuilder app, [NotNull] string clientId, [NotNull] string clientSecret) + { + return app.UseGoogleAuthentication( + new GoogleAuthenticationOptions + { + ClientId = clientId, + ClientSecret = clientSecret + }); + } + + /// + /// Authenticate users using Google OAuth 2.0 + /// + /// The passed to the configure method + /// Middleware configuration options + /// The updated + public static IBuilder UseGoogleAuthentication([NotNull] this IBuilder app, [NotNull] GoogleAuthenticationOptions options) + { + if (string.IsNullOrEmpty(options.SignInAsAuthenticationType)) + { + options.SignInAsAuthenticationType = app.GetDefaultSignInAsAuthenticationType(); + } + return app.UseMiddleware(options); + } + } +} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Security.Google/GoogleAuthenticationHandler.cs b/src/Microsoft.AspNet.Security.Google/GoogleAuthenticationHandler.cs new file mode 100644 index 000000000..fe2a4feab --- /dev/null +++ b/src/Microsoft.AspNet.Security.Google/GoogleAuthenticationHandler.cs @@ -0,0 +1,313 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Collections.Generic; +using System.Net.Http; +using System.Net.Http.Headers; +using System.Security.Claims; +using System.Threading.Tasks; +using Microsoft.AspNet.Http; +using Microsoft.AspNet.Http.Security; +using Microsoft.AspNet.Security.Infrastructure; +using Microsoft.AspNet.WebUtilities; +using Microsoft.Framework.Logging; +using Newtonsoft.Json.Linq; + +namespace Microsoft.AspNet.Security.Google +{ + internal class GoogleAuthenticationHandler : AuthenticationHandler + { + private const string TokenEndpoint = "https://accounts.google.com/o/oauth2/token"; + private const string UserInfoEndpoint = "https://www.googleapis.com/plus/v1/people/me"; + private const string AuthorizeEndpoint = "https://accounts.google.com/o/oauth2/auth"; + + private readonly ILogger _logger; + private readonly HttpClient _httpClient; + + public GoogleAuthenticationHandler(HttpClient httpClient, ILogger logger) + { + _httpClient = httpClient; + _logger = logger; + } + + protected override AuthenticationTicket AuthenticateCore() + { + return AuthenticateCoreAsync().Result; + } + + protected override async Task AuthenticateCoreAsync() + { + AuthenticationProperties properties = null; + + try + { + string code = null; + string state = null; + + IReadableStringCollection query = Request.Query; + IList values = query.GetValues("code"); + if (values != null && values.Count == 1) + { + code = values[0]; + } + values = query.GetValues("state"); + if (values != null && values.Count == 1) + { + state = values[0]; + } + + properties = Options.StateDataFormat.Unprotect(state); + if (properties == null) + { + return null; + } + + // OAuth2 10.12 CSRF + if (!ValidateCorrelationId(properties, _logger)) + { + return new AuthenticationTicket(null, properties); + } + + string requestPrefix = Request.Scheme + "://" + Request.Host; + string redirectUri = requestPrefix + Request.PathBase + Options.CallbackPath; + + // Build up the body for the token request + var body = new List>(); + body.Add(new KeyValuePair("grant_type", "authorization_code")); + body.Add(new KeyValuePair("code", code)); + body.Add(new KeyValuePair("redirect_uri", redirectUri)); + body.Add(new KeyValuePair("client_id", Options.ClientId)); + body.Add(new KeyValuePair("client_secret", Options.ClientSecret)); + + // Request the token + HttpResponseMessage tokenResponse = + await _httpClient.PostAsync(TokenEndpoint, new FormUrlEncodedContent(body)); + tokenResponse.EnsureSuccessStatusCode(); + string text = await tokenResponse.Content.ReadAsStringAsync(); + + // Deserializes the token response + JObject response = JObject.Parse(text); + string accessToken = response.Value("access_token"); + string expires = response.Value("expires_in"); + string refreshToken = response.Value("refresh_token"); + + if (string.IsNullOrWhiteSpace(accessToken)) + { + _logger.WriteWarning("Access token was not found"); + return new AuthenticationTicket(null, properties); + } + + // Get the Google user + HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, UserInfoEndpoint); + request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", accessToken); + HttpResponseMessage graphResponse = await _httpClient.SendAsync(request, Context.RequestAborted); + graphResponse.EnsureSuccessStatusCode(); + text = await graphResponse.Content.ReadAsStringAsync(); + JObject user = JObject.Parse(text); + + var context = new GoogleAuthenticatedContext(Context, user, accessToken, refreshToken, expires); + context.Identity = new ClaimsIdentity( + Options.AuthenticationType, + ClaimsIdentity.DefaultNameClaimType, + ClaimsIdentity.DefaultRoleClaimType); + if (!string.IsNullOrEmpty(context.Id)) + { + context.Identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, context.Id, + ClaimValueTypes.String, Options.AuthenticationType)); + } + if (!string.IsNullOrEmpty(context.GivenName)) + { + context.Identity.AddClaim(new Claim(ClaimTypes.GivenName, context.GivenName, + ClaimValueTypes.String, Options.AuthenticationType)); + } + if (!string.IsNullOrEmpty(context.FamilyName)) + { + context.Identity.AddClaim(new Claim(ClaimTypes.Surname, context.FamilyName, + ClaimValueTypes.String, Options.AuthenticationType)); + } + if (!string.IsNullOrEmpty(context.Name)) + { + context.Identity.AddClaim(new Claim(ClaimTypes.Name, context.Name, ClaimValueTypes.String, + Options.AuthenticationType)); + } + if (!string.IsNullOrEmpty(context.Email)) + { + context.Identity.AddClaim(new Claim(ClaimTypes.Email, context.Email, ClaimValueTypes.String, + Options.AuthenticationType)); + } + + if (!string.IsNullOrEmpty(context.Profile)) + { + context.Identity.AddClaim(new Claim("urn:google:profile", context.Profile, ClaimValueTypes.String, + Options.AuthenticationType)); + } + context.Properties = properties; + + await Options.Notifications.Authenticated(context); + + return new AuthenticationTicket(context.Identity, context.Properties); + } + catch (Exception ex) + { + _logger.WriteError("Authentication failed", ex); + return new AuthenticationTicket(null, properties); + } + } + + protected override void ApplyResponseChallenge() + { + if (Response.StatusCode != 401) + { + return; + } + + // Active middleware should redirect on 401 even if there wasn't an explicit challenge. + if (ChallengeContext == null && Options.AuthenticationMode == AuthenticationMode.Passive) + { + return; + } + + string baseUri = + Request.Scheme + + "://" + + Request.Host + + Request.PathBase; + + string currentUri = + baseUri + + Request.Path + + Request.QueryString; + + string redirectUri = + baseUri + + Options.CallbackPath; + + AuthenticationProperties properties; + if (ChallengeContext == null) + { + properties = new AuthenticationProperties(); + } + else + { + properties = new AuthenticationProperties(ChallengeContext.Properties); + } + if (string.IsNullOrEmpty(properties.RedirectUri)) + { + properties.RedirectUri = currentUri; + } + + // OAuth2 10.12 CSRF + GenerateCorrelationId(properties); + + var queryStrings = new Dictionary(StringComparer.OrdinalIgnoreCase); + queryStrings.Add("response_type", "code"); + queryStrings.Add("client_id", Options.ClientId); + queryStrings.Add("redirect_uri", redirectUri); + + // space separated + string scope = string.Join(" ", Options.Scope); + if (string.IsNullOrEmpty(scope)) + { + // Google OAuth 2.0 asks for non-empty scope. If user didn't set it, set default scope to + // "openid profile email" to get basic user information. + scope = "openid profile email"; + } + AddQueryString(queryStrings, properties, "scope", scope); + + AddQueryString(queryStrings, properties, "access_type", Options.AccessType); + AddQueryString(queryStrings, properties, "approval_prompt"); + AddQueryString(queryStrings, properties, "login_hint"); + + string state = Options.StateDataFormat.Protect(properties); + queryStrings.Add("state", state); + + string authorizationEndpoint = QueryHelpers.AddQueryString(AuthorizeEndpoint, queryStrings); + + var redirectContext = new GoogleApplyRedirectContext( + Context, Options, + properties, authorizationEndpoint); + Options.Notifications.ApplyRedirect(redirectContext); + } + + public override async Task InvokeAsync() + { + return await InvokeReplyPathAsync(); + } + + private async Task InvokeReplyPathAsync() + { + if (Options.CallbackPath.HasValue && Options.CallbackPath == Request.Path) + { + // TODO: error responses + + AuthenticationTicket ticket = await AuthenticateAsync(); + if (ticket == null) + { + _logger.WriteWarning("Invalid return state, unable to redirect."); + Response.StatusCode = 500; + return true; + } + + var context = new GoogleReturnEndpointContext(Context, ticket); + context.SignInAsAuthenticationType = Options.SignInAsAuthenticationType; + context.RedirectUri = ticket.Properties.RedirectUri; + + await Options.Notifications.ReturnEndpoint(context); + + if (context.SignInAsAuthenticationType != null && + context.Identity != null) + { + ClaimsIdentity grantIdentity = context.Identity; + if (!string.Equals(grantIdentity.AuthenticationType, context.SignInAsAuthenticationType, StringComparison.Ordinal)) + { + grantIdentity = new ClaimsIdentity(grantIdentity.Claims, context.SignInAsAuthenticationType, grantIdentity.NameClaimType, grantIdentity.RoleClaimType); + } + Context.Response.SignIn(context.Properties, grantIdentity); + } + + if (!context.IsRequestCompleted && context.RedirectUri != null) + { + string redirectUri = context.RedirectUri; + if (context.Identity == null) + { + // add a redirect hint that sign-in failed in some way + redirectUri = QueryHelpers.AddQueryString(redirectUri, "error", "access_denied"); + } + Response.Redirect(redirectUri); + context.RequestCompleted(); + } + + return context.IsRequestCompleted; + } + return false; + } + + private static void AddQueryString(IDictionary queryStrings, AuthenticationProperties properties, + string name, string defaultValue = null) + { + string value; + if (!properties.Dictionary.TryGetValue(name, out value)) + { + value = defaultValue; + } + else + { + // Remove the parameter from AuthenticationProperties so it won't be serialized to state parameter + properties.Dictionary.Remove(name); + } + + if (value == null) + { + return; + } + + queryStrings[name] = value; + } + + protected override void ApplyResponseGrant() + { + // N/A - No SignIn or SignOut support. + } + } +} diff --git a/src/Microsoft.AspNet.Security.Google/GoogleAuthenticationMiddleware.cs b/src/Microsoft.AspNet.Security.Google/GoogleAuthenticationMiddleware.cs new file mode 100644 index 000000000..15c5c2a79 --- /dev/null +++ b/src/Microsoft.AspNet.Security.Google/GoogleAuthenticationMiddleware.cs @@ -0,0 +1,98 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Diagnostics.CodeAnalysis; +using System.Globalization; +using System.Net.Http; +using Microsoft.AspNet.Builder; +using Microsoft.AspNet.Security.DataHandler; +using Microsoft.AspNet.Security.DataProtection; +using Microsoft.AspNet.Security.Infrastructure; +using Microsoft.Framework.Logging; + +namespace Microsoft.AspNet.Security.Google +{ + /// + /// ASP.NET middleware for authenticating users using Google OAuth 2.0 + /// + [SuppressMessage("Microsoft.Design", "CA1001:TypesThatOwnDisposableFieldsShouldBeDisposable", Justification = "Middleware are not disposable.")] + public class GoogleAuthenticationMiddleware : AuthenticationMiddleware + { + private readonly ILogger _logger; + private readonly HttpClient _httpClient; + + /// + /// Initializes a + /// + /// The next middleware in the HTTP pipeline to invoke + /// + /// + /// Configuration options for the middleware + public GoogleAuthenticationMiddleware( + RequestDelegate next, + IDataProtectionProvider dataProtectionProvider, + ILoggerFactory loggerFactory, + GoogleAuthenticationOptions options) + : base(next, options) + { + if (string.IsNullOrWhiteSpace(Options.ClientId)) + { + throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, Resources.Exception_OptionMustBeProvided, "ClientId")); + } + if (string.IsNullOrWhiteSpace(Options.ClientSecret)) + { + throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, Resources.Exception_OptionMustBeProvided, "ClientSecret")); + } + + _logger = loggerFactory.Create(typeof(GoogleAuthenticationMiddleware).FullName); + + if (Options.Notifications == null) + { + Options.Notifications = new GoogleAuthenticationNotifications(); + } + if (Options.StateDataFormat == null) + { + IDataProtector dataProtector = DataProtectionHelpers.CreateDataProtector(dataProtectionProvider, + typeof(GoogleAuthenticationMiddleware).FullName, options.AuthenticationType, "v1"); + Options.StateDataFormat = new PropertiesDataFormat(dataProtector); + } + + _httpClient = new HttpClient(ResolveHttpMessageHandler(Options)); + _httpClient.Timeout = Options.BackchannelTimeout; + _httpClient.MaxResponseContentBufferSize = 1024 * 1024 * 10; // 10 MB + } + + /// + /// Provides the object for processing authentication-related requests. + /// + /// An configured with the supplied to the constructor. + protected override AuthenticationHandler CreateHandler() + { + return new GoogleAuthenticationHandler(_httpClient, _logger); + } + + [SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Justification = "Managed by caller")] + private static HttpMessageHandler ResolveHttpMessageHandler(GoogleAuthenticationOptions options) + { + HttpMessageHandler handler = options.BackchannelHttpHandler ?? +#if NET45 + new WebRequestHandler(); + // If they provided a validator, apply it or fail. + if (options.BackchannelCertificateValidator != null) + { + // Set the cert validate callback + var webRequestHandler = handler as WebRequestHandler; + if (webRequestHandler == null) + { + throw new InvalidOperationException(Resources.Exception_ValidatorHandlerMismatch); + } + webRequestHandler.ServerCertificateValidationCallback = options.BackchannelCertificateValidator.Validate; + } +#else + new WinHttpHandler(); +#endif + return handler; + } + } +} diff --git a/src/Microsoft.AspNet.Security.Google/GoogleAuthenticationOptions.cs b/src/Microsoft.AspNet.Security.Google/GoogleAuthenticationOptions.cs new file mode 100644 index 000000000..fd7b06999 --- /dev/null +++ b/src/Microsoft.AspNet.Security.Google/GoogleAuthenticationOptions.cs @@ -0,0 +1,110 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Collections.Generic; +using System.Net.Http; +using Microsoft.AspNet.Http; +using Microsoft.AspNet.Http.Security; + +namespace Microsoft.AspNet.Security.Google +{ + /// + /// Configuration options for + /// + public class GoogleAuthenticationOptions : AuthenticationOptions + { + /// + /// Initializes a new + /// + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1303:Do not pass literals as localized parameters", + MessageId = "Microsoft.AspNet.Security.Google.GoogleAuthenticationOptions.set_Caption(System.String)", + Justification = "Not localizable.")] + public GoogleAuthenticationOptions() + : base(GoogleAuthenticationDefaults.AuthenticationType) + { + Caption = GoogleAuthenticationDefaults.AuthenticationType; + CallbackPath = new PathString("/signin-google"); + AuthenticationMode = AuthenticationMode.Passive; + Scope = new List(); + BackchannelTimeout = TimeSpan.FromSeconds(60); + } + + /// + /// Gets or sets the Google-assigned client id + /// + public string ClientId { get; set; } + + /// + /// Gets or sets the Google-assigned client secret + /// + public string ClientSecret { get; set; } +#if NET45 + /// + /// Gets or sets the a pinned certificate validator to use to validate the endpoints used + /// in back channel communications belong to Google. + /// + /// + /// The pinned certificate validator. + /// + /// If this property is null then the default certificate checks are performed, + /// validating the subject name and if the signing chain is a trusted party. + public ICertificateValidator BackchannelCertificateValidator { get; set; } +#endif + /// + /// Gets or sets timeout value in milliseconds for back channel communications with Google. + /// + /// + /// The back channel timeout in milliseconds. + /// + public TimeSpan BackchannelTimeout { get; set; } + + /// + /// The HttpMessageHandler used to communicate with Google. + /// This cannot be set at the same time as BackchannelCertificateValidator unless the value + /// can be downcast to a WebRequestHandler. + /// + public HttpMessageHandler BackchannelHttpHandler { get; set; } + + /// + /// Get or sets the text that the user can display on a sign in user interface. + /// + public string Caption + { + get { return Description.Caption; } + set { Description.Caption = value; } + } + + /// + /// The request path within the application's base path where the user-agent will be returned. + /// The middleware will process this request when it arrives. + /// Default value is "/signin-google". + /// + public PathString CallbackPath { get; set; } + + /// + /// Gets or sets the name of another authentication middleware which will be responsible for actually issuing a user . + /// + public string SignInAsAuthenticationType { get; set; } + + /// + /// Gets or sets the used to handle authentication events. + /// + public IGoogleAuthenticationNotifications Notifications { get; set; } + + /// + /// Gets or sets the type used to secure data handled by the middleware. + /// + public ISecureDataFormat StateDataFormat { get; set; } + + /// + /// A list of permissions to request. + /// + public IList Scope { get; private set; } + + /// + /// access_type. Set to 'offline' to request a refresh token. + /// + public string AccessType { get; set; } + } +} diff --git a/src/Microsoft.AspNet.Security.Google/Microsoft.AspNet.Security.Google.kproj b/src/Microsoft.AspNet.Security.Google/Microsoft.AspNet.Security.Google.kproj new file mode 100644 index 000000000..111093c64 --- /dev/null +++ b/src/Microsoft.AspNet.Security.Google/Microsoft.AspNet.Security.Google.kproj @@ -0,0 +1,28 @@ + + + + 12.0 + $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) + + + + 89bf8535-a849-458e-868a-a68fcf620486 + Library + + + + ConsoleDebugger + + + WebDebugger + + + + + + + + 2.0 + + + \ No newline at end of file diff --git a/src/Microsoft.AspNet.Security.Google/NotNullAttribute.cs b/src/Microsoft.AspNet.Security.Google/NotNullAttribute.cs new file mode 100644 index 000000000..e87e361e4 --- /dev/null +++ b/src/Microsoft.AspNet.Security.Google/NotNullAttribute.cs @@ -0,0 +1,12 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; + +namespace Microsoft.AspNet.Security.Google +{ + [AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false)] + internal sealed class NotNullAttribute : Attribute + { + } +} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Security.Google/Notifications/GoogleApplyRedirectContext.cs b/src/Microsoft.AspNet.Security.Google/Notifications/GoogleApplyRedirectContext.cs new file mode 100644 index 000000000..ac020b563 --- /dev/null +++ b/src/Microsoft.AspNet.Security.Google/Notifications/GoogleApplyRedirectContext.cs @@ -0,0 +1,43 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using Microsoft.AspNet.Http; +using Microsoft.AspNet.Http.Security; +using Microsoft.AspNet.Security.Notifications; + +namespace Microsoft.AspNet.Security.Google +{ + /// + /// Context passed when a Challenge causes a redirect to authorize endpoint in the Google OAuth 2.0 middleware + /// + public class GoogleApplyRedirectContext : BaseContext + { + /// + /// Creates a new context object. + /// + /// The HTTP request context + /// The Google OAuth 2.0 middleware options + /// The authenticaiton properties of the challenge + /// The initial redirect URI + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings", MessageId = "3#", + Justification = "Represents header value")] + public GoogleApplyRedirectContext(HttpContext context, GoogleAuthenticationOptions options, + AuthenticationProperties properties, string redirectUri) + : base(context, options) + { + RedirectUri = redirectUri; + Properties = properties; + } + + /// + /// Gets the URI used for the redirect operation. + /// + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1056:UriPropertiesShouldNotBeStrings", Justification = "Represents header value")] + public string RedirectUri { get; private set; } + + /// + /// Gets the authenticaiton properties of the challenge + /// + public AuthenticationProperties Properties { get; private set; } + } +} diff --git a/src/Microsoft.AspNet.Security.Google/Notifications/GoogleAuthenticatedContext.cs b/src/Microsoft.AspNet.Security.Google/Notifications/GoogleAuthenticatedContext.cs new file mode 100644 index 000000000..ca8996276 --- /dev/null +++ b/src/Microsoft.AspNet.Security.Google/Notifications/GoogleAuthenticatedContext.cs @@ -0,0 +1,158 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Globalization; +using System.Security.Claims; +using Microsoft.AspNet.Http; +using Microsoft.AspNet.Http.Security; +using Microsoft.AspNet.Security.Notifications; +using Newtonsoft.Json.Linq; + +namespace Microsoft.AspNet.Security.Google +{ + /// + /// Contains information about the login session as well as the user . + /// + public class GoogleAuthenticatedContext : BaseContext + { + /// + /// Initializes a + /// + /// The HTTP environment + /// The JSON-serialized Google user info + /// Google OAuth 2.0 access token + /// Goolge OAuth 2.0 refresh token + /// Seconds until expiration + public GoogleAuthenticatedContext(HttpContext context, JObject user, string accessToken, + string refreshToken, string expires) + : base(context) + { + User = user; + AccessToken = accessToken; + RefreshToken = refreshToken; + + int expiresValue; + if (Int32.TryParse(expires, NumberStyles.Integer, CultureInfo.InvariantCulture, out expiresValue)) + { + ExpiresIn = TimeSpan.FromSeconds(expiresValue); + } + + Id = TryGetValue(user, "id"); + Name = TryGetValue(user, "displayName"); + GivenName = TryGetValue(user, "name", "givenName"); + FamilyName = TryGetValue(user, "name", "familyName"); + Profile = TryGetValue(user, "url"); + Email = TryGetFirstValue(user, "emails", "value"); + } + + /// + /// Gets the JSON-serialized user + /// + /// + /// Contains the Google user obtained from the endpoint https://www.googleapis.com/oauth2/v3/userinfo + /// + public JObject User { get; private set; } + + /// + /// Gets the Google access token + /// + public string AccessToken { get; private set; } + + /// + /// Gets the Google refresh token + /// + /// + /// This value is not null only when access_type authorize parameter is offline. + /// + public string RefreshToken { get; private set; } + + /// + /// Gets the Google access token expiration time + /// + public TimeSpan? ExpiresIn { get; set; } + + /// + /// Gets the Google user ID + /// + public string Id { get; private set; } + + /// + /// Gets the user's name + /// + public string Name { get; private set; } + + /// + /// Gets the user's given name + /// + public string GivenName { get; set; } + + /// + /// Gets the user's family name + /// + public string FamilyName { get; set; } + + /// + /// Gets the user's profile link + /// + public string Profile { get; private set; } + + /// + /// Gets the user's email + /// + public string Email { get; private set; } + + /// + /// Gets the representing the user + /// + public ClaimsIdentity Identity { get; set; } + + /// + /// Gets or sets a property bag for common authentication properties + /// + public AuthenticationProperties Properties { get; set; } + + private static string TryGetValue(JObject user, string propertyName) + { + JToken value; + return user.TryGetValue(propertyName, out value) ? value.ToString() : null; + } + + // Get the given subProperty from a property. + private static string TryGetValue(JObject user, string propertyName, string subProperty) + { + JToken value; + if (user.TryGetValue(propertyName, out value)) + { + var subObject = JObject.Parse(value.ToString()); + if (subObject != null && subObject.TryGetValue(subProperty, out value)) + { + return value.ToString(); + } + } + return null; + } + + // Get the given subProperty from a list property. + private static string TryGetFirstValue(JObject user, string propertyName, string subProperty) + { + JToken value; + if (user.TryGetValue(propertyName, out value)) + { + var array = JArray.Parse(value.ToString()); + if (array != null && array.Count > 0) + { + var subObject = JObject.Parse(array.First.ToString()); + if (subObject != null) + { + if (subObject.TryGetValue(subProperty, out value)) + { + return value.ToString(); + } + } + } + } + return null; + } + } +} diff --git a/src/Microsoft.AspNet.Security.Google/Notifications/GoogleAuthenticationNotifications.cs b/src/Microsoft.AspNet.Security.Google/Notifications/GoogleAuthenticationNotifications.cs new file mode 100644 index 000000000..af93619ed --- /dev/null +++ b/src/Microsoft.AspNet.Security.Google/Notifications/GoogleAuthenticationNotifications.cs @@ -0,0 +1,69 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Threading.Tasks; + +namespace Microsoft.AspNet.Security.Google +{ + /// + /// Default implementation. + /// + public class GoogleAuthenticationNotifications : IGoogleAuthenticationNotifications + { + /// + /// Initializes a + /// + public GoogleAuthenticationNotifications() + { + OnAuthenticated = context => Task.FromResult(null); + OnReturnEndpoint = context => Task.FromResult(null); + OnApplyRedirect = context => + context.Response.Redirect(context.RedirectUri); + } + + /// + /// Gets or sets the function that is invoked when the Authenticated method is invoked. + /// + public Func OnAuthenticated { get; set; } + + /// + /// Gets or sets the function that is invoked when the ReturnEndpoint method is invoked. + /// + public Func OnReturnEndpoint { get; set; } + + /// + /// Gets or sets the delegate that is invoked when the ApplyRedirect method is invoked. + /// + public Action OnApplyRedirect { get; set; } + + /// + /// Invoked whenever Google succesfully authenticates a user + /// + /// Contains information about the login session as well as the user . + /// A representing the completed operation. + public virtual Task Authenticated(GoogleAuthenticatedContext context) + { + return OnAuthenticated(context); + } + + /// + /// Invoked prior to the being saved in a local cookie and the browser being redirected to the originally requested URL. + /// + /// Contains context information and authentication ticket of the return endpoint. + /// A representing the completed operation. + public virtual Task ReturnEndpoint(GoogleReturnEndpointContext context) + { + return OnReturnEndpoint(context); + } + + /// + /// Called when a Challenge causes a redirect to authorize endpoint in the Google OAuth 2.0 middleware + /// + /// Contains redirect URI and of the challenge + public virtual void ApplyRedirect(GoogleApplyRedirectContext context) + { + OnApplyRedirect(context); + } + } +} diff --git a/src/Microsoft.AspNet.Security.Google/Notifications/GoogleReturnEndpointContext.cs b/src/Microsoft.AspNet.Security.Google/Notifications/GoogleReturnEndpointContext.cs new file mode 100644 index 000000000..7172455ad --- /dev/null +++ b/src/Microsoft.AspNet.Security.Google/Notifications/GoogleReturnEndpointContext.cs @@ -0,0 +1,26 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using Microsoft.AspNet.Http; +using Microsoft.AspNet.Security.Notifications; + +namespace Microsoft.AspNet.Security.Google +{ + /// + /// Provides context information to middleware notifications. + /// + public class GoogleReturnEndpointContext : ReturnEndpointContext + { + /// + /// Initialize a + /// + /// HTTP environment + /// The authentication ticket + public GoogleReturnEndpointContext( + HttpContext context, + AuthenticationTicket ticket) + : base(context, ticket) + { + } + } +} diff --git a/src/Microsoft.AspNet.Security.Google/Notifications/IGoogleAuthenticationNotifications.cs b/src/Microsoft.AspNet.Security.Google/Notifications/IGoogleAuthenticationNotifications.cs new file mode 100644 index 000000000..7bf9a34ab --- /dev/null +++ b/src/Microsoft.AspNet.Security.Google/Notifications/IGoogleAuthenticationNotifications.cs @@ -0,0 +1,33 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System.Threading.Tasks; + +namespace Microsoft.AspNet.Security.Google +{ + /// + /// Specifies callback methods which the invokes to enable developer control over the authentication process. /> + /// + public interface IGoogleAuthenticationNotifications + { + /// + /// Invoked whenever Google succesfully authenticates a user + /// + /// Contains information about the login session as well as the user . + /// A representing the completed operation. + Task Authenticated(GoogleAuthenticatedContext context); + + /// + /// Invoked prior to the being saved in a local cookie and the browser being redirected to the originally requested URL. + /// + /// Contains context information and authentication ticket of the return endpoint. + /// A representing the completed operation. + Task ReturnEndpoint(GoogleReturnEndpointContext context); + + /// + /// Called when a Challenge causes a redirect to authorize endpoint in the Google OAuth 2.0 middleware + /// + /// Contains redirect URI and of the challenge + void ApplyRedirect(GoogleApplyRedirectContext context); + } +} diff --git a/src/Microsoft.AspNet.Security.Google/Project.json b/src/Microsoft.AspNet.Security.Google/Project.json new file mode 100644 index 000000000..9f19015e3 --- /dev/null +++ b/src/Microsoft.AspNet.Security.Google/Project.json @@ -0,0 +1,44 @@ +{ + "version": "1.0.0-*", + "dependencies": { + "Microsoft.AspNet.Http": "1.0.0-*", + "Microsoft.AspNet.RequestContainer": "1.0.0-*", + "Microsoft.AspNet.Security": "1.0.0-*", + "Microsoft.AspNet.Security.DataProtection": "1.0.0-*", + "Microsoft.AspNet.WebUtilities": "1.0.0-*", + "Microsoft.Framework.Logging": "1.0.0-*", + "Newtonsoft.Json": "5.0.8", + "System.Net.Http": "4.0.0.0" + }, + "frameworks": { + "net45": { + "dependencies": { + "System.Net.Http.WebRequest": "" + } + }, + "k10": { + "dependencies": { + "System.Collections": "4.0.10.0", + "System.ComponentModel": "4.0.0.0", + "System.Console": "4.0.0.0", + "System.Diagnostics.Debug": "4.0.10.0", + "System.Diagnostics.Tools": "4.0.0.0", + "System.Globalization": "4.0.10.0", + "System.IO": "4.0.10.0", + "System.IO.Compression": "4.0.0.0", + "System.Linq": "4.0.0.0", + "System.Net.Http.WinHttpHandler": "4.0.0.0", + "System.Reflection": "4.0.10.0", + "System.Resources.ResourceManager": "4.0.0.0", + "System.Runtime": "4.0.20.0", + "System.Runtime.Extensions": "4.0.10.0", + "System.Runtime.InteropServices": "4.0.20.0", + "System.Security.Claims": "1.0.0-*", + "System.Security.Cryptography.Hashing.Algorithms": "4.0.0.0", + "System.Security.Principal": "4.0.0.0", + "System.Threading": "4.0.0.0", + "System.Threading.Tasks": "4.0.10.0" + } + } + } +} diff --git a/src/Microsoft.AspNet.Security.Google/Resources.Designer.cs b/src/Microsoft.AspNet.Security.Google/Resources.Designer.cs new file mode 100644 index 000000000..235dcbeef --- /dev/null +++ b/src/Microsoft.AspNet.Security.Google/Resources.Designer.cs @@ -0,0 +1,81 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.34003 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace Microsoft.AspNet.Security.Google { + using System; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class Resources { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Resources() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Microsoft.AspNet.Security.Google.Resources", System.Reflection.IntrospectionExtensions.GetTypeInfo(typeof(Resources)).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + + /// + /// Looks up a localized string similar to The '{0}' option must be provided.. + /// + internal static string Exception_OptionMustBeProvided { + get { + return ResourceManager.GetString("Exception_OptionMustBeProvided", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to An ICertificateValidator cannot be specified at the same time as an HttpMessageHandler unless it is a WebRequestHandler.. + /// + internal static string Exception_ValidatorHandlerMismatch { + get { + return ResourceManager.GetString("Exception_ValidatorHandlerMismatch", resourceCulture); + } + } + } +} diff --git a/src/Microsoft.AspNet.Security.Google/Resources.resx b/src/Microsoft.AspNet.Security.Google/Resources.resx new file mode 100644 index 000000000..2a19bea96 --- /dev/null +++ b/src/Microsoft.AspNet.Security.Google/Resources.resx @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + The '{0}' option must be provided. + + + An ICertificateValidator cannot be specified at the same time as an HttpMessageHandler unless it is a WebRequestHandler. + + \ No newline at end of file diff --git a/src/Microsoft.AspNet.Security/Infrastructure/AuthenticationHandler.cs b/src/Microsoft.AspNet.Security/Infrastructure/AuthenticationHandler.cs index 57c1931f9..7970caa3a 100644 --- a/src/Microsoft.AspNet.Security/Infrastructure/AuthenticationHandler.cs +++ b/src/Microsoft.AspNet.Security/Infrastructure/AuthenticationHandler.cs @@ -351,9 +351,6 @@ protected void GenerateCorrelationId([NotNull] AuthenticationProperties properti Response.Cookies.Append(correlationKey, correlationId, cookieOptions); } - [SuppressMessage("Microsoft.Globalization", "CA1303:Do not pass literals as localized parameters", - MessageId = "Microsoft.Owin.Logging.LoggerExtensions.WriteWarning(Microsoft.Owin.Logging.ILogger,System.String,System.String[])", - Justification = "Logging is not Localized")] protected bool ValidateCorrelationId([NotNull] AuthenticationProperties properties, [NotNull] ILogger logger) { string correlationKey = Constants.CorrelationPrefix + BaseOptions.AuthenticationType; diff --git a/test/Microsoft.AspNet.Security.Test/Google/GoogleMiddlewareTests.cs b/test/Microsoft.AspNet.Security.Test/Google/GoogleMiddlewareTests.cs new file mode 100644 index 000000000..9dff1506d --- /dev/null +++ b/test/Microsoft.AspNet.Security.Test/Google/GoogleMiddlewareTests.cs @@ -0,0 +1,570 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Net; +using System.Net.Http; +using System.Security.Claims; +using System.Text; +using System.Threading.Tasks; +using System.Xml; +using System.Xml.Linq; +using Microsoft.AspNet.Builder; +using Microsoft.AspNet.Http; +using Microsoft.AspNet.Http.Security; +using Microsoft.AspNet.Security.Cookies; +using Microsoft.AspNet.TestHost; +using Newtonsoft.Json; +using Shouldly; +using Xunit; + +namespace Microsoft.AspNet.Security.Google +{ + public class GoogleMiddlewareTests + { + private const string CookieAuthenticationType = "Cookie"; + + [Fact] + public async Task ChallengeWillTriggerRedirection() + { + var server = CreateServer(new GoogleAuthenticationOptions() + { + ClientId = "Test Id", + ClientSecret = "Test Secret" + }); + var transaction = await SendAsync(server, "https://example.com/challenge"); + transaction.Response.StatusCode.ShouldBe(HttpStatusCode.Redirect); + var location = transaction.Response.Headers.Location.ToString(); + location.ShouldContain("https://accounts.google.com/o/oauth2/auth?response_type=code"); + location.ShouldContain("&client_id="); + location.ShouldContain("&redirect_uri="); + location.ShouldContain("&scope="); + location.ShouldContain("&state="); + + location.ShouldNotContain("access_type="); + location.ShouldNotContain("approval_prompt="); + location.ShouldNotContain("login_hint="); + } + + [Fact] + public async Task Challenge401WillTriggerRedirection() + { + var server = CreateServer(new GoogleAuthenticationOptions() + { + ClientId = "Test Id", + ClientSecret = "Test Secret", + AuthenticationMode = AuthenticationMode.Active, + }); + var transaction = await SendAsync(server, "https://example.com/401"); + transaction.Response.StatusCode.ShouldBe(HttpStatusCode.Redirect); + var location = transaction.Response.Headers.Location.ToString(); + location.ShouldContain("https://accounts.google.com/o/oauth2/auth?response_type=code"); + location.ShouldContain("&client_id="); + location.ShouldContain("&redirect_uri="); + location.ShouldContain("&scope="); + location.ShouldContain("&state="); + } + + [Fact] + public async Task ChallengeWillSetCorrelationCookie() + { + var server = CreateServer(new GoogleAuthenticationOptions() + { + ClientId = "Test Id", + ClientSecret = "Test Secret" + }); + var transaction = await SendAsync(server, "https://example.com/challenge"); + Console.WriteLine(transaction.SetCookie); + transaction.SetCookie.Single().ShouldContain(".AspNet.Correlation.Google="); + } + + [Fact] + public async Task Challenge401WillSetCorrelationCookie() + { + var server = CreateServer(new GoogleAuthenticationOptions() + { + ClientId = "Test Id", + ClientSecret = "Test Secret", + AuthenticationMode = AuthenticationMode.Active, + }); + var transaction = await SendAsync(server, "https://example.com/401"); + Console.WriteLine(transaction.SetCookie); + transaction.SetCookie.Single().ShouldContain(".AspNet.Correlation.Google="); + } + + [Fact] + public async Task ChallengeWillSetDefaultScope() + { + var server = CreateServer(new GoogleAuthenticationOptions() + { + ClientId = "Test Id", + ClientSecret = "Test Secret" + }); + var transaction = await SendAsync(server, "https://example.com/challenge"); + transaction.Response.StatusCode.ShouldBe(HttpStatusCode.Redirect); + var query = transaction.Response.Headers.Location.Query; + query.ShouldContain("&scope=" + Uri.EscapeDataString("openid profile email")); + } + + [Fact] + public async Task Challenge401WillSetDefaultScope() + { + var server = CreateServer(new GoogleAuthenticationOptions() + { + ClientId = "Test Id", + ClientSecret = "Test Secret", + AuthenticationMode = AuthenticationMode.Active, + }); + var transaction = await SendAsync(server, "https://example.com/401"); + transaction.Response.StatusCode.ShouldBe(HttpStatusCode.Redirect); + var query = transaction.Response.Headers.Location.Query; + query.ShouldContain("&scope=" + Uri.EscapeDataString("openid profile email")); + } + + [Fact] + public async Task ChallengeWillUseOptionsScope() + { + var options = new GoogleAuthenticationOptions() + { + ClientId = "Test Id", + ClientSecret = "Test Secret", + }; + options.Scope.Add("https://www.googleapis.com/auth/plus.login"); + var server = CreateServer(options); + var transaction = await SendAsync(server, "https://example.com/challenge"); + transaction.Response.StatusCode.ShouldBe(HttpStatusCode.Redirect); + var query = transaction.Response.Headers.Location.Query; + query.ShouldContain("&scope=" + Uri.EscapeDataString("https://www.googleapis.com/auth/plus.login")); + } + + [Fact] + public async Task ChallengeWillUseAuthenticationPropertiesAsParameters() + { + var options = new GoogleAuthenticationOptions() + { + ClientId = "Test Id", + ClientSecret = "Test Secret" + }; + var server = CreateServer(options, + context => + { + var req = context.Request; + var res = context.Response; + if (req.Path == new PathString("/challenge2")) + { + res.Challenge(new AuthenticationProperties( + new Dictionary() + { + { "scope", "https://www.googleapis.com/auth/plus.login" }, + { "access_type", "offline" }, + { "approval_prompt", "force" }, + { "login_hint", "test@example.com" } + }), "Google"); + res.StatusCode = 401; + } + + return Task.FromResult(null); + }); + var transaction = await SendAsync(server, "https://example.com/challenge2"); + transaction.Response.StatusCode.ShouldBe(HttpStatusCode.Redirect); + var query = transaction.Response.Headers.Location.Query; + query.ShouldContain("scope=" + Uri.EscapeDataString("https://www.googleapis.com/auth/plus.login")); + query.ShouldContain("access_type=offline"); + query.ShouldContain("approval_prompt=force"); + query.ShouldContain("login_hint=" + Uri.EscapeDataString("test@example.com")); + } + + [Fact] + public async Task ChallengeWillTriggerApplyRedirectEvent() + { + var options = new GoogleAuthenticationOptions() + { + ClientId = "Test Id", + ClientSecret = "Test Secret", + Notifications = new GoogleAuthenticationNotifications + { + OnApplyRedirect = context => + { + context.Response.Redirect(context.RedirectUri + "&custom=test"); + } + } + }; + var server = CreateServer(options); + var transaction = await SendAsync(server, "https://example.com/challenge"); + transaction.Response.StatusCode.ShouldBe(HttpStatusCode.Redirect); + var query = transaction.Response.Headers.Location.Query; + query.ShouldContain("custom=test"); + } + + [Fact] + public async Task ReplyPathWithoutStateQueryStringWillBeRejected() + { + var options = new GoogleAuthenticationOptions() + { + ClientId = "Test Id", + ClientSecret = "Test Secret" + }; + var server = CreateServer(options); + var transaction = await SendAsync(server, "https://example.com/signin-google?code=TestCode"); + transaction.Response.StatusCode.ShouldBe(HttpStatusCode.InternalServerError); + } + + [Fact] + public async Task ReplyPathWillAuthenticateValidAuthorizeCodeAndState() + { + var options = new GoogleAuthenticationOptions() + { + ClientId = "Test Id", + ClientSecret = "Test Secret", + BackchannelHttpHandler = new TestHttpMessageHandler + { + Sender = async req => + { + if (req.RequestUri.AbsoluteUri == "https://accounts.google.com/o/oauth2/token") + { + return await ReturnJsonResponse(new + { + access_token = "Test Access Token", + expire_in = 3600, + token_type = "Bearer" + }); + } + else if (req.RequestUri.GetLeftPart(UriPartial.Path) == "https://www.googleapis.com/plus/v1/people/me") + { + return await ReturnJsonResponse(new + { + id = "Test User ID", + displayName = "Test Name", + name = new + { + familyName = "Test Family Name", + givenName = "Test Given Name" + }, + url = "Profile link", + emails = new[] + { + new + { + value = "Test email", + type = "account" + } + } + }); + } + + return null; + } + } + }; + var server = CreateServer(options); + var properties = new AuthenticationProperties(); + var correlationKey = ".AspNet.Correlation.Google"; + var correlationValue = "TestCorrelationId"; + properties.Dictionary.Add(correlationKey, correlationValue); + properties.RedirectUri = "/me"; + var state = options.StateDataFormat.Protect(properties); + var transaction = await SendAsync(server, + "https://example.com/signin-google?code=TestCode&state=" + Uri.EscapeDataString(state), + correlationKey + "=" + correlationValue); + transaction.Response.StatusCode.ShouldBe(HttpStatusCode.Redirect); + transaction.Response.Headers.Location.ToString().ShouldBe("/me"); + transaction.SetCookie.Count.ShouldBe(2); + transaction.SetCookie[0].ShouldContain(correlationKey); + transaction.SetCookie[1].ShouldContain(".AspNet.Cookie"); + + var authCookie = transaction.AuthenticationCookieValue; + transaction = await SendAsync(server, "https://example.com/me", authCookie); + transaction.Response.StatusCode.ShouldBe(HttpStatusCode.OK); + transaction.FindClaimValue(ClaimTypes.Name).ShouldBe("Test Name"); + transaction.FindClaimValue(ClaimTypes.NameIdentifier).ShouldBe("Test User ID"); + transaction.FindClaimValue(ClaimTypes.GivenName).ShouldBe("Test Given Name"); + transaction.FindClaimValue(ClaimTypes.Surname).ShouldBe("Test Family Name"); + transaction.FindClaimValue(ClaimTypes.Email).ShouldBe("Test email"); + } + + [Fact] + public async Task ReplyPathWillRejectIfCodeIsInvalid() + { + var options = new GoogleAuthenticationOptions() + { + ClientId = "Test Id", + ClientSecret = "Test Secret", + BackchannelHttpHandler = new TestHttpMessageHandler + { + Sender = req => + { + return Task.FromResult(new HttpResponseMessage(HttpStatusCode.BadRequest)); + } + } + }; + var server = CreateServer(options); + var properties = new AuthenticationProperties(); + var correlationKey = ".AspNet.Correlation.Google"; + var correlationValue = "TestCorrelationId"; + properties.Dictionary.Add(correlationKey, correlationValue); + properties.RedirectUri = "/me"; + var state = options.StateDataFormat.Protect(properties); + var transaction = await SendAsync(server, + "https://example.com/signin-google?code=TestCode&state=" + Uri.EscapeDataString(state), + correlationKey + "=" + correlationValue); + transaction.Response.StatusCode.ShouldBe(HttpStatusCode.Redirect); + transaction.Response.Headers.Location.ToString().ShouldContain("error=access_denied"); + } + + [Fact] + public async Task ReplyPathWillRejectIfAccessTokenIsMissing() + { + var options = new GoogleAuthenticationOptions() + { + ClientId = "Test Id", + ClientSecret = "Test Secret", + BackchannelHttpHandler = new TestHttpMessageHandler + { + Sender = async req => + { + return await ReturnJsonResponse(new object()); + } + } + }; + var server = CreateServer(options); + var properties = new AuthenticationProperties(); + var correlationKey = ".AspNet.Correlation.Google"; + var correlationValue = "TestCorrelationId"; + properties.Dictionary.Add(correlationKey, correlationValue); + properties.RedirectUri = "/me"; + var state = options.StateDataFormat.Protect(properties); + var transaction = await SendAsync(server, + "https://example.com/signin-google?code=TestCode&state=" + Uri.EscapeDataString(state), + correlationKey + "=" + correlationValue); + transaction.Response.StatusCode.ShouldBe(HttpStatusCode.Redirect); + transaction.Response.Headers.Location.ToString().ShouldContain("error=access_denied"); + } + + [Fact] + public async Task AuthenticatedEventCanGetRefreshToken() + { + var options = new GoogleAuthenticationOptions() + { + ClientId = "Test Id", + ClientSecret = "Test Secret", + BackchannelHttpHandler = new TestHttpMessageHandler + { + Sender = async req => + { + if (req.RequestUri.AbsoluteUri == "https://accounts.google.com/o/oauth2/token") + { + return await ReturnJsonResponse(new + { + access_token = "Test Access Token", + expire_in = 3600, + token_type = "Bearer", + refresh_token = "Test Refresh Token" + }); + } + else if (req.RequestUri.GetLeftPart(UriPartial.Path) == "https://www.googleapis.com/plus/v1/people/me") + { + return await ReturnJsonResponse(new + { + id = "Test User ID", + displayName = "Test Name", + name = new + { + familyName = "Test Family Name", + givenName = "Test Given Name" + }, + url = "Profile link", + emails = new[] + { + new + { + value = "Test email", + type = "account" + } + } + }); + } + + return null; + } + }, + Notifications = new GoogleAuthenticationNotifications() + { + OnAuthenticated = context => + { + var refreshToken = context.RefreshToken; + context.Identity.AddClaim(new Claim("RefreshToken", refreshToken)); + return Task.FromResult(null); + } + } + }; + var server = CreateServer(options); + var properties = new AuthenticationProperties(); + var correlationKey = ".AspNet.Correlation.Google"; + var correlationValue = "TestCorrelationId"; + properties.Dictionary.Add(correlationKey, correlationValue); + properties.RedirectUri = "/me"; + var state = options.StateDataFormat.Protect(properties); + var transaction = await SendAsync(server, + "https://example.com/signin-google?code=TestCode&state=" + Uri.EscapeDataString(state), + correlationKey + "=" + correlationValue); + transaction.Response.StatusCode.ShouldBe(HttpStatusCode.Redirect); + transaction.Response.Headers.Location.ToString().ShouldBe("/me"); + transaction.SetCookie.Count.ShouldBe(2); + transaction.SetCookie[0].ShouldContain(correlationKey); + transaction.SetCookie[1].ShouldContain(".AspNet.Cookie"); + + var authCookie = transaction.AuthenticationCookieValue; + transaction = await SendAsync(server, "https://example.com/me", authCookie); + transaction.Response.StatusCode.ShouldBe(HttpStatusCode.OK); + transaction.FindClaimValue("RefreshToken").ShouldBe("Test Refresh Token"); + } + + private static async Task ReturnJsonResponse(object content) + { + var res = new HttpResponseMessage(HttpStatusCode.OK); + var text = await JsonConvert.SerializeObjectAsync(content); + res.Content = new StringContent(text, Encoding.UTF8, "application/json"); + return res; + } + + private static async Task SendAsync(TestServer server, string uri, string cookieHeader = null) + { + var request = new HttpRequestMessage(HttpMethod.Get, uri); + if (!string.IsNullOrEmpty(cookieHeader)) + { + request.Headers.Add("Cookie", cookieHeader); + } + var transaction = new Transaction + { + Request = request, + Response = await server.CreateClient().SendAsync(request), + }; + if (transaction.Response.Headers.Contains("Set-Cookie")) + { + transaction.SetCookie = transaction.Response.Headers.GetValues("Set-Cookie").ToList(); + } + transaction.ResponseText = await transaction.Response.Content.ReadAsStringAsync(); + + if (transaction.Response.Content != null && + transaction.Response.Content.Headers.ContentType != null && + transaction.Response.Content.Headers.ContentType.MediaType == "text/xml") + { + transaction.ResponseElement = XElement.Parse(transaction.ResponseText); + } + return transaction; + } + + private static TestServer CreateServer(GoogleAuthenticationOptions options, Func testpath = null) + { + return TestServer.Create(app => + { + app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationType); + app.UseCookieAuthentication(new CookieAuthenticationOptions() + { + AuthenticationType = CookieAuthenticationType + }); + app.UseGoogleAuthentication(options); + app.Use(async (context, next) => + { + var req = context.Request; + var res = context.Response; + if (req.Path == new PathString("/challenge")) + { + res.Challenge("Google"); + res.StatusCode = 401; + } + else if (req.Path == new PathString("/me")) + { + Describe(res, (ClaimsIdentity)context.User.Identity); + } + else if (req.Path == new PathString("/401")) + { + res.StatusCode = 401; + } + else if (testpath != null) + { + await testpath(context); + } + else + { + await next(); + } + }); + }); + } + + private static void Describe(HttpResponse res, ClaimsIdentity identity) + { + res.StatusCode = 200; + res.ContentType = "text/xml"; + var xml = new XElement("xml"); + if (identity != null) + { + xml.Add(identity.Claims.Select(claim => new XElement("claim", new XAttribute("type", claim.Type), new XAttribute("value", claim.Value)))); + } + using (var memory = new MemoryStream()) + { + using (var writer = new XmlTextWriter(memory, Encoding.UTF8)) + { + xml.WriteTo(writer); + } + res.Body.Write(memory.ToArray(), 0, memory.ToArray().Length); + } + } + + private class TestHttpMessageHandler : HttpMessageHandler + { + public Func> Sender { get; set; } + + protected override async Task SendAsync(HttpRequestMessage request, System.Threading.CancellationToken cancellationToken) + { + if (Sender != null) + { + return await Sender(request); + } + + return null; + } + } + + private class Transaction + { + public HttpRequestMessage Request { get; set; } + public HttpResponseMessage Response { get; set; } + + public IList SetCookie { get; set; } + + public string ResponseText { get; set; } + public XElement ResponseElement { get; set; } + + public string AuthenticationCookieValue + { + get + { + if (SetCookie != null && SetCookie.Count > 0) + { + var authCookie = SetCookie.SingleOrDefault(c => c.Contains(".AspNet.Cookie=")); + if (authCookie != null) + { + return authCookie.Substring(0, authCookie.IndexOf(';')); + } + } + + return null; + } + } + + public string FindClaimValue(string claimType) + { + XElement claim = ResponseElement.Elements("claim").SingleOrDefault(elt => elt.Attribute("type").Value == claimType); + if (claim == null) + { + return null; + } + return claim.Attribute("value").Value; + } + } + } +} diff --git a/test/Microsoft.AspNet.Security.Test/project.json b/test/Microsoft.AspNet.Security.Test/project.json index d45c84b1f..542d5ee25 100644 --- a/test/Microsoft.AspNet.Security.Test/project.json +++ b/test/Microsoft.AspNet.Security.Test/project.json @@ -4,9 +4,10 @@ }, "dependencies": { "Microsoft.AspNet.Http": "1.0.0-*", - "Microsoft.AspNet.Security" : "", - "Microsoft.AspNet.Security.Cookies" : "", - "Microsoft.AspNet.Security.Facebook" : "", + "Microsoft.AspNet.Security" : "1.0.0-*", + "Microsoft.AspNet.Security.Cookies" : "1.0.0-*", + "Microsoft.AspNet.Security.Facebook" : "1.0.0-*", + "Microsoft.AspNet.Security.Google" : "1.0.0-*", "Microsoft.AspNet.TestHost": "1.0.0-*", "Microsoft.Framework.DependencyInjection": "1.0.0-*", "System.Net.Http": "4.0.0.0", From b9eb7ba28210528d1af66c377c967644ac582716 Mon Sep 17 00:00:00 2001 From: Chris Ross Date: Mon, 25 Aug 2014 13:50:34 -0700 Subject: [PATCH 035/216] #38 - Port the Twitter middleware from katana --- Security.sln | 13 + samples/SocialSample/Project.json | 1 + samples/SocialSample/Startup.cs | 7 + .../Messages/AccessToken.cs | 21 + .../Messages/RequestToken.cs | 30 ++ .../Messages/RequestTokenSerializer.cs | 93 +++++ .../Messages/Serializers.cs | 23 ++ .../Microsoft.AspNet.Security.Twitter.kproj | 28 ++ .../NotNullAttribute.cs | 12 + .../ITwitterAuthenticationNotifications.cs | 33 ++ .../TwitterApplyRedirectContext.cs | 40 ++ .../TwitterAuthenticatedContext.cs | 68 ++++ .../TwitterAuthenticationNotifications.cs | 68 ++++ .../TwitterReturnEndpointContext.cs | 26 ++ .../Project.json | 44 ++ .../Resources.Designer.cs | 81 ++++ .../Resources.resx | 126 ++++++ .../TwitterAuthenticationDefaults.cs | 10 + .../TwitterAuthenticationExtensions.cs | 45 ++ .../TwitterAuthenticationHandler.cs | 384 ++++++++++++++++++ .../TwitterAuthenticationMiddleware.cs | 106 +++++ .../TwitterAuthenticationOptions.cs | 107 +++++ .../DataHandler/Serializer/DataSerializers.cs | 4 +- .../Twitter/TwitterMiddlewareTests.cs | 183 +++++++++ .../project.json | 1 + 25 files changed, 1552 insertions(+), 2 deletions(-) create mode 100644 src/Microsoft.AspNet.Security.Twitter/Messages/AccessToken.cs create mode 100644 src/Microsoft.AspNet.Security.Twitter/Messages/RequestToken.cs create mode 100644 src/Microsoft.AspNet.Security.Twitter/Messages/RequestTokenSerializer.cs create mode 100644 src/Microsoft.AspNet.Security.Twitter/Messages/Serializers.cs create mode 100644 src/Microsoft.AspNet.Security.Twitter/Microsoft.AspNet.Security.Twitter.kproj create mode 100644 src/Microsoft.AspNet.Security.Twitter/NotNullAttribute.cs create mode 100644 src/Microsoft.AspNet.Security.Twitter/Notifications/ITwitterAuthenticationNotifications.cs create mode 100644 src/Microsoft.AspNet.Security.Twitter/Notifications/TwitterApplyRedirectContext.cs create mode 100644 src/Microsoft.AspNet.Security.Twitter/Notifications/TwitterAuthenticatedContext.cs create mode 100644 src/Microsoft.AspNet.Security.Twitter/Notifications/TwitterAuthenticationNotifications.cs create mode 100644 src/Microsoft.AspNet.Security.Twitter/Notifications/TwitterReturnEndpointContext.cs create mode 100644 src/Microsoft.AspNet.Security.Twitter/Project.json create mode 100644 src/Microsoft.AspNet.Security.Twitter/Resources.Designer.cs create mode 100644 src/Microsoft.AspNet.Security.Twitter/Resources.resx create mode 100644 src/Microsoft.AspNet.Security.Twitter/TwitterAuthenticationDefaults.cs create mode 100644 src/Microsoft.AspNet.Security.Twitter/TwitterAuthenticationExtensions.cs create mode 100644 src/Microsoft.AspNet.Security.Twitter/TwitterAuthenticationHandler.cs create mode 100644 src/Microsoft.AspNet.Security.Twitter/TwitterAuthenticationMiddleware.cs create mode 100644 src/Microsoft.AspNet.Security.Twitter/TwitterAuthenticationOptions.cs create mode 100644 test/Microsoft.AspNet.Security.Test/Twitter/TwitterMiddlewareTests.cs diff --git a/Security.sln b/Security.sln index 5ae54786f..976cfd4ea 100644 --- a/Security.sln +++ b/Security.sln @@ -28,6 +28,8 @@ Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "SocialSample", "samples\Soc EndProject Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNet.Security.Google", "src\Microsoft.AspNet.Security.Google\Microsoft.AspNet.Security.Google.kproj", "{89BF8535-A849-458E-868A-A68FCF620486}" EndProject +Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNet.Security.Twitter", "src\Microsoft.AspNet.Security.Twitter\Microsoft.AspNet.Security.Twitter.kproj", "{C96B77EA-4078-4C31-BDB2-878F11C5E061}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -108,6 +110,16 @@ Global {89BF8535-A849-458E-868A-A68FCF620486}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU {89BF8535-A849-458E-868A-A68FCF620486}.Release|Mixed Platforms.Build.0 = Release|Any CPU {89BF8535-A849-458E-868A-A68FCF620486}.Release|x86.ActiveCfg = Release|Any CPU + {C96B77EA-4078-4C31-BDB2-878F11C5E061}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C96B77EA-4078-4C31-BDB2-878F11C5E061}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C96B77EA-4078-4C31-BDB2-878F11C5E061}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {C96B77EA-4078-4C31-BDB2-878F11C5E061}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {C96B77EA-4078-4C31-BDB2-878F11C5E061}.Debug|x86.ActiveCfg = Debug|Any CPU + {C96B77EA-4078-4C31-BDB2-878F11C5E061}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C96B77EA-4078-4C31-BDB2-878F11C5E061}.Release|Any CPU.Build.0 = Release|Any CPU + {C96B77EA-4078-4C31-BDB2-878F11C5E061}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {C96B77EA-4078-4C31-BDB2-878F11C5E061}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {C96B77EA-4078-4C31-BDB2-878F11C5E061}.Release|x86.ActiveCfg = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -120,5 +132,6 @@ Global {3984651C-FD44-4394-8793-3D14EE348C04} = {4D2B6A51-2F9F-44F5-8131-EA5CAC053652} {8C73D216-332D-41D8-BFD0-45BC4BC36552} = {F8C0AA27-F3FB-4286-8E4C-47EF86B539FF} {89BF8535-A849-458E-868A-A68FCF620486} = {4D2B6A51-2F9F-44F5-8131-EA5CAC053652} + {C96B77EA-4078-4C31-BDB2-878F11C5E061} = {4D2B6A51-2F9F-44F5-8131-EA5CAC053652} EndGlobalSection EndGlobal diff --git a/samples/SocialSample/Project.json b/samples/SocialSample/Project.json index 525d9dd6a..1af9beef0 100644 --- a/samples/SocialSample/Project.json +++ b/samples/SocialSample/Project.json @@ -7,6 +7,7 @@ "Microsoft.AspNet.Security.Cookies": "1.0.0-*", "Microsoft.AspNet.Security.Facebook": "1.0.0-*", "Microsoft.AspNet.Security.Google": "1.0.0-*", + "Microsoft.AspNet.Security.Twitter": "1.0.0-*", "Microsoft.AspNet.Server.WebListener": "1.0.0-*", "Microsoft.Framework.DependencyInjection": "1.0.0-*" }, diff --git a/samples/SocialSample/Startup.cs b/samples/SocialSample/Startup.cs index 68dd967e4..bc2e967b3 100644 --- a/samples/SocialSample/Startup.cs +++ b/samples/SocialSample/Startup.cs @@ -4,6 +4,7 @@ using Microsoft.AspNet.Security.Cookies; using Microsoft.AspNet.Security.Facebook; using Microsoft.AspNet.Security.Google; +using Microsoft.AspNet.Security.Twitter; namespace CookieSample { @@ -32,6 +33,12 @@ public void Configure(IBuilder app) ClientSecret = "n2Q-GEw9RQjzcRbU3qhfTj8f", }); + app.UseTwitterAuthentication(new TwitterAuthenticationOptions() + { + ConsumerKey = "6XaCTaLbMqfj6ww3zvZ5g", + ConsumerSecret = "Il2eFzGIrYhz6BWjYhVXBPQSfZuS4xoHpSSyD9PI", + }); + // Choose an authentication type app.Map("/login", signoutApp => { diff --git a/src/Microsoft.AspNet.Security.Twitter/Messages/AccessToken.cs b/src/Microsoft.AspNet.Security.Twitter/Messages/AccessToken.cs new file mode 100644 index 000000000..f935da72a --- /dev/null +++ b/src/Microsoft.AspNet.Security.Twitter/Messages/AccessToken.cs @@ -0,0 +1,21 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +namespace Microsoft.AspNet.Security.Twitter.Messages +{ + /// + /// The Twitter access token retrieved from the access token endpoint. + /// + public class AccessToken : RequestToken + { + /// + /// Gets or sets the Twitter User ID. + /// + public string UserId { get; set; } + + /// + /// Gets or sets the Twitter screen name. + /// + public string ScreenName { get; set; } + } +} diff --git a/src/Microsoft.AspNet.Security.Twitter/Messages/RequestToken.cs b/src/Microsoft.AspNet.Security.Twitter/Messages/RequestToken.cs new file mode 100644 index 000000000..f801e555f --- /dev/null +++ b/src/Microsoft.AspNet.Security.Twitter/Messages/RequestToken.cs @@ -0,0 +1,30 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using Microsoft.AspNet.Http.Security; + +namespace Microsoft.AspNet.Security.Twitter.Messages +{ + /// + /// The Twitter request token obtained from the request token endpoint. + /// + public class RequestToken + { + /// + /// Gets or sets the Twitter request token. + /// + public string Token { get; set; } + + /// + /// Gets or sets the Twitter token secret. + /// + public string TokenSecret { get; set; } + + public bool CallbackConfirmed { get; set; } + + /// + /// Gets or sets a property bag for common authentication properties. + /// + public AuthenticationProperties Properties { get; set; } + } +} diff --git a/src/Microsoft.AspNet.Security.Twitter/Messages/RequestTokenSerializer.cs b/src/Microsoft.AspNet.Security.Twitter/Messages/RequestTokenSerializer.cs new file mode 100644 index 000000000..725dcc341 --- /dev/null +++ b/src/Microsoft.AspNet.Security.Twitter/Messages/RequestTokenSerializer.cs @@ -0,0 +1,93 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Diagnostics.CodeAnalysis; +using System.IO; +using Microsoft.AspNet.Http.Security; +using Microsoft.AspNet.Security.DataHandler.Serializer; + +namespace Microsoft.AspNet.Security.Twitter.Messages +{ + /// + /// Serializes and deserializes Twitter request and access tokens so that they can be used by other application components. + /// + public class RequestTokenSerializer : IDataSerializer + { + private const int FormatVersion = 1; + + /// + /// Serialize a request token. + /// + /// The token to serialize + /// A byte array containing the serialized token + [SuppressMessage("Microsoft.Usage", "CA2202:Do not dispose objects multiple times", Justification = "Dispose is idempotent")] + public virtual byte[] Serialize(RequestToken model) + { + using (var memory = new MemoryStream()) + { + using (var writer = new BinaryWriter(memory)) + { + Write(writer, model); + writer.Flush(); + return memory.ToArray(); + } + } + } + + /// + /// Deserializes a request token. + /// + /// A byte array containing the serialized token + /// The Twitter request token + [SuppressMessage("Microsoft.Usage", "CA2202:Do not dispose objects multiple times", Justification = "Dispose is idempotent")] + public virtual RequestToken Deserialize(byte[] data) + { + using (var memory = new MemoryStream(data)) + { + using (var reader = new BinaryReader(memory)) + { + return Read(reader); + } + } + } + + /// + /// Writes a Twitter request token as a series of bytes. Used by the method. + /// + /// The writer to use in writing the token + /// The token to write + public static void Write([NotNull] BinaryWriter writer, [NotNull] RequestToken token) + { + writer.Write(FormatVersion); + writer.Write(token.Token); + writer.Write(token.TokenSecret); + writer.Write(token.CallbackConfirmed); + PropertiesSerializer.Write(writer, token.Properties); + } + + /// + /// Reads a Twitter request token from a series of bytes. Used by the method. + /// + /// The reader to use in reading the token bytes + /// The token + public static RequestToken Read([NotNull] BinaryReader reader) + { + if (reader.ReadInt32() != FormatVersion) + { + return null; + } + + string token = reader.ReadString(); + string tokenSecret = reader.ReadString(); + bool callbackConfirmed = reader.ReadBoolean(); + AuthenticationProperties properties = PropertiesSerializer.Read(reader); + if (properties == null) + { + return null; + } + + return new RequestToken { Token = token, TokenSecret = tokenSecret, CallbackConfirmed = callbackConfirmed, Properties = properties }; + } + } +} diff --git a/src/Microsoft.AspNet.Security.Twitter/Messages/Serializers.cs b/src/Microsoft.AspNet.Security.Twitter/Messages/Serializers.cs new file mode 100644 index 000000000..3d2e1a458 --- /dev/null +++ b/src/Microsoft.AspNet.Security.Twitter/Messages/Serializers.cs @@ -0,0 +1,23 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using Microsoft.AspNet.Security.DataHandler.Serializer; + +namespace Microsoft.AspNet.Security.Twitter.Messages +{ + /// + /// Provides access to a request token serializer. + /// + public static class Serializers + { + static Serializers() + { + RequestToken = new RequestTokenSerializer(); + } + + /// + /// Gets or sets a statically-avaliable serializer object. The value for this property will be by default. + /// + public static IDataSerializer RequestToken { get; private set; } + } +} diff --git a/src/Microsoft.AspNet.Security.Twitter/Microsoft.AspNet.Security.Twitter.kproj b/src/Microsoft.AspNet.Security.Twitter/Microsoft.AspNet.Security.Twitter.kproj new file mode 100644 index 000000000..48dfc3069 --- /dev/null +++ b/src/Microsoft.AspNet.Security.Twitter/Microsoft.AspNet.Security.Twitter.kproj @@ -0,0 +1,28 @@ + + + + 12.0 + $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) + + + + c96b77ea-4078-4c31-bdb2-878f11c5e061 + Library + + + + ConsoleDebugger + + + WebDebugger + + + + + + + + 2.0 + + + \ No newline at end of file diff --git a/src/Microsoft.AspNet.Security.Twitter/NotNullAttribute.cs b/src/Microsoft.AspNet.Security.Twitter/NotNullAttribute.cs new file mode 100644 index 000000000..0d6e98224 --- /dev/null +++ b/src/Microsoft.AspNet.Security.Twitter/NotNullAttribute.cs @@ -0,0 +1,12 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; + +namespace Microsoft.AspNet.Security.Twitter +{ + [AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false)] + internal sealed class NotNullAttribute : Attribute + { + } +} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Security.Twitter/Notifications/ITwitterAuthenticationNotifications.cs b/src/Microsoft.AspNet.Security.Twitter/Notifications/ITwitterAuthenticationNotifications.cs new file mode 100644 index 000000000..55fd54892 --- /dev/null +++ b/src/Microsoft.AspNet.Security.Twitter/Notifications/ITwitterAuthenticationNotifications.cs @@ -0,0 +1,33 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System.Threading.Tasks; + +namespace Microsoft.AspNet.Security.Twitter +{ + /// + /// Specifies callback methods which the invokes to enable developer control over the authentication process. /> + /// + public interface ITwitterAuthenticationNotifications + { + /// + /// Invoked whenever Twitter succesfully authenticates a user + /// + /// Contains information about the login session as well as the user . + /// A representing the completed operation. + Task Authenticated(TwitterAuthenticatedContext context); + + /// + /// Invoked prior to the being saved in a local cookie and the browser being redirected to the originally requested URL. + /// + /// + /// A representing the completed operation. + Task ReturnEndpoint(TwitterReturnEndpointContext context); + + /// + /// Called when a Challenge causes a redirect to authorize endpoint in the Twitter middleware + /// + /// Contains redirect URI and of the challenge + void ApplyRedirect(TwitterApplyRedirectContext context); + } +} diff --git a/src/Microsoft.AspNet.Security.Twitter/Notifications/TwitterApplyRedirectContext.cs b/src/Microsoft.AspNet.Security.Twitter/Notifications/TwitterApplyRedirectContext.cs new file mode 100644 index 000000000..3d5ab80ff --- /dev/null +++ b/src/Microsoft.AspNet.Security.Twitter/Notifications/TwitterApplyRedirectContext.cs @@ -0,0 +1,40 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using Microsoft.AspNet.Http; +using Microsoft.AspNet.Http.Security; +using Microsoft.AspNet.Security.Notifications; + +namespace Microsoft.AspNet.Security.Twitter +{ + /// + /// Context passed when a Challenge causes a redirect to authorize endpoint in the Twitter middleware + /// + public class TwitterApplyRedirectContext : BaseContext + { + /// + /// Creates a new context object. + /// + /// The HTTP request context + /// The Facebook middleware options + /// The authenticaiton properties of the challenge + /// The initial redirect URI + public TwitterApplyRedirectContext(HttpContext context, TwitterAuthenticationOptions options, + AuthenticationProperties properties, string redirectUri) + : base(context, options) + { + RedirectUri = redirectUri; + Properties = properties; + } + + /// + /// Gets the URI used for the redirect operation. + /// + public string RedirectUri { get; private set; } + + /// + /// Gets the authenticaiton properties of the challenge + /// + public AuthenticationProperties Properties { get; private set; } + } +} diff --git a/src/Microsoft.AspNet.Security.Twitter/Notifications/TwitterAuthenticatedContext.cs b/src/Microsoft.AspNet.Security.Twitter/Notifications/TwitterAuthenticatedContext.cs new file mode 100644 index 000000000..0c050d9e8 --- /dev/null +++ b/src/Microsoft.AspNet.Security.Twitter/Notifications/TwitterAuthenticatedContext.cs @@ -0,0 +1,68 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System.Security.Claims; +using Microsoft.AspNet.Http; +using Microsoft.AspNet.Http.Security; +using Microsoft.AspNet.Security.Notifications; + +namespace Microsoft.AspNet.Security.Twitter +{ + /// + /// Contains information about the login session as well as the user . + /// + public class TwitterAuthenticatedContext : BaseContext + { + /// + /// Initializes a + /// + /// The HTTP environment + /// Twitter user ID + /// Twitter screen name + /// Twitter access token + /// Twitter access token secret + public TwitterAuthenticatedContext( + HttpContext context, + string userId, + string screenName, + string accessToken, + string accessTokenSecret) + : base(context) + { + UserId = userId; + ScreenName = screenName; + AccessToken = accessToken; + AccessTokenSecret = accessTokenSecret; + } + + /// + /// Gets the Twitter user ID + /// + public string UserId { get; private set; } + + /// + /// Gets the Twitter screen name + /// + public string ScreenName { get; private set; } + + /// + /// Gets the Twitter access token + /// + public string AccessToken { get; private set; } + + /// + /// Gets the Twitter access token secret + /// + public string AccessTokenSecret { get; private set; } + + /// + /// Gets the representing the user + /// + public ClaimsIdentity Identity { get; set; } + + /// + /// Gets or sets a property bag for common authentication properties + /// + public AuthenticationProperties Properties { get; set; } + } +} diff --git a/src/Microsoft.AspNet.Security.Twitter/Notifications/TwitterAuthenticationNotifications.cs b/src/Microsoft.AspNet.Security.Twitter/Notifications/TwitterAuthenticationNotifications.cs new file mode 100644 index 000000000..2c6ff19d5 --- /dev/null +++ b/src/Microsoft.AspNet.Security.Twitter/Notifications/TwitterAuthenticationNotifications.cs @@ -0,0 +1,68 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Threading.Tasks; + +namespace Microsoft.AspNet.Security.Twitter +{ + /// + /// Default implementation. + /// + public class TwitterAuthenticationNotifications : ITwitterAuthenticationNotifications + { + /// + /// Initializes a + /// + public TwitterAuthenticationNotifications() + { + OnAuthenticated = context => Task.FromResult(null); + OnReturnEndpoint = context => Task.FromResult(null); + OnApplyRedirect = context => context.Response.Redirect(context.RedirectUri); + } + + /// + /// Gets or sets the function that is invoked when the Authenticated method is invoked. + /// + public Func OnAuthenticated { get; set; } + + /// + /// Gets or sets the function that is invoked when the ReturnEndpoint method is invoked. + /// + public Func OnReturnEndpoint { get; set; } + + /// + /// Gets or sets the delegate that is invoked when the ApplyRedirect method is invoked. + /// + public Action OnApplyRedirect { get; set; } + + /// + /// Invoked whenever Twitter succesfully authenticates a user + /// + /// Contains information about the login session as well as the user . + /// A representing the completed operation. + public virtual Task Authenticated(TwitterAuthenticatedContext context) + { + return OnAuthenticated(context); + } + + /// + /// Invoked prior to the being saved in a local cookie and the browser being redirected to the originally requested URL. + /// + /// + /// A representing the completed operation. + public virtual Task ReturnEndpoint(TwitterReturnEndpointContext context) + { + return OnReturnEndpoint(context); + } + + /// + /// Called when a Challenge causes a redirect to authorize endpoint in the Twitter middleware + /// + /// Contains redirect URI and of the challenge + public virtual void ApplyRedirect(TwitterApplyRedirectContext context) + { + OnApplyRedirect(context); + } + } +} diff --git a/src/Microsoft.AspNet.Security.Twitter/Notifications/TwitterReturnEndpointContext.cs b/src/Microsoft.AspNet.Security.Twitter/Notifications/TwitterReturnEndpointContext.cs new file mode 100644 index 000000000..e420b5d1f --- /dev/null +++ b/src/Microsoft.AspNet.Security.Twitter/Notifications/TwitterReturnEndpointContext.cs @@ -0,0 +1,26 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using Microsoft.AspNet.Http; +using Microsoft.AspNet.Security.Notifications; + +namespace Microsoft.AspNet.Security.Twitter +{ + /// + /// Provides context information to middleware providers. + /// + public class TwitterReturnEndpointContext : ReturnEndpointContext + { + /// + /// Initializes a new . + /// + /// HTTP environment + /// The authentication ticket + public TwitterReturnEndpointContext( + HttpContext context, + AuthenticationTicket ticket) + : base(context, ticket) + { + } + } +} diff --git a/src/Microsoft.AspNet.Security.Twitter/Project.json b/src/Microsoft.AspNet.Security.Twitter/Project.json new file mode 100644 index 000000000..9f19015e3 --- /dev/null +++ b/src/Microsoft.AspNet.Security.Twitter/Project.json @@ -0,0 +1,44 @@ +{ + "version": "1.0.0-*", + "dependencies": { + "Microsoft.AspNet.Http": "1.0.0-*", + "Microsoft.AspNet.RequestContainer": "1.0.0-*", + "Microsoft.AspNet.Security": "1.0.0-*", + "Microsoft.AspNet.Security.DataProtection": "1.0.0-*", + "Microsoft.AspNet.WebUtilities": "1.0.0-*", + "Microsoft.Framework.Logging": "1.0.0-*", + "Newtonsoft.Json": "5.0.8", + "System.Net.Http": "4.0.0.0" + }, + "frameworks": { + "net45": { + "dependencies": { + "System.Net.Http.WebRequest": "" + } + }, + "k10": { + "dependencies": { + "System.Collections": "4.0.10.0", + "System.ComponentModel": "4.0.0.0", + "System.Console": "4.0.0.0", + "System.Diagnostics.Debug": "4.0.10.0", + "System.Diagnostics.Tools": "4.0.0.0", + "System.Globalization": "4.0.10.0", + "System.IO": "4.0.10.0", + "System.IO.Compression": "4.0.0.0", + "System.Linq": "4.0.0.0", + "System.Net.Http.WinHttpHandler": "4.0.0.0", + "System.Reflection": "4.0.10.0", + "System.Resources.ResourceManager": "4.0.0.0", + "System.Runtime": "4.0.20.0", + "System.Runtime.Extensions": "4.0.10.0", + "System.Runtime.InteropServices": "4.0.20.0", + "System.Security.Claims": "1.0.0-*", + "System.Security.Cryptography.Hashing.Algorithms": "4.0.0.0", + "System.Security.Principal": "4.0.0.0", + "System.Threading": "4.0.0.0", + "System.Threading.Tasks": "4.0.10.0" + } + } + } +} diff --git a/src/Microsoft.AspNet.Security.Twitter/Resources.Designer.cs b/src/Microsoft.AspNet.Security.Twitter/Resources.Designer.cs new file mode 100644 index 000000000..deda3cc77 --- /dev/null +++ b/src/Microsoft.AspNet.Security.Twitter/Resources.Designer.cs @@ -0,0 +1,81 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.32559 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace Microsoft.AspNet.Security.Twitter { + using System; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class Resources { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Resources() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Microsoft.AspNet.Security.Twitter.Resources", System.Reflection.IntrospectionExtensions.GetTypeInfo(typeof(Resources)).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + + /// + /// Looks up a localized string similar to The '{0}' option must be provided.. + /// + internal static string Exception_OptionMustBeProvided { + get { + return ResourceManager.GetString("Exception_OptionMustBeProvided", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to An ICertificateValidator cannot be specified at the same time as an HttpMessageHandler unless it is a WebRequestHandler.. + /// + internal static string Exception_ValidatorHandlerMismatch { + get { + return ResourceManager.GetString("Exception_ValidatorHandlerMismatch", resourceCulture); + } + } + } +} diff --git a/src/Microsoft.AspNet.Security.Twitter/Resources.resx b/src/Microsoft.AspNet.Security.Twitter/Resources.resx new file mode 100644 index 000000000..2a19bea96 --- /dev/null +++ b/src/Microsoft.AspNet.Security.Twitter/Resources.resx @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + The '{0}' option must be provided. + + + An ICertificateValidator cannot be specified at the same time as an HttpMessageHandler unless it is a WebRequestHandler. + + \ No newline at end of file diff --git a/src/Microsoft.AspNet.Security.Twitter/TwitterAuthenticationDefaults.cs b/src/Microsoft.AspNet.Security.Twitter/TwitterAuthenticationDefaults.cs new file mode 100644 index 000000000..1f29a04b1 --- /dev/null +++ b/src/Microsoft.AspNet.Security.Twitter/TwitterAuthenticationDefaults.cs @@ -0,0 +1,10 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +namespace Microsoft.AspNet.Security.Twitter +{ + public static class TwitterAuthenticationDefaults + { + public const string AuthenticationType = "Twitter"; + } +} diff --git a/src/Microsoft.AspNet.Security.Twitter/TwitterAuthenticationExtensions.cs b/src/Microsoft.AspNet.Security.Twitter/TwitterAuthenticationExtensions.cs new file mode 100644 index 000000000..250c721cb --- /dev/null +++ b/src/Microsoft.AspNet.Security.Twitter/TwitterAuthenticationExtensions.cs @@ -0,0 +1,45 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using Microsoft.AspNet.Security.Twitter; + +namespace Microsoft.AspNet.Builder +{ + /// + /// Extension methods for using + /// + public static class TwitterAuthenticationExtensions + { + /// + /// Authenticate users using Twitter + /// + /// The passed to the configure method + /// The Twitter-issued consumer key + /// The Twitter-issued consumer secret + /// The updated + public static IBuilder UseTwitterAuthentication([NotNull] this IBuilder app, [NotNull] string consumerKey, [NotNull] string consumerSecret) + { + return app.UseTwitterAuthentication( + new TwitterAuthenticationOptions + { + ConsumerKey = consumerKey, + ConsumerSecret = consumerSecret, + }); + } + + /// + /// Authenticate users using Twitter + /// + /// The passed to the configure method + /// Middleware configuration options + /// The updated + public static IBuilder UseTwitterAuthentication([NotNull] this IBuilder app, [NotNull] TwitterAuthenticationOptions options) + { + if (string.IsNullOrEmpty(options.SignInAsAuthenticationType)) + { + options.SignInAsAuthenticationType = app.GetDefaultSignInAsAuthenticationType(); + } + return app.UseMiddleware(options); + } + } +} diff --git a/src/Microsoft.AspNet.Security.Twitter/TwitterAuthenticationHandler.cs b/src/Microsoft.AspNet.Security.Twitter/TwitterAuthenticationHandler.cs new file mode 100644 index 000000000..b24aa71c3 --- /dev/null +++ b/src/Microsoft.AspNet.Security.Twitter/TwitterAuthenticationHandler.cs @@ -0,0 +1,384 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Net.Http; +using System.Security.Claims; +using System.Security.Cryptography; +using System.Text; +using System.Threading.Tasks; +using Microsoft.AspNet.Http; +using Microsoft.AspNet.Http.Security; +using Microsoft.AspNet.Security.Infrastructure; +using Microsoft.AspNet.Security.Twitter.Messages; +using Microsoft.AspNet.WebUtilities; +using Microsoft.Framework.Logging; + +namespace Microsoft.AspNet.Security.Twitter +{ + internal class TwitterAuthenticationHandler : AuthenticationHandler + { + private static readonly DateTime Epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); + private const string StateCookie = "__TwitterState"; + private const string RequestTokenEndpoint = "https://api.twitter.com/oauth/request_token"; + private const string AuthenticationEndpoint = "https://twitter.com/oauth/authenticate?oauth_token="; + private const string AccessTokenEndpoint = "https://api.twitter.com/oauth/access_token"; + + private readonly HttpClient _httpClient; + private readonly ILogger _logger; + + public TwitterAuthenticationHandler(HttpClient httpClient, ILogger logger) + { + _httpClient = httpClient; + _logger = logger; + } + + public override async Task InvokeAsync() + { + if (Options.CallbackPath.HasValue && Options.CallbackPath == Request.Path) + { + return await InvokeReturnPathAsync(); + } + return false; + } + + protected override AuthenticationTicket AuthenticateCore() + { + return AuthenticateCoreAsync().Result; + } + + protected override async Task AuthenticateCoreAsync() + { + AuthenticationProperties properties = null; + try + { + IReadableStringCollection query = Request.Query; + string protectedRequestToken = Request.Cookies[StateCookie]; + + RequestToken requestToken = Options.StateDataFormat.Unprotect(protectedRequestToken); + + if (requestToken == null) + { + _logger.WriteWarning("Invalid state"); + return null; + } + + properties = requestToken.Properties; + + string returnedToken = query.Get("oauth_token"); + if (string.IsNullOrWhiteSpace(returnedToken)) + { + _logger.WriteWarning("Missing oauth_token"); + return new AuthenticationTicket(null, properties); + } + + if (returnedToken != requestToken.Token) + { + _logger.WriteWarning("Unmatched token"); + return new AuthenticationTicket(null, properties); + } + + string oauthVerifier = query.Get("oauth_verifier"); + if (string.IsNullOrWhiteSpace(oauthVerifier)) + { + _logger.WriteWarning("Missing or blank oauth_verifier"); + return new AuthenticationTicket(null, properties); + } + + AccessToken accessToken = await ObtainAccessTokenAsync(Options.ConsumerKey, Options.ConsumerSecret, requestToken, oauthVerifier); + + var context = new TwitterAuthenticatedContext(Context, accessToken.UserId, accessToken.ScreenName, accessToken.Token, accessToken.TokenSecret); + + context.Identity = new ClaimsIdentity( + new[] + { + new Claim(ClaimTypes.NameIdentifier, accessToken.UserId, "http://www.w3.org/2001/XMLSchema#string", Options.AuthenticationType), + new Claim(ClaimTypes.Name, accessToken.ScreenName, "http://www.w3.org/2001/XMLSchema#string", Options.AuthenticationType), + new Claim("urn:twitter:userid", accessToken.UserId, "http://www.w3.org/2001/XMLSchema#string", Options.AuthenticationType), + new Claim("urn:twitter:screenname", accessToken.ScreenName, "http://www.w3.org/2001/XMLSchema#string", Options.AuthenticationType) + }, + Options.AuthenticationType, + ClaimsIdentity.DefaultNameClaimType, + ClaimsIdentity.DefaultRoleClaimType); + context.Properties = requestToken.Properties; + + Response.Cookies.Delete(StateCookie); + + await Options.Notifications.Authenticated(context); + + return new AuthenticationTicket(context.Identity, context.Properties); + } + catch (Exception ex) + { + _logger.WriteError("Authentication failed", ex); + return new AuthenticationTicket(null, properties); + } + } + protected override void ApplyResponseChallenge() + { + ApplyResponseChallengeAsync().Wait(); + } + + protected override async Task ApplyResponseChallengeAsync() + { + if (Response.StatusCode != 401) + { + return; + } + + // Active middleware should redirect on 401 even if there wasn't an explicit challenge. + if (ChallengeContext == null && Options.AuthenticationMode == AuthenticationMode.Passive) + { + return; + } + + string requestPrefix = Request.Scheme + "://" + Request.Host; + string callBackUrl = requestPrefix + RequestPathBase + Options.CallbackPath; + + AuthenticationProperties properties; + if (ChallengeContext == null) + { + properties = new AuthenticationProperties(); + } + else + { + properties = new AuthenticationProperties(ChallengeContext.Properties); + } + if (string.IsNullOrEmpty(properties.RedirectUri)) + { + properties.RedirectUri = requestPrefix + Request.PathBase + Request.Path + Request.QueryString; + } + + RequestToken requestToken = await ObtainRequestTokenAsync(Options.ConsumerKey, Options.ConsumerSecret, callBackUrl, properties); + + if (requestToken.CallbackConfirmed) + { + string twitterAuthenticationEndpoint = AuthenticationEndpoint + requestToken.Token; + + var cookieOptions = new CookieOptions + { + HttpOnly = true, + Secure = Request.IsSecure + }; + + Response.Cookies.Append(StateCookie, Options.StateDataFormat.Protect(requestToken), cookieOptions); + + var redirectContext = new TwitterApplyRedirectContext( + Context, Options, + properties, twitterAuthenticationEndpoint); + Options.Notifications.ApplyRedirect(redirectContext); + } + else + { + _logger.WriteError("requestToken CallbackConfirmed!=true"); + } + } + + public async Task InvokeReturnPathAsync() + { + AuthenticationTicket model = await AuthenticateAsync(); + if (model == null) + { + _logger.WriteWarning("Invalid return state, unable to redirect."); + Response.StatusCode = 500; + return true; + } + + var context = new TwitterReturnEndpointContext(Context, model) + { + SignInAsAuthenticationType = Options.SignInAsAuthenticationType, + RedirectUri = model.Properties.RedirectUri + }; + model.Properties.RedirectUri = null; + + await Options.Notifications.ReturnEndpoint(context); + + if (context.SignInAsAuthenticationType != null && context.Identity != null) + { + ClaimsIdentity signInIdentity = context.Identity; + if (!string.Equals(signInIdentity.AuthenticationType, context.SignInAsAuthenticationType, StringComparison.Ordinal)) + { + signInIdentity = new ClaimsIdentity(signInIdentity.Claims, context.SignInAsAuthenticationType, signInIdentity.NameClaimType, signInIdentity.RoleClaimType); + } + Context.Response.SignIn(context.Properties, signInIdentity); + } + + if (!context.IsRequestCompleted && context.RedirectUri != null) + { + if (context.Identity == null) + { + // add a redirect hint that sign-in failed in some way + context.RedirectUri = QueryHelpers.AddQueryString(context.RedirectUri, "error", "access_denied"); + } + Response.Redirect(context.RedirectUri); + context.RequestCompleted(); + } + + return context.IsRequestCompleted; + } + + private async Task ObtainRequestTokenAsync(string consumerKey, string consumerSecret, string callBackUri, AuthenticationProperties properties) + { + _logger.WriteVerbose("ObtainRequestToken"); + + string nonce = Guid.NewGuid().ToString("N"); + + var authorizationParts = new SortedDictionary + { + { "oauth_callback", callBackUri }, + { "oauth_consumer_key", consumerKey }, + { "oauth_nonce", nonce }, + { "oauth_signature_method", "HMAC-SHA1" }, + { "oauth_timestamp", GenerateTimeStamp() }, + { "oauth_version", "1.0" } + }; + + var parameterBuilder = new StringBuilder(); + foreach (var authorizationKey in authorizationParts) + { + parameterBuilder.AppendFormat("{0}={1}&", Uri.EscapeDataString(authorizationKey.Key), Uri.EscapeDataString(authorizationKey.Value)); + } + parameterBuilder.Length--; + string parameterString = parameterBuilder.ToString(); + + var canonicalizedRequestBuilder = new StringBuilder(); + canonicalizedRequestBuilder.Append(HttpMethod.Post.Method); + canonicalizedRequestBuilder.Append("&"); + canonicalizedRequestBuilder.Append(Uri.EscapeDataString(RequestTokenEndpoint)); + canonicalizedRequestBuilder.Append("&"); + canonicalizedRequestBuilder.Append(Uri.EscapeDataString(parameterString)); + + string signature = ComputeSignature(consumerSecret, null, canonicalizedRequestBuilder.ToString()); + authorizationParts.Add("oauth_signature", signature); + + var authorizationHeaderBuilder = new StringBuilder(); + authorizationHeaderBuilder.Append("OAuth "); + foreach (var authorizationPart in authorizationParts) + { + authorizationHeaderBuilder.AppendFormat( + "{0}=\"{1}\", ", authorizationPart.Key, Uri.EscapeDataString(authorizationPart.Value)); + } + authorizationHeaderBuilder.Length = authorizationHeaderBuilder.Length - 2; + + var request = new HttpRequestMessage(HttpMethod.Post, RequestTokenEndpoint); + request.Headers.Add("Authorization", authorizationHeaderBuilder.ToString()); + + HttpResponseMessage response = await _httpClient.SendAsync(request, Context.RequestAborted); + response.EnsureSuccessStatusCode(); + string responseText = await response.Content.ReadAsStringAsync(); + + IFormCollection responseParameters = FormHelpers.ParseForm(responseText); + if (string.Equals(responseParameters["oauth_callback_confirmed"], "true", StringComparison.Ordinal)) + { + return new RequestToken { Token = Uri.UnescapeDataString(responseParameters["oauth_token"]), TokenSecret = Uri.UnescapeDataString(responseParameters["oauth_token_secret"]), CallbackConfirmed = true, Properties = properties }; + } + + return new RequestToken(); + } + + private async Task ObtainAccessTokenAsync(string consumerKey, string consumerSecret, RequestToken token, string verifier) + { + // https://dev.twitter.com/docs/api/1/post/oauth/access_token + + _logger.WriteVerbose("ObtainAccessToken"); + + string nonce = Guid.NewGuid().ToString("N"); + + var authorizationParts = new SortedDictionary + { + { "oauth_consumer_key", consumerKey }, + { "oauth_nonce", nonce }, + { "oauth_signature_method", "HMAC-SHA1" }, + { "oauth_token", token.Token }, + { "oauth_timestamp", GenerateTimeStamp() }, + { "oauth_verifier", verifier }, + { "oauth_version", "1.0" }, + }; + + var parameterBuilder = new StringBuilder(); + foreach (var authorizationKey in authorizationParts) + { + parameterBuilder.AppendFormat("{0}={1}&", Uri.EscapeDataString(authorizationKey.Key), Uri.EscapeDataString(authorizationKey.Value)); + } + parameterBuilder.Length--; + string parameterString = parameterBuilder.ToString(); + + var canonicalizedRequestBuilder = new StringBuilder(); + canonicalizedRequestBuilder.Append(HttpMethod.Post.Method); + canonicalizedRequestBuilder.Append("&"); + canonicalizedRequestBuilder.Append(Uri.EscapeDataString(AccessTokenEndpoint)); + canonicalizedRequestBuilder.Append("&"); + canonicalizedRequestBuilder.Append(Uri.EscapeDataString(parameterString)); + + string signature = ComputeSignature(consumerSecret, token.TokenSecret, canonicalizedRequestBuilder.ToString()); + authorizationParts.Add("oauth_signature", signature); + authorizationParts.Remove("oauth_verifier"); + + var authorizationHeaderBuilder = new StringBuilder(); + authorizationHeaderBuilder.Append("OAuth "); + foreach (var authorizationPart in authorizationParts) + { + authorizationHeaderBuilder.AppendFormat( + "{0}=\"{1}\", ", authorizationPart.Key, Uri.EscapeDataString(authorizationPart.Value)); + } + authorizationHeaderBuilder.Length = authorizationHeaderBuilder.Length - 2; + + var request = new HttpRequestMessage(HttpMethod.Post, AccessTokenEndpoint); + request.Headers.Add("Authorization", authorizationHeaderBuilder.ToString()); + + var formPairs = new List>() + { + new KeyValuePair("oauth_verifier", verifier) + }; + + request.Content = new FormUrlEncodedContent(formPairs); + + HttpResponseMessage response = await _httpClient.SendAsync(request, Context.RequestAborted); + + if (!response.IsSuccessStatusCode) + { + _logger.WriteError("AccessToken request failed with a status code of " + response.StatusCode); + response.EnsureSuccessStatusCode(); // throw + } + + string responseText = await response.Content.ReadAsStringAsync(); + + IFormCollection responseParameters = FormHelpers.ParseForm(responseText); + + return new AccessToken + { + Token = Uri.UnescapeDataString(responseParameters["oauth_token"]), + TokenSecret = Uri.UnescapeDataString(responseParameters["oauth_token_secret"]), + UserId = Uri.UnescapeDataString(responseParameters["user_id"]), + ScreenName = Uri.UnescapeDataString(responseParameters["screen_name"]) + }; + } + + private static string GenerateTimeStamp() + { + TimeSpan secondsSinceUnixEpocStart = DateTime.UtcNow - Epoch; + return Convert.ToInt64(secondsSinceUnixEpocStart.TotalSeconds).ToString(CultureInfo.InvariantCulture); + } + + private static string ComputeSignature(string consumerSecret, string tokenSecret, string signatureData) + { + using (var algorithm = new HMACSHA1()) + { + algorithm.Key = Encoding.ASCII.GetBytes( + string.Format(CultureInfo.InvariantCulture, + "{0}&{1}", + Uri.EscapeDataString(consumerSecret), + string.IsNullOrEmpty(tokenSecret) ? string.Empty : Uri.EscapeDataString(tokenSecret))); + byte[] hash = algorithm.ComputeHash(Encoding.ASCII.GetBytes(signatureData)); + return Convert.ToBase64String(hash); + } + } + + protected override void ApplyResponseGrant() + { + // N/A - No SignIn or SignOut support. + } + } +} diff --git a/src/Microsoft.AspNet.Security.Twitter/TwitterAuthenticationMiddleware.cs b/src/Microsoft.AspNet.Security.Twitter/TwitterAuthenticationMiddleware.cs new file mode 100644 index 000000000..421a68557 --- /dev/null +++ b/src/Microsoft.AspNet.Security.Twitter/TwitterAuthenticationMiddleware.cs @@ -0,0 +1,106 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Diagnostics.CodeAnalysis; +using System.Globalization; +using System.Net.Http; +using Microsoft.AspNet.Builder; +using Microsoft.AspNet.Security.DataHandler; +using Microsoft.AspNet.Security.DataHandler.Encoder; +using Microsoft.AspNet.Security.DataProtection; +using Microsoft.AspNet.Security.Infrastructure; +using Microsoft.AspNet.Security.Twitter.Messages; +using Microsoft.Framework.Logging; + +namespace Microsoft.AspNet.Security.Twitter +{ + /// + /// ASP.NET middleware for authenticating users using Twitter + /// + [SuppressMessage("Microsoft.Design", "CA1001:TypesThatOwnDisposableFieldsShouldBeDisposable", Justification = "Middleware are not disposable.")] + public class TwitterAuthenticationMiddleware : AuthenticationMiddleware + { + private readonly ILogger _logger; + private readonly HttpClient _httpClient; + + /// + /// Initializes a + /// + /// The next middleware in the HTTP pipeline to invoke + /// + /// + /// Configuration options for the middleware + public TwitterAuthenticationMiddleware( + RequestDelegate next, + IDataProtectionProvider dataProtectionProvider, + ILoggerFactory loggerFactory, + TwitterAuthenticationOptions options) + : base(next, options) + { + if (string.IsNullOrWhiteSpace(Options.ConsumerSecret)) + { + throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, Resources.Exception_OptionMustBeProvided, "ConsumerSecret")); + } + if (string.IsNullOrWhiteSpace(Options.ConsumerKey)) + { + throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, Resources.Exception_OptionMustBeProvided, "ConsumerKey")); + } + + _logger = loggerFactory.Create(typeof(TwitterAuthenticationMiddleware).FullName); + + if (Options.Notifications == null) + { + Options.Notifications = new TwitterAuthenticationNotifications(); + } + if (Options.StateDataFormat == null) + { + IDataProtector dataProtector = DataProtectionHelpers.CreateDataProtector(dataProtectionProvider, + typeof(TwitterAuthenticationMiddleware).FullName, options.AuthenticationType, "v1"); + Options.StateDataFormat = new SecureDataFormat( + Serializers.RequestToken, + dataProtector, + TextEncodings.Base64Url); + } + + _httpClient = new HttpClient(ResolveHttpMessageHandler(Options)); + _httpClient.Timeout = Options.BackchannelTimeout; + _httpClient.MaxResponseContentBufferSize = 1024 * 1024 * 10; // 10 MB + _httpClient.DefaultRequestHeaders.Accept.ParseAdd("*/*"); + _httpClient.DefaultRequestHeaders.UserAgent.ParseAdd("Microsoft ASP.NET Twitter middleware"); + _httpClient.DefaultRequestHeaders.ExpectContinue = false; + } + + /// + /// Provides the object for processing authentication-related requests. + /// + /// An configured with the supplied to the constructor. + protected override AuthenticationHandler CreateHandler() + { + return new TwitterAuthenticationHandler(_httpClient, _logger); + } + + [SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Justification = "Managed by caller")] + private static HttpMessageHandler ResolveHttpMessageHandler(TwitterAuthenticationOptions options) + { + HttpMessageHandler handler = options.BackchannelHttpHandler ?? +#if NET45 + new WebRequestHandler(); + // If they provided a validator, apply it or fail. + if (options.BackchannelCertificateValidator != null) + { + // Set the cert validate callback + var webRequestHandler = handler as WebRequestHandler; + if (webRequestHandler == null) + { + throw new InvalidOperationException(Resources.Exception_ValidatorHandlerMismatch); + } + webRequestHandler.ServerCertificateValidationCallback = options.BackchannelCertificateValidator.Validate; + } +#else + new WinHttpHandler(); +#endif + return handler; + } + } +} diff --git a/src/Microsoft.AspNet.Security.Twitter/TwitterAuthenticationOptions.cs b/src/Microsoft.AspNet.Security.Twitter/TwitterAuthenticationOptions.cs new file mode 100644 index 000000000..fcf307d5c --- /dev/null +++ b/src/Microsoft.AspNet.Security.Twitter/TwitterAuthenticationOptions.cs @@ -0,0 +1,107 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Net.Http; +using Microsoft.AspNet.Http; +using Microsoft.AspNet.Security.Twitter.Messages; + +namespace Microsoft.AspNet.Security.Twitter +{ + /// + /// Options for the Twitter authentication middleware. + /// + public class TwitterAuthenticationOptions : AuthenticationOptions + { + /// + /// Initializes a new instance of the class. + /// + public TwitterAuthenticationOptions() + : base(TwitterAuthenticationDefaults.AuthenticationType) + { + Caption = TwitterAuthenticationDefaults.AuthenticationType; + CallbackPath = new PathString("/signin-twitter"); + AuthenticationMode = AuthenticationMode.Passive; + BackchannelTimeout = TimeSpan.FromSeconds(60); +#if NET45 + // Twitter lists its valid Subject Key Identifiers at https://dev.twitter.com/docs/security/using-ssl + BackchannelCertificateValidator = new CertificateSubjectKeyIdentifierValidator( + new[] + { + "A5EF0B11CEC04103A34A659048B21CE0572D7D47", // VeriSign Class 3 Secure Server CA - G2 + "0D445C165344C1827E1D20AB25F40163D8BE79A5", // VeriSign Class 3 Secure Server CA - G3 + "5F60CF619055DF8443148A602AB2F57AF44318EF", // Symantec Class 3 Secure Server CA - G4 + }); +#endif + } + + /// + /// Gets or sets the consumer key used to communicate with Twitter. + /// + /// The consumer key used to communicate with Twitter. + public string ConsumerKey { get; set; } + + /// + /// Gets or sets the consumer secret used to sign requests to Twitter. + /// + /// The consumer secret used to sign requests to Twitter. + public string ConsumerSecret { get; set; } + + /// + /// Gets or sets timeout value in milliseconds for back channel communications with Twitter. + /// + /// + /// The back channel timeout. + /// + public TimeSpan BackchannelTimeout { get; set; } +#if NET45 + /// + /// Gets or sets the a pinned certificate validator to use to validate the endpoints used + /// in back channel communications belong to Twitter. + /// + /// + /// The pinned certificate validator. + /// + /// If this property is null then the default certificate checks are performed, + /// validating the subject name and if the signing chain is a trusted party. + public ICertificateValidator BackchannelCertificateValidator { get; set; } +#endif + /// + /// The HttpMessageHandler used to communicate with Twitter. + /// This cannot be set at the same time as BackchannelCertificateValidator unless the value + /// can be downcast to a WebRequestHandler. + /// + public HttpMessageHandler BackchannelHttpHandler { get; set; } + + /// + /// Get or sets the text that the user can display on a sign in user interface. + /// + public string Caption + { + get { return Description.Caption; } + set { Description.Caption = value; } + } + + /// + /// The request path within the application's base path where the user-agent will be returned. + /// The middleware will process this request when it arrives. + /// Default value is "/signin-twitter". + /// + public PathString CallbackPath { get; set; } + + /// + /// Gets or sets the name of another authentication middleware which will be responsible for actually issuing a user . + /// + public string SignInAsAuthenticationType { get; set; } + + /// + /// Gets or sets the type used to secure data handled by the middleware. + /// + public ISecureDataFormat StateDataFormat { get; set; } + + /// + /// Gets or sets the used to handle authentication events. + /// + public ITwitterAuthenticationNotifications Notifications { get; set; } + } +} diff --git a/src/Microsoft.AspNet.Security/DataHandler/Serializer/DataSerializers.cs b/src/Microsoft.AspNet.Security/DataHandler/Serializer/DataSerializers.cs index 476fe7bb7..a1864b44d 100644 --- a/src/Microsoft.AspNet.Security/DataHandler/Serializer/DataSerializers.cs +++ b/src/Microsoft.AspNet.Security/DataHandler/Serializer/DataSerializers.cs @@ -14,8 +14,8 @@ static DataSerializers() Ticket = new TicketSerializer(); } - public static IDataSerializer Properties { get; set; } + public static IDataSerializer Properties { get; private set; } - public static IDataSerializer Ticket { get; set; } + public static IDataSerializer Ticket { get; private set; } } } diff --git a/test/Microsoft.AspNet.Security.Test/Twitter/TwitterMiddlewareTests.cs b/test/Microsoft.AspNet.Security.Test/Twitter/TwitterMiddlewareTests.cs new file mode 100644 index 000000000..d5eb56896 --- /dev/null +++ b/test/Microsoft.AspNet.Security.Test/Twitter/TwitterMiddlewareTests.cs @@ -0,0 +1,183 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net; +using System.Net.Http; +using System.Text; +using System.Threading.Tasks; +using Microsoft.AspNet.Builder; +using Microsoft.AspNet.Http; +using Microsoft.AspNet.Security.Cookies; +using Microsoft.AspNet.Security.Twitter; +using Microsoft.AspNet.TestHost; +using Newtonsoft.Json; +using Shouldly; +using Xunit; + +namespace Microsoft.AspNet.Security.Twitter +{ + public class TwitterMiddlewareTests + { + [Fact] + public async Task ChallengeWillTriggerApplyRedirectEvent() + { + var options = new TwitterAuthenticationOptions() + { + ConsumerKey = "Test Consumer Key", + ConsumerSecret = "Test Consumer Secret", + Notifications = new TwitterAuthenticationNotifications + { + OnApplyRedirect = context => + { + context.Response.Redirect(context.RedirectUri + "&custom=test"); + } + }, + BackchannelHttpHandler = new TestHttpMessageHandler + { + Sender = req => + { + if (req.RequestUri.AbsoluteUri == "https://api.twitter.com/oauth/request_token") + { + return Task.FromResult(new HttpResponseMessage(HttpStatusCode.OK) + { + Content = + new StringContent("oauth_callback_confirmed=true&oauth_token=test_oauth_token&oauth_token_secret=test_oauth_token_secret", + Encoding.UTF8, + "application/x-www-form-urlencoded") + }); + } + return Task.FromResult(null); + } + }, + BackchannelCertificateValidator = null + }; + var server = CreateServer( + app => app.UseTwitterAuthentication(options), + context => + { + context.Response.Challenge("Twitter"); + return true; + }); + var transaction = await SendAsync(server, "http://example.com/challenge"); + transaction.Response.StatusCode.ShouldBe(HttpStatusCode.Redirect); + var query = transaction.Response.Headers.Location.Query; + query.ShouldContain("custom=test"); + } + + [Fact] + public async Task ChallengeWillTriggerRedirection() + { + var options = new TwitterAuthenticationOptions() + { + ConsumerKey = "Test Consumer Key", + ConsumerSecret = "Test Consumer Secret", + BackchannelHttpHandler = new TestHttpMessageHandler + { + Sender = req => + { + if (req.RequestUri.AbsoluteUri == "https://api.twitter.com/oauth/request_token") + { + return Task.FromResult(new HttpResponseMessage(HttpStatusCode.OK) + { + Content = + new StringContent("oauth_callback_confirmed=true&oauth_token=test_oauth_token&oauth_token_secret=test_oauth_token_secret", + Encoding.UTF8, + "application/x-www-form-urlencoded") + }); + } + return Task.FromResult(null); + } + }, + BackchannelCertificateValidator = null + }; + var server = CreateServer( + app => app.UseTwitterAuthentication(options), + context => + { + context.Response.Challenge("Twitter"); + return true; + }); + var transaction = await SendAsync(server, "http://example.com/challenge"); + transaction.Response.StatusCode.ShouldBe(HttpStatusCode.Redirect); + var location = transaction.Response.Headers.Location.AbsoluteUri; + location.ShouldContain("https://twitter.com/oauth/authenticate?oauth_token="); + } + + private static TestServer CreateServer(Action configure, Func handler) + { + return TestServer.Create(app => + { + app.SetDefaultSignInAsAuthenticationType("External"); + app.UseCookieAuthentication(new CookieAuthenticationOptions + { + AuthenticationType = "External" + }); + if (configure != null) + { + configure(app); + } + app.Use(async (context, next) => + { + if (handler == null || !handler(context)) + { + await next(); + } + }); + }); + } + + private static async Task SendAsync(TestServer server, string uri, string cookieHeader = null) + { + var request = new HttpRequestMessage(HttpMethod.Get, uri); + if (!string.IsNullOrEmpty(cookieHeader)) + { + request.Headers.Add("Cookie", cookieHeader); + } + var transaction = new Transaction + { + Request = request, + Response = await server.CreateClient().SendAsync(request), + }; + if (transaction.Response.Headers.Contains("Set-Cookie")) + { + transaction.SetCookie = transaction.Response.Headers.GetValues("Set-Cookie").ToList(); + } + transaction.ResponseText = await transaction.Response.Content.ReadAsStringAsync(); + + return transaction; + } + + private static async Task ReturnJsonResponse(object content) + { + var res = new HttpResponseMessage(HttpStatusCode.OK); + var text = await JsonConvert.SerializeObjectAsync(content); + res.Content = new StringContent(text, Encoding.UTF8, "application/json"); + return res; + } + + private class TestHttpMessageHandler : HttpMessageHandler + { + public Func> Sender { get; set; } + + protected override async Task SendAsync(HttpRequestMessage request, System.Threading.CancellationToken cancellationToken) + { + if (Sender != null) + { + return await Sender(request); + } + + return null; + } + } + + private class Transaction + { + public HttpRequestMessage Request { get; set; } + public HttpResponseMessage Response { get; set; } + public IList SetCookie { get; set; } + public string ResponseText { get; set; } + } + } +} diff --git a/test/Microsoft.AspNet.Security.Test/project.json b/test/Microsoft.AspNet.Security.Test/project.json index 542d5ee25..976f4ef7a 100644 --- a/test/Microsoft.AspNet.Security.Test/project.json +++ b/test/Microsoft.AspNet.Security.Test/project.json @@ -8,6 +8,7 @@ "Microsoft.AspNet.Security.Cookies" : "1.0.0-*", "Microsoft.AspNet.Security.Facebook" : "1.0.0-*", "Microsoft.AspNet.Security.Google" : "1.0.0-*", + "Microsoft.AspNet.Security.Twitter" : "1.0.0-*", "Microsoft.AspNet.TestHost": "1.0.0-*", "Microsoft.Framework.DependencyInjection": "1.0.0-*", "System.Net.Http": "4.0.0.0", From 536da0666038d824d9f374ba26001f998f143cb3 Mon Sep 17 00:00:00 2001 From: David Fowler Date: Thu, 28 Aug 2014 23:48:55 -0700 Subject: [PATCH 036/216] Updated to use the new target framework in project.json --- samples/CookieSample/project.json | 2 +- samples/SocialSample/Project.json | 2 +- src/Microsoft.AspNet.Security.Cookies/project.json | 2 +- src/Microsoft.AspNet.Security.Facebook/Project.json | 2 +- src/Microsoft.AspNet.Security.Google/Project.json | 2 +- src/Microsoft.AspNet.Security.Twitter/Project.json | 2 +- src/Microsoft.AspNet.Security/project.json | 2 +- test/Microsoft.AspNet.Security.Test/project.json | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/samples/CookieSample/project.json b/samples/CookieSample/project.json index 85f8a1e33..c405745f1 100644 --- a/samples/CookieSample/project.json +++ b/samples/CookieSample/project.json @@ -15,7 +15,7 @@ "frameworks": { "net45": { }, - "k10": { + "aspnetcore50": { "dependencies": { "System.Collections": "4.0.10.0", "System.Console": "4.0.0.0", diff --git a/samples/SocialSample/Project.json b/samples/SocialSample/Project.json index 1af9beef0..1dc7c6944 100644 --- a/samples/SocialSample/Project.json +++ b/samples/SocialSample/Project.json @@ -15,7 +15,7 @@ "frameworks": { "net45": { }, - "k10": { + "aspnetcore50": { "dependencies": { "System.Collections": "4.0.10.0", "System.Console": "4.0.0.0", diff --git a/src/Microsoft.AspNet.Security.Cookies/project.json b/src/Microsoft.AspNet.Security.Cookies/project.json index 0336d73e9..0a3d6d36d 100644 --- a/src/Microsoft.AspNet.Security.Cookies/project.json +++ b/src/Microsoft.AspNet.Security.Cookies/project.json @@ -14,7 +14,7 @@ }, "frameworks": { "net45": {}, - "k10": { + "aspnetcore50": { "dependencies": { "System.Collections": "4.0.10.0", "System.ComponentModel": "4.0.0.0", diff --git a/src/Microsoft.AspNet.Security.Facebook/Project.json b/src/Microsoft.AspNet.Security.Facebook/Project.json index 9f19015e3..608aa0b6d 100644 --- a/src/Microsoft.AspNet.Security.Facebook/Project.json +++ b/src/Microsoft.AspNet.Security.Facebook/Project.json @@ -16,7 +16,7 @@ "System.Net.Http.WebRequest": "" } }, - "k10": { + "aspnetcore50": { "dependencies": { "System.Collections": "4.0.10.0", "System.ComponentModel": "4.0.0.0", diff --git a/src/Microsoft.AspNet.Security.Google/Project.json b/src/Microsoft.AspNet.Security.Google/Project.json index 9f19015e3..608aa0b6d 100644 --- a/src/Microsoft.AspNet.Security.Google/Project.json +++ b/src/Microsoft.AspNet.Security.Google/Project.json @@ -16,7 +16,7 @@ "System.Net.Http.WebRequest": "" } }, - "k10": { + "aspnetcore50": { "dependencies": { "System.Collections": "4.0.10.0", "System.ComponentModel": "4.0.0.0", diff --git a/src/Microsoft.AspNet.Security.Twitter/Project.json b/src/Microsoft.AspNet.Security.Twitter/Project.json index 9f19015e3..608aa0b6d 100644 --- a/src/Microsoft.AspNet.Security.Twitter/Project.json +++ b/src/Microsoft.AspNet.Security.Twitter/Project.json @@ -16,7 +16,7 @@ "System.Net.Http.WebRequest": "" } }, - "k10": { + "aspnetcore50": { "dependencies": { "System.Collections": "4.0.10.0", "System.ComponentModel": "4.0.0.0", diff --git a/src/Microsoft.AspNet.Security/project.json b/src/Microsoft.AspNet.Security/project.json index e79296344..f328ce750 100644 --- a/src/Microsoft.AspNet.Security/project.json +++ b/src/Microsoft.AspNet.Security/project.json @@ -11,7 +11,7 @@ }, "frameworks": { "net45": {}, - "k10": { + "aspnetcore50": { "dependencies": { "System.Collections": "4.0.10.0", "System.ComponentModel": "4.0.0.0", diff --git a/test/Microsoft.AspNet.Security.Test/project.json b/test/Microsoft.AspNet.Security.Test/project.json index 976f4ef7a..4da682291 100644 --- a/test/Microsoft.AspNet.Security.Test/project.json +++ b/test/Microsoft.AspNet.Security.Test/project.json @@ -1,4 +1,4 @@ -{ +{ "compilationOptions": { "warningsAsErrors": true }, From 3a3816af412b32ff6924d9f1c70f6875616dd06f Mon Sep 17 00:00:00 2001 From: Chris Ross Date: Fri, 29 Aug 2014 13:19:18 -0700 Subject: [PATCH 037/216] #41 - Port MicrosoftAccount middleware from Katana. --- Security.sln | 13 + samples/SocialSample/Project.json | 1 + samples/SocialSample/Startup.cs | 25 ++ .../CookieAuthenticationMiddleware.cs | 2 +- .../CookieAuthenticationOptions.cs | 2 +- .../FacebookAuthenticationExtensions.cs | 20 +- .../FacebookAuthenticationMiddleware.cs | 8 +- .../FacebookAuthenticationOptions.cs | 8 +- .../FacebookApplyRedirectContext.cs | 12 +- .../FacebookAuthenticatedContext.cs | 31 +- .../FacebookAuthenticationNotifications.cs | 10 +- .../FacebookReturnEndpointContext.cs | 6 +- .../IFacebookAuthenticationNotifications.cs | 8 +- .../GoogleAuthenticationExtensions.cs | 20 +- .../GoogleAuthenticationMiddleware.cs | 8 +- .../GoogleAuthenticationOptions.cs | 8 +- .../GoogleApplyRedirectContext.cs | 12 +- .../GoogleAuthenticatedContext.cs | 38 +-- .../GoogleAuthenticationNotifications.cs | 13 +- .../GoogleReturnEndpointContext.cs | 6 +- .../IGoogleAuthenticationNotifications.cs | 8 +- ...oft.AspNet.Security.MicrosoftAccount.kproj | 28 ++ .../MicrosoftAccountAuthenticationDefaults.cs | 10 + ...icrosoftAccountAuthenticationExtensions.cs | 45 +++ .../MicrosoftAccountAuthenticationHandler.cs | 257 ++++++++++++++++ ...icrosoftAccountAuthenticationMiddleware.cs | 98 ++++++ .../MicrosoftAccountAuthenticationOptions.cs | 106 +++++++ .../NotNullAttribute.cs | 12 + ...osoftAccountAuthenticationNotifications.cs | 33 ++ .../MicrosoftAccountApplyRedirectContext.cs | 40 +++ .../MicrosoftAccountAuthenticatedContext.cs | 130 ++++++++ ...osoftAccountAuthenticationNotifications.cs | 68 +++++ .../MicrosoftAccountReturnEndpointContext.cs | 26 ++ .../Resources.Designer.cs | 90 ++++++ .../Resources.resx | 129 ++++++++ .../project.json | 46 +++ .../TwitterApplyRedirectContext.cs | 12 +- .../Resources.Designer.cs | 4 +- src/Microsoft.AspNet.Security/Resources.resx | 4 +- .../MicrosoftAccountMiddlewareTests.cs | 282 ++++++++++++++++++ .../project.json | 1 + 41 files changed, 1561 insertions(+), 119 deletions(-) create mode 100644 src/Microsoft.AspNet.Security.MicrosoftAccount/Microsoft.AspNet.Security.MicrosoftAccount.kproj create mode 100644 src/Microsoft.AspNet.Security.MicrosoftAccount/MicrosoftAccountAuthenticationDefaults.cs create mode 100644 src/Microsoft.AspNet.Security.MicrosoftAccount/MicrosoftAccountAuthenticationExtensions.cs create mode 100644 src/Microsoft.AspNet.Security.MicrosoftAccount/MicrosoftAccountAuthenticationHandler.cs create mode 100644 src/Microsoft.AspNet.Security.MicrosoftAccount/MicrosoftAccountAuthenticationMiddleware.cs create mode 100644 src/Microsoft.AspNet.Security.MicrosoftAccount/MicrosoftAccountAuthenticationOptions.cs create mode 100644 src/Microsoft.AspNet.Security.MicrosoftAccount/NotNullAttribute.cs create mode 100644 src/Microsoft.AspNet.Security.MicrosoftAccount/Notifications/IMicrosoftAccountAuthenticationNotifications.cs create mode 100644 src/Microsoft.AspNet.Security.MicrosoftAccount/Notifications/MicrosoftAccountApplyRedirectContext.cs create mode 100644 src/Microsoft.AspNet.Security.MicrosoftAccount/Notifications/MicrosoftAccountAuthenticatedContext.cs create mode 100644 src/Microsoft.AspNet.Security.MicrosoftAccount/Notifications/MicrosoftAccountAuthenticationNotifications.cs create mode 100644 src/Microsoft.AspNet.Security.MicrosoftAccount/Notifications/MicrosoftAccountReturnEndpointContext.cs create mode 100644 src/Microsoft.AspNet.Security.MicrosoftAccount/Resources.Designer.cs create mode 100644 src/Microsoft.AspNet.Security.MicrosoftAccount/Resources.resx create mode 100644 src/Microsoft.AspNet.Security.MicrosoftAccount/project.json create mode 100644 test/Microsoft.AspNet.Security.Test/MicrosoftAccount/MicrosoftAccountMiddlewareTests.cs diff --git a/Security.sln b/Security.sln index 976cfd4ea..be6636fe2 100644 --- a/Security.sln +++ b/Security.sln @@ -30,6 +30,8 @@ Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNet.Security.G EndProject Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNet.Security.Twitter", "src\Microsoft.AspNet.Security.Twitter\Microsoft.AspNet.Security.Twitter.kproj", "{C96B77EA-4078-4C31-BDB2-878F11C5E061}" EndProject +Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNet.Security.MicrosoftAccount", "src\Microsoft.AspNet.Security.MicrosoftAccount\Microsoft.AspNet.Security.MicrosoftAccount.kproj", "{1FCF26C2-A3C7-4308-B698-4AFC3560BC0C}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -120,6 +122,16 @@ Global {C96B77EA-4078-4C31-BDB2-878F11C5E061}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU {C96B77EA-4078-4C31-BDB2-878F11C5E061}.Release|Mixed Platforms.Build.0 = Release|Any CPU {C96B77EA-4078-4C31-BDB2-878F11C5E061}.Release|x86.ActiveCfg = Release|Any CPU + {1FCF26C2-A3C7-4308-B698-4AFC3560BC0C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {1FCF26C2-A3C7-4308-B698-4AFC3560BC0C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {1FCF26C2-A3C7-4308-B698-4AFC3560BC0C}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {1FCF26C2-A3C7-4308-B698-4AFC3560BC0C}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {1FCF26C2-A3C7-4308-B698-4AFC3560BC0C}.Debug|x86.ActiveCfg = Debug|Any CPU + {1FCF26C2-A3C7-4308-B698-4AFC3560BC0C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {1FCF26C2-A3C7-4308-B698-4AFC3560BC0C}.Release|Any CPU.Build.0 = Release|Any CPU + {1FCF26C2-A3C7-4308-B698-4AFC3560BC0C}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {1FCF26C2-A3C7-4308-B698-4AFC3560BC0C}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {1FCF26C2-A3C7-4308-B698-4AFC3560BC0C}.Release|x86.ActiveCfg = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -133,5 +145,6 @@ Global {8C73D216-332D-41D8-BFD0-45BC4BC36552} = {F8C0AA27-F3FB-4286-8E4C-47EF86B539FF} {89BF8535-A849-458E-868A-A68FCF620486} = {4D2B6A51-2F9F-44F5-8131-EA5CAC053652} {C96B77EA-4078-4C31-BDB2-878F11C5E061} = {4D2B6A51-2F9F-44F5-8131-EA5CAC053652} + {1FCF26C2-A3C7-4308-B698-4AFC3560BC0C} = {4D2B6A51-2F9F-44F5-8131-EA5CAC053652} EndGlobalSection EndGlobal diff --git a/samples/SocialSample/Project.json b/samples/SocialSample/Project.json index 1dc7c6944..8703a24bf 100644 --- a/samples/SocialSample/Project.json +++ b/samples/SocialSample/Project.json @@ -7,6 +7,7 @@ "Microsoft.AspNet.Security.Cookies": "1.0.0-*", "Microsoft.AspNet.Security.Facebook": "1.0.0-*", "Microsoft.AspNet.Security.Google": "1.0.0-*", + "Microsoft.AspNet.Security.MicrosoftAccount": "1.0.0-*", "Microsoft.AspNet.Security.Twitter": "1.0.0-*", "Microsoft.AspNet.Server.WebListener": "1.0.0-*", "Microsoft.Framework.DependencyInjection": "1.0.0-*" diff --git a/samples/SocialSample/Startup.cs b/samples/SocialSample/Startup.cs index bc2e967b3..03435fe0f 100644 --- a/samples/SocialSample/Startup.cs +++ b/samples/SocialSample/Startup.cs @@ -4,6 +4,7 @@ using Microsoft.AspNet.Security.Cookies; using Microsoft.AspNet.Security.Facebook; using Microsoft.AspNet.Security.Google; +using Microsoft.AspNet.Security.MicrosoftAccount; using Microsoft.AspNet.Security.Twitter; namespace CookieSample @@ -39,6 +40,30 @@ public void Configure(IBuilder app) ConsumerSecret = "Il2eFzGIrYhz6BWjYhVXBPQSfZuS4xoHpSSyD9PI", }); + /* + The MicrosoftAccount service has restrictions that prevent the use of http://localhost:12345/ for test applications. + As such, here is how to change this sample to uses http://mssecsample.localhost.this:12345/ instead. + + Edit the Project.json file and replace http://localhost:12345/ with http://mssecsample.localhost.this:12345/. + + From an admin command console first enter: + notepad C:\Windows\System32\drivers\etc\hosts + and add this to the file, save, and exit (and reboot?): + 127.0.0.1 MsSecSample.localhost.this + + Then you can choose to run the app as admin (see below) or add the following ACL as admin: + netsh http add urlacl url=http://mssecsample.localhost.this:12345/ user=[domain\user] + + The sample app can then be run via: + k web + */ + app.UseMicrosoftAccountAuthentication(new MicrosoftAccountAuthenticationOptions() + { + Caption = "MicrosoftAccount - Requires project changes", + ClientId = "00000000480FF62E", + ClientSecret = "bLw2JIvf8Y1TaToipPEqxTVlOeJwCUsr", + }); + // Choose an authentication type app.Map("/login", signoutApp => { diff --git a/src/Microsoft.AspNet.Security.Cookies/CookieAuthenticationMiddleware.cs b/src/Microsoft.AspNet.Security.Cookies/CookieAuthenticationMiddleware.cs index 423ec040b..6f2a5dec0 100644 --- a/src/Microsoft.AspNet.Security.Cookies/CookieAuthenticationMiddleware.cs +++ b/src/Microsoft.AspNet.Security.Cookies/CookieAuthenticationMiddleware.cs @@ -12,7 +12,7 @@ namespace Microsoft.AspNet.Security.Cookies { - internal class CookieAuthenticationMiddleware : AuthenticationMiddleware + public class CookieAuthenticationMiddleware : AuthenticationMiddleware { private readonly ILogger _logger; diff --git a/src/Microsoft.AspNet.Security.Cookies/CookieAuthenticationOptions.cs b/src/Microsoft.AspNet.Security.Cookies/CookieAuthenticationOptions.cs index 60565c812..8499fa33f 100644 --- a/src/Microsoft.AspNet.Security.Cookies/CookieAuthenticationOptions.cs +++ b/src/Microsoft.AspNet.Security.Cookies/CookieAuthenticationOptions.cs @@ -125,7 +125,7 @@ public string CookieName /// /// The TicketDataFormat is used to protect and unprotect the identity and other properties which are stored in the /// cookie value. If it is not provided a default data handler is created using the data protection service contained - /// in the IAppBuilder.Properties. The default data protection service is based on machine key when running on ASP.NET, + /// in the IBuilder.Properties. The default data protection service is based on machine key when running on ASP.NET, /// and on DPAPI when running in a different process. /// public ISecureDataFormat TicketDataFormat { get; set; } diff --git a/src/Microsoft.AspNet.Security.Facebook/FacebookAuthenticationExtensions.cs b/src/Microsoft.AspNet.Security.Facebook/FacebookAuthenticationExtensions.cs index cdaade120..7f7cb4ebd 100644 --- a/src/Microsoft.AspNet.Security.Facebook/FacebookAuthenticationExtensions.cs +++ b/src/Microsoft.AspNet.Security.Facebook/FacebookAuthenticationExtensions.cs @@ -6,17 +6,17 @@ namespace Microsoft.AspNet.Builder { /// - /// Extension methods for using + /// Extension methods for using . /// public static class FacebookAuthenticationExtensions { /// - /// Authenticate users using Facebook + /// Authenticate users using Facebook. /// - /// The passed to the configure method - /// The appId assigned by Facebook - /// The appSecret assigned by Facebook - /// The updated + /// The passed to the configure method. + /// The appId assigned by Facebook. + /// The appSecret assigned by Facebook. + /// The updated . public static IBuilder UseFacebookAuthentication([NotNull] this IBuilder app, [NotNull] string appId, [NotNull] string appSecret) { return app.UseFacebookAuthentication(new FacebookAuthenticationOptions() @@ -27,11 +27,11 @@ public static IBuilder UseFacebookAuthentication([NotNull] this IBuilder app, [N } /// - /// Authenticate users using Facebook + /// Authenticate users using Facebook. /// - /// The passed to the configure method - /// Middleware configuration options - /// The updated + /// The passed to the configure method. + /// The middleware configuration options. + /// The updated . public static IBuilder UseFacebookAuthentication([NotNull] this IBuilder app, [NotNull] FacebookAuthenticationOptions options) { if (string.IsNullOrEmpty(options.SignInAsAuthenticationType)) diff --git a/src/Microsoft.AspNet.Security.Facebook/FacebookAuthenticationMiddleware.cs b/src/Microsoft.AspNet.Security.Facebook/FacebookAuthenticationMiddleware.cs index 5a3ef41e6..af1da5c30 100644 --- a/src/Microsoft.AspNet.Security.Facebook/FacebookAuthenticationMiddleware.cs +++ b/src/Microsoft.AspNet.Security.Facebook/FacebookAuthenticationMiddleware.cs @@ -14,7 +14,7 @@ namespace Microsoft.AspNet.Security.Facebook { /// - /// ASP.NET middleware for authenticating users using Facebook + /// An ASP.NET middleware for authenticating users using Facebook. /// [SuppressMessage("Microsoft.Design", "CA1001:TypesThatOwnDisposableFieldsShouldBeDisposable", Justification = "Middleware is not disposable.")] public class FacebookAuthenticationMiddleware : AuthenticationMiddleware @@ -23,12 +23,12 @@ public class FacebookAuthenticationMiddleware : AuthenticationMiddleware - /// Initializes a + /// Initializes a new . /// - /// The next middleware in the application pipeline to invoke + /// The next middleware in the application pipeline to invoke. /// /// - /// Configuration options for the middleware + /// Configuration options for the middleware. public FacebookAuthenticationMiddleware( RequestDelegate next, IDataProtectionProvider dataProtectionProvider, diff --git a/src/Microsoft.AspNet.Security.Facebook/FacebookAuthenticationOptions.cs b/src/Microsoft.AspNet.Security.Facebook/FacebookAuthenticationOptions.cs index 983273446..1b9d2c145 100644 --- a/src/Microsoft.AspNet.Security.Facebook/FacebookAuthenticationOptions.cs +++ b/src/Microsoft.AspNet.Security.Facebook/FacebookAuthenticationOptions.cs @@ -11,12 +11,12 @@ namespace Microsoft.AspNet.Security.Facebook { /// - /// Configuration options for + /// Configuration options for . /// public class FacebookAuthenticationOptions : AuthenticationOptions { /// - /// Initializes a new + /// Initializes a new . /// [SuppressMessage("Microsoft.Globalization", "CA1303:Do not pass literals as localized parameters", MessageId = "Microsoft.AspNet.Security.Facebook.FacebookAuthenticationOptions.set_Caption(System.String)", Justification = "Not localizable.")] @@ -32,12 +32,12 @@ public FacebookAuthenticationOptions() } /// - /// Gets or sets the Facebook-assigned appId + /// Gets or sets the Facebook-assigned appId. /// public string AppId { get; set; } /// - /// Gets or sets the Facebook-assigned app secret + /// Gets or sets the Facebook-assigned app secret. /// public string AppSecret { get; set; } #if NET45 diff --git a/src/Microsoft.AspNet.Security.Facebook/Notifications/FacebookApplyRedirectContext.cs b/src/Microsoft.AspNet.Security.Facebook/Notifications/FacebookApplyRedirectContext.cs index 020e2d32e..e3e1b35b3 100644 --- a/src/Microsoft.AspNet.Security.Facebook/Notifications/FacebookApplyRedirectContext.cs +++ b/src/Microsoft.AspNet.Security.Facebook/Notifications/FacebookApplyRedirectContext.cs @@ -8,17 +8,17 @@ namespace Microsoft.AspNet.Security.Facebook { /// - /// Context passed when a Challenge causes a redirect to authorize endpoint in the Facebook middleware + /// The Context passed when a Challenge causes a redirect to authorize endpoint in the Facebook middleware. /// public class FacebookApplyRedirectContext : BaseContext { /// /// Creates a new context object. /// - /// The http request context - /// The Facebook middleware options - /// The authenticaiton properties of the challenge - /// The initial redirect URI + /// The http request context. + /// The Facebook middleware options. + /// The authentication properties of the challenge. + /// The initial redirect URI. [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings", MessageId = "3#", Justification = "Represents header value")] public FacebookApplyRedirectContext(HttpContext context, FacebookAuthenticationOptions options, @@ -36,7 +36,7 @@ public FacebookApplyRedirectContext(HttpContext context, FacebookAuthenticationO public string RedirectUri { get; private set; } /// - /// Gets the authentication properties of the challenge + /// Gets the authentication properties of the challenge. /// public AuthenticationProperties Properties { get; private set; } } diff --git a/src/Microsoft.AspNet.Security.Facebook/Notifications/FacebookAuthenticatedContext.cs b/src/Microsoft.AspNet.Security.Facebook/Notifications/FacebookAuthenticatedContext.cs index c173dfde8..6797ed495 100644 --- a/src/Microsoft.AspNet.Security.Facebook/Notifications/FacebookAuthenticatedContext.cs +++ b/src/Microsoft.AspNet.Security.Facebook/Notifications/FacebookAuthenticatedContext.cs @@ -17,12 +17,12 @@ namespace Microsoft.AspNet.Security.Facebook public class FacebookAuthenticatedContext : BaseContext { /// - /// Initializes a + /// Initializes a new . /// - /// The http environment - /// The JSON-serialized user - /// Facebook Access token - /// Seconds until expiration + /// The HTTP environment. + /// The JSON-serialized user. + /// The Facebook Access token. + /// Seconds until expiration. public FacebookAuthenticatedContext(HttpContext context, JObject user, string accessToken, string expires) : base(context) { @@ -43,49 +43,52 @@ public FacebookAuthenticatedContext(HttpContext context, JObject user, string ac } /// - /// Gets the JSON-serialized user + /// Gets the JSON-serialized user. /// public JObject User { get; private set; } /// - /// Gets the Facebook access token + /// Gets the Facebook access token. /// public string AccessToken { get; private set; } /// - /// Gets the Facebook access token expiration time + /// Gets the Facebook access token expiration time. /// public TimeSpan? ExpiresIn { get; set; } /// - /// Gets the Facebook user ID + /// Gets the Facebook user ID. /// public string Id { get; private set; } /// - /// Gets the user's name + /// Gets the user's name. /// public string Name { get; private set; } + /// + /// Gets the user's link. + /// public string Link { get; private set; } /// - /// Gets the Facebook username + /// Gets the Facebook username. /// public string UserName { get; private set; } /// - /// Gets the Facebook email + /// Gets the Facebook email. /// public string Email { get; private set; } /// - /// Gets the representing the user + /// Gets the representing the user. /// public ClaimsIdentity Identity { get; set; } /// - /// Gets or sets a property bag for common authentication properties + /// Gets or sets a property bag for common authentication properties. /// public AuthenticationProperties Properties { get; set; } diff --git a/src/Microsoft.AspNet.Security.Facebook/Notifications/FacebookAuthenticationNotifications.cs b/src/Microsoft.AspNet.Security.Facebook/Notifications/FacebookAuthenticationNotifications.cs index 22dbcfcc0..b9b33b125 100644 --- a/src/Microsoft.AspNet.Security.Facebook/Notifications/FacebookAuthenticationNotifications.cs +++ b/src/Microsoft.AspNet.Security.Facebook/Notifications/FacebookAuthenticationNotifications.cs @@ -7,12 +7,12 @@ namespace Microsoft.AspNet.Security.Facebook { /// - /// Default implementation. + /// The default implementation. /// public class FacebookAuthenticationNotifications : IFacebookAuthenticationNotifications { /// - /// Initializes a + /// Initializes a new . /// public FacebookAuthenticationNotifications() { @@ -38,7 +38,7 @@ public FacebookAuthenticationNotifications() public Action OnApplyRedirect { get; set; } /// - /// Invoked whenever Facebook succesfully authenticates a user + /// Invoked whenever Facebook succesfully authenticates a user. /// /// Contains information about the login session as well as the user . /// A representing the completed operation. @@ -58,9 +58,9 @@ public virtual Task ReturnEndpoint(FacebookReturnEndpointContext context) } /// - /// Called when a Challenge causes a redirect to authorize endpoint in the Facebook middleware + /// Called when a Challenge causes a redirect to authorize endpoint in the Facebook middleware. /// - /// Contains redirect URI and of the challenge + /// Contains redirect URI and of the challenge. public virtual void ApplyRedirect(FacebookApplyRedirectContext context) { OnApplyRedirect(context); diff --git a/src/Microsoft.AspNet.Security.Facebook/Notifications/FacebookReturnEndpointContext.cs b/src/Microsoft.AspNet.Security.Facebook/Notifications/FacebookReturnEndpointContext.cs index e32cad4ee..29786a906 100644 --- a/src/Microsoft.AspNet.Security.Facebook/Notifications/FacebookReturnEndpointContext.cs +++ b/src/Microsoft.AspNet.Security.Facebook/Notifications/FacebookReturnEndpointContext.cs @@ -7,15 +7,15 @@ namespace Microsoft.AspNet.Security.Facebook { /// - /// Provides context information to middleware providers. + /// Provides context information for notifications. /// public class FacebookReturnEndpointContext : ReturnEndpointContext { /// /// Creates a new context object. /// - /// The http environment - /// The authentication ticket + /// The http environment. + /// The authentication ticket. public FacebookReturnEndpointContext( HttpContext context, AuthenticationTicket ticket) diff --git a/src/Microsoft.AspNet.Security.Facebook/Notifications/IFacebookAuthenticationNotifications.cs b/src/Microsoft.AspNet.Security.Facebook/Notifications/IFacebookAuthenticationNotifications.cs index 530ea6505..236cba3ac 100644 --- a/src/Microsoft.AspNet.Security.Facebook/Notifications/IFacebookAuthenticationNotifications.cs +++ b/src/Microsoft.AspNet.Security.Facebook/Notifications/IFacebookAuthenticationNotifications.cs @@ -6,12 +6,12 @@ namespace Microsoft.AspNet.Security.Facebook { /// - /// Specifies callback methods which the invokes to enable developer control over the authentication process. /> + /// Specifies callback methods which the invokes to enable developer control over the authentication process. /// public interface IFacebookAuthenticationNotifications { /// - /// Invoked whenever Facebook succesfully authenticates a user + /// Invoked when Facebook succesfully authenticates a user. /// /// Contains information about the login session as well as the user . /// A representing the completed operation. @@ -25,9 +25,9 @@ public interface IFacebookAuthenticationNotifications Task ReturnEndpoint(FacebookReturnEndpointContext context); /// - /// Called when a Challenge causes a redirect to authorize endpoint in the Facebook middleware + /// Called when a Challenge causes a redirect to authorize endpoint in the Facebook middleware. /// - /// Contains redirect URI and of the challenge + /// Contains redirect URI and of the challenge. void ApplyRedirect(FacebookApplyRedirectContext context); } } diff --git a/src/Microsoft.AspNet.Security.Google/GoogleAuthenticationExtensions.cs b/src/Microsoft.AspNet.Security.Google/GoogleAuthenticationExtensions.cs index 120373535..cfac47773 100644 --- a/src/Microsoft.AspNet.Security.Google/GoogleAuthenticationExtensions.cs +++ b/src/Microsoft.AspNet.Security.Google/GoogleAuthenticationExtensions.cs @@ -6,17 +6,17 @@ namespace Microsoft.AspNet.Builder { /// - /// Extension methods for using + /// Extension methods for using . /// public static class GoogleAuthenticationExtensions { /// - /// Authenticate users using Google OAuth 2.0 + /// Authenticate users using Google OAuth 2.0. /// - /// The passed to the configure method - /// The google assigned client id - /// The google assigned client secret - /// The updated + /// The passed to the configure method. + /// The google assigned client id. + /// The google assigned client secret. + /// The updated . public static IBuilder UseGoogleAuthentication([NotNull] this IBuilder app, [NotNull] string clientId, [NotNull] string clientSecret) { return app.UseGoogleAuthentication( @@ -28,11 +28,11 @@ public static IBuilder UseGoogleAuthentication([NotNull] this IBuilder app, [Not } /// - /// Authenticate users using Google OAuth 2.0 + /// Authenticate users using Google OAuth 2.0. /// - /// The passed to the configure method - /// Middleware configuration options - /// The updated + /// The passed to the configure method. + /// Middleware configuration options. + /// The updated . public static IBuilder UseGoogleAuthentication([NotNull] this IBuilder app, [NotNull] GoogleAuthenticationOptions options) { if (string.IsNullOrEmpty(options.SignInAsAuthenticationType)) diff --git a/src/Microsoft.AspNet.Security.Google/GoogleAuthenticationMiddleware.cs b/src/Microsoft.AspNet.Security.Google/GoogleAuthenticationMiddleware.cs index 15c5c2a79..1105b149b 100644 --- a/src/Microsoft.AspNet.Security.Google/GoogleAuthenticationMiddleware.cs +++ b/src/Microsoft.AspNet.Security.Google/GoogleAuthenticationMiddleware.cs @@ -14,7 +14,7 @@ namespace Microsoft.AspNet.Security.Google { /// - /// ASP.NET middleware for authenticating users using Google OAuth 2.0 + /// An ASP.NET middleware for authenticating users using Google OAuth 2.0. /// [SuppressMessage("Microsoft.Design", "CA1001:TypesThatOwnDisposableFieldsShouldBeDisposable", Justification = "Middleware are not disposable.")] public class GoogleAuthenticationMiddleware : AuthenticationMiddleware @@ -23,12 +23,12 @@ public class GoogleAuthenticationMiddleware : AuthenticationMiddleware - /// Initializes a + /// Initializes a new . /// - /// The next middleware in the HTTP pipeline to invoke + /// The next middleware in the HTTP pipeline to invoke. /// /// - /// Configuration options for the middleware + /// Configuration options for the middleware. public GoogleAuthenticationMiddleware( RequestDelegate next, IDataProtectionProvider dataProtectionProvider, diff --git a/src/Microsoft.AspNet.Security.Google/GoogleAuthenticationOptions.cs b/src/Microsoft.AspNet.Security.Google/GoogleAuthenticationOptions.cs index fd7b06999..f03b7d2ef 100644 --- a/src/Microsoft.AspNet.Security.Google/GoogleAuthenticationOptions.cs +++ b/src/Microsoft.AspNet.Security.Google/GoogleAuthenticationOptions.cs @@ -10,12 +10,12 @@ namespace Microsoft.AspNet.Security.Google { /// - /// Configuration options for + /// Configuration options for . /// public class GoogleAuthenticationOptions : AuthenticationOptions { /// - /// Initializes a new + /// Initializes a new . /// [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1303:Do not pass literals as localized parameters", MessageId = "Microsoft.AspNet.Security.Google.GoogleAuthenticationOptions.set_Caption(System.String)", @@ -31,12 +31,12 @@ public GoogleAuthenticationOptions() } /// - /// Gets or sets the Google-assigned client id + /// Gets or sets the Google-assigned client id. /// public string ClientId { get; set; } /// - /// Gets or sets the Google-assigned client secret + /// Gets or sets the Google-assigned client secret. /// public string ClientSecret { get; set; } #if NET45 diff --git a/src/Microsoft.AspNet.Security.Google/Notifications/GoogleApplyRedirectContext.cs b/src/Microsoft.AspNet.Security.Google/Notifications/GoogleApplyRedirectContext.cs index ac020b563..7df6358dd 100644 --- a/src/Microsoft.AspNet.Security.Google/Notifications/GoogleApplyRedirectContext.cs +++ b/src/Microsoft.AspNet.Security.Google/Notifications/GoogleApplyRedirectContext.cs @@ -8,17 +8,17 @@ namespace Microsoft.AspNet.Security.Google { /// - /// Context passed when a Challenge causes a redirect to authorize endpoint in the Google OAuth 2.0 middleware + /// The Context passed when a Challenge causes a redirect to authorize endpoint in the Google OAuth 2.0 middleware. /// public class GoogleApplyRedirectContext : BaseContext { /// /// Creates a new context object. /// - /// The HTTP request context - /// The Google OAuth 2.0 middleware options - /// The authenticaiton properties of the challenge - /// The initial redirect URI + /// The HTTP request context. + /// The Google OAuth 2.0 middleware options. + /// The authentication properties of the challenge. + /// The initial redirect URI. [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings", MessageId = "3#", Justification = "Represents header value")] public GoogleApplyRedirectContext(HttpContext context, GoogleAuthenticationOptions options, @@ -36,7 +36,7 @@ public GoogleApplyRedirectContext(HttpContext context, GoogleAuthenticationOptio public string RedirectUri { get; private set; } /// - /// Gets the authenticaiton properties of the challenge + /// Gets the authentication properties of the challenge. /// public AuthenticationProperties Properties { get; private set; } } diff --git a/src/Microsoft.AspNet.Security.Google/Notifications/GoogleAuthenticatedContext.cs b/src/Microsoft.AspNet.Security.Google/Notifications/GoogleAuthenticatedContext.cs index ca8996276..84f535fb8 100644 --- a/src/Microsoft.AspNet.Security.Google/Notifications/GoogleAuthenticatedContext.cs +++ b/src/Microsoft.AspNet.Security.Google/Notifications/GoogleAuthenticatedContext.cs @@ -17,13 +17,13 @@ namespace Microsoft.AspNet.Security.Google public class GoogleAuthenticatedContext : BaseContext { /// - /// Initializes a + /// Initializes a new . /// - /// The HTTP environment - /// The JSON-serialized Google user info - /// Google OAuth 2.0 access token - /// Goolge OAuth 2.0 refresh token - /// Seconds until expiration + /// The HTTP environment. + /// The JSON-serialized Google user info. + /// Google OAuth 2.0 access token. + /// Goolge OAuth 2.0 refresh token. + /// Seconds until expiration. public GoogleAuthenticatedContext(HttpContext context, JObject user, string accessToken, string refreshToken, string expires) : base(context) @@ -47,20 +47,20 @@ public GoogleAuthenticatedContext(HttpContext context, JObject user, string acce } /// - /// Gets the JSON-serialized user + /// Gets the JSON-serialized user. /// /// - /// Contains the Google user obtained from the endpoint https://www.googleapis.com/oauth2/v3/userinfo + /// Contains the Google user obtained from the userinfo endpoint. /// public JObject User { get; private set; } /// - /// Gets the Google access token + /// Gets the Google access token. /// public string AccessToken { get; private set; } /// - /// Gets the Google refresh token + /// Gets the Google refresh token. /// /// /// This value is not null only when access_type authorize parameter is offline. @@ -68,47 +68,47 @@ public GoogleAuthenticatedContext(HttpContext context, JObject user, string acce public string RefreshToken { get; private set; } /// - /// Gets the Google access token expiration time + /// Gets the Google access token expiration time. /// public TimeSpan? ExpiresIn { get; set; } /// - /// Gets the Google user ID + /// Gets the Google user ID. /// public string Id { get; private set; } /// - /// Gets the user's name + /// Gets the user's name. /// public string Name { get; private set; } /// - /// Gets the user's given name + /// Gets the user's given name. /// public string GivenName { get; set; } /// - /// Gets the user's family name + /// Gets the user's family name. /// public string FamilyName { get; set; } /// - /// Gets the user's profile link + /// Gets the user's profile link. /// public string Profile { get; private set; } /// - /// Gets the user's email + /// Gets the user's email. /// public string Email { get; private set; } /// - /// Gets the representing the user + /// Gets the representing the user. /// public ClaimsIdentity Identity { get; set; } /// - /// Gets or sets a property bag for common authentication properties + /// Gets or sets a property bag for common authentication properties. /// public AuthenticationProperties Properties { get; set; } diff --git a/src/Microsoft.AspNet.Security.Google/Notifications/GoogleAuthenticationNotifications.cs b/src/Microsoft.AspNet.Security.Google/Notifications/GoogleAuthenticationNotifications.cs index af93619ed..36f936895 100644 --- a/src/Microsoft.AspNet.Security.Google/Notifications/GoogleAuthenticationNotifications.cs +++ b/src/Microsoft.AspNet.Security.Google/Notifications/GoogleAuthenticationNotifications.cs @@ -7,19 +7,18 @@ namespace Microsoft.AspNet.Security.Google { /// - /// Default implementation. + /// The default implementation. /// public class GoogleAuthenticationNotifications : IGoogleAuthenticationNotifications { /// - /// Initializes a + /// Initializes a new . /// public GoogleAuthenticationNotifications() { OnAuthenticated = context => Task.FromResult(null); OnReturnEndpoint = context => Task.FromResult(null); - OnApplyRedirect = context => - context.Response.Redirect(context.RedirectUri); + OnApplyRedirect = context => context.Response.Redirect(context.RedirectUri); } /// @@ -38,7 +37,7 @@ public GoogleAuthenticationNotifications() public Action OnApplyRedirect { get; set; } /// - /// Invoked whenever Google succesfully authenticates a user + /// Invoked whenever Google succesfully authenticates a user. /// /// Contains information about the login session as well as the user . /// A representing the completed operation. @@ -58,9 +57,9 @@ public virtual Task ReturnEndpoint(GoogleReturnEndpointContext context) } /// - /// Called when a Challenge causes a redirect to authorize endpoint in the Google OAuth 2.0 middleware + /// Called when a Challenge causes a redirect to authorize endpoint in the Google OAuth 2.0 middleware. /// - /// Contains redirect URI and of the challenge + /// Contains redirect URI and of the challenge. public virtual void ApplyRedirect(GoogleApplyRedirectContext context) { OnApplyRedirect(context); diff --git a/src/Microsoft.AspNet.Security.Google/Notifications/GoogleReturnEndpointContext.cs b/src/Microsoft.AspNet.Security.Google/Notifications/GoogleReturnEndpointContext.cs index 7172455ad..ce6a13742 100644 --- a/src/Microsoft.AspNet.Security.Google/Notifications/GoogleReturnEndpointContext.cs +++ b/src/Microsoft.AspNet.Security.Google/Notifications/GoogleReturnEndpointContext.cs @@ -12,10 +12,10 @@ namespace Microsoft.AspNet.Security.Google public class GoogleReturnEndpointContext : ReturnEndpointContext { /// - /// Initialize a + /// Initialize a . /// - /// HTTP environment - /// The authentication ticket + /// The HTTP environment. + /// The authentication ticket. public GoogleReturnEndpointContext( HttpContext context, AuthenticationTicket ticket) diff --git a/src/Microsoft.AspNet.Security.Google/Notifications/IGoogleAuthenticationNotifications.cs b/src/Microsoft.AspNet.Security.Google/Notifications/IGoogleAuthenticationNotifications.cs index 7bf9a34ab..13930346c 100644 --- a/src/Microsoft.AspNet.Security.Google/Notifications/IGoogleAuthenticationNotifications.cs +++ b/src/Microsoft.AspNet.Security.Google/Notifications/IGoogleAuthenticationNotifications.cs @@ -6,12 +6,12 @@ namespace Microsoft.AspNet.Security.Google { /// - /// Specifies callback methods which the invokes to enable developer control over the authentication process. /> + /// Specifies callback methods which the invokes to enable developer control over the authentication process. /// public interface IGoogleAuthenticationNotifications { /// - /// Invoked whenever Google succesfully authenticates a user + /// Invoked whenever Google succesfully authenticates a user. /// /// Contains information about the login session as well as the user . /// A representing the completed operation. @@ -25,9 +25,9 @@ public interface IGoogleAuthenticationNotifications Task ReturnEndpoint(GoogleReturnEndpointContext context); /// - /// Called when a Challenge causes a redirect to authorize endpoint in the Google OAuth 2.0 middleware + /// Called when a Challenge causes a redirect to authorize endpoint in the Google OAuth 2.0 middleware. /// - /// Contains redirect URI and of the challenge + /// Contains redirect URI and of the challenge. void ApplyRedirect(GoogleApplyRedirectContext context); } } diff --git a/src/Microsoft.AspNet.Security.MicrosoftAccount/Microsoft.AspNet.Security.MicrosoftAccount.kproj b/src/Microsoft.AspNet.Security.MicrosoftAccount/Microsoft.AspNet.Security.MicrosoftAccount.kproj new file mode 100644 index 000000000..dbdeeb34c --- /dev/null +++ b/src/Microsoft.AspNet.Security.MicrosoftAccount/Microsoft.AspNet.Security.MicrosoftAccount.kproj @@ -0,0 +1,28 @@ + + + + 12.0 + $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) + + + + 1fcf26c2-a3c7-4308-b698-4afc3560bc0c + Library + + + + ConsoleDebugger + + + WebDebugger + + + + + + + + 2.0 + + + \ No newline at end of file diff --git a/src/Microsoft.AspNet.Security.MicrosoftAccount/MicrosoftAccountAuthenticationDefaults.cs b/src/Microsoft.AspNet.Security.MicrosoftAccount/MicrosoftAccountAuthenticationDefaults.cs new file mode 100644 index 000000000..8f83dac3e --- /dev/null +++ b/src/Microsoft.AspNet.Security.MicrosoftAccount/MicrosoftAccountAuthenticationDefaults.cs @@ -0,0 +1,10 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +namespace Microsoft.AspNet.Security.MicrosoftAccount +{ + public static class MicrosoftAccountAuthenticationDefaults + { + public const string AuthenticationType = "Microsoft"; + } +} diff --git a/src/Microsoft.AspNet.Security.MicrosoftAccount/MicrosoftAccountAuthenticationExtensions.cs b/src/Microsoft.AspNet.Security.MicrosoftAccount/MicrosoftAccountAuthenticationExtensions.cs new file mode 100644 index 000000000..468d27907 --- /dev/null +++ b/src/Microsoft.AspNet.Security.MicrosoftAccount/MicrosoftAccountAuthenticationExtensions.cs @@ -0,0 +1,45 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using Microsoft.AspNet.Security.MicrosoftAccount; + +namespace Microsoft.AspNet.Builder +{ + /// + /// Extension methods for using + /// + public static class MicrosoftAccountAuthenticationExtensions + { + /// + /// Authenticate users using Microsoft Account. + /// + /// The passed to the configure method. + /// The application client ID assigned by the Microsoft authentication service. + /// The application client secret assigned by the Microsoft authentication service. + /// The updated . + public static IBuilder UseMicrosoftAccountAuthentication([NotNull] this IBuilder app, [NotNull] string clientId, [NotNull] string clientSecret) + { + return app.UseMicrosoftAccountAuthentication( + new MicrosoftAccountAuthenticationOptions + { + ClientId = clientId, + ClientSecret = clientSecret, + }); + } + + /// + /// Authenticate users using Microsoft Account. + /// + /// The passed to the configure method. + /// The middleware configuration options. + /// The updated . + public static IBuilder UseMicrosoftAccountAuthentication([NotNull] this IBuilder app, [NotNull] MicrosoftAccountAuthenticationOptions options) + { + if (string.IsNullOrEmpty(options.SignInAsAuthenticationType)) + { + options.SignInAsAuthenticationType = app.GetDefaultSignInAsAuthenticationType(); + } + return app.UseMiddleware(options); + } + } +} diff --git a/src/Microsoft.AspNet.Security.MicrosoftAccount/MicrosoftAccountAuthenticationHandler.cs b/src/Microsoft.AspNet.Security.MicrosoftAccount/MicrosoftAccountAuthenticationHandler.cs new file mode 100644 index 000000000..6ee11c1d8 --- /dev/null +++ b/src/Microsoft.AspNet.Security.MicrosoftAccount/MicrosoftAccountAuthenticationHandler.cs @@ -0,0 +1,257 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Collections.Generic; +using System.Net.Http; +using System.Security.Claims; +using System.Threading.Tasks; +using Microsoft.AspNet.Http; +using Microsoft.AspNet.Http.Security; +using Microsoft.AspNet.Security.Infrastructure; +using Microsoft.AspNet.WebUtilities; +using Microsoft.Framework.Logging; +using Newtonsoft.Json.Linq; + +namespace Microsoft.AspNet.Security.MicrosoftAccount +{ + internal class MicrosoftAccountAuthenticationHandler : AuthenticationHandler + { + private const string TokenEndpoint = "https://login.live.com/oauth20_token.srf"; + private const string GraphApiEndpoint = "https://apis.live.net/v5.0/me"; + + private readonly ILogger _logger; + private readonly HttpClient _httpClient; + + public MicrosoftAccountAuthenticationHandler(HttpClient httpClient, ILogger logger) + { + _httpClient = httpClient; + _logger = logger; + } + + public override async Task InvokeAsync() + { + if (Options.CallbackPath.HasValue && Options.CallbackPath == Request.Path) + { + return await InvokeReturnPathAsync(); + } + return false; + } + + protected override AuthenticationTicket AuthenticateCore() + { + return AuthenticateCoreAsync().Result; + } + + protected override async Task AuthenticateCoreAsync() + { + AuthenticationProperties properties = null; + try + { + string code = null; + string state = null; + + IReadableStringCollection query = Request.Query; + IList values = query.GetValues("code"); + if (values != null && values.Count == 1) + { + code = values[0]; + } + values = query.GetValues("state"); + if (values != null && values.Count == 1) + { + state = values[0]; + } + + properties = Options.StateDataFormat.Unprotect(state); + if (properties == null) + { + return null; + } + + // OAuth2 10.12 CSRF + if (!ValidateCorrelationId(properties, _logger)) + { + return new AuthenticationTicket(null, properties); + } + + var tokenRequestParameters = new List>() + { + new KeyValuePair("client_id", Options.ClientId), + new KeyValuePair("redirect_uri", GenerateRedirectUri()), + new KeyValuePair("client_secret", Options.ClientSecret), + new KeyValuePair("code", code), + new KeyValuePair("grant_type", "authorization_code"), + }; + + var requestContent = new FormUrlEncodedContent(tokenRequestParameters); + + HttpResponseMessage response = await _httpClient.PostAsync(TokenEndpoint, requestContent, Context.RequestAborted); + response.EnsureSuccessStatusCode(); + string oauthTokenResponse = await response.Content.ReadAsStringAsync(); + + JObject oauth2Token = JObject.Parse(oauthTokenResponse); + var accessToken = oauth2Token["access_token"].Value(); + + // Refresh token is only available when wl.offline_access is request. + // Otherwise, it is null. + var refreshToken = oauth2Token.Value("refresh_token"); + var expire = oauth2Token.Value("expires_in"); + + if (string.IsNullOrWhiteSpace(accessToken)) + { + _logger.WriteWarning("Access token was not found"); + return new AuthenticationTicket(null, properties); + } + + HttpResponseMessage graphResponse = await _httpClient.GetAsync( + GraphApiEndpoint + "?access_token=" + Uri.EscapeDataString(accessToken), Context.RequestAborted); + graphResponse.EnsureSuccessStatusCode(); + string accountString = await graphResponse.Content.ReadAsStringAsync(); + JObject accountInformation = JObject.Parse(accountString); + + var context = new MicrosoftAccountAuthenticatedContext(Context, accountInformation, accessToken, + refreshToken, expire); + context.Identity = new ClaimsIdentity( + new[] + { + new Claim(ClaimTypes.NameIdentifier, context.Id, "http://www.w3.org/2001/XMLSchema#string", Options.AuthenticationType), + new Claim(ClaimTypes.Name, context.Name, "http://www.w3.org/2001/XMLSchema#string", Options.AuthenticationType), + new Claim("urn:microsoftaccount:id", context.Id, "http://www.w3.org/2001/XMLSchema#string", Options.AuthenticationType), + new Claim("urn:microsoftaccount:name", context.Name, "http://www.w3.org/2001/XMLSchema#string", Options.AuthenticationType) + }, + Options.AuthenticationType, + ClaimsIdentity.DefaultNameClaimType, + ClaimsIdentity.DefaultRoleClaimType); + if (!string.IsNullOrWhiteSpace(context.Email)) + { + context.Identity.AddClaim(new Claim(ClaimTypes.Email, context.Email, "http://www.w3.org/2001/XMLSchema#string", Options.AuthenticationType)); + } + + await Options.Notifications.Authenticated(context); + + context.Properties = properties; + + return new AuthenticationTicket(context.Identity, context.Properties); + } + catch (Exception ex) + { + _logger.WriteError("Authentication failed", ex); + return new AuthenticationTicket(null, properties); + } + } + + protected override void ApplyResponseChallenge() + { + if (Response.StatusCode != 401) + { + return; + } + + // Active middleware should redirect on 401 even if there wasn't an explicit challenge. + if (ChallengeContext == null && Options.AuthenticationMode == AuthenticationMode.Passive) + { + return; + } + + string baseUri = Request.Scheme + "://" + Request.Host + Request.PathBase; + + string currentUri = baseUri + Request.Path + Request.QueryString; + + string redirectUri = baseUri + Options.CallbackPath; + + AuthenticationProperties properties; + if (ChallengeContext == null) + { + properties = new AuthenticationProperties(); + } + else + { + properties = new AuthenticationProperties(ChallengeContext.Properties); + } + if (string.IsNullOrEmpty(properties.RedirectUri)) + { + properties.RedirectUri = currentUri; + } + + // OAuth2 10.12 CSRF + GenerateCorrelationId(properties); + + // OAuth2 3.3 space separated + string scope = string.Join(" ", Options.Scope); + // LiveID requires a scope string, so if the user didn't set one we go for the least possible. + if (string.IsNullOrWhiteSpace(scope)) + { + scope = "wl.basic"; + } + + string state = Options.StateDataFormat.Protect(properties); + + string authorizationEndpoint = + "https://login.live.com/oauth20_authorize.srf" + + "?client_id=" + Uri.EscapeDataString(Options.ClientId) + + "&scope=" + Uri.EscapeDataString(scope) + + "&response_type=code" + + "&redirect_uri=" + Uri.EscapeDataString(redirectUri) + + "&state=" + Uri.EscapeDataString(state); + + var redirectContext = new MicrosoftAccountApplyRedirectContext( + Context, Options, + properties, authorizationEndpoint); + Options.Notifications.ApplyRedirect(redirectContext); + } + + public async Task InvokeReturnPathAsync() + { + AuthenticationTicket model = await AuthenticateAsync(); + if (model == null) + { + _logger.WriteWarning("Invalid return state, unable to redirect."); + Response.StatusCode = 500; + return true; + } + + var context = new MicrosoftAccountReturnEndpointContext(Context, model); + context.SignInAsAuthenticationType = Options.SignInAsAuthenticationType; + context.RedirectUri = model.Properties.RedirectUri; + model.Properties.RedirectUri = null; + + await Options.Notifications.ReturnEndpoint(context); + + if (context.SignInAsAuthenticationType != null && context.Identity != null) + { + ClaimsIdentity signInIdentity = context.Identity; + if (!string.Equals(signInIdentity.AuthenticationType, context.SignInAsAuthenticationType, StringComparison.Ordinal)) + { + signInIdentity = new ClaimsIdentity(signInIdentity.Claims, context.SignInAsAuthenticationType, signInIdentity.NameClaimType, signInIdentity.RoleClaimType); + } + Context.Response.SignIn(context.Properties, signInIdentity); + } + + if (!context.IsRequestCompleted && context.RedirectUri != null) + { + if (context.Identity == null) + { + // add a redirect hint that sign-in failed in some way + context.RedirectUri = QueryHelpers.AddQueryString(context.RedirectUri, "error", "access_denied"); + } + Response.Redirect(context.RedirectUri); + context.RequestCompleted(); + } + + return context.IsRequestCompleted; + } + + private string GenerateRedirectUri() + { + string requestPrefix = Request.Scheme + "://" + Request.Host; + + return requestPrefix + RequestPathBase + Options.CallbackPath; + } + + protected override void ApplyResponseGrant() + { + // N/A - No SignIn or SignOut support. + } + } +} diff --git a/src/Microsoft.AspNet.Security.MicrosoftAccount/MicrosoftAccountAuthenticationMiddleware.cs b/src/Microsoft.AspNet.Security.MicrosoftAccount/MicrosoftAccountAuthenticationMiddleware.cs new file mode 100644 index 000000000..0bd8f4c3e --- /dev/null +++ b/src/Microsoft.AspNet.Security.MicrosoftAccount/MicrosoftAccountAuthenticationMiddleware.cs @@ -0,0 +1,98 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Diagnostics.CodeAnalysis; +using System.Globalization; +using System.Net.Http; +using Microsoft.AspNet.Builder; +using Microsoft.AspNet.Security.DataHandler; +using Microsoft.AspNet.Security.DataProtection; +using Microsoft.AspNet.Security.Infrastructure; +using Microsoft.Framework.Logging; + +namespace Microsoft.AspNet.Security.MicrosoftAccount +{ + /// + /// An ASP.NET middleware for authenticating users using the Microsoft Account service. + /// + [SuppressMessage("Microsoft.Design", "CA1001:TypesThatOwnDisposableFieldsShouldBeDisposable", Justification = "Middleware are not disposable.")] + public class MicrosoftAccountAuthenticationMiddleware : AuthenticationMiddleware + { + private readonly ILogger _logger; + private readonly HttpClient _httpClient; + + /// + /// Initializes a new . + /// + /// The next middleware in the HTTP pipeline to invoke. + /// + /// + /// Configuration options for the middleware. + public MicrosoftAccountAuthenticationMiddleware( + RequestDelegate next, + IDataProtectionProvider dataProtectionProvider, + ILoggerFactory loggerFactory, + MicrosoftAccountAuthenticationOptions options) + : base(next, options) + { + if (string.IsNullOrWhiteSpace(Options.ClientId)) + { + throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, Resources.Exception_OptionMustBeProvided, "ClientId")); + } + if (string.IsNullOrWhiteSpace(Options.ClientSecret)) + { + throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, Resources.Exception_OptionMustBeProvided, "ClientSecret")); + } + + _logger = loggerFactory.Create(typeof(MicrosoftAccountAuthenticationMiddleware).FullName); + + if (Options.Notifications == null) + { + Options.Notifications = new MicrosoftAccountAuthenticationNotifications(); + } + if (Options.StateDataFormat == null) + { + IDataProtector dataProtector = DataProtectionHelpers.CreateDataProtector(dataProtectionProvider, + typeof(MicrosoftAccountAuthenticationMiddleware).FullName, options.AuthenticationType, "v1"); + Options.StateDataFormat = new PropertiesDataFormat(dataProtector); + } + + _httpClient = new HttpClient(ResolveHttpMessageHandler(Options)); + _httpClient.Timeout = Options.BackchannelTimeout; + _httpClient.MaxResponseContentBufferSize = 1024 * 1024 * 10; // 10 MB + } + + /// + /// Provides the object for processing authentication-related requests. + /// + /// An configured with the supplied to the constructor. + protected override AuthenticationHandler CreateHandler() + { + return new MicrosoftAccountAuthenticationHandler(_httpClient, _logger); + } + + [SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Justification = "Managed by caller")] + private static HttpMessageHandler ResolveHttpMessageHandler(MicrosoftAccountAuthenticationOptions options) + { + HttpMessageHandler handler = options.BackchannelHttpHandler ?? +#if NET45 + new WebRequestHandler(); + // If they provided a validator, apply it or fail. + if (options.BackchannelCertificateValidator != null) + { + // Set the cert validate callback + var webRequestHandler = handler as WebRequestHandler; + if (webRequestHandler == null) + { + throw new InvalidOperationException(Resources.Exception_ValidatorHandlerMismatch); + } + webRequestHandler.ServerCertificateValidationCallback = options.BackchannelCertificateValidator.Validate; + } +#else + new WinHttpHandler(); +#endif + return handler; + } + } +} diff --git a/src/Microsoft.AspNet.Security.MicrosoftAccount/MicrosoftAccountAuthenticationOptions.cs b/src/Microsoft.AspNet.Security.MicrosoftAccount/MicrosoftAccountAuthenticationOptions.cs new file mode 100644 index 000000000..47ee6fe0e --- /dev/null +++ b/src/Microsoft.AspNet.Security.MicrosoftAccount/MicrosoftAccountAuthenticationOptions.cs @@ -0,0 +1,106 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using System.Net.Http; +using Microsoft.AspNet.Http; +using Microsoft.AspNet.Http.Security; + +namespace Microsoft.AspNet.Security.MicrosoftAccount +{ + /// + /// Configuration options for . + /// + public class MicrosoftAccountAuthenticationOptions : AuthenticationOptions + { + /// + /// Initializes a new . + /// + public MicrosoftAccountAuthenticationOptions() + : base(MicrosoftAccountAuthenticationDefaults.AuthenticationType) + { + Caption = MicrosoftAccountAuthenticationDefaults.AuthenticationType; + CallbackPath = new PathString("/signin-microsoft"); + AuthenticationMode = AuthenticationMode.Passive; + Scope = new List(); + BackchannelTimeout = TimeSpan.FromSeconds(60); + } +#if NET45 + /// + /// Gets or sets the a pinned certificate validator to use to validate the endpoints used + /// in back channel communications belong to Microsoft Account. + /// + /// + /// The pinned certificate validator. + /// + /// If this property is null then the default certificate checks are performed, + /// validating the subject name and if the signing chain is a trusted party. + public ICertificateValidator BackchannelCertificateValidator { get; set; } +#endif + /// + /// Get or sets the text that the user can display on a sign in user interface. + /// + /// + /// The default value is 'Microsoft'. + /// + public string Caption + { + get { return Description.Caption; } + set { Description.Caption = value; } + } + + /// + /// The application client ID assigned by the Microsoft authentication service. + /// + public string ClientId { get; set; } + + /// + /// The application client secret assigned by the Microsoft authentication service. + /// + public string ClientSecret { get; set; } + + /// + /// Gets or sets timeout value in milliseconds for back channel communications with Microsoft. + /// + /// + /// The back channel timeout. + /// + public TimeSpan BackchannelTimeout { get; set; } + + /// + /// The HttpMessageHandler used to communicate with Microsoft. + /// This cannot be set at the same time as BackchannelCertificateValidator unless the value + /// can be downcast to a WebRequestHandler. + /// + public HttpMessageHandler BackchannelHttpHandler { get; set; } + + /// + /// A list of permissions to request. + /// + public IList Scope { get; private set; } + + /// + /// The request path within the application's base path where the user-agent will be returned. + /// The middleware will process this request when it arrives. + /// Default value is "/signin-microsoft". + /// + public PathString CallbackPath { get; set; } + + /// + /// Gets or sets the name of another authentication middleware which will be responsible for actually issuing a user . + /// + public string SignInAsAuthenticationType { get; set; } + + /// + /// Gets or sets the used to handle authentication events. + /// + public IMicrosoftAccountAuthenticationNotifications Notifications { get; set; } + + /// + /// Gets or sets the type used to secure data handled by the middleware. + /// + public ISecureDataFormat StateDataFormat { get; set; } + } +} diff --git a/src/Microsoft.AspNet.Security.MicrosoftAccount/NotNullAttribute.cs b/src/Microsoft.AspNet.Security.MicrosoftAccount/NotNullAttribute.cs new file mode 100644 index 000000000..f3900accc --- /dev/null +++ b/src/Microsoft.AspNet.Security.MicrosoftAccount/NotNullAttribute.cs @@ -0,0 +1,12 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; + +namespace Microsoft.AspNet.Security.MicrosoftAccount +{ + [AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false)] + internal sealed class NotNullAttribute : Attribute + { + } +} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Security.MicrosoftAccount/Notifications/IMicrosoftAccountAuthenticationNotifications.cs b/src/Microsoft.AspNet.Security.MicrosoftAccount/Notifications/IMicrosoftAccountAuthenticationNotifications.cs new file mode 100644 index 000000000..d7c43a463 --- /dev/null +++ b/src/Microsoft.AspNet.Security.MicrosoftAccount/Notifications/IMicrosoftAccountAuthenticationNotifications.cs @@ -0,0 +1,33 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System.Threading.Tasks; + +namespace Microsoft.AspNet.Security.MicrosoftAccount +{ + /// + /// Specifies callback methods which the invokes to enable developer control over the authentication process. + /// + public interface IMicrosoftAccountAuthenticationNotifications + { + /// + /// Invoked whenever Microsoft succesfully authenticates a user. + /// + /// Contains information about the login session as well as the user . + /// A representing the completed operation. + Task Authenticated(MicrosoftAccountAuthenticatedContext context); + + /// + /// Invoked prior to the being saved in a local cookie and the browser being redirected to the originally requested URL. + /// + /// + /// A representing the completed operation. + Task ReturnEndpoint(MicrosoftAccountReturnEndpointContext context); + + /// + /// Called when a Challenge causes a redirect to authorize endpoint in the Microsoft middleware. + /// + /// Contains redirect URI and of the challenge. + void ApplyRedirect(MicrosoftAccountApplyRedirectContext context); + } +} diff --git a/src/Microsoft.AspNet.Security.MicrosoftAccount/Notifications/MicrosoftAccountApplyRedirectContext.cs b/src/Microsoft.AspNet.Security.MicrosoftAccount/Notifications/MicrosoftAccountApplyRedirectContext.cs new file mode 100644 index 000000000..f61a9eee4 --- /dev/null +++ b/src/Microsoft.AspNet.Security.MicrosoftAccount/Notifications/MicrosoftAccountApplyRedirectContext.cs @@ -0,0 +1,40 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using Microsoft.AspNet.Http; +using Microsoft.AspNet.Http.Security; +using Microsoft.AspNet.Security.Notifications; + +namespace Microsoft.AspNet.Security.MicrosoftAccount +{ + /// + /// Context passed when a Challenge causes a redirect to authorize endpoint in the Microsoft account middleware. + /// + public class MicrosoftAccountApplyRedirectContext : BaseContext + { + /// + /// Creates a new context object. + /// + /// The HTTP request context. + /// The Microsoft account middleware options. + /// The authentication properties of the challenge. + /// The initial redirect URI. + public MicrosoftAccountApplyRedirectContext(HttpContext context, MicrosoftAccountAuthenticationOptions options, + AuthenticationProperties properties, string redirectUri) + : base(context, options) + { + RedirectUri = redirectUri; + Properties = properties; + } + + /// + /// Gets the URI used for the redirect operation. + /// + public string RedirectUri { get; private set; } + + /// + /// Gets the authentication properties of the challenge. + /// + public AuthenticationProperties Properties { get; private set; } + } +} diff --git a/src/Microsoft.AspNet.Security.MicrosoftAccount/Notifications/MicrosoftAccountAuthenticatedContext.cs b/src/Microsoft.AspNet.Security.MicrosoftAccount/Notifications/MicrosoftAccountAuthenticatedContext.cs new file mode 100644 index 000000000..ef2b0b50f --- /dev/null +++ b/src/Microsoft.AspNet.Security.MicrosoftAccount/Notifications/MicrosoftAccountAuthenticatedContext.cs @@ -0,0 +1,130 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Security.Claims; +using Microsoft.AspNet.Http; +using Microsoft.AspNet.Http.Security; +using Microsoft.AspNet.Security.Notifications; +using Newtonsoft.Json.Linq; + +namespace Microsoft.AspNet.Security.MicrosoftAccount +{ + /// + /// Contains information about the login session as well as the user . + /// + public class MicrosoftAccountAuthenticatedContext : BaseContext + { + /// + /// Initializes a new . + /// + /// The HTTP environment. + /// The JSON-serialized user. + /// The access token provided by the Microsoft authentication service. + /// The refresh token provided by Microsoft authentication service. + /// Seconds until expiration. + public MicrosoftAccountAuthenticatedContext(HttpContext context, [NotNull] JObject user, string accessToken, + string refreshToken, string expires) + : base(context) + { + IDictionary userAsDictionary = user; + + User = user; + AccessToken = accessToken; + RefreshToken = refreshToken; + + int expiresValue; + if (Int32.TryParse(expires, NumberStyles.Integer, CultureInfo.InvariantCulture, out expiresValue)) + { + ExpiresIn = TimeSpan.FromSeconds(expiresValue); + } + + JToken userId = User["id"]; + if (userId == null) + { + throw new ArgumentException(Resources.Exception_MissingId, "user"); + } + + Id = userId.ToString(); + Name = PropertyValueIfExists("name", userAsDictionary); + FirstName = PropertyValueIfExists("first_name", userAsDictionary); + LastName = PropertyValueIfExists("last_name", userAsDictionary); + + if (userAsDictionary.ContainsKey("emails")) + { + JToken emailsNode = user["emails"]; + foreach (var childAsProperty in emailsNode.OfType().Where(childAsProperty => childAsProperty.Name == "preferred")) + { + Email = childAsProperty.Value.ToString(); + } + } + } + + /// + /// Gets the JSON-serialized user. + /// + public JObject User { get; private set; } + + /// + /// Gets the access token provided by the Microsoft authenication service. + /// + public string AccessToken { get; private set; } + + /// + /// Gets the refresh token provided by Microsoft authentication service. + /// + /// + /// Refresh token is only available when wl.offline_access is request. + /// Otherwise, it is null. + /// + public string RefreshToken { get; private set; } + + /// + /// Gets the Microsoft access token expiration time. + /// + public TimeSpan? ExpiresIn { get; set; } + + /// + /// Gets the Microsoft Account user ID. + /// + public string Id { get; private set; } + + /// + /// Gets the user's name. + /// + public string Name { get; private set; } + + /// + /// Gets the user's first name. + /// + public string FirstName { get; private set; } + + /// + /// Gets the user's last name. + /// + public string LastName { get; private set; } + + /// + /// Gets the user's email address. + /// + public string Email { get; private set; } + + /// + /// Gets the representing the user. + /// + public ClaimsIdentity Identity { get; set; } + + /// + /// Gets or sets a property bag for common authentication properties. + /// + public AuthenticationProperties Properties { get; set; } + + private static string PropertyValueIfExists(string property, IDictionary dictionary) + { + return dictionary.ContainsKey(property) ? dictionary[property].ToString() : null; + } + } +} diff --git a/src/Microsoft.AspNet.Security.MicrosoftAccount/Notifications/MicrosoftAccountAuthenticationNotifications.cs b/src/Microsoft.AspNet.Security.MicrosoftAccount/Notifications/MicrosoftAccountAuthenticationNotifications.cs new file mode 100644 index 000000000..deb561b94 --- /dev/null +++ b/src/Microsoft.AspNet.Security.MicrosoftAccount/Notifications/MicrosoftAccountAuthenticationNotifications.cs @@ -0,0 +1,68 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Threading.Tasks; + +namespace Microsoft.AspNet.Security.MicrosoftAccount +{ + /// + /// Default implementation. + /// + public class MicrosoftAccountAuthenticationNotifications : IMicrosoftAccountAuthenticationNotifications + { + /// + /// Initializes a new + /// + public MicrosoftAccountAuthenticationNotifications() + { + OnAuthenticated = context => Task.FromResult(0); + OnReturnEndpoint = context => Task.FromResult(0); + OnApplyRedirect = context => context.Response.Redirect(context.RedirectUri); + } + + /// + /// Gets or sets the function that is invoked when the Authenticated method is invoked. + /// + public Func OnAuthenticated { get; set; } + + /// + /// Gets or sets the function that is invoked when the ReturnEndpoint method is invoked. + /// + public Func OnReturnEndpoint { get; set; } + + /// + /// Gets or sets the delegate that is invoked when the ApplyRedirect method is invoked. + /// + public Action OnApplyRedirect { get; set; } + + /// + /// Invoked whenever Microsoft succesfully authenticates a user + /// + /// Contains information about the login session as well as the user . + /// A representing the completed operation. + public virtual Task Authenticated(MicrosoftAccountAuthenticatedContext context) + { + return OnAuthenticated(context); + } + + /// + /// Invoked prior to the being saved in a local cookie and the browser being redirected to the originally requested URL. + /// + /// Contains information about the login session as well as the user + /// A representing the completed operation. + public virtual Task ReturnEndpoint(MicrosoftAccountReturnEndpointContext context) + { + return OnReturnEndpoint(context); + } + + /// + /// Called when a Challenge causes a redirect to authorize endpoint in the Microsoft account middleware. + /// + /// Contains redirect URI and of the challenge. + public virtual void ApplyRedirect(MicrosoftAccountApplyRedirectContext context) + { + OnApplyRedirect(context); + } + } +} diff --git a/src/Microsoft.AspNet.Security.MicrosoftAccount/Notifications/MicrosoftAccountReturnEndpointContext.cs b/src/Microsoft.AspNet.Security.MicrosoftAccount/Notifications/MicrosoftAccountReturnEndpointContext.cs new file mode 100644 index 000000000..93e767024 --- /dev/null +++ b/src/Microsoft.AspNet.Security.MicrosoftAccount/Notifications/MicrosoftAccountReturnEndpointContext.cs @@ -0,0 +1,26 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using Microsoft.AspNet.Http; +using Microsoft.AspNet.Security.Notifications; + +namespace Microsoft.AspNet.Security.MicrosoftAccount +{ + /// + /// Provides context information to middleware providers. + /// + public class MicrosoftAccountReturnEndpointContext : ReturnEndpointContext + { + /// + /// Initializes a new . + /// + /// The HTTP environment. + /// The authentication ticket. + public MicrosoftAccountReturnEndpointContext( + HttpContext context, + AuthenticationTicket ticket) + : base(context, ticket) + { + } + } +} diff --git a/src/Microsoft.AspNet.Security.MicrosoftAccount/Resources.Designer.cs b/src/Microsoft.AspNet.Security.MicrosoftAccount/Resources.Designer.cs new file mode 100644 index 000000000..62f1707ef --- /dev/null +++ b/src/Microsoft.AspNet.Security.MicrosoftAccount/Resources.Designer.cs @@ -0,0 +1,90 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.33440 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace Microsoft.AspNet.Security.MicrosoftAccount { + using System; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class Resources { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Resources() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Microsoft.AspNet.Security.MicrosoftAccount.Resources", System.Reflection.IntrospectionExtensions.GetTypeInfo(typeof(Resources)).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + + /// + /// Looks up a localized string similar to The user does not have an id.. + /// + internal static string Exception_MissingId { + get { + return ResourceManager.GetString("Exception_MissingId", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to The '{0}' option must be provided.. + /// + internal static string Exception_OptionMustBeProvided { + get { + return ResourceManager.GetString("Exception_OptionMustBeProvided", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to An ICertificateValidator cannot be specified at the same time as an HttpMessageHandler unless it is a WebRequestHandler.. + /// + internal static string Exception_ValidatorHandlerMismatch { + get { + return ResourceManager.GetString("Exception_ValidatorHandlerMismatch", resourceCulture); + } + } + } +} diff --git a/src/Microsoft.AspNet.Security.MicrosoftAccount/Resources.resx b/src/Microsoft.AspNet.Security.MicrosoftAccount/Resources.resx new file mode 100644 index 000000000..26eb43888 --- /dev/null +++ b/src/Microsoft.AspNet.Security.MicrosoftAccount/Resources.resx @@ -0,0 +1,129 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + The user does not have an id. + + + The '{0}' option must be provided. + + + An ICertificateValidator cannot be specified at the same time as an HttpMessageHandler unless it is a WebRequestHandler. + + \ No newline at end of file diff --git a/src/Microsoft.AspNet.Security.MicrosoftAccount/project.json b/src/Microsoft.AspNet.Security.MicrosoftAccount/project.json new file mode 100644 index 000000000..b583f1ae8 --- /dev/null +++ b/src/Microsoft.AspNet.Security.MicrosoftAccount/project.json @@ -0,0 +1,46 @@ +{ + "version": "1.0.0-*", + "dependencies": { + "Microsoft.AspNet.Http": "1.0.0-*", + "Microsoft.AspNet.RequestContainer": "1.0.0-*", + "Microsoft.AspNet.Security": "1.0.0-*", + "Microsoft.AspNet.Security.DataProtection": "1.0.0-*", + "Microsoft.AspNet.WebUtilities": "1.0.0-*", + "Microsoft.Framework.Logging": "1.0.0-*", + "Newtonsoft.Json": "5.0.8", + "System.Net.Http": "4.0.0.0" + }, + "frameworks": { + "net45": { + "dependencies": { + "System.Net.Http.WebRequest": "" + } + }, + "aspnetcore50": { + "dependencies": { + "System.Collections": "4.0.10.0", + "System.ComponentModel": "4.0.0.0", + "System.Console": "4.0.0.0", + "System.Diagnostics.Debug": "4.0.10.0", + "System.Diagnostics.Tools": "4.0.0.0", + "System.Dynamic.Runtime": "4.0.0.0", + "System.Globalization": "4.0.10.0", + "System.IO": "4.0.10.0", + "System.IO.Compression": "4.0.0.0", + "System.Linq": "4.0.0.0", + "System.Net.Http.WinHttpHandler": "4.0.0.0", + "System.ObjectModel": "4.0.0.0", + "System.Reflection": "4.0.10.0", + "System.Resources.ResourceManager": "4.0.0.0", + "System.Runtime": "4.0.20.0", + "System.Runtime.Extensions": "4.0.10.0", + "System.Runtime.InteropServices": "4.0.20.0", + "System.Security.Claims": "1.0.0-*", + "System.Security.Cryptography.Hashing.Algorithms": "4.0.0.0", + "System.Security.Principal": "4.0.0.0", + "System.Threading": "4.0.0.0", + "System.Threading.Tasks": "4.0.10.0" + } + } + } +} diff --git a/src/Microsoft.AspNet.Security.Twitter/Notifications/TwitterApplyRedirectContext.cs b/src/Microsoft.AspNet.Security.Twitter/Notifications/TwitterApplyRedirectContext.cs index 3d5ab80ff..a328730de 100644 --- a/src/Microsoft.AspNet.Security.Twitter/Notifications/TwitterApplyRedirectContext.cs +++ b/src/Microsoft.AspNet.Security.Twitter/Notifications/TwitterApplyRedirectContext.cs @@ -8,17 +8,17 @@ namespace Microsoft.AspNet.Security.Twitter { /// - /// 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 middleware. /// public class TwitterApplyRedirectContext : BaseContext { /// /// Creates a new context object. /// - /// The HTTP request context - /// The Facebook middleware options - /// The authenticaiton properties of the challenge - /// The initial redirect URI + /// The HTTP request context. + /// The Twitter middleware options. + /// The authentication properties of the challenge. + /// The initial redirect URI. public TwitterApplyRedirectContext(HttpContext context, TwitterAuthenticationOptions options, AuthenticationProperties properties, string redirectUri) : base(context, options) @@ -33,7 +33,7 @@ public TwitterApplyRedirectContext(HttpContext context, TwitterAuthenticationOpt public string RedirectUri { get; private set; } /// - /// Gets the authenticaiton properties of the challenge + /// Gets the authentication properties of the challenge. /// public AuthenticationProperties Properties { get; private set; } } diff --git a/src/Microsoft.AspNet.Security/Resources.Designer.cs b/src/Microsoft.AspNet.Security/Resources.Designer.cs index 26e74bb6c..d53526588 100644 --- a/src/Microsoft.AspNet.Security/Resources.Designer.cs +++ b/src/Microsoft.AspNet.Security/Resources.Designer.cs @@ -70,7 +70,7 @@ internal static string Exception_AuthenticationTokenDoesNotProvideSyncMethods { } /// - /// Looks up a localized string similar to The default data protection provider may only be used when the IAppBuilder.Properties contains an appropriate 'host.AppName' key.. + /// Looks up a localized string similar to The default data protection provider may only be used when the IBuilder.Properties contains an appropriate 'host.AppName' key.. /// internal static string Exception_DefaultDpapiRequiresAppNameKey { get { @@ -79,7 +79,7 @@ internal static string Exception_DefaultDpapiRequiresAppNameKey { } /// - /// Looks up a localized string similar to A default value for SignInAsAuthenticationType was not found in IAppBuilder Properties. This can happen if your authentication middleware are added in the wrong order, or if one is missing.. + /// Looks up a localized string similar to A default value for SignInAsAuthenticationType was not found in IBuilder Properties. This can happen if your authentication middleware are added in the wrong order, or if one is missing.. /// internal static string Exception_MissingDefaultSignInAsAuthenticationType { get { diff --git a/src/Microsoft.AspNet.Security/Resources.resx b/src/Microsoft.AspNet.Security/Resources.resx index fdd098066..5a02ab772 100644 --- a/src/Microsoft.AspNet.Security/Resources.resx +++ b/src/Microsoft.AspNet.Security/Resources.resx @@ -118,13 +118,13 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - The default data protection provider may only be used when the IAppBuilder.Properties contains an appropriate 'host.AppName' key. + The default data protection provider may only be used when the IBuilder.Properties contains an appropriate 'host.AppName' key. The state passed to UnhookAuthentication may only be the return value from HookAuthentication. - A default value for SignInAsAuthenticationType was not found in IAppBuilder Properties. This can happen if your authentication middleware are added in the wrong order, or if one is missing. + A default value for SignInAsAuthenticationType was not found in IBuilder Properties. This can happen if your authentication middleware are added in the wrong order, or if one is missing. The AuthenticationTokenProvider's required synchronous events have not been registered. diff --git a/test/Microsoft.AspNet.Security.Test/MicrosoftAccount/MicrosoftAccountMiddlewareTests.cs b/test/Microsoft.AspNet.Security.Test/MicrosoftAccount/MicrosoftAccountMiddlewareTests.cs new file mode 100644 index 000000000..2c1da025f --- /dev/null +++ b/test/Microsoft.AspNet.Security.Test/MicrosoftAccount/MicrosoftAccountMiddlewareTests.cs @@ -0,0 +1,282 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Net; +using System.Net.Http; +using System.Security.Claims; +using System.Text; +using System.Threading.Tasks; +using System.Xml; +using System.Xml.Linq; +using Microsoft.AspNet.Builder; +using Microsoft.AspNet.Http; +using Microsoft.AspNet.Http.Security; +using Microsoft.AspNet.Security.Cookies; +using Microsoft.AspNet.Security.MicrosoftAccount; +using Microsoft.AspNet.TestHost; +using Newtonsoft.Json; +using Shouldly; +using Xunit; + +namespace Microsoft.AspNet.Security.Tests.MicrosoftAccount +{ + public class MicrosoftAccountMiddlewareTests + { + [Fact] + public async Task ChallengeWillTriggerApplyRedirectEvent() + { + var options = new MicrosoftAccountAuthenticationOptions() + { + ClientId = "Test Client Id", + ClientSecret = "Test Client Secret", + Notifications = new MicrosoftAccountAuthenticationNotifications + { + OnApplyRedirect = context => + { + context.Response.Redirect(context.RedirectUri + "&custom=test"); + } + } + }; + var server = CreateServer( + app => app.UseMicrosoftAccountAuthentication(options), + context => + { + context.Response.Challenge("Microsoft"); + return true; + }); + var transaction = await SendAsync(server, "http://example.com/challenge"); + transaction.Response.StatusCode.ShouldBe(HttpStatusCode.Redirect); + var query = transaction.Response.Headers.Location.Query; + query.ShouldContain("custom=test"); + } + + [Fact] + public async Task ChallengeWillTriggerRedirection() + { + var server = CreateServer( + app => app.UseMicrosoftAccountAuthentication("Test Client Id", "Test Client Secret"), + context => + { + context.Response.Challenge("Microsoft"); + return true; + }); + var transaction = await SendAsync(server, "http://example.com/challenge"); + transaction.Response.StatusCode.ShouldBe(HttpStatusCode.Redirect); + var location = transaction.Response.Headers.Location.AbsoluteUri; + location.ShouldContain("https://login.live.com/oauth20_authorize.srf"); + location.ShouldContain("response_type=code"); + location.ShouldContain("client_id="); + location.ShouldContain("redirect_uri="); + location.ShouldContain("scope="); + location.ShouldContain("state="); + } + + [Fact] + public async Task AuthenticatedEventCanGetRefreshToken() + { + var options = new MicrosoftAccountAuthenticationOptions() + { + ClientId = "Test Client Id", + ClientSecret = "Test Client Secret", + BackchannelHttpHandler = new TestHttpMessageHandler + { + Sender = async req => + { + if (req.RequestUri.AbsoluteUri == "https://login.live.com/oauth20_token.srf") + { + return await ReturnJsonResponse(new + { + access_token = "Test Access Token", + expire_in = 3600, + token_type = "Bearer", + refresh_token = "Test Refresh Token" + }); + } + else if (req.RequestUri.GetLeftPart(UriPartial.Path) == "https://apis.live.net/v5.0/me") + { + return await ReturnJsonResponse(new + { + id = "Test User ID", + name = "Test Name", + first_name = "Test Given Name", + last_name = "Test Family Name", + emails = new + { + preferred = "Test email" + } + }); + } + + return null; + } + }, + Notifications = new MicrosoftAccountAuthenticationNotifications + { + OnAuthenticated = context => + { + var refreshToken = context.RefreshToken; + context.Identity.AddClaim(new Claim("RefreshToken", refreshToken)); + return Task.FromResult(null); + } + } + }; + var server = CreateServer( + app => app.UseMicrosoftAccountAuthentication(options), + context => + { + Describe(context.Response, (ClaimsIdentity)context.User.Identity); + return true; + }); + var properties = new AuthenticationProperties(); + var correlationKey = ".AspNet.Correlation.Microsoft"; + var correlationValue = "TestCorrelationId"; + properties.Dictionary.Add(correlationKey, correlationValue); + properties.RedirectUri = "/me"; + var state = options.StateDataFormat.Protect(properties); + var transaction = await SendAsync(server, + "https://example.com/signin-microsoft?code=TestCode&state=" + Uri.EscapeDataString(state), + correlationKey + "=" + correlationValue); + transaction.Response.StatusCode.ShouldBe(HttpStatusCode.Redirect); + transaction.Response.Headers.Location.ToString().ShouldBe("/me"); + transaction.SetCookie.Count.ShouldBe(2); + transaction.SetCookie[0].ShouldContain(correlationKey); + transaction.SetCookie[1].ShouldContain(".AspNet.External"); + + var authCookie = transaction.AuthenticationCookieValue; + transaction = await SendAsync(server, "https://example.com/me", authCookie); + transaction.Response.StatusCode.ShouldBe(HttpStatusCode.OK); + transaction.FindClaimValue("RefreshToken").ShouldBe("Test Refresh Token"); + } + + private static TestServer CreateServer(Action configure, Func handler) + { + return TestServer.Create(app => + { + app.UseCookieAuthentication(new CookieAuthenticationOptions + { + AuthenticationType = "External" + }); + app.SetDefaultSignInAsAuthenticationType("External"); + if (configure != null) + { + configure(app); + } + app.Use(async (context, next) => + { + if (handler == null || !handler(context)) + { + await next(); + } + }); + }); + } + + private static async Task SendAsync(TestServer server, string uri, string cookieHeader = null) + { + var request = new HttpRequestMessage(HttpMethod.Get, uri); + if (!string.IsNullOrEmpty(cookieHeader)) + { + request.Headers.Add("Cookie", cookieHeader); + } + var transaction = new Transaction + { + Request = request, + Response = await server.CreateClient().SendAsync(request), + }; + if (transaction.Response.Headers.Contains("Set-Cookie")) + { + transaction.SetCookie = transaction.Response.Headers.GetValues("Set-Cookie").ToList(); + } + transaction.ResponseText = await transaction.Response.Content.ReadAsStringAsync(); + + if (transaction.Response.Content != null && + transaction.Response.Content.Headers.ContentType != null && + transaction.Response.Content.Headers.ContentType.MediaType == "text/xml") + { + transaction.ResponseElement = XElement.Parse(transaction.ResponseText); + } + return transaction; + } + + private static async Task ReturnJsonResponse(object content) + { + var res = new HttpResponseMessage(HttpStatusCode.OK); + var text = await JsonConvert.SerializeObjectAsync(content); + res.Content = new StringContent(text, Encoding.UTF8, "application/json"); + return res; + } + + private static void Describe(HttpResponse res, ClaimsIdentity identity) + { + res.StatusCode = 200; + res.ContentType = "text/xml"; + var xml = new XElement("xml"); + if (identity != null) + { + xml.Add(identity.Claims.Select(claim => new XElement("claim", new XAttribute("type", claim.Type), new XAttribute("value", claim.Value)))); + } + using (var memory = new MemoryStream()) + { + using (var writer = new XmlTextWriter(memory, Encoding.UTF8)) + { + xml.WriteTo(writer); + } + res.Body.Write(memory.ToArray(), 0, memory.ToArray().Length); + } + } + + private class TestHttpMessageHandler : HttpMessageHandler + { + public Func> Sender { get; set; } + + protected override async Task SendAsync(HttpRequestMessage request, System.Threading.CancellationToken cancellationToken) + { + if (Sender != null) + { + return await Sender(request); + } + + return null; + } + } + + private class Transaction + { + public HttpRequestMessage Request { get; set; } + public HttpResponseMessage Response { get; set; } + public IList SetCookie { get; set; } + public string ResponseText { get; set; } + public XElement ResponseElement { get; set; } + + public string AuthenticationCookieValue + { + get + { + if (SetCookie != null && SetCookie.Count > 0) + { + var authCookie = SetCookie.SingleOrDefault(c => c.Contains(".AspNet.External=")); + if (authCookie != null) + { + return authCookie.Substring(0, authCookie.IndexOf(';')); + } + } + + return null; + } + } + + public string FindClaimValue(string claimType) + { + XElement claim = ResponseElement.Elements("claim").SingleOrDefault(elt => elt.Attribute("type").Value == claimType); + if (claim == null) + { + return null; + } + return claim.Attribute("value").Value; + } + } + } +} diff --git a/test/Microsoft.AspNet.Security.Test/project.json b/test/Microsoft.AspNet.Security.Test/project.json index 4da682291..4cfa4fb96 100644 --- a/test/Microsoft.AspNet.Security.Test/project.json +++ b/test/Microsoft.AspNet.Security.Test/project.json @@ -8,6 +8,7 @@ "Microsoft.AspNet.Security.Cookies" : "1.0.0-*", "Microsoft.AspNet.Security.Facebook" : "1.0.0-*", "Microsoft.AspNet.Security.Google" : "1.0.0-*", + "Microsoft.AspNet.Security.MicrosoftAccount" : "1.0.0-*", "Microsoft.AspNet.Security.Twitter" : "1.0.0-*", "Microsoft.AspNet.TestHost": "1.0.0-*", "Microsoft.Framework.DependencyInjection": "1.0.0-*", From 6b0c51a5310ff9f38567573ee2b7a7719324c762 Mon Sep 17 00:00:00 2001 From: Chris Ross Date: Fri, 29 Aug 2014 13:26:14 -0700 Subject: [PATCH 038/216] Renamed Project.json to Project.json2 --- samples/SocialSample/{Project.json => Project.json2} | 0 .../{Project.json => Project.json2} | 0 .../{Project.json => Project.json2} | 0 .../{Project.json => Project.json2} | 0 4 files changed, 0 insertions(+), 0 deletions(-) rename samples/SocialSample/{Project.json => Project.json2} (100%) rename src/Microsoft.AspNet.Security.Facebook/{Project.json => Project.json2} (100%) rename src/Microsoft.AspNet.Security.Google/{Project.json => Project.json2} (100%) rename src/Microsoft.AspNet.Security.Twitter/{Project.json => Project.json2} (100%) diff --git a/samples/SocialSample/Project.json b/samples/SocialSample/Project.json2 similarity index 100% rename from samples/SocialSample/Project.json rename to samples/SocialSample/Project.json2 diff --git a/src/Microsoft.AspNet.Security.Facebook/Project.json b/src/Microsoft.AspNet.Security.Facebook/Project.json2 similarity index 100% rename from src/Microsoft.AspNet.Security.Facebook/Project.json rename to src/Microsoft.AspNet.Security.Facebook/Project.json2 diff --git a/src/Microsoft.AspNet.Security.Google/Project.json b/src/Microsoft.AspNet.Security.Google/Project.json2 similarity index 100% rename from src/Microsoft.AspNet.Security.Google/Project.json rename to src/Microsoft.AspNet.Security.Google/Project.json2 diff --git a/src/Microsoft.AspNet.Security.Twitter/Project.json b/src/Microsoft.AspNet.Security.Twitter/Project.json2 similarity index 100% rename from src/Microsoft.AspNet.Security.Twitter/Project.json rename to src/Microsoft.AspNet.Security.Twitter/Project.json2 From 06bdcebf631ed9574db1c3329ee82caa1f64e811 Mon Sep 17 00:00:00 2001 From: Chris Ross Date: Fri, 29 Aug 2014 13:29:29 -0700 Subject: [PATCH 039/216] Fixed project.json casing --- samples/SocialSample/SocialSample.kproj | 6 ------ samples/SocialSample/{Project.json2 => project.json} | 0 .../{Project.json2 => project.json} | 0 .../{Project.json2 => project.json} | 0 .../{Project.json2 => project.json} | 0 5 files changed, 6 deletions(-) rename samples/SocialSample/{Project.json2 => project.json} (100%) rename src/Microsoft.AspNet.Security.Facebook/{Project.json2 => project.json} (100%) rename src/Microsoft.AspNet.Security.Google/{Project.json2 => project.json} (100%) rename src/Microsoft.AspNet.Security.Twitter/{Project.json2 => project.json} (100%) diff --git a/samples/SocialSample/SocialSample.kproj b/samples/SocialSample/SocialSample.kproj index c4ab469bf..4447d1b1d 100644 --- a/samples/SocialSample/SocialSample.kproj +++ b/samples/SocialSample/SocialSample.kproj @@ -22,11 +22,5 @@ 2.0 - - - - - - \ No newline at end of file diff --git a/samples/SocialSample/Project.json2 b/samples/SocialSample/project.json similarity index 100% rename from samples/SocialSample/Project.json2 rename to samples/SocialSample/project.json diff --git a/src/Microsoft.AspNet.Security.Facebook/Project.json2 b/src/Microsoft.AspNet.Security.Facebook/project.json similarity index 100% rename from src/Microsoft.AspNet.Security.Facebook/Project.json2 rename to src/Microsoft.AspNet.Security.Facebook/project.json diff --git a/src/Microsoft.AspNet.Security.Google/Project.json2 b/src/Microsoft.AspNet.Security.Google/project.json similarity index 100% rename from src/Microsoft.AspNet.Security.Google/Project.json2 rename to src/Microsoft.AspNet.Security.Google/project.json diff --git a/src/Microsoft.AspNet.Security.Twitter/Project.json2 b/src/Microsoft.AspNet.Security.Twitter/project.json similarity index 100% rename from src/Microsoft.AspNet.Security.Twitter/Project.json2 rename to src/Microsoft.AspNet.Security.Twitter/project.json From 565fde51878fb84d1cc325680cbbfa07f3b2286d Mon Sep 17 00:00:00 2001 From: David Fowler Date: Tue, 2 Sep 2014 21:29:07 -0700 Subject: [PATCH 040/216] Fixed packages --- src/Microsoft.AspNet.Security.MicrosoftAccount/project.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Microsoft.AspNet.Security.MicrosoftAccount/project.json b/src/Microsoft.AspNet.Security.MicrosoftAccount/project.json index b583f1ae8..3457c15c9 100644 --- a/src/Microsoft.AspNet.Security.MicrosoftAccount/project.json +++ b/src/Microsoft.AspNet.Security.MicrosoftAccount/project.json @@ -29,7 +29,7 @@ "System.IO.Compression": "4.0.0.0", "System.Linq": "4.0.0.0", "System.Net.Http.WinHttpHandler": "4.0.0.0", - "System.ObjectModel": "4.0.0.0", + "System.ObjectModel": "4.0.10.0", "System.Reflection": "4.0.10.0", "System.Resources.ResourceManager": "4.0.0.0", "System.Runtime": "4.0.20.0", From 810c96e9397720e2696127939cbcab10796c26f4 Mon Sep 17 00:00:00 2001 From: David Fowler Date: Thu, 4 Sep 2014 01:47:16 -0700 Subject: [PATCH 041/216] Updated to use the new target framework in project.json --- samples/CookieSample/project.json | 2 +- samples/SocialSample/project.json | 2 +- src/Microsoft.AspNet.Security.Cookies/project.json | 2 +- .../FacebookAuthenticationMiddleware.cs | 4 ++-- .../FacebookAuthenticationOptions.cs | 2 +- src/Microsoft.AspNet.Security.Facebook/project.json | 2 +- .../GoogleAuthenticationMiddleware.cs | 4 ++-- .../GoogleAuthenticationOptions.cs | 4 ++-- src/Microsoft.AspNet.Security.Google/project.json | 2 +- .../MicrosoftAccountAuthenticationMiddleware.cs | 4 ++-- .../MicrosoftAccountAuthenticationOptions.cs | 4 ++-- src/Microsoft.AspNet.Security.MicrosoftAccount/project.json | 2 +- .../TwitterAuthenticationMiddleware.cs | 4 ++-- .../TwitterAuthenticationOptions.cs | 6 +++--- src/Microsoft.AspNet.Security.Twitter/project.json | 2 +- .../CertificateSubjectKeyIdentifierValidator.cs | 4 ++-- .../CertificateSubjectPublicKeyInfoValidator.cs | 4 ++-- .../CertificateThumbprintValidator.cs | 4 ++-- src/Microsoft.AspNet.Security/ICertificateValidator.cs | 4 ++-- src/Microsoft.AspNet.Security/project.json | 2 +- test/Microsoft.AspNet.Security.Test/project.json | 2 +- 21 files changed, 33 insertions(+), 33 deletions(-) diff --git a/samples/CookieSample/project.json b/samples/CookieSample/project.json index c405745f1..c8eabcb68 100644 --- a/samples/CookieSample/project.json +++ b/samples/CookieSample/project.json @@ -13,7 +13,7 @@ }, "commands": { "web": "Microsoft.AspNet.Hosting server=Microsoft.AspNet.Server.WebListener server.urls=http://localhost:12345" }, "frameworks": { - "net45": { + "aspnet50": { }, "aspnetcore50": { "dependencies": { diff --git a/samples/SocialSample/project.json b/samples/SocialSample/project.json index 8703a24bf..ed77607d2 100644 --- a/samples/SocialSample/project.json +++ b/samples/SocialSample/project.json @@ -14,7 +14,7 @@ }, "commands": { "web": "Microsoft.AspNet.Hosting server=Microsoft.AspNet.Server.WebListener server.urls=http://localhost:12345" }, "frameworks": { - "net45": { + "aspnet50": { }, "aspnetcore50": { "dependencies": { diff --git a/src/Microsoft.AspNet.Security.Cookies/project.json b/src/Microsoft.AspNet.Security.Cookies/project.json index 0a3d6d36d..9d9e58616 100644 --- a/src/Microsoft.AspNet.Security.Cookies/project.json +++ b/src/Microsoft.AspNet.Security.Cookies/project.json @@ -13,7 +13,7 @@ "Newtonsoft.Json": "5.0.8" }, "frameworks": { - "net45": {}, + "aspnet50": {}, "aspnetcore50": { "dependencies": { "System.Collections": "4.0.10.0", diff --git a/src/Microsoft.AspNet.Security.Facebook/FacebookAuthenticationMiddleware.cs b/src/Microsoft.AspNet.Security.Facebook/FacebookAuthenticationMiddleware.cs index af1da5c30..e67abf1c9 100644 --- a/src/Microsoft.AspNet.Security.Facebook/FacebookAuthenticationMiddleware.cs +++ b/src/Microsoft.AspNet.Security.Facebook/FacebookAuthenticationMiddleware.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; @@ -76,7 +76,7 @@ protected override AuthenticationHandler CreateHa private static HttpMessageHandler ResolveHttpMessageHandler(FacebookAuthenticationOptions options) { HttpMessageHandler handler = options.BackchannelHttpHandler ?? -#if NET45 +#if ASPNET50 new WebRequestHandler(); // If they provided a validator, apply it or fail. if (options.BackchannelCertificateValidator != null) diff --git a/src/Microsoft.AspNet.Security.Facebook/FacebookAuthenticationOptions.cs b/src/Microsoft.AspNet.Security.Facebook/FacebookAuthenticationOptions.cs index 1b9d2c145..1d4fa9a54 100644 --- a/src/Microsoft.AspNet.Security.Facebook/FacebookAuthenticationOptions.cs +++ b/src/Microsoft.AspNet.Security.Facebook/FacebookAuthenticationOptions.cs @@ -40,7 +40,7 @@ public FacebookAuthenticationOptions() /// Gets or sets the Facebook-assigned app secret. /// public string AppSecret { get; set; } -#if NET45 +#if ASPNET50 /// /// Gets or sets the a pinned certificate validator to use to validate the endpoints used /// in back channel communications belong to Facebook. diff --git a/src/Microsoft.AspNet.Security.Facebook/project.json b/src/Microsoft.AspNet.Security.Facebook/project.json index 608aa0b6d..bf9da2253 100644 --- a/src/Microsoft.AspNet.Security.Facebook/project.json +++ b/src/Microsoft.AspNet.Security.Facebook/project.json @@ -11,7 +11,7 @@ "System.Net.Http": "4.0.0.0" }, "frameworks": { - "net45": { + "aspnet50": { "dependencies": { "System.Net.Http.WebRequest": "" } diff --git a/src/Microsoft.AspNet.Security.Google/GoogleAuthenticationMiddleware.cs b/src/Microsoft.AspNet.Security.Google/GoogleAuthenticationMiddleware.cs index 1105b149b..66768cbb8 100644 --- a/src/Microsoft.AspNet.Security.Google/GoogleAuthenticationMiddleware.cs +++ b/src/Microsoft.AspNet.Security.Google/GoogleAuthenticationMiddleware.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; @@ -76,7 +76,7 @@ protected override AuthenticationHandler CreateHand private static HttpMessageHandler ResolveHttpMessageHandler(GoogleAuthenticationOptions options) { HttpMessageHandler handler = options.BackchannelHttpHandler ?? -#if NET45 +#if ASPNET50 new WebRequestHandler(); // If they provided a validator, apply it or fail. if (options.BackchannelCertificateValidator != null) diff --git a/src/Microsoft.AspNet.Security.Google/GoogleAuthenticationOptions.cs b/src/Microsoft.AspNet.Security.Google/GoogleAuthenticationOptions.cs index f03b7d2ef..1ede9f042 100644 --- a/src/Microsoft.AspNet.Security.Google/GoogleAuthenticationOptions.cs +++ b/src/Microsoft.AspNet.Security.Google/GoogleAuthenticationOptions.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; @@ -39,7 +39,7 @@ public GoogleAuthenticationOptions() /// Gets or sets the Google-assigned client secret. /// public string ClientSecret { get; set; } -#if NET45 +#if ASPNET50 /// /// Gets or sets the a pinned certificate validator to use to validate the endpoints used /// in back channel communications belong to Google. diff --git a/src/Microsoft.AspNet.Security.Google/project.json b/src/Microsoft.AspNet.Security.Google/project.json index 608aa0b6d..bf9da2253 100644 --- a/src/Microsoft.AspNet.Security.Google/project.json +++ b/src/Microsoft.AspNet.Security.Google/project.json @@ -11,7 +11,7 @@ "System.Net.Http": "4.0.0.0" }, "frameworks": { - "net45": { + "aspnet50": { "dependencies": { "System.Net.Http.WebRequest": "" } diff --git a/src/Microsoft.AspNet.Security.MicrosoftAccount/MicrosoftAccountAuthenticationMiddleware.cs b/src/Microsoft.AspNet.Security.MicrosoftAccount/MicrosoftAccountAuthenticationMiddleware.cs index 0bd8f4c3e..3f5e24cec 100644 --- a/src/Microsoft.AspNet.Security.MicrosoftAccount/MicrosoftAccountAuthenticationMiddleware.cs +++ b/src/Microsoft.AspNet.Security.MicrosoftAccount/MicrosoftAccountAuthenticationMiddleware.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; @@ -76,7 +76,7 @@ protected override AuthenticationHandler private static HttpMessageHandler ResolveHttpMessageHandler(MicrosoftAccountAuthenticationOptions options) { HttpMessageHandler handler = options.BackchannelHttpHandler ?? -#if NET45 +#if ASPNET50 new WebRequestHandler(); // If they provided a validator, apply it or fail. if (options.BackchannelCertificateValidator != null) diff --git a/src/Microsoft.AspNet.Security.MicrosoftAccount/MicrosoftAccountAuthenticationOptions.cs b/src/Microsoft.AspNet.Security.MicrosoftAccount/MicrosoftAccountAuthenticationOptions.cs index 47ee6fe0e..7668b0d08 100644 --- a/src/Microsoft.AspNet.Security.MicrosoftAccount/MicrosoftAccountAuthenticationOptions.cs +++ b/src/Microsoft.AspNet.Security.MicrosoftAccount/MicrosoftAccountAuthenticationOptions.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; @@ -27,7 +27,7 @@ public MicrosoftAccountAuthenticationOptions() Scope = new List(); BackchannelTimeout = TimeSpan.FromSeconds(60); } -#if NET45 +#if ASPNET50 /// /// Gets or sets the a pinned certificate validator to use to validate the endpoints used /// in back channel communications belong to Microsoft Account. diff --git a/src/Microsoft.AspNet.Security.MicrosoftAccount/project.json b/src/Microsoft.AspNet.Security.MicrosoftAccount/project.json index 3457c15c9..83bc4823b 100644 --- a/src/Microsoft.AspNet.Security.MicrosoftAccount/project.json +++ b/src/Microsoft.AspNet.Security.MicrosoftAccount/project.json @@ -11,7 +11,7 @@ "System.Net.Http": "4.0.0.0" }, "frameworks": { - "net45": { + "aspnet50": { "dependencies": { "System.Net.Http.WebRequest": "" } diff --git a/src/Microsoft.AspNet.Security.Twitter/TwitterAuthenticationMiddleware.cs b/src/Microsoft.AspNet.Security.Twitter/TwitterAuthenticationMiddleware.cs index 421a68557..596176219 100644 --- a/src/Microsoft.AspNet.Security.Twitter/TwitterAuthenticationMiddleware.cs +++ b/src/Microsoft.AspNet.Security.Twitter/TwitterAuthenticationMiddleware.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; @@ -84,7 +84,7 @@ protected override AuthenticationHandler CreateHan private static HttpMessageHandler ResolveHttpMessageHandler(TwitterAuthenticationOptions options) { HttpMessageHandler handler = options.BackchannelHttpHandler ?? -#if NET45 +#if ASPNET50 new WebRequestHandler(); // If they provided a validator, apply it or fail. if (options.BackchannelCertificateValidator != null) diff --git a/src/Microsoft.AspNet.Security.Twitter/TwitterAuthenticationOptions.cs b/src/Microsoft.AspNet.Security.Twitter/TwitterAuthenticationOptions.cs index fcf307d5c..043911e75 100644 --- a/src/Microsoft.AspNet.Security.Twitter/TwitterAuthenticationOptions.cs +++ b/src/Microsoft.AspNet.Security.Twitter/TwitterAuthenticationOptions.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; @@ -23,7 +23,7 @@ public TwitterAuthenticationOptions() CallbackPath = new PathString("/signin-twitter"); AuthenticationMode = AuthenticationMode.Passive; BackchannelTimeout = TimeSpan.FromSeconds(60); -#if NET45 +#if ASPNET50 // Twitter lists its valid Subject Key Identifiers at https://dev.twitter.com/docs/security/using-ssl BackchannelCertificateValidator = new CertificateSubjectKeyIdentifierValidator( new[] @@ -54,7 +54,7 @@ public TwitterAuthenticationOptions() /// The back channel timeout. /// public TimeSpan BackchannelTimeout { get; set; } -#if NET45 +#if ASPNET50 /// /// Gets or sets the a pinned certificate validator to use to validate the endpoints used /// in back channel communications belong to Twitter. diff --git a/src/Microsoft.AspNet.Security.Twitter/project.json b/src/Microsoft.AspNet.Security.Twitter/project.json index 608aa0b6d..bf9da2253 100644 --- a/src/Microsoft.AspNet.Security.Twitter/project.json +++ b/src/Microsoft.AspNet.Security.Twitter/project.json @@ -11,7 +11,7 @@ "System.Net.Http": "4.0.0.0" }, "frameworks": { - "net45": { + "aspnet50": { "dependencies": { "System.Net.Http.WebRequest": "" } diff --git a/src/Microsoft.AspNet.Security/CertificateSubjectKeyIdentifierValidator.cs b/src/Microsoft.AspNet.Security/CertificateSubjectKeyIdentifierValidator.cs index d91311202..68cf5abd2 100644 --- a/src/Microsoft.AspNet.Security/CertificateSubjectKeyIdentifierValidator.cs +++ b/src/Microsoft.AspNet.Security/CertificateSubjectKeyIdentifierValidator.cs @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -#if NET45 +#if ASPNET50 using System; using System.Collections.Generic; using System.Net.Security; @@ -77,4 +77,4 @@ private static string GetSubjectKeyIdentifier(X509Certificate2 certificate) } } } -#endif \ No newline at end of file +#endif diff --git a/src/Microsoft.AspNet.Security/CertificateSubjectPublicKeyInfoValidator.cs b/src/Microsoft.AspNet.Security/CertificateSubjectPublicKeyInfoValidator.cs index a0ba22310..4ad5ee81c 100644 --- a/src/Microsoft.AspNet.Security/CertificateSubjectPublicKeyInfoValidator.cs +++ b/src/Microsoft.AspNet.Security/CertificateSubjectPublicKeyInfoValidator.cs @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -#if NET45 +#if ASPNET50 using System; using System.Collections.Generic; using System.ComponentModel; @@ -124,4 +124,4 @@ private HashAlgorithm CreateHashAlgorithm() } } } -#endif \ No newline at end of file +#endif diff --git a/src/Microsoft.AspNet.Security/CertificateThumbprintValidator.cs b/src/Microsoft.AspNet.Security/CertificateThumbprintValidator.cs index 9a9dadf60..a276536a7 100644 --- a/src/Microsoft.AspNet.Security/CertificateThumbprintValidator.cs +++ b/src/Microsoft.AspNet.Security/CertificateThumbprintValidator.cs @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -#if NET45 +#if ASPNET50 using System; using System.Collections.Generic; using System.Net.Security; @@ -70,4 +70,4 @@ public bool Validate(object sender, X509Certificate certificate, [NotNull] X509C } } } -#endif \ No newline at end of file +#endif diff --git a/src/Microsoft.AspNet.Security/ICertificateValidator.cs b/src/Microsoft.AspNet.Security/ICertificateValidator.cs index 3157a5c5a..26756324f 100644 --- a/src/Microsoft.AspNet.Security/ICertificateValidator.cs +++ b/src/Microsoft.AspNet.Security/ICertificateValidator.cs @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -#if NET45 +#if ASPNET50 using System; using System.Net.Security; using System.Security.Cryptography.X509Certificates; @@ -27,4 +27,4 @@ public interface ICertificateValidator bool Validate(Object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors); } } -#endif \ No newline at end of file +#endif diff --git a/src/Microsoft.AspNet.Security/project.json b/src/Microsoft.AspNet.Security/project.json index f328ce750..d54725296 100644 --- a/src/Microsoft.AspNet.Security/project.json +++ b/src/Microsoft.AspNet.Security/project.json @@ -10,7 +10,7 @@ "Microsoft.Framework.Logging": "1.0.0-*" }, "frameworks": { - "net45": {}, + "aspnet50": {}, "aspnetcore50": { "dependencies": { "System.Collections": "4.0.10.0", diff --git a/test/Microsoft.AspNet.Security.Test/project.json b/test/Microsoft.AspNet.Security.Test/project.json index 4cfa4fb96..49f7858ad 100644 --- a/test/Microsoft.AspNet.Security.Test/project.json +++ b/test/Microsoft.AspNet.Security.Test/project.json @@ -20,7 +20,7 @@ "test": "Xunit.KRunner" }, "frameworks": { - "net45": { + "aspnet50": { "dependencies": { "Shouldly": "1.1.1.1", "System.Runtime": "", From 214b82ea01291bd0f511c1036e960a6524e2948f Mon Sep 17 00:00:00 2001 From: David Fowler Date: Fri, 5 Sep 2014 01:52:04 -0700 Subject: [PATCH 042/216] Updated build.cmd --- build.cmd | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/build.cmd b/build.cmd index 3aaf95758..86ca5bbbf 100644 --- a/build.cmd +++ b/build.cmd @@ -20,9 +20,9 @@ IF EXIST packages\KoreBuild goto run .nuget\NuGet.exe install Sake -version 0.2 -o packages -ExcludeVersion IF "%SKIP_KRE_INSTALL%"=="1" goto run -CALL packages\KoreBuild\build\kvm upgrade -svr50 -x86 -CALL packages\KoreBuild\build\kvm install default -svrc50 -x86 +CALL packages\KoreBuild\build\kvm upgrade -runtime CLR -x86 +CALL packages\KoreBuild\build\kvm install default -runtime CoreCLR -x86 :run -CALL packages\KoreBuild\build\kvm use default -svr50 -x86 +CALL packages\KoreBuild\build\kvm use default -runtime CLR -x86 packages\Sake\tools\Sake.exe -I packages\KoreBuild\build -f makefile.shade %* From 80c8891c0854edaecf658f6972c524ef21cd15fa Mon Sep 17 00:00:00 2001 From: Chris Ross Date: Wed, 3 Sep 2014 11:48:38 -0700 Subject: [PATCH 043/216] #49 - OAuth base middleware. --- Security.sln | 13 + samples/SocialSample/Startup.cs | 93 ++++++ .../FacebookAuthenticationDefaults.cs | 6 + .../FacebookAuthenticationHandler.cs | 294 ++++-------------- .../FacebookAuthenticationMiddleware.cs | 49 +-- .../FacebookAuthenticationOptions.cs | 89 +----- .../FacebookApplyRedirectContext.cs | 43 --- .../FacebookAuthenticatedContext.cs | 50 +-- .../FacebookAuthenticationNotifications.cs | 35 +-- .../FacebookReturnEndpointContext.cs | 26 -- .../IFacebookAuthenticationNotifications.cs | 16 +- .../Resources.Designer.cs | 9 - .../Resources.resx | 3 - .../project.json | 3 +- .../GoogleAuthenticationDefaults.cs | 6 + .../GoogleAuthenticationHandler.cs | 286 +++-------------- .../GoogleAuthenticationMiddleware.cs | 60 +--- .../GoogleAuthenticationOptions.cs | 85 +---- .../GoogleApplyRedirectContext.cs | 43 --- .../GoogleAuthenticatedContext.cs | 60 +--- .../GoogleAuthenticationNotifications.cs | 34 +- .../GoogleReturnEndpointContext.cs | 26 -- .../IGoogleAuthenticationNotifications.cs | 16 +- .../project.json | 3 +- .../MicrosoftAccountAuthenticationDefaults.cs | 6 + .../MicrosoftAccountAuthenticationHandler.cs | 251 ++------------- ...icrosoftAccountAuthenticationMiddleware.cs | 60 +--- .../MicrosoftAccountAuthenticationOptions.cs | 90 +----- ...osoftAccountAuthenticationNotifications.cs | 16 +- .../MicrosoftAccountAuthenticatedContext.cs | 61 +--- ...osoftAccountAuthenticationNotifications.cs | 34 +- .../project.json | 3 +- .../Microsoft.AspNet.Security.OAuth.kproj | 28 ++ .../NotNullAttribute.cs | 12 + .../IOAuthAuthenticationNotifications.cs | 34 ++ .../OAuthApplyRedirectContext.cs} | 8 +- .../OAuthAuthenticatedContext.cs | 77 +++++ .../OAuthAuthenticationNotifications.cs | 68 ++++ .../OAuthGetUserInformationContext.cs | 76 +++++ .../OAuthReturnEndpointContext.cs} | 8 +- .../OAuthAuthenticationDefaults.cs | 39 +++ .../OAuthAuthenticationExtensions.cs | 34 ++ .../OAuthAuthenticationHandler.cs | 253 +++++++++++++++ .../OAuthAuthenticationMiddleware.cs | 105 +++++++ .../OAuthAuthenticationOptions.cs | 117 +++++++ .../OAuthAuthenticationOptions`1.cs | 24 ++ .../Resources.Designer.cs | 83 +++++ .../Resources.resx | 126 ++++++++ .../TokenResponse.cs | 25 ++ .../project.json | 46 +++ .../TwitterAuthenticationHandler.cs | 4 +- .../Facebook/FacebookMiddlewareTests.cs | 10 +- 52 files changed, 1504 insertions(+), 1542 deletions(-) delete mode 100644 src/Microsoft.AspNet.Security.Facebook/Notifications/FacebookApplyRedirectContext.cs delete mode 100644 src/Microsoft.AspNet.Security.Facebook/Notifications/FacebookReturnEndpointContext.cs delete mode 100644 src/Microsoft.AspNet.Security.Google/Notifications/GoogleApplyRedirectContext.cs delete mode 100644 src/Microsoft.AspNet.Security.Google/Notifications/GoogleReturnEndpointContext.cs create mode 100644 src/Microsoft.AspNet.Security.OAuth/Microsoft.AspNet.Security.OAuth.kproj create mode 100644 src/Microsoft.AspNet.Security.OAuth/NotNullAttribute.cs create mode 100644 src/Microsoft.AspNet.Security.OAuth/Notifications/IOAuthAuthenticationNotifications.cs rename src/{Microsoft.AspNet.Security.MicrosoftAccount/Notifications/MicrosoftAccountApplyRedirectContext.cs => Microsoft.AspNet.Security.OAuth/Notifications/OAuthApplyRedirectContext.cs} (74%) create mode 100644 src/Microsoft.AspNet.Security.OAuth/Notifications/OAuthAuthenticatedContext.cs create mode 100644 src/Microsoft.AspNet.Security.OAuth/Notifications/OAuthAuthenticationNotifications.cs create mode 100644 src/Microsoft.AspNet.Security.OAuth/Notifications/OAuthGetUserInformationContext.cs rename src/{Microsoft.AspNet.Security.MicrosoftAccount/Notifications/MicrosoftAccountReturnEndpointContext.cs => Microsoft.AspNet.Security.OAuth/Notifications/OAuthReturnEndpointContext.cs} (71%) create mode 100644 src/Microsoft.AspNet.Security.OAuth/OAuthAuthenticationDefaults.cs create mode 100644 src/Microsoft.AspNet.Security.OAuth/OAuthAuthenticationExtensions.cs create mode 100644 src/Microsoft.AspNet.Security.OAuth/OAuthAuthenticationHandler.cs create mode 100644 src/Microsoft.AspNet.Security.OAuth/OAuthAuthenticationMiddleware.cs create mode 100644 src/Microsoft.AspNet.Security.OAuth/OAuthAuthenticationOptions.cs create mode 100644 src/Microsoft.AspNet.Security.OAuth/OAuthAuthenticationOptions`1.cs create mode 100644 src/Microsoft.AspNet.Security.OAuth/Resources.Designer.cs create mode 100644 src/Microsoft.AspNet.Security.OAuth/Resources.resx create mode 100644 src/Microsoft.AspNet.Security.OAuth/TokenResponse.cs create mode 100644 src/Microsoft.AspNet.Security.OAuth/project.json diff --git a/Security.sln b/Security.sln index be6636fe2..c9951b0dd 100644 --- a/Security.sln +++ b/Security.sln @@ -32,6 +32,8 @@ Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNet.Security.T EndProject Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNet.Security.MicrosoftAccount", "src\Microsoft.AspNet.Security.MicrosoftAccount\Microsoft.AspNet.Security.MicrosoftAccount.kproj", "{1FCF26C2-A3C7-4308-B698-4AFC3560BC0C}" EndProject +Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNet.Security.OAuth", "src\Microsoft.AspNet.Security.OAuth\Microsoft.AspNet.Security.OAuth.kproj", "{4A636011-68EE-4CE5-836D-EA8E13CF71E4}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -132,6 +134,16 @@ Global {1FCF26C2-A3C7-4308-B698-4AFC3560BC0C}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU {1FCF26C2-A3C7-4308-B698-4AFC3560BC0C}.Release|Mixed Platforms.Build.0 = Release|Any CPU {1FCF26C2-A3C7-4308-B698-4AFC3560BC0C}.Release|x86.ActiveCfg = Release|Any CPU + {4A636011-68EE-4CE5-836D-EA8E13CF71E4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4A636011-68EE-4CE5-836D-EA8E13CF71E4}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4A636011-68EE-4CE5-836D-EA8E13CF71E4}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {4A636011-68EE-4CE5-836D-EA8E13CF71E4}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {4A636011-68EE-4CE5-836D-EA8E13CF71E4}.Debug|x86.ActiveCfg = Debug|Any CPU + {4A636011-68EE-4CE5-836D-EA8E13CF71E4}.Release|Any CPU.ActiveCfg = Release|Any CPU + {4A636011-68EE-4CE5-836D-EA8E13CF71E4}.Release|Any CPU.Build.0 = Release|Any CPU + {4A636011-68EE-4CE5-836D-EA8E13CF71E4}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {4A636011-68EE-4CE5-836D-EA8E13CF71E4}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {4A636011-68EE-4CE5-836D-EA8E13CF71E4}.Release|x86.ActiveCfg = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -146,5 +158,6 @@ Global {89BF8535-A849-458E-868A-A68FCF620486} = {4D2B6A51-2F9F-44F5-8131-EA5CAC053652} {C96B77EA-4078-4C31-BDB2-878F11C5E061} = {4D2B6A51-2F9F-44F5-8131-EA5CAC053652} {1FCF26C2-A3C7-4308-B698-4AFC3560BC0C} = {4D2B6A51-2F9F-44F5-8131-EA5CAC053652} + {4A636011-68EE-4CE5-836D-EA8E13CF71E4} = {4D2B6A51-2F9F-44F5-8131-EA5CAC053652} EndGlobalSection EndGlobal diff --git a/samples/SocialSample/Startup.cs b/samples/SocialSample/Startup.cs index 03435fe0f..f3aff738d 100644 --- a/samples/SocialSample/Startup.cs +++ b/samples/SocialSample/Startup.cs @@ -1,11 +1,19 @@ +using System; +using System.Collections.Generic; +using System.Net.Http; +using System.Net.Http.Headers; +using System.Security.Claims; using Microsoft.AspNet.Builder; using Microsoft.AspNet.Http; using Microsoft.AspNet.Http.Security; +using Microsoft.AspNet.Security; using Microsoft.AspNet.Security.Cookies; using Microsoft.AspNet.Security.Facebook; using Microsoft.AspNet.Security.Google; using Microsoft.AspNet.Security.MicrosoftAccount; +using Microsoft.AspNet.Security.OAuth; using Microsoft.AspNet.Security.Twitter; +using Newtonsoft.Json.Linq; namespace CookieSample { @@ -28,6 +36,16 @@ public void Configure(IBuilder app) AppSecret = "a124463c4719c94b4228d9a240e5dc1a", }); + app.UseOAuthAuthentication(new OAuthAuthenticationOptions("Google-AccessToken") + { + ClientId = "560027070069-37ldt4kfuohhu3m495hk2j4pjp92d382.apps.googleusercontent.com", + ClientSecret = "n2Q-GEw9RQjzcRbU3qhfTj8f", + CallbackPath = new PathString("/signin-google-token"), + AuthorizationEndpoint = GoogleAuthenticationDefaults.AuthorizationEndpoint, + TokenEndpoint = GoogleAuthenticationDefaults.TokenEndpoint, + Scope = { "openid", "profile", "email" }, + }); + app.UseGoogleAuthentication(new GoogleAuthenticationOptions() { ClientId = "560027070069-37ldt4kfuohhu3m495hk2j4pjp92d382.apps.googleusercontent.com", @@ -57,6 +75,17 @@ Then you can choose to run the app as admin (see below) or add the following ACL The sample app can then be run via: k web */ + app.UseOAuthAuthentication(new OAuthAuthenticationOptions("Microsoft-AccessToken") + { + Caption = "MicrosoftAccount-AccessToken - Requires project changes", + ClientId = "00000000480FF62E", + ClientSecret = "bLw2JIvf8Y1TaToipPEqxTVlOeJwCUsr", + CallbackPath = new PathString("/signin-microsoft-token"), + AuthorizationEndpoint = MicrosoftAccountAuthenticationDefaults.AuthorizationEndpoint, + TokenEndpoint = MicrosoftAccountAuthenticationDefaults.TokenEndpoint, + Scope = { "wl.basic" }, + }); + app.UseMicrosoftAccountAuthentication(new MicrosoftAccountAuthenticationOptions() { Caption = "MicrosoftAccount - Requires project changes", @@ -64,6 +93,70 @@ k web ClientSecret = "bLw2JIvf8Y1TaToipPEqxTVlOeJwCUsr", }); + app.UseOAuthAuthentication(new OAuthAuthenticationOptions("GitHub-AccessToken") + { + ClientId = "8c0c5a572abe8fe89588", + ClientSecret = "e1d95eaf03461d27acd6f49d4fc7bf19d6ac8cda", + CallbackPath = new PathString("/signin-github-token"), + AuthorizationEndpoint = "https://github.com/login/oauth/authorize", + TokenEndpoint = "https://github.com/login/oauth/access_token", + }); + + app.UseOAuthAuthentication(new OAuthAuthenticationOptions("GitHub") + { + ClientId = "49e302895d8b09ea5656", + ClientSecret = "98f1bf028608901e9df91d64ee61536fe562064b", + 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", + // Retrieving user information is unique to each provider. + Notifications = new OAuthAuthenticationNotifications() + { + OnGetUserInformationAsync = async (context) => + { + // Get the GitHub user + HttpRequestMessage userRequest = new HttpRequestMessage(HttpMethod.Get, context.Options.UserInformationEndpoint); + userRequest.Headers.Authorization = new AuthenticationHeaderValue("Bearer", context.AccessToken); + userRequest.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); + userRequest.Headers.UserAgent.ParseAdd("Microsoft ASP.NET OAuth middleware for GitHub"); + HttpResponseMessage userResponse = await context.Backchannel.SendAsync(userRequest, context.HttpContext.RequestAborted); + userResponse.EnsureSuccessStatusCode(); + var text = await userResponse.Content.ReadAsStringAsync(); + JObject user = JObject.Parse(text); + + var identity = new ClaimsIdentity( + context.Options.AuthenticationType, + ClaimsIdentity.DefaultNameClaimType, + ClaimsIdentity.DefaultRoleClaimType); + + JToken value; + var id = user.TryGetValue("id", out value) ? value.ToString() : null; + if (!string.IsNullOrEmpty(id)) + { + identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, id, ClaimValueTypes.String, context.Options.AuthenticationType)); + } + var userName = user.TryGetValue("login", out value) ? value.ToString() : null; + if (!string.IsNullOrEmpty(userName)) + { + identity.AddClaim(new Claim(ClaimsIdentity.DefaultNameClaimType, userName, ClaimValueTypes.String, context.Options.AuthenticationType)); + } + var name = user.TryGetValue("name", out value) ? value.ToString() : null; + if (!string.IsNullOrEmpty(name)) + { + identity.AddClaim(new Claim("urn:github:name", name, ClaimValueTypes.String, context.Options.AuthenticationType)); + } + var link = user.TryGetValue("url", out value) ? value.ToString() : null; + if (!string.IsNullOrEmpty(link)) + { + identity.AddClaim(new Claim("urn:github:url", link, ClaimValueTypes.String, context.Options.AuthenticationType)); + } + + context.Identity = identity; + }, + }, + }); + // Choose an authentication type app.Map("/login", signoutApp => { diff --git a/src/Microsoft.AspNet.Security.Facebook/FacebookAuthenticationDefaults.cs b/src/Microsoft.AspNet.Security.Facebook/FacebookAuthenticationDefaults.cs index a9d35151c..19cc38074 100644 --- a/src/Microsoft.AspNet.Security.Facebook/FacebookAuthenticationDefaults.cs +++ b/src/Microsoft.AspNet.Security.Facebook/FacebookAuthenticationDefaults.cs @@ -6,5 +6,11 @@ namespace Microsoft.AspNet.Security.Facebook public static class FacebookAuthenticationDefaults { public const string AuthenticationType = "Facebook"; + + public const string AuthorizationEndpoint = "https://www.facebook.com/dialog/oauth"; + + public const string TokenEndpoint = "https://graph.facebook.com/oauth/access_token"; + + public const string UserInformationEndpoint = "https://graph.facebook.com/me"; } } diff --git a/src/Microsoft.AspNet.Security.Facebook/FacebookAuthenticationHandler.cs b/src/Microsoft.AspNet.Security.Facebook/FacebookAuthenticationHandler.cs index 4dde8b75d..652090255 100644 --- a/src/Microsoft.AspNet.Security.Facebook/FacebookAuthenticationHandler.cs +++ b/src/Microsoft.AspNet.Security.Facebook/FacebookAuthenticationHandler.cs @@ -2,7 +2,6 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; -using System.Collections.Generic; using System.Globalization; using System.Net.Http; using System.Security.Claims; @@ -11,269 +10,94 @@ using System.Threading.Tasks; using Microsoft.AspNet.Http; using Microsoft.AspNet.Http.Security; -using Microsoft.AspNet.Security.Infrastructure; +using Microsoft.AspNet.Security.OAuth; using Microsoft.AspNet.WebUtilities; using Microsoft.Framework.Logging; using Newtonsoft.Json.Linq; namespace Microsoft.AspNet.Security.Facebook { - internal class FacebookAuthenticationHandler : AuthenticationHandler + internal class FacebookAuthenticationHandler : OAuthAuthenticationHandler { - private const string XmlSchemaString = "http://www.w3.org/2001/XMLSchema#string"; - private const string TokenEndpoint = "https://graph.facebook.com/oauth/access_token"; - private const string GraphApiEndpoint = "https://graph.facebook.com/me"; - private const string AuthorizationEndpoint = "https://www.facebook.com/dialog/oauth"; - - private readonly ILogger _logger; - private readonly HttpClient _httpClient; - public FacebookAuthenticationHandler(HttpClient httpClient, ILogger logger) + : base(httpClient, logger) { - _httpClient = httpClient; - _logger = logger; - } - - protected override AuthenticationTicket AuthenticateCore() - { - return AuthenticateCoreAsync().Result; } - protected override async Task AuthenticateCoreAsync() + protected override async Task ExchangeCodeAsync(string code, string redirectUri) { - AuthenticationProperties properties = null; - - try + var queryBuilder = new QueryBuilder() { - string code = null; - string state = null; - - IReadableStringCollection query = Request.Query; - - IList values = query.GetValues("error"); - if (values != null && values.Count >= 1) - { - _logger.WriteVerbose("Remote server returned an error: " + Request.QueryString); - } - - values = query.GetValues("code"); - if (values != null && values.Count == 1) - { - code = values[0]; - } - values = query.GetValues("state"); - if (values != null && values.Count == 1) - { - state = values[0]; - } - - properties = Options.StateDataFormat.Unprotect(state); - if (properties == null) - { - return null; - } - - // OAuth2 10.12 CSRF - if (!ValidateCorrelationId(properties, _logger)) - { - return new AuthenticationTicket(null, properties); - } - - if (code == null) - { - // Null if the remote server returns an error. - return new AuthenticationTicket(null, properties); - } - - string requestPrefix = Request.Scheme + "://" + Request.Host; - string redirectUri = requestPrefix + Request.PathBase + Options.CallbackPath; - - string tokenRequest = "grant_type=authorization_code" + - "&code=" + Uri.EscapeDataString(code) + - "&redirect_uri=" + Uri.EscapeDataString(redirectUri) + - "&client_id=" + Uri.EscapeDataString(Options.AppId) + - "&client_secret=" + Uri.EscapeDataString(Options.AppSecret); - - var tokenResponse = await _httpClient.GetAsync(TokenEndpoint + "?" + tokenRequest, Context.RequestAborted); - tokenResponse.EnsureSuccessStatusCode(); - string text = await tokenResponse.Content.ReadAsStringAsync(); - IFormCollection form = FormHelpers.ParseForm(text); - - string accessToken = form["access_token"]; - string expires = form["expires"]; - string graphAddress = GraphApiEndpoint + "?access_token=" + Uri.EscapeDataString(accessToken); - if (Options.SendAppSecretProof) - { - graphAddress += "&appsecret_proof=" + GenerateAppSecretProof(accessToken); - } - - var graphResponse = await _httpClient.GetAsync(graphAddress, Context.RequestAborted); - graphResponse.EnsureSuccessStatusCode(); - text = await graphResponse.Content.ReadAsStringAsync(); - JObject user = JObject.Parse(text); - - var context = new FacebookAuthenticatedContext(Context, user, accessToken, expires); - context.Identity = new ClaimsIdentity( - Options.AuthenticationType, - ClaimsIdentity.DefaultNameClaimType, - ClaimsIdentity.DefaultRoleClaimType); - if (!string.IsNullOrEmpty(context.Id)) - { - context.Identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, context.Id, XmlSchemaString, Options.AuthenticationType)); - } - if (!string.IsNullOrEmpty(context.UserName)) - { - context.Identity.AddClaim(new Claim(ClaimsIdentity.DefaultNameClaimType, context.UserName, XmlSchemaString, Options.AuthenticationType)); - } - if (!string.IsNullOrEmpty(context.Email)) - { - context.Identity.AddClaim(new Claim(ClaimTypes.Email, context.Email, XmlSchemaString, Options.AuthenticationType)); - } - if (!string.IsNullOrEmpty(context.Name)) - { - context.Identity.AddClaim(new Claim("urn:facebook:name", context.Name, XmlSchemaString, Options.AuthenticationType)); - - // Many Facebook accounts do not set the UserName field. Fall back to the Name field instead. - if (string.IsNullOrEmpty(context.UserName)) - { - context.Identity.AddClaim(new Claim(ClaimsIdentity.DefaultNameClaimType, context.Name, XmlSchemaString, Options.AuthenticationType)); - } - } - if (!string.IsNullOrEmpty(context.Link)) - { - context.Identity.AddClaim(new Claim("urn:facebook:link", context.Link, XmlSchemaString, Options.AuthenticationType)); - } - context.Properties = properties; - - await Options.Notifications.Authenticated(context); - - return new AuthenticationTicket(context.Identity, context.Properties); - } - catch (Exception ex) + { "grant_type", "authorization_code" }, + { "code", code }, + { "redirect_uri", redirectUri }, + { "client_id", Options.AppId }, + { "client_secret", Options.AppSecret }, + }; + + var tokenResponse = await Backchannel.GetAsync(Options.TokenEndpoint + queryBuilder.ToString(), Context.RequestAborted); + tokenResponse.EnsureSuccessStatusCode(); + string oauthTokenResponse = await tokenResponse.Content.ReadAsStringAsync(); + + IFormCollection form = FormHelpers.ParseForm(oauthTokenResponse); + var response = new JObject(); + foreach (string key in form.Keys) { - _logger.WriteError("Authentication failed", ex); - return new AuthenticationTicket(null, properties); + response.Add(string.Equals(key, "expires", StringComparison.OrdinalIgnoreCase) ? "expires_in" : key, form[key]); } + // The refresh token is not available. + return new TokenResponse(response); } - protected override void ApplyResponseChallenge() + protected override async Task GetUserInformationAsync(AuthenticationProperties properties, TokenResponse tokens) { - if (Response.StatusCode != 401) + string graphAddress = Options.UserInformationEndpoint + "?access_token=" + Uri.EscapeDataString(tokens.AccessToken); + if (Options.SendAppSecretProof) { - return; + graphAddress += "&appsecret_proof=" + GenerateAppSecretProof(tokens.AccessToken); } - // Active middleware should redirect on 401 even if there wasn't an explicit challenge. - if (ChallengeContext == null && Options.AuthenticationMode == AuthenticationMode.Passive) - { - return; - } - - string baseUri = - Request.Scheme + - "://" + - Request.Host + - Request.PathBase; - - string currentUri = - baseUri + - Request.Path + - Request.QueryString; - - string redirectUri = - baseUri + - Options.CallbackPath; - - AuthenticationProperties properties; - if (ChallengeContext == null) + var graphResponse = await Backchannel.GetAsync(graphAddress, Context.RequestAborted); + graphResponse.EnsureSuccessStatusCode(); + string text = await graphResponse.Content.ReadAsStringAsync(); + JObject user = JObject.Parse(text); + + var context = new FacebookAuthenticatedContext(Context, Options, user, tokens); + context.Identity = new ClaimsIdentity( + Options.AuthenticationType, + ClaimsIdentity.DefaultNameClaimType, + ClaimsIdentity.DefaultRoleClaimType); + if (!string.IsNullOrEmpty(context.Id)) { - properties = new AuthenticationProperties(); + context.Identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, context.Id, ClaimValueTypes.String, Options.AuthenticationType)); } - else + if (!string.IsNullOrEmpty(context.UserName)) { - properties = new AuthenticationProperties(ChallengeContext.Properties); + context.Identity.AddClaim(new Claim(ClaimsIdentity.DefaultNameClaimType, context.UserName, ClaimValueTypes.String, Options.AuthenticationType)); } - if (string.IsNullOrEmpty(properties.RedirectUri)) + if (!string.IsNullOrEmpty(context.Email)) { - properties.RedirectUri = currentUri; + context.Identity.AddClaim(new Claim(ClaimTypes.Email, context.Email, ClaimValueTypes.String, Options.AuthenticationType)); } - - // OAuth2 10.12 CSRF - GenerateCorrelationId(properties); - - // comma separated - string scope = string.Join(",", Options.Scope); - - string state = Options.StateDataFormat.Protect(properties); - - string authorizationEndpoint = - AuthorizationEndpoint + - "?response_type=code" + - "&client_id=" + Uri.EscapeDataString(Options.AppId) + - "&redirect_uri=" + Uri.EscapeDataString(redirectUri) + - "&scope=" + Uri.EscapeDataString(scope) + - "&state=" + Uri.EscapeDataString(state); - - var redirectContext = new FacebookApplyRedirectContext(Context, Options, properties, authorizationEndpoint); - Options.Notifications.ApplyRedirect(redirectContext); - } - - protected override void ApplyResponseGrant() - { - // N/A - } - - public override async Task InvokeAsync() - { - return await InvokeReplyPathAsync(); - } - - private async Task InvokeReplyPathAsync() - { - if (Options.CallbackPath.HasValue && Options.CallbackPath == Request.Path) + if (!string.IsNullOrEmpty(context.Name)) { - // TODO: error responses - - AuthenticationTicket ticket = await AuthenticateAsync(); - if (ticket == null) - { - _logger.WriteWarning("Invalid return state, unable to redirect."); - Response.StatusCode = 500; - return true; - } - - var context = new FacebookReturnEndpointContext(Context, ticket); - context.SignInAsAuthenticationType = Options.SignInAsAuthenticationType; - context.RedirectUri = ticket.Properties.RedirectUri; + context.Identity.AddClaim(new Claim("urn:facebook:name", context.Name, ClaimValueTypes.String, Options.AuthenticationType)); - await Options.Notifications.ReturnEndpoint(context); - - if (context.SignInAsAuthenticationType != null && - context.Identity != null) + // Many Facebook accounts do not set the UserName field. Fall back to the Name field instead. + if (string.IsNullOrEmpty(context.UserName)) { - ClaimsIdentity grantIdentity = context.Identity; - if (!string.Equals(grantIdentity.AuthenticationType, context.SignInAsAuthenticationType, StringComparison.Ordinal)) - { - grantIdentity = new ClaimsIdentity(grantIdentity.Claims, context.SignInAsAuthenticationType, grantIdentity.NameClaimType, grantIdentity.RoleClaimType); - } - Context.Response.SignIn(context.Properties, grantIdentity); + context.Identity.AddClaim(new Claim(ClaimsIdentity.DefaultNameClaimType, context.Name, ClaimValueTypes.String, Options.AuthenticationType)); } + } + if (!string.IsNullOrEmpty(context.Link)) + { + context.Identity.AddClaim(new Claim("urn:facebook:link", context.Link, ClaimValueTypes.String, Options.AuthenticationType)); + } + context.Properties = properties; - if (!context.IsRequestCompleted && context.RedirectUri != null) - { - string redirectUri = context.RedirectUri; - if (context.Identity == null) - { - // add a redirect hint that sign-in failed in some way - redirectUri = QueryHelpers.AddQueryString(redirectUri, "error", "access_denied"); - } - Response.Redirect(redirectUri); - context.RequestCompleted(); - } + await Options.Notifications.Authenticated(context); - return context.IsRequestCompleted; - } - return false; + return new AuthenticationTicket(context.Identity, context.Properties); } private string GenerateAppSecretProof(string accessToken) @@ -289,5 +113,13 @@ private string GenerateAppSecretProof(string accessToken) return builder.ToString(); } } + + protected override string FormatScope() + { + // Facebook deviates from the OAuth spec here. They require comma separated instead of space separated. + // https://developers.facebook.com/docs/reference/dialogs/oauth + // http://tools.ietf.org/html/rfc6749#section-3.3 + return string.Join(",", Options.Scope); + } } } diff --git a/src/Microsoft.AspNet.Security.Facebook/FacebookAuthenticationMiddleware.cs b/src/Microsoft.AspNet.Security.Facebook/FacebookAuthenticationMiddleware.cs index e67abf1c9..2d653d7c2 100644 --- a/src/Microsoft.AspNet.Security.Facebook/FacebookAuthenticationMiddleware.cs +++ b/src/Microsoft.AspNet.Security.Facebook/FacebookAuthenticationMiddleware.cs @@ -2,13 +2,11 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; -using System.Diagnostics.CodeAnalysis; using System.Globalization; -using System.Net.Http; using Microsoft.AspNet.Builder; -using Microsoft.AspNet.Security.DataHandler; using Microsoft.AspNet.Security.DataProtection; using Microsoft.AspNet.Security.Infrastructure; +using Microsoft.AspNet.Security.OAuth; using Microsoft.Framework.Logging; namespace Microsoft.AspNet.Security.Facebook @@ -16,12 +14,8 @@ namespace Microsoft.AspNet.Security.Facebook /// /// An ASP.NET middleware for authenticating users using Facebook. /// - [SuppressMessage("Microsoft.Design", "CA1001:TypesThatOwnDisposableFieldsShouldBeDisposable", Justification = "Middleware is not disposable.")] - public class FacebookAuthenticationMiddleware : AuthenticationMiddleware + public class FacebookAuthenticationMiddleware : OAuthAuthenticationMiddleware { - private readonly ILogger _logger; - private readonly HttpClient _httpClient; - /// /// Initializes a new . /// @@ -34,7 +28,7 @@ public FacebookAuthenticationMiddleware( IDataProtectionProvider dataProtectionProvider, ILoggerFactory loggerFactory, FacebookAuthenticationOptions options) - : base(next, options) + : base(next, dataProtectionProvider, loggerFactory, options) { if (string.IsNullOrWhiteSpace(Options.AppId)) { @@ -45,22 +39,10 @@ public FacebookAuthenticationMiddleware( throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, Resources.Exception_OptionMustBeProvided, "AppSecret")); } - _logger = loggerFactory.Create(typeof(FacebookAuthenticationMiddleware).FullName); - if (Options.Notifications == null) { Options.Notifications = new FacebookAuthenticationNotifications(); } - if (Options.StateDataFormat == null) - { - IDataProtector dataProtector = DataProtectionHelpers.CreateDataProtector(dataProtectionProvider, - typeof(FacebookAuthenticationMiddleware).FullName, options.AuthenticationType, "v1"); - Options.StateDataFormat = new PropertiesDataFormat(dataProtector); - } - - _httpClient = new HttpClient(ResolveHttpMessageHandler(Options)); - _httpClient.Timeout = Options.BackchannelTimeout; - _httpClient.MaxResponseContentBufferSize = 1024 * 1024 * 10; // 10 MB } /// @@ -69,30 +51,7 @@ public FacebookAuthenticationMiddleware( /// An configured with the supplied to the constructor. protected override AuthenticationHandler CreateHandler() { - return new FacebookAuthenticationHandler(_httpClient, _logger); - } - - [SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Justification = "Managed by caller")] - private static HttpMessageHandler ResolveHttpMessageHandler(FacebookAuthenticationOptions options) - { - HttpMessageHandler handler = options.BackchannelHttpHandler ?? -#if ASPNET50 - new WebRequestHandler(); - // If they provided a validator, apply it or fail. - if (options.BackchannelCertificateValidator != null) - { - // Set the cert validate callback - var webRequestHandler = handler as WebRequestHandler; - if (webRequestHandler == null) - { - throw new InvalidOperationException(Resources.Exception_ValidatorHandlerMismatch); - } - webRequestHandler.ServerCertificateValidationCallback = options.BackchannelCertificateValidator.Validate; - } -#else - new WinHttpHandler(); -#endif - return handler; + return new FacebookAuthenticationHandler(Backchannel, Logger); } } } diff --git a/src/Microsoft.AspNet.Security.Facebook/FacebookAuthenticationOptions.cs b/src/Microsoft.AspNet.Security.Facebook/FacebookAuthenticationOptions.cs index 1d4fa9a54..7f1199a08 100644 --- a/src/Microsoft.AspNet.Security.Facebook/FacebookAuthenticationOptions.cs +++ b/src/Microsoft.AspNet.Security.Facebook/FacebookAuthenticationOptions.cs @@ -1,108 +1,49 @@ // Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -using System; -using System.Collections.Generic; -using System.Diagnostics.CodeAnalysis; -using System.Net.Http; using Microsoft.AspNet.Http; -using Microsoft.AspNet.Http.Security; +using Microsoft.AspNet.Security.OAuth; namespace Microsoft.AspNet.Security.Facebook { /// /// Configuration options for . /// - public class FacebookAuthenticationOptions : AuthenticationOptions + public class FacebookAuthenticationOptions : OAuthAuthenticationOptions { /// /// Initializes a new . /// - [SuppressMessage("Microsoft.Globalization", "CA1303:Do not pass literals as localized parameters", - MessageId = "Microsoft.AspNet.Security.Facebook.FacebookAuthenticationOptions.set_Caption(System.String)", Justification = "Not localizable.")] public FacebookAuthenticationOptions() : base(FacebookAuthenticationDefaults.AuthenticationType) { - Caption = FacebookAuthenticationDefaults.AuthenticationType; CallbackPath = new PathString("/signin-facebook"); - AuthenticationMode = AuthenticationMode.Passive; - Scope = new List(); - BackchannelTimeout = TimeSpan.FromSeconds(60); SendAppSecretProof = true; + AuthorizationEndpoint = FacebookAuthenticationDefaults.AuthorizationEndpoint; + TokenEndpoint = FacebookAuthenticationDefaults.TokenEndpoint; + UserInformationEndpoint = FacebookAuthenticationDefaults.UserInformationEndpoint; } + // Facebook uses a non-standard term for this field. /// /// Gets or sets the Facebook-assigned appId. /// - public string AppId { get; set; } + public string AppId + { + get { return ClientId; } + set { ClientId = value; } + } + // Facebook uses a non-standard term for this field. /// /// Gets or sets the Facebook-assigned app secret. /// - public string AppSecret { get; set; } -#if ASPNET50 - /// - /// Gets or sets the a pinned certificate validator to use to validate the endpoints used - /// in back channel communications belong to Facebook. - /// - /// - /// The pinned certificate validator. - /// - /// If this property is null then the default certificate checks are performed, - /// validating the subject name and if the signing chain is a trusted party. - public ICertificateValidator BackchannelCertificateValidator { get; set; } -#endif - /// - /// Gets or sets timeout value in milliseconds for back channel communications with Facebook. - /// - /// - /// The back channel timeout in milliseconds. - /// - public TimeSpan BackchannelTimeout { get; set; } - - /// - /// The HttpMessageHandler used to communicate with Facebook. - /// This cannot be set at the same time as BackchannelCertificateValidator unless the value - /// can be downcast to a WebRequestHandler. - /// - public HttpMessageHandler BackchannelHttpHandler { get; set; } - - /// - /// Get or sets the text that the user can display on a sign in user interface. - /// - public string Caption + public string AppSecret { - get { return Description.Caption; } - set { Description.Caption = value; } + get { return ClientSecret; } + set { ClientSecret = value; } } - /// - /// The request path within the application's base path where the user-agent will be returned. - /// The middleware will process this request when it arrives. - /// Default value is "/signin-facebook". - /// - public PathString CallbackPath { get; set; } - - /// - /// Gets or sets the name of another authentication middleware which will be responsible for actually issuing a user . - /// - public string SignInAsAuthenticationType { get; set; } - - /// - /// Gets or sets the used to handle authentication events. - /// - public IFacebookAuthenticationNotifications Notifications { get; set; } - - /// - /// Gets or sets the type used to secure data handled by the middleware. - /// - public ISecureDataFormat StateDataFormat { get; set; } - - /// - /// A list of permissions to request. - /// - public IList Scope { get; private set; } - /// /// Gets or sets if the appsecret_proof should be generated and sent with Facebook API calls. /// This is enabled by default. diff --git a/src/Microsoft.AspNet.Security.Facebook/Notifications/FacebookApplyRedirectContext.cs b/src/Microsoft.AspNet.Security.Facebook/Notifications/FacebookApplyRedirectContext.cs deleted file mode 100644 index e3e1b35b3..000000000 --- a/src/Microsoft.AspNet.Security.Facebook/Notifications/FacebookApplyRedirectContext.cs +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using Microsoft.AspNet.Http; -using Microsoft.AspNet.Http.Security; -using Microsoft.AspNet.Security.Notifications; - -namespace Microsoft.AspNet.Security.Facebook -{ - /// - /// The Context passed when a Challenge causes a redirect to authorize endpoint in the Facebook middleware. - /// - public class FacebookApplyRedirectContext : BaseContext - { - /// - /// Creates a new context object. - /// - /// The http request context. - /// The Facebook middleware options. - /// The authentication properties of the challenge. - /// The initial redirect URI. - [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings", MessageId = "3#", - Justification = "Represents header value")] - public FacebookApplyRedirectContext(HttpContext context, FacebookAuthenticationOptions options, - AuthenticationProperties properties, string redirectUri) - : base(context, options) - { - RedirectUri = redirectUri; - Properties = properties; - } - - /// - /// Gets the URI used for the redirect operation. - /// - [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1056:UriPropertiesShouldNotBeStrings", Justification = "Represents header value")] - public string RedirectUri { get; private set; } - - /// - /// Gets the authentication properties of the challenge. - /// - public AuthenticationProperties Properties { get; private set; } - } -} diff --git a/src/Microsoft.AspNet.Security.Facebook/Notifications/FacebookAuthenticatedContext.cs b/src/Microsoft.AspNet.Security.Facebook/Notifications/FacebookAuthenticatedContext.cs index 6797ed495..aa4e07daa 100644 --- a/src/Microsoft.AspNet.Security.Facebook/Notifications/FacebookAuthenticatedContext.cs +++ b/src/Microsoft.AspNet.Security.Facebook/Notifications/FacebookAuthenticatedContext.cs @@ -1,12 +1,9 @@ // Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -using System; -using System.Globalization; -using System.Security.Claims; +using System.Net.Http; using Microsoft.AspNet.Http; -using Microsoft.AspNet.Http.Security; -using Microsoft.AspNet.Security.Notifications; +using Microsoft.AspNet.Security.OAuth; using Newtonsoft.Json.Linq; namespace Microsoft.AspNet.Security.Facebook @@ -14,27 +11,17 @@ namespace Microsoft.AspNet.Security.Facebook /// /// Contains information about the login session as well as the user . /// - public class FacebookAuthenticatedContext : BaseContext + public class FacebookAuthenticatedContext : OAuthAuthenticatedContext { /// /// Initializes a new . /// /// The HTTP environment. /// The JSON-serialized user. - /// The Facebook Access token. - /// Seconds until expiration. - public FacebookAuthenticatedContext(HttpContext context, JObject user, string accessToken, string expires) - : base(context) + /// The Facebook Access token. + public FacebookAuthenticatedContext(HttpContext context, OAuthAuthenticationOptions options, JObject user, TokenResponse tokens) + : base(context, options, user, tokens) { - User = user; - AccessToken = accessToken; - - int expiresValue; - if (Int32.TryParse(expires, NumberStyles.Integer, CultureInfo.InvariantCulture, out expiresValue)) - { - ExpiresIn = TimeSpan.FromSeconds(expiresValue); - } - Id = TryGetValue(user, "id"); Name = TryGetValue(user, "name"); Link = TryGetValue(user, "link"); @@ -42,21 +29,6 @@ public FacebookAuthenticatedContext(HttpContext context, JObject user, string ac Email = TryGetValue(user, "email"); } - /// - /// Gets the JSON-serialized user. - /// - public JObject User { get; private set; } - - /// - /// Gets the Facebook access token. - /// - public string AccessToken { get; private set; } - - /// - /// Gets the Facebook access token expiration time. - /// - public TimeSpan? ExpiresIn { get; set; } - /// /// Gets the Facebook user ID. /// @@ -82,16 +54,6 @@ public FacebookAuthenticatedContext(HttpContext context, JObject user, string ac /// public string Email { get; private set; } - /// - /// Gets the representing the user. - /// - public ClaimsIdentity Identity { get; set; } - - /// - /// Gets or sets a property bag for common authentication properties. - /// - public AuthenticationProperties Properties { get; set; } - private static string TryGetValue(JObject user, string propertyName) { JToken value; diff --git a/src/Microsoft.AspNet.Security.Facebook/Notifications/FacebookAuthenticationNotifications.cs b/src/Microsoft.AspNet.Security.Facebook/Notifications/FacebookAuthenticationNotifications.cs index b9b33b125..f86287cc1 100644 --- a/src/Microsoft.AspNet.Security.Facebook/Notifications/FacebookAuthenticationNotifications.cs +++ b/src/Microsoft.AspNet.Security.Facebook/Notifications/FacebookAuthenticationNotifications.cs @@ -3,13 +3,14 @@ using System; using System.Threading.Tasks; +using Microsoft.AspNet.Security.OAuth; namespace Microsoft.AspNet.Security.Facebook { /// /// The default implementation. /// - public class FacebookAuthenticationNotifications : IFacebookAuthenticationNotifications + public class FacebookAuthenticationNotifications : OAuthAuthenticationNotifications, IFacebookAuthenticationNotifications { /// /// Initializes a new . @@ -17,9 +18,6 @@ public class FacebookAuthenticationNotifications : IFacebookAuthenticationNotifi public FacebookAuthenticationNotifications() { OnAuthenticated = context => Task.FromResult(null); - OnReturnEndpoint = context => Task.FromResult(null); - OnApplyRedirect = context => - context.Response.Redirect(context.RedirectUri); } /// @@ -27,16 +25,6 @@ public FacebookAuthenticationNotifications() /// public Func OnAuthenticated { get; set; } - /// - /// Gets or sets the function that is invoked when the ReturnEndpoint method is invoked. - /// - public Func OnReturnEndpoint { get; set; } - - /// - /// Gets or sets the delegate that is invoked when the ApplyRedirect method is invoked. - /// - public Action OnApplyRedirect { get; set; } - /// /// Invoked whenever Facebook succesfully authenticates a user. /// @@ -46,24 +34,5 @@ public virtual Task Authenticated(FacebookAuthenticatedContext context) { return OnAuthenticated(context); } - - /// - /// Invoked prior to the being saved in a local cookie and the browser being redirected to the originally requested URL. - /// - /// - /// A representing the completed operation. - public virtual Task ReturnEndpoint(FacebookReturnEndpointContext context) - { - return OnReturnEndpoint(context); - } - - /// - /// Called when a Challenge causes a redirect to authorize endpoint in the Facebook middleware. - /// - /// Contains redirect URI and of the challenge. - public virtual void ApplyRedirect(FacebookApplyRedirectContext context) - { - OnApplyRedirect(context); - } } } diff --git a/src/Microsoft.AspNet.Security.Facebook/Notifications/FacebookReturnEndpointContext.cs b/src/Microsoft.AspNet.Security.Facebook/Notifications/FacebookReturnEndpointContext.cs deleted file mode 100644 index 29786a906..000000000 --- a/src/Microsoft.AspNet.Security.Facebook/Notifications/FacebookReturnEndpointContext.cs +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using Microsoft.AspNet.Http; -using Microsoft.AspNet.Security.Notifications; - -namespace Microsoft.AspNet.Security.Facebook -{ - /// - /// Provides context information for notifications. - /// - public class FacebookReturnEndpointContext : ReturnEndpointContext - { - /// - /// Creates a new context object. - /// - /// The http environment. - /// The authentication ticket. - public FacebookReturnEndpointContext( - HttpContext context, - AuthenticationTicket ticket) - : base(context, ticket) - { - } - } -} diff --git a/src/Microsoft.AspNet.Security.Facebook/Notifications/IFacebookAuthenticationNotifications.cs b/src/Microsoft.AspNet.Security.Facebook/Notifications/IFacebookAuthenticationNotifications.cs index 236cba3ac..0849a84a0 100644 --- a/src/Microsoft.AspNet.Security.Facebook/Notifications/IFacebookAuthenticationNotifications.cs +++ b/src/Microsoft.AspNet.Security.Facebook/Notifications/IFacebookAuthenticationNotifications.cs @@ -2,13 +2,14 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System.Threading.Tasks; +using Microsoft.AspNet.Security.OAuth; namespace Microsoft.AspNet.Security.Facebook { /// /// Specifies callback methods which the invokes to enable developer control over the authentication process. /// - public interface IFacebookAuthenticationNotifications + public interface IFacebookAuthenticationNotifications : IOAuthAuthenticationNotifications { /// /// Invoked when Facebook succesfully authenticates a user. @@ -16,18 +17,5 @@ public interface IFacebookAuthenticationNotifications /// Contains information about the login session as well as the user . /// A representing the completed operation. Task Authenticated(FacebookAuthenticatedContext context); - - /// - /// Invoked prior to the being saved in a local cookie and the browser being redirected to the originally requested URL. - /// - /// - /// A representing the completed operation. - Task ReturnEndpoint(FacebookReturnEndpointContext context); - - /// - /// Called when a Challenge causes a redirect to authorize endpoint in the Facebook middleware. - /// - /// Contains redirect URI and of the challenge. - void ApplyRedirect(FacebookApplyRedirectContext context); } } diff --git a/src/Microsoft.AspNet.Security.Facebook/Resources.Designer.cs b/src/Microsoft.AspNet.Security.Facebook/Resources.Designer.cs index dca281f82..18a738d70 100644 --- a/src/Microsoft.AspNet.Security.Facebook/Resources.Designer.cs +++ b/src/Microsoft.AspNet.Security.Facebook/Resources.Designer.cs @@ -68,14 +68,5 @@ internal static string Exception_OptionMustBeProvided { return ResourceManager.GetString("Exception_OptionMustBeProvided", resourceCulture); } } - - /// - /// Looks up a localized string similar to An ICertificateValidator cannot be specified at the same time as an HttpMessageHandler unless it is a WebRequestHandler.. - /// - internal static string Exception_ValidatorHandlerMismatch { - get { - return ResourceManager.GetString("Exception_ValidatorHandlerMismatch", resourceCulture); - } - } } } diff --git a/src/Microsoft.AspNet.Security.Facebook/Resources.resx b/src/Microsoft.AspNet.Security.Facebook/Resources.resx index 2a19bea96..56ef7f56b 100644 --- a/src/Microsoft.AspNet.Security.Facebook/Resources.resx +++ b/src/Microsoft.AspNet.Security.Facebook/Resources.resx @@ -120,7 +120,4 @@ The '{0}' option must be provided. - - An ICertificateValidator cannot be specified at the same time as an HttpMessageHandler unless it is a WebRequestHandler. - \ No newline at end of file diff --git a/src/Microsoft.AspNet.Security.Facebook/project.json b/src/Microsoft.AspNet.Security.Facebook/project.json index bf9da2253..fbbb32c78 100644 --- a/src/Microsoft.AspNet.Security.Facebook/project.json +++ b/src/Microsoft.AspNet.Security.Facebook/project.json @@ -5,6 +5,7 @@ "Microsoft.AspNet.RequestContainer": "1.0.0-*", "Microsoft.AspNet.Security": "1.0.0-*", "Microsoft.AspNet.Security.DataProtection": "1.0.0-*", + "Microsoft.AspNet.Security.OAuth": "1.0.0-*", "Microsoft.AspNet.WebUtilities": "1.0.0-*", "Microsoft.Framework.Logging": "1.0.0-*", "Newtonsoft.Json": "5.0.8", @@ -13,7 +14,6 @@ "frameworks": { "aspnet50": { "dependencies": { - "System.Net.Http.WebRequest": "" } }, "aspnetcore50": { @@ -27,7 +27,6 @@ "System.IO": "4.0.10.0", "System.IO.Compression": "4.0.0.0", "System.Linq": "4.0.0.0", - "System.Net.Http.WinHttpHandler": "4.0.0.0", "System.Reflection": "4.0.10.0", "System.Resources.ResourceManager": "4.0.0.0", "System.Runtime": "4.0.20.0", diff --git a/src/Microsoft.AspNet.Security.Google/GoogleAuthenticationDefaults.cs b/src/Microsoft.AspNet.Security.Google/GoogleAuthenticationDefaults.cs index b13506384..acf982906 100644 --- a/src/Microsoft.AspNet.Security.Google/GoogleAuthenticationDefaults.cs +++ b/src/Microsoft.AspNet.Security.Google/GoogleAuthenticationDefaults.cs @@ -6,5 +6,11 @@ namespace Microsoft.AspNet.Security.Google public static class GoogleAuthenticationDefaults { public const string AuthenticationType = "Google"; + + public const string AuthorizationEndpoint = "https://accounts.google.com/o/oauth2/auth"; + + public const string TokenEndpoint = "https://accounts.google.com/o/oauth2/token"; + + public const string UserInformationEndpoint = "https://www.googleapis.com/plus/v1/people/me"; } } diff --git a/src/Microsoft.AspNet.Security.Google/GoogleAuthenticationHandler.cs b/src/Microsoft.AspNet.Security.Google/GoogleAuthenticationHandler.cs index fe2a4feab..1d75c889f 100644 --- a/src/Microsoft.AspNet.Security.Google/GoogleAuthenticationHandler.cs +++ b/src/Microsoft.AspNet.Security.Google/GoogleAuthenticationHandler.cs @@ -7,212 +7,84 @@ using System.Net.Http.Headers; using System.Security.Claims; using System.Threading.Tasks; -using Microsoft.AspNet.Http; using Microsoft.AspNet.Http.Security; -using Microsoft.AspNet.Security.Infrastructure; +using Microsoft.AspNet.Security.OAuth; using Microsoft.AspNet.WebUtilities; using Microsoft.Framework.Logging; using Newtonsoft.Json.Linq; namespace Microsoft.AspNet.Security.Google { - internal class GoogleAuthenticationHandler : AuthenticationHandler + internal class GoogleAuthenticationHandler : OAuthAuthenticationHandler { - private const string TokenEndpoint = "https://accounts.google.com/o/oauth2/token"; - private const string UserInfoEndpoint = "https://www.googleapis.com/plus/v1/people/me"; - private const string AuthorizeEndpoint = "https://accounts.google.com/o/oauth2/auth"; - - private readonly ILogger _logger; - private readonly HttpClient _httpClient; - public GoogleAuthenticationHandler(HttpClient httpClient, ILogger logger) + : base(httpClient, logger) { - _httpClient = httpClient; - _logger = logger; } - protected override AuthenticationTicket AuthenticateCore() + protected override async Task GetUserInformationAsync(AuthenticationProperties properties, TokenResponse tokens) { - return AuthenticateCoreAsync().Result; - } - - protected override async Task AuthenticateCoreAsync() - { - AuthenticationProperties properties = null; - - try + // Get the Google user + HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, Options.UserInformationEndpoint); + request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", tokens.AccessToken); + HttpResponseMessage graphResponse = await Backchannel.SendAsync(request, Context.RequestAborted); + graphResponse.EnsureSuccessStatusCode(); + var text = await graphResponse.Content.ReadAsStringAsync(); + JObject user = JObject.Parse(text); + + var context = new GoogleAuthenticatedContext(Context, Options, user, tokens); + context.Identity = new ClaimsIdentity( + Options.AuthenticationType, + ClaimsIdentity.DefaultNameClaimType, + ClaimsIdentity.DefaultRoleClaimType); + + if (!string.IsNullOrEmpty(context.Id)) { - string code = null; - string state = null; - - IReadableStringCollection query = Request.Query; - IList values = query.GetValues("code"); - if (values != null && values.Count == 1) - { - code = values[0]; - } - values = query.GetValues("state"); - if (values != null && values.Count == 1) - { - state = values[0]; - } - - properties = Options.StateDataFormat.Unprotect(state); - if (properties == null) - { - return null; - } - - // OAuth2 10.12 CSRF - if (!ValidateCorrelationId(properties, _logger)) - { - return new AuthenticationTicket(null, properties); - } - - string requestPrefix = Request.Scheme + "://" + Request.Host; - string redirectUri = requestPrefix + Request.PathBase + Options.CallbackPath; - - // Build up the body for the token request - var body = new List>(); - body.Add(new KeyValuePair("grant_type", "authorization_code")); - body.Add(new KeyValuePair("code", code)); - body.Add(new KeyValuePair("redirect_uri", redirectUri)); - body.Add(new KeyValuePair("client_id", Options.ClientId)); - body.Add(new KeyValuePair("client_secret", Options.ClientSecret)); - - // Request the token - HttpResponseMessage tokenResponse = - await _httpClient.PostAsync(TokenEndpoint, new FormUrlEncodedContent(body)); - tokenResponse.EnsureSuccessStatusCode(); - string text = await tokenResponse.Content.ReadAsStringAsync(); - - // Deserializes the token response - JObject response = JObject.Parse(text); - string accessToken = response.Value("access_token"); - string expires = response.Value("expires_in"); - string refreshToken = response.Value("refresh_token"); - - if (string.IsNullOrWhiteSpace(accessToken)) - { - _logger.WriteWarning("Access token was not found"); - return new AuthenticationTicket(null, properties); - } - - // Get the Google user - HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, UserInfoEndpoint); - request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", accessToken); - HttpResponseMessage graphResponse = await _httpClient.SendAsync(request, Context.RequestAborted); - graphResponse.EnsureSuccessStatusCode(); - text = await graphResponse.Content.ReadAsStringAsync(); - JObject user = JObject.Parse(text); - - var context = new GoogleAuthenticatedContext(Context, user, accessToken, refreshToken, expires); - context.Identity = new ClaimsIdentity( - Options.AuthenticationType, - ClaimsIdentity.DefaultNameClaimType, - ClaimsIdentity.DefaultRoleClaimType); - if (!string.IsNullOrEmpty(context.Id)) - { - context.Identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, context.Id, - ClaimValueTypes.String, Options.AuthenticationType)); - } - if (!string.IsNullOrEmpty(context.GivenName)) - { - context.Identity.AddClaim(new Claim(ClaimTypes.GivenName, context.GivenName, - ClaimValueTypes.String, Options.AuthenticationType)); - } - if (!string.IsNullOrEmpty(context.FamilyName)) - { - context.Identity.AddClaim(new Claim(ClaimTypes.Surname, context.FamilyName, - ClaimValueTypes.String, Options.AuthenticationType)); - } - if (!string.IsNullOrEmpty(context.Name)) - { - context.Identity.AddClaim(new Claim(ClaimTypes.Name, context.Name, ClaimValueTypes.String, - Options.AuthenticationType)); - } - if (!string.IsNullOrEmpty(context.Email)) - { - context.Identity.AddClaim(new Claim(ClaimTypes.Email, context.Email, ClaimValueTypes.String, - Options.AuthenticationType)); - } - - if (!string.IsNullOrEmpty(context.Profile)) - { - context.Identity.AddClaim(new Claim("urn:google:profile", context.Profile, ClaimValueTypes.String, - Options.AuthenticationType)); - } - context.Properties = properties; - - await Options.Notifications.Authenticated(context); - - return new AuthenticationTicket(context.Identity, context.Properties); + context.Identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, context.Id, + ClaimValueTypes.String, Options.AuthenticationType)); } - catch (Exception ex) + if (!string.IsNullOrEmpty(context.GivenName)) { - _logger.WriteError("Authentication failed", ex); - return new AuthenticationTicket(null, properties); + context.Identity.AddClaim(new Claim(ClaimTypes.GivenName, context.GivenName, + ClaimValueTypes.String, Options.AuthenticationType)); } - } - - protected override void ApplyResponseChallenge() - { - if (Response.StatusCode != 401) + if (!string.IsNullOrEmpty(context.FamilyName)) { - return; + context.Identity.AddClaim(new Claim(ClaimTypes.Surname, context.FamilyName, + ClaimValueTypes.String, Options.AuthenticationType)); } - - // Active middleware should redirect on 401 even if there wasn't an explicit challenge. - if (ChallengeContext == null && Options.AuthenticationMode == AuthenticationMode.Passive) + if (!string.IsNullOrEmpty(context.Name)) { - return; + context.Identity.AddClaim(new Claim(ClaimTypes.Name, context.Name, ClaimValueTypes.String, + Options.AuthenticationType)); } - - string baseUri = - Request.Scheme + - "://" + - Request.Host + - Request.PathBase; - - string currentUri = - baseUri + - Request.Path + - Request.QueryString; - - string redirectUri = - baseUri + - Options.CallbackPath; - - AuthenticationProperties properties; - if (ChallengeContext == null) + if (!string.IsNullOrEmpty(context.Email)) { - properties = new AuthenticationProperties(); + context.Identity.AddClaim(new Claim(ClaimTypes.Email, context.Email, ClaimValueTypes.String, + Options.AuthenticationType)); } - else - { - properties = new AuthenticationProperties(ChallengeContext.Properties); - } - if (string.IsNullOrEmpty(properties.RedirectUri)) + if (!string.IsNullOrEmpty(context.Profile)) { - properties.RedirectUri = currentUri; + context.Identity.AddClaim(new Claim("urn:google:profile", context.Profile, ClaimValueTypes.String, + Options.AuthenticationType)); } + context.Properties = properties; + + await Options.Notifications.Authenticated(context); - // OAuth2 10.12 CSRF - GenerateCorrelationId(properties); + return new AuthenticationTicket(context.Identity, context.Properties); + } + + // TODO: Abstract this properties override pattern into the base class? + protected override string BuildChallengeUrl(AuthenticationProperties properties, string redirectUri) + { + string scope = FormatScope(); var queryStrings = new Dictionary(StringComparer.OrdinalIgnoreCase); queryStrings.Add("response_type", "code"); queryStrings.Add("client_id", Options.ClientId); queryStrings.Add("redirect_uri", redirectUri); - // space separated - string scope = string.Join(" ", Options.Scope); - if (string.IsNullOrEmpty(scope)) - { - // Google OAuth 2.0 asks for non-empty scope. If user didn't set it, set default scope to - // "openid profile email" to get basic user information. - scope = "openid profile email"; - } AddQueryString(queryStrings, properties, "scope", scope); AddQueryString(queryStrings, properties, "access_type", Options.AccessType); @@ -222,65 +94,8 @@ protected override void ApplyResponseChallenge() string state = Options.StateDataFormat.Protect(properties); queryStrings.Add("state", state); - string authorizationEndpoint = QueryHelpers.AddQueryString(AuthorizeEndpoint, queryStrings); - - var redirectContext = new GoogleApplyRedirectContext( - Context, Options, - properties, authorizationEndpoint); - Options.Notifications.ApplyRedirect(redirectContext); - } - - public override async Task InvokeAsync() - { - return await InvokeReplyPathAsync(); - } - - private async Task InvokeReplyPathAsync() - { - if (Options.CallbackPath.HasValue && Options.CallbackPath == Request.Path) - { - // TODO: error responses - - AuthenticationTicket ticket = await AuthenticateAsync(); - if (ticket == null) - { - _logger.WriteWarning("Invalid return state, unable to redirect."); - Response.StatusCode = 500; - return true; - } - - var context = new GoogleReturnEndpointContext(Context, ticket); - context.SignInAsAuthenticationType = Options.SignInAsAuthenticationType; - context.RedirectUri = ticket.Properties.RedirectUri; - - await Options.Notifications.ReturnEndpoint(context); - - if (context.SignInAsAuthenticationType != null && - context.Identity != null) - { - ClaimsIdentity grantIdentity = context.Identity; - if (!string.Equals(grantIdentity.AuthenticationType, context.SignInAsAuthenticationType, StringComparison.Ordinal)) - { - grantIdentity = new ClaimsIdentity(grantIdentity.Claims, context.SignInAsAuthenticationType, grantIdentity.NameClaimType, grantIdentity.RoleClaimType); - } - Context.Response.SignIn(context.Properties, grantIdentity); - } - - if (!context.IsRequestCompleted && context.RedirectUri != null) - { - string redirectUri = context.RedirectUri; - if (context.Identity == null) - { - // add a redirect hint that sign-in failed in some way - redirectUri = QueryHelpers.AddQueryString(redirectUri, "error", "access_denied"); - } - Response.Redirect(redirectUri); - context.RequestCompleted(); - } - - return context.IsRequestCompleted; - } - return false; + string authorizationEndpoint = QueryHelpers.AddQueryString(Options.AuthorizationEndpoint, queryStrings); + return authorizationEndpoint; } private static void AddQueryString(IDictionary queryStrings, AuthenticationProperties properties, @@ -304,10 +119,5 @@ private static void AddQueryString(IDictionary queryStrings, Aut queryStrings[name] = value; } - - protected override void ApplyResponseGrant() - { - // N/A - No SignIn or SignOut support. - } } } diff --git a/src/Microsoft.AspNet.Security.Google/GoogleAuthenticationMiddleware.cs b/src/Microsoft.AspNet.Security.Google/GoogleAuthenticationMiddleware.cs index 66768cbb8..08d7610fa 100644 --- a/src/Microsoft.AspNet.Security.Google/GoogleAuthenticationMiddleware.cs +++ b/src/Microsoft.AspNet.Security.Google/GoogleAuthenticationMiddleware.cs @@ -9,6 +9,7 @@ using Microsoft.AspNet.Security.DataHandler; using Microsoft.AspNet.Security.DataProtection; using Microsoft.AspNet.Security.Infrastructure; +using Microsoft.AspNet.Security.OAuth; using Microsoft.Framework.Logging; namespace Microsoft.AspNet.Security.Google @@ -17,11 +18,8 @@ namespace Microsoft.AspNet.Security.Google /// An ASP.NET middleware for authenticating users using Google OAuth 2.0. /// [SuppressMessage("Microsoft.Design", "CA1001:TypesThatOwnDisposableFieldsShouldBeDisposable", Justification = "Middleware are not disposable.")] - public class GoogleAuthenticationMiddleware : AuthenticationMiddleware + public class GoogleAuthenticationMiddleware : OAuthAuthenticationMiddleware { - private readonly ILogger _logger; - private readonly HttpClient _httpClient; - /// /// Initializes a new . /// @@ -34,33 +32,22 @@ public GoogleAuthenticationMiddleware( IDataProtectionProvider dataProtectionProvider, ILoggerFactory loggerFactory, GoogleAuthenticationOptions options) - : base(next, options) + : base(next, dataProtectionProvider, loggerFactory, options) { - if (string.IsNullOrWhiteSpace(Options.ClientId)) - { - throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, Resources.Exception_OptionMustBeProvided, "ClientId")); - } - if (string.IsNullOrWhiteSpace(Options.ClientSecret)) - { - throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, Resources.Exception_OptionMustBeProvided, "ClientSecret")); - } - - _logger = loggerFactory.Create(typeof(GoogleAuthenticationMiddleware).FullName); - if (Options.Notifications == null) { Options.Notifications = new GoogleAuthenticationNotifications(); } - if (Options.StateDataFormat == null) + + if (Options.Scope.Count == 0) { - IDataProtector dataProtector = DataProtectionHelpers.CreateDataProtector(dataProtectionProvider, - typeof(GoogleAuthenticationMiddleware).FullName, options.AuthenticationType, "v1"); - Options.StateDataFormat = new PropertiesDataFormat(dataProtector); + // Google OAuth 2.0 asks for non-empty scope. If user didn't set it, set default scope to + // "openid profile email" to get basic user information. + // TODO: Should we just add these by default when we create the Options? + Options.Scope.Add("openid"); + Options.Scope.Add("profile"); + Options.Scope.Add("email"); } - - _httpClient = new HttpClient(ResolveHttpMessageHandler(Options)); - _httpClient.Timeout = Options.BackchannelTimeout; - _httpClient.MaxResponseContentBufferSize = 1024 * 1024 * 10; // 10 MB } /// @@ -69,30 +56,7 @@ public GoogleAuthenticationMiddleware( /// An configured with the supplied to the constructor. protected override AuthenticationHandler CreateHandler() { - return new GoogleAuthenticationHandler(_httpClient, _logger); - } - - [SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Justification = "Managed by caller")] - private static HttpMessageHandler ResolveHttpMessageHandler(GoogleAuthenticationOptions options) - { - HttpMessageHandler handler = options.BackchannelHttpHandler ?? -#if ASPNET50 - new WebRequestHandler(); - // If they provided a validator, apply it or fail. - if (options.BackchannelCertificateValidator != null) - { - // Set the cert validate callback - var webRequestHandler = handler as WebRequestHandler; - if (webRequestHandler == null) - { - throw new InvalidOperationException(Resources.Exception_ValidatorHandlerMismatch); - } - webRequestHandler.ServerCertificateValidationCallback = options.BackchannelCertificateValidator.Validate; - } -#else - new WinHttpHandler(); -#endif - return handler; + return new GoogleAuthenticationHandler(Backchannel, Logger); } } } diff --git a/src/Microsoft.AspNet.Security.Google/GoogleAuthenticationOptions.cs b/src/Microsoft.AspNet.Security.Google/GoogleAuthenticationOptions.cs index 1ede9f042..0b8e3ab09 100644 --- a/src/Microsoft.AspNet.Security.Google/GoogleAuthenticationOptions.cs +++ b/src/Microsoft.AspNet.Security.Google/GoogleAuthenticationOptions.cs @@ -6,102 +6,27 @@ using System.Net.Http; using Microsoft.AspNet.Http; using Microsoft.AspNet.Http.Security; +using Microsoft.AspNet.Security.OAuth; namespace Microsoft.AspNet.Security.Google { /// /// Configuration options for . /// - public class GoogleAuthenticationOptions : AuthenticationOptions + public class GoogleAuthenticationOptions : OAuthAuthenticationOptions { /// /// Initializes a new . /// - [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1303:Do not pass literals as localized parameters", - MessageId = "Microsoft.AspNet.Security.Google.GoogleAuthenticationOptions.set_Caption(System.String)", - Justification = "Not localizable.")] public GoogleAuthenticationOptions() : base(GoogleAuthenticationDefaults.AuthenticationType) { - Caption = GoogleAuthenticationDefaults.AuthenticationType; CallbackPath = new PathString("/signin-google"); - AuthenticationMode = AuthenticationMode.Passive; - Scope = new List(); - BackchannelTimeout = TimeSpan.FromSeconds(60); + AuthorizationEndpoint = GoogleAuthenticationDefaults.AuthorizationEndpoint; + TokenEndpoint = GoogleAuthenticationDefaults.TokenEndpoint; + UserInformationEndpoint = GoogleAuthenticationDefaults.UserInformationEndpoint; } - /// - /// Gets or sets the Google-assigned client id. - /// - public string ClientId { get; set; } - - /// - /// Gets or sets the Google-assigned client secret. - /// - public string ClientSecret { get; set; } -#if ASPNET50 - /// - /// Gets or sets the a pinned certificate validator to use to validate the endpoints used - /// in back channel communications belong to Google. - /// - /// - /// The pinned certificate validator. - /// - /// If this property is null then the default certificate checks are performed, - /// validating the subject name and if the signing chain is a trusted party. - public ICertificateValidator BackchannelCertificateValidator { get; set; } -#endif - /// - /// Gets or sets timeout value in milliseconds for back channel communications with Google. - /// - /// - /// The back channel timeout in milliseconds. - /// - public TimeSpan BackchannelTimeout { get; set; } - - /// - /// The HttpMessageHandler used to communicate with Google. - /// This cannot be set at the same time as BackchannelCertificateValidator unless the value - /// can be downcast to a WebRequestHandler. - /// - public HttpMessageHandler BackchannelHttpHandler { get; set; } - - /// - /// Get or sets the text that the user can display on a sign in user interface. - /// - public string Caption - { - get { return Description.Caption; } - set { Description.Caption = value; } - } - - /// - /// The request path within the application's base path where the user-agent will be returned. - /// The middleware will process this request when it arrives. - /// Default value is "/signin-google". - /// - public PathString CallbackPath { get; set; } - - /// - /// Gets or sets the name of another authentication middleware which will be responsible for actually issuing a user . - /// - public string SignInAsAuthenticationType { get; set; } - - /// - /// Gets or sets the used to handle authentication events. - /// - public IGoogleAuthenticationNotifications Notifications { get; set; } - - /// - /// Gets or sets the type used to secure data handled by the middleware. - /// - public ISecureDataFormat StateDataFormat { get; set; } - - /// - /// A list of permissions to request. - /// - public IList Scope { get; private set; } - /// /// access_type. Set to 'offline' to request a refresh token. /// diff --git a/src/Microsoft.AspNet.Security.Google/Notifications/GoogleApplyRedirectContext.cs b/src/Microsoft.AspNet.Security.Google/Notifications/GoogleApplyRedirectContext.cs deleted file mode 100644 index 7df6358dd..000000000 --- a/src/Microsoft.AspNet.Security.Google/Notifications/GoogleApplyRedirectContext.cs +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using Microsoft.AspNet.Http; -using Microsoft.AspNet.Http.Security; -using Microsoft.AspNet.Security.Notifications; - -namespace Microsoft.AspNet.Security.Google -{ - /// - /// The Context passed when a Challenge causes a redirect to authorize endpoint in the Google OAuth 2.0 middleware. - /// - public class GoogleApplyRedirectContext : BaseContext - { - /// - /// Creates a new context object. - /// - /// The HTTP request context. - /// The Google OAuth 2.0 middleware options. - /// The authentication properties of the challenge. - /// The initial redirect URI. - [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings", MessageId = "3#", - Justification = "Represents header value")] - public GoogleApplyRedirectContext(HttpContext context, GoogleAuthenticationOptions options, - AuthenticationProperties properties, string redirectUri) - : base(context, options) - { - RedirectUri = redirectUri; - Properties = properties; - } - - /// - /// Gets the URI used for the redirect operation. - /// - [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1056:UriPropertiesShouldNotBeStrings", Justification = "Represents header value")] - public string RedirectUri { get; private set; } - - /// - /// Gets the authentication properties of the challenge. - /// - public AuthenticationProperties Properties { get; private set; } - } -} diff --git a/src/Microsoft.AspNet.Security.Google/Notifications/GoogleAuthenticatedContext.cs b/src/Microsoft.AspNet.Security.Google/Notifications/GoogleAuthenticatedContext.cs index 84f535fb8..10fa2b370 100644 --- a/src/Microsoft.AspNet.Security.Google/Notifications/GoogleAuthenticatedContext.cs +++ b/src/Microsoft.AspNet.Security.Google/Notifications/GoogleAuthenticatedContext.cs @@ -3,10 +3,11 @@ using System; using System.Globalization; +using System.Net.Http; using System.Security.Claims; using Microsoft.AspNet.Http; using Microsoft.AspNet.Http.Security; -using Microsoft.AspNet.Security.Notifications; +using Microsoft.AspNet.Security.OAuth; using Newtonsoft.Json.Linq; namespace Microsoft.AspNet.Security.Google @@ -14,30 +15,17 @@ namespace Microsoft.AspNet.Security.Google /// /// Contains information about the login session as well as the user . /// - public class GoogleAuthenticatedContext : BaseContext + public class GoogleAuthenticatedContext : OAuthAuthenticatedContext { /// /// Initializes a new . /// /// The HTTP environment. /// The JSON-serialized Google user info. - /// Google OAuth 2.0 access token. - /// Goolge OAuth 2.0 refresh token. - /// Seconds until expiration. - public GoogleAuthenticatedContext(HttpContext context, JObject user, string accessToken, - string refreshToken, string expires) - : base(context) + /// Google OAuth 2.0 access token, refresh token, etc. + public GoogleAuthenticatedContext(HttpContext context, OAuthAuthenticationOptions options, JObject user, TokenResponse tokens) + : base(context, options, user, tokens) { - User = user; - AccessToken = accessToken; - RefreshToken = refreshToken; - - int expiresValue; - if (Int32.TryParse(expires, NumberStyles.Integer, CultureInfo.InvariantCulture, out expiresValue)) - { - ExpiresIn = TimeSpan.FromSeconds(expiresValue); - } - Id = TryGetValue(user, "id"); Name = TryGetValue(user, "displayName"); GivenName = TryGetValue(user, "name", "givenName"); @@ -46,32 +34,6 @@ public GoogleAuthenticatedContext(HttpContext context, JObject user, string acce Email = TryGetFirstValue(user, "emails", "value"); } - /// - /// Gets the JSON-serialized user. - /// - /// - /// Contains the Google user obtained from the userinfo endpoint. - /// - public JObject User { get; private set; } - - /// - /// Gets the Google access token. - /// - public string AccessToken { get; private set; } - - /// - /// Gets the Google refresh token. - /// - /// - /// This value is not null only when access_type authorize parameter is offline. - /// - public string RefreshToken { get; private set; } - - /// - /// Gets the Google access token expiration time. - /// - public TimeSpan? ExpiresIn { get; set; } - /// /// Gets the Google user ID. /// @@ -102,16 +64,6 @@ public GoogleAuthenticatedContext(HttpContext context, JObject user, string acce /// public string Email { get; private set; } - /// - /// Gets the representing the user. - /// - public ClaimsIdentity Identity { get; set; } - - /// - /// Gets or sets a property bag for common authentication properties. - /// - public AuthenticationProperties Properties { get; set; } - private static string TryGetValue(JObject user, string propertyName) { JToken value; diff --git a/src/Microsoft.AspNet.Security.Google/Notifications/GoogleAuthenticationNotifications.cs b/src/Microsoft.AspNet.Security.Google/Notifications/GoogleAuthenticationNotifications.cs index 36f936895..ef2e5d3ce 100644 --- a/src/Microsoft.AspNet.Security.Google/Notifications/GoogleAuthenticationNotifications.cs +++ b/src/Microsoft.AspNet.Security.Google/Notifications/GoogleAuthenticationNotifications.cs @@ -3,13 +3,14 @@ using System; using System.Threading.Tasks; +using Microsoft.AspNet.Security.OAuth; namespace Microsoft.AspNet.Security.Google { /// /// The default implementation. /// - public class GoogleAuthenticationNotifications : IGoogleAuthenticationNotifications + public class GoogleAuthenticationNotifications : OAuthAuthenticationNotifications, IGoogleAuthenticationNotifications { /// /// Initializes a new . @@ -17,8 +18,6 @@ public class GoogleAuthenticationNotifications : IGoogleAuthenticationNotificati public GoogleAuthenticationNotifications() { OnAuthenticated = context => Task.FromResult(null); - OnReturnEndpoint = context => Task.FromResult(null); - OnApplyRedirect = context => context.Response.Redirect(context.RedirectUri); } /// @@ -26,16 +25,6 @@ public GoogleAuthenticationNotifications() /// public Func OnAuthenticated { get; set; } - /// - /// Gets or sets the function that is invoked when the ReturnEndpoint method is invoked. - /// - public Func OnReturnEndpoint { get; set; } - - /// - /// Gets or sets the delegate that is invoked when the ApplyRedirect method is invoked. - /// - public Action OnApplyRedirect { get; set; } - /// /// Invoked whenever Google succesfully authenticates a user. /// @@ -45,24 +34,5 @@ public virtual Task Authenticated(GoogleAuthenticatedContext context) { return OnAuthenticated(context); } - - /// - /// Invoked prior to the being saved in a local cookie and the browser being redirected to the originally requested URL. - /// - /// Contains context information and authentication ticket of the return endpoint. - /// A representing the completed operation. - public virtual Task ReturnEndpoint(GoogleReturnEndpointContext context) - { - return OnReturnEndpoint(context); - } - - /// - /// Called when a Challenge causes a redirect to authorize endpoint in the Google OAuth 2.0 middleware. - /// - /// Contains redirect URI and of the challenge. - public virtual void ApplyRedirect(GoogleApplyRedirectContext context) - { - OnApplyRedirect(context); - } } } diff --git a/src/Microsoft.AspNet.Security.Google/Notifications/GoogleReturnEndpointContext.cs b/src/Microsoft.AspNet.Security.Google/Notifications/GoogleReturnEndpointContext.cs deleted file mode 100644 index ce6a13742..000000000 --- a/src/Microsoft.AspNet.Security.Google/Notifications/GoogleReturnEndpointContext.cs +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using Microsoft.AspNet.Http; -using Microsoft.AspNet.Security.Notifications; - -namespace Microsoft.AspNet.Security.Google -{ - /// - /// Provides context information to middleware notifications. - /// - public class GoogleReturnEndpointContext : ReturnEndpointContext - { - /// - /// Initialize a . - /// - /// The HTTP environment. - /// The authentication ticket. - public GoogleReturnEndpointContext( - HttpContext context, - AuthenticationTicket ticket) - : base(context, ticket) - { - } - } -} diff --git a/src/Microsoft.AspNet.Security.Google/Notifications/IGoogleAuthenticationNotifications.cs b/src/Microsoft.AspNet.Security.Google/Notifications/IGoogleAuthenticationNotifications.cs index 13930346c..9cf9d2dd5 100644 --- a/src/Microsoft.AspNet.Security.Google/Notifications/IGoogleAuthenticationNotifications.cs +++ b/src/Microsoft.AspNet.Security.Google/Notifications/IGoogleAuthenticationNotifications.cs @@ -2,13 +2,14 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System.Threading.Tasks; +using Microsoft.AspNet.Security.OAuth; namespace Microsoft.AspNet.Security.Google { /// /// Specifies callback methods which the invokes to enable developer control over the authentication process. /// - public interface IGoogleAuthenticationNotifications + public interface IGoogleAuthenticationNotifications : IOAuthAuthenticationNotifications { /// /// Invoked whenever Google succesfully authenticates a user. @@ -16,18 +17,5 @@ public interface IGoogleAuthenticationNotifications /// Contains information about the login session as well as the user . /// A representing the completed operation. Task Authenticated(GoogleAuthenticatedContext context); - - /// - /// Invoked prior to the being saved in a local cookie and the browser being redirected to the originally requested URL. - /// - /// Contains context information and authentication ticket of the return endpoint. - /// A representing the completed operation. - Task ReturnEndpoint(GoogleReturnEndpointContext context); - - /// - /// Called when a Challenge causes a redirect to authorize endpoint in the Google OAuth 2.0 middleware. - /// - /// Contains redirect URI and of the challenge. - void ApplyRedirect(GoogleApplyRedirectContext context); } } diff --git a/src/Microsoft.AspNet.Security.Google/project.json b/src/Microsoft.AspNet.Security.Google/project.json index bf9da2253..fbbb32c78 100644 --- a/src/Microsoft.AspNet.Security.Google/project.json +++ b/src/Microsoft.AspNet.Security.Google/project.json @@ -5,6 +5,7 @@ "Microsoft.AspNet.RequestContainer": "1.0.0-*", "Microsoft.AspNet.Security": "1.0.0-*", "Microsoft.AspNet.Security.DataProtection": "1.0.0-*", + "Microsoft.AspNet.Security.OAuth": "1.0.0-*", "Microsoft.AspNet.WebUtilities": "1.0.0-*", "Microsoft.Framework.Logging": "1.0.0-*", "Newtonsoft.Json": "5.0.8", @@ -13,7 +14,6 @@ "frameworks": { "aspnet50": { "dependencies": { - "System.Net.Http.WebRequest": "" } }, "aspnetcore50": { @@ -27,7 +27,6 @@ "System.IO": "4.0.10.0", "System.IO.Compression": "4.0.0.0", "System.Linq": "4.0.0.0", - "System.Net.Http.WinHttpHandler": "4.0.0.0", "System.Reflection": "4.0.10.0", "System.Resources.ResourceManager": "4.0.0.0", "System.Runtime": "4.0.20.0", diff --git a/src/Microsoft.AspNet.Security.MicrosoftAccount/MicrosoftAccountAuthenticationDefaults.cs b/src/Microsoft.AspNet.Security.MicrosoftAccount/MicrosoftAccountAuthenticationDefaults.cs index 8f83dac3e..825ab4121 100644 --- a/src/Microsoft.AspNet.Security.MicrosoftAccount/MicrosoftAccountAuthenticationDefaults.cs +++ b/src/Microsoft.AspNet.Security.MicrosoftAccount/MicrosoftAccountAuthenticationDefaults.cs @@ -6,5 +6,11 @@ namespace Microsoft.AspNet.Security.MicrosoftAccount public static class MicrosoftAccountAuthenticationDefaults { public const string AuthenticationType = "Microsoft"; + + public const string AuthorizationEndpoint = "https://login.live.com/oauth20_authorize.srf"; + + public const string TokenEndpoint = "https://login.live.com/oauth20_token.srf"; + + public const string UserInformationEndpoint = "https://apis.live.net/v5.0/me"; } } diff --git a/src/Microsoft.AspNet.Security.MicrosoftAccount/MicrosoftAccountAuthenticationHandler.cs b/src/Microsoft.AspNet.Security.MicrosoftAccount/MicrosoftAccountAuthenticationHandler.cs index 6ee11c1d8..502eaec13 100644 --- a/src/Microsoft.AspNet.Security.MicrosoftAccount/MicrosoftAccountAuthenticationHandler.cs +++ b/src/Microsoft.AspNet.Security.MicrosoftAccount/MicrosoftAccountAuthenticationHandler.cs @@ -4,254 +4,55 @@ using System; using System.Collections.Generic; using System.Net.Http; +using System.Net.Http.Headers; using System.Security.Claims; using System.Threading.Tasks; using Microsoft.AspNet.Http; using Microsoft.AspNet.Http.Security; -using Microsoft.AspNet.Security.Infrastructure; -using Microsoft.AspNet.WebUtilities; +using Microsoft.AspNet.Security.OAuth; using Microsoft.Framework.Logging; using Newtonsoft.Json.Linq; namespace Microsoft.AspNet.Security.MicrosoftAccount { - internal class MicrosoftAccountAuthenticationHandler : AuthenticationHandler + internal class MicrosoftAccountAuthenticationHandler : OAuthAuthenticationHandler { - private const string TokenEndpoint = "https://login.live.com/oauth20_token.srf"; - private const string GraphApiEndpoint = "https://apis.live.net/v5.0/me"; - - private readonly ILogger _logger; - private readonly HttpClient _httpClient; - public MicrosoftAccountAuthenticationHandler(HttpClient httpClient, ILogger logger) + : base(httpClient, logger) { - _httpClient = httpClient; - _logger = logger; } - public override async Task InvokeAsync() + protected override async Task GetUserInformationAsync(AuthenticationProperties properties, TokenResponse tokens) { - if (Options.CallbackPath.HasValue && Options.CallbackPath == Request.Path) - { - return await InvokeReturnPathAsync(); - } - return false; - } - - protected override AuthenticationTicket AuthenticateCore() - { - return AuthenticateCoreAsync().Result; - } - - protected override async Task AuthenticateCoreAsync() - { - AuthenticationProperties properties = null; - try - { - string code = null; - string state = null; - - IReadableStringCollection query = Request.Query; - IList values = query.GetValues("code"); - if (values != null && values.Count == 1) - { - code = values[0]; - } - values = query.GetValues("state"); - if (values != null && values.Count == 1) - { - state = values[0]; - } - - properties = Options.StateDataFormat.Unprotect(state); - if (properties == null) - { - return null; - } - - // OAuth2 10.12 CSRF - if (!ValidateCorrelationId(properties, _logger)) - { - return new AuthenticationTicket(null, properties); - } - - var tokenRequestParameters = new List>() - { - new KeyValuePair("client_id", Options.ClientId), - new KeyValuePair("redirect_uri", GenerateRedirectUri()), - new KeyValuePair("client_secret", Options.ClientSecret), - new KeyValuePair("code", code), - new KeyValuePair("grant_type", "authorization_code"), - }; - - var requestContent = new FormUrlEncodedContent(tokenRequestParameters); - - HttpResponseMessage response = await _httpClient.PostAsync(TokenEndpoint, requestContent, Context.RequestAborted); - response.EnsureSuccessStatusCode(); - string oauthTokenResponse = await response.Content.ReadAsStringAsync(); + HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, Options.UserInformationEndpoint); + request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", tokens.AccessToken); + HttpResponseMessage graphResponse = await Backchannel.SendAsync(request, Context.RequestAborted); + graphResponse.EnsureSuccessStatusCode(); + string accountString = await graphResponse.Content.ReadAsStringAsync(); + JObject accountInformation = JObject.Parse(accountString); - JObject oauth2Token = JObject.Parse(oauthTokenResponse); - var accessToken = oauth2Token["access_token"].Value(); - - // Refresh token is only available when wl.offline_access is request. - // Otherwise, it is null. - var refreshToken = oauth2Token.Value("refresh_token"); - var expire = oauth2Token.Value("expires_in"); - - if (string.IsNullOrWhiteSpace(accessToken)) - { - _logger.WriteWarning("Access token was not found"); - return new AuthenticationTicket(null, properties); - } - - HttpResponseMessage graphResponse = await _httpClient.GetAsync( - GraphApiEndpoint + "?access_token=" + Uri.EscapeDataString(accessToken), Context.RequestAborted); - graphResponse.EnsureSuccessStatusCode(); - string accountString = await graphResponse.Content.ReadAsStringAsync(); - JObject accountInformation = JObject.Parse(accountString); - - var context = new MicrosoftAccountAuthenticatedContext(Context, accountInformation, accessToken, - refreshToken, expire); - context.Identity = new ClaimsIdentity( - new[] + var context = new MicrosoftAccountAuthenticatedContext(Context, Options, accountInformation, tokens); + context.Properties = properties; + context.Identity = new ClaimsIdentity( + new[] { - new Claim(ClaimTypes.NameIdentifier, context.Id, "http://www.w3.org/2001/XMLSchema#string", Options.AuthenticationType), - new Claim(ClaimTypes.Name, context.Name, "http://www.w3.org/2001/XMLSchema#string", Options.AuthenticationType), - new Claim("urn:microsoftaccount:id", context.Id, "http://www.w3.org/2001/XMLSchema#string", Options.AuthenticationType), - new Claim("urn:microsoftaccount:name", context.Name, "http://www.w3.org/2001/XMLSchema#string", Options.AuthenticationType) + new Claim(ClaimTypes.NameIdentifier, context.Id, ClaimValueTypes.String, Options.AuthenticationType), + new Claim(ClaimTypes.Name, context.Name, ClaimValueTypes.String, Options.AuthenticationType), + new Claim("urn:microsoftaccount:id", context.Id, ClaimValueTypes.String, Options.AuthenticationType), + new Claim("urn:microsoftaccount:name", context.Name, ClaimValueTypes.String, Options.AuthenticationType) }, - Options.AuthenticationType, - ClaimsIdentity.DefaultNameClaimType, - ClaimsIdentity.DefaultRoleClaimType); - if (!string.IsNullOrWhiteSpace(context.Email)) - { - context.Identity.AddClaim(new Claim(ClaimTypes.Email, context.Email, "http://www.w3.org/2001/XMLSchema#string", Options.AuthenticationType)); - } - - await Options.Notifications.Authenticated(context); - - context.Properties = properties; - - return new AuthenticationTicket(context.Identity, context.Properties); - } - catch (Exception ex) - { - _logger.WriteError("Authentication failed", ex); - return new AuthenticationTicket(null, properties); - } - } - - protected override void ApplyResponseChallenge() - { - if (Response.StatusCode != 401) - { - return; - } - - // Active middleware should redirect on 401 even if there wasn't an explicit challenge. - if (ChallengeContext == null && Options.AuthenticationMode == AuthenticationMode.Passive) - { - return; - } - - string baseUri = Request.Scheme + "://" + Request.Host + Request.PathBase; - - string currentUri = baseUri + Request.Path + Request.QueryString; - - string redirectUri = baseUri + Options.CallbackPath; - - AuthenticationProperties properties; - if (ChallengeContext == null) - { - properties = new AuthenticationProperties(); - } - else - { - properties = new AuthenticationProperties(ChallengeContext.Properties); - } - if (string.IsNullOrEmpty(properties.RedirectUri)) - { - properties.RedirectUri = currentUri; - } - - // OAuth2 10.12 CSRF - GenerateCorrelationId(properties); - - // OAuth2 3.3 space separated - string scope = string.Join(" ", Options.Scope); - // LiveID requires a scope string, so if the user didn't set one we go for the least possible. - if (string.IsNullOrWhiteSpace(scope)) - { - scope = "wl.basic"; - } - - string state = Options.StateDataFormat.Protect(properties); - - string authorizationEndpoint = - "https://login.live.com/oauth20_authorize.srf" + - "?client_id=" + Uri.EscapeDataString(Options.ClientId) + - "&scope=" + Uri.EscapeDataString(scope) + - "&response_type=code" + - "&redirect_uri=" + Uri.EscapeDataString(redirectUri) + - "&state=" + Uri.EscapeDataString(state); + Options.AuthenticationType, + ClaimsIdentity.DefaultNameClaimType, + ClaimsIdentity.DefaultRoleClaimType); - var redirectContext = new MicrosoftAccountApplyRedirectContext( - Context, Options, - properties, authorizationEndpoint); - Options.Notifications.ApplyRedirect(redirectContext); - } - - public async Task InvokeReturnPathAsync() - { - AuthenticationTicket model = await AuthenticateAsync(); - if (model == null) + if (!string.IsNullOrWhiteSpace(context.Email)) { - _logger.WriteWarning("Invalid return state, unable to redirect."); - Response.StatusCode = 500; - return true; + context.Identity.AddClaim(new Claim(ClaimTypes.Email, context.Email, ClaimValueTypes.String, Options.AuthenticationType)); } - var context = new MicrosoftAccountReturnEndpointContext(Context, model); - context.SignInAsAuthenticationType = Options.SignInAsAuthenticationType; - context.RedirectUri = model.Properties.RedirectUri; - model.Properties.RedirectUri = null; + await Options.Notifications.Authenticated(context); - await Options.Notifications.ReturnEndpoint(context); - - if (context.SignInAsAuthenticationType != null && context.Identity != null) - { - ClaimsIdentity signInIdentity = context.Identity; - if (!string.Equals(signInIdentity.AuthenticationType, context.SignInAsAuthenticationType, StringComparison.Ordinal)) - { - signInIdentity = new ClaimsIdentity(signInIdentity.Claims, context.SignInAsAuthenticationType, signInIdentity.NameClaimType, signInIdentity.RoleClaimType); - } - Context.Response.SignIn(context.Properties, signInIdentity); - } - - if (!context.IsRequestCompleted && context.RedirectUri != null) - { - if (context.Identity == null) - { - // add a redirect hint that sign-in failed in some way - context.RedirectUri = QueryHelpers.AddQueryString(context.RedirectUri, "error", "access_denied"); - } - Response.Redirect(context.RedirectUri); - context.RequestCompleted(); - } - - return context.IsRequestCompleted; - } - - private string GenerateRedirectUri() - { - string requestPrefix = Request.Scheme + "://" + Request.Host; - - return requestPrefix + RequestPathBase + Options.CallbackPath; - } - - protected override void ApplyResponseGrant() - { - // N/A - No SignIn or SignOut support. + return new AuthenticationTicket(context.Identity, context.Properties); } } } diff --git a/src/Microsoft.AspNet.Security.MicrosoftAccount/MicrosoftAccountAuthenticationMiddleware.cs b/src/Microsoft.AspNet.Security.MicrosoftAccount/MicrosoftAccountAuthenticationMiddleware.cs index 3f5e24cec..29ad5c5ef 100644 --- a/src/Microsoft.AspNet.Security.MicrosoftAccount/MicrosoftAccountAuthenticationMiddleware.cs +++ b/src/Microsoft.AspNet.Security.MicrosoftAccount/MicrosoftAccountAuthenticationMiddleware.cs @@ -2,13 +2,11 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; -using System.Diagnostics.CodeAnalysis; using System.Globalization; -using System.Net.Http; using Microsoft.AspNet.Builder; -using Microsoft.AspNet.Security.DataHandler; using Microsoft.AspNet.Security.DataProtection; using Microsoft.AspNet.Security.Infrastructure; +using Microsoft.AspNet.Security.OAuth; using Microsoft.Framework.Logging; namespace Microsoft.AspNet.Security.MicrosoftAccount @@ -16,12 +14,8 @@ namespace Microsoft.AspNet.Security.MicrosoftAccount /// /// An ASP.NET middleware for authenticating users using the Microsoft Account service. /// - [SuppressMessage("Microsoft.Design", "CA1001:TypesThatOwnDisposableFieldsShouldBeDisposable", Justification = "Middleware are not disposable.")] - public class MicrosoftAccountAuthenticationMiddleware : AuthenticationMiddleware + public class MicrosoftAccountAuthenticationMiddleware : OAuthAuthenticationMiddleware { - private readonly ILogger _logger; - private readonly HttpClient _httpClient; - /// /// Initializes a new . /// @@ -34,33 +28,18 @@ public MicrosoftAccountAuthenticationMiddleware( IDataProtectionProvider dataProtectionProvider, ILoggerFactory loggerFactory, MicrosoftAccountAuthenticationOptions options) - : base(next, options) + : base(next, dataProtectionProvider, loggerFactory, options) { - if (string.IsNullOrWhiteSpace(Options.ClientId)) - { - throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, Resources.Exception_OptionMustBeProvided, "ClientId")); - } - if (string.IsNullOrWhiteSpace(Options.ClientSecret)) - { - throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, Resources.Exception_OptionMustBeProvided, "ClientSecret")); - } - - _logger = loggerFactory.Create(typeof(MicrosoftAccountAuthenticationMiddleware).FullName); - if (Options.Notifications == null) { Options.Notifications = new MicrosoftAccountAuthenticationNotifications(); } - if (Options.StateDataFormat == null) + if (Options.Scope.Count == 0) { - IDataProtector dataProtector = DataProtectionHelpers.CreateDataProtector(dataProtectionProvider, - typeof(MicrosoftAccountAuthenticationMiddleware).FullName, options.AuthenticationType, "v1"); - Options.StateDataFormat = new PropertiesDataFormat(dataProtector); + // LiveID requires a scope string, so if the user didn't set one we go for the least possible. + // TODO: Should we just add these by default when we create the Options? + Options.Scope.Add("wl.basic"); } - - _httpClient = new HttpClient(ResolveHttpMessageHandler(Options)); - _httpClient.Timeout = Options.BackchannelTimeout; - _httpClient.MaxResponseContentBufferSize = 1024 * 1024 * 10; // 10 MB } /// @@ -69,30 +48,7 @@ public MicrosoftAccountAuthenticationMiddleware( /// An configured with the supplied to the constructor. protected override AuthenticationHandler CreateHandler() { - return new MicrosoftAccountAuthenticationHandler(_httpClient, _logger); - } - - [SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Justification = "Managed by caller")] - private static HttpMessageHandler ResolveHttpMessageHandler(MicrosoftAccountAuthenticationOptions options) - { - HttpMessageHandler handler = options.BackchannelHttpHandler ?? -#if ASPNET50 - new WebRequestHandler(); - // If they provided a validator, apply it or fail. - if (options.BackchannelCertificateValidator != null) - { - // Set the cert validate callback - var webRequestHandler = handler as WebRequestHandler; - if (webRequestHandler == null) - { - throw new InvalidOperationException(Resources.Exception_ValidatorHandlerMismatch); - } - webRequestHandler.ServerCertificateValidationCallback = options.BackchannelCertificateValidator.Validate; - } -#else - new WinHttpHandler(); -#endif - return handler; + return new MicrosoftAccountAuthenticationHandler(Backchannel, Logger); } } } diff --git a/src/Microsoft.AspNet.Security.MicrosoftAccount/MicrosoftAccountAuthenticationOptions.cs b/src/Microsoft.AspNet.Security.MicrosoftAccount/MicrosoftAccountAuthenticationOptions.cs index 7668b0d08..24d2599cb 100644 --- a/src/Microsoft.AspNet.Security.MicrosoftAccount/MicrosoftAccountAuthenticationOptions.cs +++ b/src/Microsoft.AspNet.Security.MicrosoftAccount/MicrosoftAccountAuthenticationOptions.cs @@ -1,19 +1,15 @@ // Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -using System; -using System.Collections.Generic; -using System.Diagnostics.CodeAnalysis; -using System.Net.Http; using Microsoft.AspNet.Http; -using Microsoft.AspNet.Http.Security; +using Microsoft.AspNet.Security.OAuth; namespace Microsoft.AspNet.Security.MicrosoftAccount { /// /// Configuration options for . /// - public class MicrosoftAccountAuthenticationOptions : AuthenticationOptions + public class MicrosoftAccountAuthenticationOptions : OAuthAuthenticationOptions { /// /// Initializes a new . @@ -21,86 +17,10 @@ public class MicrosoftAccountAuthenticationOptions : AuthenticationOptions public MicrosoftAccountAuthenticationOptions() : base(MicrosoftAccountAuthenticationDefaults.AuthenticationType) { - Caption = MicrosoftAccountAuthenticationDefaults.AuthenticationType; CallbackPath = new PathString("/signin-microsoft"); - AuthenticationMode = AuthenticationMode.Passive; - Scope = new List(); - BackchannelTimeout = TimeSpan.FromSeconds(60); + AuthorizationEndpoint = MicrosoftAccountAuthenticationDefaults.AuthorizationEndpoint; + TokenEndpoint = MicrosoftAccountAuthenticationDefaults.TokenEndpoint; + UserInformationEndpoint = MicrosoftAccountAuthenticationDefaults.UserInformationEndpoint; } -#if ASPNET50 - /// - /// Gets or sets the a pinned certificate validator to use to validate the endpoints used - /// in back channel communications belong to Microsoft Account. - /// - /// - /// The pinned certificate validator. - /// - /// If this property is null then the default certificate checks are performed, - /// validating the subject name and if the signing chain is a trusted party. - public ICertificateValidator BackchannelCertificateValidator { get; set; } -#endif - /// - /// Get or sets the text that the user can display on a sign in user interface. - /// - /// - /// The default value is 'Microsoft'. - /// - public string Caption - { - get { return Description.Caption; } - set { Description.Caption = value; } - } - - /// - /// The application client ID assigned by the Microsoft authentication service. - /// - public string ClientId { get; set; } - - /// - /// The application client secret assigned by the Microsoft authentication service. - /// - public string ClientSecret { get; set; } - - /// - /// Gets or sets timeout value in milliseconds for back channel communications with Microsoft. - /// - /// - /// The back channel timeout. - /// - public TimeSpan BackchannelTimeout { get; set; } - - /// - /// The HttpMessageHandler used to communicate with Microsoft. - /// This cannot be set at the same time as BackchannelCertificateValidator unless the value - /// can be downcast to a WebRequestHandler. - /// - public HttpMessageHandler BackchannelHttpHandler { get; set; } - - /// - /// A list of permissions to request. - /// - public IList Scope { get; private set; } - - /// - /// The request path within the application's base path where the user-agent will be returned. - /// The middleware will process this request when it arrives. - /// Default value is "/signin-microsoft". - /// - public PathString CallbackPath { get; set; } - - /// - /// Gets or sets the name of another authentication middleware which will be responsible for actually issuing a user . - /// - public string SignInAsAuthenticationType { get; set; } - - /// - /// Gets or sets the used to handle authentication events. - /// - public IMicrosoftAccountAuthenticationNotifications Notifications { get; set; } - - /// - /// Gets or sets the type used to secure data handled by the middleware. - /// - public ISecureDataFormat StateDataFormat { get; set; } } } diff --git a/src/Microsoft.AspNet.Security.MicrosoftAccount/Notifications/IMicrosoftAccountAuthenticationNotifications.cs b/src/Microsoft.AspNet.Security.MicrosoftAccount/Notifications/IMicrosoftAccountAuthenticationNotifications.cs index d7c43a463..d6eb0f642 100644 --- a/src/Microsoft.AspNet.Security.MicrosoftAccount/Notifications/IMicrosoftAccountAuthenticationNotifications.cs +++ b/src/Microsoft.AspNet.Security.MicrosoftAccount/Notifications/IMicrosoftAccountAuthenticationNotifications.cs @@ -2,13 +2,14 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System.Threading.Tasks; +using Microsoft.AspNet.Security.OAuth; namespace Microsoft.AspNet.Security.MicrosoftAccount { /// /// Specifies callback methods which the invokes to enable developer control over the authentication process. /// - public interface IMicrosoftAccountAuthenticationNotifications + public interface IMicrosoftAccountAuthenticationNotifications : IOAuthAuthenticationNotifications { /// /// Invoked whenever Microsoft succesfully authenticates a user. @@ -16,18 +17,5 @@ public interface IMicrosoftAccountAuthenticationNotifications /// Contains information about the login session as well as the user . /// A representing the completed operation. Task Authenticated(MicrosoftAccountAuthenticatedContext context); - - /// - /// Invoked prior to the being saved in a local cookie and the browser being redirected to the originally requested URL. - /// - /// - /// A representing the completed operation. - Task ReturnEndpoint(MicrosoftAccountReturnEndpointContext context); - - /// - /// Called when a Challenge causes a redirect to authorize endpoint in the Microsoft middleware. - /// - /// Contains redirect URI and of the challenge. - void ApplyRedirect(MicrosoftAccountApplyRedirectContext context); } } diff --git a/src/Microsoft.AspNet.Security.MicrosoftAccount/Notifications/MicrosoftAccountAuthenticatedContext.cs b/src/Microsoft.AspNet.Security.MicrosoftAccount/Notifications/MicrosoftAccountAuthenticatedContext.cs index ef2b0b50f..8b1a53312 100644 --- a/src/Microsoft.AspNet.Security.MicrosoftAccount/Notifications/MicrosoftAccountAuthenticatedContext.cs +++ b/src/Microsoft.AspNet.Security.MicrosoftAccount/Notifications/MicrosoftAccountAuthenticatedContext.cs @@ -3,12 +3,10 @@ using System; using System.Collections.Generic; -using System.Globalization; using System.Linq; -using System.Security.Claims; +using System.Net.Http; using Microsoft.AspNet.Http; -using Microsoft.AspNet.Http.Security; -using Microsoft.AspNet.Security.Notifications; +using Microsoft.AspNet.Security.OAuth; using Newtonsoft.Json.Linq; namespace Microsoft.AspNet.Security.MicrosoftAccount @@ -16,32 +14,19 @@ namespace Microsoft.AspNet.Security.MicrosoftAccount /// /// Contains information about the login session as well as the user . /// - public class MicrosoftAccountAuthenticatedContext : BaseContext + public class MicrosoftAccountAuthenticatedContext : OAuthAuthenticatedContext { /// /// Initializes a new . /// /// The HTTP environment. /// The JSON-serialized user. - /// The access token provided by the Microsoft authentication service. - /// The refresh token provided by Microsoft authentication service. - /// Seconds until expiration. - public MicrosoftAccountAuthenticatedContext(HttpContext context, [NotNull] JObject user, string accessToken, - string refreshToken, string expires) - : base(context) + /// The access token provided by the Microsoft authentication service. + public MicrosoftAccountAuthenticatedContext(HttpContext context, OAuthAuthenticationOptions options, [NotNull] JObject user, TokenResponse tokens) + : base(context, options, user, tokens) { IDictionary userAsDictionary = user; - User = user; - AccessToken = accessToken; - RefreshToken = refreshToken; - - int expiresValue; - if (Int32.TryParse(expires, NumberStyles.Integer, CultureInfo.InvariantCulture, out expiresValue)) - { - ExpiresIn = TimeSpan.FromSeconds(expiresValue); - } - JToken userId = User["id"]; if (userId == null) { @@ -63,30 +48,6 @@ public MicrosoftAccountAuthenticatedContext(HttpContext context, [NotNull] JObje } } - /// - /// Gets the JSON-serialized user. - /// - public JObject User { get; private set; } - - /// - /// Gets the access token provided by the Microsoft authenication service. - /// - public string AccessToken { get; private set; } - - /// - /// Gets the refresh token provided by Microsoft authentication service. - /// - /// - /// Refresh token is only available when wl.offline_access is request. - /// Otherwise, it is null. - /// - public string RefreshToken { get; private set; } - - /// - /// Gets the Microsoft access token expiration time. - /// - public TimeSpan? ExpiresIn { get; set; } - /// /// Gets the Microsoft Account user ID. /// @@ -112,16 +73,6 @@ public MicrosoftAccountAuthenticatedContext(HttpContext context, [NotNull] JObje /// public string Email { get; private set; } - /// - /// Gets the representing the user. - /// - public ClaimsIdentity Identity { get; set; } - - /// - /// Gets or sets a property bag for common authentication properties. - /// - public AuthenticationProperties Properties { get; set; } - private static string PropertyValueIfExists(string property, IDictionary dictionary) { return dictionary.ContainsKey(property) ? dictionary[property].ToString() : null; diff --git a/src/Microsoft.AspNet.Security.MicrosoftAccount/Notifications/MicrosoftAccountAuthenticationNotifications.cs b/src/Microsoft.AspNet.Security.MicrosoftAccount/Notifications/MicrosoftAccountAuthenticationNotifications.cs index deb561b94..26db09d15 100644 --- a/src/Microsoft.AspNet.Security.MicrosoftAccount/Notifications/MicrosoftAccountAuthenticationNotifications.cs +++ b/src/Microsoft.AspNet.Security.MicrosoftAccount/Notifications/MicrosoftAccountAuthenticationNotifications.cs @@ -3,13 +3,14 @@ using System; using System.Threading.Tasks; +using Microsoft.AspNet.Security.OAuth; namespace Microsoft.AspNet.Security.MicrosoftAccount { /// /// Default implementation. /// - public class MicrosoftAccountAuthenticationNotifications : IMicrosoftAccountAuthenticationNotifications + public class MicrosoftAccountAuthenticationNotifications : OAuthAuthenticationNotifications, IMicrosoftAccountAuthenticationNotifications { /// /// Initializes a new @@ -17,8 +18,6 @@ public class MicrosoftAccountAuthenticationNotifications : IMicrosoftAccountAuth public MicrosoftAccountAuthenticationNotifications() { OnAuthenticated = context => Task.FromResult(0); - OnReturnEndpoint = context => Task.FromResult(0); - OnApplyRedirect = context => context.Response.Redirect(context.RedirectUri); } /// @@ -26,16 +25,6 @@ public MicrosoftAccountAuthenticationNotifications() /// public Func OnAuthenticated { get; set; } - /// - /// Gets or sets the function that is invoked when the ReturnEndpoint method is invoked. - /// - public Func OnReturnEndpoint { get; set; } - - /// - /// Gets or sets the delegate that is invoked when the ApplyRedirect method is invoked. - /// - public Action OnApplyRedirect { get; set; } - /// /// Invoked whenever Microsoft succesfully authenticates a user /// @@ -45,24 +34,5 @@ public virtual Task Authenticated(MicrosoftAccountAuthenticatedContext context) { return OnAuthenticated(context); } - - /// - /// Invoked prior to the being saved in a local cookie and the browser being redirected to the originally requested URL. - /// - /// Contains information about the login session as well as the user - /// A representing the completed operation. - public virtual Task ReturnEndpoint(MicrosoftAccountReturnEndpointContext context) - { - return OnReturnEndpoint(context); - } - - /// - /// Called when a Challenge causes a redirect to authorize endpoint in the Microsoft account middleware. - /// - /// Contains redirect URI and of the challenge. - public virtual void ApplyRedirect(MicrosoftAccountApplyRedirectContext context) - { - OnApplyRedirect(context); - } } } diff --git a/src/Microsoft.AspNet.Security.MicrosoftAccount/project.json b/src/Microsoft.AspNet.Security.MicrosoftAccount/project.json index 83bc4823b..d452d0121 100644 --- a/src/Microsoft.AspNet.Security.MicrosoftAccount/project.json +++ b/src/Microsoft.AspNet.Security.MicrosoftAccount/project.json @@ -5,6 +5,7 @@ "Microsoft.AspNet.RequestContainer": "1.0.0-*", "Microsoft.AspNet.Security": "1.0.0-*", "Microsoft.AspNet.Security.DataProtection": "1.0.0-*", + "Microsoft.AspNet.Security.OAuth": "1.0.0-*", "Microsoft.AspNet.WebUtilities": "1.0.0-*", "Microsoft.Framework.Logging": "1.0.0-*", "Newtonsoft.Json": "5.0.8", @@ -13,7 +14,6 @@ "frameworks": { "aspnet50": { "dependencies": { - "System.Net.Http.WebRequest": "" } }, "aspnetcore50": { @@ -28,7 +28,6 @@ "System.IO": "4.0.10.0", "System.IO.Compression": "4.0.0.0", "System.Linq": "4.0.0.0", - "System.Net.Http.WinHttpHandler": "4.0.0.0", "System.ObjectModel": "4.0.10.0", "System.Reflection": "4.0.10.0", "System.Resources.ResourceManager": "4.0.0.0", diff --git a/src/Microsoft.AspNet.Security.OAuth/Microsoft.AspNet.Security.OAuth.kproj b/src/Microsoft.AspNet.Security.OAuth/Microsoft.AspNet.Security.OAuth.kproj new file mode 100644 index 000000000..f0c8d7b47 --- /dev/null +++ b/src/Microsoft.AspNet.Security.OAuth/Microsoft.AspNet.Security.OAuth.kproj @@ -0,0 +1,28 @@ + + + + 12.0 + $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) + + + + 4a636011-68ee-4ce5-836d-ea8e13cf71e4 + Library + + + + ConsoleDebugger + + + WebDebugger + + + + + + + + 2.0 + + + \ No newline at end of file diff --git a/src/Microsoft.AspNet.Security.OAuth/NotNullAttribute.cs b/src/Microsoft.AspNet.Security.OAuth/NotNullAttribute.cs new file mode 100644 index 000000000..3f56c4151 --- /dev/null +++ b/src/Microsoft.AspNet.Security.OAuth/NotNullAttribute.cs @@ -0,0 +1,12 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; + +namespace Microsoft.AspNet.Security.OAuth +{ + [AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false)] + internal sealed class NotNullAttribute : Attribute + { + } +} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Security.OAuth/Notifications/IOAuthAuthenticationNotifications.cs b/src/Microsoft.AspNet.Security.OAuth/Notifications/IOAuthAuthenticationNotifications.cs new file mode 100644 index 000000000..b00b0175e --- /dev/null +++ b/src/Microsoft.AspNet.Security.OAuth/Notifications/IOAuthAuthenticationNotifications.cs @@ -0,0 +1,34 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System.Threading.Tasks; + +namespace Microsoft.AspNet.Security.OAuth +{ + /// + /// Specifies callback methods which the invokes to enable developer control over the authentication process. + /// + public interface IOAuthAuthenticationNotifications + { + /// + /// Invoked after the provider successfully authenticates a user. This can be used to retrieve user information. + /// This notification may not be invoked by sub-classes of OAuthAuthenticationHandler if they override GetUserInformationAsync. + /// + /// Contains information about the login session. + /// A representing the completed operation. + Task GetUserInformationAsync(OAuthGetUserInformationContext context); + + /// + /// Invoked prior to the being saved in a local cookie and the browser being redirected to the originally requested URL. + /// + /// + /// A representing the completed operation. + Task ReturnEndpoint(OAuthReturnEndpointContext context); + + /// + /// Called when a Challenge causes a redirect to authorize endpoint in the Microsoft middleware. + /// + /// Contains redirect URI and of the challenge. + void ApplyRedirect(OAuthApplyRedirectContext context); + } +} diff --git a/src/Microsoft.AspNet.Security.MicrosoftAccount/Notifications/MicrosoftAccountApplyRedirectContext.cs b/src/Microsoft.AspNet.Security.OAuth/Notifications/OAuthApplyRedirectContext.cs similarity index 74% rename from src/Microsoft.AspNet.Security.MicrosoftAccount/Notifications/MicrosoftAccountApplyRedirectContext.cs rename to src/Microsoft.AspNet.Security.OAuth/Notifications/OAuthApplyRedirectContext.cs index f61a9eee4..df1f6a424 100644 --- a/src/Microsoft.AspNet.Security.MicrosoftAccount/Notifications/MicrosoftAccountApplyRedirectContext.cs +++ b/src/Microsoft.AspNet.Security.OAuth/Notifications/OAuthApplyRedirectContext.cs @@ -5,22 +5,20 @@ using Microsoft.AspNet.Http.Security; using Microsoft.AspNet.Security.Notifications; -namespace Microsoft.AspNet.Security.MicrosoftAccount +namespace Microsoft.AspNet.Security.OAuth { /// /// Context passed when a Challenge causes a redirect to authorize endpoint in the Microsoft account middleware. /// - public class MicrosoftAccountApplyRedirectContext : BaseContext + public class OAuthApplyRedirectContext : BaseContext { /// /// Creates a new context object. /// /// The HTTP request context. - /// The Microsoft account middleware options. /// The authentication properties of the challenge. /// The initial redirect URI. - public MicrosoftAccountApplyRedirectContext(HttpContext context, MicrosoftAccountAuthenticationOptions options, - AuthenticationProperties properties, string redirectUri) + public OAuthApplyRedirectContext(HttpContext context, OAuthAuthenticationOptions options, AuthenticationProperties properties, string redirectUri) : base(context, options) { RedirectUri = redirectUri; diff --git a/src/Microsoft.AspNet.Security.OAuth/Notifications/OAuthAuthenticatedContext.cs b/src/Microsoft.AspNet.Security.OAuth/Notifications/OAuthAuthenticatedContext.cs new file mode 100644 index 000000000..a651767e8 --- /dev/null +++ b/src/Microsoft.AspNet.Security.OAuth/Notifications/OAuthAuthenticatedContext.cs @@ -0,0 +1,77 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Globalization; +using System.Net.Http; +using System.Security.Claims; +using Microsoft.AspNet.Http; +using Microsoft.AspNet.Http.Security; +using Microsoft.AspNet.Security.Notifications; +using Newtonsoft.Json.Linq; + +namespace Microsoft.AspNet.Security.OAuth +{ + /// + /// Contains information about the login session as well as the user . + /// + public class OAuthAuthenticatedContext : BaseContext + { + /// + /// Initializes a new . + /// + /// The HTTP environment. + /// The JSON-serialized user. + /// The tokens returned from the token endpoint. + public OAuthAuthenticatedContext(HttpContext context, OAuthAuthenticationOptions options, JObject user, + TokenResponse tokens) + : base(context, options) + { + User = user; + AccessToken = tokens.AccessToken; + TokenType = tokens.TokenType; + RefreshToken = tokens.RefreshToken; + + int expiresInValue; + if (Int32.TryParse(tokens.ExpiresIn, NumberStyles.Integer, CultureInfo.InvariantCulture, out expiresInValue)) + { + ExpiresIn = TimeSpan.FromSeconds(expiresInValue); + } + } + + /// + /// Gets the JSON-serialized user. + /// + public JObject User { get; protected set; } + + /// + /// Gets the access token provided by the authentication service. + /// + public string AccessToken { get; protected set; } + + /// + /// Gets the access token type provided by the authentication service. + /// + public string TokenType { get; protected set; } + + /// + /// Gets the refresh token provided by the authentication service. + /// + public string RefreshToken { get; protected set; } + + /// + /// Gets the access token expiration time. + /// + public TimeSpan? ExpiresIn { get; protected set; } + + /// + /// Gets the representing the user. + /// + public ClaimsIdentity Identity { get; set; } + + /// + /// Gets or sets a property bag for common authentication properties. + /// + public AuthenticationProperties Properties { get; set; } + } +} diff --git a/src/Microsoft.AspNet.Security.OAuth/Notifications/OAuthAuthenticationNotifications.cs b/src/Microsoft.AspNet.Security.OAuth/Notifications/OAuthAuthenticationNotifications.cs new file mode 100644 index 000000000..a91f8f0b0 --- /dev/null +++ b/src/Microsoft.AspNet.Security.OAuth/Notifications/OAuthAuthenticationNotifications.cs @@ -0,0 +1,68 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Threading.Tasks; + +namespace Microsoft.AspNet.Security.OAuth +{ + /// + /// Default implementation. + /// + public class OAuthAuthenticationNotifications : IOAuthAuthenticationNotifications + { + /// + /// Initializes a new + /// + public OAuthAuthenticationNotifications() + { + OnGetUserInformationAsync = OAuthAuthenticationDefaults.DefaultOnGetUserInformationAsync; + OnReturnEndpoint = context => Task.FromResult(0); + OnApplyRedirect = context => context.Response.Redirect(context.RedirectUri); + } + + /// + /// Gets or sets the function that is invoked when the Authenticated method is invoked. + /// + public Func OnGetUserInformationAsync { get; set; } + + /// + /// Gets or sets the function that is invoked when the ReturnEndpoint method is invoked. + /// + public Func OnReturnEndpoint { get; set; } + + /// + /// Gets or sets the delegate that is invoked when the ApplyRedirect method is invoked. + /// + public Action OnApplyRedirect { get; set; } + + /// + /// Invoked after the provider successfully authenticates a user. + /// + /// Contains information about the login session as well as the user . + /// A representing the completed operation. + public virtual Task GetUserInformationAsync(OAuthGetUserInformationContext context) + { + return OnGetUserInformationAsync(context); + } + + /// + /// Invoked prior to the being saved in a local cookie and the browser being redirected to the originally requested URL. + /// + /// Contains information about the login session as well as the user + /// A representing the completed operation. + public virtual Task ReturnEndpoint(OAuthReturnEndpointContext context) + { + return OnReturnEndpoint(context); + } + + /// + /// Called when a Challenge causes a redirect to authorize endpoint in the OAuth middleware. + /// + /// Contains redirect URI and of the challenge. + public virtual void ApplyRedirect(OAuthApplyRedirectContext context) + { + OnApplyRedirect(context); + } + } +} diff --git a/src/Microsoft.AspNet.Security.OAuth/Notifications/OAuthGetUserInformationContext.cs b/src/Microsoft.AspNet.Security.OAuth/Notifications/OAuthGetUserInformationContext.cs new file mode 100644 index 000000000..5886d1b54 --- /dev/null +++ b/src/Microsoft.AspNet.Security.OAuth/Notifications/OAuthGetUserInformationContext.cs @@ -0,0 +1,76 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Globalization; +using System.Net.Http; +using System.Security.Claims; +using Microsoft.AspNet.Http; +using Microsoft.AspNet.Http.Security; +using Microsoft.AspNet.Security.Notifications; +using Newtonsoft.Json.Linq; + +namespace Microsoft.AspNet.Security.OAuth +{ + /// + /// Contains information about the login session as well as the user . + /// + public class OAuthGetUserInformationContext : BaseContext + { + /// + /// Initializes a new . + /// + /// The HTTP environment. + /// The JSON-serialized user. + /// The tokens returned from the token endpoint. + public OAuthGetUserInformationContext(HttpContext context, OAuthAuthenticationOptions options, HttpClient backchannel, TokenResponse tokens) + : base(context, options) + { + AccessToken = tokens.AccessToken; + TokenType = tokens.TokenType; + RefreshToken = tokens.RefreshToken; + Backchannel = backchannel; + + int expiresInValue; + if (Int32.TryParse(tokens.ExpiresIn, NumberStyles.Integer, CultureInfo.InvariantCulture, out expiresInValue)) + { + ExpiresIn = TimeSpan.FromSeconds(expiresInValue); + } + } + + /// + /// Gets the access token provided by the authentication service. + /// + public string AccessToken { get; protected set; } + + /// + /// Gets the access token type provided by the authentication service. + /// + public string TokenType { get; protected set; } + + /// + /// Gets the refresh token provided by the authentication service. + /// + public string RefreshToken { get; protected set; } + + /// + /// Gets the access token expiration time. + /// + public TimeSpan? ExpiresIn { get; protected set; } + + /// + /// Gets the backchannel used to communicate with the provider. + /// + public HttpClient Backchannel { get; protected set; } + + /// + /// Gets the representing the user. + /// + public ClaimsIdentity Identity { get; set; } + + /// + /// Gets or sets a property bag for common authentication properties. + /// + public AuthenticationProperties Properties { get; set; } + } +} diff --git a/src/Microsoft.AspNet.Security.MicrosoftAccount/Notifications/MicrosoftAccountReturnEndpointContext.cs b/src/Microsoft.AspNet.Security.OAuth/Notifications/OAuthReturnEndpointContext.cs similarity index 71% rename from src/Microsoft.AspNet.Security.MicrosoftAccount/Notifications/MicrosoftAccountReturnEndpointContext.cs rename to src/Microsoft.AspNet.Security.OAuth/Notifications/OAuthReturnEndpointContext.cs index 93e767024..6f465ef3d 100644 --- a/src/Microsoft.AspNet.Security.MicrosoftAccount/Notifications/MicrosoftAccountReturnEndpointContext.cs +++ b/src/Microsoft.AspNet.Security.OAuth/Notifications/OAuthReturnEndpointContext.cs @@ -4,19 +4,19 @@ using Microsoft.AspNet.Http; using Microsoft.AspNet.Security.Notifications; -namespace Microsoft.AspNet.Security.MicrosoftAccount +namespace Microsoft.AspNet.Security.OAuth { /// /// Provides context information to middleware providers. /// - public class MicrosoftAccountReturnEndpointContext : ReturnEndpointContext + public class OAuthReturnEndpointContext : ReturnEndpointContext { /// - /// Initializes a new . + /// Initializes a new . /// /// The HTTP environment. /// The authentication ticket. - public MicrosoftAccountReturnEndpointContext( + public OAuthReturnEndpointContext( HttpContext context, AuthenticationTicket ticket) : base(context, ticket) diff --git a/src/Microsoft.AspNet.Security.OAuth/OAuthAuthenticationDefaults.cs b/src/Microsoft.AspNet.Security.OAuth/OAuthAuthenticationDefaults.cs new file mode 100644 index 000000000..758417ecf --- /dev/null +++ b/src/Microsoft.AspNet.Security.OAuth/OAuthAuthenticationDefaults.cs @@ -0,0 +1,39 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Globalization; +using System.Security.Claims; +using System.Threading.Tasks; + +namespace Microsoft.AspNet.Security.OAuth +{ + public static class OAuthAuthenticationDefaults + { + public static readonly Func DefaultOnGetUserInformationAsync = context => + { + // If the developer doesn't specify a user-info callback, just give them the tokens. + var identity = new ClaimsIdentity( + context.Options.AuthenticationType, + ClaimsIdentity.DefaultNameClaimType, + ClaimsIdentity.DefaultRoleClaimType); + + identity.AddClaim(new Claim("access_token", context.AccessToken, ClaimValueTypes.String, context.Options.AuthenticationType)); + if (!string.IsNullOrEmpty(context.RefreshToken)) + { + identity.AddClaim(new Claim("refresh_token", context.RefreshToken, ClaimValueTypes.String, context.Options.AuthenticationType)); + } + if (!string.IsNullOrEmpty(context.TokenType)) + { + identity.AddClaim(new Claim("token_type", context.TokenType, ClaimValueTypes.String, context.Options.AuthenticationType)); + } + if (context.ExpiresIn.HasValue) + { + identity.AddClaim(new Claim("expires_in", context.ExpiresIn.Value.TotalSeconds.ToString(CultureInfo.InvariantCulture), + ClaimValueTypes.String, context.Options.AuthenticationType)); + } + context.Identity = identity; + return Task.FromResult(0); + }; + } +} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Security.OAuth/OAuthAuthenticationExtensions.cs b/src/Microsoft.AspNet.Security.OAuth/OAuthAuthenticationExtensions.cs new file mode 100644 index 000000000..e140620e6 --- /dev/null +++ b/src/Microsoft.AspNet.Security.OAuth/OAuthAuthenticationExtensions.cs @@ -0,0 +1,34 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Globalization; +using Microsoft.AspNet.Security.OAuth; + +namespace Microsoft.AspNet.Builder +{ + /// + /// Extension methods for using + /// + public static class OAuthAuthenticationExtensions + { + /// + /// Authenticate users using OAuth. + /// + /// The passed to the configure method. + /// The middleware configuration options. + /// The updated . + public static IBuilder UseOAuthAuthentication([NotNull] this IBuilder app, [NotNull] OAuthAuthenticationOptions options) + { + if (string.IsNullOrEmpty(options.SignInAsAuthenticationType)) + { + options.SignInAsAuthenticationType = app.GetDefaultSignInAsAuthenticationType(); + } + if (options.Notifications == null) + { + options.Notifications = new OAuthAuthenticationNotifications(); + } + return app.UseMiddleware, IOAuthAuthenticationNotifications>>(options); + } + } +} diff --git a/src/Microsoft.AspNet.Security.OAuth/OAuthAuthenticationHandler.cs b/src/Microsoft.AspNet.Security.OAuth/OAuthAuthenticationHandler.cs new file mode 100644 index 000000000..eae146363 --- /dev/null +++ b/src/Microsoft.AspNet.Security.OAuth/OAuthAuthenticationHandler.cs @@ -0,0 +1,253 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Collections.Generic; +using System.Net.Http; +using System.Net.Http.Headers; +using System.Security.Claims; +using System.Threading.Tasks; +using Microsoft.AspNet.Http; +using Microsoft.AspNet.Http.Security; +using Microsoft.AspNet.Security.Infrastructure; +using Microsoft.AspNet.WebUtilities; +using Microsoft.Framework.Logging; +using Newtonsoft.Json.Linq; + +namespace Microsoft.AspNet.Security.OAuth +{ + public class OAuthAuthenticationHandler : AuthenticationHandler + where TOptions : OAuthAuthenticationOptions + where TNotifications : IOAuthAuthenticationNotifications + { + public OAuthAuthenticationHandler(HttpClient backchannel, ILogger logger) + { + Backchannel = backchannel; + Logger = logger; + } + + protected HttpClient Backchannel { get; private set; } + + protected ILogger Logger { get; private set; } + + public override async Task InvokeAsync() + { + if (Options.CallbackPath.HasValue && Options.CallbackPath == Request.Path) + { + return await InvokeReturnPathAsync(); + } + return false; + } + + public async Task InvokeReturnPathAsync() + { + AuthenticationTicket ticket = await AuthenticateAsync(); + if (ticket == null) + { + Logger.WriteWarning("Invalid return state, unable to redirect."); + Response.StatusCode = 500; + return true; + } + + var context = new OAuthReturnEndpointContext(Context, ticket) + { + SignInAsAuthenticationType = Options.SignInAsAuthenticationType, + RedirectUri = ticket.Properties.RedirectUri, + }; + ticket.Properties.RedirectUri = null; + + await Options.Notifications.ReturnEndpoint(context); + + if (context.SignInAsAuthenticationType != null && context.Identity != null) + { + ClaimsIdentity signInIdentity = context.Identity; + if (!string.Equals(signInIdentity.AuthenticationType, context.SignInAsAuthenticationType, StringComparison.Ordinal)) + { + signInIdentity = new ClaimsIdentity(signInIdentity.Claims, context.SignInAsAuthenticationType, signInIdentity.NameClaimType, signInIdentity.RoleClaimType); + } + Context.Response.SignIn(context.Properties, signInIdentity); + } + + if (!context.IsRequestCompleted && context.RedirectUri != null) + { + if (context.Identity == null) + { + // add a redirect hint that sign-in failed in some way + context.RedirectUri = QueryHelpers.AddQueryString(context.RedirectUri, "error", "access_denied"); + } + Response.Redirect(context.RedirectUri); + context.RequestCompleted(); + } + + return context.IsRequestCompleted; + } + + protected override AuthenticationTicket AuthenticateCore() + { + return AuthenticateCoreAsync().Result; + } + + protected override async Task AuthenticateCoreAsync() + { + AuthenticationProperties properties = null; + try + { + IReadableStringCollection query = Request.Query; + + // TODO: Is this a standard error returned by servers? + var value = query.Get("error"); + if (!string.IsNullOrEmpty(value)) + { + Logger.WriteVerbose("Remote server returned an error: " + Request.QueryString); + // TODO: Fail request rather than passing through? + return null; + } + + string code = query.Get("code"); + string state = query.Get("state"); + + properties = Options.StateDataFormat.Unprotect(state); + if (properties == null) + { + return null; + } + + // OAuth2 10.12 CSRF + if (!ValidateCorrelationId(properties, Logger)) + { + return new AuthenticationTicket(null, properties); + } + + if (string.IsNullOrEmpty(code)) + { + // Null if the remote server returns an error. + return new AuthenticationTicket(null, properties); + } + + string requestPrefix = Request.Scheme + "://" + Request.Host; + string redirectUri = requestPrefix + RequestPathBase + Options.CallbackPath; + + var tokens = await ExchangeCodeAsync(code, redirectUri); + + if (string.IsNullOrWhiteSpace(tokens.AccessToken)) + { + Logger.WriteWarning("Access token was not found"); + return new AuthenticationTicket(null, properties); + } + + return await GetUserInformationAsync(properties, tokens); + } + catch (Exception ex) + { + Logger.WriteError("Authentication failed", ex); + return new AuthenticationTicket(null, properties); + } + } + + protected virtual async Task ExchangeCodeAsync(string code, string redirectUri) + { + var tokenRequestParameters = new Dictionary() + { + { "client_id", Options.ClientId }, + { "redirect_uri", redirectUri }, + { "client_secret", Options.ClientSecret }, + { "code", code }, + { "grant_type", "authorization_code" }, + }; + + var requestContent = new FormUrlEncodedContent(tokenRequestParameters); + + var requestMessage = new HttpRequestMessage(HttpMethod.Post, Options.TokenEndpoint); + requestMessage.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); + requestMessage.Content = requestContent; + HttpResponseMessage response = await Backchannel.SendAsync(requestMessage, Context.RequestAborted); + response.EnsureSuccessStatusCode(); + string oauthTokenResponse = await response.Content.ReadAsStringAsync(); + + JObject oauth2Token = JObject.Parse(oauthTokenResponse); + return new TokenResponse(oauth2Token); + } + + protected virtual async Task GetUserInformationAsync(AuthenticationProperties properties, TokenResponse tokens) + { + var context = new OAuthGetUserInformationContext(Context, Options, Backchannel, tokens) + { + Properties = properties, + }; + await Options.Notifications.GetUserInformationAsync(context); + return new AuthenticationTicket(context.Identity, context.Properties); + } + + protected override void ApplyResponseChallenge() + { + if (Response.StatusCode != 401) + { + return; + } + + // Active middleware should redirect on 401 even if there wasn't an explicit challenge. + if (ChallengeContext == null && Options.AuthenticationMode == AuthenticationMode.Passive) + { + return; + } + + string baseUri = Request.Scheme + "://" + Request.Host + Request.PathBase; + + string currentUri = baseUri + Request.Path + Request.QueryString; + + string redirectUri = baseUri + Options.CallbackPath; + + AuthenticationProperties properties; + if (ChallengeContext == null) + { + properties = new AuthenticationProperties(); + } + else + { + properties = new AuthenticationProperties(ChallengeContext.Properties); + } + if (string.IsNullOrEmpty(properties.RedirectUri)) + { + properties.RedirectUri = currentUri; + } + + // OAuth2 10.12 CSRF + GenerateCorrelationId(properties); + + string authorizationEndpoint = BuildChallengeUrl(properties, redirectUri); + + var redirectContext = new OAuthApplyRedirectContext( + Context, Options, + properties, authorizationEndpoint); + Options.Notifications.ApplyRedirect(redirectContext); + } + + protected virtual string BuildChallengeUrl(AuthenticationProperties properties, string redirectUri) + { + string scope = FormatScope(); + + string state = Options.StateDataFormat.Protect(properties); + + var queryBuilder = new QueryBuilder() + { + { "client_id", Options.ClientId }, + { "scope", scope }, + { "response_type", "code" }, + { "redirect_uri", redirectUri }, + { "state", state }, + }; + return Options.AuthorizationEndpoint + queryBuilder.ToString(); + } + + protected virtual string FormatScope() + { + // OAuth2 3.3 space separated + return string.Join(" ", Options.Scope); + } + + protected override void ApplyResponseGrant() + { + // N/A - No SignIn or SignOut support. + } + } +} diff --git a/src/Microsoft.AspNet.Security.OAuth/OAuthAuthenticationMiddleware.cs b/src/Microsoft.AspNet.Security.OAuth/OAuthAuthenticationMiddleware.cs new file mode 100644 index 000000000..3dd00f4b0 --- /dev/null +++ b/src/Microsoft.AspNet.Security.OAuth/OAuthAuthenticationMiddleware.cs @@ -0,0 +1,105 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Diagnostics.CodeAnalysis; +using System.Globalization; +using System.Net.Http; +using Microsoft.AspNet.Builder; +using Microsoft.AspNet.Security.DataHandler; +using Microsoft.AspNet.Security.DataProtection; +using Microsoft.AspNet.Security.Infrastructure; +using Microsoft.Framework.Logging; + +namespace Microsoft.AspNet.Security.OAuth +{ + /// + /// An ASP.NET middleware for authenticating users using OAuth services. + /// + [SuppressMessage("Microsoft.Design", "CA1001:TypesThatOwnDisposableFieldsShouldBeDisposable", Justification = "Middleware are not disposable.")] + public class OAuthAuthenticationMiddleware : AuthenticationMiddleware + where TOptions : OAuthAuthenticationOptions + where TNotifications : IOAuthAuthenticationNotifications + { + /// + /// Initializes a new . + /// + /// The next middleware in the HTTP pipeline to invoke. + /// + /// + /// Configuration options for the middleware. + public OAuthAuthenticationMiddleware( + RequestDelegate next, + IDataProtectionProvider dataProtectionProvider, + ILoggerFactory loggerFactory, + TOptions options) + : base(next, options) + { + if (string.IsNullOrWhiteSpace(Options.ClientId)) + { + throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, Resources.Exception_OptionMustBeProvided, "ClientId")); + } + if (string.IsNullOrWhiteSpace(Options.ClientSecret)) + { + throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, Resources.Exception_OptionMustBeProvided, "ClientSecret")); + } + if (string.IsNullOrWhiteSpace(Options.AuthorizationEndpoint)) + { + throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, Resources.Exception_OptionMustBeProvided, "AuthorizationEndpoint")); + } + if (string.IsNullOrWhiteSpace(Options.TokenEndpoint)) + { + throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, Resources.Exception_OptionMustBeProvided, "TokenEndpoint")); + } + + Logger = loggerFactory.Create(this.GetType().FullName); + + if (Options.StateDataFormat == null) + { + IDataProtector dataProtector = DataProtectionHelpers.CreateDataProtector(dataProtectionProvider, + this.GetType().FullName, options.AuthenticationType, "v1"); + Options.StateDataFormat = new PropertiesDataFormat(dataProtector); + } + + Backchannel = new HttpClient(ResolveHttpMessageHandler(Options)); + Backchannel.Timeout = Options.BackchannelTimeout; + Backchannel.MaxResponseContentBufferSize = 1024 * 1024 * 10; // 10 MB + } + + protected HttpClient Backchannel { get; private set; } + + protected ILogger Logger { get; private set; } + + /// + /// Provides the object for processing authentication-related requests. + /// + /// An configured with the supplied to the constructor. + protected override AuthenticationHandler CreateHandler() + { + return new OAuthAuthenticationHandler(Backchannel, Logger); + } + + [SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Justification = "Managed by caller")] + private static HttpMessageHandler ResolveHttpMessageHandler(OAuthAuthenticationOptions options) + { + HttpMessageHandler handler = options.BackchannelHttpHandler ?? +#if ASPNET50 + new WebRequestHandler(); + // If they provided a validator, apply it or fail. + if (options.BackchannelCertificateValidator != null) + { + // Set the cert validate callback + var webRequestHandler = handler as WebRequestHandler; + if (webRequestHandler == null) + { + throw new InvalidOperationException(Resources.Exception_ValidatorHandlerMismatch); + } + webRequestHandler.ServerCertificateValidationCallback = options.BackchannelCertificateValidator.Validate; + } +#else + new WinHttpHandler(); +#endif + return handler; + } + } +} diff --git a/src/Microsoft.AspNet.Security.OAuth/OAuthAuthenticationOptions.cs b/src/Microsoft.AspNet.Security.OAuth/OAuthAuthenticationOptions.cs new file mode 100644 index 000000000..69e889744 --- /dev/null +++ b/src/Microsoft.AspNet.Security.OAuth/OAuthAuthenticationOptions.cs @@ -0,0 +1,117 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Collections.Generic; +using System.Net.Http; +using System.Threading.Tasks; +using Microsoft.AspNet.Http; +using Microsoft.AspNet.Http.Security; + +namespace Microsoft.AspNet.Security.OAuth +{ + /// + /// Configuration options for . + /// + public class OAuthAuthenticationOptions : AuthenticationOptions + { + /// + /// Initializes a new . + /// + public OAuthAuthenticationOptions([NotNull] string authenticationType) + : base(authenticationType) + { + Caption = authenticationType; + AuthenticationMode = AuthenticationMode.Passive; + Scope = new List(); + BackchannelTimeout = TimeSpan.FromSeconds(60); + } + + /// + /// Gets or sets the provider-assigned client id. + /// + public string ClientId { get; set; } + + /// + /// Gets or sets the provider-assigned client secret. + /// + public string ClientSecret { get; set; } + + /// + /// Gets or sets the URI where the client will be redirected to authenticate. + /// + public string AuthorizationEndpoint { get; set; } + + /// + /// Gets or sets the URI the middleware will access to exchange the OAuth token. + /// + public string TokenEndpoint { get; set; } + + /// + /// Gets or sets the URI the middleware will access to obtain the user information. + /// This value is not used in the default implementation, it is for use in custom implementations of + /// IOAuthAuthenticationNotifications.GetUserInformationAsync or OAuthAuthenticationHandler.GetUserInformationAsync. + /// + public string UserInformationEndpoint { get; set; } + +#if ASPNET50 + /// + /// Gets or sets the a pinned certificate validator to use to validate the endpoints used + /// in back channel communications belong to the auth provider. + /// + /// + /// The pinned certificate validator. + /// + /// If this property is null then the default certificate checks are performed, + /// validating the subject name and if the signing chain is a trusted party. + public ICertificateValidator BackchannelCertificateValidator { get; set; } +#endif + /// + /// Get or sets the text that the user can display on a sign in user interface. + /// + /// + /// The default value is the authentication type. + /// + public string Caption + { + get { return Description.Caption; } + set { Description.Caption = value; } + } + + /// + /// Gets or sets timeout value in milliseconds for back channel communications with the auth provider. + /// + /// + /// The back channel timeout. + /// + public TimeSpan BackchannelTimeout { get; set; } + + /// + /// The HttpMessageHandler used to communicate with the auth provider. + /// This cannot be set at the same time as BackchannelCertificateValidator unless the value + /// can be downcast to a WebRequestHandler. + /// + public HttpMessageHandler BackchannelHttpHandler { get; set; } + + /// + /// A list of permissions to request. + /// + public IList Scope { get; private set; } + + /// + /// The request path within the application's base path where the user-agent will be returned. + /// The middleware will process this request when it arrives. + /// + public PathString CallbackPath { get; set; } + + /// + /// Gets or sets the name of another authentication middleware which will be responsible for actually issuing a user . + /// + public string SignInAsAuthenticationType { get; set; } + + /// + /// Gets or sets the type used to secure data handled by the middleware. + /// + public ISecureDataFormat StateDataFormat { get; set; } + } +} diff --git a/src/Microsoft.AspNet.Security.OAuth/OAuthAuthenticationOptions`1.cs b/src/Microsoft.AspNet.Security.OAuth/OAuthAuthenticationOptions`1.cs new file mode 100644 index 000000000..65f01b5b8 --- /dev/null +++ b/src/Microsoft.AspNet.Security.OAuth/OAuthAuthenticationOptions`1.cs @@ -0,0 +1,24 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +namespace Microsoft.AspNet.Security.OAuth +{ + /// + /// Configuration options for . + /// + public class OAuthAuthenticationOptions : OAuthAuthenticationOptions where TNotifications : IOAuthAuthenticationNotifications + { + /// + /// Initializes a new . + /// + public OAuthAuthenticationOptions([NotNull] string authenticationType) + : base(authenticationType) + { + } + + /// + /// Gets or sets the used to handle authentication events. + /// + public TNotifications Notifications { get; set; } + } +} diff --git a/src/Microsoft.AspNet.Security.OAuth/Resources.Designer.cs b/src/Microsoft.AspNet.Security.OAuth/Resources.Designer.cs new file mode 100644 index 000000000..892b42b5f --- /dev/null +++ b/src/Microsoft.AspNet.Security.OAuth/Resources.Designer.cs @@ -0,0 +1,83 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.33440 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace Microsoft.AspNet.Security.OAuth { + using System; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class Resources { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Resources() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Microsoft.AspNet.Security.OAuth.Resources", System.Reflection.IntrospectionExtensions.GetTypeInfo(typeof(Resources)).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + + /// + /// Looks up a localized string similar to The '{0}' option must be provided.. + /// + internal static string Exception_OptionMustBeProvided + { + get + { + return ResourceManager.GetString("Exception_OptionMustBeProvided", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to An ICertificateValidator cannot be specified at the same time as an HttpMessageHandler unless it is a WebRequestHandler.. + /// + internal static string Exception_ValidatorHandlerMismatch { + get { + return ResourceManager.GetString("Exception_ValidatorHandlerMismatch", resourceCulture); + } + } + } +} diff --git a/src/Microsoft.AspNet.Security.OAuth/Resources.resx b/src/Microsoft.AspNet.Security.OAuth/Resources.resx new file mode 100644 index 000000000..2a19bea96 --- /dev/null +++ b/src/Microsoft.AspNet.Security.OAuth/Resources.resx @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + The '{0}' option must be provided. + + + An ICertificateValidator cannot be specified at the same time as an HttpMessageHandler unless it is a WebRequestHandler. + + \ No newline at end of file diff --git a/src/Microsoft.AspNet.Security.OAuth/TokenResponse.cs b/src/Microsoft.AspNet.Security.OAuth/TokenResponse.cs new file mode 100644 index 000000000..84c3e95aa --- /dev/null +++ b/src/Microsoft.AspNet.Security.OAuth/TokenResponse.cs @@ -0,0 +1,25 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using Newtonsoft.Json.Linq; + +namespace Microsoft.AspNet.Security.OAuth +{ + public class TokenResponse + { + public TokenResponse(JObject response) + { + Response = response; + AccessToken = response.Value("access_token"); + TokenType = response.Value("token_type"); + RefreshToken = response.Value("refresh_token"); + ExpiresIn = response.Value("expires_in"); + } + + public JObject Response { get; set; } + public string AccessToken { get; set; } + public string TokenType { get; set; } + public string RefreshToken { get; set; } + public string ExpiresIn { get; set; } + } +} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Security.OAuth/project.json b/src/Microsoft.AspNet.Security.OAuth/project.json new file mode 100644 index 000000000..b6ccd3fe5 --- /dev/null +++ b/src/Microsoft.AspNet.Security.OAuth/project.json @@ -0,0 +1,46 @@ +{ + "version": "1.0.0-*", + "dependencies": { + "Microsoft.AspNet.Http": "1.0.0-*", + "Microsoft.AspNet.RequestContainer": "1.0.0-*", + "Microsoft.AspNet.Security": "1.0.0-*", + "Microsoft.AspNet.Security.DataProtection": "1.0.0-*", + "Microsoft.AspNet.WebUtilities": "1.0.0-*", + "Microsoft.Framework.Logging": "1.0.0-*", + "Newtonsoft.Json": "5.0.8", + "System.Net.Http": "4.0.0.0" + }, + "frameworks": { + "aspnet50": { + "dependencies": { + "System.Net.Http.WebRequest": "" + } + }, + "aspnetcore50": { + "dependencies": { + "System.Collections": "4.0.10.0", + "System.ComponentModel": "4.0.0.0", + "System.Console": "4.0.0.0", + "System.Diagnostics.Debug": "4.0.10.0", + "System.Diagnostics.Tools": "4.0.0.0", + "System.Dynamic.Runtime": "4.0.0.0", + "System.Globalization": "4.0.10.0", + "System.IO": "4.0.10.0", + "System.IO.Compression": "4.0.0.0", + "System.Linq": "4.0.0.0", + "System.Net.Http.WinHttpHandler": "4.0.0.0", + "System.ObjectModel": "4.0.0.0", + "System.Reflection": "4.0.10.0", + "System.Resources.ResourceManager": "4.0.0.0", + "System.Runtime": "4.0.20.0", + "System.Runtime.Extensions": "4.0.10.0", + "System.Runtime.InteropServices": "4.0.20.0", + "System.Security.Claims": "1.0.0-*", + "System.Security.Cryptography.Hashing.Algorithms": "4.0.0.0", + "System.Security.Principal": "4.0.0.0", + "System.Threading": "4.0.0.0", + "System.Threading.Tasks": "4.0.10.0" + } + } + } +} diff --git a/src/Microsoft.AspNet.Security.Twitter/TwitterAuthenticationHandler.cs b/src/Microsoft.AspNet.Security.Twitter/TwitterAuthenticationHandler.cs index b24aa71c3..7fbb4fbc3 100644 --- a/src/Microsoft.AspNet.Security.Twitter/TwitterAuthenticationHandler.cs +++ b/src/Microsoft.AspNet.Security.Twitter/TwitterAuthenticationHandler.cs @@ -328,9 +328,9 @@ private async Task ObtainAccessTokenAsync(string consumerKey, strin var request = new HttpRequestMessage(HttpMethod.Post, AccessTokenEndpoint); request.Headers.Add("Authorization", authorizationHeaderBuilder.ToString()); - var formPairs = new List>() + var formPairs = new Dictionary() { - new KeyValuePair("oauth_verifier", verifier) + { "oauth_verifier", verifier }, }; request.Content = new FormUrlEncodedContent(formPairs); diff --git a/test/Microsoft.AspNet.Security.Test/Facebook/FacebookMiddlewareTests.cs b/test/Microsoft.AspNet.Security.Test/Facebook/FacebookMiddlewareTests.cs index 853894878..56467a760 100644 --- a/test/Microsoft.AspNet.Security.Test/Facebook/FacebookMiddlewareTests.cs +++ b/test/Microsoft.AspNet.Security.Test/Facebook/FacebookMiddlewareTests.cs @@ -62,11 +62,11 @@ public async Task ChallengeWillTriggerRedirection() transaction.Response.StatusCode.ShouldBe(HttpStatusCode.Redirect); var location = transaction.Response.Headers.Location.AbsoluteUri; location.ShouldContain("https://www.facebook.com/dialog/oauth"); - location.ShouldContain("?response_type=code"); - location.ShouldContain("&client_id="); - location.ShouldContain("&redirect_uri="); - location.ShouldContain("&scope="); - location.ShouldContain("&state="); + location.ShouldContain("response_type=code"); + location.ShouldContain("client_id="); + location.ShouldContain("redirect_uri="); + location.ShouldContain("scope="); + location.ShouldContain("state="); } private static TestServer CreateServer(Action configure, Func handler) From 77f9fc496df73ca8575148566d26e5a6a320a91e Mon Sep 17 00:00:00 2001 From: Chris Ross Date: Mon, 8 Sep 2014 13:50:14 -0700 Subject: [PATCH 044/216] Update dependecy versions. --- src/Microsoft.AspNet.Security.OAuth/project.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Microsoft.AspNet.Security.OAuth/project.json b/src/Microsoft.AspNet.Security.OAuth/project.json index b6ccd3fe5..83bc4823b 100644 --- a/src/Microsoft.AspNet.Security.OAuth/project.json +++ b/src/Microsoft.AspNet.Security.OAuth/project.json @@ -29,7 +29,7 @@ "System.IO.Compression": "4.0.0.0", "System.Linq": "4.0.0.0", "System.Net.Http.WinHttpHandler": "4.0.0.0", - "System.ObjectModel": "4.0.0.0", + "System.ObjectModel": "4.0.10.0", "System.Reflection": "4.0.10.0", "System.Resources.ResourceManager": "4.0.0.0", "System.Runtime": "4.0.20.0", From 43fdf2a460f5a90bfd85f8bbbcc71e70b72852f7 Mon Sep 17 00:00:00 2001 From: Wei Wang Date: Tue, 9 Sep 2014 20:42:41 -0700 Subject: [PATCH 045/216] Upgrade Newtonsoft.Json to 6.0.4 version --- src/Microsoft.AspNet.Security.Cookies/project.json | 2 +- src/Microsoft.AspNet.Security.Facebook/project.json | 2 +- src/Microsoft.AspNet.Security.Google/project.json | 2 +- src/Microsoft.AspNet.Security.MicrosoftAccount/project.json | 2 +- src/Microsoft.AspNet.Security.OAuth/project.json | 2 +- src/Microsoft.AspNet.Security.Twitter/project.json | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Microsoft.AspNet.Security.Cookies/project.json b/src/Microsoft.AspNet.Security.Cookies/project.json index 9d9e58616..715a02a7e 100644 --- a/src/Microsoft.AspNet.Security.Cookies/project.json +++ b/src/Microsoft.AspNet.Security.Cookies/project.json @@ -10,7 +10,7 @@ "Microsoft.AspNet.Security.DataProtection": "1.0.0-*", "Microsoft.Framework.DependencyInjection": "1.0.0-*", "Microsoft.Framework.Logging": "1.0.0-*", - "Newtonsoft.Json": "5.0.8" + "Newtonsoft.Json": "6.0.4" }, "frameworks": { "aspnet50": {}, diff --git a/src/Microsoft.AspNet.Security.Facebook/project.json b/src/Microsoft.AspNet.Security.Facebook/project.json index fbbb32c78..eeba5b2d2 100644 --- a/src/Microsoft.AspNet.Security.Facebook/project.json +++ b/src/Microsoft.AspNet.Security.Facebook/project.json @@ -8,7 +8,7 @@ "Microsoft.AspNet.Security.OAuth": "1.0.0-*", "Microsoft.AspNet.WebUtilities": "1.0.0-*", "Microsoft.Framework.Logging": "1.0.0-*", - "Newtonsoft.Json": "5.0.8", + "Newtonsoft.Json": "6.0.4", "System.Net.Http": "4.0.0.0" }, "frameworks": { diff --git a/src/Microsoft.AspNet.Security.Google/project.json b/src/Microsoft.AspNet.Security.Google/project.json index fbbb32c78..eeba5b2d2 100644 --- a/src/Microsoft.AspNet.Security.Google/project.json +++ b/src/Microsoft.AspNet.Security.Google/project.json @@ -8,7 +8,7 @@ "Microsoft.AspNet.Security.OAuth": "1.0.0-*", "Microsoft.AspNet.WebUtilities": "1.0.0-*", "Microsoft.Framework.Logging": "1.0.0-*", - "Newtonsoft.Json": "5.0.8", + "Newtonsoft.Json": "6.0.4", "System.Net.Http": "4.0.0.0" }, "frameworks": { diff --git a/src/Microsoft.AspNet.Security.MicrosoftAccount/project.json b/src/Microsoft.AspNet.Security.MicrosoftAccount/project.json index d452d0121..cf6a2e96a 100644 --- a/src/Microsoft.AspNet.Security.MicrosoftAccount/project.json +++ b/src/Microsoft.AspNet.Security.MicrosoftAccount/project.json @@ -8,7 +8,7 @@ "Microsoft.AspNet.Security.OAuth": "1.0.0-*", "Microsoft.AspNet.WebUtilities": "1.0.0-*", "Microsoft.Framework.Logging": "1.0.0-*", - "Newtonsoft.Json": "5.0.8", + "Newtonsoft.Json": "6.0.4", "System.Net.Http": "4.0.0.0" }, "frameworks": { diff --git a/src/Microsoft.AspNet.Security.OAuth/project.json b/src/Microsoft.AspNet.Security.OAuth/project.json index 83bc4823b..f81cf844e 100644 --- a/src/Microsoft.AspNet.Security.OAuth/project.json +++ b/src/Microsoft.AspNet.Security.OAuth/project.json @@ -7,7 +7,7 @@ "Microsoft.AspNet.Security.DataProtection": "1.0.0-*", "Microsoft.AspNet.WebUtilities": "1.0.0-*", "Microsoft.Framework.Logging": "1.0.0-*", - "Newtonsoft.Json": "5.0.8", + "Newtonsoft.Json": "6.0.4", "System.Net.Http": "4.0.0.0" }, "frameworks": { diff --git a/src/Microsoft.AspNet.Security.Twitter/project.json b/src/Microsoft.AspNet.Security.Twitter/project.json index bf9da2253..f8498191b 100644 --- a/src/Microsoft.AspNet.Security.Twitter/project.json +++ b/src/Microsoft.AspNet.Security.Twitter/project.json @@ -7,7 +7,7 @@ "Microsoft.AspNet.Security.DataProtection": "1.0.0-*", "Microsoft.AspNet.WebUtilities": "1.0.0-*", "Microsoft.Framework.Logging": "1.0.0-*", - "Newtonsoft.Json": "5.0.8", + "Newtonsoft.Json": "6.0.4", "System.Net.Http": "4.0.0.0" }, "frameworks": { From 13adde63fa2bf2c8b8ec8c253a5a9c18d01a1156 Mon Sep 17 00:00:00 2001 From: Wei Wang Date: Wed, 10 Sep 2014 09:13:22 -0700 Subject: [PATCH 046/216] Update the method used to read JSON asynchronously --- .../Google/GoogleMiddlewareTests.cs | 2 +- .../MicrosoftAccount/MicrosoftAccountMiddlewareTests.cs | 2 +- .../Twitter/TwitterMiddlewareTests.cs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/test/Microsoft.AspNet.Security.Test/Google/GoogleMiddlewareTests.cs b/test/Microsoft.AspNet.Security.Test/Google/GoogleMiddlewareTests.cs index 9dff1506d..e12def60f 100644 --- a/test/Microsoft.AspNet.Security.Test/Google/GoogleMiddlewareTests.cs +++ b/test/Microsoft.AspNet.Security.Test/Google/GoogleMiddlewareTests.cs @@ -424,7 +424,7 @@ public async Task AuthenticatedEventCanGetRefreshToken() private static async Task ReturnJsonResponse(object content) { var res = new HttpResponseMessage(HttpStatusCode.OK); - var text = await JsonConvert.SerializeObjectAsync(content); + var text = await Task.Factory.StartNew(() => JsonConvert.SerializeObject(content)); res.Content = new StringContent(text, Encoding.UTF8, "application/json"); return res; } diff --git a/test/Microsoft.AspNet.Security.Test/MicrosoftAccount/MicrosoftAccountMiddlewareTests.cs b/test/Microsoft.AspNet.Security.Test/MicrosoftAccount/MicrosoftAccountMiddlewareTests.cs index 2c1da025f..7bfb0d449 100644 --- a/test/Microsoft.AspNet.Security.Test/MicrosoftAccount/MicrosoftAccountMiddlewareTests.cs +++ b/test/Microsoft.AspNet.Security.Test/MicrosoftAccount/MicrosoftAccountMiddlewareTests.cs @@ -204,7 +204,7 @@ private static async Task SendAsync(TestServer server, string uri, private static async Task ReturnJsonResponse(object content) { var res = new HttpResponseMessage(HttpStatusCode.OK); - var text = await JsonConvert.SerializeObjectAsync(content); + var text = await Task.Factory.StartNew(() => JsonConvert.SerializeObject(content)); res.Content = new StringContent(text, Encoding.UTF8, "application/json"); return res; } diff --git a/test/Microsoft.AspNet.Security.Test/Twitter/TwitterMiddlewareTests.cs b/test/Microsoft.AspNet.Security.Test/Twitter/TwitterMiddlewareTests.cs index d5eb56896..75f7ebbfd 100644 --- a/test/Microsoft.AspNet.Security.Test/Twitter/TwitterMiddlewareTests.cs +++ b/test/Microsoft.AspNet.Security.Test/Twitter/TwitterMiddlewareTests.cs @@ -152,7 +152,7 @@ private static async Task SendAsync(TestServer server, string uri, private static async Task ReturnJsonResponse(object content) { var res = new HttpResponseMessage(HttpStatusCode.OK); - var text = await JsonConvert.SerializeObjectAsync(content); + var text = await Task.Factory.StartNew(() => JsonConvert.SerializeObject(content)); res.Content = new StringContent(text, Encoding.UTF8, "application/json"); return res; } From 51c3dc98dc08a1e4a761bb77469a45b3b33271c2 Mon Sep 17 00:00:00 2001 From: Chris Ross Date: Wed, 10 Sep 2014 12:27:01 -0700 Subject: [PATCH 047/216] Handle IBuilder rename to IApplicationBuilder. --- samples/CookieSample/Startup.cs | 2 +- samples/SocialSample/Startup.cs | 2 +- .../CookieAuthenticationExtensions.cs | 4 ++-- .../CookieAuthenticationOptions.cs | 2 +- .../FacebookAuthenticationExtensions.cs | 12 ++++++------ .../GoogleAuthenticationExtensions.cs | 12 ++++++------ .../MicrosoftAccountAuthenticationExtensions.cs | 12 ++++++------ .../OAuthAuthenticationExtensions.cs | 6 +++--- .../TwitterAuthenticationExtensions.cs | 12 ++++++------ .../BuilderSecurityExtensions.cs | 4 ++-- src/Microsoft.AspNet.Security/Resources.Designer.cs | 4 ++-- src/Microsoft.AspNet.Security/Resources.resx | 4 ++-- .../Facebook/FacebookMiddlewareTests.cs | 2 +- .../MicrosoftAccountMiddlewareTests.cs | 2 +- .../Twitter/TwitterMiddlewareTests.cs | 2 +- 15 files changed, 41 insertions(+), 41 deletions(-) diff --git a/samples/CookieSample/Startup.cs b/samples/CookieSample/Startup.cs index 2a01fc0b2..2e5602b9c 100644 --- a/samples/CookieSample/Startup.cs +++ b/samples/CookieSample/Startup.cs @@ -7,7 +7,7 @@ namespace CookieSample { public class Startup { - public void Configure(IBuilder app) + public void Configure(IApplicationBuilder app) { app.UseCookieAuthentication(new CookieAuthenticationOptions() { diff --git a/samples/SocialSample/Startup.cs b/samples/SocialSample/Startup.cs index f3aff738d..5fbb8887a 100644 --- a/samples/SocialSample/Startup.cs +++ b/samples/SocialSample/Startup.cs @@ -19,7 +19,7 @@ namespace CookieSample { public class Startup { - public void Configure(IBuilder app) + public void Configure(IApplicationBuilder app) { app.UseErrorPage(); diff --git a/src/Microsoft.AspNet.Security.Cookies/CookieAuthenticationExtensions.cs b/src/Microsoft.AspNet.Security.Cookies/CookieAuthenticationExtensions.cs index eb4f64903..03af44a43 100644 --- a/src/Microsoft.AspNet.Security.Cookies/CookieAuthenticationExtensions.cs +++ b/src/Microsoft.AspNet.Security.Cookies/CookieAuthenticationExtensions.cs @@ -13,10 +13,10 @@ public static class CookieAuthenticationExtensions /// /// Adds a cookie-based authentication middleware to your web application pipeline. /// - /// The IBuilder passed to your configuration method + /// The IApplicationBuilder passed to your configuration method /// An options class that controls the middleware behavior /// The original app parameter - public static IBuilder UseCookieAuthentication([NotNull] this IBuilder app, [NotNull] CookieAuthenticationOptions options) + public static IApplicationBuilder UseCookieAuthentication([NotNull] this IApplicationBuilder app, [NotNull] CookieAuthenticationOptions options) { return app.UseMiddleware(options); } diff --git a/src/Microsoft.AspNet.Security.Cookies/CookieAuthenticationOptions.cs b/src/Microsoft.AspNet.Security.Cookies/CookieAuthenticationOptions.cs index 8499fa33f..f04c51264 100644 --- a/src/Microsoft.AspNet.Security.Cookies/CookieAuthenticationOptions.cs +++ b/src/Microsoft.AspNet.Security.Cookies/CookieAuthenticationOptions.cs @@ -125,7 +125,7 @@ public string CookieName /// /// The TicketDataFormat is used to protect and unprotect the identity and other properties which are stored in the /// cookie value. If it is not provided a default data handler is created using the data protection service contained - /// in the IBuilder.Properties. The default data protection service is based on machine key when running on ASP.NET, + /// in the IApplicationBuilder.Properties. The default data protection service is based on machine key when running on ASP.NET, /// and on DPAPI when running in a different process. /// public ISecureDataFormat TicketDataFormat { get; set; } diff --git a/src/Microsoft.AspNet.Security.Facebook/FacebookAuthenticationExtensions.cs b/src/Microsoft.AspNet.Security.Facebook/FacebookAuthenticationExtensions.cs index 7f7cb4ebd..543827209 100644 --- a/src/Microsoft.AspNet.Security.Facebook/FacebookAuthenticationExtensions.cs +++ b/src/Microsoft.AspNet.Security.Facebook/FacebookAuthenticationExtensions.cs @@ -13,11 +13,11 @@ public static class FacebookAuthenticationExtensions /// /// Authenticate users using Facebook. /// - /// The passed to the configure method. + /// The passed to the configure method. /// The appId assigned by Facebook. /// The appSecret assigned by Facebook. - /// The updated . - public static IBuilder UseFacebookAuthentication([NotNull] this IBuilder app, [NotNull] string appId, [NotNull] string appSecret) + /// The updated . + public static IApplicationBuilder UseFacebookAuthentication([NotNull] this IApplicationBuilder app, [NotNull] string appId, [NotNull] string appSecret) { return app.UseFacebookAuthentication(new FacebookAuthenticationOptions() { @@ -29,10 +29,10 @@ public static IBuilder UseFacebookAuthentication([NotNull] this IBuilder app, [N /// /// Authenticate users using Facebook. /// - /// The passed to the configure method. + /// The passed to the configure method. /// The middleware configuration options. - /// The updated . - public static IBuilder UseFacebookAuthentication([NotNull] this IBuilder app, [NotNull] FacebookAuthenticationOptions options) + /// The updated . + public static IApplicationBuilder UseFacebookAuthentication([NotNull] this IApplicationBuilder app, [NotNull] FacebookAuthenticationOptions options) { if (string.IsNullOrEmpty(options.SignInAsAuthenticationType)) { diff --git a/src/Microsoft.AspNet.Security.Google/GoogleAuthenticationExtensions.cs b/src/Microsoft.AspNet.Security.Google/GoogleAuthenticationExtensions.cs index cfac47773..571ff5ffe 100644 --- a/src/Microsoft.AspNet.Security.Google/GoogleAuthenticationExtensions.cs +++ b/src/Microsoft.AspNet.Security.Google/GoogleAuthenticationExtensions.cs @@ -13,11 +13,11 @@ public static class GoogleAuthenticationExtensions /// /// Authenticate users using Google OAuth 2.0. /// - /// The passed to the configure method. + /// The passed to the configure method. /// The google assigned client id. /// The google assigned client secret. - /// The updated . - public static IBuilder UseGoogleAuthentication([NotNull] this IBuilder app, [NotNull] string clientId, [NotNull] string clientSecret) + /// The updated . + public static IApplicationBuilder UseGoogleAuthentication([NotNull] this IApplicationBuilder app, [NotNull] string clientId, [NotNull] string clientSecret) { return app.UseGoogleAuthentication( new GoogleAuthenticationOptions @@ -30,10 +30,10 @@ public static IBuilder UseGoogleAuthentication([NotNull] this IBuilder app, [Not /// /// Authenticate users using Google OAuth 2.0. /// - /// The passed to the configure method. + /// The passed to the configure method. /// Middleware configuration options. - /// The updated . - public static IBuilder UseGoogleAuthentication([NotNull] this IBuilder app, [NotNull] GoogleAuthenticationOptions options) + /// The updated . + public static IApplicationBuilder UseGoogleAuthentication([NotNull] this IApplicationBuilder app, [NotNull] GoogleAuthenticationOptions options) { if (string.IsNullOrEmpty(options.SignInAsAuthenticationType)) { diff --git a/src/Microsoft.AspNet.Security.MicrosoftAccount/MicrosoftAccountAuthenticationExtensions.cs b/src/Microsoft.AspNet.Security.MicrosoftAccount/MicrosoftAccountAuthenticationExtensions.cs index 468d27907..9963abf1d 100644 --- a/src/Microsoft.AspNet.Security.MicrosoftAccount/MicrosoftAccountAuthenticationExtensions.cs +++ b/src/Microsoft.AspNet.Security.MicrosoftAccount/MicrosoftAccountAuthenticationExtensions.cs @@ -13,11 +13,11 @@ public static class MicrosoftAccountAuthenticationExtensions /// /// Authenticate users using Microsoft Account. /// - /// The passed to the configure method. + /// The passed to the configure method. /// The application client ID assigned by the Microsoft authentication service. /// The application client secret assigned by the Microsoft authentication service. - /// The updated . - public static IBuilder UseMicrosoftAccountAuthentication([NotNull] this IBuilder app, [NotNull] string clientId, [NotNull] string clientSecret) + /// The updated . + public static IApplicationBuilder UseMicrosoftAccountAuthentication([NotNull] this IApplicationBuilder app, [NotNull] string clientId, [NotNull] string clientSecret) { return app.UseMicrosoftAccountAuthentication( new MicrosoftAccountAuthenticationOptions @@ -30,10 +30,10 @@ public static IBuilder UseMicrosoftAccountAuthentication([NotNull] this IBuilder /// /// Authenticate users using Microsoft Account. /// - /// The passed to the configure method. + /// The passed to the configure method. /// The middleware configuration options. - /// The updated . - public static IBuilder UseMicrosoftAccountAuthentication([NotNull] this IBuilder app, [NotNull] MicrosoftAccountAuthenticationOptions options) + /// The updated . + public static IApplicationBuilder UseMicrosoftAccountAuthentication([NotNull] this IApplicationBuilder app, [NotNull] MicrosoftAccountAuthenticationOptions options) { if (string.IsNullOrEmpty(options.SignInAsAuthenticationType)) { diff --git a/src/Microsoft.AspNet.Security.OAuth/OAuthAuthenticationExtensions.cs b/src/Microsoft.AspNet.Security.OAuth/OAuthAuthenticationExtensions.cs index e140620e6..0b6f0ddec 100644 --- a/src/Microsoft.AspNet.Security.OAuth/OAuthAuthenticationExtensions.cs +++ b/src/Microsoft.AspNet.Security.OAuth/OAuthAuthenticationExtensions.cs @@ -15,10 +15,10 @@ public static class OAuthAuthenticationExtensions /// /// Authenticate users using OAuth. /// - /// The passed to the configure method. + /// The passed to the configure method. /// The middleware configuration options. - /// The updated . - public static IBuilder UseOAuthAuthentication([NotNull] this IBuilder app, [NotNull] OAuthAuthenticationOptions options) + /// The updated . + public static IApplicationBuilder UseOAuthAuthentication([NotNull] this IApplicationBuilder app, [NotNull] OAuthAuthenticationOptions options) { if (string.IsNullOrEmpty(options.SignInAsAuthenticationType)) { diff --git a/src/Microsoft.AspNet.Security.Twitter/TwitterAuthenticationExtensions.cs b/src/Microsoft.AspNet.Security.Twitter/TwitterAuthenticationExtensions.cs index 250c721cb..aa56249cc 100644 --- a/src/Microsoft.AspNet.Security.Twitter/TwitterAuthenticationExtensions.cs +++ b/src/Microsoft.AspNet.Security.Twitter/TwitterAuthenticationExtensions.cs @@ -13,11 +13,11 @@ public static class TwitterAuthenticationExtensions /// /// Authenticate users using Twitter /// - /// The passed to the configure method + /// The passed to the configure method /// The Twitter-issued consumer key /// The Twitter-issued consumer secret - /// The updated - public static IBuilder UseTwitterAuthentication([NotNull] this IBuilder app, [NotNull] string consumerKey, [NotNull] string consumerSecret) + /// The updated + public static IApplicationBuilder UseTwitterAuthentication([NotNull] this IApplicationBuilder app, [NotNull] string consumerKey, [NotNull] string consumerSecret) { return app.UseTwitterAuthentication( new TwitterAuthenticationOptions @@ -30,10 +30,10 @@ public static IBuilder UseTwitterAuthentication([NotNull] this IBuilder app, [No /// /// Authenticate users using Twitter /// - /// The passed to the configure method + /// The passed to the configure method /// Middleware configuration options - /// The updated - public static IBuilder UseTwitterAuthentication([NotNull] this IBuilder app, [NotNull] TwitterAuthenticationOptions options) + /// The updated + public static IApplicationBuilder UseTwitterAuthentication([NotNull] this IApplicationBuilder app, [NotNull] TwitterAuthenticationOptions options) { if (string.IsNullOrEmpty(options.SignInAsAuthenticationType)) { diff --git a/src/Microsoft.AspNet.Security/BuilderSecurityExtensions.cs b/src/Microsoft.AspNet.Security/BuilderSecurityExtensions.cs index 6043a0966..5a9aec367 100644 --- a/src/Microsoft.AspNet.Security/BuilderSecurityExtensions.cs +++ b/src/Microsoft.AspNet.Security/BuilderSecurityExtensions.cs @@ -17,7 +17,7 @@ public static class BuilderSecurityExtensions /// /// App builder passed to the application startup code /// - public static string GetDefaultSignInAsAuthenticationType([NotNull] this IBuilder app) + public static string GetDefaultSignInAsAuthenticationType([NotNull] this IApplicationBuilder app) { object value; if (app.Properties.TryGetValue(Constants.DefaultSignInAsAuthenticationType, out value)) @@ -37,7 +37,7 @@ public static string GetDefaultSignInAsAuthenticationType([NotNull] this IBuilde /// /// App builder passed to the application startup code /// AuthenticationType that external middleware should sign in as. - public static void SetDefaultSignInAsAuthenticationType([NotNull] this IBuilder app, [NotNull] string authenticationType) + public static void SetDefaultSignInAsAuthenticationType([NotNull] this IApplicationBuilder app, [NotNull] string authenticationType) { app.Properties[Constants.DefaultSignInAsAuthenticationType] = authenticationType; } diff --git a/src/Microsoft.AspNet.Security/Resources.Designer.cs b/src/Microsoft.AspNet.Security/Resources.Designer.cs index d53526588..485da1825 100644 --- a/src/Microsoft.AspNet.Security/Resources.Designer.cs +++ b/src/Microsoft.AspNet.Security/Resources.Designer.cs @@ -70,7 +70,7 @@ internal static string Exception_AuthenticationTokenDoesNotProvideSyncMethods { } /// - /// Looks up a localized string similar to The default data protection provider may only be used when the IBuilder.Properties contains an appropriate 'host.AppName' key.. + /// Looks up a localized string similar to The default data protection provider may only be used when the IApplicationBuilder.Properties contains an appropriate 'host.AppName' key.. /// internal static string Exception_DefaultDpapiRequiresAppNameKey { get { @@ -79,7 +79,7 @@ internal static string Exception_DefaultDpapiRequiresAppNameKey { } /// - /// Looks up a localized string similar to A default value for SignInAsAuthenticationType was not found in IBuilder Properties. This can happen if your authentication middleware are added in the wrong order, or if one is missing.. + /// Looks up a localized string similar to A default value for SignInAsAuthenticationType was not found in IApplicationBuilder Properties. This can happen if your authentication middleware are added in the wrong order, or if one is missing.. /// internal static string Exception_MissingDefaultSignInAsAuthenticationType { get { diff --git a/src/Microsoft.AspNet.Security/Resources.resx b/src/Microsoft.AspNet.Security/Resources.resx index 5a02ab772..f0765cc32 100644 --- a/src/Microsoft.AspNet.Security/Resources.resx +++ b/src/Microsoft.AspNet.Security/Resources.resx @@ -118,13 +118,13 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - The default data protection provider may only be used when the IBuilder.Properties contains an appropriate 'host.AppName' key. + The default data protection provider may only be used when the IApplicationBuilder.Properties contains an appropriate 'host.AppName' key. The state passed to UnhookAuthentication may only be the return value from HookAuthentication. - A default value for SignInAsAuthenticationType was not found in IBuilder Properties. This can happen if your authentication middleware are added in the wrong order, or if one is missing. + A default value for SignInAsAuthenticationType was not found in IApplicationBuilder Properties. This can happen if your authentication middleware are added in the wrong order, or if one is missing. The AuthenticationTokenProvider's required synchronous events have not been registered. diff --git a/test/Microsoft.AspNet.Security.Test/Facebook/FacebookMiddlewareTests.cs b/test/Microsoft.AspNet.Security.Test/Facebook/FacebookMiddlewareTests.cs index 56467a760..672dc04ac 100644 --- a/test/Microsoft.AspNet.Security.Test/Facebook/FacebookMiddlewareTests.cs +++ b/test/Microsoft.AspNet.Security.Test/Facebook/FacebookMiddlewareTests.cs @@ -69,7 +69,7 @@ public async Task ChallengeWillTriggerRedirection() location.ShouldContain("state="); } - private static TestServer CreateServer(Action configure, Func handler) + private static TestServer CreateServer(Action configure, Func handler) { return TestServer.Create(app => { diff --git a/test/Microsoft.AspNet.Security.Test/MicrosoftAccount/MicrosoftAccountMiddlewareTests.cs b/test/Microsoft.AspNet.Security.Test/MicrosoftAccount/MicrosoftAccountMiddlewareTests.cs index 7bfb0d449..a19aeae05 100644 --- a/test/Microsoft.AspNet.Security.Test/MicrosoftAccount/MicrosoftAccountMiddlewareTests.cs +++ b/test/Microsoft.AspNet.Security.Test/MicrosoftAccount/MicrosoftAccountMiddlewareTests.cs @@ -151,7 +151,7 @@ public async Task AuthenticatedEventCanGetRefreshToken() transaction.FindClaimValue("RefreshToken").ShouldBe("Test Refresh Token"); } - private static TestServer CreateServer(Action configure, Func handler) + private static TestServer CreateServer(Action configure, Func handler) { return TestServer.Create(app => { diff --git a/test/Microsoft.AspNet.Security.Test/Twitter/TwitterMiddlewareTests.cs b/test/Microsoft.AspNet.Security.Test/Twitter/TwitterMiddlewareTests.cs index 75f7ebbfd..461e54184 100644 --- a/test/Microsoft.AspNet.Security.Test/Twitter/TwitterMiddlewareTests.cs +++ b/test/Microsoft.AspNet.Security.Test/Twitter/TwitterMiddlewareTests.cs @@ -105,7 +105,7 @@ public async Task ChallengeWillTriggerRedirection() location.ShouldContain("https://twitter.com/oauth/authenticate?oauth_token="); } - private static TestServer CreateServer(Action configure, Func handler) + private static TestServer CreateServer(Action configure, Func handler) { return TestServer.Create(app => { From f6d6f3141400bef8c53e56d1eec683a2c7713826 Mon Sep 17 00:00:00 2001 From: Chris Ross Date: Tue, 9 Sep 2014 10:38:39 -0700 Subject: [PATCH 048/216] #32 - Port Cookie chunking from Katana. --- .../CookieAuthenticationHandler.cs | 12 +- .../CookieAuthenticationMiddleware.cs | 5 + .../CookieAuthenticationOptions.cs | 8 + .../Infrastructure/ChunkingCookieManager.cs | 310 ++++++++++++++++++ .../Infrastructure/Constants.cs | 13 + .../Infrastructure/ICookieManager.cs | 39 +++ .../Resources.Designer.cs | 85 +++++ .../Resources.resx | 126 +++++++ .../Infrastructure/CookieChunkingTests.cs | 168 ++++++++++ 9 files changed, 761 insertions(+), 5 deletions(-) create mode 100644 src/Microsoft.AspNet.Security.Cookies/Infrastructure/ChunkingCookieManager.cs create mode 100644 src/Microsoft.AspNet.Security.Cookies/Infrastructure/Constants.cs create mode 100644 src/Microsoft.AspNet.Security.Cookies/Infrastructure/ICookieManager.cs create mode 100644 src/Microsoft.AspNet.Security.Cookies/Resources.Designer.cs create mode 100644 src/Microsoft.AspNet.Security.Cookies/Resources.resx create mode 100644 test/Microsoft.AspNet.Security.Test/Cookies/Infrastructure/CookieChunkingTests.cs diff --git a/src/Microsoft.AspNet.Security.Cookies/CookieAuthenticationHandler.cs b/src/Microsoft.AspNet.Security.Cookies/CookieAuthenticationHandler.cs index 1e21937fa..23f66b6c5 100644 --- a/src/Microsoft.AspNet.Security.Cookies/CookieAuthenticationHandler.cs +++ b/src/Microsoft.AspNet.Security.Cookies/CookieAuthenticationHandler.cs @@ -37,8 +37,7 @@ protected override AuthenticationTicket AuthenticateCore() protected override async Task AuthenticateCoreAsync() { - IReadableStringCollection cookies = Request.Cookies; - string cookie = cookies[Options.CookieName]; + string cookie = Options.CookieManager.GetRequestCookie(Context, Options.CookieName); if (string.IsNullOrWhiteSpace(cookie)) { return null; @@ -148,7 +147,8 @@ protected override async Task ApplyResponseGrantAsync() var model = new AuthenticationTicket(context.Identity, context.Properties); string cookieValue = Options.TicketDataFormat.Protect(model); - Response.Cookies.Append( + Options.CookieManager.AppendResponseCookie( + Context, Options.CookieName, cookieValue, cookieOptions); @@ -162,7 +162,8 @@ protected override async Task ApplyResponseGrantAsync() Options.Notifications.ResponseSignOut(context); - Response.Cookies.Delete( + Options.CookieManager.DeleteCookie( + Context, Options.CookieName, cookieOptions); } @@ -180,7 +181,8 @@ protected override async Task ApplyResponseGrantAsync() cookieOptions.Expires = _renewExpiresUtc.ToUniversalTime().DateTime; } - Response.Cookies.Append( + Options.CookieManager.AppendResponseCookie( + Context, Options.CookieName, cookieValue, cookieOptions); diff --git a/src/Microsoft.AspNet.Security.Cookies/CookieAuthenticationMiddleware.cs b/src/Microsoft.AspNet.Security.Cookies/CookieAuthenticationMiddleware.cs index 6f2a5dec0..1349ccade 100644 --- a/src/Microsoft.AspNet.Security.Cookies/CookieAuthenticationMiddleware.cs +++ b/src/Microsoft.AspNet.Security.Cookies/CookieAuthenticationMiddleware.cs @@ -5,6 +5,7 @@ using System; using Microsoft.AspNet.Builder; using Microsoft.AspNet.Http; +using Microsoft.AspNet.Security.Cookies.Infrastructure; using Microsoft.AspNet.Security.DataHandler; using Microsoft.AspNet.Security.DataProtection; using Microsoft.AspNet.Security.Infrastructure; @@ -33,6 +34,10 @@ public CookieAuthenticationMiddleware(RequestDelegate next, IDataProtectionProvi typeof(CookieAuthenticationMiddleware).FullName, options.AuthenticationType, "v1"); options.TicketDataFormat = new TicketDataFormat(dataProtector); } + if (Options.CookieManager == null) + { + Options.CookieManager = new ChunkingCookieManager(); + } _logger = loggerFactory.Create(typeof(CookieAuthenticationMiddleware).FullName); } diff --git a/src/Microsoft.AspNet.Security.Cookies/CookieAuthenticationOptions.cs b/src/Microsoft.AspNet.Security.Cookies/CookieAuthenticationOptions.cs index f04c51264..0b6ef879e 100644 --- a/src/Microsoft.AspNet.Security.Cookies/CookieAuthenticationOptions.cs +++ b/src/Microsoft.AspNet.Security.Cookies/CookieAuthenticationOptions.cs @@ -5,6 +5,7 @@ using System; using System.Diagnostics.CodeAnalysis; using Microsoft.AspNet.Http; +using Microsoft.AspNet.Security.Cookies.Infrastructure; using Microsoft.AspNet.Security.Infrastructure; namespace Microsoft.AspNet.Security.Cookies @@ -135,5 +136,12 @@ public string CookieName /// used which calls DateTimeOffset.UtcNow. This is typically not replaced except for unit testing. /// public ISystemClock SystemClock { get; set; } + + /// + /// The component used to get cookies from the request or set them on the response. + /// + /// ChunkingCookieManager will be used by default. + /// + public ICookieManager CookieManager { get; set; } } } diff --git a/src/Microsoft.AspNet.Security.Cookies/Infrastructure/ChunkingCookieManager.cs b/src/Microsoft.AspNet.Security.Cookies/Infrastructure/ChunkingCookieManager.cs new file mode 100644 index 000000000..d5e48c198 --- /dev/null +++ b/src/Microsoft.AspNet.Security.Cookies/Infrastructure/ChunkingCookieManager.cs @@ -0,0 +1,310 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using Microsoft.AspNet.Http; + +namespace Microsoft.AspNet.Security.Cookies.Infrastructure +{ + /// + /// This handles cookies that are limited by per cookie length. It breaks down long cookies for responses, and reassembles them + /// from requests. + /// + public class ChunkingCookieManager : ICookieManager + { + public ChunkingCookieManager() + { + ChunkSize = 4090; + ThrowForPartialCookies = true; + } + + /// + /// The maximum size of cookie to send back to the client. If a cookie exceeds this size it will be broken down into multiple + /// cookies. Set this value to null to disable this behavior. The default is 4090 characters, which is supported by all + /// common browsers. + /// + /// Note that browsers may also have limits on the total size of all cookies per domain, and on the number of cookies per domain. + /// + public int? ChunkSize { get; set; } + + /// + /// Throw if not all chunks of a cookie are available on a request for re-assembly. + /// + public bool ThrowForPartialCookies { get; set; } + + // Parse the "chunks:XX" to determine how many chunks there should be. + private static int ParseChunksCount(string value) + { + if (value != null && value.StartsWith("chunks:", StringComparison.Ordinal)) + { + string chunksCountString = value.Substring("chunks:".Length); + int chunksCount; + if (int.TryParse(chunksCountString, NumberStyles.None, CultureInfo.InvariantCulture, out chunksCount)) + { + return chunksCount; + } + } + return 0; + } + + /// + /// Get the reassembled cookie. Non chunked cookies are returned normally. + /// Cookies with missing chunks just have their "chunks:XX" header returned. + /// + /// + /// + /// The reassembled cookie, if any, or null. + public string GetRequestCookie(HttpContext context, string key) + { + if (context == null) + { + throw new ArgumentNullException("context"); + } + + IReadableStringCollection requestCookies = context.Request.Cookies; + string value = requestCookies[key]; + int chunksCount = ParseChunksCount(value); + if (chunksCount > 0) + { + bool quoted = false; + string[] chunks = new string[chunksCount]; + for (int chunkId = 1; chunkId <= chunksCount; chunkId++) + { + string chunk = requestCookies[key + "C" + chunkId.ToString(CultureInfo.InvariantCulture)]; + if (chunk == null) + { + if (ThrowForPartialCookies) + { + int totalSize = 0; + for (int i = 0; i < chunkId - 1; i++) + { + totalSize += chunks[i].Length; + } + throw new FormatException( + string.Format(CultureInfo.CurrentCulture, Resources.Exception_ImcompleteChunkedCookie, chunkId - 1, chunksCount, totalSize)); + } + // Missing chunk, abort by returning the original cookie value. It may have been a false positive? + return value; + } + if (IsQuoted(chunk)) + { + // Note: Since we assume these cookies were generated by our code, then we can assume that if one cookie has quotes then they all do. + quoted = true; + chunk = RemoveQuotes(chunk); + } + chunks[chunkId - 1] = chunk; + } + string merged = string.Join(string.Empty, chunks); + if (quoted) + { + merged = Quote(merged); + } + return merged; + } + return value; + } + + /// + /// Appends a new response cookie to the Set-Cookie header. If the cookie is larger than the given size limit + /// then it will be broken down into multiple cookies as follows: + /// Set-Cookie: CookieName=chunks:3; path=/ + /// Set-Cookie: CookieNameC1=Segment1; path=/ + /// Set-Cookie: CookieNameC2=Segment2; path=/ + /// Set-Cookie: CookieNameC3=Segment3; path=/ + /// + /// + /// + /// + /// + public void AppendResponseCookie(HttpContext context, string key, string value, CookieOptions options) + { + if (context == null) + { + throw new ArgumentNullException("context"); + } + if (options == null) + { + throw new ArgumentNullException("options"); + } + + bool domainHasValue = !string.IsNullOrEmpty(options.Domain); + bool pathHasValue = !string.IsNullOrEmpty(options.Path); + bool expiresHasValue = options.Expires.HasValue; + + string escapedKey = Uri.EscapeDataString(key); + string prefix = escapedKey + "="; + + string suffix = string.Concat( + !domainHasValue ? null : "; domain=", + !domainHasValue ? null : options.Domain, + !pathHasValue ? null : "; path=", + !pathHasValue ? null : options.Path, + !expiresHasValue ? null : "; expires=", + !expiresHasValue ? null : options.Expires.Value.ToString("ddd, dd-MMM-yyyy HH:mm:ss ", CultureInfo.InvariantCulture) + "GMT", + !options.Secure ? null : "; secure", + !options.HttpOnly ? null : "; HttpOnly"); + + value = value ?? string.Empty; + bool quoted = false; + if (IsQuoted(value)) + { + quoted = true; + value = RemoveQuotes(value); + } + string escapedValue = Uri.EscapeDataString(value); + + // Normal cookie + IHeaderDictionary responseHeaders = context.Response.Headers; + if (!ChunkSize.HasValue || ChunkSize.Value > prefix.Length + escapedValue.Length + suffix.Length + (quoted ? 2 : 0)) + { + string setCookieValue = string.Concat( + prefix, + quoted ? Quote(escapedValue) : escapedValue, + suffix); + responseHeaders.AppendValues(Constants.Headers.SetCookie, setCookieValue); + } + else if (ChunkSize.Value < prefix.Length + suffix.Length + (quoted ? 2 : 0) + 10) + { + // 10 is the minimum data we want to put in an individual cookie, including the cookie chunk identifier "CXX". + // No room for data, we can't chunk the options and name + throw new InvalidOperationException(Resources.Exception_CookieLimitTooSmall); + } + else + { + // Break the cookie down into multiple cookies. + // Key = CookieName, value = "Segment1Segment2Segment2" + // Set-Cookie: CookieName=chunks:3; path=/ + // Set-Cookie: CookieNameC1="Segment1"; path=/ + // Set-Cookie: CookieNameC2="Segment2"; path=/ + // Set-Cookie: CookieNameC3="Segment3"; path=/ + int dataSizePerCookie = ChunkSize.Value - prefix.Length - suffix.Length - (quoted ? 2 : 0) - 3; // Budget 3 chars for the chunkid. + int cookieChunkCount = (int)Math.Ceiling(escapedValue.Length * 1.0 / dataSizePerCookie); + + responseHeaders.AppendValues(Constants.Headers.SetCookie, prefix + "chunks:" + cookieChunkCount.ToString(CultureInfo.InvariantCulture) + suffix); + + string[] chunks = new string[cookieChunkCount]; + int offset = 0; + for (int chunkId = 1; chunkId <= cookieChunkCount; chunkId++) + { + int remainingLength = escapedValue.Length - offset; + int length = Math.Min(dataSizePerCookie, remainingLength); + string segment = escapedValue.Substring(offset, length); + offset += length; + + chunks[chunkId - 1] = string.Concat( + escapedKey, + "C", + chunkId.ToString(CultureInfo.InvariantCulture), + "=", + quoted ? "\"" : string.Empty, + segment, + quoted ? "\"" : string.Empty, + suffix); + } + responseHeaders.AppendValues(Constants.Headers.SetCookie, chunks); + } + } + + /// + /// Deletes the cookie with the given key by setting an expired state. If a matching chunked cookie exists on + /// the request, delete each chunk. + /// + /// + /// + /// + public void DeleteCookie(HttpContext context, string key, CookieOptions options) + { + if (context == null) + { + throw new ArgumentNullException("context"); + } + if (options == null) + { + throw new ArgumentNullException("options"); + } + + string escapedKey = Uri.EscapeDataString(key); + List keys = new List(); + keys.Add(escapedKey + "="); + + string requestCookie = context.Request.Cookies[key]; + int chunks = ParseChunksCount(requestCookie); + if (chunks > 0) + { + for (int i = 1; i <= chunks + 1; i++) + { + string subkey = escapedKey + "C" + i.ToString(CultureInfo.InvariantCulture); + keys.Add(subkey + "="); + } + } + + bool domainHasValue = !string.IsNullOrEmpty(options.Domain); + bool pathHasValue = !string.IsNullOrEmpty(options.Path); + + Func rejectPredicate; + Func predicate = value => keys.Any(k => value.StartsWith(k, StringComparison.OrdinalIgnoreCase)); + if (domainHasValue) + { + rejectPredicate = value => predicate(value) && value.IndexOf("domain=" + options.Domain, StringComparison.OrdinalIgnoreCase) != -1; + } + else if (pathHasValue) + { + rejectPredicate = value => predicate(value) && value.IndexOf("path=" + options.Path, StringComparison.OrdinalIgnoreCase) != -1; + } + else + { + rejectPredicate = value => predicate(value); + } + + IHeaderDictionary responseHeaders = context.Response.Headers; + IList existingValues = responseHeaders.GetValues(Constants.Headers.SetCookie); + if (existingValues != null) + { + responseHeaders.SetValues(Constants.Headers.SetCookie, existingValues.Where(value => !rejectPredicate(value)).ToArray()); + } + + AppendResponseCookie( + context, + key, + string.Empty, + new CookieOptions + { + Path = options.Path, + Domain = options.Domain, + Expires = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc), + }); + + for (int i = 1; i <= chunks; i++) + { + AppendResponseCookie( + context, + key + "C" + i.ToString(CultureInfo.InvariantCulture), + string.Empty, + new CookieOptions + { + Path = options.Path, + Domain = options.Domain, + Expires = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc), + }); + } + } + + private static bool IsQuoted(string value) + { + return value.Length >= 2 && value[0] == '"' && value[value.Length - 1] == '"'; + } + + private static string RemoveQuotes(string value) + { + return value.Substring(1, value.Length - 2); + } + + private static string Quote(string value) + { + return '"' + value + '"'; + } + } +} diff --git a/src/Microsoft.AspNet.Security.Cookies/Infrastructure/Constants.cs b/src/Microsoft.AspNet.Security.Cookies/Infrastructure/Constants.cs new file mode 100644 index 000000000..ef8db8e9e --- /dev/null +++ b/src/Microsoft.AspNet.Security.Cookies/Infrastructure/Constants.cs @@ -0,0 +1,13 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +namespace Microsoft.AspNet.Security.Cookies.Infrastructure +{ + internal static class Constants + { + internal static class Headers + { + internal const string SetCookie = "Set-Cookie"; + } + } +} diff --git a/src/Microsoft.AspNet.Security.Cookies/Infrastructure/ICookieManager.cs b/src/Microsoft.AspNet.Security.Cookies/Infrastructure/ICookieManager.cs new file mode 100644 index 000000000..b523b1bad --- /dev/null +++ b/src/Microsoft.AspNet.Security.Cookies/Infrastructure/ICookieManager.cs @@ -0,0 +1,39 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using Microsoft.AspNet.Http; + +namespace Microsoft.AspNet.Security.Cookies.Infrastructure +{ + /// + /// This is used by the CookieAuthenticationMiddleware to process request and response cookies. + /// It is abstracted from the normal cookie APIs to allow for complex operations like chunking. + /// + public interface ICookieManager + { + /// + /// Retrieve a cookie of the given name from the request. + /// + /// + /// + /// + string GetRequestCookie(HttpContext context, string key); + + /// + /// Append the given cookie to the response. + /// + /// + /// + /// + /// + void AppendResponseCookie(HttpContext context, string key, string value, CookieOptions options); + + /// + /// Append a delete cookie to the response. + /// + /// + /// + /// + void DeleteCookie(HttpContext context, string key, CookieOptions options); + } +} diff --git a/src/Microsoft.AspNet.Security.Cookies/Resources.Designer.cs b/src/Microsoft.AspNet.Security.Cookies/Resources.Designer.cs new file mode 100644 index 000000000..1a0258ba6 --- /dev/null +++ b/src/Microsoft.AspNet.Security.Cookies/Resources.Designer.cs @@ -0,0 +1,85 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.34003 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace Microsoft.AspNet.Security.Cookies { + using System; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class Resources { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Resources() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Microsoft.AspNet.Security.Cookies.Resources", System.Reflection.IntrospectionExtensions.GetTypeInfo(typeof(Resources)).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + + /// + /// Looks up a localized string similar to The cookie key and options are larger than ChunksSize, leaving no room for data.. + /// + internal static string Exception_CookieLimitTooSmall + { + get + { + return ResourceManager.GetString("Exception_CookieLimitTooSmall", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to The chunked cookie is incomplete. Only {0} of the expected {1} chunks were found, totaling {2} characters. A client size limit may have been exceeded.. + /// + internal static string Exception_ImcompleteChunkedCookie + { + get + { + return ResourceManager.GetString("Exception_ImcompleteChunkedCookie", resourceCulture); + } + } + } +} diff --git a/src/Microsoft.AspNet.Security.Cookies/Resources.resx b/src/Microsoft.AspNet.Security.Cookies/Resources.resx new file mode 100644 index 000000000..71debecfa --- /dev/null +++ b/src/Microsoft.AspNet.Security.Cookies/Resources.resx @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + The cookie key and options are larger than ChunksSize, leaving no room for data. + + + The chunked cookie is incomplete. Only {0} of the expected {1} chunks were found, totaling {2} characters. A client size limit may have been exceeded. + + \ No newline at end of file diff --git a/test/Microsoft.AspNet.Security.Test/Cookies/Infrastructure/CookieChunkingTests.cs b/test/Microsoft.AspNet.Security.Test/Cookies/Infrastructure/CookieChunkingTests.cs new file mode 100644 index 000000000..4df8763bd --- /dev/null +++ b/test/Microsoft.AspNet.Security.Test/Cookies/Infrastructure/CookieChunkingTests.cs @@ -0,0 +1,168 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Collections.Generic; +using Microsoft.AspNet.Http; +using Microsoft.AspNet.PipelineCore; +using Xunit; + +namespace Microsoft.AspNet.Security.Cookies.Infrastructure +{ + public class CookieChunkingTests + { + [Fact] + public void AppendLargeCookie_Appended() + { + HttpContext context = new DefaultHttpContext(); + + string testString = "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + new ChunkingCookieManager() { ChunkSize = null }.AppendResponseCookie(context, "TestCookie", testString, new CookieOptions()); + IList values = context.Response.Headers.GetValues("Set-Cookie"); + Assert.Equal(1, values.Count); + Assert.Equal("TestCookie=" + testString + "; path=/", values[0]); + } + + [Fact] + public void AppendLargeCookieWithLimit_Chunked() + { + HttpContext context = new DefaultHttpContext(); + + string testString = "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + new ChunkingCookieManager() { ChunkSize = 30 }.AppendResponseCookie(context, "TestCookie", testString, new CookieOptions()); + IList values = context.Response.Headers.GetValues("Set-Cookie"); + Assert.Equal(9, values.Count); + Assert.Equal(new[] + { + "TestCookie=chunks:8; path=/", + "TestCookieC1=abcdefgh; path=/", + "TestCookieC2=ijklmnop; path=/", + "TestCookieC3=qrstuvwx; path=/", + "TestCookieC4=yz012345; path=/", + "TestCookieC5=6789ABCD; path=/", + "TestCookieC6=EFGHIJKL; path=/", + "TestCookieC7=MNOPQRST; path=/", + "TestCookieC8=UVWXYZ; path=/", + }, values); + } + + [Fact] + public void AppendLargeQuotedCookieWithLimit_QuotedChunked() + { + HttpContext context = new DefaultHttpContext(); + + string testString = "\"abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ\""; + new ChunkingCookieManager() { ChunkSize = 32 }.AppendResponseCookie(context, "TestCookie", testString, new CookieOptions()); + IList values = context.Response.Headers.GetValues("Set-Cookie"); + Assert.Equal(9, values.Count); + Assert.Equal(new[] + { + "TestCookie=chunks:8; path=/", + "TestCookieC1=\"abcdefgh\"; path=/", + "TestCookieC2=\"ijklmnop\"; path=/", + "TestCookieC3=\"qrstuvwx\"; path=/", + "TestCookieC4=\"yz012345\"; path=/", + "TestCookieC5=\"6789ABCD\"; path=/", + "TestCookieC6=\"EFGHIJKL\"; path=/", + "TestCookieC7=\"MNOPQRST\"; path=/", + "TestCookieC8=\"UVWXYZ\"; path=/", + }, values); + } + + [Fact] + public void GetLargeChunkedCookie_Reassembled() + { + HttpContext context = new DefaultHttpContext(); + context.Request.Headers.AppendValues("Cookie", + "TestCookie=chunks:7", + "TestCookieC1=abcdefghi", + "TestCookieC2=jklmnopqr", + "TestCookieC3=stuvwxyz0", + "TestCookieC4=123456789", + "TestCookieC5=ABCDEFGHI", + "TestCookieC6=JKLMNOPQR", + "TestCookieC7=STUVWXYZ"); + + string result = new ChunkingCookieManager().GetRequestCookie(context, "TestCookie"); + string testString = "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + Assert.Equal(testString, result); + } + + [Fact] + public void GetLargeChunkedCookieWithQuotes_Reassembled() + { + HttpContext context = new DefaultHttpContext(); + context.Request.Headers.AppendValues("Cookie", + "TestCookie=chunks:7", + "TestCookieC1=\"abcdefghi\"", + "TestCookieC2=\"jklmnopqr\"", + "TestCookieC3=\"stuvwxyz0\"", + "TestCookieC4=\"123456789\"", + "TestCookieC5=\"ABCDEFGHI\"", + "TestCookieC6=\"JKLMNOPQR\"", + "TestCookieC7=\"STUVWXYZ\""); + + string result = new ChunkingCookieManager().GetRequestCookie(context, "TestCookie"); + string testString = "\"abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ\""; + Assert.Equal(testString, result); + } + + [Fact] + public void GetLargeChunkedCookieWithMissingChunk_ThrowingEnabled_Throws() + { + HttpContext context = new DefaultHttpContext(); + context.Request.Headers.AppendValues("Cookie", + "TestCookie=chunks:7", + "TestCookieC1=abcdefghi", + // Missing chunk "TestCookieC2=jklmnopqr", + "TestCookieC3=stuvwxyz0", + "TestCookieC4=123456789", + "TestCookieC5=ABCDEFGHI", + "TestCookieC6=JKLMNOPQR", + "TestCookieC7=STUVWXYZ"); + + Assert.Throws(() => new ChunkingCookieManager().GetRequestCookie(context, "TestCookie")); + } + + [Fact] + public void GetLargeChunkedCookieWithMissingChunk_ThrowingDisabled_NotReassembled() + { + HttpContext context = new DefaultHttpContext(); + context.Request.Headers.AppendValues("Cookie", + "TestCookie=chunks:7", + "TestCookieC1=abcdefghi", + // Missing chunk "TestCookieC2=jklmnopqr", + "TestCookieC3=stuvwxyz0", + "TestCookieC4=123456789", + "TestCookieC5=ABCDEFGHI", + "TestCookieC6=JKLMNOPQR", + "TestCookieC7=STUVWXYZ"); + + string result = new ChunkingCookieManager() { ThrowForPartialCookies = false }.GetRequestCookie(context, "TestCookie"); + string testString = "chunks:7"; + Assert.Equal(testString, result); + } + + [Fact] + public void DeleteChunkedCookieWithOptions_AllDeleted() + { + HttpContext context = new DefaultHttpContext(); + context.Request.Headers.AppendValues("Cookie", "TestCookie=chunks:7"); + + new ChunkingCookieManager().DeleteCookie(context, "TestCookie", new CookieOptions() { Domain = "foo.com" }); + var cookies = context.Response.Headers.GetValues("Set-Cookie"); + Assert.Equal(8, cookies.Count); + Assert.Equal(new[] + { + "TestCookie=; domain=foo.com; path=/; expires=Thu, 01-Jan-1970 00:00:00 GMT", + "TestCookieC1=; domain=foo.com; path=/; expires=Thu, 01-Jan-1970 00:00:00 GMT", + "TestCookieC2=; domain=foo.com; path=/; expires=Thu, 01-Jan-1970 00:00:00 GMT", + "TestCookieC3=; domain=foo.com; path=/; expires=Thu, 01-Jan-1970 00:00:00 GMT", + "TestCookieC4=; domain=foo.com; path=/; expires=Thu, 01-Jan-1970 00:00:00 GMT", + "TestCookieC5=; domain=foo.com; path=/; expires=Thu, 01-Jan-1970 00:00:00 GMT", + "TestCookieC6=; domain=foo.com; path=/; expires=Thu, 01-Jan-1970 00:00:00 GMT", + "TestCookieC7=; domain=foo.com; path=/; expires=Thu, 01-Jan-1970 00:00:00 GMT", + }, cookies); + } + } +} From d6b82b87993489d5be1b48d6f46ee6d5cc034a9e Mon Sep 17 00:00:00 2001 From: Chris Ross Date: Tue, 9 Sep 2014 15:25:39 -0700 Subject: [PATCH 049/216] #32 - Port cookie auth session store from Katana. Add MemoryCache sample. --- Security.sln | 13 +++++ samples/CookieSample/project.json | 4 +- .../CookieSessionSample.kproj | 32 +++++++++++ .../MemoryCacheSessionStore.cs | 56 +++++++++++++++++++ samples/CookieSessionSample/Startup.cs | 41 ++++++++++++++ samples/CookieSessionSample/project.json | 37 ++++++++++++ .../CookieAuthenticationHandler.cs | 56 ++++++++++++++++++- .../CookieAuthenticationOptions.cs | 6 ++ .../IAuthenticationSessionStore.cs | 43 ++++++++++++++ 9 files changed, 283 insertions(+), 5 deletions(-) create mode 100644 samples/CookieSessionSample/CookieSessionSample.kproj create mode 100644 samples/CookieSessionSample/MemoryCacheSessionStore.cs create mode 100644 samples/CookieSessionSample/Startup.cs create mode 100644 samples/CookieSessionSample/project.json create mode 100644 src/Microsoft.AspNet.Security.Cookies/Infrastructure/IAuthenticationSessionStore.cs diff --git a/Security.sln b/Security.sln index c9951b0dd..2cc23038e 100644 --- a/Security.sln +++ b/Security.sln @@ -34,6 +34,8 @@ Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNet.Security.M EndProject Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNet.Security.OAuth", "src\Microsoft.AspNet.Security.OAuth\Microsoft.AspNet.Security.OAuth.kproj", "{4A636011-68EE-4CE5-836D-EA8E13CF71E4}" EndProject +Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "CookieSessionSample", "samples\CookieSessionSample\CookieSessionSample.kproj", "{19711880-46DA-4A26-9E0F-9B2E41D27651}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -144,6 +146,16 @@ Global {4A636011-68EE-4CE5-836D-EA8E13CF71E4}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU {4A636011-68EE-4CE5-836D-EA8E13CF71E4}.Release|Mixed Platforms.Build.0 = Release|Any CPU {4A636011-68EE-4CE5-836D-EA8E13CF71E4}.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|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|x86.ActiveCfg = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -159,5 +171,6 @@ Global {C96B77EA-4078-4C31-BDB2-878F11C5E061} = {4D2B6A51-2F9F-44F5-8131-EA5CAC053652} {1FCF26C2-A3C7-4308-B698-4AFC3560BC0C} = {4D2B6A51-2F9F-44F5-8131-EA5CAC053652} {4A636011-68EE-4CE5-836D-EA8E13CF71E4} = {4D2B6A51-2F9F-44F5-8131-EA5CAC053652} + {19711880-46DA-4A26-9E0F-9B2E41D27651} = {F8C0AA27-F3FB-4286-8E4C-47EF86B539FF} EndGlobalSection EndGlobal diff --git a/samples/CookieSample/project.json b/samples/CookieSample/project.json index c8eabcb68..405e3ba0d 100644 --- a/samples/CookieSample/project.json +++ b/samples/CookieSample/project.json @@ -6,8 +6,8 @@ "Microsoft.AspNet.HttpFeature": "1.0.0-*", "Microsoft.AspNet.PipelineCore": "1.0.0-*", "Microsoft.AspNet.RequestContainer": "1.0.0-*", - "Microsoft.AspNet.Security": "", - "Microsoft.AspNet.Security.Cookies": "", + "Microsoft.AspNet.Security": "1.0.0-*", + "Microsoft.AspNet.Security.Cookies": "1.0.0-*", "Microsoft.AspNet.Server.WebListener": "1.0.0-*", "Microsoft.Framework.DependencyInjection": "1.0.0-*" }, diff --git a/samples/CookieSessionSample/CookieSessionSample.kproj b/samples/CookieSessionSample/CookieSessionSample.kproj new file mode 100644 index 000000000..951ff1cc5 --- /dev/null +++ b/samples/CookieSessionSample/CookieSessionSample.kproj @@ -0,0 +1,32 @@ + + + + 12.0 + $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) + + + Debug + AnyCPU + + + + + 19711880-46da-4a26-9e0f-9b2e41d27651 + Library + CookieSessionSample + + + + ConsoleDebugger + + + WebDebugger + + + + + + 2.0 + + + \ No newline at end of file diff --git a/samples/CookieSessionSample/MemoryCacheSessionStore.cs b/samples/CookieSessionSample/MemoryCacheSessionStore.cs new file mode 100644 index 000000000..07adddd04 --- /dev/null +++ b/samples/CookieSessionSample/MemoryCacheSessionStore.cs @@ -0,0 +1,56 @@ +using System; +using System.Threading.Tasks; +using Microsoft.AspNet.MemoryCache; +using Microsoft.AspNet.Security; +using Microsoft.AspNet.Security.Cookies.Infrastructure; + +namespace CookieSessionSample +{ + public class MemoryCacheSessionStore : IAuthenticationSessionStore + { + private const string KeyPrefix = "AuthSessionStore-"; + private IMemoryCache _cache; + + public MemoryCacheSessionStore() + { + _cache = new MemoryCache(); + } + + public async Task StoreAsync(AuthenticationTicket ticket) + { + var guid = Guid.NewGuid(); + var key = KeyPrefix + guid.ToString(); + await RenewAsync(key, ticket); + return key; + } + + public Task RenewAsync(string key, AuthenticationTicket ticket) + { + _cache.Set(key, ticket, context => + { + var expiresUtc = ticket.Properties.ExpiresUtc; + if (expiresUtc.HasValue) + { + context.SetAbsoluteExpiration(expiresUtc.Value); + } + context.SetSlidingExpiraiton(TimeSpan.FromHours(1)); // TODO: configurable. + + return (AuthenticationTicket)context.State; + }); + return Task.FromResult(0); + } + + public Task RetrieveAsync(string key) + { + AuthenticationTicket ticket; + _cache.TryGetValue(key, out ticket); + return Task.FromResult(ticket); + } + + public Task RemoveAsync(string key) + { + _cache.Remove(key); + return Task.FromResult(0); + } + } +} diff --git a/samples/CookieSessionSample/Startup.cs b/samples/CookieSessionSample/Startup.cs new file mode 100644 index 000000000..c5359a05f --- /dev/null +++ b/samples/CookieSessionSample/Startup.cs @@ -0,0 +1,41 @@ +using System.Collections.Generic; +using System.Security.Claims; +using Microsoft.AspNet.Builder; +using Microsoft.AspNet.Http; +using Microsoft.AspNet.Security.Cookies; + +namespace CookieSessionSample +{ + public class Startup + { + public void Configure(IBuilder app) + { + app.UseCookieAuthentication(new CookieAuthenticationOptions() + { + SessionStore = new MemoryCacheSessionStore(), + }); + + app.Run(async context => + { + if (context.User == null || !context.User.Identity.IsAuthenticated) + { + // Make a large identity + var claims = new List(1001); + claims.Add(new Claim("name", "bob")); + for (int i = 0; i < 1000; i++) + { + claims.Add(new Claim(ClaimTypes.Role, "SomeRandomGroup" + i, ClaimValueTypes.String, "IssuedByBob", "OriginalIssuerJoe")); + } + context.Response.SignIn(new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationType)); + + context.Response.ContentType = "text/plain"; + await context.Response.WriteAsync("Hello First timer"); + return; + } + + context.Response.ContentType = "text/plain"; + await context.Response.WriteAsync("Hello old timer"); + }); + } + } +} \ No newline at end of file diff --git a/samples/CookieSessionSample/project.json b/samples/CookieSessionSample/project.json new file mode 100644 index 000000000..729917712 --- /dev/null +++ b/samples/CookieSessionSample/project.json @@ -0,0 +1,37 @@ +{ + "dependencies": { + "Microsoft.AspNet.FeatureModel": "1.0.0-*", + "Microsoft.AspNet.Hosting": "1.0.0-*", + "Microsoft.AspNet.Http": "1.0.0-*", + "Microsoft.AspNet.HttpFeature": "1.0.0-*", + "Microsoft.AspNet.MemoryCache": "1.0.0-*", + "Microsoft.AspNet.PipelineCore": "1.0.0-*", + "Microsoft.AspNet.RequestContainer": "1.0.0-*", + "Microsoft.AspNet.Security": "1.0.0-*", + "Microsoft.AspNet.Security.Cookies": "1.0.0-*", + "Microsoft.AspNet.Server.WebListener": "1.0.0-*", + "Microsoft.Framework.DependencyInjection": "1.0.0-*" + }, + "commands": { "web": "Microsoft.AspNet.Hosting server=Microsoft.AspNet.Server.WebListener server.urls=http://localhost:12345" }, + "frameworks": { + "aspnet50": { + }, + "aspnetcore50": { + "dependencies": { + "System.Collections": "4.0.10.0", + "System.Console": "4.0.0.0", + "System.Diagnostics.Debug": "4.0.10.0", + "System.Diagnostics.Tools": "4.0.0.0", + "System.Globalization": "4.0.10.0", + "System.IO": "4.0.10.0", + "System.Linq": "4.0.0.0", + "System.Reflection": "4.0.10.0", + "System.Resources.ResourceManager": "4.0.0.0", + "System.Runtime": "4.0.20.0", + "System.Runtime.Extensions": "4.0.10.0", + "System.Runtime.InteropServices": "4.0.20.0", + "System.Threading.Tasks": "4.0.10.0" + } + } + } +} diff --git a/src/Microsoft.AspNet.Security.Cookies/CookieAuthenticationHandler.cs b/src/Microsoft.AspNet.Security.Cookies/CookieAuthenticationHandler.cs index 23f66b6c5..317c27d21 100644 --- a/src/Microsoft.AspNet.Security.Cookies/CookieAuthenticationHandler.cs +++ b/src/Microsoft.AspNet.Security.Cookies/CookieAuthenticationHandler.cs @@ -3,6 +3,8 @@ using System; +using System.Linq; +using System.Security.Claims; using System.Threading.Tasks; using Microsoft.AspNet.Http; using Microsoft.AspNet.Http.Security; @@ -18,12 +20,14 @@ internal class CookieAuthenticationHandler : AuthenticationHandler AuthenticateCoreAsync() return null; } + if (Options.SessionStore != null) + { + Claim claim = ticket.Identity.Claims.FirstOrDefault(c => c.Type.Equals(SessionIdClaim)); + if (claim == null) + { + _logger.WriteWarning(@"SessoinId missing"); + return null; + } + _sessionKey = claim.Value; + ticket = await Options.SessionStore.RetrieveAsync(_sessionKey); + if (ticket == null) + { + _logger.WriteWarning(@"Identity missing in session store"); + return null; + } + } + DateTimeOffset currentUtc = Options.SystemClock.UtcNow; DateTimeOffset? issuedUtc = ticket.Properties.IssuedUtc; DateTimeOffset? expiresUtc = ticket.Properties.ExpiresUtc; if (expiresUtc != null && expiresUtc.Value < currentUtc) { + if (Options.SessionStore != null) + { + await Options.SessionStore.RemoveAsync(_sessionKey); + } return null; } @@ -95,6 +120,7 @@ protected override async Task ApplyResponseGrantAsync() if (shouldSignin || shouldSignout || _shouldRenew) { + AuthenticationTicket model = await AuthenticateAsync(); var cookieOptions = new CookieOptions { Domain = Options.CookieDomain, @@ -144,7 +170,19 @@ protected override async Task ApplyResponseGrantAsync() context.CookieOptions.Expires = expiresUtc.ToUniversalTime().DateTime; } - var model = new AuthenticationTicket(context.Identity, context.Properties); + model = new AuthenticationTicket(context.Identity, context.Properties); + if (Options.SessionStore != null) + { + if (_sessionKey != null) + { + await Options.SessionStore.RemoveAsync(_sessionKey); + } + _sessionKey = await Options.SessionStore.StoreAsync(model); + ClaimsIdentity identity = new ClaimsIdentity( + new[] { new Claim(SessionIdClaim, _sessionKey) }, + Options.AuthenticationType); + model = new AuthenticationTicket(identity, null); + } string cookieValue = Options.TicketDataFormat.Protect(model); Options.CookieManager.AppendResponseCookie( @@ -155,6 +193,11 @@ protected override async Task ApplyResponseGrantAsync() } else if (shouldSignout) { + if (Options.SessionStore != null && _sessionKey != null) + { + await Options.SessionStore.RemoveAsync(_sessionKey); + } + var context = new CookieResponseSignOutContext( Context, Options, @@ -169,11 +212,18 @@ protected override async Task ApplyResponseGrantAsync() } else if (_shouldRenew) { - AuthenticationTicket model = await AuthenticateAsync(); - model.Properties.IssuedUtc = _renewIssuedUtc; model.Properties.ExpiresUtc = _renewExpiresUtc; + if (Options.SessionStore != null && _sessionKey != null) + { + await Options.SessionStore.RenewAsync(_sessionKey, model); + ClaimsIdentity identity = new ClaimsIdentity( + new[] { new Claim(SessionIdClaim, _sessionKey) }, + Options.AuthenticationType); + model = new AuthenticationTicket(identity, null); + } + string cookieValue = Options.TicketDataFormat.Protect(model); if (model.Properties.IsPersistent) diff --git a/src/Microsoft.AspNet.Security.Cookies/CookieAuthenticationOptions.cs b/src/Microsoft.AspNet.Security.Cookies/CookieAuthenticationOptions.cs index 0b6ef879e..c6373a0ec 100644 --- a/src/Microsoft.AspNet.Security.Cookies/CookieAuthenticationOptions.cs +++ b/src/Microsoft.AspNet.Security.Cookies/CookieAuthenticationOptions.cs @@ -143,5 +143,11 @@ public string CookieName /// ChunkingCookieManager will be used by default. /// public ICookieManager CookieManager { get; set; } + + /// + /// An optional container in which to store the identity across requests. When used, only a session identifier is sent + /// to the client. This can be used to mitigate potential problems with very large identities. + /// + public IAuthenticationSessionStore SessionStore { get; set; } } } diff --git a/src/Microsoft.AspNet.Security.Cookies/Infrastructure/IAuthenticationSessionStore.cs b/src/Microsoft.AspNet.Security.Cookies/Infrastructure/IAuthenticationSessionStore.cs new file mode 100644 index 000000000..9f449b098 --- /dev/null +++ b/src/Microsoft.AspNet.Security.Cookies/Infrastructure/IAuthenticationSessionStore.cs @@ -0,0 +1,43 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +using System.Threading.Tasks; + +namespace Microsoft.AspNet.Security.Cookies.Infrastructure +{ + /// + /// This provides an abstract storage mechanic to preserve identity information on the server + /// while only sending a simple identifier key to the client. This is most commonly used to mitigate + /// issues with serializing large identities into cookies. + /// + public interface IAuthenticationSessionStore + { + /// + /// Store the identity ticket and return the associated key. + /// + /// The identity information to store. + /// The key that can be used to retrieve the identity later. + Task StoreAsync(AuthenticationTicket ticket); + + /// + /// Tells the store that the given identity should be updated. + /// + /// + /// + /// + Task RenewAsync(string key, AuthenticationTicket ticket); + + /// + /// Retrieves an identity from the store for the given key. + /// + /// The key associated with the identity. + /// The identity associated with the given key, or if not found. + Task RetrieveAsync(string key); + + /// + /// Remove the identity associated with the given key. + /// + /// The key associated with the identity. + /// + Task RemoveAsync(string key); + } +} From 83bffe35421c2096155f345cb0dff5beb0c98050 Mon Sep 17 00:00:00 2001 From: Chris Ross Date: Tue, 9 Sep 2014 15:26:50 -0700 Subject: [PATCH 050/216] #32 - Port Cookies OnSignedIn notification from Katana. --- .../CookieAuthenticationHandler.cs | 21 +++++--- .../CookieAuthenticationNotifications.cs | 15 ++++++ .../CookieResponseSignedInContext.cs | 52 +++++++++++++++++++ .../ICookieAuthenticationNotifications.cs | 6 +++ 4 files changed, 88 insertions(+), 6 deletions(-) create mode 100644 src/Microsoft.AspNet.Security.Cookies/Notifications/CookieResponseSignedInContext.cs diff --git a/src/Microsoft.AspNet.Security.Cookies/CookieAuthenticationHandler.cs b/src/Microsoft.AspNet.Security.Cookies/CookieAuthenticationHandler.cs index 317c27d21..b83835aff 100644 --- a/src/Microsoft.AspNet.Security.Cookies/CookieAuthenticationHandler.cs +++ b/src/Microsoft.AspNet.Security.Cookies/CookieAuthenticationHandler.cs @@ -138,7 +138,7 @@ protected override async Task ApplyResponseGrantAsync() if (shouldSignin) { - var context = new CookieResponseSignInContext( + var signInContext = new CookieResponseSignInContext( Context, Options, Options.AuthenticationType, @@ -162,15 +162,15 @@ protected override async Task ApplyResponseGrantAsync() signin.Properties.ExpiresUtc = issuedUtc.Add(Options.ExpireTimeSpan); } - Options.Notifications.ResponseSignIn(context); + Options.Notifications.ResponseSignIn(signInContext); - if (context.Properties.IsPersistent) + if (signInContext.Properties.IsPersistent) { - DateTimeOffset expiresUtc = context.Properties.ExpiresUtc ?? issuedUtc.Add(Options.ExpireTimeSpan); - context.CookieOptions.Expires = expiresUtc.ToUniversalTime().DateTime; + DateTimeOffset expiresUtc = signInContext.Properties.ExpiresUtc ?? issuedUtc.Add(Options.ExpireTimeSpan); + signInContext.CookieOptions.Expires = expiresUtc.ToUniversalTime().DateTime; } - model = new AuthenticationTicket(context.Identity, context.Properties); + model = new AuthenticationTicket(signInContext.Identity, signInContext.Properties); if (Options.SessionStore != null) { if (_sessionKey != null) @@ -190,6 +190,15 @@ protected override async Task ApplyResponseGrantAsync() Options.CookieName, cookieValue, cookieOptions); + + var signedInContext = new CookieResponseSignedInContext( + Context, + Options, + Options.AuthenticationType, + signInContext.Identity, + signInContext.Properties); + + Options.Notifications.ResponseSignedIn(signedInContext); } else if (shouldSignout) { diff --git a/src/Microsoft.AspNet.Security.Cookies/Notifications/CookieAuthenticationNotifications.cs b/src/Microsoft.AspNet.Security.Cookies/Notifications/CookieAuthenticationNotifications.cs index 79b7e5bd9..efa30c02e 100644 --- a/src/Microsoft.AspNet.Security.Cookies/Notifications/CookieAuthenticationNotifications.cs +++ b/src/Microsoft.AspNet.Security.Cookies/Notifications/CookieAuthenticationNotifications.cs @@ -21,6 +21,7 @@ public CookieAuthenticationNotifications() { OnValidateIdentity = context => Task.FromResult(0); OnResponseSignIn = context => { }; + OnResponseSignedIn = context => { }; OnResponseSignOut = context => { }; OnApplyRedirect = DefaultBehavior.ApplyRedirect; } @@ -35,6 +36,11 @@ public CookieAuthenticationNotifications() /// public Action OnResponseSignIn { get; set; } + /// + /// A delegate assigned to this property will be invoked when the related method is called + /// + public Action OnResponseSignedIn { get; set; } + /// /// A delegate assigned to this property will be invoked when the related method is called /// @@ -64,6 +70,15 @@ public virtual void ResponseSignIn(CookieResponseSignInContext context) OnResponseSignIn.Invoke(context); } + /// + /// Implements the interface method by invoking the related delegate method + /// + /// + public virtual void ResponseSignedIn(CookieResponseSignedInContext context) + { + OnResponseSignedIn.Invoke(context); + } + /// /// Implements the interface method by invoking the related delegate method /// diff --git a/src/Microsoft.AspNet.Security.Cookies/Notifications/CookieResponseSignedInContext.cs b/src/Microsoft.AspNet.Security.Cookies/Notifications/CookieResponseSignedInContext.cs new file mode 100644 index 000000000..3366fb9f7 --- /dev/null +++ b/src/Microsoft.AspNet.Security.Cookies/Notifications/CookieResponseSignedInContext.cs @@ -0,0 +1,52 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System.Security.Claims; +using Microsoft.AspNet.Http; +using Microsoft.AspNet.Http.Security; +using Microsoft.AspNet.Security.Notifications; + +namespace Microsoft.AspNet.Security.Cookies +{ + /// + /// Context object passed to the ICookieAuthenticationNotifications method ResponseSignedIn. + /// + public class CookieResponseSignedInContext : BaseContext + { + /// + /// Creates a new instance of the context object. + /// + /// The HTTP request context + /// The middleware options + /// Initializes AuthenticationType property + /// Initializes Identity property + /// Initializes Properties property + public CookieResponseSignedInContext( + HttpContext context, + CookieAuthenticationOptions options, + string authenticationType, + ClaimsIdentity identity, + AuthenticationProperties properties) + : base(context, options) + { + AuthenticationType = authenticationType; + Identity = identity; + Properties = properties; + } + + /// + /// The name of the AuthenticationType creating a cookie + /// + public string AuthenticationType { get; private set; } + + /// + /// Contains the claims that were converted into the outgoing cookie. + /// + public ClaimsIdentity Identity { get; private set; } + + /// + /// Contains the extra data that was contained in the outgoing cookie. + /// + public AuthenticationProperties Properties { get; private set; } + } +} diff --git a/src/Microsoft.AspNet.Security.Cookies/Notifications/ICookieAuthenticationNotifications.cs b/src/Microsoft.AspNet.Security.Cookies/Notifications/ICookieAuthenticationNotifications.cs index f97a4546e..046dcd153 100644 --- a/src/Microsoft.AspNet.Security.Cookies/Notifications/ICookieAuthenticationNotifications.cs +++ b/src/Microsoft.AspNet.Security.Cookies/Notifications/ICookieAuthenticationNotifications.cs @@ -26,6 +26,12 @@ public interface ICookieAuthenticationNotifications /// Contains information about the login session as well as the user . void ResponseSignIn(CookieResponseSignInContext context); + /// + /// Called when an endpoint has provided sign in information after it is converted into a cookie. + /// + /// Contains information about the login session as well as the user . + void ResponseSignedIn(CookieResponseSignedInContext context); + /// /// Called when a Challenge, SignIn, or SignOut causes a redirect in the cookie middleware /// From b10cda80a7b8f496d3c24b904e983dc662402776 Mon Sep 17 00:00:00 2001 From: Chris Ross Date: Tue, 9 Sep 2014 16:12:19 -0700 Subject: [PATCH 051/216] #32 - Port Cookies OnException notification from Katana. --- .../CookieAuthenticationHandler.cs | 167 +++++++++++------- .../CookieAuthenticationNotifications.cs | 15 ++ .../Notifications/CookieExceptionContext.cs | 83 +++++++++ .../ICookieAuthenticationNotifications.cs | 6 + 4 files changed, 209 insertions(+), 62 deletions(-) create mode 100644 src/Microsoft.AspNet.Security.Cookies/Notifications/CookieExceptionContext.cs diff --git a/src/Microsoft.AspNet.Security.Cookies/CookieAuthenticationHandler.cs b/src/Microsoft.AspNet.Security.Cookies/CookieAuthenticationHandler.cs index b83835aff..db5ea054c 100644 --- a/src/Microsoft.AspNet.Security.Cookies/CookieAuthenticationHandler.cs +++ b/src/Microsoft.AspNet.Security.Cookies/CookieAuthenticationHandler.cs @@ -41,69 +41,84 @@ protected override AuthenticationTicket AuthenticateCore() protected override async Task AuthenticateCoreAsync() { - string cookie = Options.CookieManager.GetRequestCookie(Context, Options.CookieName); - if (string.IsNullOrWhiteSpace(cookie)) + AuthenticationTicket ticket = null; + try { - return null; - } - - AuthenticationTicket ticket = Options.TicketDataFormat.Unprotect(cookie); - - if (ticket == null) - { - _logger.WriteWarning(@"Unprotect ticket failed"); - return null; - } - - if (Options.SessionStore != null) - { - Claim claim = ticket.Identity.Claims.FirstOrDefault(c => c.Type.Equals(SessionIdClaim)); - if (claim == null) + string cookie = Options.CookieManager.GetRequestCookie(Context, Options.CookieName); + if (string.IsNullOrWhiteSpace(cookie)) { - _logger.WriteWarning(@"SessoinId missing"); return null; } - _sessionKey = claim.Value; - ticket = await Options.SessionStore.RetrieveAsync(_sessionKey); + + ticket = Options.TicketDataFormat.Unprotect(cookie); + if (ticket == null) { - _logger.WriteWarning(@"Identity missing in session store"); + _logger.WriteWarning(@"Unprotect ticket failed"); return null; } - } - DateTimeOffset currentUtc = Options.SystemClock.UtcNow; - DateTimeOffset? issuedUtc = ticket.Properties.IssuedUtc; - DateTimeOffset? expiresUtc = ticket.Properties.ExpiresUtc; - - if (expiresUtc != null && expiresUtc.Value < currentUtc) - { if (Options.SessionStore != null) { - await Options.SessionStore.RemoveAsync(_sessionKey); + Claim claim = ticket.Identity.Claims.FirstOrDefault(c => c.Type.Equals(SessionIdClaim)); + if (claim == null) + { + _logger.WriteWarning(@"SessoinId missing"); + return null; + } + _sessionKey = claim.Value; + ticket = await Options.SessionStore.RetrieveAsync(_sessionKey); + if (ticket == null) + { + _logger.WriteWarning(@"Identity missing in session store"); + return null; + } } - return null; - } - if (issuedUtc != null && expiresUtc != null && Options.SlidingExpiration) - { - TimeSpan timeElapsed = currentUtc.Subtract(issuedUtc.Value); - TimeSpan timeRemaining = expiresUtc.Value.Subtract(currentUtc); + DateTimeOffset currentUtc = Options.SystemClock.UtcNow; + DateTimeOffset? issuedUtc = ticket.Properties.IssuedUtc; + DateTimeOffset? expiresUtc = ticket.Properties.ExpiresUtc; - if (timeRemaining < timeElapsed) + if (expiresUtc != null && expiresUtc.Value < currentUtc) { - _shouldRenew = true; - _renewIssuedUtc = currentUtc; - TimeSpan timeSpan = expiresUtc.Value.Subtract(issuedUtc.Value); - _renewExpiresUtc = currentUtc.Add(timeSpan); + if (Options.SessionStore != null) + { + await Options.SessionStore.RemoveAsync(_sessionKey); + } + return null; } - } - var context = new CookieValidateIdentityContext(Context, ticket, Options); + if (issuedUtc != null && expiresUtc != null && Options.SlidingExpiration) + { + TimeSpan timeElapsed = currentUtc.Subtract(issuedUtc.Value); + TimeSpan timeRemaining = expiresUtc.Value.Subtract(currentUtc); - await Options.Notifications.ValidateIdentity(context); + if (timeRemaining < timeElapsed) + { + _shouldRenew = true; + _renewIssuedUtc = currentUtc; + TimeSpan timeSpan = expiresUtc.Value.Subtract(issuedUtc.Value); + _renewExpiresUtc = currentUtc.Add(timeSpan); + } + } + + var context = new CookieValidateIdentityContext(Context, ticket, Options); + + await Options.Notifications.ValidateIdentity(context); - return new AuthenticationTicket(context.Identity, context.Properties); + return new AuthenticationTicket(context.Identity, context.Properties); + } + catch (Exception exception) + { + CookieExceptionContext exceptionContext = new CookieExceptionContext(Context, Options, + CookieExceptionContext.ExceptionLocation.Authenticate, exception, ticket); + Options.Notifications.Exception(exceptionContext); + if (exceptionContext.Rethrow) + { + throw; + } + return exceptionContext.Ticket; + } } protected override void ApplyResponseGrant() @@ -118,9 +133,14 @@ protected override async Task ApplyResponseGrantAsync() var signout = SignOutContext; bool shouldSignout = signout != null; - if (shouldSignin || shouldSignout || _shouldRenew) + if (!(shouldSignin || shouldSignout || _shouldRenew)) + { + return; + } + + AuthenticationTicket model = await AuthenticateAsync(); + try { - AuthenticationTicket model = await AuthenticateAsync(); var cookieOptions = new CookieOptions { Domain = Options.CookieDomain, @@ -274,6 +294,16 @@ protected override async Task ApplyResponseGrantAsync() } } } + catch (Exception exception) + { + CookieExceptionContext exceptionContext = new CookieExceptionContext(Context, Options, + CookieExceptionContext.ExceptionLocation.ApplyResponseGrant, exception, model); + Options.Notifications.Exception(exceptionContext); + if (exceptionContext.Rethrow) + { + throw; + } + } } private static bool IsHostRelative(string path) @@ -308,24 +338,37 @@ protected override void ApplyResponseChallenge() loginUri = new AuthenticationProperties(ChallengeContext.Properties).RedirectUri; } - if (string.IsNullOrWhiteSpace(loginUri)) + try { - string currentUri = - Request.PathBase + - Request.Path + - Request.QueryString; - - loginUri = - Request.Scheme + - "://" + - Request.Host + - Request.PathBase + - Options.LoginPath + - new QueryString(Options.ReturnUrlParameter, currentUri); - } + if (string.IsNullOrWhiteSpace(loginUri)) + { + string currentUri = + Request.PathBase + + Request.Path + + Request.QueryString; + + loginUri = + Request.Scheme + + "://" + + Request.Host + + Request.PathBase + + Options.LoginPath + + new QueryString(Options.ReturnUrlParameter, currentUri); + } - var redirectContext = new CookieApplyRedirectContext(Context, Options, loginUri); - Options.Notifications.ApplyRedirect(redirectContext); + var redirectContext = new CookieApplyRedirectContext(Context, Options, loginUri); + Options.Notifications.ApplyRedirect(redirectContext); + } + catch (Exception exception) + { + CookieExceptionContext exceptionContext = new CookieExceptionContext(Context, Options, + CookieExceptionContext.ExceptionLocation.ApplyResponseChallenge, exception, ticket: null); + Options.Notifications.Exception(exceptionContext); + if (exceptionContext.Rethrow) + { + throw; + } + } } } } diff --git a/src/Microsoft.AspNet.Security.Cookies/Notifications/CookieAuthenticationNotifications.cs b/src/Microsoft.AspNet.Security.Cookies/Notifications/CookieAuthenticationNotifications.cs index efa30c02e..e378a08c1 100644 --- a/src/Microsoft.AspNet.Security.Cookies/Notifications/CookieAuthenticationNotifications.cs +++ b/src/Microsoft.AspNet.Security.Cookies/Notifications/CookieAuthenticationNotifications.cs @@ -24,6 +24,7 @@ public CookieAuthenticationNotifications() OnResponseSignedIn = context => { }; OnResponseSignOut = context => { }; OnApplyRedirect = DefaultBehavior.ApplyRedirect; + OnException = context => { }; } /// @@ -51,6 +52,11 @@ public CookieAuthenticationNotifications() /// public Action OnApplyRedirect { get; set; } + /// + /// A delegate assigned to this property will be invoked when the related method is called + /// + public Action OnException { get; set; } + /// /// Implements the interface method by invoking the related delegate method /// @@ -96,5 +102,14 @@ public void ApplyRedirect(CookieApplyRedirectContext context) { OnApplyRedirect.Invoke(context); } + + /// + /// Implements the interface method by invoking the related delegate method + /// + /// Contains information about the event + public virtual void Exception(CookieExceptionContext context) + { + OnException.Invoke(context); + } } } diff --git a/src/Microsoft.AspNet.Security.Cookies/Notifications/CookieExceptionContext.cs b/src/Microsoft.AspNet.Security.Cookies/Notifications/CookieExceptionContext.cs new file mode 100644 index 000000000..e8e4fc80b --- /dev/null +++ b/src/Microsoft.AspNet.Security.Cookies/Notifications/CookieExceptionContext.cs @@ -0,0 +1,83 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Diagnostics.CodeAnalysis; +using Microsoft.AspNet.Http; +using Microsoft.AspNet.Security.Notifications; + +namespace Microsoft.AspNet.Security.Cookies +{ + /// + /// Context object passed to the ICookieAuthenticationProvider method Exception. + /// + public class CookieExceptionContext : BaseContext + { + /// + /// Creates a new instance of the context object. + /// + /// The HTTP request context + /// The middleware options + /// The location of the exception + /// The exception thrown. + /// The current ticket, if any. + public CookieExceptionContext( + HttpContext context, + CookieAuthenticationOptions options, + ExceptionLocation location, + Exception exception, + AuthenticationTicket ticket) + : base(context, options) + { + Location = location; + Exception = exception; + Rethrow = true; + Ticket = ticket; + } + + /// + /// The code paths where exceptions may be reported. + /// + [SuppressMessage("Microsoft.Design", "CA1034:NestedTypesShouldNotBeVisible", Scope = "type", + Target = "Microsoft.Owin.Security.Cookies.CookieExceptionContext+ExceptionLocation", Justification = "It is a directly related option.")] + public enum ExceptionLocation + { + /// + /// The exception was reported in the Authenticate code path. + /// + Authenticate, + + /// + /// The exception was reported in the ApplyResponseGrant code path, during sign-in, sign-out, or refresh. + /// + ApplyResponseGrant, + + /// + /// The exception was reported in the ApplyResponseChallenge code path, during redirect generation. + /// + ApplyResponseChallenge, + } + + /// + /// The code path the exception occurred in. + /// + public ExceptionLocation Location { get; private set; } + + /// + /// The exception thrown. + /// + public Exception Exception { get; private set; } + + /// + /// True if the exception should be re-thrown (default), false if it should be suppressed. + /// + public bool Rethrow { get; set; } + + /// + /// The current authentication ticket, if any. + /// In the AuthenticateAsync code path, if the given exception is not re-thrown then this ticket + /// will be returned to the application. The ticket may be replaced if needed. + /// + public AuthenticationTicket Ticket { get; set; } + } +} diff --git a/src/Microsoft.AspNet.Security.Cookies/Notifications/ICookieAuthenticationNotifications.cs b/src/Microsoft.AspNet.Security.Cookies/Notifications/ICookieAuthenticationNotifications.cs index 046dcd153..b6ced343f 100644 --- a/src/Microsoft.AspNet.Security.Cookies/Notifications/ICookieAuthenticationNotifications.cs +++ b/src/Microsoft.AspNet.Security.Cookies/Notifications/ICookieAuthenticationNotifications.cs @@ -43,5 +43,11 @@ public interface ICookieAuthenticationNotifications /// /// Contains information about the login session as well as information about the authentication cookie. void ResponseSignOut(CookieResponseSignOutContext context); + + /// + /// Called when an exception occurs during request or response processing. + /// + /// Contains information about the exception that occurred + void Exception(CookieExceptionContext context); } } From a9e40ac895cadf4bea118c1e6eee69d1434db1cb Mon Sep 17 00:00:00 2001 From: Chris Ross Date: Tue, 9 Sep 2014 16:17:46 -0700 Subject: [PATCH 052/216] Properly delete the correlation cookie. See Katana #230. --- .../Infrastructure/AuthenticationHandler.cs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/Microsoft.AspNet.Security/Infrastructure/AuthenticationHandler.cs b/src/Microsoft.AspNet.Security/Infrastructure/AuthenticationHandler.cs index 7970caa3a..f7e5adc34 100644 --- a/src/Microsoft.AspNet.Security/Infrastructure/AuthenticationHandler.cs +++ b/src/Microsoft.AspNet.Security/Infrastructure/AuthenticationHandler.cs @@ -362,7 +362,12 @@ protected bool ValidateCorrelationId([NotNull] AuthenticationProperties properti return false; } - Response.Cookies.Delete(correlationKey); + var cookieOptions = new CookieOptions + { + HttpOnly = true, + Secure = Request.IsSecure + }; + Response.Cookies.Delete(correlationKey, cookieOptions); string correlationExtra; if (!properties.Dictionary.TryGetValue( From f258724cbd355a8097c88bf87eeb056ede378609 Mon Sep 17 00:00:00 2001 From: Chris Ross Date: Tue, 9 Sep 2014 16:38:06 -0700 Subject: [PATCH 053/216] #32 - Honor AuthenticationProperties.AllowRefresh. --- .../CookieAuthenticationHandler.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Microsoft.AspNet.Security.Cookies/CookieAuthenticationHandler.cs b/src/Microsoft.AspNet.Security.Cookies/CookieAuthenticationHandler.cs index db5ea054c..45ee68599 100644 --- a/src/Microsoft.AspNet.Security.Cookies/CookieAuthenticationHandler.cs +++ b/src/Microsoft.AspNet.Security.Cookies/CookieAuthenticationHandler.cs @@ -88,7 +88,8 @@ protected override async Task AuthenticateCoreAsync() return null; } - if (issuedUtc != null && expiresUtc != null && Options.SlidingExpiration) + bool allowRefresh = ticket.Properties.AllowRefresh ?? true; + if (issuedUtc != null && expiresUtc != null && Options.SlidingExpiration && allowRefresh) { TimeSpan timeElapsed = currentUtc.Subtract(issuedUtc.Value); TimeSpan timeRemaining = expiresUtc.Value.Subtract(currentUtc); From 55f8b9d41ddabaf7158e41b3bdfceeee96f3cfbc Mon Sep 17 00:00:00 2001 From: Chris Ross Date: Fri, 12 Sep 2014 14:32:35 -0700 Subject: [PATCH 054/216] Rebase. --- samples/CookieSessionSample/Startup.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/CookieSessionSample/Startup.cs b/samples/CookieSessionSample/Startup.cs index c5359a05f..32721afb0 100644 --- a/samples/CookieSessionSample/Startup.cs +++ b/samples/CookieSessionSample/Startup.cs @@ -8,7 +8,7 @@ namespace CookieSessionSample { public class Startup { - public void Configure(IBuilder app) + public void Configure(IApplicationBuilder app) { app.UseCookieAuthentication(new CookieAuthenticationOptions() { From 07b3fe213595ab99c3e74919c71b496311bac560 Mon Sep 17 00:00:00 2001 From: Chris Ross Date: Fri, 12 Sep 2014 14:42:55 -0700 Subject: [PATCH 055/216] #32 - Port comment and flow cleanup from Katana. --- .../CookieAuthenticationHandler.cs | 4 ++-- .../Notifications/CookieAuthenticationNotifications.cs | 4 ++-- .../Notifications/CookieResponseSignOutContext.cs | 2 +- .../Notifications/ICookieAuthenticationNotifications.cs | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Microsoft.AspNet.Security.Cookies/CookieAuthenticationHandler.cs b/src/Microsoft.AspNet.Security.Cookies/CookieAuthenticationHandler.cs index 45ee68599..1a2b7eeb8 100644 --- a/src/Microsoft.AspNet.Security.Cookies/CookieAuthenticationHandler.cs +++ b/src/Microsoft.AspNet.Security.Cookies/CookieAuthenticationHandler.cs @@ -210,7 +210,7 @@ protected override async Task ApplyResponseGrantAsync() Context, Options.CookieName, cookieValue, - cookieOptions); + signInContext.CookieOptions); var signedInContext = new CookieResponseSignedInContext( Context, @@ -238,7 +238,7 @@ protected override async Task ApplyResponseGrantAsync() Options.CookieManager.DeleteCookie( Context, Options.CookieName, - cookieOptions); + context.CookieOptions); } else if (_shouldRenew) { diff --git a/src/Microsoft.AspNet.Security.Cookies/Notifications/CookieAuthenticationNotifications.cs b/src/Microsoft.AspNet.Security.Cookies/Notifications/CookieAuthenticationNotifications.cs index e378a08c1..c38489ed8 100644 --- a/src/Microsoft.AspNet.Security.Cookies/Notifications/CookieAuthenticationNotifications.cs +++ b/src/Microsoft.AspNet.Security.Cookies/Notifications/CookieAuthenticationNotifications.cs @@ -95,10 +95,10 @@ public virtual void ResponseSignOut(CookieResponseSignOutContext context) } /// - /// Called when a Challenge, SignIn, or SignOut causes a redirect in the cookie middleware + /// Implements the interface method by invoking the related delegate method /// /// Contains information about the event - public void ApplyRedirect(CookieApplyRedirectContext context) + public virtual void ApplyRedirect(CookieApplyRedirectContext context) { OnApplyRedirect.Invoke(context); } diff --git a/src/Microsoft.AspNet.Security.Cookies/Notifications/CookieResponseSignOutContext.cs b/src/Microsoft.AspNet.Security.Cookies/Notifications/CookieResponseSignOutContext.cs index b484b7436..a7cf4129a 100644 --- a/src/Microsoft.AspNet.Security.Cookies/Notifications/CookieResponseSignOutContext.cs +++ b/src/Microsoft.AspNet.Security.Cookies/Notifications/CookieResponseSignOutContext.cs @@ -26,7 +26,7 @@ public CookieResponseSignOutContext(HttpContext context, CookieAuthenticationOpt /// /// The options for creating the outgoing cookie. - /// May be replace or altered during the ResponseSignIn call. + /// May be replace or altered during the ResponseSignOut call. /// public CookieOptions CookieOptions { diff --git a/src/Microsoft.AspNet.Security.Cookies/Notifications/ICookieAuthenticationNotifications.cs b/src/Microsoft.AspNet.Security.Cookies/Notifications/ICookieAuthenticationNotifications.cs index b6ced343f..edfb6b69c 100644 --- a/src/Microsoft.AspNet.Security.Cookies/Notifications/ICookieAuthenticationNotifications.cs +++ b/src/Microsoft.AspNet.Security.Cookies/Notifications/ICookieAuthenticationNotifications.cs @@ -39,7 +39,7 @@ public interface ICookieAuthenticationNotifications void ApplyRedirect(CookieApplyRedirectContext context); /// - /// + /// Called during the sign-out flow to augment the cookie cleanup process. /// /// Contains information about the login session as well as information about the authentication cookie. void ResponseSignOut(CookieResponseSignOutContext context); From 35ad3ec7bb5cdbd7091c6fbcf912f25131e65d7d Mon Sep 17 00:00:00 2001 From: Chris Ross Date: Mon, 15 Sep 2014 09:35:55 -0700 Subject: [PATCH 056/216] Code cleanup. --- .../MemoryCacheSessionStore.cs | 4 +- samples/CookieSessionSample/Startup.cs | 2 +- samples/CookieSessionSample/project.json | 2 +- .../CookieAuthenticationHandler.cs | 2 +- .../CookieAuthenticationMiddleware.cs | 1 - .../Infrastructure/ChunkingCookieManager.cs | 120 +++++++----------- 6 files changed, 54 insertions(+), 77 deletions(-) diff --git a/samples/CookieSessionSample/MemoryCacheSessionStore.cs b/samples/CookieSessionSample/MemoryCacheSessionStore.cs index 07adddd04..e452683d4 100644 --- a/samples/CookieSessionSample/MemoryCacheSessionStore.cs +++ b/samples/CookieSessionSample/MemoryCacheSessionStore.cs @@ -1,8 +1,8 @@ using System; using System.Threading.Tasks; -using Microsoft.AspNet.MemoryCache; using Microsoft.AspNet.Security; using Microsoft.AspNet.Security.Cookies.Infrastructure; +using Microsoft.Framework.Cache.Memory; namespace CookieSessionSample { @@ -33,7 +33,7 @@ public Task RenewAsync(string key, AuthenticationTicket ticket) { context.SetAbsoluteExpiration(expiresUtc.Value); } - context.SetSlidingExpiraiton(TimeSpan.FromHours(1)); // TODO: configurable. + context.SetSlidingExpiration(TimeSpan.FromHours(1)); // TODO: configurable. return (AuthenticationTicket)context.State; }); diff --git a/samples/CookieSessionSample/Startup.cs b/samples/CookieSessionSample/Startup.cs index 32721afb0..890e63116 100644 --- a/samples/CookieSessionSample/Startup.cs +++ b/samples/CookieSessionSample/Startup.cs @@ -17,7 +17,7 @@ public void Configure(IApplicationBuilder app) app.Run(async context => { - if (context.User == null || !context.User.Identity.IsAuthenticated) + if (context.User.Identity == null || !context.User.Identity.IsAuthenticated) { // Make a large identity var claims = new List(1001); diff --git a/samples/CookieSessionSample/project.json b/samples/CookieSessionSample/project.json index 729917712..c5aca5588 100644 --- a/samples/CookieSessionSample/project.json +++ b/samples/CookieSessionSample/project.json @@ -4,12 +4,12 @@ "Microsoft.AspNet.Hosting": "1.0.0-*", "Microsoft.AspNet.Http": "1.0.0-*", "Microsoft.AspNet.HttpFeature": "1.0.0-*", - "Microsoft.AspNet.MemoryCache": "1.0.0-*", "Microsoft.AspNet.PipelineCore": "1.0.0-*", "Microsoft.AspNet.RequestContainer": "1.0.0-*", "Microsoft.AspNet.Security": "1.0.0-*", "Microsoft.AspNet.Security.Cookies": "1.0.0-*", "Microsoft.AspNet.Server.WebListener": "1.0.0-*", + "Microsoft.Framework.Cache.Memory": "1.0.0-*", "Microsoft.Framework.DependencyInjection": "1.0.0-*" }, "commands": { "web": "Microsoft.AspNet.Hosting server=Microsoft.AspNet.Server.WebListener server.urls=http://localhost:12345" }, diff --git a/src/Microsoft.AspNet.Security.Cookies/CookieAuthenticationHandler.cs b/src/Microsoft.AspNet.Security.Cookies/CookieAuthenticationHandler.cs index 1a2b7eeb8..4a43b58be 100644 --- a/src/Microsoft.AspNet.Security.Cookies/CookieAuthenticationHandler.cs +++ b/src/Microsoft.AspNet.Security.Cookies/CookieAuthenticationHandler.cs @@ -63,7 +63,7 @@ protected override async Task AuthenticateCoreAsync() Claim claim = ticket.Identity.Claims.FirstOrDefault(c => c.Type.Equals(SessionIdClaim)); if (claim == null) { - _logger.WriteWarning(@"SessoinId missing"); + _logger.WriteWarning(@"SessionId missing"); return null; } _sessionKey = claim.Value; diff --git a/src/Microsoft.AspNet.Security.Cookies/CookieAuthenticationMiddleware.cs b/src/Microsoft.AspNet.Security.Cookies/CookieAuthenticationMiddleware.cs index 1349ccade..92ab1b122 100644 --- a/src/Microsoft.AspNet.Security.Cookies/CookieAuthenticationMiddleware.cs +++ b/src/Microsoft.AspNet.Security.Cookies/CookieAuthenticationMiddleware.cs @@ -4,7 +4,6 @@ using System; using Microsoft.AspNet.Builder; -using Microsoft.AspNet.Http; using Microsoft.AspNet.Security.Cookies.Infrastructure; using Microsoft.AspNet.Security.DataHandler; using Microsoft.AspNet.Security.DataProtection; diff --git a/src/Microsoft.AspNet.Security.Cookies/Infrastructure/ChunkingCookieManager.cs b/src/Microsoft.AspNet.Security.Cookies/Infrastructure/ChunkingCookieManager.cs index d5e48c198..f4d893bd5 100644 --- a/src/Microsoft.AspNet.Security.Cookies/Infrastructure/ChunkingCookieManager.cs +++ b/src/Microsoft.AspNet.Security.Cookies/Infrastructure/ChunkingCookieManager.cs @@ -17,6 +17,8 @@ public class ChunkingCookieManager : ICookieManager { public ChunkingCookieManager() { + // Lowest common denominator. Safari has the lowest known limit (4093), and we leave little extra just in case. + // See http://browsercookielimits.x64.me/. ChunkSize = 4090; ThrowForPartialCookies = true; } @@ -40,9 +42,8 @@ private static int ParseChunksCount(string value) { if (value != null && value.StartsWith("chunks:", StringComparison.Ordinal)) { - string chunksCountString = value.Substring("chunks:".Length); - int chunksCount; - if (int.TryParse(chunksCountString, NumberStyles.None, CultureInfo.InvariantCulture, out chunksCount)) + var chunksCountString = value.Substring("chunks:".Length); + if (int.TryParse(chunksCountString, NumberStyles.None, CultureInfo.InvariantCulture, out var chunksCount)) { return chunksCount; } @@ -57,28 +58,23 @@ private static int ParseChunksCount(string value) /// /// /// The reassembled cookie, if any, or null. - public string GetRequestCookie(HttpContext context, string key) + public string GetRequestCookie([NotNull] HttpContext context, [NotNull] string key) { - if (context == null) - { - throw new ArgumentNullException("context"); - } - - IReadableStringCollection requestCookies = context.Request.Cookies; - string value = requestCookies[key]; - int chunksCount = ParseChunksCount(value); + var requestCookies = context.Request.Cookies; + var value = requestCookies[key]; + var chunksCount = ParseChunksCount(value); if (chunksCount > 0) { - bool quoted = false; - string[] chunks = new string[chunksCount]; - for (int chunkId = 1; chunkId <= chunksCount; chunkId++) + var quoted = false; + var chunks = new string[chunksCount]; + for (var chunkId = 1; chunkId <= chunksCount; chunkId++) { - string chunk = requestCookies[key + "C" + chunkId.ToString(CultureInfo.InvariantCulture)]; + var chunk = requestCookies[key + "C" + chunkId.ToString(CultureInfo.InvariantCulture)]; if (chunk == null) { if (ThrowForPartialCookies) { - int totalSize = 0; + var totalSize = 0; for (int i = 0; i < chunkId - 1; i++) { totalSize += chunks[i].Length; @@ -97,7 +93,7 @@ public string GetRequestCookie(HttpContext context, string key) } chunks[chunkId - 1] = chunk; } - string merged = string.Join(string.Empty, chunks); + var merged = string.Join(string.Empty, chunks); if (quoted) { merged = Quote(merged); @@ -119,25 +115,16 @@ public string GetRequestCookie(HttpContext context, string key) /// /// /// - public void AppendResponseCookie(HttpContext context, string key, string value, CookieOptions options) + public void AppendResponseCookie([NotNull] HttpContext context, [NotNull] string key, string value, [NotNull] CookieOptions options) { - if (context == null) - { - throw new ArgumentNullException("context"); - } - if (options == null) - { - throw new ArgumentNullException("options"); - } + var domainHasValue = !string.IsNullOrEmpty(options.Domain); + var pathHasValue = !string.IsNullOrEmpty(options.Path); + var expiresHasValue = options.Expires.HasValue; - bool domainHasValue = !string.IsNullOrEmpty(options.Domain); - bool pathHasValue = !string.IsNullOrEmpty(options.Path); - bool expiresHasValue = options.Expires.HasValue; + var escapedKey = Uri.EscapeDataString(key); + var prefix = escapedKey + "="; - string escapedKey = Uri.EscapeDataString(key); - string prefix = escapedKey + "="; - - string suffix = string.Concat( + var suffix = string.Concat( !domainHasValue ? null : "; domain=", !domainHasValue ? null : options.Domain, !pathHasValue ? null : "; path=", @@ -148,19 +135,19 @@ public void AppendResponseCookie(HttpContext context, string key, string value, !options.HttpOnly ? null : "; HttpOnly"); value = value ?? string.Empty; - bool quoted = false; + var quoted = false; if (IsQuoted(value)) { quoted = true; value = RemoveQuotes(value); } - string escapedValue = Uri.EscapeDataString(value); + var escapedValue = Uri.EscapeDataString(value); // Normal cookie - IHeaderDictionary responseHeaders = context.Response.Headers; + var responseHeaders = context.Response.Headers; if (!ChunkSize.HasValue || ChunkSize.Value > prefix.Length + escapedValue.Length + suffix.Length + (quoted ? 2 : 0)) { - string setCookieValue = string.Concat( + var setCookieValue = string.Concat( prefix, quoted ? Quote(escapedValue) : escapedValue, suffix); @@ -180,18 +167,18 @@ public void AppendResponseCookie(HttpContext context, string key, string value, // Set-Cookie: CookieNameC1="Segment1"; path=/ // Set-Cookie: CookieNameC2="Segment2"; path=/ // Set-Cookie: CookieNameC3="Segment3"; path=/ - int dataSizePerCookie = ChunkSize.Value - prefix.Length - suffix.Length - (quoted ? 2 : 0) - 3; // Budget 3 chars for the chunkid. - int cookieChunkCount = (int)Math.Ceiling(escapedValue.Length * 1.0 / dataSizePerCookie); + var dataSizePerCookie = ChunkSize.Value - prefix.Length - suffix.Length - (quoted ? 2 : 0) - 3; // Budget 3 chars for the chunkid. + var cookieChunkCount = (int)Math.Ceiling(escapedValue.Length * 1.0 / dataSizePerCookie); responseHeaders.AppendValues(Constants.Headers.SetCookie, prefix + "chunks:" + cookieChunkCount.ToString(CultureInfo.InvariantCulture) + suffix); - - string[] chunks = new string[cookieChunkCount]; - int offset = 0; - for (int chunkId = 1; chunkId <= cookieChunkCount; chunkId++) + + var chunks = new string[cookieChunkCount]; + var offset = 0; + for (var chunkId = 1; chunkId <= cookieChunkCount; chunkId++) { - int remainingLength = escapedValue.Length - offset; - int length = Math.Min(dataSizePerCookie, remainingLength); - string segment = escapedValue.Substring(offset, length); + var remainingLength = escapedValue.Length - offset; + var length = Math.Min(dataSizePerCookie, remainingLength); + var segment = escapedValue.Substring(offset, length); offset += length; chunks[chunkId - 1] = string.Concat( @@ -215,34 +202,25 @@ public void AppendResponseCookie(HttpContext context, string key, string value, /// /// /// - public void DeleteCookie(HttpContext context, string key, CookieOptions options) + public void DeleteCookie([NotNull] HttpContext context, [NotNull] string key, [NotNull] CookieOptions options) { - if (context == null) - { - throw new ArgumentNullException("context"); - } - if (options == null) - { - throw new ArgumentNullException("options"); - } - - string escapedKey = Uri.EscapeDataString(key); - List keys = new List(); + var escapedKey = Uri.EscapeDataString(key); + var keys = new List(); keys.Add(escapedKey + "="); - string requestCookie = context.Request.Cookies[key]; - int chunks = ParseChunksCount(requestCookie); + var requestCookie = context.Request.Cookies[key]; + var chunks = ParseChunksCount(requestCookie); if (chunks > 0) { for (int i = 1; i <= chunks + 1; i++) { - string subkey = escapedKey + "C" + i.ToString(CultureInfo.InvariantCulture); + var subkey = escapedKey + "C" + i.ToString(CultureInfo.InvariantCulture); keys.Add(subkey + "="); } } - bool domainHasValue = !string.IsNullOrEmpty(options.Domain); - bool pathHasValue = !string.IsNullOrEmpty(options.Path); + var domainHasValue = !string.IsNullOrEmpty(options.Domain); + var pathHasValue = !string.IsNullOrEmpty(options.Path); Func rejectPredicate; Func predicate = value => keys.Any(k => value.StartsWith(k, StringComparison.OrdinalIgnoreCase)); @@ -259,8 +237,8 @@ public void DeleteCookie(HttpContext context, string key, CookieOptions options) rejectPredicate = value => predicate(value); } - IHeaderDictionary responseHeaders = context.Response.Headers; - IList existingValues = responseHeaders.GetValues(Constants.Headers.SetCookie); + var responseHeaders = context.Response.Headers; + var existingValues = responseHeaders.GetValues(Constants.Headers.SetCookie); if (existingValues != null) { responseHeaders.SetValues(Constants.Headers.SetCookie, existingValues.Where(value => !rejectPredicate(value)).ToArray()); @@ -270,7 +248,7 @@ public void DeleteCookie(HttpContext context, string key, CookieOptions options) context, key, string.Empty, - new CookieOptions + new CookieOptions() { Path = options.Path, Domain = options.Domain, @@ -283,7 +261,7 @@ public void DeleteCookie(HttpContext context, string key, CookieOptions options) context, key + "C" + i.ToString(CultureInfo.InvariantCulture), string.Empty, - new CookieOptions + new CookieOptions() { Path = options.Path, Domain = options.Domain, @@ -292,17 +270,17 @@ public void DeleteCookie(HttpContext context, string key, CookieOptions options) } } - private static bool IsQuoted(string value) + private static bool IsQuoted([NotNull] string value) { return value.Length >= 2 && value[0] == '"' && value[value.Length - 1] == '"'; } - private static string RemoveQuotes(string value) + private static string RemoveQuotes([NotNull] string value) { return value.Substring(1, value.Length - 2); } - private static string Quote(string value) + private static string Quote([NotNull] string value) { return '"' + value + '"'; } From b832636484d85a3bfb6962d05c9835b931185e8b Mon Sep 17 00:00:00 2001 From: Chris Ross Date: Mon, 15 Sep 2014 16:09:14 -0700 Subject: [PATCH 057/216] Clean sample dependencies. --- samples/CookieSample/project.json | 15 --------------- samples/CookieSessionSample/project.json | 15 --------------- samples/SocialSample/project.json | 14 -------------- 3 files changed, 44 deletions(-) diff --git a/samples/CookieSample/project.json b/samples/CookieSample/project.json index 405e3ba0d..9d6c8a534 100644 --- a/samples/CookieSample/project.json +++ b/samples/CookieSample/project.json @@ -16,21 +16,6 @@ "aspnet50": { }, "aspnetcore50": { - "dependencies": { - "System.Collections": "4.0.10.0", - "System.Console": "4.0.0.0", - "System.Diagnostics.Debug": "4.0.10.0", - "System.Diagnostics.Tools": "4.0.0.0", - "System.Globalization": "4.0.10.0", - "System.IO": "4.0.10.0", - "System.Linq": "4.0.0.0", - "System.Reflection": "4.0.10.0", - "System.Resources.ResourceManager": "4.0.0.0", - "System.Runtime": "4.0.20.0", - "System.Runtime.Extensions": "4.0.10.0", - "System.Runtime.InteropServices": "4.0.20.0", - "System.Threading.Tasks": "4.0.10.0" - } } } } diff --git a/samples/CookieSessionSample/project.json b/samples/CookieSessionSample/project.json index c5aca5588..9e72b7aca 100644 --- a/samples/CookieSessionSample/project.json +++ b/samples/CookieSessionSample/project.json @@ -17,21 +17,6 @@ "aspnet50": { }, "aspnetcore50": { - "dependencies": { - "System.Collections": "4.0.10.0", - "System.Console": "4.0.0.0", - "System.Diagnostics.Debug": "4.0.10.0", - "System.Diagnostics.Tools": "4.0.0.0", - "System.Globalization": "4.0.10.0", - "System.IO": "4.0.10.0", - "System.Linq": "4.0.0.0", - "System.Reflection": "4.0.10.0", - "System.Resources.ResourceManager": "4.0.0.0", - "System.Runtime": "4.0.20.0", - "System.Runtime.Extensions": "4.0.10.0", - "System.Runtime.InteropServices": "4.0.20.0", - "System.Threading.Tasks": "4.0.10.0" - } } } } diff --git a/samples/SocialSample/project.json b/samples/SocialSample/project.json index ed77607d2..3909b9162 100644 --- a/samples/SocialSample/project.json +++ b/samples/SocialSample/project.json @@ -17,20 +17,6 @@ "aspnet50": { }, "aspnetcore50": { - "dependencies": { - "System.Collections": "4.0.10.0", - "System.Console": "4.0.0.0", - "System.Diagnostics.Debug": "4.0.10.0", - "System.Diagnostics.Tools": "4.0.0.0", - "System.Globalization": "4.0.10.0", - "System.IO": "4.0.0.0", - "System.Linq": "4.0.0.0", - "System.Resources.ResourceManager": "4.0.0.0", - "System.Runtime": "4.0.20.0", - "System.Runtime.Extensions": "4.0.10.0", - "System.Runtime.InteropServices": "4.0.20.0", - "System.Threading.Tasks": "4.0.10.0" - } } } } From 1a6b6fdd911643ef9cd9a21f36bea460148d2ecb Mon Sep 17 00:00:00 2001 From: Pranav K Date: Wed, 17 Sep 2014 09:59:12 -0700 Subject: [PATCH 058/216] Updating release NuGet.config --- NuGet.Config | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/NuGet.Config b/NuGet.Config index f41e9c631..1ce6b9e25 100644 --- a/NuGet.Config +++ b/NuGet.Config @@ -1,7 +1,7 @@ - + - + From ffedd046571d3c7014853fb4e59d92ab681b27eb Mon Sep 17 00:00:00 2001 From: Pranav K Date: Wed, 17 Sep 2014 09:59:14 -0700 Subject: [PATCH 059/216] Updating dev NuGet.config --- NuGet.Config | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/NuGet.Config b/NuGet.Config index 1ce6b9e25..f41e9c631 100644 --- a/NuGet.Config +++ b/NuGet.Config @@ -1,7 +1,7 @@ - + - + From 43cdd54c16481244e7836a427bc90e89bcf1828d Mon Sep 17 00:00:00 2001 From: Pranav K Date: Wed, 1 Oct 2014 14:47:27 -0700 Subject: [PATCH 060/216] Removing declaration expressions --- .../Infrastructure/ChunkingCookieManager.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Microsoft.AspNet.Security.Cookies/Infrastructure/ChunkingCookieManager.cs b/src/Microsoft.AspNet.Security.Cookies/Infrastructure/ChunkingCookieManager.cs index f4d893bd5..07fc0db34 100644 --- a/src/Microsoft.AspNet.Security.Cookies/Infrastructure/ChunkingCookieManager.cs +++ b/src/Microsoft.AspNet.Security.Cookies/Infrastructure/ChunkingCookieManager.cs @@ -43,7 +43,8 @@ private static int ParseChunksCount(string value) if (value != null && value.StartsWith("chunks:", StringComparison.Ordinal)) { var chunksCountString = value.Substring("chunks:".Length); - if (int.TryParse(chunksCountString, NumberStyles.None, CultureInfo.InvariantCulture, out var chunksCount)) + int chunksCount; + if (int.TryParse(chunksCountString, NumberStyles.None, CultureInfo.InvariantCulture, out chunksCount)) { return chunksCount; } From 0f9ac1f84fa31083f154c20f924d32855f3b11dd Mon Sep 17 00:00:00 2001 From: Chris Ross Date: Wed, 24 Sep 2014 12:13:33 -0700 Subject: [PATCH 061/216] #52 - Set a default user-agent for the OAuth backchannel. --- samples/SocialSample/Startup.cs | 1 - .../OAuthAuthenticationMiddleware.cs | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/SocialSample/Startup.cs b/samples/SocialSample/Startup.cs index 5fbb8887a..06309f541 100644 --- a/samples/SocialSample/Startup.cs +++ b/samples/SocialSample/Startup.cs @@ -119,7 +119,6 @@ k web HttpRequestMessage userRequest = new HttpRequestMessage(HttpMethod.Get, context.Options.UserInformationEndpoint); userRequest.Headers.Authorization = new AuthenticationHeaderValue("Bearer", context.AccessToken); userRequest.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); - userRequest.Headers.UserAgent.ParseAdd("Microsoft ASP.NET OAuth middleware for GitHub"); HttpResponseMessage userResponse = await context.Backchannel.SendAsync(userRequest, context.HttpContext.RequestAborted); userResponse.EnsureSuccessStatusCode(); var text = await userResponse.Content.ReadAsStringAsync(); diff --git a/src/Microsoft.AspNet.Security.OAuth/OAuthAuthenticationMiddleware.cs b/src/Microsoft.AspNet.Security.OAuth/OAuthAuthenticationMiddleware.cs index 3dd00f4b0..009b02548 100644 --- a/src/Microsoft.AspNet.Security.OAuth/OAuthAuthenticationMiddleware.cs +++ b/src/Microsoft.AspNet.Security.OAuth/OAuthAuthenticationMiddleware.cs @@ -62,6 +62,7 @@ public OAuthAuthenticationMiddleware( } Backchannel = new HttpClient(ResolveHttpMessageHandler(Options)); + Backchannel.DefaultRequestHeaders.UserAgent.ParseAdd("Microsoft ASP.NET OAuth middleware"); Backchannel.Timeout = Options.BackchannelTimeout; Backchannel.MaxResponseContentBufferSize = 1024 * 1024 * 10; // 10 MB } From 23c024ef4112f12ea4e107ceee7a0ee30ae4fb61 Mon Sep 17 00:00:00 2001 From: David Fowler Date: Sun, 5 Oct 2014 12:26:17 -0700 Subject: [PATCH 062/216] Fixup references --- samples/CookieSample/project.json | 5 -- samples/CookieSessionSample/project.json | 7 -- samples/SocialSample/project.json | 34 +++++----- .../project.json | 4 -- .../project.json | 10 +-- .../project.json | 10 +-- .../project.json | 10 +-- .../project.json | 12 ++-- .../project.json | 12 ++-- src/Microsoft.AspNet.Security/project.json | 68 +++++++++---------- .../project.json | 57 ++++++++-------- 11 files changed, 104 insertions(+), 125 deletions(-) diff --git a/samples/CookieSample/project.json b/samples/CookieSample/project.json index 9d6c8a534..a962cc962 100644 --- a/samples/CookieSample/project.json +++ b/samples/CookieSample/project.json @@ -1,10 +1,5 @@ { "dependencies": { - "Microsoft.AspNet.FeatureModel": "1.0.0-*", - "Microsoft.AspNet.Hosting": "1.0.0-*", - "Microsoft.AspNet.Http": "1.0.0-*", - "Microsoft.AspNet.HttpFeature": "1.0.0-*", - "Microsoft.AspNet.PipelineCore": "1.0.0-*", "Microsoft.AspNet.RequestContainer": "1.0.0-*", "Microsoft.AspNet.Security": "1.0.0-*", "Microsoft.AspNet.Security.Cookies": "1.0.0-*", diff --git a/samples/CookieSessionSample/project.json b/samples/CookieSessionSample/project.json index 9e72b7aca..660715f5f 100644 --- a/samples/CookieSessionSample/project.json +++ b/samples/CookieSessionSample/project.json @@ -1,12 +1,5 @@ { "dependencies": { - "Microsoft.AspNet.FeatureModel": "1.0.0-*", - "Microsoft.AspNet.Hosting": "1.0.0-*", - "Microsoft.AspNet.Http": "1.0.0-*", - "Microsoft.AspNet.HttpFeature": "1.0.0-*", - "Microsoft.AspNet.PipelineCore": "1.0.0-*", - "Microsoft.AspNet.RequestContainer": "1.0.0-*", - "Microsoft.AspNet.Security": "1.0.0-*", "Microsoft.AspNet.Security.Cookies": "1.0.0-*", "Microsoft.AspNet.Server.WebListener": "1.0.0-*", "Microsoft.Framework.Cache.Memory": "1.0.0-*", diff --git a/samples/SocialSample/project.json b/samples/SocialSample/project.json index 3909b9162..b1942aa64 100644 --- a/samples/SocialSample/project.json +++ b/samples/SocialSample/project.json @@ -1,22 +1,20 @@ { - "dependencies": { - "Microsoft.AspNet.Hosting": "1.0.0-*", - "Microsoft.AspNet.Http": "1.0.0-*", - "Microsoft.AspNet.Diagnostics": "1.0.0-*", - "Microsoft.AspNet.Security": "1.0.0-*", - "Microsoft.AspNet.Security.Cookies": "1.0.0-*", - "Microsoft.AspNet.Security.Facebook": "1.0.0-*", - "Microsoft.AspNet.Security.Google": "1.0.0-*", - "Microsoft.AspNet.Security.MicrosoftAccount": "1.0.0-*", - "Microsoft.AspNet.Security.Twitter": "1.0.0-*", - "Microsoft.AspNet.Server.WebListener": "1.0.0-*", - "Microsoft.Framework.DependencyInjection": "1.0.0-*" - }, - "commands": { "web": "Microsoft.AspNet.Hosting server=Microsoft.AspNet.Server.WebListener server.urls=http://localhost:12345" }, - "frameworks": { - "aspnet50": { + "dependencies": { + "Microsoft.AspNet.Diagnostics": "1.0.0-*", + "Microsoft.AspNet.Security": "1.0.0-*", + "Microsoft.AspNet.Security.Cookies": "1.0.0-*", + "Microsoft.AspNet.Security.Facebook": "1.0.0-*", + "Microsoft.AspNet.Security.Google": "1.0.0-*", + "Microsoft.AspNet.Security.MicrosoftAccount": "1.0.0-*", + "Microsoft.AspNet.Security.Twitter": "1.0.0-*", + "Microsoft.AspNet.Server.WebListener": "1.0.0-*", + "Microsoft.Framework.DependencyInjection": "1.0.0-*" }, - "aspnetcore50": { + "commands": { "web": "Microsoft.AspNet.Hosting server=Microsoft.AspNet.Server.WebListener server.urls=http://localhost:12345" }, + "frameworks": { + "aspnet50": { + }, + "aspnetcore50": { + } } - } } diff --git a/src/Microsoft.AspNet.Security.Cookies/project.json b/src/Microsoft.AspNet.Security.Cookies/project.json index 715a02a7e..154d01821 100644 --- a/src/Microsoft.AspNet.Security.Cookies/project.json +++ b/src/Microsoft.AspNet.Security.Cookies/project.json @@ -1,10 +1,6 @@ { "version": "1.0.0-*", "dependencies": { - "Microsoft.AspNet.FeatureModel": "1.0.0-*", - "Microsoft.AspNet.Http": "1.0.0-*", - "Microsoft.AspNet.HttpFeature": "1.0.0-*", - "Microsoft.AspNet.PipelineCore": "1.0.0-*", "Microsoft.AspNet.RequestContainer": "1.0.0-*", "Microsoft.AspNet.Security": "1.0.0-*", "Microsoft.AspNet.Security.DataProtection": "1.0.0-*", diff --git a/src/Microsoft.AspNet.Security.Facebook/project.json b/src/Microsoft.AspNet.Security.Facebook/project.json index eeba5b2d2..6ad815156 100644 --- a/src/Microsoft.AspNet.Security.Facebook/project.json +++ b/src/Microsoft.AspNet.Security.Facebook/project.json @@ -1,19 +1,18 @@ { "version": "1.0.0-*", "dependencies": { - "Microsoft.AspNet.Http": "1.0.0-*", "Microsoft.AspNet.RequestContainer": "1.0.0-*", "Microsoft.AspNet.Security": "1.0.0-*", "Microsoft.AspNet.Security.DataProtection": "1.0.0-*", "Microsoft.AspNet.Security.OAuth": "1.0.0-*", "Microsoft.AspNet.WebUtilities": "1.0.0-*", "Microsoft.Framework.Logging": "1.0.0-*", - "Newtonsoft.Json": "6.0.4", - "System.Net.Http": "4.0.0.0" + "Newtonsoft.Json": "6.0.4" }, "frameworks": { "aspnet50": { - "dependencies": { + "frameworkAssemblies": { + "System.Net.Http": "4.0.0.0" } }, "aspnetcore50": { @@ -36,7 +35,8 @@ "System.Security.Cryptography.Hashing.Algorithms": "4.0.0.0", "System.Security.Principal": "4.0.0.0", "System.Threading": "4.0.0.0", - "System.Threading.Tasks": "4.0.10.0" + "System.Threading.Tasks": "4.0.10.0", + "System.Net.Http": "4.0.0.0" } } } diff --git a/src/Microsoft.AspNet.Security.Google/project.json b/src/Microsoft.AspNet.Security.Google/project.json index eeba5b2d2..6ad815156 100644 --- a/src/Microsoft.AspNet.Security.Google/project.json +++ b/src/Microsoft.AspNet.Security.Google/project.json @@ -1,19 +1,18 @@ { "version": "1.0.0-*", "dependencies": { - "Microsoft.AspNet.Http": "1.0.0-*", "Microsoft.AspNet.RequestContainer": "1.0.0-*", "Microsoft.AspNet.Security": "1.0.0-*", "Microsoft.AspNet.Security.DataProtection": "1.0.0-*", "Microsoft.AspNet.Security.OAuth": "1.0.0-*", "Microsoft.AspNet.WebUtilities": "1.0.0-*", "Microsoft.Framework.Logging": "1.0.0-*", - "Newtonsoft.Json": "6.0.4", - "System.Net.Http": "4.0.0.0" + "Newtonsoft.Json": "6.0.4" }, "frameworks": { "aspnet50": { - "dependencies": { + "frameworkAssemblies": { + "System.Net.Http": "4.0.0.0" } }, "aspnetcore50": { @@ -36,7 +35,8 @@ "System.Security.Cryptography.Hashing.Algorithms": "4.0.0.0", "System.Security.Principal": "4.0.0.0", "System.Threading": "4.0.0.0", - "System.Threading.Tasks": "4.0.10.0" + "System.Threading.Tasks": "4.0.10.0", + "System.Net.Http": "4.0.0.0" } } } diff --git a/src/Microsoft.AspNet.Security.MicrosoftAccount/project.json b/src/Microsoft.AspNet.Security.MicrosoftAccount/project.json index cf6a2e96a..c0c9fa206 100644 --- a/src/Microsoft.AspNet.Security.MicrosoftAccount/project.json +++ b/src/Microsoft.AspNet.Security.MicrosoftAccount/project.json @@ -1,19 +1,18 @@ { "version": "1.0.0-*", "dependencies": { - "Microsoft.AspNet.Http": "1.0.0-*", "Microsoft.AspNet.RequestContainer": "1.0.0-*", "Microsoft.AspNet.Security": "1.0.0-*", "Microsoft.AspNet.Security.DataProtection": "1.0.0-*", "Microsoft.AspNet.Security.OAuth": "1.0.0-*", "Microsoft.AspNet.WebUtilities": "1.0.0-*", "Microsoft.Framework.Logging": "1.0.0-*", - "Newtonsoft.Json": "6.0.4", - "System.Net.Http": "4.0.0.0" + "Newtonsoft.Json": "6.0.4" }, "frameworks": { "aspnet50": { - "dependencies": { + "frameworkAssemblies": { + "System.Net.Http": "4.0.0.0" } }, "aspnetcore50": { @@ -38,7 +37,8 @@ "System.Security.Cryptography.Hashing.Algorithms": "4.0.0.0", "System.Security.Principal": "4.0.0.0", "System.Threading": "4.0.0.0", - "System.Threading.Tasks": "4.0.10.0" + "System.Threading.Tasks": "4.0.10.0", + "System.Net.Http": "4.0.0.0" } } } diff --git a/src/Microsoft.AspNet.Security.OAuth/project.json b/src/Microsoft.AspNet.Security.OAuth/project.json index f81cf844e..0d4766cad 100644 --- a/src/Microsoft.AspNet.Security.OAuth/project.json +++ b/src/Microsoft.AspNet.Security.OAuth/project.json @@ -1,19 +1,18 @@ { "version": "1.0.0-*", "dependencies": { - "Microsoft.AspNet.Http": "1.0.0-*", "Microsoft.AspNet.RequestContainer": "1.0.0-*", "Microsoft.AspNet.Security": "1.0.0-*", "Microsoft.AspNet.Security.DataProtection": "1.0.0-*", "Microsoft.AspNet.WebUtilities": "1.0.0-*", "Microsoft.Framework.Logging": "1.0.0-*", - "Newtonsoft.Json": "6.0.4", - "System.Net.Http": "4.0.0.0" + "Newtonsoft.Json": "6.0.4" }, "frameworks": { "aspnet50": { - "dependencies": { - "System.Net.Http.WebRequest": "" + "frameworkAssemblies": { + "System.Net.Http.WebRequest": "4.0.0.0", + "System.Net.Http": "4.0.0.0" } }, "aspnetcore50": { @@ -39,7 +38,8 @@ "System.Security.Cryptography.Hashing.Algorithms": "4.0.0.0", "System.Security.Principal": "4.0.0.0", "System.Threading": "4.0.0.0", - "System.Threading.Tasks": "4.0.10.0" + "System.Threading.Tasks": "4.0.10.0", + "System.Net.Http": "4.0.0.0" } } } diff --git a/src/Microsoft.AspNet.Security.Twitter/project.json b/src/Microsoft.AspNet.Security.Twitter/project.json index f8498191b..5f1c34c94 100644 --- a/src/Microsoft.AspNet.Security.Twitter/project.json +++ b/src/Microsoft.AspNet.Security.Twitter/project.json @@ -1,19 +1,18 @@ { "version": "1.0.0-*", "dependencies": { - "Microsoft.AspNet.Http": "1.0.0-*", "Microsoft.AspNet.RequestContainer": "1.0.0-*", "Microsoft.AspNet.Security": "1.0.0-*", "Microsoft.AspNet.Security.DataProtection": "1.0.0-*", "Microsoft.AspNet.WebUtilities": "1.0.0-*", "Microsoft.Framework.Logging": "1.0.0-*", - "Newtonsoft.Json": "6.0.4", - "System.Net.Http": "4.0.0.0" + "Newtonsoft.Json": "6.0.4" }, "frameworks": { "aspnet50": { - "dependencies": { - "System.Net.Http.WebRequest": "" + "frameworkAssemblies": { + "System.Net.Http.WebRequest": "4.0.0.0", + "System.Net.Http": "4.0.0.0" } }, "aspnetcore50": { @@ -37,7 +36,8 @@ "System.Security.Cryptography.Hashing.Algorithms": "4.0.0.0", "System.Security.Principal": "4.0.0.0", "System.Threading": "4.0.0.0", - "System.Threading.Tasks": "4.0.10.0" + "System.Threading.Tasks": "4.0.10.0", + "System.Net.Http": "4.0.0.0" } } } diff --git a/src/Microsoft.AspNet.Security/project.json b/src/Microsoft.AspNet.Security/project.json index d54725296..11854a0e1 100644 --- a/src/Microsoft.AspNet.Security/project.json +++ b/src/Microsoft.AspNet.Security/project.json @@ -1,38 +1,36 @@ { - "version": "1.0.0-*", - "dependencies": { - "Microsoft.AspNet.FeatureModel": "1.0.0-*", - "Microsoft.AspNet.Http": "1.0.0-*", - "Microsoft.AspNet.HttpFeature": "1.0.0-*", - "Microsoft.AspNet.PipelineCore": "1.0.0-*", - "Microsoft.AspNet.Security.DataProtection": "1.0.0-*", - "Microsoft.Framework.DependencyInjection": "1.0.0-*", - "Microsoft.Framework.Logging": "1.0.0-*" - }, - "frameworks": { - "aspnet50": {}, - "aspnetcore50": { - "dependencies": { - "System.Collections": "4.0.10.0", - "System.ComponentModel": "4.0.0.0", - "System.Console": "4.0.0.0", - "System.Diagnostics.Debug": "4.0.10.0", - "System.Diagnostics.Tools": "4.0.0.0", - "System.Globalization": "4.0.10.0", - "System.IO": "4.0.10.0", - "System.IO.Compression": "4.0.0.0", - "System.Linq": "4.0.0.0", - "System.Reflection": "4.0.10.0", - "System.Resources.ResourceManager": "4.0.0.0", - "System.Runtime": "4.0.20.0", - "System.Runtime.Extensions": "4.0.10.0", - "System.Runtime.InteropServices": "4.0.20.0", - "System.Security.Claims": "1.0.0-*", - "System.Security.Cryptography.RandomNumberGenerator" : "4.0.0.0", - "System.Security.Principal" : "4.0.0.0", - "System.Threading": "4.0.0.0", - "System.Threading.Tasks": "4.0.10.0" - } + "version": "1.0.0-*", + "dependencies": { + "Microsoft.AspNet.HttpFeature": { "version": "1.0.0-*", "type": "build" }, + "Microsoft.AspNet.PipelineCore": "1.0.0-*", + "Microsoft.AspNet.Security.DataProtection": "1.0.0-*", + "Microsoft.Framework.DependencyInjection": "1.0.0-*", + "Microsoft.Framework.Logging": "1.0.0-*" + }, + "frameworks": { + "aspnet50": { }, + "aspnetcore50": { + "dependencies": { + "System.Collections": "4.0.10.0", + "System.ComponentModel": "4.0.0.0", + "System.Console": "4.0.0.0", + "System.Diagnostics.Debug": "4.0.10.0", + "System.Diagnostics.Tools": "4.0.0.0", + "System.Globalization": "4.0.10.0", + "System.IO": "4.0.10.0", + "System.IO.Compression": "4.0.0.0", + "System.Linq": "4.0.0.0", + "System.Reflection": "4.0.10.0", + "System.Resources.ResourceManager": "4.0.0.0", + "System.Runtime": "4.0.20.0", + "System.Runtime.Extensions": "4.0.10.0", + "System.Runtime.InteropServices": "4.0.20.0", + "System.Security.Claims": "1.0.0-*", + "System.Security.Cryptography.RandomNumberGenerator": "4.0.0.0", + "System.Security.Principal": "4.0.0.0", + "System.Threading": "4.0.0.0", + "System.Threading.Tasks": "4.0.10.0" + } + } } - } } diff --git a/test/Microsoft.AspNet.Security.Test/project.json b/test/Microsoft.AspNet.Security.Test/project.json index 49f7858ad..c3b4a4b2c 100644 --- a/test/Microsoft.AspNet.Security.Test/project.json +++ b/test/Microsoft.AspNet.Security.Test/project.json @@ -1,32 +1,31 @@ { - "compilationOptions": { - "warningsAsErrors": true - }, - "dependencies": { - "Microsoft.AspNet.Http": "1.0.0-*", - "Microsoft.AspNet.Security" : "1.0.0-*", - "Microsoft.AspNet.Security.Cookies" : "1.0.0-*", - "Microsoft.AspNet.Security.Facebook" : "1.0.0-*", - "Microsoft.AspNet.Security.Google" : "1.0.0-*", - "Microsoft.AspNet.Security.MicrosoftAccount" : "1.0.0-*", - "Microsoft.AspNet.Security.Twitter" : "1.0.0-*", - "Microsoft.AspNet.TestHost": "1.0.0-*", - "Microsoft.Framework.DependencyInjection": "1.0.0-*", - "System.Net.Http": "4.0.0.0", - "Moq": "4.2.1312.1622", - "Xunit.KRunner": "1.0.0-*" - }, - "commands": { - "test": "Xunit.KRunner" - }, - "frameworks": { - "aspnet50": { - "dependencies": { - "Shouldly": "1.1.1.1", - "System.Runtime": "", - "System.Xml": "", - "System.Xml.Linq": "" - } + "compilationOptions": { + "warningsAsErrors": true + }, + "dependencies": { + "Microsoft.AspNet.Http": "1.0.0-*", + "Microsoft.AspNet.Security": "1.0.0-*", + "Microsoft.AspNet.Security.Cookies": "1.0.0-*", + "Microsoft.AspNet.Security.Facebook": "1.0.0-*", + "Microsoft.AspNet.Security.Google": "1.0.0-*", + "Microsoft.AspNet.Security.MicrosoftAccount": "1.0.0-*", + "Microsoft.AspNet.Security.Twitter": "1.0.0-*", + "Microsoft.AspNet.TestHost": "1.0.0-*", + "Microsoft.Framework.DependencyInjection": "1.0.0-*", + "Moq": "4.2.1312.1622", + "Xunit.KRunner": "1.0.0-*" + }, + "commands": { + "test": "Xunit.KRunner" + }, + "frameworks": { + "aspnet50": { + "dependencies": { + "Shouldly": "1.1.1.1" + }, + "frameworkAssemblies": { + "System.Net.Http": "4.0.0.0" + } + } } - } } From 3426034bcb0f5ab114031cee74a528d8fe163ab5 Mon Sep 17 00:00:00 2001 From: Hao Kung Date: Wed, 8 Oct 2014 13:02:08 -0700 Subject: [PATCH 063/216] Use DI activated options for auth middlewares UseXXX() now use DI activated options Use ExternalAuthenticationOptions instead of DefaultSignInAs --- samples/CookieSample/Startup.cs | 4 +- samples/CookieSessionSample/Startup.cs | 5 +- samples/SocialSample/SocialSample.kproj | 3 +- samples/SocialSample/Startup.cs | 104 ++++---- samples/SocialSample/project.json | 3 +- .../CookieAuthenticationExtensions.cs | 19 +- .../CookieAuthenticationMiddleware.cs | 15 +- .../CookieAuthenticationOptions.cs | 2 +- .../FacebookAuthenticationExtensions.cs | 31 +-- .../FacebookAuthenticationMiddleware.cs | 7 +- .../FacebookAuthenticationOptions.cs | 3 +- .../project.json | 1 + .../GoogleAuthenticationExtensions.cs | 34 +-- .../GoogleAuthenticationMiddleware.cs | 7 +- .../GoogleAuthenticationOptions.cs | 3 +- .../project.json | 3 +- ...icrosoftAccountAuthenticationExtensions.cs | 37 +-- ...icrosoftAccountAuthenticationMiddleware.cs | 7 +- .../MicrosoftAccountAuthenticationOptions.cs | 3 +- .../project.json | 1 + .../OAuthAuthenticationExtensions.cs | 26 +- .../OAuthAuthenticationMiddleware.cs | 25 +- .../OAuthAuthenticationOptions.cs | 7 +- .../OAuthAuthenticationOptions`1.cs | 8 - .../TwitterAuthenticationExtensions.cs | 38 +-- .../TwitterAuthenticationMiddleware.cs | 18 +- .../TwitterAuthenticationOptions.cs | 4 +- .../project.json | 1 + .../AuthenticationOptions.cs | 15 +- .../BuilderSecurityExtensions.cs | 45 ---- src/Microsoft.AspNet.Security/Constants.cs | 17 -- .../ExternalAuthenticationOptions.cs | 13 + .../AuthenticationMiddleware.cs | 17 +- src/Microsoft.AspNet.Security/Resources.resx | 3 - src/Microsoft.AspNet.Security/project.json | 3 +- .../Cookies/CookieMiddlewareTests.cs | 95 +++---- .../Facebook/FacebookMiddlewareTests.cs | 67 +++-- .../Google/GoogleMiddlewareTests.cs | 236 +++++++++--------- .../MicrosoftAccountMiddlewareTests.cs | 132 +++++----- .../Twitter/TwitterMiddlewareTests.cs | 86 ++++--- .../project.json | 1 + 41 files changed, 589 insertions(+), 560 deletions(-) delete mode 100644 src/Microsoft.AspNet.Security/BuilderSecurityExtensions.cs delete mode 100644 src/Microsoft.AspNet.Security/Constants.cs create mode 100644 src/Microsoft.AspNet.Security/ExternalAuthenticationOptions.cs diff --git a/samples/CookieSample/Startup.cs b/samples/CookieSample/Startup.cs index 2e5602b9c..fc78aec37 100644 --- a/samples/CookieSample/Startup.cs +++ b/samples/CookieSample/Startup.cs @@ -9,9 +9,9 @@ public class Startup { public void Configure(IApplicationBuilder app) { - app.UseCookieAuthentication(new CookieAuthenticationOptions() + app.UseServices(services => { }); + app.UseCookieAuthentication(options => { - }); app.Run(async context => diff --git a/samples/CookieSessionSample/Startup.cs b/samples/CookieSessionSample/Startup.cs index 890e63116..a4217e6d2 100644 --- a/samples/CookieSessionSample/Startup.cs +++ b/samples/CookieSessionSample/Startup.cs @@ -10,9 +10,10 @@ public class Startup { public void Configure(IApplicationBuilder app) { - app.UseCookieAuthentication(new CookieAuthenticationOptions() + app.UseServices(services => { }); + app.UseCookieAuthentication(options => { - SessionStore = new MemoryCacheSessionStore(), + options.SessionStore = new MemoryCacheSessionStore(); }); app.Run(async context => diff --git a/samples/SocialSample/SocialSample.kproj b/samples/SocialSample/SocialSample.kproj index 4447d1b1d..982c0c8f5 100644 --- a/samples/SocialSample/SocialSample.kproj +++ b/samples/SocialSample/SocialSample.kproj @@ -7,7 +7,7 @@ 8c73d216-332d-41d8-bfd0-45bc4bc36552 - Library + Web ConsoleDebugger @@ -21,6 +21,7 @@ 2.0 + 50113 \ No newline at end of file diff --git a/samples/SocialSample/Startup.cs b/samples/SocialSample/Startup.cs index 06309f541..35480c1cc 100644 --- a/samples/SocialSample/Startup.cs +++ b/samples/SocialSample/Startup.cs @@ -14,6 +14,7 @@ using Microsoft.AspNet.Security.OAuth; using Microsoft.AspNet.Security.Twitter; using Newtonsoft.Json.Linq; +using Microsoft.Framework.DependencyInjection; namespace CookieSample { @@ -23,39 +24,48 @@ public void Configure(IApplicationBuilder app) { app.UseErrorPage(); - app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType); - - app.UseCookieAuthentication(new CookieAuthenticationOptions() + app.UseServices(services => { - LoginPath = new PathString("/login"), + services.ConfigureOptions(options => + { + + options.SignInAsAuthenticationType = CookieAuthenticationDefaults.AuthenticationType; + }); }); - app.UseFacebookAuthentication(new FacebookAuthenticationOptions() + app.UseCookieAuthentication(options => + { + options.LoginPath = new PathString("/login"); + }); + + app.UseFacebookAuthentication(options => { - AppId = "569522623154478", - AppSecret = "a124463c4719c94b4228d9a240e5dc1a", + options.AppId = "569522623154478"; + options.AppSecret = "a124463c4719c94b4228d9a240e5dc1a"; }); - app.UseOAuthAuthentication(new OAuthAuthenticationOptions("Google-AccessToken") + app.UseOAuthAuthentication("Google-AccessToken", options => { - ClientId = "560027070069-37ldt4kfuohhu3m495hk2j4pjp92d382.apps.googleusercontent.com", - ClientSecret = "n2Q-GEw9RQjzcRbU3qhfTj8f", - CallbackPath = new PathString("/signin-google-token"), - AuthorizationEndpoint = GoogleAuthenticationDefaults.AuthorizationEndpoint, - TokenEndpoint = GoogleAuthenticationDefaults.TokenEndpoint, - Scope = { "openid", "profile", "email" }, + options.ClientId = "560027070069-37ldt4kfuohhu3m495hk2j4pjp92d382.apps.googleusercontent.com"; + options.ClientSecret = "n2Q-GEw9RQjzcRbU3qhfTj8f"; + options.CallbackPath = new PathString("/signin-google-token"); + options.AuthorizationEndpoint = GoogleAuthenticationDefaults.AuthorizationEndpoint; + options.TokenEndpoint = GoogleAuthenticationDefaults.TokenEndpoint; + options.Scope.Add("openid"); + options.Scope.Add("profile"); + options.Scope.Add("email"); }); - app.UseGoogleAuthentication(new GoogleAuthenticationOptions() + app.UseGoogleAuthentication(options => { - ClientId = "560027070069-37ldt4kfuohhu3m495hk2j4pjp92d382.apps.googleusercontent.com", - ClientSecret = "n2Q-GEw9RQjzcRbU3qhfTj8f", + options.ClientId = "560027070069-37ldt4kfuohhu3m495hk2j4pjp92d382.apps.googleusercontent.com"; + options.ClientSecret = "n2Q-GEw9RQjzcRbU3qhfTj8f"; }); - app.UseTwitterAuthentication(new TwitterAuthenticationOptions() + app.UseTwitterAuthentication(options => { - ConsumerKey = "6XaCTaLbMqfj6ww3zvZ5g", - ConsumerSecret = "Il2eFzGIrYhz6BWjYhVXBPQSfZuS4xoHpSSyD9PI", + options.ConsumerKey = "6XaCTaLbMqfj6ww3zvZ5g"; + options.ConsumerSecret = "Il2eFzGIrYhz6BWjYhVXBPQSfZuS4xoHpSSyD9PI"; }); /* @@ -75,43 +85,43 @@ Then you can choose to run the app as admin (see below) or add the following ACL The sample app can then be run via: k web */ - app.UseOAuthAuthentication(new OAuthAuthenticationOptions("Microsoft-AccessToken") + app.UseOAuthAuthentication("Microsoft-AccessToken", options => { - Caption = "MicrosoftAccount-AccessToken - Requires project changes", - ClientId = "00000000480FF62E", - ClientSecret = "bLw2JIvf8Y1TaToipPEqxTVlOeJwCUsr", - CallbackPath = new PathString("/signin-microsoft-token"), - AuthorizationEndpoint = MicrosoftAccountAuthenticationDefaults.AuthorizationEndpoint, - TokenEndpoint = MicrosoftAccountAuthenticationDefaults.TokenEndpoint, - Scope = { "wl.basic" }, + options.Caption = "MicrosoftAccount-AccessToken - Requires project changes"; + options.ClientId = "00000000480FF62E"; + options.ClientSecret = "bLw2JIvf8Y1TaToipPEqxTVlOeJwCUsr"; + options.CallbackPath = new PathString("/signin-microsoft-token"); + options.AuthorizationEndpoint = MicrosoftAccountAuthenticationDefaults.AuthorizationEndpoint; + options.TokenEndpoint = MicrosoftAccountAuthenticationDefaults.TokenEndpoint; + options.Scope.Add("wl.basic"); }); - app.UseMicrosoftAccountAuthentication(new MicrosoftAccountAuthenticationOptions() + app.UseMicrosoftAccountAuthentication(options => { - Caption = "MicrosoftAccount - Requires project changes", - ClientId = "00000000480FF62E", - ClientSecret = "bLw2JIvf8Y1TaToipPEqxTVlOeJwCUsr", + options.Caption = "MicrosoftAccount - Requires project changes"; + options.ClientId = "00000000480FF62E"; + options.ClientSecret = "bLw2JIvf8Y1TaToipPEqxTVlOeJwCUsr"; }); - app.UseOAuthAuthentication(new OAuthAuthenticationOptions("GitHub-AccessToken") + app.UseOAuthAuthentication("GitHub-AccessToken", options => { - ClientId = "8c0c5a572abe8fe89588", - ClientSecret = "e1d95eaf03461d27acd6f49d4fc7bf19d6ac8cda", - CallbackPath = new PathString("/signin-github-token"), - AuthorizationEndpoint = "https://github.com/login/oauth/authorize", - TokenEndpoint = "https://github.com/login/oauth/access_token", + options.ClientId = "8c0c5a572abe8fe89588"; + options.ClientSecret = "e1d95eaf03461d27acd6f49d4fc7bf19d6ac8cda"; + options.CallbackPath = new PathString("/signin-github-token"); + options.AuthorizationEndpoint = "https://github.com/login/oauth/authorize"; + options.TokenEndpoint = "https://github.com/login/oauth/access_token"; }); - app.UseOAuthAuthentication(new OAuthAuthenticationOptions("GitHub") + app.UseOAuthAuthentication("GitHub", options => { - ClientId = "49e302895d8b09ea5656", - ClientSecret = "98f1bf028608901e9df91d64ee61536fe562064b", - 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", + options.ClientId = "49e302895d8b09ea5656"; + options.ClientSecret = "98f1bf028608901e9df91d64ee61536fe562064b"; + options.CallbackPath = new PathString("/signin-github"); + options.AuthorizationEndpoint = "https://github.com/login/oauth/authorize"; + options.TokenEndpoint = "https://github.com/login/oauth/access_token"; + options.UserInformationEndpoint = "https://api.github.com/user"; // Retrieving user information is unique to each provider. - Notifications = new OAuthAuthenticationNotifications() + options.Notifications = new OAuthAuthenticationNotifications() { OnGetUserInformationAsync = async (context) => { @@ -153,7 +163,7 @@ k web context.Identity = identity; }, - }, + }; }); // Choose an authentication type diff --git a/samples/SocialSample/project.json b/samples/SocialSample/project.json index b1942aa64..84bb6d1c9 100644 --- a/samples/SocialSample/project.json +++ b/samples/SocialSample/project.json @@ -8,7 +8,8 @@ "Microsoft.AspNet.Security.MicrosoftAccount": "1.0.0-*", "Microsoft.AspNet.Security.Twitter": "1.0.0-*", "Microsoft.AspNet.Server.WebListener": "1.0.0-*", - "Microsoft.Framework.DependencyInjection": "1.0.0-*" + "Microsoft.Framework.DependencyInjection": "1.0.0-*", + "Microsoft.Framework.OptionsModel": "1.0.0-*" }, "commands": { "web": "Microsoft.AspNet.Hosting server=Microsoft.AspNet.Server.WebListener server.urls=http://localhost:12345" }, "frameworks": { diff --git a/src/Microsoft.AspNet.Security.Cookies/CookieAuthenticationExtensions.cs b/src/Microsoft.AspNet.Security.Cookies/CookieAuthenticationExtensions.cs index 03af44a43..98d39cca7 100644 --- a/src/Microsoft.AspNet.Security.Cookies/CookieAuthenticationExtensions.cs +++ b/src/Microsoft.AspNet.Security.Cookies/CookieAuthenticationExtensions.cs @@ -2,6 +2,9 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using Microsoft.AspNet.Security.Cookies; +using Microsoft.Framework.DependencyInjection; +using Microsoft.Framework.OptionsModel; +using System; namespace Microsoft.AspNet.Builder { @@ -10,15 +13,25 @@ namespace Microsoft.AspNet.Builder /// public static class CookieAuthenticationExtensions { + public static IServiceCollection ConfigureCookieAuthentication([NotNull] this IServiceCollection services, [NotNull] Action configure) + { + return services.ConfigureOptions(configure); + } + /// /// Adds a cookie-based authentication middleware to your web application pipeline. /// /// The IApplicationBuilder passed to your configuration method - /// An options class that controls the middleware behavior + /// Used to configure the options for the middleware + /// The name of the options class that controls the middleware behavior, null will use the default options /// The original app parameter - public static IApplicationBuilder UseCookieAuthentication([NotNull] this IApplicationBuilder app, [NotNull] CookieAuthenticationOptions options) + public static IApplicationBuilder UseCookieAuthentication([NotNull] this IApplicationBuilder app, Action configureOptions = null, string optionsName = "") { - return app.UseMiddleware(options); + return app.UseMiddleware( + new OptionsAction(configureOptions ?? (o => { })) + { + Name = optionsName + }); } } } \ No newline at end of file diff --git a/src/Microsoft.AspNet.Security.Cookies/CookieAuthenticationMiddleware.cs b/src/Microsoft.AspNet.Security.Cookies/CookieAuthenticationMiddleware.cs index 92ab1b122..fff690665 100644 --- a/src/Microsoft.AspNet.Security.Cookies/CookieAuthenticationMiddleware.cs +++ b/src/Microsoft.AspNet.Security.Cookies/CookieAuthenticationMiddleware.cs @@ -9,6 +9,7 @@ using Microsoft.AspNet.Security.DataProtection; using Microsoft.AspNet.Security.Infrastructure; using Microsoft.Framework.Logging; +using Microsoft.Framework.OptionsModel; namespace Microsoft.AspNet.Security.Cookies { @@ -16,8 +17,12 @@ public class CookieAuthenticationMiddleware : AuthenticationMiddleware options, + IOptionsAction configureOptions) + : base(next, options, configureOptions) { if (Options.Notifications == null) { @@ -27,11 +32,11 @@ public CookieAuthenticationMiddleware(RequestDelegate next, IDataProtectionProvi { Options.CookieName = CookieAuthenticationDefaults.CookiePrefix + Options.AuthenticationType; } - if (options.TicketDataFormat == null) + if (Options.TicketDataFormat == null) { IDataProtector dataProtector = DataProtectionHelpers.CreateDataProtector(dataProtectionProvider, - typeof(CookieAuthenticationMiddleware).FullName, options.AuthenticationType, "v1"); - options.TicketDataFormat = new TicketDataFormat(dataProtector); + typeof(CookieAuthenticationMiddleware).FullName, Options.AuthenticationType, "v1"); + Options.TicketDataFormat = new TicketDataFormat(dataProtector); } if (Options.CookieManager == null) { diff --git a/src/Microsoft.AspNet.Security.Cookies/CookieAuthenticationOptions.cs b/src/Microsoft.AspNet.Security.Cookies/CookieAuthenticationOptions.cs index c6373a0ec..121ff409b 100644 --- a/src/Microsoft.AspNet.Security.Cookies/CookieAuthenticationOptions.cs +++ b/src/Microsoft.AspNet.Security.Cookies/CookieAuthenticationOptions.cs @@ -21,8 +21,8 @@ public class CookieAuthenticationOptions : AuthenticationOptions /// Create an instance of the options initialized with the default values /// public CookieAuthenticationOptions() - : base(CookieAuthenticationDefaults.AuthenticationType) { + AuthenticationType = CookieAuthenticationDefaults.AuthenticationType; ReturnUrlParameter = CookieAuthenticationDefaults.ReturnUrlParameter; CookiePath = "/"; ExpireTimeSpan = TimeSpan.FromDays(14); diff --git a/src/Microsoft.AspNet.Security.Facebook/FacebookAuthenticationExtensions.cs b/src/Microsoft.AspNet.Security.Facebook/FacebookAuthenticationExtensions.cs index 543827209..aa59e2efe 100644 --- a/src/Microsoft.AspNet.Security.Facebook/FacebookAuthenticationExtensions.cs +++ b/src/Microsoft.AspNet.Security.Facebook/FacebookAuthenticationExtensions.cs @@ -2,6 +2,9 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using Microsoft.AspNet.Security.Facebook; +using Microsoft.Framework.DependencyInjection; +using Microsoft.Framework.OptionsModel; +using System; namespace Microsoft.AspNet.Builder { @@ -10,35 +13,23 @@ namespace Microsoft.AspNet.Builder /// public static class FacebookAuthenticationExtensions { - /// - /// Authenticate users using Facebook. - /// - /// The passed to the configure method. - /// The appId assigned by Facebook. - /// The appSecret assigned by Facebook. - /// The updated . - public static IApplicationBuilder UseFacebookAuthentication([NotNull] this IApplicationBuilder app, [NotNull] string appId, [NotNull] string appSecret) + public static IServiceCollection ConfigureFacebookAuthentication([NotNull] this IServiceCollection services, [NotNull] Action configure) { - return app.UseFacebookAuthentication(new FacebookAuthenticationOptions() - { - AppId = appId, - AppSecret = appSecret, - }); + return services.ConfigureOptions(configure); } /// /// Authenticate users using Facebook. /// /// The passed to the configure method. - /// The middleware configuration options. /// The updated . - public static IApplicationBuilder UseFacebookAuthentication([NotNull] this IApplicationBuilder app, [NotNull] FacebookAuthenticationOptions options) + public static IApplicationBuilder UseFacebookAuthentication([NotNull] this IApplicationBuilder app, Action configureOptions = null, string optionsName = "") { - if (string.IsNullOrEmpty(options.SignInAsAuthenticationType)) - { - options.SignInAsAuthenticationType = app.GetDefaultSignInAsAuthenticationType(); - } - return app.UseMiddleware(options); + return app.UseMiddleware( + new OptionsAction(configureOptions ?? (o => { })) + { + Name = optionsName + }); } } } diff --git a/src/Microsoft.AspNet.Security.Facebook/FacebookAuthenticationMiddleware.cs b/src/Microsoft.AspNet.Security.Facebook/FacebookAuthenticationMiddleware.cs index 2d653d7c2..a453e085a 100644 --- a/src/Microsoft.AspNet.Security.Facebook/FacebookAuthenticationMiddleware.cs +++ b/src/Microsoft.AspNet.Security.Facebook/FacebookAuthenticationMiddleware.cs @@ -8,6 +8,7 @@ using Microsoft.AspNet.Security.Infrastructure; using Microsoft.AspNet.Security.OAuth; using Microsoft.Framework.Logging; +using Microsoft.Framework.OptionsModel; namespace Microsoft.AspNet.Security.Facebook { @@ -27,8 +28,10 @@ public FacebookAuthenticationMiddleware( RequestDelegate next, IDataProtectionProvider dataProtectionProvider, ILoggerFactory loggerFactory, - FacebookAuthenticationOptions options) - : base(next, dataProtectionProvider, loggerFactory, options) + IOptionsAccessor externalOptions, + IOptionsAccessor options, + IOptionsAction configureOptions = null) + : base(next, dataProtectionProvider, loggerFactory, externalOptions, options, configureOptions) { if (string.IsNullOrWhiteSpace(Options.AppId)) { diff --git a/src/Microsoft.AspNet.Security.Facebook/FacebookAuthenticationOptions.cs b/src/Microsoft.AspNet.Security.Facebook/FacebookAuthenticationOptions.cs index 7f1199a08..172057184 100644 --- a/src/Microsoft.AspNet.Security.Facebook/FacebookAuthenticationOptions.cs +++ b/src/Microsoft.AspNet.Security.Facebook/FacebookAuthenticationOptions.cs @@ -15,8 +15,9 @@ public class FacebookAuthenticationOptions : OAuthAuthenticationOptions. /// public FacebookAuthenticationOptions() - : base(FacebookAuthenticationDefaults.AuthenticationType) { + AuthenticationType = FacebookAuthenticationDefaults.AuthenticationType; + Caption = AuthenticationType; CallbackPath = new PathString("/signin-facebook"); SendAppSecretProof = true; AuthorizationEndpoint = FacebookAuthenticationDefaults.AuthorizationEndpoint; diff --git a/src/Microsoft.AspNet.Security.Facebook/project.json b/src/Microsoft.AspNet.Security.Facebook/project.json index 6ad815156..06da113a7 100644 --- a/src/Microsoft.AspNet.Security.Facebook/project.json +++ b/src/Microsoft.AspNet.Security.Facebook/project.json @@ -7,6 +7,7 @@ "Microsoft.AspNet.Security.OAuth": "1.0.0-*", "Microsoft.AspNet.WebUtilities": "1.0.0-*", "Microsoft.Framework.Logging": "1.0.0-*", + "Microsoft.Framework.OptionsModel": "1.0.0-*", "Newtonsoft.Json": "6.0.4" }, "frameworks": { diff --git a/src/Microsoft.AspNet.Security.Google/GoogleAuthenticationExtensions.cs b/src/Microsoft.AspNet.Security.Google/GoogleAuthenticationExtensions.cs index 571ff5ffe..7bb4a24e2 100644 --- a/src/Microsoft.AspNet.Security.Google/GoogleAuthenticationExtensions.cs +++ b/src/Microsoft.AspNet.Security.Google/GoogleAuthenticationExtensions.cs @@ -2,6 +2,9 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using Microsoft.AspNet.Security.Google; +using Microsoft.Framework.DependencyInjection; +using Microsoft.Framework.OptionsModel; +using System; namespace Microsoft.AspNet.Builder { @@ -10,36 +13,25 @@ namespace Microsoft.AspNet.Builder /// public static class GoogleAuthenticationExtensions { - /// - /// Authenticate users using Google OAuth 2.0. - /// - /// The passed to the configure method. - /// The google assigned client id. - /// The google assigned client secret. - /// The updated . - public static IApplicationBuilder UseGoogleAuthentication([NotNull] this IApplicationBuilder app, [NotNull] string clientId, [NotNull] string clientSecret) + public static IServiceCollection ConfigureGoogleAuthentication([NotNull] this IServiceCollection services, [NotNull] Action configure) { - return app.UseGoogleAuthentication( - new GoogleAuthenticationOptions - { - ClientId = clientId, - ClientSecret = clientSecret - }); + return services.ConfigureOptions(configure); } /// /// Authenticate users using Google OAuth 2.0. /// /// The passed to the configure method. - /// Middleware configuration options. + /// Used to configure Middleware options. + /// Name of the options instance to be used /// The updated . - public static IApplicationBuilder UseGoogleAuthentication([NotNull] this IApplicationBuilder app, [NotNull] GoogleAuthenticationOptions options) + public static IApplicationBuilder UseGoogleAuthentication([NotNull] this IApplicationBuilder app, Action configureOptions = null, string optionsName = "") { - if (string.IsNullOrEmpty(options.SignInAsAuthenticationType)) - { - options.SignInAsAuthenticationType = app.GetDefaultSignInAsAuthenticationType(); - } - return app.UseMiddleware(options); + return app.UseMiddleware( + new OptionsAction(configureOptions ?? (o => { })) + { + Name = optionsName + }); } } } \ No newline at end of file diff --git a/src/Microsoft.AspNet.Security.Google/GoogleAuthenticationMiddleware.cs b/src/Microsoft.AspNet.Security.Google/GoogleAuthenticationMiddleware.cs index 08d7610fa..66cef2e2a 100644 --- a/src/Microsoft.AspNet.Security.Google/GoogleAuthenticationMiddleware.cs +++ b/src/Microsoft.AspNet.Security.Google/GoogleAuthenticationMiddleware.cs @@ -11,6 +11,7 @@ using Microsoft.AspNet.Security.Infrastructure; using Microsoft.AspNet.Security.OAuth; using Microsoft.Framework.Logging; +using Microsoft.Framework.OptionsModel; namespace Microsoft.AspNet.Security.Google { @@ -31,8 +32,10 @@ public GoogleAuthenticationMiddleware( RequestDelegate next, IDataProtectionProvider dataProtectionProvider, ILoggerFactory loggerFactory, - GoogleAuthenticationOptions options) - : base(next, dataProtectionProvider, loggerFactory, options) + IOptionsAccessor externalOptions, + IOptionsAccessor options, + IOptionsAction configureOptions = null) + : base(next, dataProtectionProvider, loggerFactory, externalOptions, options, configureOptions) { if (Options.Notifications == null) { diff --git a/src/Microsoft.AspNet.Security.Google/GoogleAuthenticationOptions.cs b/src/Microsoft.AspNet.Security.Google/GoogleAuthenticationOptions.cs index 0b8e3ab09..4cfb97bbb 100644 --- a/src/Microsoft.AspNet.Security.Google/GoogleAuthenticationOptions.cs +++ b/src/Microsoft.AspNet.Security.Google/GoogleAuthenticationOptions.cs @@ -19,8 +19,9 @@ public class GoogleAuthenticationOptions : OAuthAuthenticationOptions. /// public GoogleAuthenticationOptions() - : base(GoogleAuthenticationDefaults.AuthenticationType) { + AuthenticationType = GoogleAuthenticationDefaults.AuthenticationType; + Caption = AuthenticationType; CallbackPath = new PathString("/signin-google"); AuthorizationEndpoint = GoogleAuthenticationDefaults.AuthorizationEndpoint; TokenEndpoint = GoogleAuthenticationDefaults.TokenEndpoint; diff --git a/src/Microsoft.AspNet.Security.Google/project.json b/src/Microsoft.AspNet.Security.Google/project.json index 6ad815156..0cc8fa118 100644 --- a/src/Microsoft.AspNet.Security.Google/project.json +++ b/src/Microsoft.AspNet.Security.Google/project.json @@ -7,7 +7,8 @@ "Microsoft.AspNet.Security.OAuth": "1.0.0-*", "Microsoft.AspNet.WebUtilities": "1.0.0-*", "Microsoft.Framework.Logging": "1.0.0-*", - "Newtonsoft.Json": "6.0.4" + "Microsoft.Framework.OptionsModel": "1.0.0-*", + "Newtonsoft.Json": "6.0.4", }, "frameworks": { "aspnet50": { diff --git a/src/Microsoft.AspNet.Security.MicrosoftAccount/MicrosoftAccountAuthenticationExtensions.cs b/src/Microsoft.AspNet.Security.MicrosoftAccount/MicrosoftAccountAuthenticationExtensions.cs index 9963abf1d..64ec369ab 100644 --- a/src/Microsoft.AspNet.Security.MicrosoftAccount/MicrosoftAccountAuthenticationExtensions.cs +++ b/src/Microsoft.AspNet.Security.MicrosoftAccount/MicrosoftAccountAuthenticationExtensions.cs @@ -2,6 +2,9 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using Microsoft.AspNet.Security.MicrosoftAccount; +using Microsoft.Framework.DependencyInjection; +using Microsoft.Framework.OptionsModel; +using System; namespace Microsoft.AspNet.Builder { @@ -10,36 +13,18 @@ namespace Microsoft.AspNet.Builder /// public static class MicrosoftAccountAuthenticationExtensions { - /// - /// Authenticate users using Microsoft Account. - /// - /// The passed to the configure method. - /// The application client ID assigned by the Microsoft authentication service. - /// The application client secret assigned by the Microsoft authentication service. - /// The updated . - public static IApplicationBuilder UseMicrosoftAccountAuthentication([NotNull] this IApplicationBuilder app, [NotNull] string clientId, [NotNull] string clientSecret) + public static IServiceCollection ConfigureMicrosoftAccountAuthentication([NotNull] this IServiceCollection services, [NotNull] Action configure) { - return app.UseMicrosoftAccountAuthentication( - new MicrosoftAccountAuthenticationOptions - { - ClientId = clientId, - ClientSecret = clientSecret, - }); + return services.ConfigureOptions(configure); } - /// - /// Authenticate users using Microsoft Account. - /// - /// The passed to the configure method. - /// The middleware configuration options. - /// The updated . - public static IApplicationBuilder UseMicrosoftAccountAuthentication([NotNull] this IApplicationBuilder app, [NotNull] MicrosoftAccountAuthenticationOptions options) + public static IApplicationBuilder UseMicrosoftAccountAuthentication([NotNull] this IApplicationBuilder app, Action configureOptions = null, string optionsName = "") { - if (string.IsNullOrEmpty(options.SignInAsAuthenticationType)) - { - options.SignInAsAuthenticationType = app.GetDefaultSignInAsAuthenticationType(); - } - return app.UseMiddleware(options); + return app.UseMiddleware( + new OptionsAction(configureOptions ?? (o => { })) + { + Name = optionsName + }); } } } diff --git a/src/Microsoft.AspNet.Security.MicrosoftAccount/MicrosoftAccountAuthenticationMiddleware.cs b/src/Microsoft.AspNet.Security.MicrosoftAccount/MicrosoftAccountAuthenticationMiddleware.cs index 29ad5c5ef..c36ad16de 100644 --- a/src/Microsoft.AspNet.Security.MicrosoftAccount/MicrosoftAccountAuthenticationMiddleware.cs +++ b/src/Microsoft.AspNet.Security.MicrosoftAccount/MicrosoftAccountAuthenticationMiddleware.cs @@ -8,6 +8,7 @@ using Microsoft.AspNet.Security.Infrastructure; using Microsoft.AspNet.Security.OAuth; using Microsoft.Framework.Logging; +using Microsoft.Framework.OptionsModel; namespace Microsoft.AspNet.Security.MicrosoftAccount { @@ -27,8 +28,10 @@ public MicrosoftAccountAuthenticationMiddleware( RequestDelegate next, IDataProtectionProvider dataProtectionProvider, ILoggerFactory loggerFactory, - MicrosoftAccountAuthenticationOptions options) - : base(next, dataProtectionProvider, loggerFactory, options) + IOptionsAccessor externalOptions, + IOptionsAccessor options, + IOptionsAction configureOptions = null) + : base(next, dataProtectionProvider, loggerFactory, externalOptions, options, configureOptions) { if (Options.Notifications == null) { diff --git a/src/Microsoft.AspNet.Security.MicrosoftAccount/MicrosoftAccountAuthenticationOptions.cs b/src/Microsoft.AspNet.Security.MicrosoftAccount/MicrosoftAccountAuthenticationOptions.cs index 24d2599cb..8755de63b 100644 --- a/src/Microsoft.AspNet.Security.MicrosoftAccount/MicrosoftAccountAuthenticationOptions.cs +++ b/src/Microsoft.AspNet.Security.MicrosoftAccount/MicrosoftAccountAuthenticationOptions.cs @@ -15,8 +15,9 @@ public class MicrosoftAccountAuthenticationOptions : OAuthAuthenticationOptions< /// Initializes a new . /// public MicrosoftAccountAuthenticationOptions() - : base(MicrosoftAccountAuthenticationDefaults.AuthenticationType) { + AuthenticationType = MicrosoftAccountAuthenticationDefaults.AuthenticationType; + Caption = AuthenticationType; CallbackPath = new PathString("/signin-microsoft"); AuthorizationEndpoint = MicrosoftAccountAuthenticationDefaults.AuthorizationEndpoint; TokenEndpoint = MicrosoftAccountAuthenticationDefaults.TokenEndpoint; diff --git a/src/Microsoft.AspNet.Security.MicrosoftAccount/project.json b/src/Microsoft.AspNet.Security.MicrosoftAccount/project.json index c0c9fa206..08fee1520 100644 --- a/src/Microsoft.AspNet.Security.MicrosoftAccount/project.json +++ b/src/Microsoft.AspNet.Security.MicrosoftAccount/project.json @@ -7,6 +7,7 @@ "Microsoft.AspNet.Security.OAuth": "1.0.0-*", "Microsoft.AspNet.WebUtilities": "1.0.0-*", "Microsoft.Framework.Logging": "1.0.0-*", + "Microsoft.Framework.OptionsModel": "1.0.0-*", "Newtonsoft.Json": "6.0.4" }, "frameworks": { diff --git a/src/Microsoft.AspNet.Security.OAuth/OAuthAuthenticationExtensions.cs b/src/Microsoft.AspNet.Security.OAuth/OAuthAuthenticationExtensions.cs index 0b6f0ddec..bdbc3c9ee 100644 --- a/src/Microsoft.AspNet.Security.OAuth/OAuthAuthenticationExtensions.cs +++ b/src/Microsoft.AspNet.Security.OAuth/OAuthAuthenticationExtensions.cs @@ -4,6 +4,8 @@ using System; using System.Globalization; using Microsoft.AspNet.Security.OAuth; +using Microsoft.AspNet.Security.Infrastructure; +using Microsoft.Framework.OptionsModel; namespace Microsoft.AspNet.Builder { @@ -18,17 +20,21 @@ public static class OAuthAuthenticationExtensions /// The passed to the configure method. /// The middleware configuration options. /// The updated . - public static IApplicationBuilder UseOAuthAuthentication([NotNull] this IApplicationBuilder app, [NotNull] OAuthAuthenticationOptions options) + public static IApplicationBuilder UseOAuthAuthentication([NotNull] this IApplicationBuilder app, [NotNull] string authenticationType, Action> configureOptions = null) { - if (string.IsNullOrEmpty(options.SignInAsAuthenticationType)) - { - options.SignInAsAuthenticationType = app.GetDefaultSignInAsAuthenticationType(); - } - if (options.Notifications == null) - { - options.Notifications = new OAuthAuthenticationNotifications(); - } - return app.UseMiddleware, IOAuthAuthenticationNotifications>>(options); + return app.UseMiddleware, IOAuthAuthenticationNotifications>>( + new OptionsAction>(options => + { + options.AuthenticationType = authenticationType; + options.Caption = authenticationType; + if (configureOptions != null) + { + configureOptions(options); + } + }) + { + Name = authenticationType, + }); } } } diff --git a/src/Microsoft.AspNet.Security.OAuth/OAuthAuthenticationMiddleware.cs b/src/Microsoft.AspNet.Security.OAuth/OAuthAuthenticationMiddleware.cs index 009b02548..e3d65c55b 100644 --- a/src/Microsoft.AspNet.Security.OAuth/OAuthAuthenticationMiddleware.cs +++ b/src/Microsoft.AspNet.Security.OAuth/OAuthAuthenticationMiddleware.cs @@ -10,6 +10,7 @@ using Microsoft.AspNet.Security.DataProtection; using Microsoft.AspNet.Security.Infrastructure; using Microsoft.Framework.Logging; +using Microsoft.Framework.OptionsModel; namespace Microsoft.AspNet.Security.OAuth { @@ -18,7 +19,7 @@ namespace Microsoft.AspNet.Security.OAuth /// [SuppressMessage("Microsoft.Design", "CA1001:TypesThatOwnDisposableFieldsShouldBeDisposable", Justification = "Middleware are not disposable.")] public class OAuthAuthenticationMiddleware : AuthenticationMiddleware - where TOptions : OAuthAuthenticationOptions + where TOptions : OAuthAuthenticationOptions, new() where TNotifications : IOAuthAuthenticationNotifications { /// @@ -32,9 +33,16 @@ public OAuthAuthenticationMiddleware( RequestDelegate next, IDataProtectionProvider dataProtectionProvider, ILoggerFactory loggerFactory, - TOptions options) - : base(next, options) + IOptionsAccessor externalOptions, + IOptionsAccessor options, + IOptionsAction configureOptions = null) + : base(next, options, configureOptions) { + // todo: review error handling + if (string.IsNullOrWhiteSpace(Options.AuthenticationType)) + { + throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, Resources.Exception_OptionMustBeProvided, "AuthenticationType")); + } if (string.IsNullOrWhiteSpace(Options.ClientId)) { throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, Resources.Exception_OptionMustBeProvided, "ClientId")); @@ -57,7 +65,7 @@ public OAuthAuthenticationMiddleware( if (Options.StateDataFormat == null) { IDataProtector dataProtector = DataProtectionHelpers.CreateDataProtector(dataProtectionProvider, - this.GetType().FullName, options.AuthenticationType, "v1"); + this.GetType().FullName, Options.AuthenticationType, "v1"); Options.StateDataFormat = new PropertiesDataFormat(dataProtector); } @@ -65,6 +73,15 @@ public OAuthAuthenticationMiddleware( Backchannel.DefaultRequestHeaders.UserAgent.ParseAdd("Microsoft ASP.NET OAuth middleware"); Backchannel.Timeout = Options.BackchannelTimeout; Backchannel.MaxResponseContentBufferSize = 1024 * 1024 * 10; // 10 MB + + if (string.IsNullOrEmpty(Options.SignInAsAuthenticationType)) + { + Options.SignInAsAuthenticationType = externalOptions.Options.SignInAsAuthenticationType; + } + if (string.IsNullOrEmpty(Options.SignInAsAuthenticationType)) + { + throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, Resources.Exception_OptionMustBeProvided, "SignInAsAuthenticationType")); + } } protected HttpClient Backchannel { get; private set; } diff --git a/src/Microsoft.AspNet.Security.OAuth/OAuthAuthenticationOptions.cs b/src/Microsoft.AspNet.Security.OAuth/OAuthAuthenticationOptions.cs index 69e889744..cee784185 100644 --- a/src/Microsoft.AspNet.Security.OAuth/OAuthAuthenticationOptions.cs +++ b/src/Microsoft.AspNet.Security.OAuth/OAuthAuthenticationOptions.cs @@ -18,10 +18,8 @@ public class OAuthAuthenticationOptions : AuthenticationOptions /// /// Initializes a new . /// - public OAuthAuthenticationOptions([NotNull] string authenticationType) - : base(authenticationType) + public OAuthAuthenticationOptions() { - Caption = authenticationType; AuthenticationMode = AuthenticationMode.Passive; Scope = new List(); BackchannelTimeout = TimeSpan.FromSeconds(60); @@ -69,9 +67,6 @@ public OAuthAuthenticationOptions([NotNull] string authenticationType) /// /// Get or sets the text that the user can display on a sign in user interface. /// - /// - /// The default value is the authentication type. - /// public string Caption { get { return Description.Caption; } diff --git a/src/Microsoft.AspNet.Security.OAuth/OAuthAuthenticationOptions`1.cs b/src/Microsoft.AspNet.Security.OAuth/OAuthAuthenticationOptions`1.cs index 65f01b5b8..2eb1bfb89 100644 --- a/src/Microsoft.AspNet.Security.OAuth/OAuthAuthenticationOptions`1.cs +++ b/src/Microsoft.AspNet.Security.OAuth/OAuthAuthenticationOptions`1.cs @@ -8,14 +8,6 @@ namespace Microsoft.AspNet.Security.OAuth /// public class OAuthAuthenticationOptions : OAuthAuthenticationOptions where TNotifications : IOAuthAuthenticationNotifications { - /// - /// Initializes a new . - /// - public OAuthAuthenticationOptions([NotNull] string authenticationType) - : base(authenticationType) - { - } - /// /// Gets or sets the used to handle authentication events. /// diff --git a/src/Microsoft.AspNet.Security.Twitter/TwitterAuthenticationExtensions.cs b/src/Microsoft.AspNet.Security.Twitter/TwitterAuthenticationExtensions.cs index aa56249cc..9f2c54ce1 100644 --- a/src/Microsoft.AspNet.Security.Twitter/TwitterAuthenticationExtensions.cs +++ b/src/Microsoft.AspNet.Security.Twitter/TwitterAuthenticationExtensions.cs @@ -1,7 +1,11 @@ // Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. +using Microsoft.AspNet.Security.Infrastructure; using Microsoft.AspNet.Security.Twitter; +using Microsoft.Framework.DependencyInjection; +using Microsoft.Framework.OptionsModel; +using System; namespace Microsoft.AspNet.Builder { @@ -10,36 +14,18 @@ namespace Microsoft.AspNet.Builder /// public static class TwitterAuthenticationExtensions { - /// - /// Authenticate users using Twitter - /// - /// The passed to the configure method - /// The Twitter-issued consumer key - /// The Twitter-issued consumer secret - /// The updated - public static IApplicationBuilder UseTwitterAuthentication([NotNull] this IApplicationBuilder app, [NotNull] string consumerKey, [NotNull] string consumerSecret) + public static IServiceCollection ConfigureTwitterAuthentication([NotNull] this IServiceCollection services, [NotNull] Action configure) { - return app.UseTwitterAuthentication( - new TwitterAuthenticationOptions - { - ConsumerKey = consumerKey, - ConsumerSecret = consumerSecret, - }); + return services.ConfigureOptions(configure); } - /// - /// Authenticate users using Twitter - /// - /// The passed to the configure method - /// Middleware configuration options - /// The updated - public static IApplicationBuilder UseTwitterAuthentication([NotNull] this IApplicationBuilder app, [NotNull] TwitterAuthenticationOptions options) + public static IApplicationBuilder UseTwitterAuthentication([NotNull] this IApplicationBuilder app, Action configureOptions = null, string optionsName = "") { - if (string.IsNullOrEmpty(options.SignInAsAuthenticationType)) - { - options.SignInAsAuthenticationType = app.GetDefaultSignInAsAuthenticationType(); - } - return app.UseMiddleware(options); + return app.UseMiddleware( + new OptionsAction(configureOptions ?? (o => { })) + { + Name = optionsName + }); } } } diff --git a/src/Microsoft.AspNet.Security.Twitter/TwitterAuthenticationMiddleware.cs b/src/Microsoft.AspNet.Security.Twitter/TwitterAuthenticationMiddleware.cs index 596176219..ffa9b9bb6 100644 --- a/src/Microsoft.AspNet.Security.Twitter/TwitterAuthenticationMiddleware.cs +++ b/src/Microsoft.AspNet.Security.Twitter/TwitterAuthenticationMiddleware.cs @@ -12,6 +12,7 @@ using Microsoft.AspNet.Security.Infrastructure; using Microsoft.AspNet.Security.Twitter.Messages; using Microsoft.Framework.Logging; +using Microsoft.Framework.OptionsModel; namespace Microsoft.AspNet.Security.Twitter { @@ -35,8 +36,10 @@ public TwitterAuthenticationMiddleware( RequestDelegate next, IDataProtectionProvider dataProtectionProvider, ILoggerFactory loggerFactory, - TwitterAuthenticationOptions options) - : base(next, options) + IOptionsAccessor externalOptions, + IOptionsAccessor options, + IOptionsAction configureOptions = null) + : base(next, options, configureOptions) { if (string.IsNullOrWhiteSpace(Options.ConsumerSecret)) { @@ -56,13 +59,22 @@ public TwitterAuthenticationMiddleware( if (Options.StateDataFormat == null) { IDataProtector dataProtector = DataProtectionHelpers.CreateDataProtector(dataProtectionProvider, - typeof(TwitterAuthenticationMiddleware).FullName, options.AuthenticationType, "v1"); + typeof(TwitterAuthenticationMiddleware).FullName, Options.AuthenticationType, "v1"); Options.StateDataFormat = new SecureDataFormat( Serializers.RequestToken, dataProtector, TextEncodings.Base64Url); } + if (string.IsNullOrEmpty(Options.SignInAsAuthenticationType)) + { + Options.SignInAsAuthenticationType = externalOptions.Options.SignInAsAuthenticationType; + } + if (string.IsNullOrEmpty(Options.SignInAsAuthenticationType)) + { + throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, Resources.Exception_OptionMustBeProvided, "SignInAsAuthenticationType")); + } + _httpClient = new HttpClient(ResolveHttpMessageHandler(Options)); _httpClient.Timeout = Options.BackchannelTimeout; _httpClient.MaxResponseContentBufferSize = 1024 * 1024 * 10; // 10 MB diff --git a/src/Microsoft.AspNet.Security.Twitter/TwitterAuthenticationOptions.cs b/src/Microsoft.AspNet.Security.Twitter/TwitterAuthenticationOptions.cs index 043911e75..91207863d 100644 --- a/src/Microsoft.AspNet.Security.Twitter/TwitterAuthenticationOptions.cs +++ b/src/Microsoft.AspNet.Security.Twitter/TwitterAuthenticationOptions.cs @@ -17,9 +17,9 @@ public class TwitterAuthenticationOptions : AuthenticationOptions /// Initializes a new instance of the class. /// public TwitterAuthenticationOptions() - : base(TwitterAuthenticationDefaults.AuthenticationType) { - Caption = TwitterAuthenticationDefaults.AuthenticationType; + AuthenticationType = TwitterAuthenticationDefaults.AuthenticationType; + Caption = AuthenticationType; CallbackPath = new PathString("/signin-twitter"); AuthenticationMode = AuthenticationMode.Passive; BackchannelTimeout = TimeSpan.FromSeconds(60); diff --git a/src/Microsoft.AspNet.Security.Twitter/project.json b/src/Microsoft.AspNet.Security.Twitter/project.json index 5f1c34c94..f5e8ef324 100644 --- a/src/Microsoft.AspNet.Security.Twitter/project.json +++ b/src/Microsoft.AspNet.Security.Twitter/project.json @@ -6,6 +6,7 @@ "Microsoft.AspNet.Security.DataProtection": "1.0.0-*", "Microsoft.AspNet.WebUtilities": "1.0.0-*", "Microsoft.Framework.Logging": "1.0.0-*", + "Microsoft.Framework.OptionsModel": "1.0.0-*", "Newtonsoft.Json": "6.0.4" }, "frameworks": { diff --git a/src/Microsoft.AspNet.Security/AuthenticationOptions.cs b/src/Microsoft.AspNet.Security/AuthenticationOptions.cs index 77e8fa03a..e25383cfe 100644 --- a/src/Microsoft.AspNet.Security/AuthenticationOptions.cs +++ b/src/Microsoft.AspNet.Security/AuthenticationOptions.cs @@ -17,17 +17,6 @@ public abstract class AuthenticationOptions { private string _authenticationType; - /// - /// Initialize properties of AuthenticationOptions base class - /// - /// Assigned to the AuthenticationType property - protected AuthenticationOptions(string authenticationType) - { - Description = new AuthenticationDescription(); - AuthenticationType = authenticationType; - AuthenticationMode = AuthenticationMode.Active; - } - /// /// The AuthenticationType in the options corresponds to the IIdentity AuthenticationType property. A different /// value may be assigned in order to use the same authentication middleware type more than once in a pipeline. @@ -47,11 +36,11 @@ public string AuthenticationType /// alter 401 Unauthorized responses going out. If Passive the authentication middleware will only provide /// identity and alter responses when explicitly indicated by the AuthenticationType. /// - public AuthenticationMode AuthenticationMode { get; set; } + public AuthenticationMode AuthenticationMode { get; set; } = AuthenticationMode.Active; /// /// Additional information about the authentication type which is made available to the application. /// - public AuthenticationDescription Description { get; set; } + public AuthenticationDescription Description { get; set; } = new AuthenticationDescription(); } } diff --git a/src/Microsoft.AspNet.Security/BuilderSecurityExtensions.cs b/src/Microsoft.AspNet.Security/BuilderSecurityExtensions.cs deleted file mode 100644 index 5a9aec367..000000000 --- a/src/Microsoft.AspNet.Security/BuilderSecurityExtensions.cs +++ /dev/null @@ -1,45 +0,0 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System; -using Microsoft.AspNet.Security; - -namespace Microsoft.AspNet.Builder -{ - /// - /// Provides extensions methods for app.Property values that are only needed by implementations of authentication middleware. - /// - public static class BuilderSecurityExtensions - { - /// - /// Returns the previously set AuthenticationType that external sign in middleware should use when the - /// browser navigates back to their return url. - /// - /// App builder passed to the application startup code - /// - public static string GetDefaultSignInAsAuthenticationType([NotNull] this IApplicationBuilder app) - { - object value; - if (app.Properties.TryGetValue(Constants.DefaultSignInAsAuthenticationType, out value)) - { - var authenticationType = value as string; - if (!string.IsNullOrEmpty(authenticationType)) - { - return authenticationType; - } - } - throw new InvalidOperationException(Resources.Exception_MissingDefaultSignInAsAuthenticationType); - } - - /// - /// Called by middleware to change the name of the AuthenticationType that external middleware should use - /// when the browser navigates back to their return url. - /// - /// App builder passed to the application startup code - /// AuthenticationType that external middleware should sign in as. - public static void SetDefaultSignInAsAuthenticationType([NotNull] this IApplicationBuilder app, [NotNull] string authenticationType) - { - app.Properties[Constants.DefaultSignInAsAuthenticationType] = authenticationType; - } - } -} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Security/Constants.cs b/src/Microsoft.AspNet.Security/Constants.cs deleted file mode 100644 index d1bc8f01e..000000000 --- a/src/Microsoft.AspNet.Security/Constants.cs +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - - -namespace Microsoft.AspNet.Security -{ - /// - /// String constants used only by the Security assembly - /// - internal static class Constants - { - /// - /// Used by middleware extension methods to coordinate the default value Options property SignInAsAuthenticationType - /// - internal const string DefaultSignInAsAuthenticationType = "Microsoft.AspNet.Security.DefaultSignInAsAuthenticationType"; - } -} diff --git a/src/Microsoft.AspNet.Security/ExternalAuthenticationOptions.cs b/src/Microsoft.AspNet.Security/ExternalAuthenticationOptions.cs new file mode 100644 index 000000000..671020b2b --- /dev/null +++ b/src/Microsoft.AspNet.Security/ExternalAuthenticationOptions.cs @@ -0,0 +1,13 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + + +using System; + +namespace Microsoft.AspNet.Security +{ + public class ExternalAuthenticationOptions + { + public string SignInAsAuthenticationType { get; set; } + } +} diff --git a/src/Microsoft.AspNet.Security/Infrastructure/AuthenticationMiddleware.cs b/src/Microsoft.AspNet.Security/Infrastructure/AuthenticationMiddleware.cs index 8077b22d6..1ea787fce 100644 --- a/src/Microsoft.AspNet.Security/Infrastructure/AuthenticationMiddleware.cs +++ b/src/Microsoft.AspNet.Security/Infrastructure/AuthenticationMiddleware.cs @@ -6,19 +6,30 @@ using System.Threading.Tasks; using Microsoft.AspNet.Builder; using Microsoft.AspNet.Http; +using Microsoft.Framework.OptionsModel; namespace Microsoft.AspNet.Security.Infrastructure { - public abstract class AuthenticationMiddleware where TOptions : AuthenticationOptions + public abstract class AuthenticationMiddleware where TOptions : AuthenticationOptions, new() { private readonly RequestDelegate _next; - protected AuthenticationMiddleware([NotNull] RequestDelegate next, [NotNull] TOptions options) + protected AuthenticationMiddleware([NotNull] RequestDelegate next, [NotNull] IOptionsAccessor options, IOptionsAction configureOptions) { - Options = options; + if (configureOptions != null) + { + Options = options.GetNamedOptions(configureOptions.Name); + configureOptions.Invoke(Options); + } + else + { + Options = options.Options; + } _next = next; } + public string AuthenticationType { get; set; } + public TOptions Options { get; set; } public async Task Invoke(HttpContext context) diff --git a/src/Microsoft.AspNet.Security/Resources.resx b/src/Microsoft.AspNet.Security/Resources.resx index f0765cc32..77060045e 100644 --- a/src/Microsoft.AspNet.Security/Resources.resx +++ b/src/Microsoft.AspNet.Security/Resources.resx @@ -123,9 +123,6 @@ The state passed to UnhookAuthentication may only be the return value from HookAuthentication. - - A default value for SignInAsAuthenticationType was not found in IApplicationBuilder Properties. This can happen if your authentication middleware are added in the wrong order, or if one is missing. - The AuthenticationTokenProvider's required synchronous events have not been registered. diff --git a/src/Microsoft.AspNet.Security/project.json b/src/Microsoft.AspNet.Security/project.json index 11854a0e1..502d45043 100644 --- a/src/Microsoft.AspNet.Security/project.json +++ b/src/Microsoft.AspNet.Security/project.json @@ -5,7 +5,8 @@ "Microsoft.AspNet.PipelineCore": "1.0.0-*", "Microsoft.AspNet.Security.DataProtection": "1.0.0-*", "Microsoft.Framework.DependencyInjection": "1.0.0-*", - "Microsoft.Framework.Logging": "1.0.0-*" + "Microsoft.Framework.Logging": "1.0.0-*", + "Microsoft.Framework.OptionsModel": "1.0.0-*" }, "frameworks": { "aspnet50": { }, diff --git a/test/Microsoft.AspNet.Security.Test/Cookies/CookieMiddlewareTests.cs b/test/Microsoft.AspNet.Security.Test/Cookies/CookieMiddlewareTests.cs index 6578ba600..a02dc1475 100644 --- a/test/Microsoft.AspNet.Security.Test/Cookies/CookieMiddlewareTests.cs +++ b/test/Microsoft.AspNet.Security.Test/Cookies/CookieMiddlewareTests.cs @@ -18,6 +18,8 @@ using Microsoft.AspNet.TestHost; using Shouldly; using Xunit; +using Microsoft.Framework.OptionsModel; +using Microsoft.Framework.DependencyInjection; namespace Microsoft.AspNet.Security.Cookies { @@ -26,7 +28,7 @@ public class CookieMiddlewareTests [Fact] public async Task NormalRequestPassesThrough() { - TestServer server = CreateServer(new CookieAuthenticationOptions + TestServer server = CreateServer(options => { }); HttpResponseMessage response = await server.CreateClient().GetAsync("http://example.com/normal"); @@ -36,9 +38,9 @@ public async Task NormalRequestPassesThrough() [Fact] public async Task ProtectedRequestShouldRedirectToLogin() { - TestServer server = CreateServer(new CookieAuthenticationOptions + TestServer server = CreateServer(options => { - LoginPath = new PathString("/login") + options.LoginPath = new PathString("/login"); }); Transaction transaction = await SendAsync(server, "http://example.com/protected"); @@ -53,9 +55,9 @@ public async Task ProtectedRequestShouldRedirectToLogin() [Fact] public async Task ProtectedCustomRequestShouldRedirectToCustomLogin() { - TestServer server = CreateServer(new CookieAuthenticationOptions + TestServer server = CreateServer(options => { - LoginPath = new PathString("/login") + options.LoginPath = new PathString("/login"); }); Transaction transaction = await SendAsync(server, "http://example.com/protected/CustomRedirect"); @@ -77,10 +79,10 @@ private Task SignInAsAlice(HttpContext context) [Fact] public async Task SignInCausesDefaultCookieToBeCreated() { - TestServer server = CreateServer(new CookieAuthenticationOptions + TestServer server = CreateServer(options => { - LoginPath = new PathString("/login"), - CookieName = "TestCookie", + options.LoginPath = new PathString("/login"); + options.CookieName = "TestCookie"; }, SignInAsAlice); Transaction transaction = await SendAsync(server, "http://example.com/testpath"); @@ -106,11 +108,11 @@ public async Task SecureSignInCausesSecureOnlyCookieByDefault( string requestUri, bool shouldBeSecureOnly) { - TestServer server = CreateServer(new CookieAuthenticationOptions + TestServer server = CreateServer(options => { - LoginPath = new PathString("/login"), - CookieName = "TestCookie", - CookieSecure = cookieSecureOption + options.LoginPath = new PathString("/login"); + options.CookieName = "TestCookie"; + options.CookieSecure = cookieSecureOption; }, SignInAsAlice); Transaction transaction = await SendAsync(server, requestUri); @@ -129,22 +131,22 @@ public async Task SecureSignInCausesSecureOnlyCookieByDefault( [Fact] public async Task CookieOptionsAlterSetCookieHeader() { - TestServer server1 = CreateServer(new CookieAuthenticationOptions + TestServer server1 = CreateServer(options => { - CookieName = "TestCookie", - CookiePath = "/foo", - CookieDomain = "another.com", - CookieSecure = CookieSecureOption.Always, - CookieHttpOnly = true, + options.CookieName = "TestCookie"; + options.CookiePath = "/foo"; + options.CookieDomain = "another.com"; + options.CookieSecure = CookieSecureOption.Always; + options.CookieHttpOnly = true; }, SignInAsAlice); Transaction transaction1 = await SendAsync(server1, "http://example.com/testpath"); - TestServer server2 = CreateServer(new CookieAuthenticationOptions + TestServer server2 = CreateServer(options => { - CookieName = "SecondCookie", - CookieSecure = CookieSecureOption.Never, - CookieHttpOnly = false, + options.CookieName = "SecondCookie"; + options.CookieSecure = CookieSecureOption.Never; + options.CookieHttpOnly = false; }, SignInAsAlice); Transaction transaction2 = await SendAsync(server2, "http://example.com/testpath"); @@ -168,9 +170,9 @@ public async Task CookieOptionsAlterSetCookieHeader() public async Task CookieContainsIdentity() { var clock = new TestClock(); - TestServer server = CreateServer(new CookieAuthenticationOptions + TestServer server = CreateServer(options => { - SystemClock = clock + options.SystemClock = clock; }, SignInAsAlice); Transaction transaction1 = await SendAsync(server, "http://example.com/testpath"); @@ -184,11 +186,11 @@ public async Task CookieContainsIdentity() public async Task CookieStopsWorkingAfterExpiration() { var clock = new TestClock(); - TestServer server = CreateServer(new CookieAuthenticationOptions + TestServer server = CreateServer(options => { - SystemClock = clock, - ExpireTimeSpan = TimeSpan.FromMinutes(10), - SlidingExpiration = false, + options.SystemClock = clock; + options.ExpireTimeSpan = TimeSpan.FromMinutes(10); + options.SlidingExpiration = false; }, SignInAsAlice); Transaction transaction1 = await SendAsync(server, "http://example.com/testpath"); @@ -215,11 +217,11 @@ public async Task CookieStopsWorkingAfterExpiration() public async Task CookieExpirationCanBeOverridenInSignin() { var clock = new TestClock(); - TestServer server = CreateServer(new CookieAuthenticationOptions + TestServer server = CreateServer(options => { - SystemClock = clock, - ExpireTimeSpan = TimeSpan.FromMinutes(10), - SlidingExpiration = false, + options.SystemClock = clock; + options.ExpireTimeSpan = TimeSpan.FromMinutes(10); + options.SlidingExpiration = false; }, context => { @@ -253,18 +255,18 @@ public async Task CookieExpirationCanBeOverridenInSignin() public async Task CookieExpirationCanBeOverridenInEvent() { var clock = new TestClock(); - TestServer server = CreateServer(new CookieAuthenticationOptions + TestServer server = CreateServer(options => { - SystemClock = clock, - ExpireTimeSpan = TimeSpan.FromMinutes(10), - SlidingExpiration = false, - Notifications = new CookieAuthenticationNotifications() + options.SystemClock = clock; + options.ExpireTimeSpan = TimeSpan.FromMinutes(10); + options.SlidingExpiration = false; + options.Notifications = new CookieAuthenticationNotifications() { OnResponseSignIn = context => { context.Properties.ExpiresUtc = clock.UtcNow.Add(TimeSpan.FromMinutes(5)); } - } + }; }, SignInAsAlice); Transaction transaction1 = await SendAsync(server, "http://example.com/testpath"); @@ -291,11 +293,11 @@ public async Task CookieExpirationCanBeOverridenInEvent() public async Task CookieIsRenewedWithSlidingExpiration() { var clock = new TestClock(); - TestServer server = CreateServer(new CookieAuthenticationOptions + TestServer server = CreateServer(options => { - SystemClock = clock, - ExpireTimeSpan = TimeSpan.FromMinutes(10), - SlidingExpiration = true, + options.SystemClock = clock; + options.ExpireTimeSpan = TimeSpan.FromMinutes(10); + options.SlidingExpiration = true; }, SignInAsAlice); Transaction transaction1 = await SendAsync(server, "http://example.com/testpath"); @@ -328,9 +330,9 @@ public async Task CookieIsRenewedWithSlidingExpiration() [Fact] public async Task AjaxRedirectsAsExtraHeaderOnTwoHundred() { - TestServer server = CreateServer(new CookieAuthenticationOptions + TestServer server = CreateServer(options => { - LoginPath = new PathString("/login") + options.LoginPath = new PathString("/login"); }); Transaction transaction = await SendAsync(server, "http://example.com/protected", ajaxRequest: true); @@ -363,11 +365,12 @@ private static async Task GetAuthData(TestServer server, string url, s return me; } - private static TestServer CreateServer(CookieAuthenticationOptions options, Func testpath = null) + private static TestServer CreateServer(Action configureOptions, Func testpath = null) { return TestServer.Create(app => { - app.UseCookieAuthentication(options); + app.UseServices(services => { }); + app.UseCookieAuthentication(configureOptions); app.Use(async (context, next) => { var req = context.Request; diff --git a/test/Microsoft.AspNet.Security.Test/Facebook/FacebookMiddlewareTests.cs b/test/Microsoft.AspNet.Security.Test/Facebook/FacebookMiddlewareTests.cs index 672dc04ac..2f800c493 100644 --- a/test/Microsoft.AspNet.Security.Test/Facebook/FacebookMiddlewareTests.cs +++ b/test/Microsoft.AspNet.Security.Test/Facebook/FacebookMiddlewareTests.cs @@ -13,6 +13,7 @@ using Microsoft.AspNet.Security.Cookies; using Microsoft.AspNet.TestHost; using Microsoft.Framework.DependencyInjection; +using Microsoft.Framework.OptionsModel; using Shouldly; using Xunit; @@ -23,20 +24,35 @@ public class FacebookMiddlewareTests [Fact] public async Task ChallengeWillTriggerApplyRedirectEvent() { - var options = new FacebookAuthenticationOptions() - { - AppId = "Test App Id", - AppSecret = "Test App Secret", - Notifications = new FacebookAuthenticationNotifications + var server = CreateServer( + app => { - OnApplyRedirect = context => + app.UseServices(services => { - context.Response.Redirect(context.RedirectUri + "&custom=test"); - } - } - }; - var server = CreateServer( - app => app.UseFacebookAuthentication(options), + services.ConfigureFacebookAuthentication(options => + { + options.AppId = "Test App Id"; + options.AppSecret = "Test App Secret"; + options.Notifications = new FacebookAuthenticationNotifications + { + OnApplyRedirect = context => + { + context.Response.Redirect(context.RedirectUri + "&custom=test"); + } + }; + }); + services.ConfigureCookieAuthentication(options => + { + options.AuthenticationType = "External"; + }); + services.ConfigureOptions(options => + { + options.SignInAsAuthenticationType = "External"; + }); + }); + app.UseFacebookAuthentication(); + app.UseCookieAuthentication(); + }, context => { context.Response.Challenge("Facebook"); @@ -52,7 +68,27 @@ public async Task ChallengeWillTriggerApplyRedirectEvent() public async Task ChallengeWillTriggerRedirection() { var server = CreateServer( - app => app.UseFacebookAuthentication("Test App Id", "Test App Secret"), + app => + { + app.UseServices(services => + { + services.ConfigureFacebookAuthentication(options => + { + options.AppId = "Test App Id"; + options.AppSecret = "Test App Secret"; + }); + services.ConfigureCookieAuthentication(options => + { + options.AuthenticationType = "External"; + }); + services.ConfigureOptions(options => + { + options.SignInAsAuthenticationType = "External"; + }); + }); + app.UseFacebookAuthentication(); + app.UseCookieAuthentication(); + }, context => { context.Response.Challenge("Facebook"); @@ -73,11 +109,6 @@ private static TestServer CreateServer(Action configure, Fu { return TestServer.Create(app => { - app.SetDefaultSignInAsAuthenticationType("External"); - app.UseCookieAuthentication(new CookieAuthenticationOptions() - { - AuthenticationType = "External" - }); if (configure != null) { configure(app); diff --git a/test/Microsoft.AspNet.Security.Test/Google/GoogleMiddlewareTests.cs b/test/Microsoft.AspNet.Security.Test/Google/GoogleMiddlewareTests.cs index e12def60f..2a58baf16 100644 --- a/test/Microsoft.AspNet.Security.Test/Google/GoogleMiddlewareTests.cs +++ b/test/Microsoft.AspNet.Security.Test/Google/GoogleMiddlewareTests.cs @@ -19,6 +19,10 @@ using Newtonsoft.Json; using Shouldly; using Xunit; +using Microsoft.Framework.OptionsModel; +using Microsoft.Framework.DependencyInjection; +using Microsoft.AspNet.Security.DataProtection; +using Microsoft.AspNet.Security.DataHandler; namespace Microsoft.AspNet.Security.Google { @@ -29,10 +33,10 @@ public class GoogleMiddlewareTests [Fact] public async Task ChallengeWillTriggerRedirection() { - var server = CreateServer(new GoogleAuthenticationOptions() + var server = CreateServer(options => { - ClientId = "Test Id", - ClientSecret = "Test Secret" + options.ClientId = "Test Id"; + options.ClientSecret = "Test Secret"; }); var transaction = await SendAsync(server, "https://example.com/challenge"); transaction.Response.StatusCode.ShouldBe(HttpStatusCode.Redirect); @@ -51,11 +55,11 @@ public async Task ChallengeWillTriggerRedirection() [Fact] public async Task Challenge401WillTriggerRedirection() { - var server = CreateServer(new GoogleAuthenticationOptions() + var server = CreateServer(options => { - ClientId = "Test Id", - ClientSecret = "Test Secret", - AuthenticationMode = AuthenticationMode.Active, + options.ClientId = "Test Id"; + options.ClientSecret = "Test Secret"; + options.AuthenticationMode = AuthenticationMode.Active; }); var transaction = await SendAsync(server, "https://example.com/401"); transaction.Response.StatusCode.ShouldBe(HttpStatusCode.Redirect); @@ -70,10 +74,10 @@ public async Task Challenge401WillTriggerRedirection() [Fact] public async Task ChallengeWillSetCorrelationCookie() { - var server = CreateServer(new GoogleAuthenticationOptions() + var server = CreateServer(options => { - ClientId = "Test Id", - ClientSecret = "Test Secret" + options.ClientId = "Test Id"; + options.ClientSecret = "Test Secret"; }); var transaction = await SendAsync(server, "https://example.com/challenge"); Console.WriteLine(transaction.SetCookie); @@ -83,11 +87,11 @@ public async Task ChallengeWillSetCorrelationCookie() [Fact] public async Task Challenge401WillSetCorrelationCookie() { - var server = CreateServer(new GoogleAuthenticationOptions() + var server = CreateServer(options => { - ClientId = "Test Id", - ClientSecret = "Test Secret", - AuthenticationMode = AuthenticationMode.Active, + options.ClientId = "Test Id"; + options.ClientSecret = "Test Secret"; + options.AuthenticationMode = AuthenticationMode.Active; }); var transaction = await SendAsync(server, "https://example.com/401"); Console.WriteLine(transaction.SetCookie); @@ -97,10 +101,11 @@ public async Task Challenge401WillSetCorrelationCookie() [Fact] public async Task ChallengeWillSetDefaultScope() { - var server = CreateServer(new GoogleAuthenticationOptions() + var server = CreateServer(options => { - ClientId = "Test Id", - ClientSecret = "Test Secret" + options.ClientId = "Test Id"; + options.ClientSecret = "Test Secret"; + options.AuthenticationMode = AuthenticationMode.Active; }); var transaction = await SendAsync(server, "https://example.com/challenge"); transaction.Response.StatusCode.ShouldBe(HttpStatusCode.Redirect); @@ -111,11 +116,11 @@ public async Task ChallengeWillSetDefaultScope() [Fact] public async Task Challenge401WillSetDefaultScope() { - var server = CreateServer(new GoogleAuthenticationOptions() + var server = CreateServer(options => { - ClientId = "Test Id", - ClientSecret = "Test Secret", - AuthenticationMode = AuthenticationMode.Active, + options.ClientId = "Test Id"; + options.ClientSecret = "Test Secret"; + options.AuthenticationMode = AuthenticationMode.Active; }); var transaction = await SendAsync(server, "https://example.com/401"); transaction.Response.StatusCode.ShouldBe(HttpStatusCode.Redirect); @@ -126,13 +131,12 @@ public async Task Challenge401WillSetDefaultScope() [Fact] public async Task ChallengeWillUseOptionsScope() { - var options = new GoogleAuthenticationOptions() + var server = CreateServer(options => { - ClientId = "Test Id", - ClientSecret = "Test Secret", - }; - options.Scope.Add("https://www.googleapis.com/auth/plus.login"); - var server = CreateServer(options); + options.ClientId = "Test Id"; + options.ClientSecret = "Test Secret"; + options.Scope.Add("https://www.googleapis.com/auth/plus.login"); + }); var transaction = await SendAsync(server, "https://example.com/challenge"); transaction.Response.StatusCode.ShouldBe(HttpStatusCode.Redirect); var query = transaction.Response.Headers.Location.Query; @@ -142,13 +146,12 @@ public async Task ChallengeWillUseOptionsScope() [Fact] public async Task ChallengeWillUseAuthenticationPropertiesAsParameters() { - var options = new GoogleAuthenticationOptions() + var server = CreateServer(options => { - ClientId = "Test Id", - ClientSecret = "Test Secret" - }; - var server = CreateServer(options, - context => + options.ClientId = "Test Id"; + options.ClientSecret = "Test Secret"; + }, + context => { var req = context.Request; var res = context.Response; @@ -179,19 +182,18 @@ public async Task ChallengeWillUseAuthenticationPropertiesAsParameters() [Fact] public async Task ChallengeWillTriggerApplyRedirectEvent() { - var options = new GoogleAuthenticationOptions() + var server = CreateServer(options => { - ClientId = "Test Id", - ClientSecret = "Test Secret", - Notifications = new GoogleAuthenticationNotifications + options.ClientId = "Test Id"; + options.ClientSecret = "Test Secret"; + options.Notifications = new GoogleAuthenticationNotifications { OnApplyRedirect = context => { context.Response.Redirect(context.RedirectUri + "&custom=test"); } - } - }; - var server = CreateServer(options); + }; + }); var transaction = await SendAsync(server, "https://example.com/challenge"); transaction.Response.StatusCode.ShouldBe(HttpStatusCode.Redirect); var query = transaction.Response.Headers.Location.Query; @@ -201,12 +203,11 @@ public async Task ChallengeWillTriggerApplyRedirectEvent() [Fact] public async Task ReplyPathWithoutStateQueryStringWillBeRejected() { - var options = new GoogleAuthenticationOptions() + var server = CreateServer(options => { - ClientId = "Test Id", - ClientSecret = "Test Secret" - }; - var server = CreateServer(options); + options.ClientId = "Test Id"; + options.ClientSecret = "Test Secret"; + }); var transaction = await SendAsync(server, "https://example.com/signin-google?code=TestCode"); transaction.Response.StatusCode.ShouldBe(HttpStatusCode.InternalServerError); } @@ -214,57 +215,58 @@ public async Task ReplyPathWithoutStateQueryStringWillBeRejected() [Fact] public async Task ReplyPathWillAuthenticateValidAuthorizeCodeAndState() { - var options = new GoogleAuthenticationOptions() + ISecureDataFormat stateFormat = new PropertiesDataFormat(DataProtectionProvider.CreateNew().CreateProtector("GoogleTest")); + var server = CreateServer(options => { - ClientId = "Test Id", - ClientSecret = "Test Secret", - BackchannelHttpHandler = new TestHttpMessageHandler + options.ClientId = "Test Id"; + options.ClientSecret = "Test Secret"; + options.StateDataFormat = stateFormat; + options.BackchannelHttpHandler = new TestHttpMessageHandler { Sender = async req => + { + if (req.RequestUri.AbsoluteUri == "https://accounts.google.com/o/oauth2/token") { - if (req.RequestUri.AbsoluteUri == "https://accounts.google.com/o/oauth2/token") + return await ReturnJsonResponse(new { - return await ReturnJsonResponse(new - { - access_token = "Test Access Token", - expire_in = 3600, - token_type = "Bearer" - }); - } - else if (req.RequestUri.GetLeftPart(UriPartial.Path) == "https://www.googleapis.com/plus/v1/people/me") + access_token = "Test Access Token", + expire_in = 3600, + token_type = "Bearer" + }); + } + else if (req.RequestUri.GetLeftPart(UriPartial.Path) == "https://www.googleapis.com/plus/v1/people/me") + { + return await ReturnJsonResponse(new { - return await ReturnJsonResponse(new + id = "Test User ID", + displayName = "Test Name", + name = new { - id = "Test User ID", - displayName = "Test Name", - name = new - { - familyName = "Test Family Name", - givenName = "Test Given Name" - }, - url = "Profile link", - emails = new[] + familyName = "Test Family Name", + givenName = "Test Given Name" + }, + url = "Profile link", + emails = new[] + { + new { - new - { - value = "Test email", - type = "account" - } + value = "Test email", + type = "account" } - }); - } - - return null; + } + }); } - } - }; - var server = CreateServer(options); + + return null; + } + }; + }); var properties = new AuthenticationProperties(); var correlationKey = ".AspNet.Correlation.Google"; var correlationValue = "TestCorrelationId"; properties.Dictionary.Add(correlationKey, correlationValue); properties.RedirectUri = "/me"; - var state = options.StateDataFormat.Protect(properties); + var state = stateFormat.Protect(properties); var transaction = await SendAsync(server, "https://example.com/signin-google?code=TestCode&state=" + Uri.EscapeDataString(state), correlationKey + "=" + correlationValue); @@ -287,25 +289,26 @@ public async Task ReplyPathWillAuthenticateValidAuthorizeCodeAndState() [Fact] public async Task ReplyPathWillRejectIfCodeIsInvalid() { - var options = new GoogleAuthenticationOptions() + ISecureDataFormat stateFormat = new PropertiesDataFormat(DataProtectionProvider.CreateNew().CreateProtector("GoogleTest")); + var server = CreateServer(options => { - ClientId = "Test Id", - ClientSecret = "Test Secret", - BackchannelHttpHandler = new TestHttpMessageHandler + options.ClientId = "Test Id"; + options.ClientSecret = "Test Secret"; + options.StateDataFormat = stateFormat; + options.BackchannelHttpHandler = new TestHttpMessageHandler { Sender = req => { return Task.FromResult(new HttpResponseMessage(HttpStatusCode.BadRequest)); } - } - }; - var server = CreateServer(options); + }; + }); var properties = new AuthenticationProperties(); var correlationKey = ".AspNet.Correlation.Google"; var correlationValue = "TestCorrelationId"; properties.Dictionary.Add(correlationKey, correlationValue); properties.RedirectUri = "/me"; - var state = options.StateDataFormat.Protect(properties); + var state = stateFormat.Protect(properties); var transaction = await SendAsync(server, "https://example.com/signin-google?code=TestCode&state=" + Uri.EscapeDataString(state), correlationKey + "=" + correlationValue); @@ -316,25 +319,26 @@ public async Task ReplyPathWillRejectIfCodeIsInvalid() [Fact] public async Task ReplyPathWillRejectIfAccessTokenIsMissing() { - var options = new GoogleAuthenticationOptions() + ISecureDataFormat stateFormat = new PropertiesDataFormat(DataProtectionProvider.CreateNew().CreateProtector("GoogleTest")); + var server = CreateServer(options => { - ClientId = "Test Id", - ClientSecret = "Test Secret", - BackchannelHttpHandler = new TestHttpMessageHandler + options.ClientId = "Test Id"; + options.ClientSecret = "Test Secret"; + options.StateDataFormat = stateFormat; + options.BackchannelHttpHandler = new TestHttpMessageHandler { - Sender = async req => + Sender = req => { - return await ReturnJsonResponse(new object()); + return ReturnJsonResponse(new object()); } - } - }; - var server = CreateServer(options); + }; + }); var properties = new AuthenticationProperties(); var correlationKey = ".AspNet.Correlation.Google"; var correlationValue = "TestCorrelationId"; properties.Dictionary.Add(correlationKey, correlationValue); properties.RedirectUri = "/me"; - var state = options.StateDataFormat.Protect(properties); + var state = stateFormat.Protect(properties); var transaction = await SendAsync(server, "https://example.com/signin-google?code=TestCode&state=" + Uri.EscapeDataString(state), correlationKey + "=" + correlationValue); @@ -345,11 +349,13 @@ public async Task ReplyPathWillRejectIfAccessTokenIsMissing() [Fact] public async Task AuthenticatedEventCanGetRefreshToken() { - var options = new GoogleAuthenticationOptions() + ISecureDataFormat stateFormat = new PropertiesDataFormat(DataProtectionProvider.CreateNew().CreateProtector("GoogleTest")); + var server = CreateServer(options => { - ClientId = "Test Id", - ClientSecret = "Test Secret", - BackchannelHttpHandler = new TestHttpMessageHandler + options.ClientId = "Test Id"; + options.ClientSecret = "Test Secret"; + options.StateDataFormat = stateFormat; + options.BackchannelHttpHandler = new TestHttpMessageHandler { Sender = async req => { @@ -388,8 +394,8 @@ public async Task AuthenticatedEventCanGetRefreshToken() return null; } - }, - Notifications = new GoogleAuthenticationNotifications() + }; + options.Notifications = new GoogleAuthenticationNotifications() { OnAuthenticated = context => { @@ -397,15 +403,14 @@ public async Task AuthenticatedEventCanGetRefreshToken() context.Identity.AddClaim(new Claim("RefreshToken", refreshToken)); return Task.FromResult(null); } - } - }; - var server = CreateServer(options); + }; + }); var properties = new AuthenticationProperties(); var correlationKey = ".AspNet.Correlation.Google"; var correlationValue = "TestCorrelationId"; properties.Dictionary.Add(correlationKey, correlationValue); properties.RedirectUri = "/me"; - var state = options.StateDataFormat.Protect(properties); + var state = stateFormat.Protect(properties); var transaction = await SendAsync(server, "https://example.com/signin-google?code=TestCode&state=" + Uri.EscapeDataString(state), correlationKey + "=" + correlationValue); @@ -456,16 +461,19 @@ private static async Task SendAsync(TestServer server, string uri, return transaction; } - private static TestServer CreateServer(GoogleAuthenticationOptions options, Func testpath = null) + private static TestServer CreateServer(Action configureOptions, Func testpath = null) { return TestServer.Create(app => { - app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationType); - app.UseCookieAuthentication(new CookieAuthenticationOptions() + app.UseServices(services => + { + services.ConfigureOptions(options => { - AuthenticationType = CookieAuthenticationType + options.SignInAsAuthenticationType = CookieAuthenticationType; }); - app.UseGoogleAuthentication(options); + }); + app.UseCookieAuthentication(options => options.AuthenticationType = CookieAuthenticationType); + app.UseGoogleAuthentication(configureOptions); app.Use(async (context, next) => { var req = context.Request; diff --git a/test/Microsoft.AspNet.Security.Test/MicrosoftAccount/MicrosoftAccountMiddlewareTests.cs b/test/Microsoft.AspNet.Security.Test/MicrosoftAccount/MicrosoftAccountMiddlewareTests.cs index a19aeae05..3a90d5fc5 100644 --- a/test/Microsoft.AspNet.Security.Test/MicrosoftAccount/MicrosoftAccountMiddlewareTests.cs +++ b/test/Microsoft.AspNet.Security.Test/MicrosoftAccount/MicrosoftAccountMiddlewareTests.cs @@ -20,6 +20,10 @@ using Newtonsoft.Json; using Shouldly; using Xunit; +using Microsoft.Framework.OptionsModel; +using Microsoft.Framework.DependencyInjection; +using Microsoft.AspNet.Security.DataHandler; +using Microsoft.AspNet.Security.DataProtection; namespace Microsoft.AspNet.Security.Tests.MicrosoftAccount { @@ -28,20 +32,19 @@ public class MicrosoftAccountMiddlewareTests [Fact] public async Task ChallengeWillTriggerApplyRedirectEvent() { - var options = new MicrosoftAccountAuthenticationOptions() - { - ClientId = "Test Client Id", - ClientSecret = "Test Client Secret", - Notifications = new MicrosoftAccountAuthenticationNotifications + var server = CreateServer( + options => { - OnApplyRedirect = context => + options.ClientId = "Test Client Id"; + options.ClientSecret = "Test Client Secret"; + options.Notifications = new MicrosoftAccountAuthenticationNotifications { - context.Response.Redirect(context.RedirectUri + "&custom=test"); - } - } - }; - var server = CreateServer( - app => app.UseMicrosoftAccountAuthentication(options), + OnApplyRedirect = context => + { + context.Response.Redirect(context.RedirectUri + "&custom=test"); + } + }; + }, context => { context.Response.Challenge("Microsoft"); @@ -57,7 +60,11 @@ public async Task ChallengeWillTriggerApplyRedirectEvent() public async Task ChallengeWillTriggerRedirection() { var server = CreateServer( - app => app.UseMicrosoftAccountAuthentication("Test Client Id", "Test Client Secret"), + options => + { + options.ClientId = "Test Client Id"; + options.ClientSecret = "Test Client Secret"; + }, context => { context.Response.Challenge("Microsoft"); @@ -77,54 +84,55 @@ public async Task ChallengeWillTriggerRedirection() [Fact] public async Task AuthenticatedEventCanGetRefreshToken() { - var options = new MicrosoftAccountAuthenticationOptions() - { - ClientId = "Test Client Id", - ClientSecret = "Test Client Secret", - BackchannelHttpHandler = new TestHttpMessageHandler + ISecureDataFormat stateFormat = new PropertiesDataFormat(DataProtectionProvider.CreateNew().CreateProtector("MsftTest")); + var server = CreateServer( + options => { - Sender = async req => + options.ClientId = "Test Client Id"; + options.ClientSecret = "Test Client Secret"; + options.StateDataFormat = stateFormat; + options.BackchannelHttpHandler = new TestHttpMessageHandler { - if (req.RequestUri.AbsoluteUri == "https://login.live.com/oauth20_token.srf") + Sender = async req => { - return await ReturnJsonResponse(new + if (req.RequestUri.AbsoluteUri == "https://login.live.com/oauth20_token.srf") { - access_token = "Test Access Token", - expire_in = 3600, - token_type = "Bearer", - refresh_token = "Test Refresh Token" - }); - } - else if (req.RequestUri.GetLeftPart(UriPartial.Path) == "https://apis.live.net/v5.0/me") - { - return await ReturnJsonResponse(new + return await ReturnJsonResponse(new + { + access_token = "Test Access Token", + expire_in = 3600, + token_type = "Bearer", + refresh_token = "Test Refresh Token" + }); + } + else if (req.RequestUri.GetLeftPart(UriPartial.Path) == "https://apis.live.net/v5.0/me") { - id = "Test User ID", - name = "Test Name", - first_name = "Test Given Name", - last_name = "Test Family Name", - emails = new + return await ReturnJsonResponse(new { - preferred = "Test email" - } - }); - } + id = "Test User ID", + name = "Test Name", + first_name = "Test Given Name", + last_name = "Test Family Name", + emails = new + { + preferred = "Test email" + } + }); + } - return null; - } - }, - Notifications = new MicrosoftAccountAuthenticationNotifications - { - OnAuthenticated = context => + return null; + } + }; + options.Notifications = new MicrosoftAccountAuthenticationNotifications { - var refreshToken = context.RefreshToken; - context.Identity.AddClaim(new Claim("RefreshToken", refreshToken)); - return Task.FromResult(null); - } - } - }; - var server = CreateServer( - app => app.UseMicrosoftAccountAuthentication(options), + OnAuthenticated = context => + { + var refreshToken = context.RefreshToken; + context.Identity.AddClaim(new Claim("RefreshToken", refreshToken)); + return Task.FromResult(null); + } + }; + }, context => { Describe(context.Response, (ClaimsIdentity)context.User.Identity); @@ -135,7 +143,7 @@ public async Task AuthenticatedEventCanGetRefreshToken() var correlationValue = "TestCorrelationId"; properties.Dictionary.Add(correlationKey, correlationValue); properties.RedirectUri = "/me"; - var state = options.StateDataFormat.Protect(properties); + var state = stateFormat.Protect(properties); var transaction = await SendAsync(server, "https://example.com/signin-microsoft?code=TestCode&state=" + Uri.EscapeDataString(state), correlationKey + "=" + correlationValue); @@ -151,19 +159,19 @@ public async Task AuthenticatedEventCanGetRefreshToken() transaction.FindClaimValue("RefreshToken").ShouldBe("Test Refresh Token"); } - private static TestServer CreateServer(Action configure, Func handler) + private static TestServer CreateServer(Action configureOptions, Func handler) { return TestServer.Create(app => { - app.UseCookieAuthentication(new CookieAuthenticationOptions + app.UseServices(services => { - AuthenticationType = "External" + services.ConfigureOptions(options => + { + options.SignInAsAuthenticationType = "External"; + }); }); - app.SetDefaultSignInAsAuthenticationType("External"); - if (configure != null) - { - configure(app); - } + app.UseCookieAuthentication(options => options.AuthenticationType = "External"); + app.UseMicrosoftAccountAuthentication(configureOptions); app.Use(async (context, next) => { if (handler == null || !handler(context)) diff --git a/test/Microsoft.AspNet.Security.Test/Twitter/TwitterMiddlewareTests.cs b/test/Microsoft.AspNet.Security.Test/Twitter/TwitterMiddlewareTests.cs index 461e54184..31afcfa7a 100644 --- a/test/Microsoft.AspNet.Security.Test/Twitter/TwitterMiddlewareTests.cs +++ b/test/Microsoft.AspNet.Security.Test/Twitter/TwitterMiddlewareTests.cs @@ -15,6 +15,8 @@ using Newtonsoft.Json; using Shouldly; using Xunit; +using Microsoft.Framework.OptionsModel; +using Microsoft.Framework.DependencyInjection; namespace Microsoft.AspNet.Security.Twitter { @@ -23,20 +25,21 @@ public class TwitterMiddlewareTests [Fact] public async Task ChallengeWillTriggerApplyRedirectEvent() { - var options = new TwitterAuthenticationOptions() - { - ConsumerKey = "Test Consumer Key", - ConsumerSecret = "Test Consumer Secret", - Notifications = new TwitterAuthenticationNotifications + var server = CreateServer( + app => app.UseTwitterAuthentication(options => { - OnApplyRedirect = context => + options.ConsumerKey = "Test Consumer Key"; + options.ConsumerSecret = "Test Consumer Secret"; + options.Notifications = new TwitterAuthenticationNotifications { - context.Response.Redirect(context.RedirectUri + "&custom=test"); - } - }, - BackchannelHttpHandler = new TestHttpMessageHandler - { - Sender = req => + OnApplyRedirect = context => + { + context.Response.Redirect(context.RedirectUri + "&custom=test"); + } + }; + options.BackchannelHttpHandler = new TestHttpMessageHandler + { + Sender = req => { if (req.RequestUri.AbsoluteUri == "https://api.twitter.com/oauth/request_token") { @@ -50,11 +53,9 @@ public async Task ChallengeWillTriggerApplyRedirectEvent() } return Task.FromResult(null); } - }, - BackchannelCertificateValidator = null - }; - var server = CreateServer( - app => app.UseTwitterAuthentication(options), + }; + options.BackchannelCertificateValidator = null; + }), context => { context.Response.Challenge("Twitter"); @@ -69,31 +70,30 @@ public async Task ChallengeWillTriggerApplyRedirectEvent() [Fact] public async Task ChallengeWillTriggerRedirection() { - var options = new TwitterAuthenticationOptions() - { - ConsumerKey = "Test Consumer Key", - ConsumerSecret = "Test Consumer Secret", - BackchannelHttpHandler = new TestHttpMessageHandler + var server = CreateServer( + app => app.UseTwitterAuthentication(options => { - Sender = req => + options.ConsumerKey = "Test Consumer Key"; + options.ConsumerSecret = "Test Consumer Secret"; + options.BackchannelHttpHandler = new TestHttpMessageHandler { - if (req.RequestUri.AbsoluteUri == "https://api.twitter.com/oauth/request_token") + Sender = req => { - return Task.FromResult(new HttpResponseMessage(HttpStatusCode.OK) + if (req.RequestUri.AbsoluteUri == "https://api.twitter.com/oauth/request_token") { - Content = - new StringContent("oauth_callback_confirmed=true&oauth_token=test_oauth_token&oauth_token_secret=test_oauth_token_secret", - Encoding.UTF8, - "application/x-www-form-urlencoded") - }); + return Task.FromResult(new HttpResponseMessage(HttpStatusCode.OK) + { + Content = + new StringContent("oauth_callback_confirmed=true&oauth_token=test_oauth_token&oauth_token_secret=test_oauth_token_secret", + Encoding.UTF8, + "application/x-www-form-urlencoded") + }); + } + return Task.FromResult(null); } - return Task.FromResult(null); - } - }, - BackchannelCertificateValidator = null - }; - var server = CreateServer( - app => app.UseTwitterAuthentication(options), + }; + options.BackchannelCertificateValidator = null; + }), context => { context.Response.Challenge("Twitter"); @@ -109,10 +109,16 @@ private static TestServer CreateServer(Action configure, Fu { return TestServer.Create(app => { - app.SetDefaultSignInAsAuthenticationType("External"); - app.UseCookieAuthentication(new CookieAuthenticationOptions + app.UseServices(services => + { + services.ConfigureOptions(options => + { + options.SignInAsAuthenticationType = "External"; + }); + }); + app.UseCookieAuthentication(options => { - AuthenticationType = "External" + options.AuthenticationType = "External"; }); if (configure != null) { diff --git a/test/Microsoft.AspNet.Security.Test/project.json b/test/Microsoft.AspNet.Security.Test/project.json index c3b4a4b2c..7fa89c00c 100644 --- a/test/Microsoft.AspNet.Security.Test/project.json +++ b/test/Microsoft.AspNet.Security.Test/project.json @@ -12,6 +12,7 @@ "Microsoft.AspNet.Security.Twitter": "1.0.0-*", "Microsoft.AspNet.TestHost": "1.0.0-*", "Microsoft.Framework.DependencyInjection": "1.0.0-*", + "Microsoft.Framework.OptionsModel": "1.0.0-*", "Moq": "4.2.1312.1622", "Xunit.KRunner": "1.0.0-*" }, From 485355414719014008bf4d8bbbd8c8bb445dce43 Mon Sep 17 00:00:00 2001 From: Chris Ross Date: Tue, 7 Oct 2014 12:42:42 -0700 Subject: [PATCH 064/216] #39 - Port the OAuth Bearer middleware from Katana. --- samples/SocialSample/SocialSample.kproj | 2 +- samples/SocialSample/Startup.cs | 1 - samples/SocialSample/project.json | 1 + .../Notifications/BaseValidatingContext.cs | 114 ++++++++++++++++ .../BaseValidatingTicketContext.cs | 58 ++++++++ ...IOAuthBearerAuthenticationNotifications.cs | 37 +++++ .../OAuthAuthenticatedContext.cs | 1 - .../OAuthBearerAuthenticationNotifications.cs | 73 ++++++++++ .../Notifications/OAuthChallengeContext.cs | 32 +++++ .../OAuthGetUserInformationContext.cs | 1 - .../Notifications/OAuthRequestTokenContext.cs | 32 +++++ .../OAuthValidateIdentityContext.cs | 26 ++++ .../OAuthBearerAuthenticationDefaults.cs | 17 +++ .../OAuthBearerAuthenticationExtensions.cs | 41 ++++++ .../OAuthBearerAuthenticationHandler.cs | 126 ++++++++++++++++++ .../OAuthBearerAuthenticationMiddleware.cs | 79 +++++++++++ .../OAuthBearerAuthenticationOptions.cs | 66 +++++++++ 17 files changed, 703 insertions(+), 4 deletions(-) create mode 100644 src/Microsoft.AspNet.Security.OAuth/Notifications/BaseValidatingContext.cs create mode 100644 src/Microsoft.AspNet.Security.OAuth/Notifications/BaseValidatingTicketContext.cs create mode 100644 src/Microsoft.AspNet.Security.OAuth/Notifications/IOAuthBearerAuthenticationNotifications.cs create mode 100644 src/Microsoft.AspNet.Security.OAuth/Notifications/OAuthBearerAuthenticationNotifications.cs create mode 100644 src/Microsoft.AspNet.Security.OAuth/Notifications/OAuthChallengeContext.cs create mode 100644 src/Microsoft.AspNet.Security.OAuth/Notifications/OAuthRequestTokenContext.cs create mode 100644 src/Microsoft.AspNet.Security.OAuth/Notifications/OAuthValidateIdentityContext.cs create mode 100644 src/Microsoft.AspNet.Security.OAuth/OAuthBearerAuthenticationDefaults.cs create mode 100644 src/Microsoft.AspNet.Security.OAuth/OAuthBearerAuthenticationExtensions.cs create mode 100644 src/Microsoft.AspNet.Security.OAuth/OAuthBearerAuthenticationHandler.cs create mode 100644 src/Microsoft.AspNet.Security.OAuth/OAuthBearerAuthenticationMiddleware.cs create mode 100644 src/Microsoft.AspNet.Security.OAuth/OAuthBearerAuthenticationOptions.cs diff --git a/samples/SocialSample/SocialSample.kproj b/samples/SocialSample/SocialSample.kproj index 982c0c8f5..2d3d1caf5 100644 --- a/samples/SocialSample/SocialSample.kproj +++ b/samples/SocialSample/SocialSample.kproj @@ -21,7 +21,7 @@ 2.0 - 50113 + 12345 \ No newline at end of file diff --git a/samples/SocialSample/Startup.cs b/samples/SocialSample/Startup.cs index 35480c1cc..18f17ac0f 100644 --- a/samples/SocialSample/Startup.cs +++ b/samples/SocialSample/Startup.cs @@ -28,7 +28,6 @@ public void Configure(IApplicationBuilder app) { services.ConfigureOptions(options => { - options.SignInAsAuthenticationType = CookieAuthenticationDefaults.AuthenticationType; }); }); diff --git a/samples/SocialSample/project.json b/samples/SocialSample/project.json index 84bb6d1c9..40f05e17c 100644 --- a/samples/SocialSample/project.json +++ b/samples/SocialSample/project.json @@ -7,6 +7,7 @@ "Microsoft.AspNet.Security.Google": "1.0.0-*", "Microsoft.AspNet.Security.MicrosoftAccount": "1.0.0-*", "Microsoft.AspNet.Security.Twitter": "1.0.0-*", + "Microsoft.AspNet.Server.IIS": "1.0.0-*", "Microsoft.AspNet.Server.WebListener": "1.0.0-*", "Microsoft.Framework.DependencyInjection": "1.0.0-*", "Microsoft.Framework.OptionsModel": "1.0.0-*" diff --git a/src/Microsoft.AspNet.Security.OAuth/Notifications/BaseValidatingContext.cs b/src/Microsoft.AspNet.Security.OAuth/Notifications/BaseValidatingContext.cs new file mode 100644 index 000000000..0957d9fd6 --- /dev/null +++ b/src/Microsoft.AspNet.Security.OAuth/Notifications/BaseValidatingContext.cs @@ -0,0 +1,114 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using Microsoft.AspNet.Http; +using Microsoft.AspNet.Security.Notifications; + +namespace Microsoft.AspNet.Security.OAuth +{ + /// + /// Base class used for certain event contexts + /// + public abstract class BaseValidatingContext : BaseContext + { + /// + /// Initializes base class used for certain event contexts + /// + protected BaseValidatingContext( + HttpContext context, + TOptions options) + : base(context, options) + { + } + + /// + /// True if application code has called any of the Validate methods on this context. + /// + public bool IsValidated { get; private set; } + + /// + /// True if application code has called any of the SetError methods on this context. + /// + public bool HasError { get; private set; } + + /// + /// The error argument provided when SetError was called on this context. This is eventually + /// returned to the client app as the OAuth "error" parameter. + /// + public string Error { get; private set; } + + /// + /// The optional errorDescription argument provided when SetError was called on this context. This is eventually + /// returned to the client app as the OAuth "error_description" parameter. + /// + public string ErrorDescription { get; private set; } + + /// + /// The optional errorUri argument provided when SetError was called on this context. This is eventually + /// returned to the client app as the OAuth "error_uri" parameter. + /// + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1056:UriPropertiesShouldNotBeStrings", Justification = "error_uri is a string value in the protocol")] + public string ErrorUri { get; private set; } + + /// + /// Marks this context as validated by the application. IsValidated becomes true and HasError becomes false as a result of calling. + /// + /// True if the validation has taken effect. + public virtual bool Validated() + { + IsValidated = true; + HasError = false; + return true; + } + + /// + /// Marks this context as not validated by the application. IsValidated and HasError become false as a result of calling. + /// + public virtual void Rejected() + { + IsValidated = false; + HasError = false; + } + + /// + /// Marks this context as not validated by the application and assigns various error information properties. + /// HasError becomes true and IsValidated becomes false as a result of calling. + /// + /// Assigned to the Error property + public void SetError(string error) + { + SetError(error, null); + } + + /// + /// Marks this context as not validated by the application and assigns various error information properties. + /// HasError becomes true and IsValidated becomes false as a result of calling. + /// + /// Assigned to the Error property + /// Assigned to the ErrorDescription property + public void SetError(string error, + string errorDescription) + { + SetError(error, errorDescription, null); + } + + /// + /// Marks this context as not validated by the application and assigns various error information properties. + /// HasError becomes true and IsValidated becomes false as a result of calling. + /// + /// Assigned to the Error property + /// Assigned to the ErrorDescription property + /// Assigned to the ErrorUri property + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings", MessageId = "2#", Justification = "error_uri is a string value in the protocol")] + public void SetError(string error, + string errorDescription, + string errorUri) + { + Error = error; + ErrorDescription = errorDescription; + ErrorUri = errorUri; + Rejected(); + HasError = true; + } + } +} diff --git a/src/Microsoft.AspNet.Security.OAuth/Notifications/BaseValidatingTicketContext.cs b/src/Microsoft.AspNet.Security.OAuth/Notifications/BaseValidatingTicketContext.cs new file mode 100644 index 000000000..c6528619b --- /dev/null +++ b/src/Microsoft.AspNet.Security.OAuth/Notifications/BaseValidatingTicketContext.cs @@ -0,0 +1,58 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System.Security.Claims; +using Microsoft.AspNet.Http; +using Microsoft.AspNet.Http.Security; + +namespace Microsoft.AspNet.Security.OAuth +{ + /// + /// Base class used for certain event contexts + /// + public abstract class BaseValidatingTicketContext : BaseValidatingContext + { + /// + /// Initializes base class used for certain event contexts + /// + protected BaseValidatingTicketContext( + HttpContext context, + TOptions options, + AuthenticationTicket ticket) + : base(context, options) + { + Ticket = ticket; + } + + /// + /// Contains the identity and properties for the application to authenticate. If the Validated method + /// is invoked with an AuthenticationTicket or ClaimsIdentity argument, that new value is assigned to + /// this property in addition to changing IsValidated to true. + /// + public AuthenticationTicket Ticket { get; private set; } + + /// + /// Replaces the ticket information on this context and marks it as as validated by the application. + /// IsValidated becomes true and HasError becomes false as a result of calling. + /// + /// Assigned to the Ticket property + /// True if the validation has taken effect. + public bool Validated(AuthenticationTicket ticket) + { + Ticket = ticket; + return Validated(); + } + + /// + /// Alters the ticket information on this context and marks it as as validated by the application. + /// IsValidated becomes true and HasError becomes false as a result of calling. + /// + /// Assigned to the Ticket.Identity property + /// True if the validation has taken effect. + public bool Validated(ClaimsIdentity identity) + { + AuthenticationProperties properties = Ticket != null ? Ticket.Properties : new AuthenticationProperties(); + return Validated(new AuthenticationTicket(identity, properties)); + } + } +} diff --git a/src/Microsoft.AspNet.Security.OAuth/Notifications/IOAuthBearerAuthenticationNotifications.cs b/src/Microsoft.AspNet.Security.OAuth/Notifications/IOAuthBearerAuthenticationNotifications.cs new file mode 100644 index 000000000..048d8f292 --- /dev/null +++ b/src/Microsoft.AspNet.Security.OAuth/Notifications/IOAuthBearerAuthenticationNotifications.cs @@ -0,0 +1,37 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System.Threading.Tasks; + +namespace Microsoft.AspNet.Security.OAuth +{ + /// + /// Specifies callback methods which the invokes to enable developer control over the authentication process. /> + /// + public interface IOAuthBearerAuthenticationNotifications + { + /// + /// Invoked before the is created. Gives the application an + /// opportunity to find the identity from a different location, adjust, or reject the token. + /// + /// Contains the token string. + /// A representing the completed operation. + Task RequestToken(OAuthRequestTokenContext context); + + /// + /// Called each time a request identity has been validated by the middleware. By implementing this method the + /// application may alter or reject the identity which has arrived with the request. + /// + /// Contains information about the login session as well as the user . + /// A representing the completed operation. + Task ValidateIdentity(OAuthValidateIdentityContext context); + + /// + /// Called each time a challenge is being sent to the client. By implementing this method the application + /// may modify the challenge as needed. + /// + /// Contains the default challenge. + /// A representing the completed operation. + Task ApplyChallenge(OAuthChallengeContext context); + } +} diff --git a/src/Microsoft.AspNet.Security.OAuth/Notifications/OAuthAuthenticatedContext.cs b/src/Microsoft.AspNet.Security.OAuth/Notifications/OAuthAuthenticatedContext.cs index a651767e8..581707153 100644 --- a/src/Microsoft.AspNet.Security.OAuth/Notifications/OAuthAuthenticatedContext.cs +++ b/src/Microsoft.AspNet.Security.OAuth/Notifications/OAuthAuthenticatedContext.cs @@ -3,7 +3,6 @@ using System; using System.Globalization; -using System.Net.Http; using System.Security.Claims; using Microsoft.AspNet.Http; using Microsoft.AspNet.Http.Security; diff --git a/src/Microsoft.AspNet.Security.OAuth/Notifications/OAuthBearerAuthenticationNotifications.cs b/src/Microsoft.AspNet.Security.OAuth/Notifications/OAuthBearerAuthenticationNotifications.cs new file mode 100644 index 000000000..2c24f3ff1 --- /dev/null +++ b/src/Microsoft.AspNet.Security.OAuth/Notifications/OAuthBearerAuthenticationNotifications.cs @@ -0,0 +1,73 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Threading.Tasks; + +namespace Microsoft.AspNet.Security.OAuth +{ + /// + /// OAuth bearer token middleware provider + /// + public class OAuthBearerAuthenticationNotifications : IOAuthBearerAuthenticationNotifications + { + /// + /// Initializes a new instance of the class + /// + public OAuthBearerAuthenticationNotifications() + { + OnRequestToken = context => Task.FromResult(null); + OnValidateIdentity = context => Task.FromResult(null); + OnApplyChallenge = context => + { + context.HttpContext.Response.Headers.AppendValues("WWW-Authenticate", context.Challenge); + return Task.FromResult(0); + }; + } + + /// + /// Handles processing OAuth bearer token. + /// + public Func OnRequestToken { get; set; } + + /// + /// Handles validating the identity produced from an OAuth bearer token. + /// + public Func OnValidateIdentity { get; set; } + + /// + /// Handles applying the authentication challenge to the response message. + /// + public Func OnApplyChallenge { get; set; } + + /// + /// Handles processing OAuth bearer token. + /// + /// + /// + public virtual Task RequestToken(OAuthRequestTokenContext context) + { + return OnRequestToken(context); + } + + /// + /// Handles validating the identity produced from an OAuth bearer token. + /// + /// + /// + public virtual Task ValidateIdentity(OAuthValidateIdentityContext context) + { + return OnValidateIdentity.Invoke(context); + } + + /// + /// Handles applying the authentication challenge to the response message. + /// + /// + /// + public Task ApplyChallenge(OAuthChallengeContext context) + { + return OnApplyChallenge(context); + } + } +} diff --git a/src/Microsoft.AspNet.Security.OAuth/Notifications/OAuthChallengeContext.cs b/src/Microsoft.AspNet.Security.OAuth/Notifications/OAuthChallengeContext.cs new file mode 100644 index 000000000..6f5016914 --- /dev/null +++ b/src/Microsoft.AspNet.Security.OAuth/Notifications/OAuthChallengeContext.cs @@ -0,0 +1,32 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using Microsoft.AspNet.Http; +using Microsoft.AspNet.Security.Notifications; + +namespace Microsoft.AspNet.Security.OAuth +{ + /// + /// Specifies the HTTP response header for the bearer authentication scheme. + /// + public class OAuthChallengeContext : BaseContext + { + /// + /// Initializes a new + /// + /// HTTP environment + /// The www-authenticate header value. + public OAuthChallengeContext( + HttpContext context, + string challenge) + : base(context) + { + Challenge = challenge; + } + + /// + /// The www-authenticate header value. + /// + public string Challenge { get; protected set; } + } +} diff --git a/src/Microsoft.AspNet.Security.OAuth/Notifications/OAuthGetUserInformationContext.cs b/src/Microsoft.AspNet.Security.OAuth/Notifications/OAuthGetUserInformationContext.cs index 5886d1b54..15d76c6eb 100644 --- a/src/Microsoft.AspNet.Security.OAuth/Notifications/OAuthGetUserInformationContext.cs +++ b/src/Microsoft.AspNet.Security.OAuth/Notifications/OAuthGetUserInformationContext.cs @@ -8,7 +8,6 @@ using Microsoft.AspNet.Http; using Microsoft.AspNet.Http.Security; using Microsoft.AspNet.Security.Notifications; -using Newtonsoft.Json.Linq; namespace Microsoft.AspNet.Security.OAuth { diff --git a/src/Microsoft.AspNet.Security.OAuth/Notifications/OAuthRequestTokenContext.cs b/src/Microsoft.AspNet.Security.OAuth/Notifications/OAuthRequestTokenContext.cs new file mode 100644 index 000000000..785fa175d --- /dev/null +++ b/src/Microsoft.AspNet.Security.OAuth/Notifications/OAuthRequestTokenContext.cs @@ -0,0 +1,32 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using Microsoft.AspNet.Http; +using Microsoft.AspNet.Security.Notifications; + +namespace Microsoft.AspNet.Security.OAuth +{ + /// + /// Specifies the HTTP request header for the bearer authentication scheme. + /// + public class OAuthRequestTokenContext : BaseContext + { + /// + /// Initializes a new + /// + /// HTTP environment + /// The authorization header value. + public OAuthRequestTokenContext( + HttpContext context, + string token) + : base(context) + { + Token = token; + } + + /// + /// The authorization header value + /// + public string Token { get; set; } + } +} diff --git a/src/Microsoft.AspNet.Security.OAuth/Notifications/OAuthValidateIdentityContext.cs b/src/Microsoft.AspNet.Security.OAuth/Notifications/OAuthValidateIdentityContext.cs new file mode 100644 index 000000000..5dc04ffb4 --- /dev/null +++ b/src/Microsoft.AspNet.Security.OAuth/Notifications/OAuthValidateIdentityContext.cs @@ -0,0 +1,26 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using Microsoft.AspNet.Http; + +namespace Microsoft.AspNet.Security.OAuth +{ + /// + /// Contains the authentication ticket data from an OAuth bearer token. + /// + public class OAuthValidateIdentityContext : BaseValidatingTicketContext + { + /// + /// Initializes a new instance of the class + /// + /// + /// + /// + public OAuthValidateIdentityContext( + HttpContext context, + OAuthBearerAuthenticationOptions options, + AuthenticationTicket ticket) : base(context, options, ticket) + { + } + } +} diff --git a/src/Microsoft.AspNet.Security.OAuth/OAuthBearerAuthenticationDefaults.cs b/src/Microsoft.AspNet.Security.OAuth/OAuthBearerAuthenticationDefaults.cs new file mode 100644 index 000000000..70f1f1e61 --- /dev/null +++ b/src/Microsoft.AspNet.Security.OAuth/OAuthBearerAuthenticationDefaults.cs @@ -0,0 +1,17 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +namespace Microsoft.AspNet.Security.OAuth +{ + /// + /// Default values used by authorization server and bearer authentication. + /// + public static class OAuthBearerAuthenticationDefaults + { + /// + /// Default value for AuthenticationType property in the OAuthBearerAuthenticationOptions and + /// OAuthAuthorizationServerOptions. + /// + public const string AuthenticationType = "Bearer"; + } +} diff --git a/src/Microsoft.AspNet.Security.OAuth/OAuthBearerAuthenticationExtensions.cs b/src/Microsoft.AspNet.Security.OAuth/OAuthBearerAuthenticationExtensions.cs new file mode 100644 index 000000000..118598120 --- /dev/null +++ b/src/Microsoft.AspNet.Security.OAuth/OAuthBearerAuthenticationExtensions.cs @@ -0,0 +1,41 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using Microsoft.AspNet.Security.OAuth; +using Microsoft.Framework.DependencyInjection; +using Microsoft.Framework.OptionsModel; + +namespace Microsoft.AspNet.Builder +{ + /// + /// Extension methods to add OAuth Bearer authentication capabilities to an HTTP application pipeline + /// + public static class OAuthBearerAuthenticationExtensions + { + public static IServiceCollection ConfigureOAuthBearerAuthentication([NotNull] this IServiceCollection services, [NotNull] Action configure) + { + return services.ConfigureOptions(configure); + } + + /// + /// Adds Bearer token processing to an HTTP application pipeline. 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 + /// + /// The application builder + /// Options which control the processing of the bearer header. + /// The application builder + public static IApplicationBuilder UseOAuthBearerAuthentication([NotNull] this IApplicationBuilder app, Action configureOptions = null, string optionsName = "") + { + return app.UseMiddleware( + new OptionsAction(configureOptions ?? (o => { })) + { + Name = optionsName + }); + } + } +} diff --git a/src/Microsoft.AspNet.Security.OAuth/OAuthBearerAuthenticationHandler.cs b/src/Microsoft.AspNet.Security.OAuth/OAuthBearerAuthenticationHandler.cs new file mode 100644 index 000000000..b49db1f71 --- /dev/null +++ b/src/Microsoft.AspNet.Security.OAuth/OAuthBearerAuthenticationHandler.cs @@ -0,0 +1,126 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Threading.Tasks; +using Microsoft.AspNet.Security.Infrastructure; +using Microsoft.Framework.Logging; + +namespace Microsoft.AspNet.Security.OAuth +{ + internal class OAuthBearerAuthenticationHandler : AuthenticationHandler + { + private readonly ILogger _logger; + private readonly string _challenge; + + public OAuthBearerAuthenticationHandler(ILogger logger, string challenge) + { + _logger = logger; + _challenge = challenge; + } + + protected override AuthenticationTicket AuthenticateCore() + { + return AuthenticateCoreAsync().Result; + } + + protected override async Task AuthenticateCoreAsync() + { + try + { + // Find token in default location + string requestToken = null; + string authorization = Request.Headers.Get("Authorization"); + if (!string.IsNullOrEmpty(authorization)) + { + if (authorization.StartsWith("Bearer ", StringComparison.OrdinalIgnoreCase)) + { + requestToken = authorization.Substring("Bearer ".Length).Trim(); + } + } + + // Give application opportunity to find from a different location, adjust, or reject token + var requestTokenContext = new OAuthRequestTokenContext(Context, requestToken); + await Options.Notifications.RequestToken(requestTokenContext); + + // If no token found, no further work possible + if (string.IsNullOrEmpty(requestTokenContext.Token)) + { + return null; + } + + // Call provider to process the token into data + var tokenReceiveContext = new AuthenticationTokenReceiveContext( + Context, + Options.AccessTokenFormat, + requestTokenContext.Token); + + await Options.AccessTokenProvider.ReceiveAsync(tokenReceiveContext); + if (tokenReceiveContext.Ticket == null) + { + tokenReceiveContext.DeserializeTicket(tokenReceiveContext.Token); + } + + AuthenticationTicket ticket = tokenReceiveContext.Ticket; + if (ticket == null) + { + _logger.WriteWarning("invalid bearer token received"); + return null; + } + + // Validate expiration time if present + DateTimeOffset currentUtc = Options.SystemClock.UtcNow; + + if (ticket.Properties.ExpiresUtc.HasValue && + ticket.Properties.ExpiresUtc.Value < currentUtc) + { + _logger.WriteWarning("expired bearer token received"); + return null; + } + + // Give application final opportunity to override results + var context = new OAuthValidateIdentityContext(Context, Options, ticket); + if (ticket != null && + ticket.Identity != null && + ticket.Identity.IsAuthenticated) + { + // bearer token with identity starts validated + context.Validated(); + } + + await Options.Notifications.ValidateIdentity(context); + if (!context.IsValidated) + { + return null; + } + + // resulting identity values go back to caller + return context.Ticket; + } + catch (Exception ex) + { + _logger.WriteError("Authentication failed", ex); + return null; + } + } + + protected override void ApplyResponseChallenge() + { + if (Response.StatusCode != 401) + { + return; + } + + if (ChallengeContext != null) + { + OAuthChallengeContext challengeContext = new OAuthChallengeContext(Context, _challenge); + Options.Notifications.ApplyChallenge(challengeContext); + } + } + + protected override void ApplyResponseGrant() + { + // N/A + } + } +} diff --git a/src/Microsoft.AspNet.Security.OAuth/OAuthBearerAuthenticationMiddleware.cs b/src/Microsoft.AspNet.Security.OAuth/OAuthBearerAuthenticationMiddleware.cs new file mode 100644 index 000000000..715d43b13 --- /dev/null +++ b/src/Microsoft.AspNet.Security.OAuth/OAuthBearerAuthenticationMiddleware.cs @@ -0,0 +1,79 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using Microsoft.AspNet.Builder; +using Microsoft.AspNet.Security.DataHandler; +using Microsoft.AspNet.Security.DataProtection; +using Microsoft.AspNet.Security.Infrastructure; +using Microsoft.Framework.Logging; +using Microsoft.Framework.OptionsModel; + +namespace Microsoft.AspNet.Security.OAuth +{ + /// + /// 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 UseOAuthBearerAuthentication + /// extension method. + /// + public class OAuthBearerAuthenticationMiddleware : AuthenticationMiddleware + { + private readonly ILogger _logger; + + private readonly string _challenge; + + /// + /// 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 UseOAuthBearerAuthentication + /// extension method. + /// + public OAuthBearerAuthenticationMiddleware( + RequestDelegate next, + IDataProtectionProvider dataProtectionProvider, + ILoggerFactory loggerFactory, + IOptionsAccessor options, + IOptionsAction configureOptions) + : base(next, options, configureOptions) + { + _logger = loggerFactory.Create(); + + if (!string.IsNullOrWhiteSpace(Options.Challenge)) + { + _challenge = Options.Challenge; + } + else if (string.IsNullOrWhiteSpace(Options.Realm)) + { + _challenge = "Bearer"; + } + else + { + _challenge = "Bearer realm=\"" + Options.Realm + "\""; + } + + if (Options.Notifications == null) + { + Options.Notifications = new OAuthBearerAuthenticationNotifications(); + } + + if (Options.AccessTokenFormat == null) + { + var dataProtector = DataProtectionHelpers.CreateDataProtector(dataProtectionProvider, + this.GetType().FullName, Options.AuthenticationType, "v1"); + Options.AccessTokenFormat = new TicketDataFormat(dataProtector); + } + + if (Options.AccessTokenProvider == null) + { + Options.AccessTokenProvider = new AuthenticationTokenProvider(); + } + } + + /// + /// Called by the AuthenticationMiddleware base class to create a per-request handler. + /// + /// A new instance of the request handler + protected override AuthenticationHandler CreateHandler() + { + return new OAuthBearerAuthenticationHandler(_logger, _challenge); + } + } +} diff --git a/src/Microsoft.AspNet.Security.OAuth/OAuthBearerAuthenticationOptions.cs b/src/Microsoft.AspNet.Security.OAuth/OAuthBearerAuthenticationOptions.cs new file mode 100644 index 000000000..d2f9b9190 --- /dev/null +++ b/src/Microsoft.AspNet.Security.OAuth/OAuthBearerAuthenticationOptions.cs @@ -0,0 +1,66 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using Microsoft.AspNet.Security.Infrastructure; + +namespace Microsoft.AspNet.Security.OAuth +{ + /// + /// Options class provides information needed to control Bearer Authentication middleware behavior + /// + public class OAuthBearerAuthenticationOptions : AuthenticationOptions + { + /// + /// Creates an instance of bearer authentication options with default values. + /// + public OAuthBearerAuthenticationOptions() : base() + { + SystemClock = new SystemClock(); + AuthenticationType = OAuthBearerAuthenticationDefaults.AuthenticationType; + } + + /// + /// Determines what realm value is included when the bearer middleware adds a response header to an unauthorized request. + /// If not assigned, the response header does not have a realm. + /// + public string Realm { get; set; } + + /// + /// Specifies the full challenge to send to the client, and should start with "Bearer". If a challenge is provided then the + /// Realm property is ignored. If no challenge is specified then one is created using "Bearer" and the value of the Realm + /// property. + /// + public string Challenge { get; set; } + + /// + /// The object provided by the application to process events raised by the bearer authentication middleware. + /// The application may implement the interface fully, or it may create an instance of OAuthBearerAuthenticationProvider + /// and assign delegates only to the events it wants to process. + /// + public IOAuthBearerAuthenticationNotifications Notifications { get; set; } + + /// + /// The data format used to un-protect the information contained in the access token. + /// If not provided by the application the default data protection provider depends on the host server. + /// The SystemWeb host on IIS will use ASP.NET machine key data protection, and HttpListener and other self-hosted + /// servers will use DPAPI data protection. If a different access token + /// provider or format is assigned, a compatible instance must be assigned to the OAuthAuthorizationServerOptions.AccessTokenProvider + /// and OAuthAuthorizationServerOptions.AccessTokenFormat of the authorization server. + /// + public ISecureDataFormat AccessTokenFormat { get; set; } + + /// + /// Receives the bearer token the client application will be providing to web application. If not provided the token + /// produced on the server's default data protection by using the AccessTokenFormat. If a different access token + /// provider or format is assigned, a compatible instance must be assigned to the OAuthAuthorizationServerOptions.AccessTokenProvider + /// and OAuthAuthorizationServerOptions.AccessTokenFormat of the authorization server. + /// + public IAuthenticationTokenProvider AccessTokenProvider { get; set; } + + /// + /// Used to know what the current clock time is when calculating or validating token expiration. When not assigned default is based on + /// DateTimeOffset.UtcNow. This is typically needed only for unit testing. + /// + public ISystemClock SystemClock { get; set; } + } +} From e9038b40f1ba2d3f27833307bc7805ba6d20fa86 Mon Sep 17 00:00:00 2001 From: Hao Kung Date: Thu, 9 Oct 2014 14:15:58 -0700 Subject: [PATCH 065/216] React to UsePerRequestServices --- samples/CookieSample/Startup.cs | 2 +- samples/CookieSessionSample/Startup.cs | 2 +- samples/SocialSample/Startup.cs | 2 +- .../Cookies/CookieMiddlewareTests.cs | 2 +- .../Facebook/FacebookMiddlewareTests.cs | 4 ++-- .../Google/GoogleMiddlewareTests.cs | 2 +- .../MicrosoftAccount/MicrosoftAccountMiddlewareTests.cs | 2 +- .../Twitter/TwitterMiddlewareTests.cs | 2 +- 8 files changed, 9 insertions(+), 9 deletions(-) diff --git a/samples/CookieSample/Startup.cs b/samples/CookieSample/Startup.cs index fc78aec37..48c05fb7d 100644 --- a/samples/CookieSample/Startup.cs +++ b/samples/CookieSample/Startup.cs @@ -9,7 +9,7 @@ public class Startup { public void Configure(IApplicationBuilder app) { - app.UseServices(services => { }); + app.UsePerRequestServices(services => { }); app.UseCookieAuthentication(options => { }); diff --git a/samples/CookieSessionSample/Startup.cs b/samples/CookieSessionSample/Startup.cs index a4217e6d2..7772a392e 100644 --- a/samples/CookieSessionSample/Startup.cs +++ b/samples/CookieSessionSample/Startup.cs @@ -10,7 +10,7 @@ public class Startup { public void Configure(IApplicationBuilder app) { - app.UseServices(services => { }); + app.UsePerRequestServices(services => { }); app.UseCookieAuthentication(options => { options.SessionStore = new MemoryCacheSessionStore(); diff --git a/samples/SocialSample/Startup.cs b/samples/SocialSample/Startup.cs index 18f17ac0f..1836cc02a 100644 --- a/samples/SocialSample/Startup.cs +++ b/samples/SocialSample/Startup.cs @@ -24,7 +24,7 @@ public void Configure(IApplicationBuilder app) { app.UseErrorPage(); - app.UseServices(services => + app.UsePerRequestServices(services => { services.ConfigureOptions(options => { diff --git a/test/Microsoft.AspNet.Security.Test/Cookies/CookieMiddlewareTests.cs b/test/Microsoft.AspNet.Security.Test/Cookies/CookieMiddlewareTests.cs index a02dc1475..63b2c0f72 100644 --- a/test/Microsoft.AspNet.Security.Test/Cookies/CookieMiddlewareTests.cs +++ b/test/Microsoft.AspNet.Security.Test/Cookies/CookieMiddlewareTests.cs @@ -369,7 +369,7 @@ private static TestServer CreateServer(Action confi { return TestServer.Create(app => { - app.UseServices(services => { }); + app.UsePerRequestServices(services => { }); app.UseCookieAuthentication(configureOptions); app.Use(async (context, next) => { diff --git a/test/Microsoft.AspNet.Security.Test/Facebook/FacebookMiddlewareTests.cs b/test/Microsoft.AspNet.Security.Test/Facebook/FacebookMiddlewareTests.cs index 2f800c493..5e78bccda 100644 --- a/test/Microsoft.AspNet.Security.Test/Facebook/FacebookMiddlewareTests.cs +++ b/test/Microsoft.AspNet.Security.Test/Facebook/FacebookMiddlewareTests.cs @@ -27,7 +27,7 @@ public async Task ChallengeWillTriggerApplyRedirectEvent() var server = CreateServer( app => { - app.UseServices(services => + app.UsePerRequestServices(services => { services.ConfigureFacebookAuthentication(options => { @@ -70,7 +70,7 @@ public async Task ChallengeWillTriggerRedirection() var server = CreateServer( app => { - app.UseServices(services => + app.UsePerRequestServices(services => { services.ConfigureFacebookAuthentication(options => { diff --git a/test/Microsoft.AspNet.Security.Test/Google/GoogleMiddlewareTests.cs b/test/Microsoft.AspNet.Security.Test/Google/GoogleMiddlewareTests.cs index 2a58baf16..1993a56ae 100644 --- a/test/Microsoft.AspNet.Security.Test/Google/GoogleMiddlewareTests.cs +++ b/test/Microsoft.AspNet.Security.Test/Google/GoogleMiddlewareTests.cs @@ -465,7 +465,7 @@ private static TestServer CreateServer(Action confi { return TestServer.Create(app => { - app.UseServices(services => + app.UsePerRequestServices(services => { services.ConfigureOptions(options => { diff --git a/test/Microsoft.AspNet.Security.Test/MicrosoftAccount/MicrosoftAccountMiddlewareTests.cs b/test/Microsoft.AspNet.Security.Test/MicrosoftAccount/MicrosoftAccountMiddlewareTests.cs index 3a90d5fc5..d2372cc0a 100644 --- a/test/Microsoft.AspNet.Security.Test/MicrosoftAccount/MicrosoftAccountMiddlewareTests.cs +++ b/test/Microsoft.AspNet.Security.Test/MicrosoftAccount/MicrosoftAccountMiddlewareTests.cs @@ -163,7 +163,7 @@ private static TestServer CreateServer(Action { - app.UseServices(services => + app.UsePerRequestServices(services => { services.ConfigureOptions(options => { diff --git a/test/Microsoft.AspNet.Security.Test/Twitter/TwitterMiddlewareTests.cs b/test/Microsoft.AspNet.Security.Test/Twitter/TwitterMiddlewareTests.cs index 31afcfa7a..0fe4a8230 100644 --- a/test/Microsoft.AspNet.Security.Test/Twitter/TwitterMiddlewareTests.cs +++ b/test/Microsoft.AspNet.Security.Test/Twitter/TwitterMiddlewareTests.cs @@ -109,7 +109,7 @@ private static TestServer CreateServer(Action configure, Fu { return TestServer.Create(app => { - app.UseServices(services => + app.UsePerRequestServices(services => { services.ConfigureOptions(options => { From d598b83e33d407a8a150761b71f9d182015c8836 Mon Sep 17 00:00:00 2001 From: Pranav K Date: Fri, 10 Oct 2014 10:34:22 -0700 Subject: [PATCH 066/216] Reacting to CLR package versioning changes --- samples/CookieSessionSample/project.json | 2 +- .../project.json | 34 ++++++------- .../project.json | 40 ++++++++-------- .../project.json | 40 ++++++++-------- .../project.json | 44 ++++++++--------- .../project.json | 48 +++++++++---------- .../project.json | 44 ++++++++--------- src/Microsoft.AspNet.Security/project.json | 36 +++++++------- .../project.json | 2 +- 9 files changed, 145 insertions(+), 145 deletions(-) diff --git a/samples/CookieSessionSample/project.json b/samples/CookieSessionSample/project.json index 660715f5f..9e28721e3 100644 --- a/samples/CookieSessionSample/project.json +++ b/samples/CookieSessionSample/project.json @@ -1,4 +1,4 @@ -{ +{ "dependencies": { "Microsoft.AspNet.Security.Cookies": "1.0.0-*", "Microsoft.AspNet.Server.WebListener": "1.0.0-*", diff --git a/src/Microsoft.AspNet.Security.Cookies/project.json b/src/Microsoft.AspNet.Security.Cookies/project.json index 154d01821..c9e89b1c4 100644 --- a/src/Microsoft.AspNet.Security.Cookies/project.json +++ b/src/Microsoft.AspNet.Security.Cookies/project.json @@ -12,24 +12,24 @@ "aspnet50": {}, "aspnetcore50": { "dependencies": { - "System.Collections": "4.0.10.0", - "System.ComponentModel": "4.0.0.0", - "System.Console": "4.0.0.0", - "System.Diagnostics.Debug": "4.0.10.0", - "System.Diagnostics.Tools": "4.0.0.0", - "System.Globalization": "4.0.10.0", - "System.IO": "4.0.10.0", - "System.IO.Compression": "4.0.0.0", - "System.Linq": "4.0.0.0", - "System.Reflection": "4.0.10.0", - "System.Resources.ResourceManager": "4.0.0.0", - "System.Runtime": "4.0.20.0", - "System.Runtime.Extensions": "4.0.10.0", - "System.Runtime.InteropServices": "4.0.20.0", + "System.Collections": "4.0.10-beta-*", + "System.ComponentModel": "4.0.0-beta-*", + "System.Console": "4.0.0-beta-*", + "System.Diagnostics.Debug": "4.0.10-beta-*", + "System.Diagnostics.Tools": "4.0.0-beta-*", + "System.Globalization": "4.0.10-beta-*", + "System.IO": "4.0.10-beta-*", + "System.IO.Compression": "4.0.0-beta-*", + "System.Linq": "4.0.0-beta-*", + "System.Reflection": "4.0.10-beta-*", + "System.Resources.ResourceManager": "4.0.0-beta-*", + "System.Runtime": "4.0.20-beta-*", + "System.Runtime.Extensions": "4.0.10-beta-*", + "System.Runtime.InteropServices": "4.0.20-beta-*", "System.Security.Claims": "1.0.0-*", - "System.Security.Principal" : "4.0.0.0", - "System.Threading": "4.0.0.0", - "System.Threading.Tasks": "4.0.10.0" + "System.Security.Principal" : "4.0.0-beta-*", + "System.Threading": "4.0.0-beta-*", + "System.Threading.Tasks": "4.0.10-beta-*" } } } diff --git a/src/Microsoft.AspNet.Security.Facebook/project.json b/src/Microsoft.AspNet.Security.Facebook/project.json index 06da113a7..81ff96e81 100644 --- a/src/Microsoft.AspNet.Security.Facebook/project.json +++ b/src/Microsoft.AspNet.Security.Facebook/project.json @@ -13,31 +13,31 @@ "frameworks": { "aspnet50": { "frameworkAssemblies": { - "System.Net.Http": "4.0.0.0" + "System.Net.Http": "4.0.0-beta-*" } }, "aspnetcore50": { "dependencies": { - "System.Collections": "4.0.10.0", - "System.ComponentModel": "4.0.0.0", - "System.Console": "4.0.0.0", - "System.Diagnostics.Debug": "4.0.10.0", - "System.Diagnostics.Tools": "4.0.0.0", - "System.Globalization": "4.0.10.0", - "System.IO": "4.0.10.0", - "System.IO.Compression": "4.0.0.0", - "System.Linq": "4.0.0.0", - "System.Reflection": "4.0.10.0", - "System.Resources.ResourceManager": "4.0.0.0", - "System.Runtime": "4.0.20.0", - "System.Runtime.Extensions": "4.0.10.0", - "System.Runtime.InteropServices": "4.0.20.0", + "System.Collections": "4.0.10-beta-*", + "System.ComponentModel": "4.0.0-beta-*", + "System.Console": "4.0.0-beta-*", + "System.Diagnostics.Debug": "4.0.10-beta-*", + "System.Diagnostics.Tools": "4.0.0-beta-*", + "System.Globalization": "4.0.10-beta-*", + "System.IO": "4.0.10-beta-*", + "System.IO.Compression": "4.0.0-beta-*", + "System.Linq": "4.0.0-beta-*", + "System.Reflection": "4.0.10-beta-*", + "System.Resources.ResourceManager": "4.0.0-beta-*", + "System.Runtime": "4.0.20-beta-*", + "System.Runtime.Extensions": "4.0.10-beta-*", + "System.Runtime.InteropServices": "4.0.20-beta-*", "System.Security.Claims": "1.0.0-*", - "System.Security.Cryptography.Hashing.Algorithms": "4.0.0.0", - "System.Security.Principal": "4.0.0.0", - "System.Threading": "4.0.0.0", - "System.Threading.Tasks": "4.0.10.0", - "System.Net.Http": "4.0.0.0" + "System.Security.Cryptography.Hashing.Algorithms": "4.0.0-beta-*", + "System.Security.Principal": "4.0.0-beta-*", + "System.Threading": "4.0.0-beta-*", + "System.Threading.Tasks": "4.0.10-beta-*", + "System.Net.Http": "4.0.0-beta-*" } } } diff --git a/src/Microsoft.AspNet.Security.Google/project.json b/src/Microsoft.AspNet.Security.Google/project.json index 0cc8fa118..8317a9d14 100644 --- a/src/Microsoft.AspNet.Security.Google/project.json +++ b/src/Microsoft.AspNet.Security.Google/project.json @@ -13,31 +13,31 @@ "frameworks": { "aspnet50": { "frameworkAssemblies": { - "System.Net.Http": "4.0.0.0" + "System.Net.Http": "4.0.0-beta-*" } }, "aspnetcore50": { "dependencies": { - "System.Collections": "4.0.10.0", - "System.ComponentModel": "4.0.0.0", - "System.Console": "4.0.0.0", - "System.Diagnostics.Debug": "4.0.10.0", - "System.Diagnostics.Tools": "4.0.0.0", - "System.Globalization": "4.0.10.0", - "System.IO": "4.0.10.0", - "System.IO.Compression": "4.0.0.0", - "System.Linq": "4.0.0.0", - "System.Reflection": "4.0.10.0", - "System.Resources.ResourceManager": "4.0.0.0", - "System.Runtime": "4.0.20.0", - "System.Runtime.Extensions": "4.0.10.0", - "System.Runtime.InteropServices": "4.0.20.0", + "System.Collections": "4.0.10-beta-*", + "System.ComponentModel": "4.0.0-beta-*", + "System.Console": "4.0.0-beta-*", + "System.Diagnostics.Debug": "4.0.10-beta-*", + "System.Diagnostics.Tools": "4.0.0-beta-*", + "System.Globalization": "4.0.10-beta-*", + "System.IO": "4.0.10-beta-*", + "System.IO.Compression": "4.0.0-beta-*", + "System.Linq": "4.0.0-beta-*", + "System.Reflection": "4.0.10-beta-*", + "System.Resources.ResourceManager": "4.0.0-beta-*", + "System.Runtime": "4.0.20-beta-*", + "System.Runtime.Extensions": "4.0.10-beta-*", + "System.Runtime.InteropServices": "4.0.20-beta-*", "System.Security.Claims": "1.0.0-*", - "System.Security.Cryptography.Hashing.Algorithms": "4.0.0.0", - "System.Security.Principal": "4.0.0.0", - "System.Threading": "4.0.0.0", - "System.Threading.Tasks": "4.0.10.0", - "System.Net.Http": "4.0.0.0" + "System.Security.Cryptography.Hashing.Algorithms": "4.0.0-beta-*", + "System.Security.Principal": "4.0.0-beta-*", + "System.Threading": "4.0.0-beta-*", + "System.Threading.Tasks": "4.0.10-beta-*", + "System.Net.Http": "4.0.0-beta-*" } } } diff --git a/src/Microsoft.AspNet.Security.MicrosoftAccount/project.json b/src/Microsoft.AspNet.Security.MicrosoftAccount/project.json index 08fee1520..6c3046d7c 100644 --- a/src/Microsoft.AspNet.Security.MicrosoftAccount/project.json +++ b/src/Microsoft.AspNet.Security.MicrosoftAccount/project.json @@ -13,33 +13,33 @@ "frameworks": { "aspnet50": { "frameworkAssemblies": { - "System.Net.Http": "4.0.0.0" + "System.Net.Http": "4.0.0-beta-*" } }, "aspnetcore50": { "dependencies": { - "System.Collections": "4.0.10.0", - "System.ComponentModel": "4.0.0.0", - "System.Console": "4.0.0.0", - "System.Diagnostics.Debug": "4.0.10.0", - "System.Diagnostics.Tools": "4.0.0.0", - "System.Dynamic.Runtime": "4.0.0.0", - "System.Globalization": "4.0.10.0", - "System.IO": "4.0.10.0", - "System.IO.Compression": "4.0.0.0", - "System.Linq": "4.0.0.0", - "System.ObjectModel": "4.0.10.0", - "System.Reflection": "4.0.10.0", - "System.Resources.ResourceManager": "4.0.0.0", - "System.Runtime": "4.0.20.0", - "System.Runtime.Extensions": "4.0.10.0", - "System.Runtime.InteropServices": "4.0.20.0", + "System.Collections": "4.0.10-beta-*", + "System.ComponentModel": "4.0.0-beta-*", + "System.Console": "4.0.0-beta-*", + "System.Diagnostics.Debug": "4.0.10-beta-*", + "System.Diagnostics.Tools": "4.0.0-beta-*", + "System.Dynamic.Runtime": "4.0.0-beta-*", + "System.Globalization": "4.0.10-beta-*", + "System.IO": "4.0.10-beta-*", + "System.IO.Compression": "4.0.0-beta-*", + "System.Linq": "4.0.0-beta-*", + "System.ObjectModel": "4.0.10-beta-*", + "System.Reflection": "4.0.10-beta-*", + "System.Resources.ResourceManager": "4.0.0-beta-*", + "System.Runtime": "4.0.20-beta-*", + "System.Runtime.Extensions": "4.0.10-beta-*", + "System.Runtime.InteropServices": "4.0.20-beta-*", "System.Security.Claims": "1.0.0-*", - "System.Security.Cryptography.Hashing.Algorithms": "4.0.0.0", - "System.Security.Principal": "4.0.0.0", - "System.Threading": "4.0.0.0", - "System.Threading.Tasks": "4.0.10.0", - "System.Net.Http": "4.0.0.0" + "System.Security.Cryptography.Hashing.Algorithms": "4.0.0-beta-*", + "System.Security.Principal": "4.0.0-beta-*", + "System.Threading": "4.0.0-beta-*", + "System.Threading.Tasks": "4.0.10-beta-*", + "System.Net.Http": "4.0.0-beta-*" } } } diff --git a/src/Microsoft.AspNet.Security.OAuth/project.json b/src/Microsoft.AspNet.Security.OAuth/project.json index 0d4766cad..4e7a3227e 100644 --- a/src/Microsoft.AspNet.Security.OAuth/project.json +++ b/src/Microsoft.AspNet.Security.OAuth/project.json @@ -11,35 +11,35 @@ "frameworks": { "aspnet50": { "frameworkAssemblies": { - "System.Net.Http.WebRequest": "4.0.0.0", - "System.Net.Http": "4.0.0.0" + "System.Net.Http.WebRequest": "4.0.0-beta-*", + "System.Net.Http": "4.0.0-beta-*" } }, "aspnetcore50": { "dependencies": { - "System.Collections": "4.0.10.0", - "System.ComponentModel": "4.0.0.0", - "System.Console": "4.0.0.0", - "System.Diagnostics.Debug": "4.0.10.0", - "System.Diagnostics.Tools": "4.0.0.0", - "System.Dynamic.Runtime": "4.0.0.0", - "System.Globalization": "4.0.10.0", - "System.IO": "4.0.10.0", - "System.IO.Compression": "4.0.0.0", - "System.Linq": "4.0.0.0", - "System.Net.Http.WinHttpHandler": "4.0.0.0", - "System.ObjectModel": "4.0.10.0", - "System.Reflection": "4.0.10.0", - "System.Resources.ResourceManager": "4.0.0.0", - "System.Runtime": "4.0.20.0", - "System.Runtime.Extensions": "4.0.10.0", - "System.Runtime.InteropServices": "4.0.20.0", + "System.Collections": "4.0.10-beta-*", + "System.ComponentModel": "4.0.0-beta-*", + "System.Console": "4.0.0-beta-*", + "System.Diagnostics.Debug": "4.0.10-beta-*", + "System.Diagnostics.Tools": "4.0.0-beta-*", + "System.Dynamic.Runtime": "4.0.0-beta-*", + "System.Globalization": "4.0.10-beta-*", + "System.IO": "4.0.10-beta-*", + "System.IO.Compression": "4.0.0-beta-*", + "System.Linq": "4.0.0-beta-*", + "System.Net.Http.WinHttpHandler": "4.0.0-beta-*", + "System.ObjectModel": "4.0.10-beta-*", + "System.Reflection": "4.0.10-beta-*", + "System.Resources.ResourceManager": "4.0.0-beta-*", + "System.Runtime": "4.0.20-beta-*", + "System.Runtime.Extensions": "4.0.10-beta-*", + "System.Runtime.InteropServices": "4.0.20-beta-*", "System.Security.Claims": "1.0.0-*", - "System.Security.Cryptography.Hashing.Algorithms": "4.0.0.0", - "System.Security.Principal": "4.0.0.0", - "System.Threading": "4.0.0.0", - "System.Threading.Tasks": "4.0.10.0", - "System.Net.Http": "4.0.0.0" + "System.Security.Cryptography.Hashing.Algorithms": "4.0.0-beta-*", + "System.Security.Principal": "4.0.0-beta-*", + "System.Threading": "4.0.0-beta-*", + "System.Threading.Tasks": "4.0.10-beta-*", + "System.Net.Http": "4.0.0-beta-*" } } } diff --git a/src/Microsoft.AspNet.Security.Twitter/project.json b/src/Microsoft.AspNet.Security.Twitter/project.json index f5e8ef324..f838f0dc2 100644 --- a/src/Microsoft.AspNet.Security.Twitter/project.json +++ b/src/Microsoft.AspNet.Security.Twitter/project.json @@ -12,33 +12,33 @@ "frameworks": { "aspnet50": { "frameworkAssemblies": { - "System.Net.Http.WebRequest": "4.0.0.0", - "System.Net.Http": "4.0.0.0" + "System.Net.Http.WebRequest": "4.0.0-beta-*", + "System.Net.Http": "4.0.0-beta-*" } }, "aspnetcore50": { "dependencies": { - "System.Collections": "4.0.10.0", - "System.ComponentModel": "4.0.0.0", - "System.Console": "4.0.0.0", - "System.Diagnostics.Debug": "4.0.10.0", - "System.Diagnostics.Tools": "4.0.0.0", - "System.Globalization": "4.0.10.0", - "System.IO": "4.0.10.0", - "System.IO.Compression": "4.0.0.0", - "System.Linq": "4.0.0.0", - "System.Net.Http.WinHttpHandler": "4.0.0.0", - "System.Reflection": "4.0.10.0", - "System.Resources.ResourceManager": "4.0.0.0", - "System.Runtime": "4.0.20.0", - "System.Runtime.Extensions": "4.0.10.0", - "System.Runtime.InteropServices": "4.0.20.0", + "System.Collections": "4.0.10-beta-*", + "System.ComponentModel": "4.0.0-beta-*", + "System.Console": "4.0.0-beta-*", + "System.Diagnostics.Debug": "4.0.10-beta-*", + "System.Diagnostics.Tools": "4.0.0-beta-*", + "System.Globalization": "4.0.10-beta-*", + "System.IO": "4.0.10-beta-*", + "System.IO.Compression": "4.0.0-beta-*", + "System.Linq": "4.0.0-beta-*", + "System.Net.Http.WinHttpHandler": "4.0.0-beta-*", + "System.Reflection": "4.0.10-beta-*", + "System.Resources.ResourceManager": "4.0.0-beta-*", + "System.Runtime": "4.0.20-beta-*", + "System.Runtime.Extensions": "4.0.10-beta-*", + "System.Runtime.InteropServices": "4.0.20-beta-*", "System.Security.Claims": "1.0.0-*", - "System.Security.Cryptography.Hashing.Algorithms": "4.0.0.0", - "System.Security.Principal": "4.0.0.0", - "System.Threading": "4.0.0.0", - "System.Threading.Tasks": "4.0.10.0", - "System.Net.Http": "4.0.0.0" + "System.Security.Cryptography.Hashing.Algorithms": "4.0.0-beta-*", + "System.Security.Principal": "4.0.0-beta-*", + "System.Threading": "4.0.0-beta-*", + "System.Threading.Tasks": "4.0.10-beta-*", + "System.Net.Http": "4.0.0-beta-*" } } } diff --git a/src/Microsoft.AspNet.Security/project.json b/src/Microsoft.AspNet.Security/project.json index 502d45043..176c631f7 100644 --- a/src/Microsoft.AspNet.Security/project.json +++ b/src/Microsoft.AspNet.Security/project.json @@ -12,25 +12,25 @@ "aspnet50": { }, "aspnetcore50": { "dependencies": { - "System.Collections": "4.0.10.0", - "System.ComponentModel": "4.0.0.0", - "System.Console": "4.0.0.0", - "System.Diagnostics.Debug": "4.0.10.0", - "System.Diagnostics.Tools": "4.0.0.0", - "System.Globalization": "4.0.10.0", - "System.IO": "4.0.10.0", - "System.IO.Compression": "4.0.0.0", - "System.Linq": "4.0.0.0", - "System.Reflection": "4.0.10.0", - "System.Resources.ResourceManager": "4.0.0.0", - "System.Runtime": "4.0.20.0", - "System.Runtime.Extensions": "4.0.10.0", - "System.Runtime.InteropServices": "4.0.20.0", + "System.Collections": "4.0.10-beta-*", + "System.ComponentModel": "4.0.0-beta-*", + "System.Console": "4.0.0-beta-*", + "System.Diagnostics.Debug": "4.0.10-beta-*", + "System.Diagnostics.Tools": "4.0.0-beta-*", + "System.Globalization": "4.0.10-beta-*", + "System.IO": "4.0.10-beta-*", + "System.IO.Compression": "4.0.0-beta-*", + "System.Linq": "4.0.0-beta-*", + "System.Reflection": "4.0.10-beta-*", + "System.Resources.ResourceManager": "4.0.0-beta-*", + "System.Runtime": "4.0.20-beta-*", + "System.Runtime.Extensions": "4.0.10-beta-*", + "System.Runtime.InteropServices": "4.0.20-beta-*", "System.Security.Claims": "1.0.0-*", - "System.Security.Cryptography.RandomNumberGenerator": "4.0.0.0", - "System.Security.Principal": "4.0.0.0", - "System.Threading": "4.0.0.0", - "System.Threading.Tasks": "4.0.10.0" + "System.Security.Cryptography.RandomNumberGenerator": "4.0.0-beta-*", + "System.Security.Principal": "4.0.0-beta-*", + "System.Threading": "4.0.0-beta-*", + "System.Threading.Tasks": "4.0.10-beta-*" } } } diff --git a/test/Microsoft.AspNet.Security.Test/project.json b/test/Microsoft.AspNet.Security.Test/project.json index 7fa89c00c..a46009cb1 100644 --- a/test/Microsoft.AspNet.Security.Test/project.json +++ b/test/Microsoft.AspNet.Security.Test/project.json @@ -25,7 +25,7 @@ "Shouldly": "1.1.1.1" }, "frameworkAssemblies": { - "System.Net.Http": "4.0.0.0" + "System.Net.Http": "4.0.0-beta-*" } } } From 9e2f9924792da1c19f3b3ae37b292b1070c52686 Mon Sep 17 00:00:00 2001 From: Pranav K Date: Fri, 10 Oct 2014 10:57:33 -0700 Subject: [PATCH 067/216] Removing version from framework assemblies node --- src/Microsoft.AspNet.Security.Facebook/project.json | 2 +- src/Microsoft.AspNet.Security.Google/project.json | 2 +- src/Microsoft.AspNet.Security.MicrosoftAccount/project.json | 2 +- src/Microsoft.AspNet.Security.OAuth/project.json | 4 ++-- src/Microsoft.AspNet.Security.Twitter/project.json | 4 ++-- test/Microsoft.AspNet.Security.Test/project.json | 2 +- 6 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/Microsoft.AspNet.Security.Facebook/project.json b/src/Microsoft.AspNet.Security.Facebook/project.json index 81ff96e81..a4442582a 100644 --- a/src/Microsoft.AspNet.Security.Facebook/project.json +++ b/src/Microsoft.AspNet.Security.Facebook/project.json @@ -13,7 +13,7 @@ "frameworks": { "aspnet50": { "frameworkAssemblies": { - "System.Net.Http": "4.0.0-beta-*" + "System.Net.Http": "" } }, "aspnetcore50": { diff --git a/src/Microsoft.AspNet.Security.Google/project.json b/src/Microsoft.AspNet.Security.Google/project.json index 8317a9d14..b50bcd27c 100644 --- a/src/Microsoft.AspNet.Security.Google/project.json +++ b/src/Microsoft.AspNet.Security.Google/project.json @@ -13,7 +13,7 @@ "frameworks": { "aspnet50": { "frameworkAssemblies": { - "System.Net.Http": "4.0.0-beta-*" + "System.Net.Http": "" } }, "aspnetcore50": { diff --git a/src/Microsoft.AspNet.Security.MicrosoftAccount/project.json b/src/Microsoft.AspNet.Security.MicrosoftAccount/project.json index 6c3046d7c..f85c94de7 100644 --- a/src/Microsoft.AspNet.Security.MicrosoftAccount/project.json +++ b/src/Microsoft.AspNet.Security.MicrosoftAccount/project.json @@ -13,7 +13,7 @@ "frameworks": { "aspnet50": { "frameworkAssemblies": { - "System.Net.Http": "4.0.0-beta-*" + "System.Net.Http": "" } }, "aspnetcore50": { diff --git a/src/Microsoft.AspNet.Security.OAuth/project.json b/src/Microsoft.AspNet.Security.OAuth/project.json index 4e7a3227e..7cf7c0fc8 100644 --- a/src/Microsoft.AspNet.Security.OAuth/project.json +++ b/src/Microsoft.AspNet.Security.OAuth/project.json @@ -11,8 +11,8 @@ "frameworks": { "aspnet50": { "frameworkAssemblies": { - "System.Net.Http.WebRequest": "4.0.0-beta-*", - "System.Net.Http": "4.0.0-beta-*" + "System.Net.Http.WebRequest": "", + "System.Net.Http": "" } }, "aspnetcore50": { diff --git a/src/Microsoft.AspNet.Security.Twitter/project.json b/src/Microsoft.AspNet.Security.Twitter/project.json index f838f0dc2..f48ebe5ab 100644 --- a/src/Microsoft.AspNet.Security.Twitter/project.json +++ b/src/Microsoft.AspNet.Security.Twitter/project.json @@ -12,8 +12,8 @@ "frameworks": { "aspnet50": { "frameworkAssemblies": { - "System.Net.Http.WebRequest": "4.0.0-beta-*", - "System.Net.Http": "4.0.0-beta-*" + "System.Net.Http.WebRequest": "", + "System.Net.Http": "" } }, "aspnetcore50": { diff --git a/test/Microsoft.AspNet.Security.Test/project.json b/test/Microsoft.AspNet.Security.Test/project.json index a46009cb1..bcff7a978 100644 --- a/test/Microsoft.AspNet.Security.Test/project.json +++ b/test/Microsoft.AspNet.Security.Test/project.json @@ -25,7 +25,7 @@ "Shouldly": "1.1.1.1" }, "frameworkAssemblies": { - "System.Net.Http": "4.0.0-beta-*" + "System.Net.Http": "" } } } From 2e65a405552395f6e742906b574405a6a5003e05 Mon Sep 17 00:00:00 2001 From: Levi B Date: Fri, 10 Oct 2014 12:21:08 -0700 Subject: [PATCH 068/216] Update Security to account for DataProtector API changes. --- .../DataProtection/DataProtectionHelpers.cs | 3 ++- .../Google/GoogleMiddlewareTests.cs | 8 ++++---- .../MicrosoftAccount/MicrosoftAccountMiddlewareTests.cs | 2 +- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/Microsoft.AspNet.Security/DataProtection/DataProtectionHelpers.cs b/src/Microsoft.AspNet.Security/DataProtection/DataProtectionHelpers.cs index a043bb83b..eba80e708 100644 --- a/src/Microsoft.AspNet.Security/DataProtection/DataProtectionHelpers.cs +++ b/src/Microsoft.AspNet.Security/DataProtection/DataProtectionHelpers.cs @@ -13,7 +13,8 @@ public static IDataProtector CreateDataProtector(IDataProtectionProvider dataPro { if (dataProtectionProvider == null) { - dataProtectionProvider = DataProtectionProvider.CreateFromDpapi(); + // TODO: Get this from the environment. + dataProtectionProvider = new EphemeralDataProtectionProvider(); } return dataProtectionProvider.CreateProtector(string.Join(";", purposes)); diff --git a/test/Microsoft.AspNet.Security.Test/Google/GoogleMiddlewareTests.cs b/test/Microsoft.AspNet.Security.Test/Google/GoogleMiddlewareTests.cs index 1993a56ae..c7c931067 100644 --- a/test/Microsoft.AspNet.Security.Test/Google/GoogleMiddlewareTests.cs +++ b/test/Microsoft.AspNet.Security.Test/Google/GoogleMiddlewareTests.cs @@ -215,7 +215,7 @@ public async Task ReplyPathWithoutStateQueryStringWillBeRejected() [Fact] public async Task ReplyPathWillAuthenticateValidAuthorizeCodeAndState() { - ISecureDataFormat stateFormat = new PropertiesDataFormat(DataProtectionProvider.CreateNew().CreateProtector("GoogleTest")); + ISecureDataFormat stateFormat = new PropertiesDataFormat(new EphemeralDataProtectionProvider().CreateProtector("GoogleTest")); var server = CreateServer(options => { options.ClientId = "Test Id"; @@ -289,7 +289,7 @@ public async Task ReplyPathWillAuthenticateValidAuthorizeCodeAndState() [Fact] public async Task ReplyPathWillRejectIfCodeIsInvalid() { - ISecureDataFormat stateFormat = new PropertiesDataFormat(DataProtectionProvider.CreateNew().CreateProtector("GoogleTest")); + ISecureDataFormat stateFormat = new PropertiesDataFormat(new EphemeralDataProtectionProvider().CreateProtector("GoogleTest")); var server = CreateServer(options => { options.ClientId = "Test Id"; @@ -319,7 +319,7 @@ public async Task ReplyPathWillRejectIfCodeIsInvalid() [Fact] public async Task ReplyPathWillRejectIfAccessTokenIsMissing() { - ISecureDataFormat stateFormat = new PropertiesDataFormat(DataProtectionProvider.CreateNew().CreateProtector("GoogleTest")); + ISecureDataFormat stateFormat = new PropertiesDataFormat(new EphemeralDataProtectionProvider().CreateProtector("GoogleTest")); var server = CreateServer(options => { options.ClientId = "Test Id"; @@ -349,7 +349,7 @@ public async Task ReplyPathWillRejectIfAccessTokenIsMissing() [Fact] public async Task AuthenticatedEventCanGetRefreshToken() { - ISecureDataFormat stateFormat = new PropertiesDataFormat(DataProtectionProvider.CreateNew().CreateProtector("GoogleTest")); + ISecureDataFormat stateFormat = new PropertiesDataFormat(new EphemeralDataProtectionProvider().CreateProtector("GoogleTest")); var server = CreateServer(options => { options.ClientId = "Test Id"; diff --git a/test/Microsoft.AspNet.Security.Test/MicrosoftAccount/MicrosoftAccountMiddlewareTests.cs b/test/Microsoft.AspNet.Security.Test/MicrosoftAccount/MicrosoftAccountMiddlewareTests.cs index d2372cc0a..2b39e4352 100644 --- a/test/Microsoft.AspNet.Security.Test/MicrosoftAccount/MicrosoftAccountMiddlewareTests.cs +++ b/test/Microsoft.AspNet.Security.Test/MicrosoftAccount/MicrosoftAccountMiddlewareTests.cs @@ -84,7 +84,7 @@ public async Task ChallengeWillTriggerRedirection() [Fact] public async Task AuthenticatedEventCanGetRefreshToken() { - ISecureDataFormat stateFormat = new PropertiesDataFormat(DataProtectionProvider.CreateNew().CreateProtector("MsftTest")); + ISecureDataFormat stateFormat = new PropertiesDataFormat(new EphemeralDataProtectionProvider().CreateProtector("MsftTest")); var server = CreateServer( options => { From 3e88f44552da8e5395cc80d390ce1c9407408e16 Mon Sep 17 00:00:00 2001 From: Chris Ross Date: Fri, 10 Oct 2014 11:54:26 -0700 Subject: [PATCH 069/216] #69 - Properly delete Twitter state cookie. --- .../TwitterAuthenticationHandler.cs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/Microsoft.AspNet.Security.Twitter/TwitterAuthenticationHandler.cs b/src/Microsoft.AspNet.Security.Twitter/TwitterAuthenticationHandler.cs index 7fbb4fbc3..7eeac5702 100644 --- a/src/Microsoft.AspNet.Security.Twitter/TwitterAuthenticationHandler.cs +++ b/src/Microsoft.AspNet.Security.Twitter/TwitterAuthenticationHandler.cs @@ -104,7 +104,13 @@ protected override async Task AuthenticateCoreAsync() ClaimsIdentity.DefaultRoleClaimType); context.Properties = requestToken.Properties; - Response.Cookies.Delete(StateCookie); + var cookieOptions = new CookieOptions + { + HttpOnly = true, + Secure = Request.IsSecure + }; + + Response.Cookies.Delete(StateCookie, cookieOptions); await Options.Notifications.Authenticated(context); From e315a545cb37c6a1a410313dc19c4908eff2ff30 Mon Sep 17 00:00:00 2001 From: Chris Ross Date: Fri, 10 Oct 2014 12:05:34 -0700 Subject: [PATCH 070/216] #61 - Unit test cleanup. --- .../Google/GoogleMiddlewareTests.cs | 26 ++++++++--------- .../MicrosoftAccountMiddlewareTests.cs | 18 ++++++------ .../Twitter/TwitterMiddlewareTests.cs | 28 +++++++------------ 3 files changed, 32 insertions(+), 40 deletions(-) diff --git a/test/Microsoft.AspNet.Security.Test/Google/GoogleMiddlewareTests.cs b/test/Microsoft.AspNet.Security.Test/Google/GoogleMiddlewareTests.cs index c7c931067..564935496 100644 --- a/test/Microsoft.AspNet.Security.Test/Google/GoogleMiddlewareTests.cs +++ b/test/Microsoft.AspNet.Security.Test/Google/GoogleMiddlewareTests.cs @@ -223,11 +223,11 @@ public async Task ReplyPathWillAuthenticateValidAuthorizeCodeAndState() options.StateDataFormat = stateFormat; options.BackchannelHttpHandler = new TestHttpMessageHandler { - Sender = async req => + Sender = req => { if (req.RequestUri.AbsoluteUri == "https://accounts.google.com/o/oauth2/token") { - return await ReturnJsonResponse(new + return ReturnJsonResponse(new { access_token = "Test Access Token", expire_in = 3600, @@ -236,7 +236,7 @@ public async Task ReplyPathWillAuthenticateValidAuthorizeCodeAndState() } else if (req.RequestUri.GetLeftPart(UriPartial.Path) == "https://www.googleapis.com/plus/v1/people/me") { - return await ReturnJsonResponse(new + return ReturnJsonResponse(new { id = "Test User ID", displayName = "Test Name", @@ -299,7 +299,7 @@ public async Task ReplyPathWillRejectIfCodeIsInvalid() { Sender = req => { - return Task.FromResult(new HttpResponseMessage(HttpStatusCode.BadRequest)); + return new HttpResponseMessage(HttpStatusCode.BadRequest); } }; }); @@ -357,11 +357,11 @@ public async Task AuthenticatedEventCanGetRefreshToken() options.StateDataFormat = stateFormat; options.BackchannelHttpHandler = new TestHttpMessageHandler { - Sender = async req => + Sender = req => { if (req.RequestUri.AbsoluteUri == "https://accounts.google.com/o/oauth2/token") { - return await ReturnJsonResponse(new + return ReturnJsonResponse(new { access_token = "Test Access Token", expire_in = 3600, @@ -371,7 +371,7 @@ public async Task AuthenticatedEventCanGetRefreshToken() } else if (req.RequestUri.GetLeftPart(UriPartial.Path) == "https://www.googleapis.com/plus/v1/people/me") { - return await ReturnJsonResponse(new + return ReturnJsonResponse(new { id = "Test User ID", displayName = "Test Name", @@ -426,10 +426,10 @@ public async Task AuthenticatedEventCanGetRefreshToken() transaction.FindClaimValue("RefreshToken").ShouldBe("Test Refresh Token"); } - private static async Task ReturnJsonResponse(object content) + private static HttpResponseMessage ReturnJsonResponse(object content) { var res = new HttpResponseMessage(HttpStatusCode.OK); - var text = await Task.Factory.StartNew(() => JsonConvert.SerializeObject(content)); + var text = JsonConvert.SerializeObject(content); res.Content = new StringContent(text, Encoding.UTF8, "application/json"); return res; } @@ -524,16 +524,16 @@ private static void Describe(HttpResponse res, ClaimsIdentity identity) private class TestHttpMessageHandler : HttpMessageHandler { - public Func> Sender { get; set; } + public Func Sender { get; set; } - protected override async Task SendAsync(HttpRequestMessage request, System.Threading.CancellationToken cancellationToken) + protected override Task SendAsync(HttpRequestMessage request, System.Threading.CancellationToken cancellationToken) { if (Sender != null) { - return await Sender(request); + return Task.FromResult(Sender(request)); } - return null; + return Task.FromResult(null); } } diff --git a/test/Microsoft.AspNet.Security.Test/MicrosoftAccount/MicrosoftAccountMiddlewareTests.cs b/test/Microsoft.AspNet.Security.Test/MicrosoftAccount/MicrosoftAccountMiddlewareTests.cs index 2b39e4352..c42ec1851 100644 --- a/test/Microsoft.AspNet.Security.Test/MicrosoftAccount/MicrosoftAccountMiddlewareTests.cs +++ b/test/Microsoft.AspNet.Security.Test/MicrosoftAccount/MicrosoftAccountMiddlewareTests.cs @@ -93,11 +93,11 @@ public async Task AuthenticatedEventCanGetRefreshToken() options.StateDataFormat = stateFormat; options.BackchannelHttpHandler = new TestHttpMessageHandler { - Sender = async req => + Sender = req => { if (req.RequestUri.AbsoluteUri == "https://login.live.com/oauth20_token.srf") { - return await ReturnJsonResponse(new + return ReturnJsonResponse(new { access_token = "Test Access Token", expire_in = 3600, @@ -107,7 +107,7 @@ public async Task AuthenticatedEventCanGetRefreshToken() } else if (req.RequestUri.GetLeftPart(UriPartial.Path) == "https://apis.live.net/v5.0/me") { - return await ReturnJsonResponse(new + return ReturnJsonResponse(new { id = "Test User ID", name = "Test Name", @@ -209,10 +209,10 @@ private static async Task SendAsync(TestServer server, string uri, return transaction; } - private static async Task ReturnJsonResponse(object content) + private static HttpResponseMessage ReturnJsonResponse(object content) { var res = new HttpResponseMessage(HttpStatusCode.OK); - var text = await Task.Factory.StartNew(() => JsonConvert.SerializeObject(content)); + var text = JsonConvert.SerializeObject(content); res.Content = new StringContent(text, Encoding.UTF8, "application/json"); return res; } @@ -238,16 +238,16 @@ private static void Describe(HttpResponse res, ClaimsIdentity identity) private class TestHttpMessageHandler : HttpMessageHandler { - public Func> Sender { get; set; } + public Func Sender { get; set; } - protected override async Task SendAsync(HttpRequestMessage request, System.Threading.CancellationToken cancellationToken) + protected override Task SendAsync(HttpRequestMessage request, System.Threading.CancellationToken cancellationToken) { if (Sender != null) { - return await Sender(request); + return Task.FromResult(Sender(request)); } - return null; + return Task.FromResult(null); } } diff --git a/test/Microsoft.AspNet.Security.Test/Twitter/TwitterMiddlewareTests.cs b/test/Microsoft.AspNet.Security.Test/Twitter/TwitterMiddlewareTests.cs index 0fe4a8230..e9b54e4bc 100644 --- a/test/Microsoft.AspNet.Security.Test/Twitter/TwitterMiddlewareTests.cs +++ b/test/Microsoft.AspNet.Security.Test/Twitter/TwitterMiddlewareTests.cs @@ -43,15 +43,15 @@ public async Task ChallengeWillTriggerApplyRedirectEvent() { if (req.RequestUri.AbsoluteUri == "https://api.twitter.com/oauth/request_token") { - return Task.FromResult(new HttpResponseMessage(HttpStatusCode.OK) + return new HttpResponseMessage(HttpStatusCode.OK) { Content = new StringContent("oauth_callback_confirmed=true&oauth_token=test_oauth_token&oauth_token_secret=test_oauth_token_secret", Encoding.UTF8, "application/x-www-form-urlencoded") - }); + }; } - return Task.FromResult(null); + return null; } }; options.BackchannelCertificateValidator = null; @@ -81,15 +81,15 @@ public async Task ChallengeWillTriggerRedirection() { if (req.RequestUri.AbsoluteUri == "https://api.twitter.com/oauth/request_token") { - return Task.FromResult(new HttpResponseMessage(HttpStatusCode.OK) + return new HttpResponseMessage(HttpStatusCode.OK) { Content = new StringContent("oauth_callback_confirmed=true&oauth_token=test_oauth_token&oauth_token_secret=test_oauth_token_secret", Encoding.UTF8, "application/x-www-form-urlencoded") - }); + }; } - return Task.FromResult(null); + return null; } }; options.BackchannelCertificateValidator = null; @@ -155,26 +155,18 @@ private static async Task SendAsync(TestServer server, string uri, return transaction; } - private static async Task ReturnJsonResponse(object content) - { - var res = new HttpResponseMessage(HttpStatusCode.OK); - var text = await Task.Factory.StartNew(() => JsonConvert.SerializeObject(content)); - res.Content = new StringContent(text, Encoding.UTF8, "application/json"); - return res; - } - private class TestHttpMessageHandler : HttpMessageHandler { - public Func> Sender { get; set; } + public Func Sender { get; set; } - protected override async Task SendAsync(HttpRequestMessage request, System.Threading.CancellationToken cancellationToken) + protected override Task SendAsync(HttpRequestMessage request, System.Threading.CancellationToken cancellationToken) { if (Sender != null) { - return await Sender(request); + return Task.FromResult(Sender(request)); } - return null; + return Task.FromResult(null); } } From 6965a66f18a6229a1f7bee76b4b2c499f44b1ca1 Mon Sep 17 00:00:00 2001 From: Chris Ross Date: Fri, 10 Oct 2014 12:12:48 -0700 Subject: [PATCH 071/216] #59 - Use Task.GetAwaiter().GetResult() instead of Task.Result. --- .../CookieAuthenticationHandler.cs | 4 ++-- .../OAuthAuthenticationHandler.cs | 2 +- .../OAuthBearerAuthenticationHandler.cs | 2 +- .../TwitterAuthenticationHandler.cs | 4 ++-- src/Microsoft.AspNet.Security/DefaultAuthorizationService.cs | 2 +- .../Infrastructure/AuthenticationHandler.cs | 4 ++-- .../DefaultAuthorizationServiceTests.cs | 2 +- 7 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/Microsoft.AspNet.Security.Cookies/CookieAuthenticationHandler.cs b/src/Microsoft.AspNet.Security.Cookies/CookieAuthenticationHandler.cs index 4a43b58be..63c524afa 100644 --- a/src/Microsoft.AspNet.Security.Cookies/CookieAuthenticationHandler.cs +++ b/src/Microsoft.AspNet.Security.Cookies/CookieAuthenticationHandler.cs @@ -36,7 +36,7 @@ public CookieAuthenticationHandler([NotNull] ILogger logger) protected override AuthenticationTicket AuthenticateCore() { - return AuthenticateCoreAsync().Result; + return AuthenticateCoreAsync().GetAwaiter().GetResult(); } protected override async Task AuthenticateCoreAsync() @@ -124,7 +124,7 @@ protected override async Task AuthenticateCoreAsync() protected override void ApplyResponseGrant() { - ApplyResponseGrantAsync().Wait(); + ApplyResponseGrantAsync().GetAwaiter().GetResult(); } protected override async Task ApplyResponseGrantAsync() diff --git a/src/Microsoft.AspNet.Security.OAuth/OAuthAuthenticationHandler.cs b/src/Microsoft.AspNet.Security.OAuth/OAuthAuthenticationHandler.cs index eae146363..5a4ffebbd 100644 --- a/src/Microsoft.AspNet.Security.OAuth/OAuthAuthenticationHandler.cs +++ b/src/Microsoft.AspNet.Security.OAuth/OAuthAuthenticationHandler.cs @@ -84,7 +84,7 @@ public async Task InvokeReturnPathAsync() protected override AuthenticationTicket AuthenticateCore() { - return AuthenticateCoreAsync().Result; + return AuthenticateCoreAsync().GetAwaiter().GetResult(); } protected override async Task AuthenticateCoreAsync() diff --git a/src/Microsoft.AspNet.Security.OAuth/OAuthBearerAuthenticationHandler.cs b/src/Microsoft.AspNet.Security.OAuth/OAuthBearerAuthenticationHandler.cs index b49db1f71..406085b67 100644 --- a/src/Microsoft.AspNet.Security.OAuth/OAuthBearerAuthenticationHandler.cs +++ b/src/Microsoft.AspNet.Security.OAuth/OAuthBearerAuthenticationHandler.cs @@ -21,7 +21,7 @@ public OAuthBearerAuthenticationHandler(ILogger logger, string challenge) protected override AuthenticationTicket AuthenticateCore() { - return AuthenticateCoreAsync().Result; + return AuthenticateCoreAsync().GetAwaiter().GetResult(); } protected override async Task AuthenticateCoreAsync() diff --git a/src/Microsoft.AspNet.Security.Twitter/TwitterAuthenticationHandler.cs b/src/Microsoft.AspNet.Security.Twitter/TwitterAuthenticationHandler.cs index 7eeac5702..7717642a1 100644 --- a/src/Microsoft.AspNet.Security.Twitter/TwitterAuthenticationHandler.cs +++ b/src/Microsoft.AspNet.Security.Twitter/TwitterAuthenticationHandler.cs @@ -46,7 +46,7 @@ public override async Task InvokeAsync() protected override AuthenticationTicket AuthenticateCore() { - return AuthenticateCoreAsync().Result; + return AuthenticateCoreAsync().GetAwaiter().GetResult(); } protected override async Task AuthenticateCoreAsync() @@ -124,7 +124,7 @@ protected override async Task AuthenticateCoreAsync() } protected override void ApplyResponseChallenge() { - ApplyResponseChallengeAsync().Wait(); + ApplyResponseChallengeAsync().GetAwaiter().GetResult(); } protected override async Task ApplyResponseChallengeAsync() diff --git a/src/Microsoft.AspNet.Security/DefaultAuthorizationService.cs b/src/Microsoft.AspNet.Security/DefaultAuthorizationService.cs index aaa1dbc10..0b05a6d3d 100644 --- a/src/Microsoft.AspNet.Security/DefaultAuthorizationService.cs +++ b/src/Microsoft.AspNet.Security/DefaultAuthorizationService.cs @@ -84,7 +84,7 @@ public async Task AuthorizeAsync(IEnumerable claims, ClaimsPrincipa public bool Authorize(IEnumerable claims, ClaimsPrincipal user, object resource) { - return AuthorizeAsync(claims, user, resource).Result; + return AuthorizeAsync(claims, user, resource).GetAwaiter().GetResult(); } private bool ClaimsMatch([NotNull] IEnumerable x, [NotNull] IEnumerable y) diff --git a/src/Microsoft.AspNet.Security/Infrastructure/AuthenticationHandler.cs b/src/Microsoft.AspNet.Security/Infrastructure/AuthenticationHandler.cs index f7e5adc34..a5fd9876c 100644 --- a/src/Microsoft.AspNet.Security/Infrastructure/AuthenticationHandler.cs +++ b/src/Microsoft.AspNet.Security/Infrastructure/AuthenticationHandler.cs @@ -183,7 +183,7 @@ public AuthenticationTicket Authenticate() () => { return Task.FromResult(AuthenticateCore()); - }).Result; + }).GetAwaiter().GetResult(); } protected abstract AuthenticationTicket AuthenticateCore(); @@ -225,7 +225,7 @@ private void ApplyResponse() { ApplyResponseCore(); return Task.FromResult(0); - }).Wait(); // Block if the async version is in progress. + }).GetAwaiter().GetResult(); // Block if the async version is in progress. } protected virtual void ApplyResponseCore() diff --git a/test/Microsoft.AspNet.Security.Test/DefaultAuthorizationServiceTests.cs b/test/Microsoft.AspNet.Security.Test/DefaultAuthorizationServiceTests.cs index fd3a668a2..a5a003b80 100644 --- a/test/Microsoft.AspNet.Security.Test/DefaultAuthorizationServiceTests.cs +++ b/test/Microsoft.AspNet.Security.Test/DefaultAuthorizationServiceTests.cs @@ -242,7 +242,7 @@ public void Check_ShouldThrowWhenPoliciesDontStop() // Act // Assert - Exception ex = Assert.Throws(() => authorizationService.Authorize(Enumerable.Empty(), null)); + Exception ex = Assert.Throws(() => authorizationService.Authorize(Enumerable.Empty(), null)); } [Fact] From 84dfcf5258b12607656edae79fd4dcf9802a3b05 Mon Sep 17 00:00:00 2001 From: Hao Kung Date: Tue, 14 Oct 2014 19:14:54 -0700 Subject: [PATCH 072/216] React to Options and Hosting changes --- samples/CookieSample/Startup.cs | 2 +- samples/CookieSessionSample/Startup.cs | 2 +- samples/SocialSample/Startup.cs | 2 +- .../CookieAuthenticationExtensions.cs | 4 ++-- .../CookieAuthenticationMiddleware.cs | 4 ++-- .../FacebookAuthenticationExtensions.cs | 4 ++-- .../FacebookAuthenticationMiddleware.cs | 6 +++--- .../GoogleAuthenticationExtensions.cs | 4 ++-- .../GoogleAuthenticationMiddleware.cs | 6 +++--- .../MicrosoftAccountAuthenticationExtensions.cs | 4 ++-- .../MicrosoftAccountAuthenticationMiddleware.cs | 6 +++--- .../OAuthAuthenticationExtensions.cs | 2 +- .../OAuthAuthenticationMiddleware.cs | 6 +++--- .../OAuthBearerAuthenticationExtensions.cs | 2 +- .../OAuthBearerAuthenticationMiddleware.cs | 4 ++-- .../TwitterAuthenticationExtensions.cs | 4 ++-- .../TwitterAuthenticationMiddleware.cs | 6 +++--- .../Infrastructure/AuthenticationMiddleware.cs | 4 ++-- .../Cookies/CookieMiddlewareTests.cs | 2 +- .../Facebook/FacebookMiddlewareTests.cs | 8 ++++---- .../Google/GoogleMiddlewareTests.cs | 4 ++-- .../MicrosoftAccount/MicrosoftAccountMiddlewareTests.cs | 4 ++-- .../Twitter/TwitterMiddlewareTests.cs | 4 ++-- 23 files changed, 47 insertions(+), 47 deletions(-) diff --git a/samples/CookieSample/Startup.cs b/samples/CookieSample/Startup.cs index 48c05fb7d..fc78aec37 100644 --- a/samples/CookieSample/Startup.cs +++ b/samples/CookieSample/Startup.cs @@ -9,7 +9,7 @@ public class Startup { public void Configure(IApplicationBuilder app) { - app.UsePerRequestServices(services => { }); + app.UseServices(services => { }); app.UseCookieAuthentication(options => { }); diff --git a/samples/CookieSessionSample/Startup.cs b/samples/CookieSessionSample/Startup.cs index 7772a392e..a4217e6d2 100644 --- a/samples/CookieSessionSample/Startup.cs +++ b/samples/CookieSessionSample/Startup.cs @@ -10,7 +10,7 @@ public class Startup { public void Configure(IApplicationBuilder app) { - app.UsePerRequestServices(services => { }); + app.UseServices(services => { }); app.UseCookieAuthentication(options => { options.SessionStore = new MemoryCacheSessionStore(); diff --git a/samples/SocialSample/Startup.cs b/samples/SocialSample/Startup.cs index 1836cc02a..18f17ac0f 100644 --- a/samples/SocialSample/Startup.cs +++ b/samples/SocialSample/Startup.cs @@ -24,7 +24,7 @@ public void Configure(IApplicationBuilder app) { app.UseErrorPage(); - app.UsePerRequestServices(services => + app.UseServices(services => { services.ConfigureOptions(options => { diff --git a/src/Microsoft.AspNet.Security.Cookies/CookieAuthenticationExtensions.cs b/src/Microsoft.AspNet.Security.Cookies/CookieAuthenticationExtensions.cs index 98d39cca7..191d44da8 100644 --- a/src/Microsoft.AspNet.Security.Cookies/CookieAuthenticationExtensions.cs +++ b/src/Microsoft.AspNet.Security.Cookies/CookieAuthenticationExtensions.cs @@ -15,7 +15,7 @@ public static class CookieAuthenticationExtensions { public static IServiceCollection ConfigureCookieAuthentication([NotNull] this IServiceCollection services, [NotNull] Action configure) { - return services.ConfigureOptions(configure); + return services.Configure(configure); } /// @@ -28,7 +28,7 @@ public static IServiceCollection ConfigureCookieAuthentication([NotNull] this IS public static IApplicationBuilder UseCookieAuthentication([NotNull] this IApplicationBuilder app, Action configureOptions = null, string optionsName = "") { return app.UseMiddleware( - new OptionsAction(configureOptions ?? (o => { })) + new ConfigureOptions(configureOptions ?? (o => { })) { Name = optionsName }); diff --git a/src/Microsoft.AspNet.Security.Cookies/CookieAuthenticationMiddleware.cs b/src/Microsoft.AspNet.Security.Cookies/CookieAuthenticationMiddleware.cs index fff690665..087820e29 100644 --- a/src/Microsoft.AspNet.Security.Cookies/CookieAuthenticationMiddleware.cs +++ b/src/Microsoft.AspNet.Security.Cookies/CookieAuthenticationMiddleware.cs @@ -20,8 +20,8 @@ public class CookieAuthenticationMiddleware : AuthenticationMiddleware options, - IOptionsAction configureOptions) + IOptions options, + ConfigureOptions configureOptions) : base(next, options, configureOptions) { if (Options.Notifications == null) diff --git a/src/Microsoft.AspNet.Security.Facebook/FacebookAuthenticationExtensions.cs b/src/Microsoft.AspNet.Security.Facebook/FacebookAuthenticationExtensions.cs index aa59e2efe..51c5eac0e 100644 --- a/src/Microsoft.AspNet.Security.Facebook/FacebookAuthenticationExtensions.cs +++ b/src/Microsoft.AspNet.Security.Facebook/FacebookAuthenticationExtensions.cs @@ -15,7 +15,7 @@ public static class FacebookAuthenticationExtensions { public static IServiceCollection ConfigureFacebookAuthentication([NotNull] this IServiceCollection services, [NotNull] Action configure) { - return services.ConfigureOptions(configure); + return services.Configure(configure); } /// @@ -26,7 +26,7 @@ public static IServiceCollection ConfigureFacebookAuthentication([NotNull] this public static IApplicationBuilder UseFacebookAuthentication([NotNull] this IApplicationBuilder app, Action configureOptions = null, string optionsName = "") { return app.UseMiddleware( - new OptionsAction(configureOptions ?? (o => { })) + new ConfigureOptions(configureOptions ?? (o => { })) { Name = optionsName }); diff --git a/src/Microsoft.AspNet.Security.Facebook/FacebookAuthenticationMiddleware.cs b/src/Microsoft.AspNet.Security.Facebook/FacebookAuthenticationMiddleware.cs index a453e085a..b7891d139 100644 --- a/src/Microsoft.AspNet.Security.Facebook/FacebookAuthenticationMiddleware.cs +++ b/src/Microsoft.AspNet.Security.Facebook/FacebookAuthenticationMiddleware.cs @@ -28,9 +28,9 @@ public FacebookAuthenticationMiddleware( RequestDelegate next, IDataProtectionProvider dataProtectionProvider, ILoggerFactory loggerFactory, - IOptionsAccessor externalOptions, - IOptionsAccessor options, - IOptionsAction configureOptions = null) + IOptions externalOptions, + IOptions options, + ConfigureOptions configureOptions = null) : base(next, dataProtectionProvider, loggerFactory, externalOptions, options, configureOptions) { if (string.IsNullOrWhiteSpace(Options.AppId)) diff --git a/src/Microsoft.AspNet.Security.Google/GoogleAuthenticationExtensions.cs b/src/Microsoft.AspNet.Security.Google/GoogleAuthenticationExtensions.cs index 7bb4a24e2..474df5e32 100644 --- a/src/Microsoft.AspNet.Security.Google/GoogleAuthenticationExtensions.cs +++ b/src/Microsoft.AspNet.Security.Google/GoogleAuthenticationExtensions.cs @@ -15,7 +15,7 @@ public static class GoogleAuthenticationExtensions { public static IServiceCollection ConfigureGoogleAuthentication([NotNull] this IServiceCollection services, [NotNull] Action configure) { - return services.ConfigureOptions(configure); + return services.Configure(configure); } /// @@ -28,7 +28,7 @@ public static IServiceCollection ConfigureGoogleAuthentication([NotNull] this IS public static IApplicationBuilder UseGoogleAuthentication([NotNull] this IApplicationBuilder app, Action configureOptions = null, string optionsName = "") { return app.UseMiddleware( - new OptionsAction(configureOptions ?? (o => { })) + new ConfigureOptions(configureOptions ?? (o => { })) { Name = optionsName }); diff --git a/src/Microsoft.AspNet.Security.Google/GoogleAuthenticationMiddleware.cs b/src/Microsoft.AspNet.Security.Google/GoogleAuthenticationMiddleware.cs index 66cef2e2a..51072c65c 100644 --- a/src/Microsoft.AspNet.Security.Google/GoogleAuthenticationMiddleware.cs +++ b/src/Microsoft.AspNet.Security.Google/GoogleAuthenticationMiddleware.cs @@ -32,9 +32,9 @@ public GoogleAuthenticationMiddleware( RequestDelegate next, IDataProtectionProvider dataProtectionProvider, ILoggerFactory loggerFactory, - IOptionsAccessor externalOptions, - IOptionsAccessor options, - IOptionsAction configureOptions = null) + IOptions externalOptions, + IOptions options, + ConfigureOptions configureOptions = null) : base(next, dataProtectionProvider, loggerFactory, externalOptions, options, configureOptions) { if (Options.Notifications == null) diff --git a/src/Microsoft.AspNet.Security.MicrosoftAccount/MicrosoftAccountAuthenticationExtensions.cs b/src/Microsoft.AspNet.Security.MicrosoftAccount/MicrosoftAccountAuthenticationExtensions.cs index 64ec369ab..912271da6 100644 --- a/src/Microsoft.AspNet.Security.MicrosoftAccount/MicrosoftAccountAuthenticationExtensions.cs +++ b/src/Microsoft.AspNet.Security.MicrosoftAccount/MicrosoftAccountAuthenticationExtensions.cs @@ -15,13 +15,13 @@ public static class MicrosoftAccountAuthenticationExtensions { public static IServiceCollection ConfigureMicrosoftAccountAuthentication([NotNull] this IServiceCollection services, [NotNull] Action configure) { - return services.ConfigureOptions(configure); + return services.Configure(configure); } public static IApplicationBuilder UseMicrosoftAccountAuthentication([NotNull] this IApplicationBuilder app, Action configureOptions = null, string optionsName = "") { return app.UseMiddleware( - new OptionsAction(configureOptions ?? (o => { })) + new ConfigureOptions(configureOptions ?? (o => { })) { Name = optionsName }); diff --git a/src/Microsoft.AspNet.Security.MicrosoftAccount/MicrosoftAccountAuthenticationMiddleware.cs b/src/Microsoft.AspNet.Security.MicrosoftAccount/MicrosoftAccountAuthenticationMiddleware.cs index c36ad16de..26c80bac4 100644 --- a/src/Microsoft.AspNet.Security.MicrosoftAccount/MicrosoftAccountAuthenticationMiddleware.cs +++ b/src/Microsoft.AspNet.Security.MicrosoftAccount/MicrosoftAccountAuthenticationMiddleware.cs @@ -28,9 +28,9 @@ public MicrosoftAccountAuthenticationMiddleware( RequestDelegate next, IDataProtectionProvider dataProtectionProvider, ILoggerFactory loggerFactory, - IOptionsAccessor externalOptions, - IOptionsAccessor options, - IOptionsAction configureOptions = null) + IOptions externalOptions, + IOptions options, + ConfigureOptions configureOptions = null) : base(next, dataProtectionProvider, loggerFactory, externalOptions, options, configureOptions) { if (Options.Notifications == null) diff --git a/src/Microsoft.AspNet.Security.OAuth/OAuthAuthenticationExtensions.cs b/src/Microsoft.AspNet.Security.OAuth/OAuthAuthenticationExtensions.cs index bdbc3c9ee..55ac54ca6 100644 --- a/src/Microsoft.AspNet.Security.OAuth/OAuthAuthenticationExtensions.cs +++ b/src/Microsoft.AspNet.Security.OAuth/OAuthAuthenticationExtensions.cs @@ -23,7 +23,7 @@ public static class OAuthAuthenticationExtensions public static IApplicationBuilder UseOAuthAuthentication([NotNull] this IApplicationBuilder app, [NotNull] string authenticationType, Action> configureOptions = null) { return app.UseMiddleware, IOAuthAuthenticationNotifications>>( - new OptionsAction>(options => + new ConfigureOptions>(options => { options.AuthenticationType = authenticationType; options.Caption = authenticationType; diff --git a/src/Microsoft.AspNet.Security.OAuth/OAuthAuthenticationMiddleware.cs b/src/Microsoft.AspNet.Security.OAuth/OAuthAuthenticationMiddleware.cs index e3d65c55b..23160b053 100644 --- a/src/Microsoft.AspNet.Security.OAuth/OAuthAuthenticationMiddleware.cs +++ b/src/Microsoft.AspNet.Security.OAuth/OAuthAuthenticationMiddleware.cs @@ -33,9 +33,9 @@ public OAuthAuthenticationMiddleware( RequestDelegate next, IDataProtectionProvider dataProtectionProvider, ILoggerFactory loggerFactory, - IOptionsAccessor externalOptions, - IOptionsAccessor options, - IOptionsAction configureOptions = null) + IOptions externalOptions, + IOptions options, + ConfigureOptions configureOptions = null) : base(next, options, configureOptions) { // todo: review error handling diff --git a/src/Microsoft.AspNet.Security.OAuth/OAuthBearerAuthenticationExtensions.cs b/src/Microsoft.AspNet.Security.OAuth/OAuthBearerAuthenticationExtensions.cs index 118598120..b5512d01c 100644 --- a/src/Microsoft.AspNet.Security.OAuth/OAuthBearerAuthenticationExtensions.cs +++ b/src/Microsoft.AspNet.Security.OAuth/OAuthBearerAuthenticationExtensions.cs @@ -32,7 +32,7 @@ public static IServiceCollection ConfigureOAuthBearerAuthentication([NotNull] th public static IApplicationBuilder UseOAuthBearerAuthentication([NotNull] this IApplicationBuilder app, Action configureOptions = null, string optionsName = "") { return app.UseMiddleware( - new OptionsAction(configureOptions ?? (o => { })) + new ConfigureOptions(configureOptions ?? (o => { })) { Name = optionsName }); diff --git a/src/Microsoft.AspNet.Security.OAuth/OAuthBearerAuthenticationMiddleware.cs b/src/Microsoft.AspNet.Security.OAuth/OAuthBearerAuthenticationMiddleware.cs index 715d43b13..8993e107c 100644 --- a/src/Microsoft.AspNet.Security.OAuth/OAuthBearerAuthenticationMiddleware.cs +++ b/src/Microsoft.AspNet.Security.OAuth/OAuthBearerAuthenticationMiddleware.cs @@ -30,8 +30,8 @@ public OAuthBearerAuthenticationMiddleware( RequestDelegate next, IDataProtectionProvider dataProtectionProvider, ILoggerFactory loggerFactory, - IOptionsAccessor options, - IOptionsAction configureOptions) + IOptions options, + ConfigureOptions configureOptions) : base(next, options, configureOptions) { _logger = loggerFactory.Create(); diff --git a/src/Microsoft.AspNet.Security.Twitter/TwitterAuthenticationExtensions.cs b/src/Microsoft.AspNet.Security.Twitter/TwitterAuthenticationExtensions.cs index 9f2c54ce1..5e97d8224 100644 --- a/src/Microsoft.AspNet.Security.Twitter/TwitterAuthenticationExtensions.cs +++ b/src/Microsoft.AspNet.Security.Twitter/TwitterAuthenticationExtensions.cs @@ -16,13 +16,13 @@ public static class TwitterAuthenticationExtensions { public static IServiceCollection ConfigureTwitterAuthentication([NotNull] this IServiceCollection services, [NotNull] Action configure) { - return services.ConfigureOptions(configure); + return services.Configure(configure); } public static IApplicationBuilder UseTwitterAuthentication([NotNull] this IApplicationBuilder app, Action configureOptions = null, string optionsName = "") { return app.UseMiddleware( - new OptionsAction(configureOptions ?? (o => { })) + new ConfigureOptions(configureOptions ?? (o => { })) { Name = optionsName }); diff --git a/src/Microsoft.AspNet.Security.Twitter/TwitterAuthenticationMiddleware.cs b/src/Microsoft.AspNet.Security.Twitter/TwitterAuthenticationMiddleware.cs index ffa9b9bb6..7ca77a9c1 100644 --- a/src/Microsoft.AspNet.Security.Twitter/TwitterAuthenticationMiddleware.cs +++ b/src/Microsoft.AspNet.Security.Twitter/TwitterAuthenticationMiddleware.cs @@ -36,9 +36,9 @@ public TwitterAuthenticationMiddleware( RequestDelegate next, IDataProtectionProvider dataProtectionProvider, ILoggerFactory loggerFactory, - IOptionsAccessor externalOptions, - IOptionsAccessor options, - IOptionsAction configureOptions = null) + IOptions externalOptions, + IOptions options, + ConfigureOptions configureOptions = null) : base(next, options, configureOptions) { if (string.IsNullOrWhiteSpace(Options.ConsumerSecret)) diff --git a/src/Microsoft.AspNet.Security/Infrastructure/AuthenticationMiddleware.cs b/src/Microsoft.AspNet.Security/Infrastructure/AuthenticationMiddleware.cs index 1ea787fce..86c2fb921 100644 --- a/src/Microsoft.AspNet.Security/Infrastructure/AuthenticationMiddleware.cs +++ b/src/Microsoft.AspNet.Security/Infrastructure/AuthenticationMiddleware.cs @@ -14,12 +14,12 @@ namespace Microsoft.AspNet.Security.Infrastructure { private readonly RequestDelegate _next; - protected AuthenticationMiddleware([NotNull] RequestDelegate next, [NotNull] IOptionsAccessor options, IOptionsAction configureOptions) + protected AuthenticationMiddleware([NotNull] RequestDelegate next, [NotNull] IOptions options, ConfigureOptions configureOptions) { if (configureOptions != null) { Options = options.GetNamedOptions(configureOptions.Name); - configureOptions.Invoke(Options); + configureOptions.Configure(Options, configureOptions.Name); } else { diff --git a/test/Microsoft.AspNet.Security.Test/Cookies/CookieMiddlewareTests.cs b/test/Microsoft.AspNet.Security.Test/Cookies/CookieMiddlewareTests.cs index 63b2c0f72..a02dc1475 100644 --- a/test/Microsoft.AspNet.Security.Test/Cookies/CookieMiddlewareTests.cs +++ b/test/Microsoft.AspNet.Security.Test/Cookies/CookieMiddlewareTests.cs @@ -369,7 +369,7 @@ private static TestServer CreateServer(Action confi { return TestServer.Create(app => { - app.UsePerRequestServices(services => { }); + app.UseServices(services => { }); app.UseCookieAuthentication(configureOptions); app.Use(async (context, next) => { diff --git a/test/Microsoft.AspNet.Security.Test/Facebook/FacebookMiddlewareTests.cs b/test/Microsoft.AspNet.Security.Test/Facebook/FacebookMiddlewareTests.cs index 5e78bccda..f3e0bf703 100644 --- a/test/Microsoft.AspNet.Security.Test/Facebook/FacebookMiddlewareTests.cs +++ b/test/Microsoft.AspNet.Security.Test/Facebook/FacebookMiddlewareTests.cs @@ -27,7 +27,7 @@ public async Task ChallengeWillTriggerApplyRedirectEvent() var server = CreateServer( app => { - app.UsePerRequestServices(services => + app.UseServices(services => { services.ConfigureFacebookAuthentication(options => { @@ -45,7 +45,7 @@ public async Task ChallengeWillTriggerApplyRedirectEvent() { options.AuthenticationType = "External"; }); - services.ConfigureOptions(options => + services.Configure(options => { options.SignInAsAuthenticationType = "External"; }); @@ -70,7 +70,7 @@ public async Task ChallengeWillTriggerRedirection() var server = CreateServer( app => { - app.UsePerRequestServices(services => + app.UseServices(services => { services.ConfigureFacebookAuthentication(options => { @@ -81,7 +81,7 @@ public async Task ChallengeWillTriggerRedirection() { options.AuthenticationType = "External"; }); - services.ConfigureOptions(options => + services.Configure(options => { options.SignInAsAuthenticationType = "External"; }); diff --git a/test/Microsoft.AspNet.Security.Test/Google/GoogleMiddlewareTests.cs b/test/Microsoft.AspNet.Security.Test/Google/GoogleMiddlewareTests.cs index 564935496..3a1113d7f 100644 --- a/test/Microsoft.AspNet.Security.Test/Google/GoogleMiddlewareTests.cs +++ b/test/Microsoft.AspNet.Security.Test/Google/GoogleMiddlewareTests.cs @@ -465,9 +465,9 @@ private static TestServer CreateServer(Action confi { return TestServer.Create(app => { - app.UsePerRequestServices(services => + app.UseServices(services => { - services.ConfigureOptions(options => + services.Configure(options => { options.SignInAsAuthenticationType = CookieAuthenticationType; }); diff --git a/test/Microsoft.AspNet.Security.Test/MicrosoftAccount/MicrosoftAccountMiddlewareTests.cs b/test/Microsoft.AspNet.Security.Test/MicrosoftAccount/MicrosoftAccountMiddlewareTests.cs index c42ec1851..d055df748 100644 --- a/test/Microsoft.AspNet.Security.Test/MicrosoftAccount/MicrosoftAccountMiddlewareTests.cs +++ b/test/Microsoft.AspNet.Security.Test/MicrosoftAccount/MicrosoftAccountMiddlewareTests.cs @@ -163,9 +163,9 @@ private static TestServer CreateServer(Action { - app.UsePerRequestServices(services => + app.UseServices(services => { - services.ConfigureOptions(options => + services.Configure(options => { options.SignInAsAuthenticationType = "External"; }); diff --git a/test/Microsoft.AspNet.Security.Test/Twitter/TwitterMiddlewareTests.cs b/test/Microsoft.AspNet.Security.Test/Twitter/TwitterMiddlewareTests.cs index e9b54e4bc..5505f9754 100644 --- a/test/Microsoft.AspNet.Security.Test/Twitter/TwitterMiddlewareTests.cs +++ b/test/Microsoft.AspNet.Security.Test/Twitter/TwitterMiddlewareTests.cs @@ -109,9 +109,9 @@ private static TestServer CreateServer(Action configure, Fu { return TestServer.Create(app => { - app.UsePerRequestServices(services => + app.UseServices(services => { - services.ConfigureOptions(options => + services.Configure(options => { options.SignInAsAuthenticationType = "External"; }); From 45836c8041129b116d8761727808d9b45e79c835 Mon Sep 17 00:00:00 2001 From: Chris Ross Date: Wed, 15 Oct 2014 15:56:08 -0700 Subject: [PATCH 073/216] Update UseMiddleware dependencies. --- samples/CookieSessionSample/Startup.cs | 2 +- samples/CookieSessionSample/project.json | 21 +++++++++---------- samples/SocialSample/Startup.cs | 2 +- .../project.json | 2 +- .../project.json | 2 +- .../project.json | 2 +- .../project.json | 2 +- .../project.json | 2 +- .../project.json | 2 +- .../project.json | 1 + 10 files changed, 19 insertions(+), 19 deletions(-) diff --git a/samples/CookieSessionSample/Startup.cs b/samples/CookieSessionSample/Startup.cs index a4217e6d2..e03c034f3 100644 --- a/samples/CookieSessionSample/Startup.cs +++ b/samples/CookieSessionSample/Startup.cs @@ -10,7 +10,7 @@ public class Startup { public void Configure(IApplicationBuilder app) { - app.UseServices(services => { }); + app.UseRequestServices(); app.UseCookieAuthentication(options => { options.SessionStore = new MemoryCacheSessionStore(); diff --git a/samples/CookieSessionSample/project.json b/samples/CookieSessionSample/project.json index 9e28721e3..ebfb92a06 100644 --- a/samples/CookieSessionSample/project.json +++ b/samples/CookieSessionSample/project.json @@ -1,15 +1,14 @@ { - "dependencies": { - "Microsoft.AspNet.Security.Cookies": "1.0.0-*", - "Microsoft.AspNet.Server.WebListener": "1.0.0-*", - "Microsoft.Framework.Cache.Memory": "1.0.0-*", - "Microsoft.Framework.DependencyInjection": "1.0.0-*" - }, - "commands": { "web": "Microsoft.AspNet.Hosting server=Microsoft.AspNet.Server.WebListener server.urls=http://localhost:12345" }, - "frameworks": { - "aspnet50": { + "dependencies": { + "Microsoft.AspNet.RequestContainer": "1.0.0-*", + "Microsoft.AspNet.Security.Cookies": "1.0.0-*", + "Microsoft.AspNet.Server.WebListener": "1.0.0-*", + "Microsoft.Framework.Cache.Memory": "1.0.0-*", + "Microsoft.Framework.DependencyInjection": "1.0.0-*" }, - "aspnetcore50": { + "commands": { "web": "Microsoft.AspNet.Hosting server=Microsoft.AspNet.Server.WebListener server.urls=http://localhost:12345" }, + "frameworks": { + "aspnet50": { }, + "aspnetcore50": { } } - } } diff --git a/samples/SocialSample/Startup.cs b/samples/SocialSample/Startup.cs index 18f17ac0f..3ddba6fb4 100644 --- a/samples/SocialSample/Startup.cs +++ b/samples/SocialSample/Startup.cs @@ -26,7 +26,7 @@ public void Configure(IApplicationBuilder app) app.UseServices(services => { - services.ConfigureOptions(options => + services.Configure(options => { options.SignInAsAuthenticationType = CookieAuthenticationDefaults.AuthenticationType; }); diff --git a/src/Microsoft.AspNet.Security.Cookies/project.json b/src/Microsoft.AspNet.Security.Cookies/project.json index c9e89b1c4..8c824d876 100644 --- a/src/Microsoft.AspNet.Security.Cookies/project.json +++ b/src/Microsoft.AspNet.Security.Cookies/project.json @@ -1,7 +1,7 @@ { "version": "1.0.0-*", "dependencies": { - "Microsoft.AspNet.RequestContainer": "1.0.0-*", + "Microsoft.AspNet.Http.Extensions": "1.0.0-*", "Microsoft.AspNet.Security": "1.0.0-*", "Microsoft.AspNet.Security.DataProtection": "1.0.0-*", "Microsoft.Framework.DependencyInjection": "1.0.0-*", diff --git a/src/Microsoft.AspNet.Security.Facebook/project.json b/src/Microsoft.AspNet.Security.Facebook/project.json index a4442582a..22e59b7f4 100644 --- a/src/Microsoft.AspNet.Security.Facebook/project.json +++ b/src/Microsoft.AspNet.Security.Facebook/project.json @@ -1,7 +1,7 @@ { "version": "1.0.0-*", "dependencies": { - "Microsoft.AspNet.RequestContainer": "1.0.0-*", + "Microsoft.AspNet.Http.Extensions": "1.0.0-*", "Microsoft.AspNet.Security": "1.0.0-*", "Microsoft.AspNet.Security.DataProtection": "1.0.0-*", "Microsoft.AspNet.Security.OAuth": "1.0.0-*", diff --git a/src/Microsoft.AspNet.Security.Google/project.json b/src/Microsoft.AspNet.Security.Google/project.json index b50bcd27c..b8e38ecf3 100644 --- a/src/Microsoft.AspNet.Security.Google/project.json +++ b/src/Microsoft.AspNet.Security.Google/project.json @@ -1,7 +1,7 @@ { "version": "1.0.0-*", "dependencies": { - "Microsoft.AspNet.RequestContainer": "1.0.0-*", + "Microsoft.AspNet.Http.Extensions": "1.0.0-*", "Microsoft.AspNet.Security": "1.0.0-*", "Microsoft.AspNet.Security.DataProtection": "1.0.0-*", "Microsoft.AspNet.Security.OAuth": "1.0.0-*", diff --git a/src/Microsoft.AspNet.Security.MicrosoftAccount/project.json b/src/Microsoft.AspNet.Security.MicrosoftAccount/project.json index f85c94de7..9e5091b73 100644 --- a/src/Microsoft.AspNet.Security.MicrosoftAccount/project.json +++ b/src/Microsoft.AspNet.Security.MicrosoftAccount/project.json @@ -1,7 +1,7 @@ { "version": "1.0.0-*", "dependencies": { - "Microsoft.AspNet.RequestContainer": "1.0.0-*", + "Microsoft.AspNet.Http.Extensions": "1.0.0-*", "Microsoft.AspNet.Security": "1.0.0-*", "Microsoft.AspNet.Security.DataProtection": "1.0.0-*", "Microsoft.AspNet.Security.OAuth": "1.0.0-*", diff --git a/src/Microsoft.AspNet.Security.OAuth/project.json b/src/Microsoft.AspNet.Security.OAuth/project.json index 7cf7c0fc8..288c92536 100644 --- a/src/Microsoft.AspNet.Security.OAuth/project.json +++ b/src/Microsoft.AspNet.Security.OAuth/project.json @@ -1,7 +1,7 @@ { "version": "1.0.0-*", "dependencies": { - "Microsoft.AspNet.RequestContainer": "1.0.0-*", + "Microsoft.AspNet.Http.Extensions": "1.0.0-*", "Microsoft.AspNet.Security": "1.0.0-*", "Microsoft.AspNet.Security.DataProtection": "1.0.0-*", "Microsoft.AspNet.WebUtilities": "1.0.0-*", diff --git a/src/Microsoft.AspNet.Security.Twitter/project.json b/src/Microsoft.AspNet.Security.Twitter/project.json index f48ebe5ab..7caac86cf 100644 --- a/src/Microsoft.AspNet.Security.Twitter/project.json +++ b/src/Microsoft.AspNet.Security.Twitter/project.json @@ -1,7 +1,7 @@ { "version": "1.0.0-*", "dependencies": { - "Microsoft.AspNet.RequestContainer": "1.0.0-*", + "Microsoft.AspNet.Http.Extensions": "1.0.0-*", "Microsoft.AspNet.Security": "1.0.0-*", "Microsoft.AspNet.Security.DataProtection": "1.0.0-*", "Microsoft.AspNet.WebUtilities": "1.0.0-*", diff --git a/test/Microsoft.AspNet.Security.Test/project.json b/test/Microsoft.AspNet.Security.Test/project.json index bcff7a978..886baff98 100644 --- a/test/Microsoft.AspNet.Security.Test/project.json +++ b/test/Microsoft.AspNet.Security.Test/project.json @@ -4,6 +4,7 @@ }, "dependencies": { "Microsoft.AspNet.Http": "1.0.0-*", + "Microsoft.AspNet.RequestContainer": "1.0.0-*", "Microsoft.AspNet.Security": "1.0.0-*", "Microsoft.AspNet.Security.Cookies": "1.0.0-*", "Microsoft.AspNet.Security.Facebook": "1.0.0-*", From 78f472fd205599850119dfbd70f46b7334c06936 Mon Sep 17 00:00:00 2001 From: Hao Kung Date: Wed, 15 Oct 2014 23:42:45 -0700 Subject: [PATCH 074/216] Switch to automatically ensure request services --- samples/CookieSample/Startup.cs | 1 - samples/CookieSessionSample/Startup.cs | 1 - .../CookieAuthenticationMiddleware.cs | 3 ++- .../FacebookAuthenticationMiddleware.cs | 3 ++- .../GoogleAuthenticationMiddleware.cs | 4 +++- ...icrosoftAccountAuthenticationMiddleware.cs | 4 +++- .../OAuthAuthenticationMiddleware.cs | 4 +++- .../OAuthBearerAuthenticationMiddleware.cs | 4 +++- .../TwitterAuthenticationMiddleware.cs | 4 +++- .../AuthenticationMiddleware.cs | 20 ++++++++++++------- src/Microsoft.AspNet.Security/project.json | 1 + .../Cookies/CookieMiddlewareTests.cs | 1 - 12 files changed, 33 insertions(+), 17 deletions(-) diff --git a/samples/CookieSample/Startup.cs b/samples/CookieSample/Startup.cs index fc78aec37..cff673d75 100644 --- a/samples/CookieSample/Startup.cs +++ b/samples/CookieSample/Startup.cs @@ -9,7 +9,6 @@ public class Startup { public void Configure(IApplicationBuilder app) { - app.UseServices(services => { }); app.UseCookieAuthentication(options => { }); diff --git a/samples/CookieSessionSample/Startup.cs b/samples/CookieSessionSample/Startup.cs index e03c034f3..2b6cfd846 100644 --- a/samples/CookieSessionSample/Startup.cs +++ b/samples/CookieSessionSample/Startup.cs @@ -10,7 +10,6 @@ public class Startup { public void Configure(IApplicationBuilder app) { - app.UseRequestServices(); app.UseCookieAuthentication(options => { options.SessionStore = new MemoryCacheSessionStore(); diff --git a/src/Microsoft.AspNet.Security.Cookies/CookieAuthenticationMiddleware.cs b/src/Microsoft.AspNet.Security.Cookies/CookieAuthenticationMiddleware.cs index 087820e29..fdbd3cc08 100644 --- a/src/Microsoft.AspNet.Security.Cookies/CookieAuthenticationMiddleware.cs +++ b/src/Microsoft.AspNet.Security.Cookies/CookieAuthenticationMiddleware.cs @@ -18,11 +18,12 @@ public class CookieAuthenticationMiddleware : AuthenticationMiddleware options, ConfigureOptions configureOptions) - : base(next, options, configureOptions) + : base(next, services, options, configureOptions) { if (Options.Notifications == null) { diff --git a/src/Microsoft.AspNet.Security.Facebook/FacebookAuthenticationMiddleware.cs b/src/Microsoft.AspNet.Security.Facebook/FacebookAuthenticationMiddleware.cs index b7891d139..5f6eb525e 100644 --- a/src/Microsoft.AspNet.Security.Facebook/FacebookAuthenticationMiddleware.cs +++ b/src/Microsoft.AspNet.Security.Facebook/FacebookAuthenticationMiddleware.cs @@ -26,12 +26,13 @@ public class FacebookAuthenticationMiddleware : OAuthAuthenticationMiddlewareConfiguration options for the middleware. public FacebookAuthenticationMiddleware( RequestDelegate next, + IServiceProvider services, IDataProtectionProvider dataProtectionProvider, ILoggerFactory loggerFactory, IOptions externalOptions, IOptions options, ConfigureOptions configureOptions = null) - : base(next, dataProtectionProvider, loggerFactory, externalOptions, options, configureOptions) + : base(next, services, dataProtectionProvider, loggerFactory, externalOptions, options, configureOptions) { if (string.IsNullOrWhiteSpace(Options.AppId)) { diff --git a/src/Microsoft.AspNet.Security.Google/GoogleAuthenticationMiddleware.cs b/src/Microsoft.AspNet.Security.Google/GoogleAuthenticationMiddleware.cs index 51072c65c..7de253070 100644 --- a/src/Microsoft.AspNet.Security.Google/GoogleAuthenticationMiddleware.cs +++ b/src/Microsoft.AspNet.Security.Google/GoogleAuthenticationMiddleware.cs @@ -25,17 +25,19 @@ public class GoogleAuthenticationMiddleware : OAuthAuthenticationMiddleware. /// /// The next middleware in the HTTP pipeline to invoke. + /// /// /// /// Configuration options for the middleware. public GoogleAuthenticationMiddleware( RequestDelegate next, + IServiceProvider services, IDataProtectionProvider dataProtectionProvider, ILoggerFactory loggerFactory, IOptions externalOptions, IOptions options, ConfigureOptions configureOptions = null) - : base(next, dataProtectionProvider, loggerFactory, externalOptions, options, configureOptions) + : base(next, services, dataProtectionProvider, loggerFactory, externalOptions, options, configureOptions) { if (Options.Notifications == null) { diff --git a/src/Microsoft.AspNet.Security.MicrosoftAccount/MicrosoftAccountAuthenticationMiddleware.cs b/src/Microsoft.AspNet.Security.MicrosoftAccount/MicrosoftAccountAuthenticationMiddleware.cs index 26c80bac4..ce50b7033 100644 --- a/src/Microsoft.AspNet.Security.MicrosoftAccount/MicrosoftAccountAuthenticationMiddleware.cs +++ b/src/Microsoft.AspNet.Security.MicrosoftAccount/MicrosoftAccountAuthenticationMiddleware.cs @@ -21,17 +21,19 @@ public class MicrosoftAccountAuthenticationMiddleware : OAuthAuthenticationMiddl /// Initializes a new . /// /// The next middleware in the HTTP pipeline to invoke. + /// /// /// /// Configuration options for the middleware. public MicrosoftAccountAuthenticationMiddleware( RequestDelegate next, + IServiceProvider services, IDataProtectionProvider dataProtectionProvider, ILoggerFactory loggerFactory, IOptions externalOptions, IOptions options, ConfigureOptions configureOptions = null) - : base(next, dataProtectionProvider, loggerFactory, externalOptions, options, configureOptions) + : base(next, services, dataProtectionProvider, loggerFactory, externalOptions, options, configureOptions) { if (Options.Notifications == null) { diff --git a/src/Microsoft.AspNet.Security.OAuth/OAuthAuthenticationMiddleware.cs b/src/Microsoft.AspNet.Security.OAuth/OAuthAuthenticationMiddleware.cs index 23160b053..1f9eace70 100644 --- a/src/Microsoft.AspNet.Security.OAuth/OAuthAuthenticationMiddleware.cs +++ b/src/Microsoft.AspNet.Security.OAuth/OAuthAuthenticationMiddleware.cs @@ -26,17 +26,19 @@ public class OAuthAuthenticationMiddleware : Authentic /// Initializes a new . /// /// The next middleware in the HTTP pipeline to invoke. + /// /// /// /// Configuration options for the middleware. public OAuthAuthenticationMiddleware( RequestDelegate next, + IServiceProvider services, IDataProtectionProvider dataProtectionProvider, ILoggerFactory loggerFactory, IOptions externalOptions, IOptions options, ConfigureOptions configureOptions = null) - : base(next, options, configureOptions) + : base(next, services, options, configureOptions) { // todo: review error handling if (string.IsNullOrWhiteSpace(Options.AuthenticationType)) diff --git a/src/Microsoft.AspNet.Security.OAuth/OAuthBearerAuthenticationMiddleware.cs b/src/Microsoft.AspNet.Security.OAuth/OAuthBearerAuthenticationMiddleware.cs index 8993e107c..eaa862a28 100644 --- a/src/Microsoft.AspNet.Security.OAuth/OAuthBearerAuthenticationMiddleware.cs +++ b/src/Microsoft.AspNet.Security.OAuth/OAuthBearerAuthenticationMiddleware.cs @@ -7,6 +7,7 @@ using Microsoft.AspNet.Security.Infrastructure; using Microsoft.Framework.Logging; using Microsoft.Framework.OptionsModel; +using System; namespace Microsoft.AspNet.Security.OAuth { @@ -28,11 +29,12 @@ public class OAuthBearerAuthenticationMiddleware : AuthenticationMiddleware public OAuthBearerAuthenticationMiddleware( RequestDelegate next, + IServiceProvider services, IDataProtectionProvider dataProtectionProvider, ILoggerFactory loggerFactory, IOptions options, ConfigureOptions configureOptions) - : base(next, options, configureOptions) + : base(next, services, options, configureOptions) { _logger = loggerFactory.Create(); diff --git a/src/Microsoft.AspNet.Security.Twitter/TwitterAuthenticationMiddleware.cs b/src/Microsoft.AspNet.Security.Twitter/TwitterAuthenticationMiddleware.cs index 7ca77a9c1..e3a56efab 100644 --- a/src/Microsoft.AspNet.Security.Twitter/TwitterAuthenticationMiddleware.cs +++ b/src/Microsoft.AspNet.Security.Twitter/TwitterAuthenticationMiddleware.cs @@ -29,17 +29,19 @@ public class TwitterAuthenticationMiddleware : AuthenticationMiddleware /// /// The next middleware in the HTTP pipeline to invoke + /// /// /// /// Configuration options for the middleware public TwitterAuthenticationMiddleware( RequestDelegate next, + IServiceProvider services, IDataProtectionProvider dataProtectionProvider, ILoggerFactory loggerFactory, IOptions externalOptions, IOptions options, ConfigureOptions configureOptions = null) - : base(next, options, configureOptions) + : base(next, services, options, configureOptions) { if (string.IsNullOrWhiteSpace(Options.ConsumerSecret)) { diff --git a/src/Microsoft.AspNet.Security/Infrastructure/AuthenticationMiddleware.cs b/src/Microsoft.AspNet.Security/Infrastructure/AuthenticationMiddleware.cs index 86c2fb921..b7fb77fe8 100644 --- a/src/Microsoft.AspNet.Security/Infrastructure/AuthenticationMiddleware.cs +++ b/src/Microsoft.AspNet.Security/Infrastructure/AuthenticationMiddleware.cs @@ -6,6 +6,7 @@ using System.Threading.Tasks; using Microsoft.AspNet.Builder; using Microsoft.AspNet.Http; +using Microsoft.AspNet.RequestContainer; using Microsoft.Framework.OptionsModel; namespace Microsoft.AspNet.Security.Infrastructure @@ -13,8 +14,9 @@ namespace Microsoft.AspNet.Security.Infrastructure public abstract class AuthenticationMiddleware where TOptions : AuthenticationOptions, new() { private readonly RequestDelegate _next; + private readonly IServiceProvider _services; - protected AuthenticationMiddleware([NotNull] RequestDelegate next, [NotNull] IOptions options, ConfigureOptions configureOptions) + protected AuthenticationMiddleware([NotNull] RequestDelegate next, [NotNull] IServiceProvider services, [NotNull] IOptions options, ConfigureOptions configureOptions) { if (configureOptions != null) { @@ -26,6 +28,7 @@ protected AuthenticationMiddleware([NotNull] RequestDelegate next, [NotNull] IOp Options = options.Options; } _next = next; + _services = services; } public string AuthenticationType { get; set; } @@ -34,15 +37,18 @@ protected AuthenticationMiddleware([NotNull] RequestDelegate next, [NotNull] IOp public async Task Invoke(HttpContext context) { - AuthenticationHandler handler = CreateHandler(); - await handler.Initialize(Options, context); - if (!await handler.InvokeAsync()) + using (RequestServicesContainer.EnsureRequestServices(context, _services)) { - await _next(context); + AuthenticationHandler handler = CreateHandler(); + await handler.Initialize(Options, context); + if (!await handler.InvokeAsync()) + { + await _next(context); + } + await handler.TeardownAsync(); } - await handler.TeardownAsync(); } protected abstract AuthenticationHandler CreateHandler(); } -} +} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Security/project.json b/src/Microsoft.AspNet.Security/project.json index 176c631f7..160e03b51 100644 --- a/src/Microsoft.AspNet.Security/project.json +++ b/src/Microsoft.AspNet.Security/project.json @@ -1,6 +1,7 @@ { "version": "1.0.0-*", "dependencies": { + "Microsoft.AspNet.RequestContainer": "1.0.0-*", "Microsoft.AspNet.HttpFeature": { "version": "1.0.0-*", "type": "build" }, "Microsoft.AspNet.PipelineCore": "1.0.0-*", "Microsoft.AspNet.Security.DataProtection": "1.0.0-*", diff --git a/test/Microsoft.AspNet.Security.Test/Cookies/CookieMiddlewareTests.cs b/test/Microsoft.AspNet.Security.Test/Cookies/CookieMiddlewareTests.cs index a02dc1475..fc101faaa 100644 --- a/test/Microsoft.AspNet.Security.Test/Cookies/CookieMiddlewareTests.cs +++ b/test/Microsoft.AspNet.Security.Test/Cookies/CookieMiddlewareTests.cs @@ -369,7 +369,6 @@ private static TestServer CreateServer(Action confi { return TestServer.Create(app => { - app.UseServices(services => { }); app.UseCookieAuthentication(configureOptions); app.Use(async (context, next) => { From 89ade800c48834e9feef876709fcf1fc29f12838 Mon Sep 17 00:00:00 2001 From: Chris Ross Date: Fri, 17 Oct 2014 09:49:04 -0700 Subject: [PATCH 075/216] Update Claims dependency. --- src/Microsoft.AspNet.Security.Cookies/project.json | 2 +- src/Microsoft.AspNet.Security.Facebook/project.json | 2 +- src/Microsoft.AspNet.Security.Google/project.json | 2 +- src/Microsoft.AspNet.Security.MicrosoftAccount/project.json | 2 +- src/Microsoft.AspNet.Security.OAuth/project.json | 2 +- src/Microsoft.AspNet.Security.Twitter/project.json | 2 +- src/Microsoft.AspNet.Security/project.json | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/Microsoft.AspNet.Security.Cookies/project.json b/src/Microsoft.AspNet.Security.Cookies/project.json index 8c824d876..a3fca6701 100644 --- a/src/Microsoft.AspNet.Security.Cookies/project.json +++ b/src/Microsoft.AspNet.Security.Cookies/project.json @@ -26,7 +26,7 @@ "System.Runtime": "4.0.20-beta-*", "System.Runtime.Extensions": "4.0.10-beta-*", "System.Runtime.InteropServices": "4.0.20-beta-*", - "System.Security.Claims": "1.0.0-*", + "System.Security.Claims": "4.0.0-beta-*", "System.Security.Principal" : "4.0.0-beta-*", "System.Threading": "4.0.0-beta-*", "System.Threading.Tasks": "4.0.10-beta-*" diff --git a/src/Microsoft.AspNet.Security.Facebook/project.json b/src/Microsoft.AspNet.Security.Facebook/project.json index 22e59b7f4..4f74026f6 100644 --- a/src/Microsoft.AspNet.Security.Facebook/project.json +++ b/src/Microsoft.AspNet.Security.Facebook/project.json @@ -32,7 +32,7 @@ "System.Runtime": "4.0.20-beta-*", "System.Runtime.Extensions": "4.0.10-beta-*", "System.Runtime.InteropServices": "4.0.20-beta-*", - "System.Security.Claims": "1.0.0-*", + "System.Security.Claims": "4.0.0-beta-*", "System.Security.Cryptography.Hashing.Algorithms": "4.0.0-beta-*", "System.Security.Principal": "4.0.0-beta-*", "System.Threading": "4.0.0-beta-*", diff --git a/src/Microsoft.AspNet.Security.Google/project.json b/src/Microsoft.AspNet.Security.Google/project.json index b8e38ecf3..59ba01fb3 100644 --- a/src/Microsoft.AspNet.Security.Google/project.json +++ b/src/Microsoft.AspNet.Security.Google/project.json @@ -32,7 +32,7 @@ "System.Runtime": "4.0.20-beta-*", "System.Runtime.Extensions": "4.0.10-beta-*", "System.Runtime.InteropServices": "4.0.20-beta-*", - "System.Security.Claims": "1.0.0-*", + "System.Security.Claims": "4.0.0-beta-*", "System.Security.Cryptography.Hashing.Algorithms": "4.0.0-beta-*", "System.Security.Principal": "4.0.0-beta-*", "System.Threading": "4.0.0-beta-*", diff --git a/src/Microsoft.AspNet.Security.MicrosoftAccount/project.json b/src/Microsoft.AspNet.Security.MicrosoftAccount/project.json index 9e5091b73..7e97b89e0 100644 --- a/src/Microsoft.AspNet.Security.MicrosoftAccount/project.json +++ b/src/Microsoft.AspNet.Security.MicrosoftAccount/project.json @@ -34,7 +34,7 @@ "System.Runtime": "4.0.20-beta-*", "System.Runtime.Extensions": "4.0.10-beta-*", "System.Runtime.InteropServices": "4.0.20-beta-*", - "System.Security.Claims": "1.0.0-*", + "System.Security.Claims": "4.0.0-beta-*", "System.Security.Cryptography.Hashing.Algorithms": "4.0.0-beta-*", "System.Security.Principal": "4.0.0-beta-*", "System.Threading": "4.0.0-beta-*", diff --git a/src/Microsoft.AspNet.Security.OAuth/project.json b/src/Microsoft.AspNet.Security.OAuth/project.json index 288c92536..d83974977 100644 --- a/src/Microsoft.AspNet.Security.OAuth/project.json +++ b/src/Microsoft.AspNet.Security.OAuth/project.json @@ -34,7 +34,7 @@ "System.Runtime": "4.0.20-beta-*", "System.Runtime.Extensions": "4.0.10-beta-*", "System.Runtime.InteropServices": "4.0.20-beta-*", - "System.Security.Claims": "1.0.0-*", + "System.Security.Claims": "4.0.0-beta-*", "System.Security.Cryptography.Hashing.Algorithms": "4.0.0-beta-*", "System.Security.Principal": "4.0.0-beta-*", "System.Threading": "4.0.0-beta-*", diff --git a/src/Microsoft.AspNet.Security.Twitter/project.json b/src/Microsoft.AspNet.Security.Twitter/project.json index 7caac86cf..a487d802a 100644 --- a/src/Microsoft.AspNet.Security.Twitter/project.json +++ b/src/Microsoft.AspNet.Security.Twitter/project.json @@ -33,7 +33,7 @@ "System.Runtime": "4.0.20-beta-*", "System.Runtime.Extensions": "4.0.10-beta-*", "System.Runtime.InteropServices": "4.0.20-beta-*", - "System.Security.Claims": "1.0.0-*", + "System.Security.Claims": "4.0.0-beta-*", "System.Security.Cryptography.Hashing.Algorithms": "4.0.0-beta-*", "System.Security.Principal": "4.0.0-beta-*", "System.Threading": "4.0.0-beta-*", diff --git a/src/Microsoft.AspNet.Security/project.json b/src/Microsoft.AspNet.Security/project.json index 160e03b51..8d1f81def 100644 --- a/src/Microsoft.AspNet.Security/project.json +++ b/src/Microsoft.AspNet.Security/project.json @@ -27,7 +27,7 @@ "System.Runtime": "4.0.20-beta-*", "System.Runtime.Extensions": "4.0.10-beta-*", "System.Runtime.InteropServices": "4.0.20-beta-*", - "System.Security.Claims": "1.0.0-*", + "System.Security.Claims": "4.0.0-beta-*", "System.Security.Cryptography.RandomNumberGenerator": "4.0.0-beta-*", "System.Security.Principal": "4.0.0-beta-*", "System.Threading": "4.0.0-beta-*", From 2c64ebdbc234b6c08be3ad917e36d1e5f0a20b91 Mon Sep 17 00:00:00 2001 From: Pranav K Date: Tue, 21 Oct 2014 12:47:26 -0700 Subject: [PATCH 076/216] Updating build.sh to work on Mono --- build.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build.sh b/build.sh index 4323aefc4..c7873ef58 100644 --- a/build.sh +++ b/build.sh @@ -1,4 +1,4 @@ -#!/bin/sh +#!/bin/bash if test `uname` = Darwin; then cachedir=~/Library/Caches/KBuild @@ -28,7 +28,7 @@ if test ! -d packages/KoreBuild; then fi if ! type k > /dev/null 2>&1; then - source setup/kvm.sh + source packages/KoreBuild/build/kvm.sh fi if ! type k > /dev/null 2>&1; then From 95f19407fc0a3f4c49f8ad618d8a3452b3474ee4 Mon Sep 17 00:00:00 2001 From: Chris Ross Date: Tue, 21 Oct 2014 14:00:49 -0700 Subject: [PATCH 077/216] #74 - Clean up data protection provider helper. --- .../CookieSessionSample/MemoryCacheSessionStore.cs | 2 +- .../CookieAuthenticationMiddleware.cs | 2 +- .../OAuthAuthenticationMiddleware.cs | 2 +- .../OAuthBearerAuthenticationMiddleware.cs | 2 +- .../TwitterAuthenticationMiddleware.cs | 2 +- .../DataProtection/DataProtectionHelpers.cs | 12 +----------- 6 files changed, 6 insertions(+), 16 deletions(-) diff --git a/samples/CookieSessionSample/MemoryCacheSessionStore.cs b/samples/CookieSessionSample/MemoryCacheSessionStore.cs index e452683d4..9877ded68 100644 --- a/samples/CookieSessionSample/MemoryCacheSessionStore.cs +++ b/samples/CookieSessionSample/MemoryCacheSessionStore.cs @@ -13,7 +13,7 @@ public class MemoryCacheSessionStore : IAuthenticationSessionStore public MemoryCacheSessionStore() { - _cache = new MemoryCache(); + _cache = new MemoryCache(new MemoryCacheOptions()); } public async Task StoreAsync(AuthenticationTicket ticket) diff --git a/src/Microsoft.AspNet.Security.Cookies/CookieAuthenticationMiddleware.cs b/src/Microsoft.AspNet.Security.Cookies/CookieAuthenticationMiddleware.cs index fdbd3cc08..482f43b37 100644 --- a/src/Microsoft.AspNet.Security.Cookies/CookieAuthenticationMiddleware.cs +++ b/src/Microsoft.AspNet.Security.Cookies/CookieAuthenticationMiddleware.cs @@ -35,7 +35,7 @@ public CookieAuthenticationMiddleware(RequestDelegate next, } if (Options.TicketDataFormat == null) { - IDataProtector dataProtector = DataProtectionHelpers.CreateDataProtector(dataProtectionProvider, + IDataProtector dataProtector = dataProtectionProvider.CreateDataProtector( typeof(CookieAuthenticationMiddleware).FullName, Options.AuthenticationType, "v1"); Options.TicketDataFormat = new TicketDataFormat(dataProtector); } diff --git a/src/Microsoft.AspNet.Security.OAuth/OAuthAuthenticationMiddleware.cs b/src/Microsoft.AspNet.Security.OAuth/OAuthAuthenticationMiddleware.cs index 1f9eace70..2628d3849 100644 --- a/src/Microsoft.AspNet.Security.OAuth/OAuthAuthenticationMiddleware.cs +++ b/src/Microsoft.AspNet.Security.OAuth/OAuthAuthenticationMiddleware.cs @@ -66,7 +66,7 @@ public OAuthAuthenticationMiddleware( if (Options.StateDataFormat == null) { - IDataProtector dataProtector = DataProtectionHelpers.CreateDataProtector(dataProtectionProvider, + IDataProtector dataProtector = dataProtectionProvider.CreateDataProtector( this.GetType().FullName, Options.AuthenticationType, "v1"); Options.StateDataFormat = new PropertiesDataFormat(dataProtector); } diff --git a/src/Microsoft.AspNet.Security.OAuth/OAuthBearerAuthenticationMiddleware.cs b/src/Microsoft.AspNet.Security.OAuth/OAuthBearerAuthenticationMiddleware.cs index eaa862a28..0661c4fed 100644 --- a/src/Microsoft.AspNet.Security.OAuth/OAuthBearerAuthenticationMiddleware.cs +++ b/src/Microsoft.AspNet.Security.OAuth/OAuthBearerAuthenticationMiddleware.cs @@ -58,7 +58,7 @@ public OAuthBearerAuthenticationMiddleware( if (Options.AccessTokenFormat == null) { - var dataProtector = DataProtectionHelpers.CreateDataProtector(dataProtectionProvider, + IDataProtector dataProtector = dataProtectionProvider.CreateDataProtector( this.GetType().FullName, Options.AuthenticationType, "v1"); Options.AccessTokenFormat = new TicketDataFormat(dataProtector); } diff --git a/src/Microsoft.AspNet.Security.Twitter/TwitterAuthenticationMiddleware.cs b/src/Microsoft.AspNet.Security.Twitter/TwitterAuthenticationMiddleware.cs index e3a56efab..6c4204a4b 100644 --- a/src/Microsoft.AspNet.Security.Twitter/TwitterAuthenticationMiddleware.cs +++ b/src/Microsoft.AspNet.Security.Twitter/TwitterAuthenticationMiddleware.cs @@ -60,7 +60,7 @@ public TwitterAuthenticationMiddleware( } if (Options.StateDataFormat == null) { - IDataProtector dataProtector = DataProtectionHelpers.CreateDataProtector(dataProtectionProvider, + IDataProtector dataProtector = dataProtectionProvider.CreateDataProtector( typeof(TwitterAuthenticationMiddleware).FullName, Options.AuthenticationType, "v1"); Options.StateDataFormat = new SecureDataFormat( Serializers.RequestToken, diff --git a/src/Microsoft.AspNet.Security/DataProtection/DataProtectionHelpers.cs b/src/Microsoft.AspNet.Security/DataProtection/DataProtectionHelpers.cs index eba80e708..986bc8dc8 100644 --- a/src/Microsoft.AspNet.Security/DataProtection/DataProtectionHelpers.cs +++ b/src/Microsoft.AspNet.Security/DataProtection/DataProtectionHelpers.cs @@ -1,22 +1,12 @@ // Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System; -using Microsoft.AspNet.Http; - namespace Microsoft.AspNet.Security.DataProtection { public static class DataProtectionHelpers { - public static IDataProtector CreateDataProtector(IDataProtectionProvider dataProtectionProvider, params string[] purposes) + public static IDataProtector CreateDataProtector([NotNull] this IDataProtectionProvider dataProtectionProvider, params string[] purposes) { - if (dataProtectionProvider == null) - { - // TODO: Get this from the environment. - dataProtectionProvider = new EphemeralDataProtectionProvider(); - } - return dataProtectionProvider.CreateProtector(string.Join(";", purposes)); } } From a492b8fcbdc0e13bb842d6315bf7622966bc2382 Mon Sep 17 00:00:00 2001 From: Chris Ross Date: Mon, 27 Oct 2014 16:01:31 -0700 Subject: [PATCH 078/216] #84 - Fix regression with OAuth Notifications. --- samples/SocialSample/project.json | 3 ++- .../OAuthAuthenticationExtensions.cs | 4 ++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/samples/SocialSample/project.json b/samples/SocialSample/project.json index 40f05e17c..5be1930c0 100644 --- a/samples/SocialSample/project.json +++ b/samples/SocialSample/project.json @@ -18,5 +18,6 @@ }, "aspnetcore50": { } - } + }, + "webroot": "wwwroot" } diff --git a/src/Microsoft.AspNet.Security.OAuth/OAuthAuthenticationExtensions.cs b/src/Microsoft.AspNet.Security.OAuth/OAuthAuthenticationExtensions.cs index 55ac54ca6..3e4947de2 100644 --- a/src/Microsoft.AspNet.Security.OAuth/OAuthAuthenticationExtensions.cs +++ b/src/Microsoft.AspNet.Security.OAuth/OAuthAuthenticationExtensions.cs @@ -31,6 +31,10 @@ public static IApplicationBuilder UseOAuthAuthentication([NotNull] this IApplica { configureOptions(options); } + if (options.Notifications == null) + { + options.Notifications = new OAuthAuthenticationNotifications(); + } }) { Name = authenticationType, From edefdf6b2f19a10edd64b2e2447a757a928536ee Mon Sep 17 00:00:00 2001 From: Pranav K Date: Wed, 29 Oct 2014 10:32:37 -0700 Subject: [PATCH 079/216] Updating Newtonsoft.json version to 6.0.6 --- src/Microsoft.AspNet.Security.Cookies/project.json | 2 +- src/Microsoft.AspNet.Security.Facebook/project.json | 2 +- src/Microsoft.AspNet.Security.Google/project.json | 2 +- src/Microsoft.AspNet.Security.MicrosoftAccount/project.json | 2 +- src/Microsoft.AspNet.Security.OAuth/project.json | 2 +- src/Microsoft.AspNet.Security.Twitter/project.json | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Microsoft.AspNet.Security.Cookies/project.json b/src/Microsoft.AspNet.Security.Cookies/project.json index a3fca6701..06074c5d4 100644 --- a/src/Microsoft.AspNet.Security.Cookies/project.json +++ b/src/Microsoft.AspNet.Security.Cookies/project.json @@ -6,7 +6,7 @@ "Microsoft.AspNet.Security.DataProtection": "1.0.0-*", "Microsoft.Framework.DependencyInjection": "1.0.0-*", "Microsoft.Framework.Logging": "1.0.0-*", - "Newtonsoft.Json": "6.0.4" + "Newtonsoft.Json": "6.0.6" }, "frameworks": { "aspnet50": {}, diff --git a/src/Microsoft.AspNet.Security.Facebook/project.json b/src/Microsoft.AspNet.Security.Facebook/project.json index 4f74026f6..4d95af136 100644 --- a/src/Microsoft.AspNet.Security.Facebook/project.json +++ b/src/Microsoft.AspNet.Security.Facebook/project.json @@ -8,7 +8,7 @@ "Microsoft.AspNet.WebUtilities": "1.0.0-*", "Microsoft.Framework.Logging": "1.0.0-*", "Microsoft.Framework.OptionsModel": "1.0.0-*", - "Newtonsoft.Json": "6.0.4" + "Newtonsoft.Json": "6.0.6" }, "frameworks": { "aspnet50": { diff --git a/src/Microsoft.AspNet.Security.Google/project.json b/src/Microsoft.AspNet.Security.Google/project.json index 59ba01fb3..01b6c030a 100644 --- a/src/Microsoft.AspNet.Security.Google/project.json +++ b/src/Microsoft.AspNet.Security.Google/project.json @@ -8,7 +8,7 @@ "Microsoft.AspNet.WebUtilities": "1.0.0-*", "Microsoft.Framework.Logging": "1.0.0-*", "Microsoft.Framework.OptionsModel": "1.0.0-*", - "Newtonsoft.Json": "6.0.4", + "Newtonsoft.Json": "6.0.6", }, "frameworks": { "aspnet50": { diff --git a/src/Microsoft.AspNet.Security.MicrosoftAccount/project.json b/src/Microsoft.AspNet.Security.MicrosoftAccount/project.json index 7e97b89e0..634cd05ae 100644 --- a/src/Microsoft.AspNet.Security.MicrosoftAccount/project.json +++ b/src/Microsoft.AspNet.Security.MicrosoftAccount/project.json @@ -8,7 +8,7 @@ "Microsoft.AspNet.WebUtilities": "1.0.0-*", "Microsoft.Framework.Logging": "1.0.0-*", "Microsoft.Framework.OptionsModel": "1.0.0-*", - "Newtonsoft.Json": "6.0.4" + "Newtonsoft.Json": "6.0.6" }, "frameworks": { "aspnet50": { diff --git a/src/Microsoft.AspNet.Security.OAuth/project.json b/src/Microsoft.AspNet.Security.OAuth/project.json index d83974977..b55368c09 100644 --- a/src/Microsoft.AspNet.Security.OAuth/project.json +++ b/src/Microsoft.AspNet.Security.OAuth/project.json @@ -6,7 +6,7 @@ "Microsoft.AspNet.Security.DataProtection": "1.0.0-*", "Microsoft.AspNet.WebUtilities": "1.0.0-*", "Microsoft.Framework.Logging": "1.0.0-*", - "Newtonsoft.Json": "6.0.4" + "Newtonsoft.Json": "6.0.6" }, "frameworks": { "aspnet50": { diff --git a/src/Microsoft.AspNet.Security.Twitter/project.json b/src/Microsoft.AspNet.Security.Twitter/project.json index a487d802a..2d5057682 100644 --- a/src/Microsoft.AspNet.Security.Twitter/project.json +++ b/src/Microsoft.AspNet.Security.Twitter/project.json @@ -7,7 +7,7 @@ "Microsoft.AspNet.WebUtilities": "1.0.0-*", "Microsoft.Framework.Logging": "1.0.0-*", "Microsoft.Framework.OptionsModel": "1.0.0-*", - "Newtonsoft.Json": "6.0.4" + "Newtonsoft.Json": "6.0.6" }, "frameworks": { "aspnet50": { From 2934bb866ddc54e5a29bb5ab65295deb1c143afa Mon Sep 17 00:00:00 2001 From: Pranav K Date: Wed, 29 Oct 2014 11:23:57 -0700 Subject: [PATCH 080/216] Removing transitive dependencies from project.json --- samples/CookieSample/project.json | 5 +-- samples/CookieSessionSample/project.json | 4 +- samples/SocialSample/project.json | 5 +-- .../project.json | 27 +------------ .../project.json | 40 ++----------------- .../project.json | 40 ++----------------- .../project.json | 40 +------------------ .../project.json | 28 +------------ src/Microsoft.AspNet.Security/project.json | 24 +---------- .../project.json | 8 ---- 10 files changed, 15 insertions(+), 206 deletions(-) diff --git a/samples/CookieSample/project.json b/samples/CookieSample/project.json index a962cc962..e84a83269 100644 --- a/samples/CookieSample/project.json +++ b/samples/CookieSample/project.json @@ -1,10 +1,7 @@ { "dependencies": { - "Microsoft.AspNet.RequestContainer": "1.0.0-*", - "Microsoft.AspNet.Security": "1.0.0-*", "Microsoft.AspNet.Security.Cookies": "1.0.0-*", - "Microsoft.AspNet.Server.WebListener": "1.0.0-*", - "Microsoft.Framework.DependencyInjection": "1.0.0-*" + "Microsoft.AspNet.Server.WebListener": "1.0.0-*" }, "commands": { "web": "Microsoft.AspNet.Hosting server=Microsoft.AspNet.Server.WebListener server.urls=http://localhost:12345" }, "frameworks": { diff --git a/samples/CookieSessionSample/project.json b/samples/CookieSessionSample/project.json index ebfb92a06..ff8e88be0 100644 --- a/samples/CookieSessionSample/project.json +++ b/samples/CookieSessionSample/project.json @@ -1,10 +1,8 @@ { "dependencies": { - "Microsoft.AspNet.RequestContainer": "1.0.0-*", "Microsoft.AspNet.Security.Cookies": "1.0.0-*", "Microsoft.AspNet.Server.WebListener": "1.0.0-*", - "Microsoft.Framework.Cache.Memory": "1.0.0-*", - "Microsoft.Framework.DependencyInjection": "1.0.0-*" + "Microsoft.Framework.Cache.Memory": "1.0.0-*" }, "commands": { "web": "Microsoft.AspNet.Hosting server=Microsoft.AspNet.Server.WebListener server.urls=http://localhost:12345" }, "frameworks": { diff --git a/samples/SocialSample/project.json b/samples/SocialSample/project.json index 5be1930c0..9a47104e2 100644 --- a/samples/SocialSample/project.json +++ b/samples/SocialSample/project.json @@ -1,16 +1,13 @@ { "dependencies": { "Microsoft.AspNet.Diagnostics": "1.0.0-*", - "Microsoft.AspNet.Security": "1.0.0-*", "Microsoft.AspNet.Security.Cookies": "1.0.0-*", "Microsoft.AspNet.Security.Facebook": "1.0.0-*", "Microsoft.AspNet.Security.Google": "1.0.0-*", "Microsoft.AspNet.Security.MicrosoftAccount": "1.0.0-*", "Microsoft.AspNet.Security.Twitter": "1.0.0-*", "Microsoft.AspNet.Server.IIS": "1.0.0-*", - "Microsoft.AspNet.Server.WebListener": "1.0.0-*", - "Microsoft.Framework.DependencyInjection": "1.0.0-*", - "Microsoft.Framework.OptionsModel": "1.0.0-*" + "Microsoft.AspNet.Server.WebListener": "1.0.0-*" }, "commands": { "web": "Microsoft.AspNet.Hosting server=Microsoft.AspNet.Server.WebListener server.urls=http://localhost:12345" }, "frameworks": { diff --git a/src/Microsoft.AspNet.Security.Cookies/project.json b/src/Microsoft.AspNet.Security.Cookies/project.json index 06074c5d4..7ef42a5be 100644 --- a/src/Microsoft.AspNet.Security.Cookies/project.json +++ b/src/Microsoft.AspNet.Security.Cookies/project.json @@ -1,36 +1,11 @@ { "version": "1.0.0-*", "dependencies": { - "Microsoft.AspNet.Http.Extensions": "1.0.0-*", "Microsoft.AspNet.Security": "1.0.0-*", - "Microsoft.AspNet.Security.DataProtection": "1.0.0-*", - "Microsoft.Framework.DependencyInjection": "1.0.0-*", - "Microsoft.Framework.Logging": "1.0.0-*", "Newtonsoft.Json": "6.0.6" }, "frameworks": { "aspnet50": {}, - "aspnetcore50": { - "dependencies": { - "System.Collections": "4.0.10-beta-*", - "System.ComponentModel": "4.0.0-beta-*", - "System.Console": "4.0.0-beta-*", - "System.Diagnostics.Debug": "4.0.10-beta-*", - "System.Diagnostics.Tools": "4.0.0-beta-*", - "System.Globalization": "4.0.10-beta-*", - "System.IO": "4.0.10-beta-*", - "System.IO.Compression": "4.0.0-beta-*", - "System.Linq": "4.0.0-beta-*", - "System.Reflection": "4.0.10-beta-*", - "System.Resources.ResourceManager": "4.0.0-beta-*", - "System.Runtime": "4.0.20-beta-*", - "System.Runtime.Extensions": "4.0.10-beta-*", - "System.Runtime.InteropServices": "4.0.20-beta-*", - "System.Security.Claims": "4.0.0-beta-*", - "System.Security.Principal" : "4.0.0-beta-*", - "System.Threading": "4.0.0-beta-*", - "System.Threading.Tasks": "4.0.10-beta-*" - } - } + "aspnetcore50": {} } } diff --git a/src/Microsoft.AspNet.Security.Facebook/project.json b/src/Microsoft.AspNet.Security.Facebook/project.json index 4d95af136..bd8c42fe1 100644 --- a/src/Microsoft.AspNet.Security.Facebook/project.json +++ b/src/Microsoft.AspNet.Security.Facebook/project.json @@ -1,44 +1,10 @@ { "version": "1.0.0-*", "dependencies": { - "Microsoft.AspNet.Http.Extensions": "1.0.0-*", - "Microsoft.AspNet.Security": "1.0.0-*", - "Microsoft.AspNet.Security.DataProtection": "1.0.0-*", - "Microsoft.AspNet.Security.OAuth": "1.0.0-*", - "Microsoft.AspNet.WebUtilities": "1.0.0-*", - "Microsoft.Framework.Logging": "1.0.0-*", - "Microsoft.Framework.OptionsModel": "1.0.0-*", - "Newtonsoft.Json": "6.0.6" + "Microsoft.AspNet.Security.OAuth": "1.0.0-*" }, "frameworks": { - "aspnet50": { - "frameworkAssemblies": { - "System.Net.Http": "" - } - }, - "aspnetcore50": { - "dependencies": { - "System.Collections": "4.0.10-beta-*", - "System.ComponentModel": "4.0.0-beta-*", - "System.Console": "4.0.0-beta-*", - "System.Diagnostics.Debug": "4.0.10-beta-*", - "System.Diagnostics.Tools": "4.0.0-beta-*", - "System.Globalization": "4.0.10-beta-*", - "System.IO": "4.0.10-beta-*", - "System.IO.Compression": "4.0.0-beta-*", - "System.Linq": "4.0.0-beta-*", - "System.Reflection": "4.0.10-beta-*", - "System.Resources.ResourceManager": "4.0.0-beta-*", - "System.Runtime": "4.0.20-beta-*", - "System.Runtime.Extensions": "4.0.10-beta-*", - "System.Runtime.InteropServices": "4.0.20-beta-*", - "System.Security.Claims": "4.0.0-beta-*", - "System.Security.Cryptography.Hashing.Algorithms": "4.0.0-beta-*", - "System.Security.Principal": "4.0.0-beta-*", - "System.Threading": "4.0.0-beta-*", - "System.Threading.Tasks": "4.0.10-beta-*", - "System.Net.Http": "4.0.0-beta-*" - } - } + "aspnet50": {}, + "aspnetcore50": {} } } diff --git a/src/Microsoft.AspNet.Security.Google/project.json b/src/Microsoft.AspNet.Security.Google/project.json index 01b6c030a..bd8c42fe1 100644 --- a/src/Microsoft.AspNet.Security.Google/project.json +++ b/src/Microsoft.AspNet.Security.Google/project.json @@ -1,44 +1,10 @@ { "version": "1.0.0-*", "dependencies": { - "Microsoft.AspNet.Http.Extensions": "1.0.0-*", - "Microsoft.AspNet.Security": "1.0.0-*", - "Microsoft.AspNet.Security.DataProtection": "1.0.0-*", - "Microsoft.AspNet.Security.OAuth": "1.0.0-*", - "Microsoft.AspNet.WebUtilities": "1.0.0-*", - "Microsoft.Framework.Logging": "1.0.0-*", - "Microsoft.Framework.OptionsModel": "1.0.0-*", - "Newtonsoft.Json": "6.0.6", + "Microsoft.AspNet.Security.OAuth": "1.0.0-*" }, "frameworks": { - "aspnet50": { - "frameworkAssemblies": { - "System.Net.Http": "" - } - }, - "aspnetcore50": { - "dependencies": { - "System.Collections": "4.0.10-beta-*", - "System.ComponentModel": "4.0.0-beta-*", - "System.Console": "4.0.0-beta-*", - "System.Diagnostics.Debug": "4.0.10-beta-*", - "System.Diagnostics.Tools": "4.0.0-beta-*", - "System.Globalization": "4.0.10-beta-*", - "System.IO": "4.0.10-beta-*", - "System.IO.Compression": "4.0.0-beta-*", - "System.Linq": "4.0.0-beta-*", - "System.Reflection": "4.0.10-beta-*", - "System.Resources.ResourceManager": "4.0.0-beta-*", - "System.Runtime": "4.0.20-beta-*", - "System.Runtime.Extensions": "4.0.10-beta-*", - "System.Runtime.InteropServices": "4.0.20-beta-*", - "System.Security.Claims": "4.0.0-beta-*", - "System.Security.Cryptography.Hashing.Algorithms": "4.0.0-beta-*", - "System.Security.Principal": "4.0.0-beta-*", - "System.Threading": "4.0.0-beta-*", - "System.Threading.Tasks": "4.0.10-beta-*", - "System.Net.Http": "4.0.0-beta-*" - } - } + "aspnet50": {}, + "aspnetcore50": {} } } diff --git a/src/Microsoft.AspNet.Security.MicrosoftAccount/project.json b/src/Microsoft.AspNet.Security.MicrosoftAccount/project.json index 634cd05ae..581fc6c2f 100644 --- a/src/Microsoft.AspNet.Security.MicrosoftAccount/project.json +++ b/src/Microsoft.AspNet.Security.MicrosoftAccount/project.json @@ -1,46 +1,10 @@ { "version": "1.0.0-*", "dependencies": { - "Microsoft.AspNet.Http.Extensions": "1.0.0-*", - "Microsoft.AspNet.Security": "1.0.0-*", - "Microsoft.AspNet.Security.DataProtection": "1.0.0-*", "Microsoft.AspNet.Security.OAuth": "1.0.0-*", - "Microsoft.AspNet.WebUtilities": "1.0.0-*", - "Microsoft.Framework.Logging": "1.0.0-*", - "Microsoft.Framework.OptionsModel": "1.0.0-*", - "Newtonsoft.Json": "6.0.6" }, "frameworks": { - "aspnet50": { - "frameworkAssemblies": { - "System.Net.Http": "" - } - }, - "aspnetcore50": { - "dependencies": { - "System.Collections": "4.0.10-beta-*", - "System.ComponentModel": "4.0.0-beta-*", - "System.Console": "4.0.0-beta-*", - "System.Diagnostics.Debug": "4.0.10-beta-*", - "System.Diagnostics.Tools": "4.0.0-beta-*", - "System.Dynamic.Runtime": "4.0.0-beta-*", - "System.Globalization": "4.0.10-beta-*", - "System.IO": "4.0.10-beta-*", - "System.IO.Compression": "4.0.0-beta-*", - "System.Linq": "4.0.0-beta-*", - "System.ObjectModel": "4.0.10-beta-*", - "System.Reflection": "4.0.10-beta-*", - "System.Resources.ResourceManager": "4.0.0-beta-*", - "System.Runtime": "4.0.20-beta-*", - "System.Runtime.Extensions": "4.0.10-beta-*", - "System.Runtime.InteropServices": "4.0.20-beta-*", - "System.Security.Claims": "4.0.0-beta-*", - "System.Security.Cryptography.Hashing.Algorithms": "4.0.0-beta-*", - "System.Security.Principal": "4.0.0-beta-*", - "System.Threading": "4.0.0-beta-*", - "System.Threading.Tasks": "4.0.10-beta-*", - "System.Net.Http": "4.0.0-beta-*" - } - } + "aspnet50": {}, + "aspnetcore50": {} } } diff --git a/src/Microsoft.AspNet.Security.Twitter/project.json b/src/Microsoft.AspNet.Security.Twitter/project.json index 2d5057682..41557ab40 100644 --- a/src/Microsoft.AspNet.Security.Twitter/project.json +++ b/src/Microsoft.AspNet.Security.Twitter/project.json @@ -1,13 +1,7 @@ { "version": "1.0.0-*", "dependencies": { - "Microsoft.AspNet.Http.Extensions": "1.0.0-*", - "Microsoft.AspNet.Security": "1.0.0-*", - "Microsoft.AspNet.Security.DataProtection": "1.0.0-*", - "Microsoft.AspNet.WebUtilities": "1.0.0-*", - "Microsoft.Framework.Logging": "1.0.0-*", - "Microsoft.Framework.OptionsModel": "1.0.0-*", - "Newtonsoft.Json": "6.0.6" + "Microsoft.AspNet.Security": "1.0.0-*" }, "frameworks": { "aspnet50": { @@ -18,27 +12,7 @@ }, "aspnetcore50": { "dependencies": { - "System.Collections": "4.0.10-beta-*", - "System.ComponentModel": "4.0.0-beta-*", - "System.Console": "4.0.0-beta-*", - "System.Diagnostics.Debug": "4.0.10-beta-*", - "System.Diagnostics.Tools": "4.0.0-beta-*", - "System.Globalization": "4.0.10-beta-*", - "System.IO": "4.0.10-beta-*", - "System.IO.Compression": "4.0.0-beta-*", - "System.Linq": "4.0.0-beta-*", "System.Net.Http.WinHttpHandler": "4.0.0-beta-*", - "System.Reflection": "4.0.10-beta-*", - "System.Resources.ResourceManager": "4.0.0-beta-*", - "System.Runtime": "4.0.20-beta-*", - "System.Runtime.Extensions": "4.0.10-beta-*", - "System.Runtime.InteropServices": "4.0.20-beta-*", - "System.Security.Claims": "4.0.0-beta-*", - "System.Security.Cryptography.Hashing.Algorithms": "4.0.0-beta-*", - "System.Security.Principal": "4.0.0-beta-*", - "System.Threading": "4.0.0-beta-*", - "System.Threading.Tasks": "4.0.10-beta-*", - "System.Net.Http": "4.0.0-beta-*" } } } diff --git a/src/Microsoft.AspNet.Security/project.json b/src/Microsoft.AspNet.Security/project.json index 8d1f81def..a06583787 100644 --- a/src/Microsoft.AspNet.Security/project.json +++ b/src/Microsoft.AspNet.Security/project.json @@ -5,33 +5,13 @@ "Microsoft.AspNet.HttpFeature": { "version": "1.0.0-*", "type": "build" }, "Microsoft.AspNet.PipelineCore": "1.0.0-*", "Microsoft.AspNet.Security.DataProtection": "1.0.0-*", - "Microsoft.Framework.DependencyInjection": "1.0.0-*", - "Microsoft.Framework.Logging": "1.0.0-*", - "Microsoft.Framework.OptionsModel": "1.0.0-*" + "Microsoft.Framework.Logging": "1.0.0-*" }, "frameworks": { "aspnet50": { }, "aspnetcore50": { "dependencies": { - "System.Collections": "4.0.10-beta-*", - "System.ComponentModel": "4.0.0-beta-*", - "System.Console": "4.0.0-beta-*", - "System.Diagnostics.Debug": "4.0.10-beta-*", - "System.Diagnostics.Tools": "4.0.0-beta-*", - "System.Globalization": "4.0.10-beta-*", - "System.IO": "4.0.10-beta-*", - "System.IO.Compression": "4.0.0-beta-*", - "System.Linq": "4.0.0-beta-*", - "System.Reflection": "4.0.10-beta-*", - "System.Resources.ResourceManager": "4.0.0-beta-*", - "System.Runtime": "4.0.20-beta-*", - "System.Runtime.Extensions": "4.0.10-beta-*", - "System.Runtime.InteropServices": "4.0.20-beta-*", - "System.Security.Claims": "4.0.0-beta-*", - "System.Security.Cryptography.RandomNumberGenerator": "4.0.0-beta-*", - "System.Security.Principal": "4.0.0-beta-*", - "System.Threading": "4.0.0-beta-*", - "System.Threading.Tasks": "4.0.10-beta-*" + "System.IO.Compression": "4.0.0-beta-*" } } } diff --git a/test/Microsoft.AspNet.Security.Test/project.json b/test/Microsoft.AspNet.Security.Test/project.json index 886baff98..affdcafeb 100644 --- a/test/Microsoft.AspNet.Security.Test/project.json +++ b/test/Microsoft.AspNet.Security.Test/project.json @@ -3,17 +3,12 @@ "warningsAsErrors": true }, "dependencies": { - "Microsoft.AspNet.Http": "1.0.0-*", - "Microsoft.AspNet.RequestContainer": "1.0.0-*", - "Microsoft.AspNet.Security": "1.0.0-*", "Microsoft.AspNet.Security.Cookies": "1.0.0-*", "Microsoft.AspNet.Security.Facebook": "1.0.0-*", "Microsoft.AspNet.Security.Google": "1.0.0-*", "Microsoft.AspNet.Security.MicrosoftAccount": "1.0.0-*", "Microsoft.AspNet.Security.Twitter": "1.0.0-*", "Microsoft.AspNet.TestHost": "1.0.0-*", - "Microsoft.Framework.DependencyInjection": "1.0.0-*", - "Microsoft.Framework.OptionsModel": "1.0.0-*", "Moq": "4.2.1312.1622", "Xunit.KRunner": "1.0.0-*" }, @@ -24,9 +19,6 @@ "aspnet50": { "dependencies": { "Shouldly": "1.1.1.1" - }, - "frameworkAssemblies": { - "System.Net.Http": "" } } } From a5bd9d29e54738cbde64d6598c9c0b32b9c9a2f1 Mon Sep 17 00:00:00 2001 From: David Fowler Date: Fri, 31 Oct 2014 02:11:42 -0700 Subject: [PATCH 081/216] Added package descriptions --- src/Microsoft.AspNet.Security.Cookies/project.json | 1 + src/Microsoft.AspNet.Security.Facebook/project.json | 1 + src/Microsoft.AspNet.Security.Google/project.json | 1 + src/Microsoft.AspNet.Security.MicrosoftAccount/project.json | 1 + src/Microsoft.AspNet.Security.OAuth/project.json | 1 + src/Microsoft.AspNet.Security.Twitter/project.json | 1 + src/Microsoft.AspNet.Security/project.json | 1 + 7 files changed, 7 insertions(+) diff --git a/src/Microsoft.AspNet.Security.Cookies/project.json b/src/Microsoft.AspNet.Security.Cookies/project.json index 06074c5d4..801141caf 100644 --- a/src/Microsoft.AspNet.Security.Cookies/project.json +++ b/src/Microsoft.AspNet.Security.Cookies/project.json @@ -1,5 +1,6 @@ { "version": "1.0.0-*", + "description": "ASP.NET middleware that enables an application to use cookie based authentication, similar to ASP.NET's forms authentication.", "dependencies": { "Microsoft.AspNet.Http.Extensions": "1.0.0-*", "Microsoft.AspNet.Security": "1.0.0-*", diff --git a/src/Microsoft.AspNet.Security.Facebook/project.json b/src/Microsoft.AspNet.Security.Facebook/project.json index 4d95af136..09d55389f 100644 --- a/src/Microsoft.AspNet.Security.Facebook/project.json +++ b/src/Microsoft.AspNet.Security.Facebook/project.json @@ -1,5 +1,6 @@ { "version": "1.0.0-*", + "description": "ASP.NET 5 middleware that enables an application to support Facebook's OAuth 2.0 authentication workflow.", "dependencies": { "Microsoft.AspNet.Http.Extensions": "1.0.0-*", "Microsoft.AspNet.Security": "1.0.0-*", diff --git a/src/Microsoft.AspNet.Security.Google/project.json b/src/Microsoft.AspNet.Security.Google/project.json index 01b6c030a..276f5b449 100644 --- a/src/Microsoft.AspNet.Security.Google/project.json +++ b/src/Microsoft.AspNet.Security.Google/project.json @@ -1,5 +1,6 @@ { "version": "1.0.0-*", + "description": "ASP.NET 5 contains middlewares to support Google's OpenId and OAuth 2.0 authentication workflows.", "dependencies": { "Microsoft.AspNet.Http.Extensions": "1.0.0-*", "Microsoft.AspNet.Security": "1.0.0-*", diff --git a/src/Microsoft.AspNet.Security.MicrosoftAccount/project.json b/src/Microsoft.AspNet.Security.MicrosoftAccount/project.json index 634cd05ae..d63b67608 100644 --- a/src/Microsoft.AspNet.Security.MicrosoftAccount/project.json +++ b/src/Microsoft.AspNet.Security.MicrosoftAccount/project.json @@ -1,5 +1,6 @@ { "version": "1.0.0-*", + "description": "ASP.NET 5 middleware that enables an application to support the Microsoft Account authentication workflow.", "dependencies": { "Microsoft.AspNet.Http.Extensions": "1.0.0-*", "Microsoft.AspNet.Security": "1.0.0-*", diff --git a/src/Microsoft.AspNet.Security.OAuth/project.json b/src/Microsoft.AspNet.Security.OAuth/project.json index b55368c09..bae60ec0b 100644 --- a/src/Microsoft.AspNet.Security.OAuth/project.json +++ b/src/Microsoft.AspNet.Security.OAuth/project.json @@ -1,5 +1,6 @@ { "version": "1.0.0-*", + "description": "ASP.NET 5 middleware that enables an application to support any standard OAuth 2.0 authentication workflow.", "dependencies": { "Microsoft.AspNet.Http.Extensions": "1.0.0-*", "Microsoft.AspNet.Security": "1.0.0-*", diff --git a/src/Microsoft.AspNet.Security.Twitter/project.json b/src/Microsoft.AspNet.Security.Twitter/project.json index 2d5057682..442ce80be 100644 --- a/src/Microsoft.AspNet.Security.Twitter/project.json +++ b/src/Microsoft.AspNet.Security.Twitter/project.json @@ -1,5 +1,6 @@ { "version": "1.0.0-*", + "description": "ASP.NET 5 middleware that enables an application to support Twitter's OAuth 2.0 authentication workflow.", "dependencies": { "Microsoft.AspNet.Http.Extensions": "1.0.0-*", "Microsoft.AspNet.Security": "1.0.0-*", diff --git a/src/Microsoft.AspNet.Security/project.json b/src/Microsoft.AspNet.Security/project.json index 8d1f81def..fd79fde8e 100644 --- a/src/Microsoft.AspNet.Security/project.json +++ b/src/Microsoft.AspNet.Security/project.json @@ -1,5 +1,6 @@ { "version": "1.0.0-*", + "description": "ASP.NET 5 common types used by the various authentication middleware.", "dependencies": { "Microsoft.AspNet.RequestContainer": "1.0.0-*", "Microsoft.AspNet.HttpFeature": { "version": "1.0.0-*", "type": "build" }, From 32a967d58f6746b23b3d2c89c923fbbaafd3224d Mon Sep 17 00:00:00 2001 From: Pranav K Date: Thu, 6 Nov 2014 10:49:29 -0800 Subject: [PATCH 082/216] Updating to release NuGet.config --- NuGet.Config | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NuGet.Config b/NuGet.Config index f41e9c631..2d3b0cb85 100644 --- a/NuGet.Config +++ b/NuGet.Config @@ -1,7 +1,7 @@  - + From ee162013a5c9f4ff94fe3aa7ef5560cf46e8d103 Mon Sep 17 00:00:00 2001 From: Victor Hurdugaci Date: Wed, 12 Nov 2014 15:33:16 -0800 Subject: [PATCH 083/216] Update KProj to the latest format --- samples/CookieSample/CookieSample.kproj | 18 ++++------- .../CookieSessionSample.kproj | 30 ++++--------------- samples/SocialSample/SocialSample.kproj | 25 ++++------------ .../Microsoft.AspNet.Security.Cookies.kproj | 18 ++++------- .../Microsoft.AspNet.Security.Facebook.kproj | 18 ++++------- .../Microsoft.AspNet.Security.Google.kproj | 26 ++++------------ ...oft.AspNet.Security.MicrosoftAccount.kproj | 26 ++++------------ .../Microsoft.AspNet.Security.OAuth.kproj | 26 ++++------------ .../Microsoft.AspNet.Security.Twitter.kproj | 26 ++++------------ .../Microsoft.AspNet.Security.kproj | 18 ++++------- .../Microsoft.AspNet.Security.Tests.kproj | 18 ++++------- 11 files changed, 66 insertions(+), 183 deletions(-) diff --git a/samples/CookieSample/CookieSample.kproj b/samples/CookieSample/CookieSample.kproj index 3f9173352..86a746ad6 100644 --- a/samples/CookieSample/CookieSample.kproj +++ b/samples/CookieSample/CookieSample.kproj @@ -1,20 +1,14 @@ - - + + - 12.0 + 14.0 $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) 558c2c2a-aed8-49de-bb60-d5f8ae06c714 - Library - - - - - - - 2.0 + ..\..\artifacts\obj\$(MSBuildProjectName) + ..\..\artifacts\bin\$(MSBuildProjectName)\ - \ No newline at end of file + diff --git a/samples/CookieSessionSample/CookieSessionSample.kproj b/samples/CookieSessionSample/CookieSessionSample.kproj index 951ff1cc5..81e25a7fc 100644 --- a/samples/CookieSessionSample/CookieSessionSample.kproj +++ b/samples/CookieSessionSample/CookieSessionSample.kproj @@ -1,32 +1,14 @@ - - + + - 12.0 + 14.0 $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) - - Debug - AnyCPU - - 19711880-46da-4a26-9e0f-9b2e41d27651 - Library - CookieSessionSample - - - - ConsoleDebugger - - - WebDebugger - - - - - - 2.0 + ..\..\artifacts\obj\$(MSBuildProjectName) + ..\..\artifacts\bin\$(MSBuildProjectName)\ - \ No newline at end of file + diff --git a/samples/SocialSample/SocialSample.kproj b/samples/SocialSample/SocialSample.kproj index 2d3d1caf5..358b0923f 100644 --- a/samples/SocialSample/SocialSample.kproj +++ b/samples/SocialSample/SocialSample.kproj @@ -1,27 +1,14 @@ - - + + - 12.0 + 14.0 $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) 8c73d216-332d-41d8-bfd0-45bc4bc36552 - Web - - - ConsoleDebugger - - - WebDebugger - - - - - - - 2.0 - 12345 + ..\..\artifacts\obj\$(MSBuildProjectName) + ..\..\artifacts\bin\$(MSBuildProjectName)\ - \ No newline at end of file + diff --git a/src/Microsoft.AspNet.Security.Cookies/Microsoft.AspNet.Security.Cookies.kproj b/src/Microsoft.AspNet.Security.Cookies/Microsoft.AspNet.Security.Cookies.kproj index 75aae6178..6f2989244 100644 --- a/src/Microsoft.AspNet.Security.Cookies/Microsoft.AspNet.Security.Cookies.kproj +++ b/src/Microsoft.AspNet.Security.Cookies/Microsoft.AspNet.Security.Cookies.kproj @@ -1,20 +1,14 @@ - - + + - 12.0 + 14.0 $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) 15f1211b-b695-4a1c-b730-1ac58fc91090 - Library - - - - - - - 2.0 + ..\..\artifacts\obj\$(MSBuildProjectName) + ..\..\artifacts\bin\$(MSBuildProjectName)\ - \ No newline at end of file + diff --git a/src/Microsoft.AspNet.Security.Facebook/Microsoft.AspNet.Security.Facebook.kproj b/src/Microsoft.AspNet.Security.Facebook/Microsoft.AspNet.Security.Facebook.kproj index c576730aa..b4d160363 100644 --- a/src/Microsoft.AspNet.Security.Facebook/Microsoft.AspNet.Security.Facebook.kproj +++ b/src/Microsoft.AspNet.Security.Facebook/Microsoft.AspNet.Security.Facebook.kproj @@ -1,20 +1,14 @@ - - + + - 12.0 + 14.0 $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) 3984651c-fd44-4394-8793-3d14ee348c04 - Library - - - - - - - 2.0 + ..\..\artifacts\obj\$(MSBuildProjectName) + ..\..\artifacts\bin\$(MSBuildProjectName)\ - \ No newline at end of file + diff --git a/src/Microsoft.AspNet.Security.Google/Microsoft.AspNet.Security.Google.kproj b/src/Microsoft.AspNet.Security.Google/Microsoft.AspNet.Security.Google.kproj index 111093c64..93e3716ce 100644 --- a/src/Microsoft.AspNet.Security.Google/Microsoft.AspNet.Security.Google.kproj +++ b/src/Microsoft.AspNet.Security.Google/Microsoft.AspNet.Security.Google.kproj @@ -1,28 +1,14 @@ - - + + - 12.0 + 14.0 $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) 89bf8535-a849-458e-868a-a68fcf620486 - Library - - - - ConsoleDebugger - - - WebDebugger - - - - - - - - 2.0 + ..\..\artifacts\obj\$(MSBuildProjectName) + ..\..\artifacts\bin\$(MSBuildProjectName)\ - \ No newline at end of file + diff --git a/src/Microsoft.AspNet.Security.MicrosoftAccount/Microsoft.AspNet.Security.MicrosoftAccount.kproj b/src/Microsoft.AspNet.Security.MicrosoftAccount/Microsoft.AspNet.Security.MicrosoftAccount.kproj index dbdeeb34c..439829d54 100644 --- a/src/Microsoft.AspNet.Security.MicrosoftAccount/Microsoft.AspNet.Security.MicrosoftAccount.kproj +++ b/src/Microsoft.AspNet.Security.MicrosoftAccount/Microsoft.AspNet.Security.MicrosoftAccount.kproj @@ -1,28 +1,14 @@ - - + + - 12.0 + 14.0 $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) 1fcf26c2-a3c7-4308-b698-4afc3560bc0c - Library - - - - ConsoleDebugger - - - WebDebugger - - - - - - - - 2.0 + ..\..\artifacts\obj\$(MSBuildProjectName) + ..\..\artifacts\bin\$(MSBuildProjectName)\ - \ No newline at end of file + diff --git a/src/Microsoft.AspNet.Security.OAuth/Microsoft.AspNet.Security.OAuth.kproj b/src/Microsoft.AspNet.Security.OAuth/Microsoft.AspNet.Security.OAuth.kproj index f0c8d7b47..32d728261 100644 --- a/src/Microsoft.AspNet.Security.OAuth/Microsoft.AspNet.Security.OAuth.kproj +++ b/src/Microsoft.AspNet.Security.OAuth/Microsoft.AspNet.Security.OAuth.kproj @@ -1,28 +1,14 @@ - - + + - 12.0 + 14.0 $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) 4a636011-68ee-4ce5-836d-ea8e13cf71e4 - Library - - - - ConsoleDebugger - - - WebDebugger - - - - - - - - 2.0 + ..\..\artifacts\obj\$(MSBuildProjectName) + ..\..\artifacts\bin\$(MSBuildProjectName)\ - \ No newline at end of file + diff --git a/src/Microsoft.AspNet.Security.Twitter/Microsoft.AspNet.Security.Twitter.kproj b/src/Microsoft.AspNet.Security.Twitter/Microsoft.AspNet.Security.Twitter.kproj index 48dfc3069..980720b3f 100644 --- a/src/Microsoft.AspNet.Security.Twitter/Microsoft.AspNet.Security.Twitter.kproj +++ b/src/Microsoft.AspNet.Security.Twitter/Microsoft.AspNet.Security.Twitter.kproj @@ -1,28 +1,14 @@ - - + + - 12.0 + 14.0 $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) c96b77ea-4078-4c31-bdb2-878f11c5e061 - Library - - - - ConsoleDebugger - - - WebDebugger - - - - - - - - 2.0 + ..\..\artifacts\obj\$(MSBuildProjectName) + ..\..\artifacts\bin\$(MSBuildProjectName)\ - \ No newline at end of file + diff --git a/src/Microsoft.AspNet.Security/Microsoft.AspNet.Security.kproj b/src/Microsoft.AspNet.Security/Microsoft.AspNet.Security.kproj index 923789fb1..9a1e95727 100644 --- a/src/Microsoft.AspNet.Security/Microsoft.AspNet.Security.kproj +++ b/src/Microsoft.AspNet.Security/Microsoft.AspNet.Security.kproj @@ -1,20 +1,14 @@ - - + + - 12.0 + 14.0 $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) 0f174c63-1898-4024-9a3c-3fdf5cae5c68 - Library - - - - - - - 2.0 + ..\..\artifacts\obj\$(MSBuildProjectName) + ..\..\artifacts\bin\$(MSBuildProjectName)\ - \ No newline at end of file + diff --git a/test/Microsoft.AspNet.Security.Test/Microsoft.AspNet.Security.Tests.kproj b/test/Microsoft.AspNet.Security.Test/Microsoft.AspNet.Security.Tests.kproj index 54191c08d..a989127e4 100644 --- a/test/Microsoft.AspNet.Security.Test/Microsoft.AspNet.Security.Tests.kproj +++ b/test/Microsoft.AspNet.Security.Test/Microsoft.AspNet.Security.Tests.kproj @@ -1,20 +1,14 @@ - - + + - 12.0 + 14.0 $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) 8da26cd1-1302-4cfd-9270-9fa1b7c6138b - Library - - - - - - - 2.0 + ..\..\artifacts\obj\$(MSBuildProjectName) + ..\..\artifacts\bin\$(MSBuildProjectName)\ - \ No newline at end of file + From 0815681a9551ddc65213449e73306e89476d801c Mon Sep 17 00:00:00 2001 From: Suhas Joshi Date: Thu, 13 Nov 2014 11:16:36 -0800 Subject: [PATCH 084/216] Added kestrel to run samples on Mono --- samples/CookieSample/project.json | 22 +++++++++++++--------- samples/CookieSessionSample/project.json | 8 ++++++-- samples/SocialSample/project.json | 8 ++++++-- 3 files changed, 25 insertions(+), 13 deletions(-) diff --git a/samples/CookieSample/project.json b/samples/CookieSample/project.json index e84a83269..0cc0dd1f4 100644 --- a/samples/CookieSample/project.json +++ b/samples/CookieSample/project.json @@ -1,13 +1,17 @@ { - "dependencies": { - "Microsoft.AspNet.Security.Cookies": "1.0.0-*", - "Microsoft.AspNet.Server.WebListener": "1.0.0-*" - }, - "commands": { "web": "Microsoft.AspNet.Hosting server=Microsoft.AspNet.Server.WebListener server.urls=http://localhost:12345" }, - "frameworks": { - "aspnet50": { + "dependencies": { + "Microsoft.AspNet.Security.Cookies": "1.0.0-*", + "Microsoft.AspNet.Server.WebListener": "1.0.0-*", + "Kestrel": "1.0.0-*" }, - "aspnetcore50": { + "commands": { + "web": "Microsoft.AspNet.Hosting server=Microsoft.AspNet.Server.WebListener server.urls=http://localhost:12345", + "kestrel": "Microsoft.AspNet.Hosting --server Kestrel --server.urls http://localhost:5004" + }, + "frameworks": { + "aspnet50": { + }, + "aspnetcore50": { + } } - } } diff --git a/samples/CookieSessionSample/project.json b/samples/CookieSessionSample/project.json index ff8e88be0..7ef0f4e96 100644 --- a/samples/CookieSessionSample/project.json +++ b/samples/CookieSessionSample/project.json @@ -2,9 +2,13 @@ "dependencies": { "Microsoft.AspNet.Security.Cookies": "1.0.0-*", "Microsoft.AspNet.Server.WebListener": "1.0.0-*", - "Microsoft.Framework.Cache.Memory": "1.0.0-*" + "Microsoft.Framework.Cache.Memory": "1.0.0-*", + "Kestrel": "1.0.0-*" + }, + "commands": { + "web": "Microsoft.AspNet.Hosting server=Microsoft.AspNet.Server.WebListener server.urls=http://localhost:12345", + "kestrel": "Microsoft.AspNet.Hosting --server Kestrel --server.urls http://localhost:5004" }, - "commands": { "web": "Microsoft.AspNet.Hosting server=Microsoft.AspNet.Server.WebListener server.urls=http://localhost:12345" }, "frameworks": { "aspnet50": { }, "aspnetcore50": { } diff --git a/samples/SocialSample/project.json b/samples/SocialSample/project.json index 9a47104e2..737c6638e 100644 --- a/samples/SocialSample/project.json +++ b/samples/SocialSample/project.json @@ -7,9 +7,13 @@ "Microsoft.AspNet.Security.MicrosoftAccount": "1.0.0-*", "Microsoft.AspNet.Security.Twitter": "1.0.0-*", "Microsoft.AspNet.Server.IIS": "1.0.0-*", - "Microsoft.AspNet.Server.WebListener": "1.0.0-*" + "Microsoft.AspNet.Server.WebListener": "1.0.0-*", + "Kestrel": "1.0.0-*" + }, + "commands": { + "web": "Microsoft.AspNet.Hosting server=Microsoft.AspNet.Server.WebListener server.urls=http://localhost:12345", + "kestrel": "Microsoft.AspNet.Hosting --server Kestrel --server.urls http://localhost:5004" }, - "commands": { "web": "Microsoft.AspNet.Hosting server=Microsoft.AspNet.Server.WebListener server.urls=http://localhost:12345" }, "frameworks": { "aspnet50": { }, From 2f7c186b24eb7c76f2610bc935f9c553d61906c4 Mon Sep 17 00:00:00 2001 From: Suhas Joshi Date: Thu, 13 Nov 2014 12:57:01 -0800 Subject: [PATCH 085/216] Adding necesary files for IIS hosting --- samples/CookieSample/project.json | 4 +++- samples/CookieSample/wwwroot/.gitkeep | 0 samples/CookieSessionSample/project.json | 6 ++++-- samples/CookieSessionSample/wwwroot/.gitkeep | 0 samples/SocialSample/wwwroot/.gitkeep | 0 5 files changed, 7 insertions(+), 3 deletions(-) create mode 100644 samples/CookieSample/wwwroot/.gitkeep create mode 100644 samples/CookieSessionSample/wwwroot/.gitkeep create mode 100644 samples/SocialSample/wwwroot/.gitkeep diff --git a/samples/CookieSample/project.json b/samples/CookieSample/project.json index 0cc0dd1f4..2cda02680 100644 --- a/samples/CookieSample/project.json +++ b/samples/CookieSample/project.json @@ -2,6 +2,7 @@ "dependencies": { "Microsoft.AspNet.Security.Cookies": "1.0.0-*", "Microsoft.AspNet.Server.WebListener": "1.0.0-*", + "Microsoft.AspNet.Server.IIS": "1.0.0-*", "Kestrel": "1.0.0-*" }, "commands": { @@ -13,5 +14,6 @@ }, "aspnetcore50": { } - } + }, + "webroot":"wwwroot" } diff --git a/samples/CookieSample/wwwroot/.gitkeep b/samples/CookieSample/wwwroot/.gitkeep new file mode 100644 index 000000000..e69de29bb diff --git a/samples/CookieSessionSample/project.json b/samples/CookieSessionSample/project.json index 7ef0f4e96..684c76517 100644 --- a/samples/CookieSessionSample/project.json +++ b/samples/CookieSessionSample/project.json @@ -3,7 +3,8 @@ "Microsoft.AspNet.Security.Cookies": "1.0.0-*", "Microsoft.AspNet.Server.WebListener": "1.0.0-*", "Microsoft.Framework.Cache.Memory": "1.0.0-*", - "Kestrel": "1.0.0-*" + "Kestrel": "1.0.0-*", + "Microsoft.AspNet.Server.IIS": "1.0.0-*" }, "commands": { "web": "Microsoft.AspNet.Hosting server=Microsoft.AspNet.Server.WebListener server.urls=http://localhost:12345", @@ -12,5 +13,6 @@ "frameworks": { "aspnet50": { }, "aspnetcore50": { } - } + }, + "webroot": "wwwroot" } diff --git a/samples/CookieSessionSample/wwwroot/.gitkeep b/samples/CookieSessionSample/wwwroot/.gitkeep new file mode 100644 index 000000000..e69de29bb diff --git a/samples/SocialSample/wwwroot/.gitkeep b/samples/SocialSample/wwwroot/.gitkeep new file mode 100644 index 000000000..e69de29bb From 4f90920b6d02af885371b9f24c660a175c71f293 Mon Sep 17 00:00:00 2001 From: Suhas Joshi Date: Thu, 13 Nov 2014 11:16:36 -0800 Subject: [PATCH 086/216] Added kestrel and running on IIS support --- samples/CookieSample/project.json | 26 ++++++++++++-------- samples/CookieSample/wwwroot/.gitkeep | 0 samples/CookieSessionSample/project.json | 12 ++++++--- samples/CookieSessionSample/wwwroot/.gitkeep | 0 samples/SocialSample/project.json | 8 ++++-- samples/SocialSample/wwwroot/.gitkeep | 0 6 files changed, 31 insertions(+), 15 deletions(-) create mode 100644 samples/CookieSample/wwwroot/.gitkeep create mode 100644 samples/CookieSessionSample/wwwroot/.gitkeep create mode 100644 samples/SocialSample/wwwroot/.gitkeep diff --git a/samples/CookieSample/project.json b/samples/CookieSample/project.json index e84a83269..2cda02680 100644 --- a/samples/CookieSample/project.json +++ b/samples/CookieSample/project.json @@ -1,13 +1,19 @@ { - "dependencies": { - "Microsoft.AspNet.Security.Cookies": "1.0.0-*", - "Microsoft.AspNet.Server.WebListener": "1.0.0-*" - }, - "commands": { "web": "Microsoft.AspNet.Hosting server=Microsoft.AspNet.Server.WebListener server.urls=http://localhost:12345" }, - "frameworks": { - "aspnet50": { + "dependencies": { + "Microsoft.AspNet.Security.Cookies": "1.0.0-*", + "Microsoft.AspNet.Server.WebListener": "1.0.0-*", + "Microsoft.AspNet.Server.IIS": "1.0.0-*", + "Kestrel": "1.0.0-*" }, - "aspnetcore50": { - } - } + "commands": { + "web": "Microsoft.AspNet.Hosting server=Microsoft.AspNet.Server.WebListener server.urls=http://localhost:12345", + "kestrel": "Microsoft.AspNet.Hosting --server Kestrel --server.urls http://localhost:5004" + }, + "frameworks": { + "aspnet50": { + }, + "aspnetcore50": { + } + }, + "webroot":"wwwroot" } diff --git a/samples/CookieSample/wwwroot/.gitkeep b/samples/CookieSample/wwwroot/.gitkeep new file mode 100644 index 000000000..e69de29bb diff --git a/samples/CookieSessionSample/project.json b/samples/CookieSessionSample/project.json index ff8e88be0..684c76517 100644 --- a/samples/CookieSessionSample/project.json +++ b/samples/CookieSessionSample/project.json @@ -2,11 +2,17 @@ "dependencies": { "Microsoft.AspNet.Security.Cookies": "1.0.0-*", "Microsoft.AspNet.Server.WebListener": "1.0.0-*", - "Microsoft.Framework.Cache.Memory": "1.0.0-*" + "Microsoft.Framework.Cache.Memory": "1.0.0-*", + "Kestrel": "1.0.0-*", + "Microsoft.AspNet.Server.IIS": "1.0.0-*" + }, + "commands": { + "web": "Microsoft.AspNet.Hosting server=Microsoft.AspNet.Server.WebListener server.urls=http://localhost:12345", + "kestrel": "Microsoft.AspNet.Hosting --server Kestrel --server.urls http://localhost:5004" }, - "commands": { "web": "Microsoft.AspNet.Hosting server=Microsoft.AspNet.Server.WebListener server.urls=http://localhost:12345" }, "frameworks": { "aspnet50": { }, "aspnetcore50": { } - } + }, + "webroot": "wwwroot" } diff --git a/samples/CookieSessionSample/wwwroot/.gitkeep b/samples/CookieSessionSample/wwwroot/.gitkeep new file mode 100644 index 000000000..e69de29bb diff --git a/samples/SocialSample/project.json b/samples/SocialSample/project.json index 9a47104e2..737c6638e 100644 --- a/samples/SocialSample/project.json +++ b/samples/SocialSample/project.json @@ -7,9 +7,13 @@ "Microsoft.AspNet.Security.MicrosoftAccount": "1.0.0-*", "Microsoft.AspNet.Security.Twitter": "1.0.0-*", "Microsoft.AspNet.Server.IIS": "1.0.0-*", - "Microsoft.AspNet.Server.WebListener": "1.0.0-*" + "Microsoft.AspNet.Server.WebListener": "1.0.0-*", + "Kestrel": "1.0.0-*" + }, + "commands": { + "web": "Microsoft.AspNet.Hosting server=Microsoft.AspNet.Server.WebListener server.urls=http://localhost:12345", + "kestrel": "Microsoft.AspNet.Hosting --server Kestrel --server.urls http://localhost:5004" }, - "commands": { "web": "Microsoft.AspNet.Hosting server=Microsoft.AspNet.Server.WebListener server.urls=http://localhost:12345" }, "frameworks": { "aspnet50": { }, diff --git a/samples/SocialSample/wwwroot/.gitkeep b/samples/SocialSample/wwwroot/.gitkeep new file mode 100644 index 000000000..e69de29bb From 0fee3c87a0359dad9df0e5a519b8b0673b8d8540 Mon Sep 17 00:00:00 2001 From: Chris Ross Date: Fri, 14 Nov 2014 15:05:31 -0800 Subject: [PATCH 087/216] #85 - Update the targeted Facebook API version to v2.2. --- samples/CookieSample/CookieSample.kproj | 5 +++-- .../CookieSessionSample/CookieSessionSample.kproj | 5 +++-- samples/SocialSample/SocialSample.kproj | 7 +++++-- samples/SocialSample/Startup.cs | 14 +++++++++----- samples/SocialSample/project.json | 5 +++-- .../FacebookAuthenticationDefaults.cs | 6 +++--- .../Facebook/FacebookMiddlewareTests.cs | 2 +- 7 files changed, 27 insertions(+), 17 deletions(-) diff --git a/samples/CookieSample/CookieSample.kproj b/samples/CookieSample/CookieSample.kproj index 86a746ad6..3afd3733f 100644 --- a/samples/CookieSample/CookieSample.kproj +++ b/samples/CookieSample/CookieSample.kproj @@ -1,8 +1,9 @@ - + 14.0 $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) + 54539 @@ -11,4 +12,4 @@ ..\..\artifacts\bin\$(MSBuildProjectName)\ - + \ No newline at end of file diff --git a/samples/CookieSessionSample/CookieSessionSample.kproj b/samples/CookieSessionSample/CookieSessionSample.kproj index 81e25a7fc..954c473e9 100644 --- a/samples/CookieSessionSample/CookieSessionSample.kproj +++ b/samples/CookieSessionSample/CookieSessionSample.kproj @@ -1,8 +1,9 @@ - + 14.0 $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) + 54541 @@ -11,4 +12,4 @@ ..\..\artifacts\bin\$(MSBuildProjectName)\ - + \ No newline at end of file diff --git a/samples/SocialSample/SocialSample.kproj b/samples/SocialSample/SocialSample.kproj index 358b0923f..1fbca3ad0 100644 --- a/samples/SocialSample/SocialSample.kproj +++ b/samples/SocialSample/SocialSample.kproj @@ -1,8 +1,11 @@ - + 14.0 $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) + 54540 + + @@ -11,4 +14,4 @@ ..\..\artifacts\bin\$(MSBuildProjectName)\ - + \ No newline at end of file diff --git a/samples/SocialSample/Startup.cs b/samples/SocialSample/Startup.cs index 3ddba6fb4..162a1b553 100644 --- a/samples/SocialSample/Startup.cs +++ b/samples/SocialSample/Startup.cs @@ -37,6 +37,7 @@ public void Configure(IApplicationBuilder app) options.LoginPath = new PathString("/login"); }); + // https://developers.facebook.com/apps/ app.UseFacebookAuthentication(options => { options.AppId = "569522623154478"; @@ -55,23 +56,25 @@ public void Configure(IApplicationBuilder app) options.Scope.Add("email"); }); + // https://console.developers.google.com/project app.UseGoogleAuthentication(options => { options.ClientId = "560027070069-37ldt4kfuohhu3m495hk2j4pjp92d382.apps.googleusercontent.com"; options.ClientSecret = "n2Q-GEw9RQjzcRbU3qhfTj8f"; }); + // https://apps.twitter.com/ app.UseTwitterAuthentication(options => { options.ConsumerKey = "6XaCTaLbMqfj6ww3zvZ5g"; options.ConsumerSecret = "Il2eFzGIrYhz6BWjYhVXBPQSfZuS4xoHpSSyD9PI"; }); - /* - The MicrosoftAccount service has restrictions that prevent the use of http://localhost:12345/ for test applications. - As such, here is how to change this sample to uses http://mssecsample.localhost.this:12345/ instead. + /* https://account.live.com/developers/applications + The MicrosoftAccount service has restrictions that prevent the use of http://localhost:54540/ for test applications. + As such, here is how to change this sample to uses http://mssecsample.localhost.this:54540/ instead. - Edit the Project.json file and replace http://localhost:12345/ with http://mssecsample.localhost.this:12345/. + Edit the Project.json file and replace http://localhost:54540/ with http://mssecsample.localhost.this:54540/. From an admin command console first enter: notepad C:\Windows\System32\drivers\etc\hosts @@ -79,7 +82,7 @@ public void Configure(IApplicationBuilder app) 127.0.0.1 MsSecSample.localhost.this Then you can choose to run the app as admin (see below) or add the following ACL as admin: - netsh http add urlacl url=http://mssecsample.localhost.this:12345/ user=[domain\user] + netsh http add urlacl url=http://mssecsample.localhost.this:54540/ user=[domain\user] The sample app can then be run via: k web @@ -102,6 +105,7 @@ k web options.ClientSecret = "bLw2JIvf8Y1TaToipPEqxTVlOeJwCUsr"; }); + // https://github.com/settings/applications/ app.UseOAuthAuthentication("GitHub-AccessToken", options => { options.ClientId = "8c0c5a572abe8fe89588"; diff --git a/samples/SocialSample/project.json b/samples/SocialSample/project.json index 737c6638e..f457d3a9d 100644 --- a/samples/SocialSample/project.json +++ b/samples/SocialSample/project.json @@ -11,8 +11,9 @@ "Kestrel": "1.0.0-*" }, "commands": { - "web": "Microsoft.AspNet.Hosting server=Microsoft.AspNet.Server.WebListener server.urls=http://localhost:12345", - "kestrel": "Microsoft.AspNet.Hosting --server Kestrel --server.urls http://localhost:5004" + /* Note all servers must use the same address and port because these are pre-registered with the various providers. */ + "web": "Microsoft.AspNet.Hosting server=Microsoft.AspNet.Server.WebListener server.urls=http://localhost:54540", + "kestrel": "Microsoft.AspNet.Hosting --server Kestrel --server.urls http://localhost:54540" }, "frameworks": { "aspnet50": { diff --git a/src/Microsoft.AspNet.Security.Facebook/FacebookAuthenticationDefaults.cs b/src/Microsoft.AspNet.Security.Facebook/FacebookAuthenticationDefaults.cs index 19cc38074..72addbef8 100644 --- a/src/Microsoft.AspNet.Security.Facebook/FacebookAuthenticationDefaults.cs +++ b/src/Microsoft.AspNet.Security.Facebook/FacebookAuthenticationDefaults.cs @@ -7,10 +7,10 @@ public static class FacebookAuthenticationDefaults { public const string AuthenticationType = "Facebook"; - public const string AuthorizationEndpoint = "https://www.facebook.com/dialog/oauth"; + public const string AuthorizationEndpoint = "https://www.facebook.com/v2.2/dialog/oauth"; - public const string TokenEndpoint = "https://graph.facebook.com/oauth/access_token"; + public const string TokenEndpoint = "https://graph.facebook.com/v2.2/oauth/access_token"; - public const string UserInformationEndpoint = "https://graph.facebook.com/me"; + public const string UserInformationEndpoint = "https://graph.facebook.com/v2.2/me"; } } diff --git a/test/Microsoft.AspNet.Security.Test/Facebook/FacebookMiddlewareTests.cs b/test/Microsoft.AspNet.Security.Test/Facebook/FacebookMiddlewareTests.cs index f3e0bf703..6120b82c4 100644 --- a/test/Microsoft.AspNet.Security.Test/Facebook/FacebookMiddlewareTests.cs +++ b/test/Microsoft.AspNet.Security.Test/Facebook/FacebookMiddlewareTests.cs @@ -97,7 +97,7 @@ public async Task ChallengeWillTriggerRedirection() var transaction = await SendAsync(server, "http://example.com/challenge"); transaction.Response.StatusCode.ShouldBe(HttpStatusCode.Redirect); var location = transaction.Response.Headers.Location.AbsoluteUri; - location.ShouldContain("https://www.facebook.com/dialog/oauth"); + location.ShouldContain("https://www.facebook.com/v2.2/dialog/oauth"); location.ShouldContain("response_type=code"); location.ShouldContain("client_id="); location.ShouldContain("redirect_uri="); From b37966f7ef7a34437e02c8347f8eb6fe57368f18 Mon Sep 17 00:00:00 2001 From: Chris Ross Date: Tue, 18 Nov 2014 14:51:36 -0800 Subject: [PATCH 088/216] Fix DataProtection DI dependencies. --- .../Cookies/CookieMiddlewareTests.cs | 4 +- .../Facebook/FacebookMiddlewareTests.cs | 2 +- .../Google/GoogleMiddlewareTests.cs | 2 +- .../MicrosoftAccountMiddlewareTests.cs | 2 +- .../TestApplicationEnvironment.cs | 37 +++++++++++++++++++ .../TestServices.cs | 22 +++++++++++ .../Twitter/TwitterMiddlewareTests.cs | 2 +- 7 files changed, 64 insertions(+), 7 deletions(-) create mode 100644 test/Microsoft.AspNet.Security.Test/TestApplicationEnvironment.cs create mode 100644 test/Microsoft.AspNet.Security.Test/TestServices.cs diff --git a/test/Microsoft.AspNet.Security.Test/Cookies/CookieMiddlewareTests.cs b/test/Microsoft.AspNet.Security.Test/Cookies/CookieMiddlewareTests.cs index fc101faaa..dbf470f83 100644 --- a/test/Microsoft.AspNet.Security.Test/Cookies/CookieMiddlewareTests.cs +++ b/test/Microsoft.AspNet.Security.Test/Cookies/CookieMiddlewareTests.cs @@ -18,8 +18,6 @@ using Microsoft.AspNet.TestHost; using Shouldly; using Xunit; -using Microsoft.Framework.OptionsModel; -using Microsoft.Framework.DependencyInjection; namespace Microsoft.AspNet.Security.Cookies { @@ -367,7 +365,7 @@ private static async Task GetAuthData(TestServer server, string url, s private static TestServer CreateServer(Action configureOptions, Func testpath = null) { - return TestServer.Create(app => + return TestServer.Create(TestServices.CreateTestServices(), app => { app.UseCookieAuthentication(configureOptions); app.Use(async (context, next) => diff --git a/test/Microsoft.AspNet.Security.Test/Facebook/FacebookMiddlewareTests.cs b/test/Microsoft.AspNet.Security.Test/Facebook/FacebookMiddlewareTests.cs index 6120b82c4..08c5e1ed4 100644 --- a/test/Microsoft.AspNet.Security.Test/Facebook/FacebookMiddlewareTests.cs +++ b/test/Microsoft.AspNet.Security.Test/Facebook/FacebookMiddlewareTests.cs @@ -107,7 +107,7 @@ public async Task ChallengeWillTriggerRedirection() private static TestServer CreateServer(Action configure, Func handler) { - return TestServer.Create(app => + return TestServer.Create(TestServices.CreateTestServices(), app => { if (configure != null) { diff --git a/test/Microsoft.AspNet.Security.Test/Google/GoogleMiddlewareTests.cs b/test/Microsoft.AspNet.Security.Test/Google/GoogleMiddlewareTests.cs index 3a1113d7f..b6945d4c5 100644 --- a/test/Microsoft.AspNet.Security.Test/Google/GoogleMiddlewareTests.cs +++ b/test/Microsoft.AspNet.Security.Test/Google/GoogleMiddlewareTests.cs @@ -463,7 +463,7 @@ private static async Task SendAsync(TestServer server, string uri, private static TestServer CreateServer(Action configureOptions, Func testpath = null) { - return TestServer.Create(app => + return TestServer.Create(TestServices.CreateTestServices(), app => { app.UseServices(services => { diff --git a/test/Microsoft.AspNet.Security.Test/MicrosoftAccount/MicrosoftAccountMiddlewareTests.cs b/test/Microsoft.AspNet.Security.Test/MicrosoftAccount/MicrosoftAccountMiddlewareTests.cs index d055df748..5b01da6c0 100644 --- a/test/Microsoft.AspNet.Security.Test/MicrosoftAccount/MicrosoftAccountMiddlewareTests.cs +++ b/test/Microsoft.AspNet.Security.Test/MicrosoftAccount/MicrosoftAccountMiddlewareTests.cs @@ -161,7 +161,7 @@ public async Task AuthenticatedEventCanGetRefreshToken() private static TestServer CreateServer(Action configureOptions, Func handler) { - return TestServer.Create(app => + return TestServer.Create(TestServices.CreateTestServices(), app => { app.UseServices(services => { diff --git a/test/Microsoft.AspNet.Security.Test/TestApplicationEnvironment.cs b/test/Microsoft.AspNet.Security.Test/TestApplicationEnvironment.cs new file mode 100644 index 000000000..01ef364c1 --- /dev/null +++ b/test/Microsoft.AspNet.Security.Test/TestApplicationEnvironment.cs @@ -0,0 +1,37 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Runtime.Versioning; +using Microsoft.Framework.Runtime; + +namespace Microsoft.AspNet.Security +{ + public class TestApplicationEnvironment : IApplicationEnvironment + { + public string ApplicationBasePath + { + get { return Environment.CurrentDirectory; } + } + + public string ApplicationName + { + get { return "Test App environment"; } + } + + public string Configuration + { + get { return "Test"; } + } + + public FrameworkName RuntimeFramework + { + get { return new FrameworkName(".NETFramework", new Version(4, 5)); } + } + + public string Version + { + get { return "1.0.0"; } + } + } +} \ No newline at end of file diff --git a/test/Microsoft.AspNet.Security.Test/TestServices.cs b/test/Microsoft.AspNet.Security.Test/TestServices.cs new file mode 100644 index 000000000..ea3b392ce --- /dev/null +++ b/test/Microsoft.AspNet.Security.Test/TestServices.cs @@ -0,0 +1,22 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using Microsoft.AspNet.Security.DataProtection; +using Microsoft.Framework.DependencyInjection; +using Microsoft.Framework.DependencyInjection.Fallback; +using Microsoft.Framework.Runtime; + +namespace Microsoft.AspNet.Security +{ + public static class TestServices + { + public static IServiceProvider CreateTestServices() + { + var collection = new ServiceCollection(); + collection.AddSingleton(); + collection.Add(DataProtectionServices.GetDefaultServices()); + return collection.BuildServiceProvider(); + } + } +} \ No newline at end of file diff --git a/test/Microsoft.AspNet.Security.Test/Twitter/TwitterMiddlewareTests.cs b/test/Microsoft.AspNet.Security.Test/Twitter/TwitterMiddlewareTests.cs index 5505f9754..ab24c0074 100644 --- a/test/Microsoft.AspNet.Security.Test/Twitter/TwitterMiddlewareTests.cs +++ b/test/Microsoft.AspNet.Security.Test/Twitter/TwitterMiddlewareTests.cs @@ -107,7 +107,7 @@ public async Task ChallengeWillTriggerRedirection() private static TestServer CreateServer(Action configure, Func handler) { - return TestServer.Create(app => + return TestServer.Create(TestServices.CreateTestServices(), app => { app.UseServices(services => { From 977a08ddca8698ea80b5e0b61ff35014357f3c05 Mon Sep 17 00:00:00 2001 From: Chris Ross Date: Tue, 18 Nov 2014 14:59:56 -0800 Subject: [PATCH 089/216] Add DataProtection to samples. --- samples/CookieSample/Startup.cs | 6 ++++++ samples/CookieSessionSample/Startup.cs | 6 ++++++ samples/SocialSample/Startup.cs | 8 +++----- 3 files changed, 15 insertions(+), 5 deletions(-) diff --git a/samples/CookieSample/Startup.cs b/samples/CookieSample/Startup.cs index cff673d75..aae3191ac 100644 --- a/samples/CookieSample/Startup.cs +++ b/samples/CookieSample/Startup.cs @@ -2,6 +2,7 @@ using Microsoft.AspNet.Builder; using Microsoft.AspNet.Http; using Microsoft.AspNet.Security.Cookies; +using Microsoft.AspNet.Security.DataProtection; namespace CookieSample { @@ -9,6 +10,11 @@ public class Startup { public void Configure(IApplicationBuilder app) { + app.UseServices(services => + { + services.Add(DataProtectionServices.GetDefaultServices()); + }); + app.UseCookieAuthentication(options => { }); diff --git a/samples/CookieSessionSample/Startup.cs b/samples/CookieSessionSample/Startup.cs index 2b6cfd846..72a5c1ff9 100644 --- a/samples/CookieSessionSample/Startup.cs +++ b/samples/CookieSessionSample/Startup.cs @@ -3,6 +3,7 @@ using Microsoft.AspNet.Builder; using Microsoft.AspNet.Http; using Microsoft.AspNet.Security.Cookies; +using Microsoft.AspNet.Security.DataProtection; namespace CookieSessionSample { @@ -10,6 +11,11 @@ public class Startup { public void Configure(IApplicationBuilder app) { + app.UseServices(services => + { + services.Add(DataProtectionServices.GetDefaultServices()); + }); + app.UseCookieAuthentication(options => { options.SessionStore = new MemoryCacheSessionStore(); diff --git a/samples/SocialSample/Startup.cs b/samples/SocialSample/Startup.cs index 162a1b553..f6070b9ff 100644 --- a/samples/SocialSample/Startup.cs +++ b/samples/SocialSample/Startup.cs @@ -1,5 +1,3 @@ -using System; -using System.Collections.Generic; using System.Net.Http; using System.Net.Http.Headers; using System.Security.Claims; @@ -8,13 +6,12 @@ using Microsoft.AspNet.Http.Security; using Microsoft.AspNet.Security; using Microsoft.AspNet.Security.Cookies; -using Microsoft.AspNet.Security.Facebook; +using Microsoft.AspNet.Security.DataProtection; using Microsoft.AspNet.Security.Google; using Microsoft.AspNet.Security.MicrosoftAccount; using Microsoft.AspNet.Security.OAuth; -using Microsoft.AspNet.Security.Twitter; -using Newtonsoft.Json.Linq; using Microsoft.Framework.DependencyInjection; +using Newtonsoft.Json.Linq; namespace CookieSample { @@ -26,6 +23,7 @@ public void Configure(IApplicationBuilder app) app.UseServices(services => { + services.Add(DataProtectionServices.GetDefaultServices()); services.Configure(options => { options.SignInAsAuthenticationType = CookieAuthenticationDefaults.AuthenticationType; From 5f06906087b71cf587dce0f4ef3e1a1f84d5348d Mon Sep 17 00:00:00 2001 From: Hao Kung Date: Thu, 20 Nov 2014 17:25:16 -0800 Subject: [PATCH 090/216] React to fallback changes --- .../Cookies/CookieMiddlewareTests.cs | 4 +++- .../Facebook/FacebookMiddlewareTests.cs | 8 +++---- .../Google/GoogleMiddlewareTests.cs | 3 ++- .../MicrosoftAccountMiddlewareTests.cs | 3 ++- .../TestServices.cs | 22 ------------------- .../Twitter/TwitterMiddlewareTests.cs | 4 +++- 6 files changed, 14 insertions(+), 30 deletions(-) delete mode 100644 test/Microsoft.AspNet.Security.Test/TestServices.cs diff --git a/test/Microsoft.AspNet.Security.Test/Cookies/CookieMiddlewareTests.cs b/test/Microsoft.AspNet.Security.Test/Cookies/CookieMiddlewareTests.cs index dbf470f83..a5ca8bcaf 100644 --- a/test/Microsoft.AspNet.Security.Test/Cookies/CookieMiddlewareTests.cs +++ b/test/Microsoft.AspNet.Security.Test/Cookies/CookieMiddlewareTests.cs @@ -15,6 +15,7 @@ using Microsoft.AspNet.Builder; using Microsoft.AspNet.Http; using Microsoft.AspNet.Http.Security; +using Microsoft.AspNet.Security.DataProtection; using Microsoft.AspNet.TestHost; using Shouldly; using Xunit; @@ -365,8 +366,9 @@ private static async Task GetAuthData(TestServer server, string url, s private static TestServer CreateServer(Action configureOptions, Func testpath = null) { - return TestServer.Create(TestServices.CreateTestServices(), app => + return TestServer.Create(app => { + app.UseServices(services => services.Add(DataProtectionServices.GetDefaultServices())); app.UseCookieAuthentication(configureOptions); app.Use(async (context, next) => { diff --git a/test/Microsoft.AspNet.Security.Test/Facebook/FacebookMiddlewareTests.cs b/test/Microsoft.AspNet.Security.Test/Facebook/FacebookMiddlewareTests.cs index 08c5e1ed4..1749a6ffe 100644 --- a/test/Microsoft.AspNet.Security.Test/Facebook/FacebookMiddlewareTests.cs +++ b/test/Microsoft.AspNet.Security.Test/Facebook/FacebookMiddlewareTests.cs @@ -9,11 +9,9 @@ using System.Threading.Tasks; using Microsoft.AspNet.Builder; using Microsoft.AspNet.Http; -using Microsoft.AspNet.Http.Security; -using Microsoft.AspNet.Security.Cookies; +using Microsoft.AspNet.Security.DataProtection; using Microsoft.AspNet.TestHost; using Microsoft.Framework.DependencyInjection; -using Microsoft.Framework.OptionsModel; using Shouldly; using Xunit; @@ -29,6 +27,7 @@ public async Task ChallengeWillTriggerApplyRedirectEvent() { app.UseServices(services => { + services.Add(DataProtectionServices.GetDefaultServices()); services.ConfigureFacebookAuthentication(options => { options.AppId = "Test App Id"; @@ -72,6 +71,7 @@ public async Task ChallengeWillTriggerRedirection() { app.UseServices(services => { + services.Add(DataProtectionServices.GetDefaultServices()); services.ConfigureFacebookAuthentication(options => { options.AppId = "Test App Id"; @@ -107,7 +107,7 @@ public async Task ChallengeWillTriggerRedirection() private static TestServer CreateServer(Action configure, Func handler) { - return TestServer.Create(TestServices.CreateTestServices(), app => + return TestServer.Create(app => { if (configure != null) { diff --git a/test/Microsoft.AspNet.Security.Test/Google/GoogleMiddlewareTests.cs b/test/Microsoft.AspNet.Security.Test/Google/GoogleMiddlewareTests.cs index b6945d4c5..e9169baf3 100644 --- a/test/Microsoft.AspNet.Security.Test/Google/GoogleMiddlewareTests.cs +++ b/test/Microsoft.AspNet.Security.Test/Google/GoogleMiddlewareTests.cs @@ -463,10 +463,11 @@ private static async Task SendAsync(TestServer server, string uri, private static TestServer CreateServer(Action configureOptions, Func testpath = null) { - return TestServer.Create(TestServices.CreateTestServices(), app => + return TestServer.Create(app => { app.UseServices(services => { + services.Add(DataProtectionServices.GetDefaultServices()); services.Configure(options => { options.SignInAsAuthenticationType = CookieAuthenticationType; diff --git a/test/Microsoft.AspNet.Security.Test/MicrosoftAccount/MicrosoftAccountMiddlewareTests.cs b/test/Microsoft.AspNet.Security.Test/MicrosoftAccount/MicrosoftAccountMiddlewareTests.cs index 5b01da6c0..6a5cb84f3 100644 --- a/test/Microsoft.AspNet.Security.Test/MicrosoftAccount/MicrosoftAccountMiddlewareTests.cs +++ b/test/Microsoft.AspNet.Security.Test/MicrosoftAccount/MicrosoftAccountMiddlewareTests.cs @@ -161,10 +161,11 @@ public async Task AuthenticatedEventCanGetRefreshToken() private static TestServer CreateServer(Action configureOptions, Func handler) { - return TestServer.Create(TestServices.CreateTestServices(), app => + return TestServer.Create(app => { app.UseServices(services => { + services.Add(DataProtectionServices.GetDefaultServices()); services.Configure(options => { options.SignInAsAuthenticationType = "External"; diff --git a/test/Microsoft.AspNet.Security.Test/TestServices.cs b/test/Microsoft.AspNet.Security.Test/TestServices.cs deleted file mode 100644 index ea3b392ce..000000000 --- a/test/Microsoft.AspNet.Security.Test/TestServices.cs +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System; -using Microsoft.AspNet.Security.DataProtection; -using Microsoft.Framework.DependencyInjection; -using Microsoft.Framework.DependencyInjection.Fallback; -using Microsoft.Framework.Runtime; - -namespace Microsoft.AspNet.Security -{ - public static class TestServices - { - public static IServiceProvider CreateTestServices() - { - var collection = new ServiceCollection(); - collection.AddSingleton(); - collection.Add(DataProtectionServices.GetDefaultServices()); - return collection.BuildServiceProvider(); - } - } -} \ No newline at end of file diff --git a/test/Microsoft.AspNet.Security.Test/Twitter/TwitterMiddlewareTests.cs b/test/Microsoft.AspNet.Security.Test/Twitter/TwitterMiddlewareTests.cs index ab24c0074..a1d6c095f 100644 --- a/test/Microsoft.AspNet.Security.Test/Twitter/TwitterMiddlewareTests.cs +++ b/test/Microsoft.AspNet.Security.Test/Twitter/TwitterMiddlewareTests.cs @@ -17,6 +17,7 @@ using Xunit; using Microsoft.Framework.OptionsModel; using Microsoft.Framework.DependencyInjection; +using Microsoft.AspNet.Security.DataProtection; namespace Microsoft.AspNet.Security.Twitter { @@ -107,10 +108,11 @@ public async Task ChallengeWillTriggerRedirection() private static TestServer CreateServer(Action configure, Func handler) { - return TestServer.Create(TestServices.CreateTestServices(), app => + return TestServer.Create(app => { app.UseServices(services => { + services.Add(DataProtectionServices.GetDefaultServices()); services.Configure(options => { options.SignInAsAuthenticationType = "External"; From 240ed82b31493f4ccf78e4327bdc5d7a557a43e9 Mon Sep 17 00:00:00 2001 From: Hao Kung Date: Mon, 24 Nov 2014 16:32:33 -0800 Subject: [PATCH 091/216] React to AddDataProtection change --- samples/CookieSample/Startup.cs | 4 ++-- samples/CookieSessionSample/Startup.cs | 4 ++-- samples/SocialSample/Startup.cs | 2 +- .../Cookies/CookieMiddlewareTests.cs | 4 ++-- .../Facebook/FacebookMiddlewareTests.cs | 4 ++-- .../Google/GoogleMiddlewareTests.cs | 2 +- .../MicrosoftAccount/MicrosoftAccountMiddlewareTests.cs | 2 +- .../Twitter/TwitterMiddlewareTests.cs | 2 +- 8 files changed, 12 insertions(+), 12 deletions(-) diff --git a/samples/CookieSample/Startup.cs b/samples/CookieSample/Startup.cs index aae3191ac..7e481c220 100644 --- a/samples/CookieSample/Startup.cs +++ b/samples/CookieSample/Startup.cs @@ -2,7 +2,7 @@ using Microsoft.AspNet.Builder; using Microsoft.AspNet.Http; using Microsoft.AspNet.Security.Cookies; -using Microsoft.AspNet.Security.DataProtection; +using Microsoft.Framework.DependencyInjection; namespace CookieSample { @@ -12,7 +12,7 @@ public void Configure(IApplicationBuilder app) { app.UseServices(services => { - services.Add(DataProtectionServices.GetDefaultServices()); + services.AddDataProtection(); }); app.UseCookieAuthentication(options => diff --git a/samples/CookieSessionSample/Startup.cs b/samples/CookieSessionSample/Startup.cs index 72a5c1ff9..ff72c0469 100644 --- a/samples/CookieSessionSample/Startup.cs +++ b/samples/CookieSessionSample/Startup.cs @@ -3,7 +3,7 @@ using Microsoft.AspNet.Builder; using Microsoft.AspNet.Http; using Microsoft.AspNet.Security.Cookies; -using Microsoft.AspNet.Security.DataProtection; +using Microsoft.Framework.DependencyInjection; namespace CookieSessionSample { @@ -13,7 +13,7 @@ public void Configure(IApplicationBuilder app) { app.UseServices(services => { - services.Add(DataProtectionServices.GetDefaultServices()); + services.AddDataProtection(); }); app.UseCookieAuthentication(options => diff --git a/samples/SocialSample/Startup.cs b/samples/SocialSample/Startup.cs index f6070b9ff..6e7b5c632 100644 --- a/samples/SocialSample/Startup.cs +++ b/samples/SocialSample/Startup.cs @@ -23,7 +23,7 @@ public void Configure(IApplicationBuilder app) app.UseServices(services => { - services.Add(DataProtectionServices.GetDefaultServices()); + services.AddDataProtection(); services.Configure(options => { options.SignInAsAuthenticationType = CookieAuthenticationDefaults.AuthenticationType; diff --git a/test/Microsoft.AspNet.Security.Test/Cookies/CookieMiddlewareTests.cs b/test/Microsoft.AspNet.Security.Test/Cookies/CookieMiddlewareTests.cs index a5ca8bcaf..b103a7c75 100644 --- a/test/Microsoft.AspNet.Security.Test/Cookies/CookieMiddlewareTests.cs +++ b/test/Microsoft.AspNet.Security.Test/Cookies/CookieMiddlewareTests.cs @@ -15,8 +15,8 @@ using Microsoft.AspNet.Builder; using Microsoft.AspNet.Http; using Microsoft.AspNet.Http.Security; -using Microsoft.AspNet.Security.DataProtection; using Microsoft.AspNet.TestHost; +using Microsoft.Framework.DependencyInjection; using Shouldly; using Xunit; @@ -368,7 +368,7 @@ private static TestServer CreateServer(Action confi { return TestServer.Create(app => { - app.UseServices(services => services.Add(DataProtectionServices.GetDefaultServices())); + app.UseServices(services => services.AddDataProtection()); app.UseCookieAuthentication(configureOptions); app.Use(async (context, next) => { diff --git a/test/Microsoft.AspNet.Security.Test/Facebook/FacebookMiddlewareTests.cs b/test/Microsoft.AspNet.Security.Test/Facebook/FacebookMiddlewareTests.cs index 1749a6ffe..7377d1a1f 100644 --- a/test/Microsoft.AspNet.Security.Test/Facebook/FacebookMiddlewareTests.cs +++ b/test/Microsoft.AspNet.Security.Test/Facebook/FacebookMiddlewareTests.cs @@ -27,7 +27,7 @@ public async Task ChallengeWillTriggerApplyRedirectEvent() { app.UseServices(services => { - services.Add(DataProtectionServices.GetDefaultServices()); + services.AddDataProtection(); services.ConfigureFacebookAuthentication(options => { options.AppId = "Test App Id"; @@ -71,7 +71,7 @@ public async Task ChallengeWillTriggerRedirection() { app.UseServices(services => { - services.Add(DataProtectionServices.GetDefaultServices()); + services.AddDataProtection(); services.ConfigureFacebookAuthentication(options => { options.AppId = "Test App Id"; diff --git a/test/Microsoft.AspNet.Security.Test/Google/GoogleMiddlewareTests.cs b/test/Microsoft.AspNet.Security.Test/Google/GoogleMiddlewareTests.cs index e9169baf3..5b6046aa9 100644 --- a/test/Microsoft.AspNet.Security.Test/Google/GoogleMiddlewareTests.cs +++ b/test/Microsoft.AspNet.Security.Test/Google/GoogleMiddlewareTests.cs @@ -467,7 +467,7 @@ private static TestServer CreateServer(Action confi { app.UseServices(services => { - services.Add(DataProtectionServices.GetDefaultServices()); + services.AddDataProtection(); services.Configure(options => { options.SignInAsAuthenticationType = CookieAuthenticationType; diff --git a/test/Microsoft.AspNet.Security.Test/MicrosoftAccount/MicrosoftAccountMiddlewareTests.cs b/test/Microsoft.AspNet.Security.Test/MicrosoftAccount/MicrosoftAccountMiddlewareTests.cs index 6a5cb84f3..8fd06d8c9 100644 --- a/test/Microsoft.AspNet.Security.Test/MicrosoftAccount/MicrosoftAccountMiddlewareTests.cs +++ b/test/Microsoft.AspNet.Security.Test/MicrosoftAccount/MicrosoftAccountMiddlewareTests.cs @@ -165,7 +165,7 @@ private static TestServer CreateServer(Action { - services.Add(DataProtectionServices.GetDefaultServices()); + services.AddDataProtection(); services.Configure(options => { options.SignInAsAuthenticationType = "External"; diff --git a/test/Microsoft.AspNet.Security.Test/Twitter/TwitterMiddlewareTests.cs b/test/Microsoft.AspNet.Security.Test/Twitter/TwitterMiddlewareTests.cs index a1d6c095f..36a829404 100644 --- a/test/Microsoft.AspNet.Security.Test/Twitter/TwitterMiddlewareTests.cs +++ b/test/Microsoft.AspNet.Security.Test/Twitter/TwitterMiddlewareTests.cs @@ -112,7 +112,7 @@ private static TestServer CreateServer(Action configure, Fu { app.UseServices(services => { - services.Add(DataProtectionServices.GetDefaultServices()); + services.AddDataProtection(); services.Configure(options => { options.SignInAsAuthenticationType = "External"; From 0a719735135c0e49ec024d377fc086e628f635bd Mon Sep 17 00:00:00 2001 From: Victor Hurdugaci Date: Tue, 25 Nov 2014 11:03:55 -0800 Subject: [PATCH 092/216] Add schema version to kproj files --- samples/CookieSample/CookieSample.kproj | 8 +++++--- samples/CookieSessionSample/CookieSessionSample.kproj | 8 +++++--- samples/SocialSample/SocialSample.kproj | 10 +++++----- .../Microsoft.AspNet.Security.Cookies.kproj | 3 +++ .../Microsoft.AspNet.Security.Facebook.kproj | 3 +++ .../Microsoft.AspNet.Security.Google.kproj | 3 +++ .../Microsoft.AspNet.Security.MicrosoftAccount.kproj | 3 +++ .../Microsoft.AspNet.Security.OAuth.kproj | 3 +++ .../Microsoft.AspNet.Security.Twitter.kproj | 3 +++ .../Microsoft.AspNet.Security.kproj | 3 +++ .../Microsoft.AspNet.Security.Tests.kproj | 3 +++ 11 files changed, 39 insertions(+), 11 deletions(-) diff --git a/samples/CookieSample/CookieSample.kproj b/samples/CookieSample/CookieSample.kproj index 3afd3733f..0cc892155 100644 --- a/samples/CookieSample/CookieSample.kproj +++ b/samples/CookieSample/CookieSample.kproj @@ -1,9 +1,8 @@ - + 14.0 $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) - 54539 @@ -11,5 +10,8 @@ ..\..\artifacts\obj\$(MSBuildProjectName) ..\..\artifacts\bin\$(MSBuildProjectName)\ + + 2.0 + - \ No newline at end of file + diff --git a/samples/CookieSessionSample/CookieSessionSample.kproj b/samples/CookieSessionSample/CookieSessionSample.kproj index 954c473e9..3dde446f7 100644 --- a/samples/CookieSessionSample/CookieSessionSample.kproj +++ b/samples/CookieSessionSample/CookieSessionSample.kproj @@ -1,9 +1,8 @@ - + 14.0 $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) - 54541 @@ -11,5 +10,8 @@ ..\..\artifacts\obj\$(MSBuildProjectName) ..\..\artifacts\bin\$(MSBuildProjectName)\ + + 2.0 + - \ No newline at end of file + diff --git a/samples/SocialSample/SocialSample.kproj b/samples/SocialSample/SocialSample.kproj index 1fbca3ad0..640b2404b 100644 --- a/samples/SocialSample/SocialSample.kproj +++ b/samples/SocialSample/SocialSample.kproj @@ -1,11 +1,8 @@ - + 14.0 $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) - 54540 - - @@ -13,5 +10,8 @@ ..\..\artifacts\obj\$(MSBuildProjectName) ..\..\artifacts\bin\$(MSBuildProjectName)\ + + 2.0 + - \ No newline at end of file + diff --git a/src/Microsoft.AspNet.Security.Cookies/Microsoft.AspNet.Security.Cookies.kproj b/src/Microsoft.AspNet.Security.Cookies/Microsoft.AspNet.Security.Cookies.kproj index 6f2989244..31c09ed57 100644 --- a/src/Microsoft.AspNet.Security.Cookies/Microsoft.AspNet.Security.Cookies.kproj +++ b/src/Microsoft.AspNet.Security.Cookies/Microsoft.AspNet.Security.Cookies.kproj @@ -10,5 +10,8 @@ ..\..\artifacts\obj\$(MSBuildProjectName) ..\..\artifacts\bin\$(MSBuildProjectName)\ + + 2.0 + diff --git a/src/Microsoft.AspNet.Security.Facebook/Microsoft.AspNet.Security.Facebook.kproj b/src/Microsoft.AspNet.Security.Facebook/Microsoft.AspNet.Security.Facebook.kproj index b4d160363..8a4224835 100644 --- a/src/Microsoft.AspNet.Security.Facebook/Microsoft.AspNet.Security.Facebook.kproj +++ b/src/Microsoft.AspNet.Security.Facebook/Microsoft.AspNet.Security.Facebook.kproj @@ -10,5 +10,8 @@ ..\..\artifacts\obj\$(MSBuildProjectName) ..\..\artifacts\bin\$(MSBuildProjectName)\ + + 2.0 + diff --git a/src/Microsoft.AspNet.Security.Google/Microsoft.AspNet.Security.Google.kproj b/src/Microsoft.AspNet.Security.Google/Microsoft.AspNet.Security.Google.kproj index 93e3716ce..32f8d92b2 100644 --- a/src/Microsoft.AspNet.Security.Google/Microsoft.AspNet.Security.Google.kproj +++ b/src/Microsoft.AspNet.Security.Google/Microsoft.AspNet.Security.Google.kproj @@ -10,5 +10,8 @@ ..\..\artifacts\obj\$(MSBuildProjectName) ..\..\artifacts\bin\$(MSBuildProjectName)\ + + 2.0 + diff --git a/src/Microsoft.AspNet.Security.MicrosoftAccount/Microsoft.AspNet.Security.MicrosoftAccount.kproj b/src/Microsoft.AspNet.Security.MicrosoftAccount/Microsoft.AspNet.Security.MicrosoftAccount.kproj index 439829d54..88701bdb3 100644 --- a/src/Microsoft.AspNet.Security.MicrosoftAccount/Microsoft.AspNet.Security.MicrosoftAccount.kproj +++ b/src/Microsoft.AspNet.Security.MicrosoftAccount/Microsoft.AspNet.Security.MicrosoftAccount.kproj @@ -10,5 +10,8 @@ ..\..\artifacts\obj\$(MSBuildProjectName) ..\..\artifacts\bin\$(MSBuildProjectName)\ + + 2.0 + diff --git a/src/Microsoft.AspNet.Security.OAuth/Microsoft.AspNet.Security.OAuth.kproj b/src/Microsoft.AspNet.Security.OAuth/Microsoft.AspNet.Security.OAuth.kproj index 32d728261..abcb5afde 100644 --- a/src/Microsoft.AspNet.Security.OAuth/Microsoft.AspNet.Security.OAuth.kproj +++ b/src/Microsoft.AspNet.Security.OAuth/Microsoft.AspNet.Security.OAuth.kproj @@ -10,5 +10,8 @@ ..\..\artifacts\obj\$(MSBuildProjectName) ..\..\artifacts\bin\$(MSBuildProjectName)\ + + 2.0 + diff --git a/src/Microsoft.AspNet.Security.Twitter/Microsoft.AspNet.Security.Twitter.kproj b/src/Microsoft.AspNet.Security.Twitter/Microsoft.AspNet.Security.Twitter.kproj index 980720b3f..e073a505c 100644 --- a/src/Microsoft.AspNet.Security.Twitter/Microsoft.AspNet.Security.Twitter.kproj +++ b/src/Microsoft.AspNet.Security.Twitter/Microsoft.AspNet.Security.Twitter.kproj @@ -10,5 +10,8 @@ ..\..\artifacts\obj\$(MSBuildProjectName) ..\..\artifacts\bin\$(MSBuildProjectName)\ + + 2.0 + diff --git a/src/Microsoft.AspNet.Security/Microsoft.AspNet.Security.kproj b/src/Microsoft.AspNet.Security/Microsoft.AspNet.Security.kproj index 9a1e95727..6262851a7 100644 --- a/src/Microsoft.AspNet.Security/Microsoft.AspNet.Security.kproj +++ b/src/Microsoft.AspNet.Security/Microsoft.AspNet.Security.kproj @@ -10,5 +10,8 @@ ..\..\artifacts\obj\$(MSBuildProjectName) ..\..\artifacts\bin\$(MSBuildProjectName)\ + + 2.0 + diff --git a/test/Microsoft.AspNet.Security.Test/Microsoft.AspNet.Security.Tests.kproj b/test/Microsoft.AspNet.Security.Test/Microsoft.AspNet.Security.Tests.kproj index a989127e4..77ea1e71c 100644 --- a/test/Microsoft.AspNet.Security.Test/Microsoft.AspNet.Security.Tests.kproj +++ b/test/Microsoft.AspNet.Security.Test/Microsoft.AspNet.Security.Tests.kproj @@ -10,5 +10,8 @@ ..\..\artifacts\obj\$(MSBuildProjectName) ..\..\artifacts\bin\$(MSBuildProjectName)\ + + 2.0 + From 184233af61978c0769714e804c15154551a07287 Mon Sep 17 00:00:00 2001 From: Chris Ross Date: Fri, 5 Dec 2014 10:40:46 -0800 Subject: [PATCH 093/216] #79: Remove cookie compression. --- .../CookieAuthenticationMiddleware.cs | 2 +- .../project.json | 1 - .../Serializer/TicketSerializer.cs | 30 +++---------------- src/Microsoft.AspNet.Security/project.json | 6 +--- 4 files changed, 6 insertions(+), 33 deletions(-) diff --git a/src/Microsoft.AspNet.Security.Cookies/CookieAuthenticationMiddleware.cs b/src/Microsoft.AspNet.Security.Cookies/CookieAuthenticationMiddleware.cs index 482f43b37..8f1cc4b54 100644 --- a/src/Microsoft.AspNet.Security.Cookies/CookieAuthenticationMiddleware.cs +++ b/src/Microsoft.AspNet.Security.Cookies/CookieAuthenticationMiddleware.cs @@ -36,7 +36,7 @@ public CookieAuthenticationMiddleware(RequestDelegate next, if (Options.TicketDataFormat == null) { IDataProtector dataProtector = dataProtectionProvider.CreateDataProtector( - typeof(CookieAuthenticationMiddleware).FullName, Options.AuthenticationType, "v1"); + typeof(CookieAuthenticationMiddleware).FullName, Options.AuthenticationType, "v2"); Options.TicketDataFormat = new TicketDataFormat(dataProtector); } if (Options.CookieManager == null) diff --git a/src/Microsoft.AspNet.Security.OAuth/project.json b/src/Microsoft.AspNet.Security.OAuth/project.json index bae60ec0b..0c44ae0cf 100644 --- a/src/Microsoft.AspNet.Security.OAuth/project.json +++ b/src/Microsoft.AspNet.Security.OAuth/project.json @@ -26,7 +26,6 @@ "System.Dynamic.Runtime": "4.0.0-beta-*", "System.Globalization": "4.0.10-beta-*", "System.IO": "4.0.10-beta-*", - "System.IO.Compression": "4.0.0-beta-*", "System.Linq": "4.0.0-beta-*", "System.Net.Http.WinHttpHandler": "4.0.0-beta-*", "System.ObjectModel": "4.0.10-beta-*", diff --git a/src/Microsoft.AspNet.Security/DataHandler/Serializer/TicketSerializer.cs b/src/Microsoft.AspNet.Security/DataHandler/Serializer/TicketSerializer.cs index 7bfa9a1e6..9fe982ee8 100644 --- a/src/Microsoft.AspNet.Security/DataHandler/Serializer/TicketSerializer.cs +++ b/src/Microsoft.AspNet.Security/DataHandler/Serializer/TicketSerializer.cs @@ -1,11 +1,8 @@ // Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - using System; -using System.Collections.Generic; using System.IO; -using System.IO.Compression; using System.Linq; using System.Security.Claims; @@ -13,46 +10,27 @@ namespace Microsoft.AspNet.Security.DataHandler.Serializer { public class TicketSerializer : IDataSerializer { - private static readonly bool IsMono = Type.GetType("Mono.Runtime") != null; private const int FormatVersion = 2; - [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2202:Do not dispose objects multiple times", Justification = "Dispose is idempotent")] public virtual byte[] Serialize(AuthenticationTicket model) { using (var memory = new MemoryStream()) { - GZipStream compression; - if (IsMono) - { - // The other constructor is not currently supported on Mono. - compression = new GZipStream(memory, CompressionMode.Compress); - } - else - { - compression = new GZipStream(memory, CompressionLevel.Optimal); - } - using (compression) + using (var writer = new BinaryWriter(memory)) { - using (var writer = new BinaryWriter(compression)) - { - Write(writer, model); - } + Write(writer, model); } return memory.ToArray(); } } - [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2202:Do not dispose objects multiple times", Justification = "Dispose is idempotent")] public virtual AuthenticationTicket Deserialize(byte[] data) { using (var memory = new MemoryStream(data)) { - using (var compression = new GZipStream(memory, CompressionMode.Decompress)) + using (var reader = new BinaryReader(memory)) { - using (var reader = new BinaryReader(compression)) - { - return Read(reader); - } + return Read(reader); } } } diff --git a/src/Microsoft.AspNet.Security/project.json b/src/Microsoft.AspNet.Security/project.json index 5ffa51a5c..cac89fbad 100644 --- a/src/Microsoft.AspNet.Security/project.json +++ b/src/Microsoft.AspNet.Security/project.json @@ -10,10 +10,6 @@ }, "frameworks": { "aspnet50": { }, - "aspnetcore50": { - "dependencies": { - "System.IO.Compression": "4.0.0-beta-*" - } - } + "aspnetcore50": { } } } From 23ce588f7bf7d6131c1cd1999e00847b46f4f91e Mon Sep 17 00:00:00 2001 From: Suhas Joshi Date: Mon, 8 Dec 2014 15:15:31 -0800 Subject: [PATCH 094/216] Updating to release NuGet.config --- NuGet.Config | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NuGet.Config b/NuGet.Config index f41e9c631..2d3b0cb85 100644 --- a/NuGet.Config +++ b/NuGet.Config @@ -1,7 +1,7 @@  - + From 915d3a6b16f72a354e8169c335c0a1e37faa768e Mon Sep 17 00:00:00 2001 From: Suhas Joshi Date: Mon, 8 Dec 2014 15:24:57 -0800 Subject: [PATCH 095/216] Updating to dev NuGet.config --- NuGet.Config | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NuGet.Config b/NuGet.Config index 2d3b0cb85..f41e9c631 100644 --- a/NuGet.Config +++ b/NuGet.Config @@ -1,7 +1,7 @@  - + From 20f21aa57f0c2141a4bed09db6e1ae403873beb3 Mon Sep 17 00:00:00 2001 From: Pranav K Date: Mon, 15 Dec 2014 15:04:48 -0800 Subject: [PATCH 096/216] Removing transitive dependencies from Microsoft.AspNet.Security.OAuth --- .../project.json | 7 ++++- .../project.json | 29 ++----------------- 2 files changed, 8 insertions(+), 28 deletions(-) diff --git a/src/Microsoft.AspNet.Security.MicrosoftAccount/project.json b/src/Microsoft.AspNet.Security.MicrosoftAccount/project.json index 5d7e26136..358d4515b 100644 --- a/src/Microsoft.AspNet.Security.MicrosoftAccount/project.json +++ b/src/Microsoft.AspNet.Security.MicrosoftAccount/project.json @@ -6,6 +6,11 @@ }, "frameworks": { "aspnet50": {}, - "aspnetcore50": {} + "aspnetcore50": { + "dependencies": { + "System.Dynamic.Runtime": "4.0.0-beta-*", + "System.ObjectModel": "4.0.0-beta-*" + } + } } } diff --git a/src/Microsoft.AspNet.Security.OAuth/project.json b/src/Microsoft.AspNet.Security.OAuth/project.json index 0c44ae0cf..6a2eed249 100644 --- a/src/Microsoft.AspNet.Security.OAuth/project.json +++ b/src/Microsoft.AspNet.Security.OAuth/project.json @@ -2,12 +2,8 @@ "version": "1.0.0-*", "description": "ASP.NET 5 middleware that enables an application to support any standard OAuth 2.0 authentication workflow.", "dependencies": { - "Microsoft.AspNet.Http.Extensions": "1.0.0-*", "Microsoft.AspNet.Security": "1.0.0-*", - "Microsoft.AspNet.Security.DataProtection": "1.0.0-*", - "Microsoft.AspNet.WebUtilities": "1.0.0-*", - "Microsoft.Framework.Logging": "1.0.0-*", - "Newtonsoft.Json": "6.0.6" + "Microsoft.AspNet.Security.DataProtection": "1.0.0-*" }, "frameworks": { "aspnet50": { @@ -18,28 +14,7 @@ }, "aspnetcore50": { "dependencies": { - "System.Collections": "4.0.10-beta-*", - "System.ComponentModel": "4.0.0-beta-*", - "System.Console": "4.0.0-beta-*", - "System.Diagnostics.Debug": "4.0.10-beta-*", - "System.Diagnostics.Tools": "4.0.0-beta-*", - "System.Dynamic.Runtime": "4.0.0-beta-*", - "System.Globalization": "4.0.10-beta-*", - "System.IO": "4.0.10-beta-*", - "System.Linq": "4.0.0-beta-*", - "System.Net.Http.WinHttpHandler": "4.0.0-beta-*", - "System.ObjectModel": "4.0.10-beta-*", - "System.Reflection": "4.0.10-beta-*", - "System.Resources.ResourceManager": "4.0.0-beta-*", - "System.Runtime": "4.0.20-beta-*", - "System.Runtime.Extensions": "4.0.10-beta-*", - "System.Runtime.InteropServices": "4.0.20-beta-*", - "System.Security.Claims": "4.0.0-beta-*", - "System.Security.Cryptography.Hashing.Algorithms": "4.0.0-beta-*", - "System.Security.Principal": "4.0.0-beta-*", - "System.Threading": "4.0.0-beta-*", - "System.Threading.Tasks": "4.0.10-beta-*", - "System.Net.Http": "4.0.0-beta-*" + "System.Net.Http.WinHttpHandler": "4.0.0-beta-*" } } } From fcf2f93aa3d811c2fed8b6e73fb0edfd376eae25 Mon Sep 17 00:00:00 2001 From: Pranav K Date: Mon, 15 Dec 2014 16:50:13 -0800 Subject: [PATCH 097/216] Updating System.ObjectModel version that was copied incorrectly --- src/Microsoft.AspNet.Security.MicrosoftAccount/project.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Microsoft.AspNet.Security.MicrosoftAccount/project.json b/src/Microsoft.AspNet.Security.MicrosoftAccount/project.json index 358d4515b..530d34c57 100644 --- a/src/Microsoft.AspNet.Security.MicrosoftAccount/project.json +++ b/src/Microsoft.AspNet.Security.MicrosoftAccount/project.json @@ -9,7 +9,7 @@ "aspnetcore50": { "dependencies": { "System.Dynamic.Runtime": "4.0.0-beta-*", - "System.ObjectModel": "4.0.0-beta-*" + "System.ObjectModel": "4.0.10-beta-*" } } } From 2d2eedf89e0524ea255a4e68881dcfe43c764687 Mon Sep 17 00:00:00 2001 From: Brennan Date: Mon, 15 Dec 2014 14:43:54 -0800 Subject: [PATCH 098/216] Update tests to use official xunit --- test/Microsoft.AspNet.Security.Test/project.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/Microsoft.AspNet.Security.Test/project.json b/test/Microsoft.AspNet.Security.Test/project.json index affdcafeb..305fe5528 100644 --- a/test/Microsoft.AspNet.Security.Test/project.json +++ b/test/Microsoft.AspNet.Security.Test/project.json @@ -10,10 +10,10 @@ "Microsoft.AspNet.Security.Twitter": "1.0.0-*", "Microsoft.AspNet.TestHost": "1.0.0-*", "Moq": "4.2.1312.1622", - "Xunit.KRunner": "1.0.0-*" + "xunit.runner.kre": "1.0.0-*" }, "commands": { - "test": "Xunit.KRunner" + "test": "xunit.runner.kre" }, "frameworks": { "aspnet50": { From 8b7d33baaf3ee2a99ca27ca91a4068e78c48cc66 Mon Sep 17 00:00:00 2001 From: Chris Ross Date: Thu, 18 Dec 2014 14:41:16 -0800 Subject: [PATCH 099/216] #63 - Use the PathBase in the Cookie path by default. --- .../CookieAuthenticationHandler.cs | 2 +- .../CookieAuthenticationOptions.cs | 1 - .../Cookies/CookieMiddlewareTests.cs | 49 ++++++++++++++----- 3 files changed, 37 insertions(+), 15 deletions(-) diff --git a/src/Microsoft.AspNet.Security.Cookies/CookieAuthenticationHandler.cs b/src/Microsoft.AspNet.Security.Cookies/CookieAuthenticationHandler.cs index 63c524afa..e29023257 100644 --- a/src/Microsoft.AspNet.Security.Cookies/CookieAuthenticationHandler.cs +++ b/src/Microsoft.AspNet.Security.Cookies/CookieAuthenticationHandler.cs @@ -146,7 +146,7 @@ protected override async Task ApplyResponseGrantAsync() { Domain = Options.CookieDomain, HttpOnly = Options.CookieHttpOnly, - Path = Options.CookiePath ?? "/", + Path = Options.CookiePath ?? (RequestPathBase.HasValue ? RequestPathBase.ToString() : "/"), }; if (Options.CookieSecure == CookieSecureOption.SameAsRequest) { diff --git a/src/Microsoft.AspNet.Security.Cookies/CookieAuthenticationOptions.cs b/src/Microsoft.AspNet.Security.Cookies/CookieAuthenticationOptions.cs index 121ff409b..ec6e10206 100644 --- a/src/Microsoft.AspNet.Security.Cookies/CookieAuthenticationOptions.cs +++ b/src/Microsoft.AspNet.Security.Cookies/CookieAuthenticationOptions.cs @@ -24,7 +24,6 @@ public CookieAuthenticationOptions() { AuthenticationType = CookieAuthenticationDefaults.AuthenticationType; ReturnUrlParameter = CookieAuthenticationDefaults.ReturnUrlParameter; - CookiePath = "/"; ExpireTimeSpan = TimeSpan.FromDays(14); SlidingExpiration = true; CookieHttpOnly = true; diff --git a/test/Microsoft.AspNet.Security.Test/Cookies/CookieMiddlewareTests.cs b/test/Microsoft.AspNet.Security.Test/Cookies/CookieMiddlewareTests.cs index b103a7c75..c66d571b2 100644 --- a/test/Microsoft.AspNet.Security.Test/Cookies/CookieMiddlewareTests.cs +++ b/test/Microsoft.AspNet.Security.Test/Cookies/CookieMiddlewareTests.cs @@ -137,29 +137,31 @@ public async Task CookieOptionsAlterSetCookieHeader() options.CookieDomain = "another.com"; options.CookieSecure = CookieSecureOption.Always; options.CookieHttpOnly = true; - }, SignInAsAlice); + }, SignInAsAlice, new Uri("http://example.com/base")); + + Transaction transaction1 = await SendAsync(server1, "http://example.com/base/testpath"); - Transaction transaction1 = await SendAsync(server1, "http://example.com/testpath"); + string setCookie1 = transaction1.SetCookie; + + setCookie1.ShouldContain("TestCookie="); + setCookie1.ShouldContain(" path=/foo"); + setCookie1.ShouldContain(" domain=another.com"); + setCookie1.ShouldContain(" secure"); + setCookie1.ShouldContain(" HttpOnly"); TestServer server2 = CreateServer(options => { options.CookieName = "SecondCookie"; options.CookieSecure = CookieSecureOption.Never; options.CookieHttpOnly = false; - }, SignInAsAlice); + }, SignInAsAlice, new Uri("http://example.com/base")); - Transaction transaction2 = await SendAsync(server2, "http://example.com/testpath"); + Transaction transaction2 = await SendAsync(server2, "http://example.com/base/testpath"); - string setCookie1 = transaction1.SetCookie; string setCookie2 = transaction2.SetCookie; - setCookie1.ShouldContain("TestCookie="); - setCookie1.ShouldContain(" path=/foo"); - setCookie1.ShouldContain(" domain=another.com"); - setCookie1.ShouldContain(" secure"); - setCookie1.ShouldContain(" HttpOnly"); - setCookie2.ShouldContain("SecondCookie="); + setCookie2.ShouldContain(" path=/base"); setCookie2.ShouldNotContain(" domain="); setCookie2.ShouldNotContain(" secure"); setCookie2.ShouldNotContain(" HttpOnly"); @@ -343,6 +345,25 @@ public async Task AjaxRedirectsAsExtraHeaderOnTwoHundred() responded.Single().ShouldContain("\"location\""); } + [Fact] + public async Task CookieUsesPathBaseByDefault() + { + var clock = new TestClock(); + TestServer server = CreateServer(options => + { + }, + context => + { + Assert.Equal(new PathString("/base"), context.Request.PathBase); + context.Response.SignIn(new ClaimsIdentity(new GenericIdentity("Alice", "Cookies"))); + return Task.FromResult(null); + }, + new Uri("http://example.com/base")); + + Transaction transaction1 = await SendAsync(server, "http://example.com/base/testpath"); + Assert.True(transaction1.SetCookie.Contains("path=/base")); + } + private static string FindClaimValue(Transaction transaction, string claimType) { XElement claim = transaction.ResponseElement.Elements("claim").SingleOrDefault(elt => elt.Attribute("type").Value == claimType); @@ -364,9 +385,9 @@ private static async Task GetAuthData(TestServer server, string url, s return me; } - private static TestServer CreateServer(Action configureOptions, Func testpath = null) + private static TestServer CreateServer(Action configureOptions, Func testpath = null, Uri baseAddress = null) { - return TestServer.Create(app => + var server = TestServer.Create(app => { app.UseServices(services => services.AddDataProtection()); app.UseCookieAuthentication(configureOptions); @@ -406,6 +427,8 @@ private static TestServer CreateServer(Action confi } }); }); + server.BaseAddress = baseAddress; + return server; } private static void Describe(HttpResponse res, AuthenticationResult result) From fec32f6746df5f01e650deb468686f184a59cf95 Mon Sep 17 00:00:00 2001 From: Chris Ross Date: Thu, 20 Nov 2014 16:14:10 -0800 Subject: [PATCH 100/216] #82 - Improve error handling mechanics. --- .../Infrastructure/AuthenticationHandler.cs | 79 +++++++++++++++---- .../AuthenticationMiddleware.cs | 20 ++++- 2 files changed, 81 insertions(+), 18 deletions(-) diff --git a/src/Microsoft.AspNet.Security/Infrastructure/AuthenticationHandler.cs b/src/Microsoft.AspNet.Security/Infrastructure/AuthenticationHandler.cs index a5fd9876c..2c9691c48 100644 --- a/src/Microsoft.AspNet.Security/Infrastructure/AuthenticationHandler.cs +++ b/src/Microsoft.AspNet.Security/Infrastructure/AuthenticationHandler.cs @@ -60,6 +60,8 @@ internal AuthenticationOptions BaseOptions public IAuthenticationHandler PriorHandler { get; set; } + public bool Faulted { get; set; } + protected async Task BaseInitializeAsync(AuthenticationOptions options, HttpContext context) { _baseOptions = options; @@ -94,12 +96,29 @@ protected virtual Task InitializeCoreAsync() } /// - /// Called once per request after Initialize and Invoke. + /// Called once per request after Initialize and Invoke. /// /// async completion internal async Task TeardownAsync() { - await ApplyResponseAsync(); + try + { + await ApplyResponseAsync(); + } + catch (Exception) + { + try + { + await TeardownCoreAsync(); + } + catch (Exception) + { + // Don't mask the original exception + } + UnregisterAuthenticationHandler(); + throw; + } + await TeardownCoreAsync(); UnregisterAuthenticationHandler(); } @@ -217,15 +236,29 @@ protected virtual Task AuthenticateCoreAsync() private void ApplyResponse() { - LazyInitializer.EnsureInitialized( - ref _applyResponse, - ref _applyResponseInitialized, - ref _applyResponseSyncLock, - () => + // If ApplyResponse already failed in the OnSendingHeaderCallback or TeardownAsync code path then a + // failed task is cached. If called again the same error will be re-thrown. This breaks error handling + // scenarios like the ability to display the error page or re-execute the request. + try + { + if (!Faulted) { - ApplyResponseCore(); - return Task.FromResult(0); - }).GetAwaiter().GetResult(); // Block if the async version is in progress. + LazyInitializer.EnsureInitialized( + ref _applyResponse, + ref _applyResponseInitialized, + ref _applyResponseSyncLock, + () => + { + ApplyResponseCore(); + return Task.FromResult(0); + }).GetAwaiter().GetResult(); // Block if the async version is in progress. + } + } + catch (Exception) + { + Faulted = true; + throw; + } } protected virtual void ApplyResponseCore() @@ -240,13 +273,27 @@ protected virtual void ApplyResponseCore() /// or later, as the last step when the original async call to the middleware is returning. /// /// - private Task ApplyResponseAsync() + private async Task ApplyResponseAsync() { - return LazyInitializer.EnsureInitialized( - ref _applyResponse, - ref _applyResponseInitialized, - ref _applyResponseSyncLock, - ApplyResponseCoreAsync); + // If ApplyResponse already failed in the OnSendingHeaderCallback or TeardownAsync code path then a + // failed task is cached. If called again the same error will be re-thrown. This breaks error handling + // scenarios like the ability to display the error page or re-execute the request. + try + { + if (!Faulted) + { + await LazyInitializer.EnsureInitialized( + ref _applyResponse, + ref _applyResponseInitialized, + ref _applyResponseSyncLock, + ApplyResponseCoreAsync); + } + } + catch (Exception) + { + Faulted = true; + throw; + } } /// diff --git a/src/Microsoft.AspNet.Security/Infrastructure/AuthenticationMiddleware.cs b/src/Microsoft.AspNet.Security/Infrastructure/AuthenticationMiddleware.cs index b7fb77fe8..a703619de 100644 --- a/src/Microsoft.AspNet.Security/Infrastructure/AuthenticationMiddleware.cs +++ b/src/Microsoft.AspNet.Security/Infrastructure/AuthenticationMiddleware.cs @@ -41,9 +41,25 @@ public async Task Invoke(HttpContext context) { AuthenticationHandler handler = CreateHandler(); await handler.Initialize(Options, context); - if (!await handler.InvokeAsync()) + try { - await _next(context); + if (!await handler.InvokeAsync()) + { + await _next(context); + } + } + catch (Exception) + { + try + { + handler.Faulted = true; + await handler.TeardownAsync(); + } + catch (Exception) + { + // Don't mask the original exception + } + throw; } await handler.TeardownAsync(); } From e6218c0429c4ee9f371e76cd8226724fde1312c5 Mon Sep 17 00:00:00 2001 From: Chris Ross Date: Wed, 7 Jan 2015 17:06:22 -0800 Subject: [PATCH 101/216] React to ReadFor breaking change. --- .../FacebookAuthenticationHandler.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Microsoft.AspNet.Security.Facebook/FacebookAuthenticationHandler.cs b/src/Microsoft.AspNet.Security.Facebook/FacebookAuthenticationHandler.cs index 652090255..455cf1a4c 100644 --- a/src/Microsoft.AspNet.Security.Facebook/FacebookAuthenticationHandler.cs +++ b/src/Microsoft.AspNet.Security.Facebook/FacebookAuthenticationHandler.cs @@ -10,6 +10,7 @@ using System.Threading.Tasks; using Microsoft.AspNet.Http; using Microsoft.AspNet.Http.Security; +using Microsoft.AspNet.PipelineCore.Collections; using Microsoft.AspNet.Security.OAuth; using Microsoft.AspNet.WebUtilities; using Microsoft.Framework.Logging; @@ -39,7 +40,7 @@ protected override async Task ExchangeCodeAsync(string code, stri tokenResponse.EnsureSuccessStatusCode(); string oauthTokenResponse = await tokenResponse.Content.ReadAsStringAsync(); - IFormCollection form = FormHelpers.ParseForm(oauthTokenResponse); + IFormCollection form = new FormCollection(FormReader.ReadForm(oauthTokenResponse)); var response = new JObject(); foreach (string key in form.Keys) { From fbe80ee64ee1e675f5b5e926c0c4afe858efdd9d Mon Sep 17 00:00:00 2001 From: Chris Ross Date: Wed, 7 Jan 2015 18:10:42 -0800 Subject: [PATCH 102/216] Handle ReadFormAsync breaking changes. --- .../TwitterAuthenticationHandler.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Microsoft.AspNet.Security.Twitter/TwitterAuthenticationHandler.cs b/src/Microsoft.AspNet.Security.Twitter/TwitterAuthenticationHandler.cs index 7717642a1..de4dee266 100644 --- a/src/Microsoft.AspNet.Security.Twitter/TwitterAuthenticationHandler.cs +++ b/src/Microsoft.AspNet.Security.Twitter/TwitterAuthenticationHandler.cs @@ -11,6 +11,7 @@ using System.Threading.Tasks; using Microsoft.AspNet.Http; using Microsoft.AspNet.Http.Security; +using Microsoft.AspNet.PipelineCore.Collections; using Microsoft.AspNet.Security.Infrastructure; using Microsoft.AspNet.Security.Twitter.Messages; using Microsoft.AspNet.WebUtilities; @@ -275,7 +276,7 @@ private async Task ObtainRequestTokenAsync(string consumerKey, str response.EnsureSuccessStatusCode(); string responseText = await response.Content.ReadAsStringAsync(); - IFormCollection responseParameters = FormHelpers.ParseForm(responseText); + IFormCollection responseParameters = new FormCollection(FormReader.ReadForm(responseText)); if (string.Equals(responseParameters["oauth_callback_confirmed"], "true", StringComparison.Ordinal)) { return new RequestToken { Token = Uri.UnescapeDataString(responseParameters["oauth_token"]), TokenSecret = Uri.UnescapeDataString(responseParameters["oauth_token_secret"]), CallbackConfirmed = true, Properties = properties }; @@ -351,7 +352,7 @@ private async Task ObtainAccessTokenAsync(string consumerKey, strin string responseText = await response.Content.ReadAsStringAsync(); - IFormCollection responseParameters = FormHelpers.ParseForm(responseText); + IFormCollection responseParameters = new FormCollection(FormReader.ReadForm(responseText)); return new AccessToken { From 49e66f03110b486f8dd9959dd2cee802d676c28f Mon Sep 17 00:00:00 2001 From: BrentSchmaltz Date: Mon, 12 Jan 2015 08:59:24 -0800 Subject: [PATCH 103/216] Additions for OpenIdConnectMiddleware and OAuthBearer Beta1. --- NuGet.Config | 1 + Security.sln | 47 +- .../OpenIdConnectSample.kproj | 30 + samples/OpenIDConnectSample/Startup.cs | 56 ++ samples/OpenIDConnectSample/project.json | 18 + ...IOAuthBearerAuthenticationNotifications.cs | 37 -- .../OAuthBearerAuthenticationNotifications.cs | 73 --- .../OAuthValidateIdentityContext.cs | 26 - .../OAuthAuthenticationMiddleware.cs | 12 +- .../OAuthBearerAuthenticationHandler.cs | 126 ---- .../OAuthBearerAuthenticationMiddleware.cs | 81 --- .../OAuthBearerAuthenticationOptions.cs | 66 -- .../project.json | 2 +- ...icrosoft.AspNet.Security.OAuthBearer.kproj | 22 + .../NotNullAttribute.cs | 12 + .../AuthenticationChallengeNotification.cs | 15 + .../OAuthBearerAuthenticationNotifications.cs | 56 ++ .../OAuthBearerAuthenticationDefaults.cs | 2 +- .../OAuthBearerAuthenticationExtensions.cs | 2 +- .../OAuthBearerAuthenticationHandler.cs | 200 ++++++ .../OAuthBearerAuthenticationMiddleware.cs | 116 ++++ .../OAuthBearerAuthenticationOptions.cs | 159 +++++ .../Resources.Designer.cs | 83 +++ .../Resources.resx | 126 ++++ .../project.json | 22 + ...rosoft.AspNet.Security.OpenIdConnect.kproj | 29 + .../NonceCache.cs | 11 + .../AuthorizationCodeReceivedNotification.cs | 45 ++ .../OpenIdConnectAuthenticationDefaults.cs | 41 ++ .../OpenIdConnectAuthenticationExtensions.cs | 29 + .../OpenIdConnectAuthenticationMiddleware.cs | 173 ++++++ ...penIdConnectAuthenticationNotifications.cs | 59 ++ .../OpenIdConnectAuthenticationOptions.cs | 337 ++++++++++ .../OpenidConnectAuthenticationHandler.cs | 577 ++++++++++++++++++ .../Project.json | 48 ++ .../Resources.Designer.cs | 101 +++ .../AuthenticationTicket.cs | 29 +- .../AuthenticationTokenReceiveContext.cs | 11 - .../AuthenticationFailedNotification.cs | 8 +- .../Notifications/BaseNotification.cs | 49 ++ .../MessageReceivedNotification.cs | 6 +- .../Notifications/NotificationResultState.cs | 22 + ...edirectFromIdentityProviderNotification.cs | 12 +- .../RedirectToIdentityProviderNotification.cs | 8 +- .../SecurityTokenReceivedNotification.cs | 10 +- .../SecurityTokenValidatedNotification.cs | 10 +- .../OAuthBearer/OAuthBearerMiddlewareTests.cs | 237 +++++++ .../OpenIdConnectMiddlewareTests.cs | 361 +++++++++++ .../project.json | 5 +- 49 files changed, 3149 insertions(+), 459 deletions(-) create mode 100644 samples/OpenIDConnectSample/OpenIdConnectSample.kproj create mode 100644 samples/OpenIDConnectSample/Startup.cs create mode 100644 samples/OpenIDConnectSample/project.json delete mode 100644 src/Microsoft.AspNet.Security.OAuth/Notifications/IOAuthBearerAuthenticationNotifications.cs delete mode 100644 src/Microsoft.AspNet.Security.OAuth/Notifications/OAuthBearerAuthenticationNotifications.cs delete mode 100644 src/Microsoft.AspNet.Security.OAuth/Notifications/OAuthValidateIdentityContext.cs delete mode 100644 src/Microsoft.AspNet.Security.OAuth/OAuthBearerAuthenticationHandler.cs delete mode 100644 src/Microsoft.AspNet.Security.OAuth/OAuthBearerAuthenticationMiddleware.cs delete mode 100644 src/Microsoft.AspNet.Security.OAuth/OAuthBearerAuthenticationOptions.cs create mode 100644 src/Microsoft.AspNet.Security.OAuthBearer/Microsoft.AspNet.Security.OAuthBearer.kproj create mode 100644 src/Microsoft.AspNet.Security.OAuthBearer/NotNullAttribute.cs create mode 100644 src/Microsoft.AspNet.Security.OAuthBearer/Notifications/AuthenticationChallengeNotification.cs create mode 100644 src/Microsoft.AspNet.Security.OAuthBearer/Notifications/OAuthBearerAuthenticationNotifications.cs rename src/{Microsoft.AspNet.Security.OAuth => Microsoft.AspNet.Security.OAuthBearer}/OAuthBearerAuthenticationDefaults.cs (92%) rename src/{Microsoft.AspNet.Security.OAuth => Microsoft.AspNet.Security.OAuthBearer}/OAuthBearerAuthenticationExtensions.cs (97%) create mode 100644 src/Microsoft.AspNet.Security.OAuthBearer/OAuthBearerAuthenticationHandler.cs create mode 100644 src/Microsoft.AspNet.Security.OAuthBearer/OAuthBearerAuthenticationMiddleware.cs create mode 100644 src/Microsoft.AspNet.Security.OAuthBearer/OAuthBearerAuthenticationOptions.cs create mode 100644 src/Microsoft.AspNet.Security.OAuthBearer/Resources.Designer.cs create mode 100644 src/Microsoft.AspNet.Security.OAuthBearer/Resources.resx create mode 100644 src/Microsoft.AspNet.Security.OAuthBearer/project.json create mode 100644 src/Microsoft.AspNet.Security.OpenIDConnect/Microsoft.AspNet.Security.OpenIdConnect.kproj create mode 100644 src/Microsoft.AspNet.Security.OpenIDConnect/NonceCache.cs create mode 100644 src/Microsoft.AspNet.Security.OpenIDConnect/Notifications/AuthorizationCodeReceivedNotification.cs create mode 100644 src/Microsoft.AspNet.Security.OpenIDConnect/OpenIdConnectAuthenticationDefaults.cs create mode 100644 src/Microsoft.AspNet.Security.OpenIDConnect/OpenIdConnectAuthenticationExtensions.cs create mode 100644 src/Microsoft.AspNet.Security.OpenIDConnect/OpenIdConnectAuthenticationMiddleware.cs create mode 100644 src/Microsoft.AspNet.Security.OpenIDConnect/OpenIdConnectAuthenticationNotifications.cs create mode 100644 src/Microsoft.AspNet.Security.OpenIDConnect/OpenIdConnectAuthenticationOptions.cs create mode 100644 src/Microsoft.AspNet.Security.OpenIDConnect/OpenidConnectAuthenticationHandler.cs create mode 100644 src/Microsoft.AspNet.Security.OpenIDConnect/Project.json create mode 100644 src/Microsoft.AspNet.Security.OpenIDConnect/Resources.Designer.cs create mode 100644 src/Microsoft.AspNet.Security/Notifications/BaseNotification.cs create mode 100644 src/Microsoft.AspNet.Security/Notifications/NotificationResultState.cs create mode 100644 test/Microsoft.AspNet.Security.Test/OAuthBearer/OAuthBearerMiddlewareTests.cs create mode 100644 test/Microsoft.AspNet.Security.Test/OpenIdConnectMiddlewareTests/OpenIdConnectMiddlewareTests.cs diff --git a/NuGet.Config b/NuGet.Config index f41e9c631..4ee105534 100644 --- a/NuGet.Config +++ b/NuGet.Config @@ -3,5 +3,6 @@ + diff --git a/Security.sln b/Security.sln index 2cc23038e..ccddd42c7 100644 --- a/Security.sln +++ b/Security.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 14 -VisualStudioVersion = 14.0.22013.1 +VisualStudioVersion = 14.0.22422.0 MinimumVisualStudioVersion = 10.0.40219.1 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{4D2B6A51-2F9F-44F5-8131-EA5CAC053652}" EndProject @@ -36,6 +36,12 @@ Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNet.Security.O EndProject Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "CookieSessionSample", "samples\CookieSessionSample\CookieSessionSample.kproj", "{19711880-46DA-4A26-9E0F-9B2E41D27651}" EndProject +Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "OpenIdConnectSample", "samples\OpenIdConnectSample\OpenIdConnectSample.kproj", "{BEF0F5C3-EF4E-4649-9C49-D5E279A3CA2B}" +EndProject +Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNet.Security.OAuthBearer", "src\Microsoft.AspNet.Security.OAuthBearer\Microsoft.AspNet.Security.OAuthBearer.kproj", "{2755BFE5-7421-4A31-A644-F817DF5CAA98}" +EndProject +Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNet.Security.OpenIdConnect", "src\Microsoft.AspNet.Security.OpenIdConnect\Microsoft.AspNet.Security.OpenIdConnect.kproj", "{674D128E-83BB-481A-A9D9-6D47872E1FC8}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -156,6 +162,42 @@ Global {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|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|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|x86.ActiveCfg = Release|Any CPU + {BEF0F5C3-EF4E-4649-9C49-D5E279A3CA2B}.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|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|x86.ActiveCfg = Release|Any CPU + {2755BFE5-7421-4A31-A644-F817DF5CAA98}.Release|x86.Build.0 = Release|Any CPU + {674D128E-83BB-481A-A9D9-6D47872E1FC8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {674D128E-83BB-481A-A9D9-6D47872E1FC8}.Debug|Any CPU.Build.0 = Debug|Any CPU + {674D128E-83BB-481A-A9D9-6D47872E1FC8}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {674D128E-83BB-481A-A9D9-6D47872E1FC8}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {674D128E-83BB-481A-A9D9-6D47872E1FC8}.Debug|x86.ActiveCfg = Debug|Any CPU + {674D128E-83BB-481A-A9D9-6D47872E1FC8}.Debug|x86.Build.0 = Debug|Any CPU + {674D128E-83BB-481A-A9D9-6D47872E1FC8}.Release|Any CPU.ActiveCfg = Release|Any CPU + {674D128E-83BB-481A-A9D9-6D47872E1FC8}.Release|Any CPU.Build.0 = Release|Any CPU + {674D128E-83BB-481A-A9D9-6D47872E1FC8}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {674D128E-83BB-481A-A9D9-6D47872E1FC8}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {674D128E-83BB-481A-A9D9-6D47872E1FC8}.Release|x86.ActiveCfg = Release|Any CPU + {674D128E-83BB-481A-A9D9-6D47872E1FC8}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -172,5 +214,8 @@ Global {1FCF26C2-A3C7-4308-B698-4AFC3560BC0C} = {4D2B6A51-2F9F-44F5-8131-EA5CAC053652} {4A636011-68EE-4CE5-836D-EA8E13CF71E4} = {4D2B6A51-2F9F-44F5-8131-EA5CAC053652} {19711880-46DA-4A26-9E0F-9B2E41D27651} = {F8C0AA27-F3FB-4286-8E4C-47EF86B539FF} + {BEF0F5C3-EF4E-4649-9C49-D5E279A3CA2B} = {F8C0AA27-F3FB-4286-8E4C-47EF86B539FF} + {2755BFE5-7421-4A31-A644-F817DF5CAA98} = {4D2B6A51-2F9F-44F5-8131-EA5CAC053652} + {674D128E-83BB-481A-A9D9-6D47872E1FC8} = {4D2B6A51-2F9F-44F5-8131-EA5CAC053652} EndGlobalSection EndGlobal diff --git a/samples/OpenIDConnectSample/OpenIdConnectSample.kproj b/samples/OpenIDConnectSample/OpenIdConnectSample.kproj new file mode 100644 index 000000000..c6ab693ae --- /dev/null +++ b/samples/OpenIDConnectSample/OpenIdConnectSample.kproj @@ -0,0 +1,30 @@ + + + + 14.0 + $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) + + + + bef0f5c3-ef4e-4649-9c49-d5e279a3ca2b + OpenIDConnectSample + ..\..\artifacts\obj\$(MSBuildProjectName) + ..\..\artifacts\bin\$(MSBuildProjectName)\ + + + OpenIDConnectSample + + + 2.0 + 42023 + + + + + + + + + + + \ No newline at end of file diff --git a/samples/OpenIDConnectSample/Startup.cs b/samples/OpenIDConnectSample/Startup.cs new file mode 100644 index 000000000..17850d03b --- /dev/null +++ b/samples/OpenIDConnectSample/Startup.cs @@ -0,0 +1,56 @@ +using Microsoft.AspNet.Builder; +using Microsoft.AspNet.Http; +using Microsoft.Framework.DependencyInjection; +using Microsoft.AspNet.Security.OpenIdConnect; +using Microsoft.AspNet.Http.Security; +using Microsoft.AspNet.Security; + +namespace OpenIdConnectSample +{ + public class Startup + { + public void Configure(IApplicationBuilder app) + { + app.UseServices(services => + { + services.AddDataProtection(); + services.Configure(options => + { + options.SignInAsAuthenticationType = OpenIdConnectAuthenticationDefaults.AuthenticationType; + }); + + }); + + app.UseCookieAuthentication(options => + { + options.AuthenticationType = OpenIdConnectAuthenticationDefaults.AuthenticationType; + }); + + app.UseOpenIdConnectAuthentication(options => + { + options.ClientId = "fe78e0b4-6fe7-47e6-812c-fb75cee266a4"; + options.Authority = "https://login.windows.net/cyrano.onmicrosoft.com"; + options.RedirectUri = "http://localhost:42023"; + options.SignInAsAuthenticationType = OpenIdConnectAuthenticationDefaults.AuthenticationType; + options.AuthenticationType = OpenIdConnectAuthenticationDefaults.AuthenticationType; + }); + + app.Run(async context => + { + if (context.User == null || !context.User.Identity.IsAuthenticated) + { + context.Response.Challenge(new AuthenticationProperties { RedirectUri = "/" }, OpenIdConnectAuthenticationDefaults.AuthenticationType); + + context.Response.ContentType = "text/plain"; + await context.Response.WriteAsync("Hello First timer"); + return; + } + + context.Response.ContentType = "text/plain"; + await context.Response.WriteAsync("Hello Authenticated User"); + }); + + + } + } +} diff --git a/samples/OpenIDConnectSample/project.json b/samples/OpenIDConnectSample/project.json new file mode 100644 index 000000000..65652110b --- /dev/null +++ b/samples/OpenIDConnectSample/project.json @@ -0,0 +1,18 @@ +{ + "dependencies": { + "Kestrel": "1.0.0-*", + "Microsoft.AspNet.Security.Cookies": "1.0.0-*", + "Microsoft.AspNet.Server.IIS": "1.0.0-*", + "Microsoft.AspNet.Security.OpenIdConnect": "1.0.0-*", + "Microsoft.AspNet.Server.WebListener": "1.0.0-*" + }, + "frameworks": { + "aspnet50": { }, + "aspnetcore50": { } + }, + "commands": { + "web": "Microsoft.AspNet.Hosting server=Microsoft.AspNet.Server.WebListener server.urls=http://localhost:12345", + "kestrel": "Microsoft.AspNet.Hosting --server Kestrel --server.urls http://localhost:5004" + }, + "webroot": "wwwroot" +} diff --git a/src/Microsoft.AspNet.Security.OAuth/Notifications/IOAuthBearerAuthenticationNotifications.cs b/src/Microsoft.AspNet.Security.OAuth/Notifications/IOAuthBearerAuthenticationNotifications.cs deleted file mode 100644 index 048d8f292..000000000 --- a/src/Microsoft.AspNet.Security.OAuth/Notifications/IOAuthBearerAuthenticationNotifications.cs +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System.Threading.Tasks; - -namespace Microsoft.AspNet.Security.OAuth -{ - /// - /// Specifies callback methods which the invokes to enable developer control over the authentication process. /> - /// - public interface IOAuthBearerAuthenticationNotifications - { - /// - /// Invoked before the is created. Gives the application an - /// opportunity to find the identity from a different location, adjust, or reject the token. - /// - /// Contains the token string. - /// A representing the completed operation. - Task RequestToken(OAuthRequestTokenContext context); - - /// - /// Called each time a request identity has been validated by the middleware. By implementing this method the - /// application may alter or reject the identity which has arrived with the request. - /// - /// Contains information about the login session as well as the user . - /// A representing the completed operation. - Task ValidateIdentity(OAuthValidateIdentityContext context); - - /// - /// Called each time a challenge is being sent to the client. By implementing this method the application - /// may modify the challenge as needed. - /// - /// Contains the default challenge. - /// A representing the completed operation. - Task ApplyChallenge(OAuthChallengeContext context); - } -} diff --git a/src/Microsoft.AspNet.Security.OAuth/Notifications/OAuthBearerAuthenticationNotifications.cs b/src/Microsoft.AspNet.Security.OAuth/Notifications/OAuthBearerAuthenticationNotifications.cs deleted file mode 100644 index 2c24f3ff1..000000000 --- a/src/Microsoft.AspNet.Security.OAuth/Notifications/OAuthBearerAuthenticationNotifications.cs +++ /dev/null @@ -1,73 +0,0 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System; -using System.Threading.Tasks; - -namespace Microsoft.AspNet.Security.OAuth -{ - /// - /// OAuth bearer token middleware provider - /// - public class OAuthBearerAuthenticationNotifications : IOAuthBearerAuthenticationNotifications - { - /// - /// Initializes a new instance of the class - /// - public OAuthBearerAuthenticationNotifications() - { - OnRequestToken = context => Task.FromResult(null); - OnValidateIdentity = context => Task.FromResult(null); - OnApplyChallenge = context => - { - context.HttpContext.Response.Headers.AppendValues("WWW-Authenticate", context.Challenge); - return Task.FromResult(0); - }; - } - - /// - /// Handles processing OAuth bearer token. - /// - public Func OnRequestToken { get; set; } - - /// - /// Handles validating the identity produced from an OAuth bearer token. - /// - public Func OnValidateIdentity { get; set; } - - /// - /// Handles applying the authentication challenge to the response message. - /// - public Func OnApplyChallenge { get; set; } - - /// - /// Handles processing OAuth bearer token. - /// - /// - /// - public virtual Task RequestToken(OAuthRequestTokenContext context) - { - return OnRequestToken(context); - } - - /// - /// Handles validating the identity produced from an OAuth bearer token. - /// - /// - /// - public virtual Task ValidateIdentity(OAuthValidateIdentityContext context) - { - return OnValidateIdentity.Invoke(context); - } - - /// - /// Handles applying the authentication challenge to the response message. - /// - /// - /// - public Task ApplyChallenge(OAuthChallengeContext context) - { - return OnApplyChallenge(context); - } - } -} diff --git a/src/Microsoft.AspNet.Security.OAuth/Notifications/OAuthValidateIdentityContext.cs b/src/Microsoft.AspNet.Security.OAuth/Notifications/OAuthValidateIdentityContext.cs deleted file mode 100644 index 5dc04ffb4..000000000 --- a/src/Microsoft.AspNet.Security.OAuth/Notifications/OAuthValidateIdentityContext.cs +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using Microsoft.AspNet.Http; - -namespace Microsoft.AspNet.Security.OAuth -{ - /// - /// Contains the authentication ticket data from an OAuth bearer token. - /// - public class OAuthValidateIdentityContext : BaseValidatingTicketContext - { - /// - /// Initializes a new instance of the class - /// - /// - /// - /// - public OAuthValidateIdentityContext( - HttpContext context, - OAuthBearerAuthenticationOptions options, - AuthenticationTicket ticket) : base(context, options, ticket) - { - } - } -} diff --git a/src/Microsoft.AspNet.Security.OAuth/OAuthAuthenticationMiddleware.cs b/src/Microsoft.AspNet.Security.OAuth/OAuthAuthenticationMiddleware.cs index 2628d3849..18dd9c9a8 100644 --- a/src/Microsoft.AspNet.Security.OAuth/OAuthAuthenticationMiddleware.cs +++ b/src/Microsoft.AspNet.Security.OAuth/OAuthAuthenticationMiddleware.cs @@ -1,16 +1,16 @@ // Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -using System; -using System.Diagnostics.CodeAnalysis; -using System.Globalization; -using System.Net.Http; using Microsoft.AspNet.Builder; using Microsoft.AspNet.Security.DataHandler; using Microsoft.AspNet.Security.DataProtection; using Microsoft.AspNet.Security.Infrastructure; using Microsoft.Framework.Logging; using Microsoft.Framework.OptionsModel; +using System; +using System.Diagnostics.CodeAnalysis; +using System.Globalization; +using System.Net.Http; namespace Microsoft.AspNet.Security.OAuth { @@ -45,18 +45,22 @@ public OAuthAuthenticationMiddleware( { throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, Resources.Exception_OptionMustBeProvided, "AuthenticationType")); } + if (string.IsNullOrWhiteSpace(Options.ClientId)) { throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, Resources.Exception_OptionMustBeProvided, "ClientId")); } + if (string.IsNullOrWhiteSpace(Options.ClientSecret)) { throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, Resources.Exception_OptionMustBeProvided, "ClientSecret")); } + if (string.IsNullOrWhiteSpace(Options.AuthorizationEndpoint)) { throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, Resources.Exception_OptionMustBeProvided, "AuthorizationEndpoint")); } + if (string.IsNullOrWhiteSpace(Options.TokenEndpoint)) { throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, Resources.Exception_OptionMustBeProvided, "TokenEndpoint")); diff --git a/src/Microsoft.AspNet.Security.OAuth/OAuthBearerAuthenticationHandler.cs b/src/Microsoft.AspNet.Security.OAuth/OAuthBearerAuthenticationHandler.cs deleted file mode 100644 index 406085b67..000000000 --- a/src/Microsoft.AspNet.Security.OAuth/OAuthBearerAuthenticationHandler.cs +++ /dev/null @@ -1,126 +0,0 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System; -using System.Threading.Tasks; -using Microsoft.AspNet.Security.Infrastructure; -using Microsoft.Framework.Logging; - -namespace Microsoft.AspNet.Security.OAuth -{ - internal class OAuthBearerAuthenticationHandler : AuthenticationHandler - { - private readonly ILogger _logger; - private readonly string _challenge; - - public OAuthBearerAuthenticationHandler(ILogger logger, string challenge) - { - _logger = logger; - _challenge = challenge; - } - - protected override AuthenticationTicket AuthenticateCore() - { - return AuthenticateCoreAsync().GetAwaiter().GetResult(); - } - - protected override async Task AuthenticateCoreAsync() - { - try - { - // Find token in default location - string requestToken = null; - string authorization = Request.Headers.Get("Authorization"); - if (!string.IsNullOrEmpty(authorization)) - { - if (authorization.StartsWith("Bearer ", StringComparison.OrdinalIgnoreCase)) - { - requestToken = authorization.Substring("Bearer ".Length).Trim(); - } - } - - // Give application opportunity to find from a different location, adjust, or reject token - var requestTokenContext = new OAuthRequestTokenContext(Context, requestToken); - await Options.Notifications.RequestToken(requestTokenContext); - - // If no token found, no further work possible - if (string.IsNullOrEmpty(requestTokenContext.Token)) - { - return null; - } - - // Call provider to process the token into data - var tokenReceiveContext = new AuthenticationTokenReceiveContext( - Context, - Options.AccessTokenFormat, - requestTokenContext.Token); - - await Options.AccessTokenProvider.ReceiveAsync(tokenReceiveContext); - if (tokenReceiveContext.Ticket == null) - { - tokenReceiveContext.DeserializeTicket(tokenReceiveContext.Token); - } - - AuthenticationTicket ticket = tokenReceiveContext.Ticket; - if (ticket == null) - { - _logger.WriteWarning("invalid bearer token received"); - return null; - } - - // Validate expiration time if present - DateTimeOffset currentUtc = Options.SystemClock.UtcNow; - - if (ticket.Properties.ExpiresUtc.HasValue && - ticket.Properties.ExpiresUtc.Value < currentUtc) - { - _logger.WriteWarning("expired bearer token received"); - return null; - } - - // Give application final opportunity to override results - var context = new OAuthValidateIdentityContext(Context, Options, ticket); - if (ticket != null && - ticket.Identity != null && - ticket.Identity.IsAuthenticated) - { - // bearer token with identity starts validated - context.Validated(); - } - - await Options.Notifications.ValidateIdentity(context); - if (!context.IsValidated) - { - return null; - } - - // resulting identity values go back to caller - return context.Ticket; - } - catch (Exception ex) - { - _logger.WriteError("Authentication failed", ex); - return null; - } - } - - protected override void ApplyResponseChallenge() - { - if (Response.StatusCode != 401) - { - return; - } - - if (ChallengeContext != null) - { - OAuthChallengeContext challengeContext = new OAuthChallengeContext(Context, _challenge); - Options.Notifications.ApplyChallenge(challengeContext); - } - } - - protected override void ApplyResponseGrant() - { - // N/A - } - } -} diff --git a/src/Microsoft.AspNet.Security.OAuth/OAuthBearerAuthenticationMiddleware.cs b/src/Microsoft.AspNet.Security.OAuth/OAuthBearerAuthenticationMiddleware.cs deleted file mode 100644 index 0661c4fed..000000000 --- a/src/Microsoft.AspNet.Security.OAuth/OAuthBearerAuthenticationMiddleware.cs +++ /dev/null @@ -1,81 +0,0 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using Microsoft.AspNet.Builder; -using Microsoft.AspNet.Security.DataHandler; -using Microsoft.AspNet.Security.DataProtection; -using Microsoft.AspNet.Security.Infrastructure; -using Microsoft.Framework.Logging; -using Microsoft.Framework.OptionsModel; -using System; - -namespace Microsoft.AspNet.Security.OAuth -{ - /// - /// 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 UseOAuthBearerAuthentication - /// extension method. - /// - public class OAuthBearerAuthenticationMiddleware : AuthenticationMiddleware - { - private readonly ILogger _logger; - - private readonly string _challenge; - - /// - /// 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 UseOAuthBearerAuthentication - /// extension method. - /// - public OAuthBearerAuthenticationMiddleware( - RequestDelegate next, - IServiceProvider services, - IDataProtectionProvider dataProtectionProvider, - ILoggerFactory loggerFactory, - IOptions options, - ConfigureOptions configureOptions) - : base(next, services, options, configureOptions) - { - _logger = loggerFactory.Create(); - - if (!string.IsNullOrWhiteSpace(Options.Challenge)) - { - _challenge = Options.Challenge; - } - else if (string.IsNullOrWhiteSpace(Options.Realm)) - { - _challenge = "Bearer"; - } - else - { - _challenge = "Bearer realm=\"" + Options.Realm + "\""; - } - - if (Options.Notifications == null) - { - Options.Notifications = new OAuthBearerAuthenticationNotifications(); - } - - if (Options.AccessTokenFormat == null) - { - IDataProtector dataProtector = dataProtectionProvider.CreateDataProtector( - this.GetType().FullName, Options.AuthenticationType, "v1"); - Options.AccessTokenFormat = new TicketDataFormat(dataProtector); - } - - if (Options.AccessTokenProvider == null) - { - Options.AccessTokenProvider = new AuthenticationTokenProvider(); - } - } - - /// - /// Called by the AuthenticationMiddleware base class to create a per-request handler. - /// - /// A new instance of the request handler - protected override AuthenticationHandler CreateHandler() - { - return new OAuthBearerAuthenticationHandler(_logger, _challenge); - } - } -} diff --git a/src/Microsoft.AspNet.Security.OAuth/OAuthBearerAuthenticationOptions.cs b/src/Microsoft.AspNet.Security.OAuth/OAuthBearerAuthenticationOptions.cs deleted file mode 100644 index d2f9b9190..000000000 --- a/src/Microsoft.AspNet.Security.OAuth/OAuthBearerAuthenticationOptions.cs +++ /dev/null @@ -1,66 +0,0 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using Microsoft.AspNet.Security.Infrastructure; - -namespace Microsoft.AspNet.Security.OAuth -{ - /// - /// Options class provides information needed to control Bearer Authentication middleware behavior - /// - public class OAuthBearerAuthenticationOptions : AuthenticationOptions - { - /// - /// Creates an instance of bearer authentication options with default values. - /// - public OAuthBearerAuthenticationOptions() : base() - { - SystemClock = new SystemClock(); - AuthenticationType = OAuthBearerAuthenticationDefaults.AuthenticationType; - } - - /// - /// Determines what realm value is included when the bearer middleware adds a response header to an unauthorized request. - /// If not assigned, the response header does not have a realm. - /// - public string Realm { get; set; } - - /// - /// Specifies the full challenge to send to the client, and should start with "Bearer". If a challenge is provided then the - /// Realm property is ignored. If no challenge is specified then one is created using "Bearer" and the value of the Realm - /// property. - /// - public string Challenge { get; set; } - - /// - /// The object provided by the application to process events raised by the bearer authentication middleware. - /// The application may implement the interface fully, or it may create an instance of OAuthBearerAuthenticationProvider - /// and assign delegates only to the events it wants to process. - /// - public IOAuthBearerAuthenticationNotifications Notifications { get; set; } - - /// - /// The data format used to un-protect the information contained in the access token. - /// If not provided by the application the default data protection provider depends on the host server. - /// The SystemWeb host on IIS will use ASP.NET machine key data protection, and HttpListener and other self-hosted - /// servers will use DPAPI data protection. If a different access token - /// provider or format is assigned, a compatible instance must be assigned to the OAuthAuthorizationServerOptions.AccessTokenProvider - /// and OAuthAuthorizationServerOptions.AccessTokenFormat of the authorization server. - /// - public ISecureDataFormat AccessTokenFormat { get; set; } - - /// - /// Receives the bearer token the client application will be providing to web application. If not provided the token - /// produced on the server's default data protection by using the AccessTokenFormat. If a different access token - /// provider or format is assigned, a compatible instance must be assigned to the OAuthAuthorizationServerOptions.AccessTokenProvider - /// and OAuthAuthorizationServerOptions.AccessTokenFormat of the authorization server. - /// - public IAuthenticationTokenProvider AccessTokenProvider { get; set; } - - /// - /// Used to know what the current clock time is when calculating or validating token expiration. When not assigned default is based on - /// DateTimeOffset.UtcNow. This is typically needed only for unit testing. - /// - public ISystemClock SystemClock { get; set; } - } -} diff --git a/src/Microsoft.AspNet.Security.OAuth/project.json b/src/Microsoft.AspNet.Security.OAuth/project.json index 6a2eed249..39ba020fc 100644 --- a/src/Microsoft.AspNet.Security.OAuth/project.json +++ b/src/Microsoft.AspNet.Security.OAuth/project.json @@ -3,7 +3,7 @@ "description": "ASP.NET 5 middleware that enables an application to support any standard OAuth 2.0 authentication workflow.", "dependencies": { "Microsoft.AspNet.Security": "1.0.0-*", - "Microsoft.AspNet.Security.DataProtection": "1.0.0-*" + "Microsoft.AspNet.Security.DataProtection": "1.0.0-*", }, "frameworks": { "aspnet50": { diff --git a/src/Microsoft.AspNet.Security.OAuthBearer/Microsoft.AspNet.Security.OAuthBearer.kproj b/src/Microsoft.AspNet.Security.OAuthBearer/Microsoft.AspNet.Security.OAuthBearer.kproj new file mode 100644 index 000000000..55d65389e --- /dev/null +++ b/src/Microsoft.AspNet.Security.OAuthBearer/Microsoft.AspNet.Security.OAuthBearer.kproj @@ -0,0 +1,22 @@ + + + + 14.0 + $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) + + + + 2755BFE5-7421-4A31-A644-F817DF5CAA98 + ..\..\artifacts\obj\$(MSBuildProjectName) + ..\..\artifacts\bin\$(MSBuildProjectName)\ + + + 2.0 + + + + + + + + \ No newline at end of file diff --git a/src/Microsoft.AspNet.Security.OAuthBearer/NotNullAttribute.cs b/src/Microsoft.AspNet.Security.OAuthBearer/NotNullAttribute.cs new file mode 100644 index 000000000..29f582749 --- /dev/null +++ b/src/Microsoft.AspNet.Security.OAuthBearer/NotNullAttribute.cs @@ -0,0 +1,12 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; + +namespace Microsoft.AspNet.Security.OAuthBearer +{ + [AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false)] + internal sealed class NotNullAttribute : Attribute + { + } +} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Security.OAuthBearer/Notifications/AuthenticationChallengeNotification.cs b/src/Microsoft.AspNet.Security.OAuthBearer/Notifications/AuthenticationChallengeNotification.cs new file mode 100644 index 000000000..f2685af0c --- /dev/null +++ b/src/Microsoft.AspNet.Security.OAuthBearer/Notifications/AuthenticationChallengeNotification.cs @@ -0,0 +1,15 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using Microsoft.AspNet.Http; +using Microsoft.AspNet.Security.Notifications; + +namespace Microsoft.AspNet.Security.OAuthBearer +{ + public class AuthenticationChallengeNotification : BaseNotification + { + public AuthenticationChallengeNotification(HttpContext context, TOptions options) : base(context, options) + { + } + } +} diff --git a/src/Microsoft.AspNet.Security.OAuthBearer/Notifications/OAuthBearerAuthenticationNotifications.cs b/src/Microsoft.AspNet.Security.OAuthBearer/Notifications/OAuthBearerAuthenticationNotifications.cs new file mode 100644 index 000000000..808615e1d --- /dev/null +++ b/src/Microsoft.AspNet.Security.OAuthBearer/Notifications/OAuthBearerAuthenticationNotifications.cs @@ -0,0 +1,56 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Threading.Tasks; +using Microsoft.AspNet.Http; +using Microsoft.AspNet.Security.Notifications; + +/// +/// Specifies events which the invokes to enable developer control over the authentication process. /> +/// +namespace Microsoft.AspNet.Security.OAuthBearer +{ + /// + /// OAuth bearer token middleware provider + /// + public class OAuthBearerAuthenticationNotifications + { + /// + /// Initializes a new instance of the class + /// + public OAuthBearerAuthenticationNotifications() + { + ApplyChallenge = notification => { notification.HttpContext.Response.Headers.AppendValues("WWW-Authenticate", notification.Options.Challenge); return Task.FromResult(0); }; + AuthenticationFailed = notification => Task.FromResult(0); + MessageReceived = notification => Task.FromResult(0); + SecurityTokenReceived = notification => Task.FromResult(0); + SecurityTokenValidated = notification => Task.FromResult(0); + } + + /// + /// Invoked if exceptions are thrown during request processing. The exceptions will be re-thrown after this event unless suppressed. + /// + public Func, Task> AuthenticationFailed { get; set; } + + /// + /// Invoked when a protocol message is first received. + /// + public Func, Task> MessageReceived { get; set; } + + /// + /// Invoked with the security token that has been extracted from the protocol message. + /// + public Func, Task> SecurityTokenReceived { get; set; } + + /// + /// Invoked after the security token has passed validation and a ClaimsIdentity has been generated. + /// + public Func, Task> SecurityTokenValidated { get; set; } + + /// + /// Invoked to apply a challenge sent back to the caller. + /// + public Func, Task> ApplyChallenge { get; set; } + } +} diff --git a/src/Microsoft.AspNet.Security.OAuth/OAuthBearerAuthenticationDefaults.cs b/src/Microsoft.AspNet.Security.OAuthBearer/OAuthBearerAuthenticationDefaults.cs similarity index 92% rename from src/Microsoft.AspNet.Security.OAuth/OAuthBearerAuthenticationDefaults.cs rename to src/Microsoft.AspNet.Security.OAuthBearer/OAuthBearerAuthenticationDefaults.cs index 70f1f1e61..5b62827cc 100644 --- a/src/Microsoft.AspNet.Security.OAuth/OAuthBearerAuthenticationDefaults.cs +++ b/src/Microsoft.AspNet.Security.OAuthBearer/OAuthBearerAuthenticationDefaults.cs @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -namespace Microsoft.AspNet.Security.OAuth +namespace Microsoft.AspNet.Security.OAuthBearer { /// /// Default values used by authorization server and bearer authentication. diff --git a/src/Microsoft.AspNet.Security.OAuth/OAuthBearerAuthenticationExtensions.cs b/src/Microsoft.AspNet.Security.OAuthBearer/OAuthBearerAuthenticationExtensions.cs similarity index 97% rename from src/Microsoft.AspNet.Security.OAuth/OAuthBearerAuthenticationExtensions.cs rename to src/Microsoft.AspNet.Security.OAuthBearer/OAuthBearerAuthenticationExtensions.cs index b5512d01c..0f31dfaf8 100644 --- a/src/Microsoft.AspNet.Security.OAuth/OAuthBearerAuthenticationExtensions.cs +++ b/src/Microsoft.AspNet.Security.OAuthBearer/OAuthBearerAuthenticationExtensions.cs @@ -2,7 +2,7 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; -using Microsoft.AspNet.Security.OAuth; +using Microsoft.AspNet.Security.OAuthBearer; using Microsoft.Framework.DependencyInjection; using Microsoft.Framework.OptionsModel; diff --git a/src/Microsoft.AspNet.Security.OAuthBearer/OAuthBearerAuthenticationHandler.cs b/src/Microsoft.AspNet.Security.OAuthBearer/OAuthBearerAuthenticationHandler.cs new file mode 100644 index 000000000..1c2eb287a --- /dev/null +++ b/src/Microsoft.AspNet.Security.OAuthBearer/OAuthBearerAuthenticationHandler.cs @@ -0,0 +1,200 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Collections.Generic; +using System.IdentityModel.Tokens; +using System.Linq; +using System.Runtime.ExceptionServices; +using System.Security.Claims; +using System.Threading.Tasks; +using Microsoft.AspNet.Http; +using Microsoft.AspNet.Http.Security; +using Microsoft.AspNet.Security.Infrastructure; +using Microsoft.AspNet.Security.Notifications; +using Microsoft.Framework.Logging; +using Microsoft.IdentityModel.Protocols; + +namespace Microsoft.AspNet.Security.OAuthBearer +{ + public class OAuthBearerAuthenticationHandler : AuthenticationHandler + { + private readonly ILogger _logger; + private OpenIdConnectConfiguration _configuration; + + public OAuthBearerAuthenticationHandler(ILogger logger) + { + _logger = logger; + } + + protected override AuthenticationTicket AuthenticateCore() + { + return AuthenticateCoreAsync().GetAwaiter().GetResult(); + } + + /// + /// Searches the 'Authorization' header for a 'Bearer' token. If the 'Bearer' token is found, it is validated using set in the options. + /// + /// + protected override async Task AuthenticateCoreAsync() + { + ExceptionDispatchInfo authFailedEx = null; + string token = null; + try + { + // Give application opportunity to find from a different location, adjust, or reject token + var messageReceivedNotification = + new MessageReceivedNotification(Context, Options) + { + ProtocolMessage = Context, + }; + + // notification can set the token + await Options.Notifications.MessageReceived(messageReceivedNotification); + if (messageReceivedNotification.HandledResponse) + { + return messageReceivedNotification.AuthenticationTicket; + } + + if (messageReceivedNotification.Skipped) + { + return null; + } + + string authorization = Request.Headers.Get("Authorization"); + if (authorization.StartsWith("Bearer ", StringComparison.OrdinalIgnoreCase)) + { + token = authorization.Substring("Bearer ".Length).Trim(); + } + + // If no token found, no further work possible + if (string.IsNullOrEmpty(token)) + { + return null; + } + + // notify user token was received + var securityTokenReceivedNotification = + new SecurityTokenReceivedNotification(Context, Options) + { + ProtocolMessage = Context, + SecurityToken = token, + }; + + await Options.Notifications.SecurityTokenReceived(securityTokenReceivedNotification); + if (securityTokenReceivedNotification.HandledResponse) + { + return securityTokenReceivedNotification.AuthenticationTicket; + } + + if (securityTokenReceivedNotification.Skipped) + { + return null; + } + + if (_configuration == null && Options.ConfigurationManager != null) + { + _configuration = await Options.ConfigurationManager.GetConfigurationAsync(Context.RequestAborted); + } + + var validationParameters = Options.TokenValidationParameters.Clone(); + if (_configuration != null) + { + if (validationParameters.ValidIssuer == null && !string.IsNullOrWhiteSpace(_configuration.Issuer)) + { + validationParameters.ValidIssuer = _configuration.Issuer; + } + else + { + IEnumerable issuers = new[] { _configuration.Issuer }; + validationParameters.ValidIssuers = (validationParameters.ValidIssuers == null ? issuers : validationParameters.ValidIssuers.Concat(issuers)); + } + + validationParameters.IssuerSigningKeys = (validationParameters.IssuerSigningKeys == null ? _configuration.SigningKeys : validationParameters.IssuerSigningKeys.Concat(_configuration.SigningKeys)); + } + + SecurityToken validatedToken; + foreach (var validator in Options.SecurityTokenValidators) + { + if (validator.CanReadToken(token)) + { + ClaimsPrincipal principal = validator.ValidateToken(token, validationParameters, out validatedToken); + AuthenticationTicket ticket = new AuthenticationTicket(principal, new AuthenticationProperties(), Options.AuthenticationType); + var securityTokenValidatedNotification = new SecurityTokenValidatedNotification(Context, Options) + { + ProtocolMessage = Context, + AuthenticationTicket = ticket + }; + + if (securityTokenReceivedNotification.HandledResponse) + { + return securityTokenValidatedNotification.AuthenticationTicket; + } + + if (securityTokenReceivedNotification.Skipped) + { + return null; + } + + return ticket; + } + } + + throw new InvalidOperationException("No SecurityTokenValidator available for token: " + token ?? "null"); + } + catch (Exception ex) + { + // We can't await inside a catch block, capture and handle outside. + authFailedEx = ExceptionDispatchInfo.Capture(ex); + } + + if (authFailedEx != null) + { + _logger.WriteError("Exception occurred while processing message", authFailedEx.SourceException); + + // Refresh the configuration for exceptions that may be caused by key rollovers. The user can also request a refresh in the notification. + if (Options.RefreshOnIssuerKeyNotFound && authFailedEx.SourceException.GetType().Equals(typeof(SecurityTokenSignatureKeyNotFoundException))) + { + Options.ConfigurationManager.RequestRefresh(); + } + + var authenticationFailedNotification = + new AuthenticationFailedNotification(Context, Options) + { + ProtocolMessage = Context, + Exception = authFailedEx.SourceException + }; + + await Options.Notifications.AuthenticationFailed(authenticationFailedNotification); + if (authenticationFailedNotification.HandledResponse) + { + return authenticationFailedNotification.AuthenticationTicket; + } + + if (authenticationFailedNotification.Skipped) + { + return null; + } + + authFailedEx.Throw(); + } + + return null; + } + + protected override void ApplyResponseChallenge() + { + ApplyResponseChallengeAsync().GetAwaiter().GetResult(); + } + + protected override async Task ApplyResponseChallengeAsync() + { + await Options.Notifications.ApplyChallenge(new AuthenticationChallengeNotification(Context, Options)); + } + + protected override void ApplyResponseGrant() + { + // N/A + } + } +} diff --git a/src/Microsoft.AspNet.Security.OAuthBearer/OAuthBearerAuthenticationMiddleware.cs b/src/Microsoft.AspNet.Security.OAuthBearer/OAuthBearerAuthenticationMiddleware.cs new file mode 100644 index 000000000..0403896ae --- /dev/null +++ b/src/Microsoft.AspNet.Security.OAuthBearer/OAuthBearerAuthenticationMiddleware.cs @@ -0,0 +1,116 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using System.IdentityModel.Tokens; +using System.Net.Http; +using Microsoft.AspNet.Builder; +using Microsoft.AspNet.Security.DataProtection; +using Microsoft.AspNet.Security.Infrastructure; +using Microsoft.Framework.Logging; +using Microsoft.Framework.OptionsModel; +using Microsoft.IdentityModel.Protocols; + +namespace Microsoft.AspNet.Security.OAuthBearer +{ + /// + /// 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 UseOAuthBearerAuthentication + /// extension method. + /// + public class OAuthBearerAuthenticationMiddleware : AuthenticationMiddleware + { + private readonly ILogger _logger; + + /// + /// 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 UseOAuthBearerAuthentication + /// extension method. + /// + public OAuthBearerAuthenticationMiddleware( + RequestDelegate next, + IServiceProvider services, + ILoggerFactory loggerFactory, + IOptions options, + ConfigureOptions configureOptions) + : base(next, services, options, configureOptions) + { + _logger = loggerFactory.Create(); + if (Options.Notifications == null) + { + Options.Notifications = new OAuthBearerAuthenticationNotifications(); + } + + if (Options.SecurityTokenValidators == null) + { + Options.SecurityTokenValidators = new List { new JwtSecurityTokenHandler() }; + } + + if (string.IsNullOrWhiteSpace(Options.TokenValidationParameters.ValidAudience) && !string.IsNullOrWhiteSpace(Options.Audience)) + { + Options.TokenValidationParameters.ValidAudience = Options.Audience; + } + + if (Options.ConfigurationManager == null) + { + if (Options.Configuration != null) + { + Options.ConfigurationManager = new StaticConfigurationManager(Options.Configuration); + } + else if (!(string.IsNullOrWhiteSpace(Options.MetadataAddress) && string.IsNullOrWhiteSpace(Options.Authority))) + { + if (string.IsNullOrWhiteSpace(Options.MetadataAddress) && !string.IsNullOrWhiteSpace(Options.Authority)) + { + Options.MetadataAddress = Options.Authority; + if (!Options.MetadataAddress.EndsWith("/", StringComparison.Ordinal)) + { + Options.MetadataAddress += "/"; + } + + Options.MetadataAddress += ".well-known/openid-configuration"; + } + + HttpClient httpClient = new HttpClient(ResolveHttpMessageHandler(Options)); + httpClient.Timeout = Options.BackchannelTimeout; + httpClient.MaxResponseContentBufferSize = 1024 * 1024 * 10; // 10 MB + + Options.ConfigurationManager = new ConfigurationManager(Options.MetadataAddress, httpClient); + } + } + } + + /// + /// Called by the AuthenticationMiddleware base class to create a per-request handler. + /// + /// A new instance of the request handler + protected override AuthenticationHandler CreateHandler() + { + return new OAuthBearerAuthenticationHandler(_logger); + } + + [SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Justification = "Managed by caller")] + private static HttpMessageHandler ResolveHttpMessageHandler(OAuthBearerAuthenticationOptions options) + { + HttpMessageHandler handler = options.BackchannelHttpHandler ?? +#if ASPNET50 + new WebRequestHandler(); + // If they provided a validator, apply it or fail. + if (options.BackchannelCertificateValidator != null) + { + // Set the cert validate callback + var webRequestHandler = handler as WebRequestHandler; + if (webRequestHandler == null) + { + throw new InvalidOperationException(Resources.Exception_ValidatorHandlerMismatch); + } + webRequestHandler.ServerCertificateValidationCallback = options.BackchannelCertificateValidator.Validate; + } +#else + new WinHttpHandler(); +#endif + return handler; + } + } +} diff --git a/src/Microsoft.AspNet.Security.OAuthBearer/OAuthBearerAuthenticationOptions.cs b/src/Microsoft.AspNet.Security.OAuthBearer/OAuthBearerAuthenticationOptions.cs new file mode 100644 index 000000000..08acf5bf4 --- /dev/null +++ b/src/Microsoft.AspNet.Security.OAuthBearer/OAuthBearerAuthenticationOptions.cs @@ -0,0 +1,159 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Collections.Generic; +using System.IdentityModel.Tokens; +using System.Net.Http; +using Microsoft.AspNet.Security.Infrastructure; +using Microsoft.IdentityModel.Protocols; + +namespace Microsoft.AspNet.Security.OAuthBearer +{ + /// + /// Options class provides information needed to control Bearer Authentication middleware behavior + /// + public class OAuthBearerAuthenticationOptions : AuthenticationOptions + { + private ICollection _securityTokenValidators; + private TokenValidationParameters _tokenValidationParameters; + + /// + /// Creates an instance of bearer authentication options with default values. + /// + public OAuthBearerAuthenticationOptions() : base() + { + AuthenticationType = OAuthBearerAuthenticationDefaults.AuthenticationType; + BackchannelTimeout = TimeSpan.FromMinutes(1); + Challenge = OAuthBearerAuthenticationDefaults.AuthenticationType; + Notifications = new OAuthBearerAuthenticationNotifications(); + RefreshOnIssuerKeyNotFound = true; + SystemClock = new SystemClock(); + TokenValidationParameters = new TokenValidationParameters(); + } + + /// + /// Gets or sets the discovery endpoint for obtaining metadata + /// + public string MetadataAddress { get; set; } + + /// + /// Gets or sets the Authority to use when making OpenIdConnect calls. + /// + public string Authority { get; set; } + + /// + /// Gets or sets the audience for any received JWT token. + /// + /// + /// The expected audience for any received JWT token. + /// + public string Audience { get; set; } + + /// + /// Gets or sets the challenge to put in the "WWW-Authenticate" header. + /// + /// TODO - brentschmaltz, should not be null. + public string Challenge { get; set; } + + /// + /// The object provided by the application to process events raised by the bearer authentication middleware. + /// The application may implement the interface fully, or it may create an instance of OAuthBearerAuthenticationProvider + /// and assign delegates only to the events it wants to process. + /// + public OAuthBearerAuthenticationNotifications Notifications { get; set; } + + /// + /// The HttpMessageHandler used to retrieve metadata. + /// This cannot be set at the same time as BackchannelCertificateValidator unless the value + /// is a WebRequestHandler. + /// + public HttpMessageHandler BackchannelHttpHandler { get; set; } + + /// + /// Gets or sets the timeout when using the backchannel to make an http call. + /// + public TimeSpan BackchannelTimeout { get; set; } + +#if ASPNET50 + /// + /// Gets or sets the a pinned certificate validator to use to validate the endpoints used + /// when retrieving metadata. + /// + /// + /// The pinned certificate validator. + /// + /// If this property is null then the default certificate checks are performed, + /// validating the subject name and if the signing chain is a trusted party. + public ICertificateValidator BackchannelCertificateValidator { get; set; } +#endif + /// + /// Configuration provided directly by the developer. If provided, then MetadataAddress and the Backchannel properties + /// will not be used. This information should not be updated during request processing. + /// + public OpenIdConnectConfiguration Configuration { get; set; } + + /// + /// Responsible for retrieving, caching, and refreshing the configuration from metadata. + /// If not provided, then one will be created using the MetadataAddress and Backchannel properties. + /// + public IConfigurationManager ConfigurationManager { get; set; } + + /// + /// Gets or sets if a metadata refresh should be attempted after a SecurityTokenSignatureKeyNotFoundException. This allows for automatic + /// recovery in the event of a signature key rollover. This is enabled by default. + /// + public bool RefreshOnIssuerKeyNotFound { get; set; } + + /// + /// Used to know what the current clock time is when calculating or validating token expiration. When not assigned default is based on + /// DateTimeOffset.UtcNow. This is typically needed only for unit testing. + /// + public ISystemClock SystemClock { get; set; } + + /// + /// Gets or sets the for validating tokens. + /// + /// if 'value' is null. + public ICollection SecurityTokenValidators + { + get + { + return _securityTokenValidators; + } + + set + { + if (value == null) + { + throw new ArgumentNullException("SecurityTokenValidators"); + } + + _securityTokenValidators = value; + } + } + + /// + /// Gets or sets the TokenValidationParameters + /// + /// Contains the types and definitions required for validating a token. + /// if 'value' is null. + public TokenValidationParameters TokenValidationParameters + { + get + { + return _tokenValidationParameters; + } + + set + { + if (value == null) + { + throw new ArgumentNullException("TokenValidationParameters"); + } + + _tokenValidationParameters = value; + } + } + } +} diff --git a/src/Microsoft.AspNet.Security.OAuthBearer/Resources.Designer.cs b/src/Microsoft.AspNet.Security.OAuthBearer/Resources.Designer.cs new file mode 100644 index 000000000..37abb160e --- /dev/null +++ b/src/Microsoft.AspNet.Security.OAuthBearer/Resources.Designer.cs @@ -0,0 +1,83 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.33440 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace Microsoft.AspNet.Security.OAuthBearer { + using System; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class Resources { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Resources() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Microsoft.AspNet.Security.OAuth.Resources", System.Reflection.IntrospectionExtensions.GetTypeInfo(typeof(Resources)).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + + /// + /// Looks up a localized string similar to The '{0}' option must be provided.. + /// + internal static string Exception_OptionMustBeProvided + { + get + { + return ResourceManager.GetString("Exception_OptionMustBeProvided", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to An ICertificateValidator cannot be specified at the same time as an HttpMessageHandler unless it is a WebRequestHandler.. + /// + internal static string Exception_ValidatorHandlerMismatch { + get { + return ResourceManager.GetString("Exception_ValidatorHandlerMismatch", resourceCulture); + } + } + } +} diff --git a/src/Microsoft.AspNet.Security.OAuthBearer/Resources.resx b/src/Microsoft.AspNet.Security.OAuthBearer/Resources.resx new file mode 100644 index 000000000..2a19bea96 --- /dev/null +++ b/src/Microsoft.AspNet.Security.OAuthBearer/Resources.resx @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + The '{0}' option must be provided. + + + An ICertificateValidator cannot be specified at the same time as an HttpMessageHandler unless it is a WebRequestHandler. + + \ No newline at end of file diff --git a/src/Microsoft.AspNet.Security.OAuthBearer/project.json b/src/Microsoft.AspNet.Security.OAuthBearer/project.json new file mode 100644 index 000000000..affb7e5b1 --- /dev/null +++ b/src/Microsoft.AspNet.Security.OAuthBearer/project.json @@ -0,0 +1,22 @@ +{ + "version": "1.0.0-*", + "description": "ASP.NET 5 middleware that enables an application to receive a OAuth bearer token.", + "dependencies": { + "Microsoft.AspNet.Security": "1.0.0-*", + "Microsoft.IdentityModel.Protocol.Extensions": "2.0.0-beta1-*", + "System.IdentityModel.Tokens": "5.0.0-beta1-*" + }, + "frameworks": { + "aspnet50": { + "frameworkAssemblies": { + "System.Net.Http.WebRequest": "", + "System.Net.Http": "" + } + }, + "aspnetcore50": { + "dependencies": { + "System.Net.Http.WinHttpHandler": "4.0.0-beta-*" + } + } + } +} diff --git a/src/Microsoft.AspNet.Security.OpenIDConnect/Microsoft.AspNet.Security.OpenIdConnect.kproj b/src/Microsoft.AspNet.Security.OpenIDConnect/Microsoft.AspNet.Security.OpenIdConnect.kproj new file mode 100644 index 000000000..ed1a12239 --- /dev/null +++ b/src/Microsoft.AspNet.Security.OpenIDConnect/Microsoft.AspNet.Security.OpenIdConnect.kproj @@ -0,0 +1,29 @@ + + + + 14.0 + $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) + + + + 674d128e-83bb-481a-a9d9-6d47872e1fc8 + Microsoft.AspNet.Security.OpenIdConnect + ..\..\artifacts\obj\$(MSBuildProjectName) + ..\..\artifacts\bin\$(MSBuildProjectName)\ + + + 2.0 + + + True + + + True + + + + + + + + \ No newline at end of file diff --git a/src/Microsoft.AspNet.Security.OpenIDConnect/NonceCache.cs b/src/Microsoft.AspNet.Security.OpenIDConnect/NonceCache.cs new file mode 100644 index 000000000..11c09b345 --- /dev/null +++ b/src/Microsoft.AspNet.Security.OpenIDConnect/NonceCache.cs @@ -0,0 +1,11 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace Microsoft.AspNet.Security.OpenIdConnect +{ + public interface INonceCache + { + string AddNonce(string nonce); + bool TryRemoveNonce(string nonce); + bool HasNonce(string nonce); + } +} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Security.OpenIDConnect/Notifications/AuthorizationCodeReceivedNotification.cs b/src/Microsoft.AspNet.Security.OpenIDConnect/Notifications/AuthorizationCodeReceivedNotification.cs new file mode 100644 index 000000000..cbcdc0618 --- /dev/null +++ b/src/Microsoft.AspNet.Security.OpenIDConnect/Notifications/AuthorizationCodeReceivedNotification.cs @@ -0,0 +1,45 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +using Microsoft.AspNet.Http; +using Microsoft.AspNet.Security.OpenIdConnect; +using Microsoft.IdentityModel.Protocols; +using System.Diagnostics.CodeAnalysis; +using System.IdentityModel.Tokens; + +namespace Microsoft.AspNet.Security.Notifications +{ + /// + /// This Notification can be used to be informed when an 'AuthorizationCode' is received over the OpenIdConnect protocol. + /// + public class AuthorizationCodeReceivedNotification : BaseNotification + { + /// + /// Creates a + /// + public AuthorizationCodeReceivedNotification(HttpContext context, OpenIdConnectAuthenticationOptions options) : base(context, options) + { + } + + /// + /// Gets or sets the 'code'. + /// + public string Code { get; set; } + + /// + /// Gets or sets the that was received in the id_token + code OpenIdConnectRequest. + /// + public JwtSecurityToken JwtSecurityToken { get; set; } + + /// + /// Gets or sets the . + /// + public OpenIdConnectMessage ProtocolMessage { get; set; } + + /// + /// Gets or sets the 'redirect_uri'. + /// + /// This is the redirect_uri that was sent in the id_token + code OpenIdConnectRequest. + [SuppressMessage("Microsoft.Design", "CA1056:UriPropertiesShouldNotBeStrings", Justification = "user controlled, not necessarily a URI")] + public string RedirectUri { get; set; } + } +} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Security.OpenIDConnect/OpenIdConnectAuthenticationDefaults.cs b/src/Microsoft.AspNet.Security.OpenIDConnect/OpenIdConnectAuthenticationDefaults.cs new file mode 100644 index 000000000..d6271488a --- /dev/null +++ b/src/Microsoft.AspNet.Security.OpenIDConnect/OpenIdConnectAuthenticationDefaults.cs @@ -0,0 +1,41 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + + +namespace Microsoft.AspNet.Security.OpenIdConnect +{ + /// + /// Default values related to OpenIdConnect authentication middleware + /// + public static class OpenIdConnectAuthenticationDefaults + { + /// + /// The default value used for OpenIdConnectAuthenticationOptions.AuthenticationType + /// + public const string AuthenticationType = "OpenIdConnect"; + + /// + /// The prefix used to provide a default OpenIdConnectAuthenticationOptions.CookieName + /// + public const string CookiePrefix = ".AspNet.OpenIdConnect."; + + /// + /// The default value for OpenIdConnectAuthenticationOptions.Caption. + /// + public const string Caption = "OpenIdConnect"; + + /// + /// The prefix used to for the a nonce in the cookie + /// + internal const string CookieNoncePrefix = ".AspNet.OpenIdConnect.Nonce."; + + /// + /// The property for the RedirectUri that was used when asking for a 'authorizationCode' + /// + public const string RedirectUriUsedForCodeKey = "OpenIdConnect.Code.RedirectUri"; + + /// + /// Constant used to identify state in openIdConnect protocal message + /// + internal const string AuthenticationPropertiesKey = "OpenIdConnect.AuthenticationProperties"; + } +} diff --git a/src/Microsoft.AspNet.Security.OpenIDConnect/OpenIdConnectAuthenticationExtensions.cs b/src/Microsoft.AspNet.Security.OpenIDConnect/OpenIdConnectAuthenticationExtensions.cs new file mode 100644 index 000000000..81a74b65c --- /dev/null +++ b/src/Microsoft.AspNet.Security.OpenIDConnect/OpenIdConnectAuthenticationExtensions.cs @@ -0,0 +1,29 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +using System; +using Microsoft.AspNet.Security.OpenIdConnect; +using Microsoft.Framework.OptionsModel; + +namespace Microsoft.AspNet.Builder +{ + /// + /// Extension methods for using + /// + public static class OpenIdConnectAuthenticationExtensions + { + /// + /// Adds the into the ASP.NET runtime. + /// + /// The application builder + /// Options which control the processing of the OpenIdConnect protocol and token validation. + /// The application builder + public static IApplicationBuilder UseOpenIdConnectAuthentication(this IApplicationBuilder app, Action configureOptions = null, string optionsName = "") + { + return app.UseMiddleware( + new ConfigureOptions(configureOptions ?? (o => { })) + { + Name = optionsName + }); + } + } +} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Security.OpenIDConnect/OpenIdConnectAuthenticationMiddleware.cs b/src/Microsoft.AspNet.Security.OpenIDConnect/OpenIdConnectAuthenticationMiddleware.cs new file mode 100644 index 000000000..bfe82b51f --- /dev/null +++ b/src/Microsoft.AspNet.Security.OpenIDConnect/OpenIdConnectAuthenticationMiddleware.cs @@ -0,0 +1,173 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +using System; +using System.Collections.ObjectModel; +using System.Diagnostics.CodeAnalysis; +using System.IdentityModel.Tokens; +using System.Net.Http; +using System.Text; +using Microsoft.AspNet.Builder; +using Microsoft.AspNet.Http; +using Microsoft.AspNet.Security.DataHandler; +using Microsoft.AspNet.Security.DataHandler.Encoder; +using Microsoft.AspNet.Security.DataHandler.Serializer; +using Microsoft.AspNet.Security.DataProtection; +using Microsoft.AspNet.Security.Infrastructure; +using Microsoft.Framework.Logging; +using Microsoft.Framework.OptionsModel; +using Microsoft.IdentityModel.Protocols; + +namespace Microsoft.AspNet.Security.OpenIdConnect +{ + /// + /// ASP.NET middleware for obtaining identities using OpenIdConnect protocol. + /// + public class OpenIdConnectAuthenticationMiddleware : AuthenticationMiddleware + { + private readonly ILogger _logger; + + /// + /// Initializes a + /// + /// The next middleware in the ASP.NET pipeline to invoke + /// The ASP.NET application + /// Configuration options for the middleware + [SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Justification = "Managed by caller")] + public OpenIdConnectAuthenticationMiddleware( + RequestDelegate next, + IServiceProvider services, + IDataProtectionProvider dataProtectionProvider, + ILoggerFactory loggerFactory, + IOptions externalOptions, + IOptions options, + ConfigureOptions configureOptions) + : base(next, services, options, configureOptions) + { + _logger = loggerFactory.Create(); + + if (string.IsNullOrWhiteSpace(Options.TokenValidationParameters.AuthenticationType)) + { + Options.TokenValidationParameters.AuthenticationType = externalOptions.Options.SignInAsAuthenticationType; + } + + if (Options.StateDataFormat == null) + { + var dataProtector = dataProtectionProvider.CreateDataProtector( + typeof(OpenIdConnectAuthenticationMiddleware).FullName, + typeof(string).FullName, + Options.AuthenticationType, + "v1"); + + Options.StateDataFormat = new PropertiesDataFormat(dataProtector); + } + + if (Options.StringDataFormat == null) + { + var dataProtector = dataProtectionProvider.CreateDataProtector( + typeof(OpenIdConnectAuthenticationMiddleware).FullName, + typeof(string).FullName, + Options.AuthenticationType, + "v1"); + + Options.StringDataFormat = new SecureDataFormat(new StringSerializer(), dataProtector, TextEncodings.Base64Url); + } + + if (Options.SecurityTokenValidators == null) + { + Options.SecurityTokenValidators = new Collection { new JwtSecurityTokenHandler() }; + } + + // if the user has not set the AuthorizeCallback, set it from the redirect_uri + if (!Options.CallbackPath.HasValue) + { + Uri redirectUri; + if (!string.IsNullOrEmpty(Options.RedirectUri) && Uri.TryCreate(Options.RedirectUri, UriKind.Absolute, out redirectUri)) + { + // Redirect_Uri must be a very specific, case sensitive value, so we can't generate it. Instead we generate AuthorizeCallback from it. + Options.CallbackPath = PathString.FromUriComponent(redirectUri); + } + } + + if (Options.Notifications == null) + { + Options.Notifications = new OpenIdConnectAuthenticationNotifications(); + } + + if (string.IsNullOrWhiteSpace(Options.TokenValidationParameters.ValidAudience) && !string.IsNullOrWhiteSpace(Options.ClientId)) + { + Options.TokenValidationParameters.ValidAudience = Options.ClientId; + } + + if (Options.ConfigurationManager == null) + { + if (Options.Configuration != null) + { + Options.ConfigurationManager = new StaticConfigurationManager(Options.Configuration); + } + else if (!(string.IsNullOrWhiteSpace(Options.MetadataAddress) && string.IsNullOrWhiteSpace(Options.Authority))) + { + if (string.IsNullOrWhiteSpace(Options.MetadataAddress) && !string.IsNullOrWhiteSpace(Options.Authority)) + { + Options.MetadataAddress = Options.Authority; + if (!Options.MetadataAddress.EndsWith("/", StringComparison.Ordinal)) + { + Options.MetadataAddress += "/"; + } + + Options.MetadataAddress += ".well-known/openid-configuration"; + } + + HttpClient httpClient = new HttpClient(ResolveHttpMessageHandler(Options)); + httpClient.Timeout = Options.BackchannelTimeout; + httpClient.MaxResponseContentBufferSize = 1024 * 1024 * 10; // 10 MB + Options.ConfigurationManager = new ConfigurationManager(Options.MetadataAddress, httpClient); + } + } + } + + /// + /// Provides the object for processing authentication-related requests. + /// + /// An configured with the supplied to the constructor. + protected override AuthenticationHandler CreateHandler() + { + return new OpenIdConnectAuthenticationHandler(_logger); + } + + [SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Justification = "Managed by caller")] + private static HttpMessageHandler ResolveHttpMessageHandler(OpenIdConnectAuthenticationOptions options) + { + HttpMessageHandler handler = options.BackchannelHttpHandler ?? +#if ASPNET50 + new WebRequestHandler(); + // If they provided a validator, apply it or fail. + if (options.BackchannelCertificateValidator != null) + { + // Set the cert validate callback + var webRequestHandler = handler as WebRequestHandler; + if (webRequestHandler == null) + { + throw new InvalidOperationException(Resources.Exception_ValidatorHandlerMismatch); + } + webRequestHandler.ServerCertificateValidationCallback = options.BackchannelCertificateValidator.Validate; + } +#else + new WinHttpHandler(); +#endif + return handler; + } + + private class StringSerializer : IDataSerializer + { + public string Deserialize(byte[] data) + { + return Encoding.UTF8.GetString(data); + } + + public byte[] Serialize(string model) + { + return Encoding.UTF8.GetBytes(model); + } + } + } +} diff --git a/src/Microsoft.AspNet.Security.OpenIDConnect/OpenIdConnectAuthenticationNotifications.cs b/src/Microsoft.AspNet.Security.OpenIDConnect/OpenIdConnectAuthenticationNotifications.cs new file mode 100644 index 000000000..36ee2fd25 --- /dev/null +++ b/src/Microsoft.AspNet.Security.OpenIDConnect/OpenIdConnectAuthenticationNotifications.cs @@ -0,0 +1,59 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +using System; +using System.Threading.Tasks; +using Microsoft.AspNet.Security.Notifications; +using Microsoft.IdentityModel.Protocols; + +namespace Microsoft.AspNet.Security.OpenIdConnect +{ + /// + /// Specifies events which the invokes to enable developer control over the authentication process. + /// + public class OpenIdConnectAuthenticationNotifications + { + /// + /// Creates a new set of notifications. Each notification has a default no-op behavior unless otherwise documented. + /// + public OpenIdConnectAuthenticationNotifications() + { + AuthenticationFailed = notification => Task.FromResult(0); + AuthorizationCodeReceived = notification => Task.FromResult(0); + MessageReceived = notification => Task.FromResult(0); + SecurityTokenReceived = notification => Task.FromResult(0); + SecurityTokenValidated = notification => Task.FromResult(0); + RedirectToIdentityProvider = notification => Task.FromResult(0); + } + + /// + /// Invoked if exceptions are thrown during request processing. The exceptions will be re-thrown after this event unless suppressed. + /// + public Func, Task> AuthenticationFailed { get; set; } + + /// + /// Invoked after security token validation if an authorization code is present in the protocol message. + /// + public Func AuthorizationCodeReceived { get; set; } + + /// + /// Invoked when a protocol message is first received. + /// + public Func, Task> MessageReceived { get; set; } + + /// + /// Invoked to manipulate redirects to the identity provider for SignIn, SignOut, or Challenge. + /// + public Func, Task> RedirectToIdentityProvider { get; set; } + + /// + /// Invoked with the security token that has been extracted from the protocol message. + /// + public Func, Task> SecurityTokenReceived { get; set; } + + /// + /// Invoked after the security token has passed validation and a ClaimsIdentity has been generated. + /// + public Func, Task> SecurityTokenValidated { get; set; } + + } +} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Security.OpenIDConnect/OpenIdConnectAuthenticationOptions.cs b/src/Microsoft.AspNet.Security.OpenIDConnect/OpenIdConnectAuthenticationOptions.cs new file mode 100644 index 000000000..5022cbf3c --- /dev/null +++ b/src/Microsoft.AspNet.Security.OpenIDConnect/OpenIdConnectAuthenticationOptions.cs @@ -0,0 +1,337 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +using System; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using System.IdentityModel.Tokens; +using System.Net.Http; +using Microsoft.AspNet.Http; +using Microsoft.AspNet.Http.Security; +using Microsoft.IdentityModel.Protocols; + +namespace Microsoft.AspNet.Security.OpenIdConnect +{ + /// + /// Configuration options for + /// + public class OpenIdConnectAuthenticationOptions : AuthenticationOptions + { + private TimeSpan _backchannelTimeout; + private OpenIdConnectProtocolValidator _protocolValidator; + private ICollection _securityTokenValidators; + private ISecureDataFormat _stateDataFormat; + private ISecureDataFormat _stringDataFormat; + private TokenValidationParameters _tokenValidationParameters; + + /// + /// Initializes a new + /// + public OpenIdConnectAuthenticationOptions() + : this(OpenIdConnectAuthenticationDefaults.AuthenticationType) + { + } + + /// + /// Initializes a new + /// + /// + /// Defaults: + /// AddNonceToRequest: true. + /// AuthenticationMode: . + /// BackchannelTimeout: 1 minute. + /// Caption: . + /// ProtocolValidator: new . + /// RefreshOnIssuerKeyNotFound: true + /// ResponseType: + /// Scope: . + /// TokenValidationParameters: new with AuthenticationType = authenticationType. + /// UseTokenLifetime: true. + /// + /// will be used to when creating the for the AuthenticationType property. + [SuppressMessage("Microsoft.Globalization", "CA1303:Do not pass literals as localized parameters", MessageId = "Microsoft.Owin.Security.OpenIdConnect.OpenIdConnectAuthenticationOptions.set_Caption(System.String)", Justification = "Not a LOC field")] + public OpenIdConnectAuthenticationOptions(string authenticationType) + { + AuthenticationMode = AuthenticationMode.Active; + AuthenticationType = authenticationType; + BackchannelTimeout = TimeSpan.FromMinutes(1); + Caption = OpenIdConnectAuthenticationDefaults.Caption; + ProtocolValidator = new OpenIdConnectProtocolValidator(); + RefreshOnIssuerKeyNotFound = true; + ResponseType = OpenIdConnectResponseTypes.CodeIdToken; + Scope = OpenIdConnectScopes.OpenIdProfile; + TokenValidationParameters = new TokenValidationParameters(); + UseTokenLifetime = true; + } + + /// + /// Gets or sets the Authority to use when making OpenIdConnect calls. + /// + public string Authority { get; set; } + + /// + /// An optional constrained path on which to process the authentication callback. + /// If not provided and RedirectUri is available, this value will be generated from RedirectUri. + /// + /// If you set this value, then the will only listen for posts at this address. + /// If the IdentityProvider does not post to this address, you may end up in a 401 -> IdentityProvider -> Client -> 401 -> ... + public PathString CallbackPath { get; set; } + +#if ASPNET50 + /// + /// Gets or sets the a pinned certificate validator to use to validate the endpoints used + /// when retrieving metadata. + /// + /// + /// The pinned certificate validator. + /// + /// If this property is null then the default certificate checks are performed, + /// validating the subject name and if the signing chain is a trusted party. + public ICertificateValidator BackchannelCertificateValidator { get; set; } +#endif + /// + /// The HttpMessageHandler used to retrieve metadata. + /// This cannot be set at the same time as BackchannelCertificateValidator unless the value + /// is a WebRequestHandler. + /// + public HttpMessageHandler BackchannelHttpHandler { get; set; } + + /// + /// Gets or sets the timeout when using the backchannel to make an http call. + /// + [SuppressMessage("Microsoft.Usage", "CA2208:InstantiateArgumentExceptionsCorrectly", Justification = "By design we use the property name in the exception")] + public TimeSpan BackchannelTimeout + { + get + { + return _backchannelTimeout; + } + + set + { + if (value <= TimeSpan.Zero) + { + throw new ArgumentOutOfRangeException("BackchannelTimeout", value, Resources.ArgsException_BackchallelLessThanZero); + } + + _backchannelTimeout = value; + } + } + + /// + /// Get or sets the text that the user can display on a sign in user interface. + /// + public string Caption + { + get { return Description.Caption; } + set { Description.Caption = value; } + } + + /// + /// Gets or sets the 'client_id'. + /// + public string ClientId { get; set; } + + /// + /// Gets or sets the 'client_secret'. + /// + public string ClientSecret { get; set; } + + /// + /// Configuration provided directly by the developer. If provided, then MetadataAddress and the Backchannel properties + /// will not be used. This information should not be updated during request processing. + /// + public OpenIdConnectConfiguration Configuration { get; set; } + + /// + /// The OpenIdConnect protocol http://openid.net/specs/openid-connect-core-1_0.html + /// recommends adding a nonce to a request as a mitigation against replay attacks when requesting id_tokens. + /// By default the runtime uses cookies with unique names generated from a hash of the nonce. + /// + public INonceCache NoneCache { get; set; } + + /// + /// Gets or sets the discovery endpoint for obtaining metadata + /// + public string MetadataAddress { get; set; } + + /// + /// Gets or sets the expected audience for any received JWT token. + /// + /// + /// The expected audience for any received JWT token. + /// + public string Audience { get; set; } + + /// + /// Responsible for retrieving, caching, and refreshing the configuration from metadata. + /// If not provided, then one will be created using the MetadataAddress and Backchannel properties. + /// + public IConfigurationManager ConfigurationManager { get; set; } + + /// + /// Gets or sets if a metadata refresh should be attempted after a SecurityTokenSignatureKeyNotFoundException. This allows for automatic + /// recovery in the event of a signature key rollover. This is enabled by default. + /// + public bool RefreshOnIssuerKeyNotFound { get; set; } + + /// + /// Gets or sets the to notify when processing OpenIdConnect messages. + /// + public OpenIdConnectAuthenticationNotifications Notifications { get; set; } + + /// + /// Gets or sets the that is used ensure the 'id_token' received + /// is valid per: http://openid.net/specs/openid-connect-core-1_0.html#IDTokenValidation + /// + /// if 'value' is null. + public OpenIdConnectProtocolValidator ProtocolValidator + { + get + { + return _protocolValidator; + } + set + { + if (value == null) + { + throw new ArgumentNullException("value"); + } + + _protocolValidator = value; + } + } + + /// + /// Gets or sets the 'post_logout_redirect_uri' + /// + /// This is sent to the OP as the redirect for the user-agent. + [SuppressMessage("Microsoft.Design", "CA1056:UriPropertiesShouldNotBeStrings", Justification = "By design")] + [SuppressMessage("Microsoft.Naming", "CA1726:UsePreferredTerms", MessageId = "Logout", Justification = "This is the term used in the spec.")] + public string PostLogoutRedirectUri { get; set; } + + /// + /// Gets or sets the 'redirect_uri'. + /// + [SuppressMessage("Microsoft.Design", "CA1056:UriPropertiesShouldNotBeStrings", Justification = "By Design")] + public string RedirectUri { get; set; } + + /// + /// Gets or sets the 'resource'. + /// + public string Resource { get; set; } + + /// + /// Gets or sets the 'response_type'. + /// + public string ResponseType { get; set; } + + /// + /// Gets or sets the 'scope'. + /// + public string Scope { get; set; } + + /// + /// Gets or sets the AuthenticationType used when creating the . + /// + public string SignInAsAuthenticationType + { + get { return TokenValidationParameters.AuthenticationType; } + set { TokenValidationParameters.AuthenticationType = value; } + } + + /// + /// Gets or sets the type used to secure data handled by the middleware. + /// + public ISecureDataFormat StateDataFormat + { + get + { + return _stateDataFormat; + } + set + { + if (value == null) + { + throw new ArgumentNullException("value"); + } + + _stateDataFormat = value; + } + } + + /// + /// Gets or sets the type used to secure strings used by the middleware. + // + public ISecureDataFormat StringDataFormat + { + get + { + return _stringDataFormat; + } + set + { + if (value == null) + { + throw new ArgumentNullException("value"); + } + + _stringDataFormat = value; + } + } + + /// + /// Gets or sets the for validating tokens. + /// + /// if 'value' is null. + public ICollection SecurityTokenValidators + { + get + { + return _securityTokenValidators; + } + + set + { + if (value == null) + { + throw new ArgumentNullException("SecurityTokenValidators"); + } + + _securityTokenValidators = value; + } + } + + /// + /// Gets or sets the TokenValidationParameters + /// + /// Contains the types and definitions required for validating a token. + public TokenValidationParameters TokenValidationParameters + { + get + { + return _tokenValidationParameters; + } + + set + { + if (value == null) + { + throw new ArgumentNullException("value"); + } + + _tokenValidationParameters = value; + } + } + + /// + /// Indicates that the authentication session lifetime (e.g. cookies) should match that of the authentication token. + /// If the token does not provide lifetime information then normal session lifetimes will be used. + /// This is enabled by default. + /// + public bool UseTokenLifetime + { + get; + set; + } + } +} diff --git a/src/Microsoft.AspNet.Security.OpenIDConnect/OpenidConnectAuthenticationHandler.cs b/src/Microsoft.AspNet.Security.OpenIDConnect/OpenidConnectAuthenticationHandler.cs new file mode 100644 index 000000000..530503910 --- /dev/null +++ b/src/Microsoft.AspNet.Security.OpenIDConnect/OpenidConnectAuthenticationHandler.cs @@ -0,0 +1,577 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +using System; +using System.Globalization; +using System.IdentityModel.Tokens; +using System.IO; +using System.Linq; +using System.Runtime.ExceptionServices; +using System.Security.Claims; +using System.Threading.Tasks; +using Microsoft.AspNet.Http; +using Microsoft.AspNet.Http.Security; +using Microsoft.AspNet.Security.Infrastructure; +using Microsoft.AspNet.Security.Notifications; +using Microsoft.Framework.Logging; +using Microsoft.IdentityModel.Protocols; + +namespace Microsoft.AspNet.Security.OpenIdConnect +{ + /// + /// A per-request authentication handler for the OpenIdConnectAuthenticationMiddleware. + /// + public class OpenIdConnectAuthenticationHandler : AuthenticationHandler + { + private const string NonceProperty = "N"; + private const string UriSchemeDelimiter = "://"; + private readonly ILogger _logger; + private OpenIdConnectConfiguration _configuration; + + /// + /// Creates a new OpenIdConnectAuthenticationHandler + /// + /// + public OpenIdConnectAuthenticationHandler(ILogger logger) + { + _logger = logger; + } + + private string CurrentUri + { + get + { + return Request.Scheme + + UriSchemeDelimiter + + Request.Host + + Request.PathBase + + Request.Path + + Request.QueryString; + } + } + + protected override void ApplyResponseGrant() + { + ApplyResponseGrantAsync().GetAwaiter().GetResult(); + } + + /// + /// Handles Signout + /// + /// + protected override async Task ApplyResponseGrantAsync() + { + var signout = SignOutContext; + if (signout != null) + { + if (_configuration == null && Options.ConfigurationManager != null) + { + _configuration = await Options.ConfigurationManager.GetConfigurationAsync(Context.RequestAborted); + } + + OpenIdConnectMessage openIdConnectMessage = new OpenIdConnectMessage() + { + IssuerAddress = _configuration == null ? string.Empty : (_configuration.EndSessionEndpoint ?? string.Empty), + RequestType = OpenIdConnectRequestType.LogoutRequest, + }; + + // Set End_Session_Endpoint in order: + // 1. properties.Redirect + // 2. Options.Wreply + AuthenticationProperties properties = new AuthenticationProperties(); // TODO signout.Properties; + if (properties != null && !string.IsNullOrEmpty(properties.RedirectUri)) + { + openIdConnectMessage.PostLogoutRedirectUri = properties.RedirectUri; + } + else if (!string.IsNullOrWhiteSpace(Options.PostLogoutRedirectUri)) + { + openIdConnectMessage.PostLogoutRedirectUri = Options.PostLogoutRedirectUri; + } + + var notification = new RedirectToIdentityProviderNotification(Context, Options) + { + ProtocolMessage = openIdConnectMessage + }; + await Options.Notifications.RedirectToIdentityProvider(notification); + + if (!notification.HandledResponse) + { + string redirectUri = notification.ProtocolMessage.CreateLogoutRequestUrl(); + if (!Uri.IsWellFormedUriString(redirectUri, UriKind.Absolute)) + { + _logger.WriteWarning("The logout redirect URI is malformed: " + redirectUri); + } + Response.Redirect(redirectUri); + } + } + } + + protected override void ApplyResponseChallenge() + { + ApplyResponseChallengeAsync().GetAwaiter().GetResult(); + } + + /// + /// Responds to a 401 Challenge sends an OpenIdConnect message to the 'identity authority' to obtain an identity. + /// + /// + protected override async Task ApplyResponseChallengeAsync() + { + if ((Response.StatusCode != 401) || (ChallengeContext == null)) + { + return; + } + + // order for redirect_uri + // 1. challenge.Properties.RedirectUri + // 2. CurrentUri + AuthenticationProperties properties = new AuthenticationProperties(ChallengeContext.Properties); + if (string.IsNullOrEmpty(properties.RedirectUri)) + { + properties.RedirectUri = CurrentUri; + } + + // this value will be passed to the AuthorizationCodeReceivedNotification + if (!string.IsNullOrWhiteSpace(Options.RedirectUri)) + { + properties.Dictionary.Add(OpenIdConnectAuthenticationDefaults.RedirectUriUsedForCodeKey, Options.RedirectUri); + } + + if (_configuration == null && Options.ConfigurationManager != null) + { + _configuration = await Options.ConfigurationManager.GetConfigurationAsync(Context.RequestAborted); + } + + OpenIdConnectMessage openIdConnectMessage = new OpenIdConnectMessage + { + ClientId = Options.ClientId, + IssuerAddress = _configuration == null ? string.Empty : (_configuration.AuthorizationEndpoint ?? string.Empty), + RedirectUri = Options.RedirectUri, + RequestType = OpenIdConnectRequestType.AuthenticationRequest, + Resource = Options.Resource, + ResponseMode = OpenIdConnectResponseModes.FormPost, + ResponseType = Options.ResponseType, + Scope = Options.Scope, + State = OpenIdConnectAuthenticationDefaults.AuthenticationPropertiesKey + "=" + Uri.EscapeDataString(Options.StateDataFormat.Protect(properties)) + }; + + // TODO - brentschmaltz, if INonceCache is set should we even consider if ProtocolValidator is set? + if (Options.ProtocolValidator.RequireNonce) + { + openIdConnectMessage.Nonce = Options.ProtocolValidator.GenerateNonce(); + if (Options.NoneCache != null) + { + Options.NoneCache.AddNonce(openIdConnectMessage.Nonce); + } + else + { + RememberNonce(openIdConnectMessage.Nonce); + } + } + + var notification = new RedirectToIdentityProviderNotification(Context, Options) + { + ProtocolMessage = openIdConnectMessage + }; + + await Options.Notifications.RedirectToIdentityProvider(notification); + if (!notification.HandledResponse) + { + string redirectUri = notification.ProtocolMessage.CreateAuthenticationRequestUrl(); + if (!Uri.IsWellFormedUriString(redirectUri, UriKind.Absolute)) + { + _logger.WriteWarning("The authenticate redirect URI is malformed: " + redirectUri); + } + + Response.Redirect(redirectUri); + } + } + + protected override AuthenticationTicket AuthenticateCore() + { + return AuthenticateCoreAsync().GetAwaiter().GetResult(); + } + + /// + /// Invoked to process incoming OpenIdConnect messages. + /// + /// An if successful. + protected override async Task AuthenticateCoreAsync() + { + // Allow login to be constrained to a specific path. Need to make this runtime configurable. + if (Options.CallbackPath.HasValue && Options.CallbackPath != (Request.PathBase + Request.Path)) + { + return null; + } + + OpenIdConnectMessage openIdConnectMessage = null; + + // assumption: if the ContentType is "application/x-www-form-urlencoded" it should be safe to read as it is small. + if (string.Equals(Request.Method, "POST", StringComparison.OrdinalIgnoreCase) + && !string.IsNullOrWhiteSpace(Request.ContentType) + // May have media/type; charset=utf-8, allow partial match. + && Request.ContentType.StartsWith("application/x-www-form-urlencoded", StringComparison.OrdinalIgnoreCase) + && Request.Body.CanRead) + { + IFormCollection form = await Request.ReadFormAsync(); + Request.Body.Seek(0, SeekOrigin.Begin); + + // TODO: a delegate on OpenIdConnectAuthenticationOptions would allow for users to hook their own custom message. + openIdConnectMessage = new OpenIdConnectMessage(form); + } + + if (openIdConnectMessage == null) + { + return null; + } + + ExceptionDispatchInfo authFailedEx = null; + try + { + var messageReceivedNotification = new MessageReceivedNotification(Context, Options) + { + ProtocolMessage = openIdConnectMessage + }; + + await Options.Notifications.MessageReceived(messageReceivedNotification); + if (messageReceivedNotification.HandledResponse) + { + return messageReceivedNotification.AuthenticationTicket; + } + + if (messageReceivedNotification.Skipped) + { + return null; + } + + // runtime always adds state, if we don't find it OR we failed to 'unprotect' it this is not a message we + // should process. + AuthenticationProperties properties = GetPropertiesFromState(openIdConnectMessage.State); + if (properties == null) + { + _logger.WriteWarning("The state field is missing or invalid."); + return null; + } + + // devs will need to hook AuthenticationFailedNotification to avoid having 'raw' runtime errors displayed to users. + if (!string.IsNullOrWhiteSpace(openIdConnectMessage.Error)) + { + throw new OpenIdConnectProtocolException( + string.Format(CultureInfo.InvariantCulture, + openIdConnectMessage.Error, + Resources.Exception_OpenIdConnectMessageError, openIdConnectMessage.ErrorDescription ?? string.Empty, openIdConnectMessage.ErrorUri ?? string.Empty)); + } + + // code is only accepted with id_token, in this version, hence check for code is inside this if + // OpenIdConnect protocol allows a Code to be received without the id_token + if (string.IsNullOrWhiteSpace(openIdConnectMessage.IdToken)) + { + _logger.WriteWarning("The id_token is missing."); + return null; + } + + var securityTokenReceivedNotification = new SecurityTokenReceivedNotification(Context, Options) + { + ProtocolMessage = openIdConnectMessage + }; + + await Options.Notifications.SecurityTokenReceived(securityTokenReceivedNotification); + if (securityTokenReceivedNotification.HandledResponse) + { + return securityTokenReceivedNotification.AuthenticationTicket; + } + + if (securityTokenReceivedNotification.Skipped) + { + return null; + } + + if (_configuration == null && Options.ConfigurationManager != null) + { + _configuration = await Options.ConfigurationManager.GetConfigurationAsync(Context.RequestAborted); + } + + // Copy and augment to avoid cross request race conditions for updated configurations. + TokenValidationParameters validationParameters = Options.TokenValidationParameters.Clone(); + if (_configuration != null) + { + if (string.IsNullOrWhiteSpace(validationParameters.ValidIssuer)) + { + validationParameters.ValidIssuer = _configuration.Issuer; + } + else if (!string.IsNullOrWhiteSpace(_configuration.Issuer)) + { + validationParameters.ValidIssuers = (validationParameters.ValidIssuers == null ? new[] { _configuration.Issuer } : validationParameters.ValidIssuers.Concat(new[] { _configuration.Issuer })); + } + + validationParameters.IssuerSigningKeys = (validationParameters.IssuerSigningKeys == null ? _configuration.SigningKeys : validationParameters.IssuerSigningKeys.Concat(_configuration.SigningKeys)); + } + + AuthenticationTicket ticket; + SecurityToken validatedToken = null; + ClaimsPrincipal principal = null; + JwtSecurityToken jwt = null; + + foreach (var validator in Options.SecurityTokenValidators) + { + if (validator.CanReadToken(openIdConnectMessage.IdToken)) + { + principal = validator.ValidateToken(openIdConnectMessage.IdToken, validationParameters, out validatedToken); + jwt = validatedToken as JwtSecurityToken; + if (jwt == null) + { + throw new InvalidOperationException("Validated Security Token must be a JwtSecurityToken was: " + (validatedToken == null ? "null" : validatedToken.GetType().ToString())); + } + } + } + + if (validatedToken == null) + { + throw new InvalidOperationException("No SecurityTokenValidator found for token: " + openIdConnectMessage.IdToken); + } + + ticket = new AuthenticationTicket(principal, properties, Options.AuthenticationType); + if (!string.IsNullOrWhiteSpace(openIdConnectMessage.SessionState)) + { + ticket.Properties.Dictionary[OpenIdConnectSessionProperties.SessionState] = openIdConnectMessage.SessionState; + } + + if (_configuration != null && !string.IsNullOrWhiteSpace(_configuration.CheckSessionIframe)) + { + ticket.Properties.Dictionary[OpenIdConnectSessionProperties.CheckSessionIFrame] = _configuration.CheckSessionIframe; + } + + if (Options.UseTokenLifetime) + { + // Override any session persistence to match the token lifetime. + DateTime issued = validatedToken.ValidFrom; + if (issued != DateTime.MinValue) + { + ticket.Properties.IssuedUtc = issued; + } + + DateTime expires = validatedToken.ValidTo; + if (expires != DateTime.MinValue) + { + ticket.Properties.ExpiresUtc = expires; + } + + ticket.Properties.AllowRefresh = false; + } + + var securityTokenValidatedNotification = new SecurityTokenValidatedNotification(Context, Options) + { + AuthenticationTicket = ticket, + ProtocolMessage = openIdConnectMessage + }; + + await Options.Notifications.SecurityTokenValidated(securityTokenValidatedNotification); + if (securityTokenValidatedNotification.HandledResponse) + { + return securityTokenValidatedNotification.AuthenticationTicket; + } + + if (securityTokenValidatedNotification.Skipped) + { + return null; + } + + var protocolValidationContext = new OpenIdConnectProtocolValidationContext + { + AuthorizationCode = openIdConnectMessage.Code, + Nonce = RetrieveNonce(jwt.Payload.Nonce), + }; + + Options.ProtocolValidator.Validate(jwt, protocolValidationContext); + if (openIdConnectMessage.Code != null) + { + var authorizationCodeReceivedNotification = new AuthorizationCodeReceivedNotification(Context, Options) + { + AuthenticationTicket = ticket, + Code = openIdConnectMessage.Code, + JwtSecurityToken = jwt, + ProtocolMessage = openIdConnectMessage, + RedirectUri = ticket.Properties.Dictionary.ContainsKey(OpenIdConnectAuthenticationDefaults.RedirectUriUsedForCodeKey) ? + ticket.Properties.Dictionary[OpenIdConnectAuthenticationDefaults.RedirectUriUsedForCodeKey] : string.Empty, + }; + + await Options.Notifications.AuthorizationCodeReceived(authorizationCodeReceivedNotification); + if (authorizationCodeReceivedNotification.HandledResponse) + { + return authorizationCodeReceivedNotification.AuthenticationTicket; + } + + if (authorizationCodeReceivedNotification.Skipped) + { + return null; + } + } + + return ticket; + } + catch (Exception exception) + { + // We can't await inside a catch block, capture and handle outside. + authFailedEx = ExceptionDispatchInfo.Capture(exception); + } + + if (authFailedEx != null) + { + _logger.WriteError("Exception occurred while processing message", authFailedEx.SourceException); + + // Refresh the configuration for exceptions that may be caused by key rollovers. The user can also request a refresh in the notification. + if (Options.RefreshOnIssuerKeyNotFound && authFailedEx.SourceException.GetType().Equals(typeof(SecurityTokenSignatureKeyNotFoundException))) + { + Options.ConfigurationManager.RequestRefresh(); + } + + var authenticationFailedNotification = new AuthenticationFailedNotification(Context, Options) + { + ProtocolMessage = openIdConnectMessage, + Exception = authFailedEx.SourceException + }; + + await Options.Notifications.AuthenticationFailed(authenticationFailedNotification); + if (authenticationFailedNotification.HandledResponse) + { + return authenticationFailedNotification.AuthenticationTicket; + } + + if (authenticationFailedNotification.Skipped) + { + return null; + } + + authFailedEx.Throw(); + } + + return null; + } + + /// + /// Adds the nonce to . + /// + /// the nonce to remember. + /// is called to add a cookie with the name: 'OpenIdConnectAuthenticationDefaults.Nonce + (nonce)'. + /// The value of the cookie is: "N". + private void RememberNonce(string nonce) + { + if (string.IsNullOrWhiteSpace(nonce)) + { + throw new ArgumentNullException("nonce"); + } + + Response.Cookies.Append( + OpenIdConnectAuthenticationDefaults.CookieNoncePrefix + Options.StringDataFormat.Protect(nonce), + NonceProperty, + new CookieOptions + { + HttpOnly = true, + Secure = Request.IsSecure + }); + } + + /// + /// Searches for a matching nonce. + /// + /// the nonce that was found in the jwt token. + /// 'nonceExpectedValue' if a cookie is found that matches, null otherwise. + /// Examins that start with the prefix: 'OpenIdConnectAuthenticationDefaults.Nonce'. + /// is used to obtain the actual 'nonce'. If the nonce is found, then is called. + private string RetrieveNonce(string nonceExpectedValue) + { + if (nonceExpectedValue == null) + { + return null; + } + + foreach (var nonceKey in Request.Cookies.Keys) + { + if (nonceKey.StartsWith(OpenIdConnectAuthenticationDefaults.CookieNoncePrefix)) + { + try + { + string nonceDecodedValue = Options.StringDataFormat.Unprotect(nonceKey.Substring(OpenIdConnectAuthenticationDefaults.CookieNoncePrefix.Length, nonceKey.Length - OpenIdConnectAuthenticationDefaults.CookieNoncePrefix.Length)); + if (nonceDecodedValue == nonceExpectedValue) + { + var cookieOptions = new CookieOptions + { + HttpOnly = true, + Secure = Request.IsSecure + }; + + Response.Cookies.Delete(nonceKey, cookieOptions); + return nonceExpectedValue; + } + } + catch (Exception ex) + { + _logger.WriteWarning("Failed to un-protect the nonce cookie.", ex); + } + } + } + + return null; + } + + private AuthenticationProperties GetPropertiesFromState(string state) + { + // assume a well formed query string: OpenIdConnectAuthenticationDefaults.AuthenticationPropertiesKey=kasjd;fljasldkjflksdj<&c=d> + int startIndex = 0; + if (string.IsNullOrWhiteSpace(state) || (startIndex = state.IndexOf(OpenIdConnectAuthenticationDefaults.AuthenticationPropertiesKey, StringComparison.Ordinal)) == -1) + { + return null; + } + + int authenticationIndex = startIndex + OpenIdConnectAuthenticationDefaults.AuthenticationPropertiesKey.Length; + if (authenticationIndex == -1 || authenticationIndex == state.Length || state[authenticationIndex] != '=') + { + return null; + } + + // scan rest of string looking for '&' + authenticationIndex++; + int endIndex = state.Substring(authenticationIndex, state.Length - authenticationIndex).IndexOf("&", StringComparison.Ordinal); + + // -1 => no other parameters are after the AuthenticationPropertiesKey + if (endIndex == -1) + { + return Options.StateDataFormat.Unprotect(Uri.UnescapeDataString(state.Substring(authenticationIndex).Replace('+', ' '))); + } + else + { + return Options.StateDataFormat.Unprotect(Uri.UnescapeDataString(state.Substring(authenticationIndex, endIndex).Replace('+', ' '))); + } + } + + /// + /// Calls InvokeReplyPathAsync + /// + /// True if the request was handled, false if the next middleware should be invoked. + public override Task InvokeAsync() + { + return InvokeReplyPathAsync(); + } + + private async Task InvokeReplyPathAsync() + { + AuthenticationTicket ticket = await AuthenticateAsync(); + + if (ticket != null) + { + if (ticket.Principal != null) + { + Request.HttpContext.Response.SignIn(ticket.Properties, ticket.Principal.Identities); + } + + // Redirect back to the original secured resource, if any. + if (!string.IsNullOrWhiteSpace(ticket.Properties.RedirectUri)) + { + Response.Redirect(ticket.Properties.RedirectUri); + return true; + } + } + + return false; + } + } +} diff --git a/src/Microsoft.AspNet.Security.OpenIDConnect/Project.json b/src/Microsoft.AspNet.Security.OpenIDConnect/Project.json new file mode 100644 index 000000000..7a6d95a05 --- /dev/null +++ b/src/Microsoft.AspNet.Security.OpenIDConnect/Project.json @@ -0,0 +1,48 @@ +{ + "version": "1.0.0-*", + "dependencies": { + "Microsoft.AspNet.Http.Extensions": "1.0.0-*", + "Microsoft.AspNet.Security": "1.0.0-*", + "Microsoft.AspNet.Security.DataProtection": "1.0.0-*", + "Microsoft.AspNet.WebUtilities": "1.0.0-*", + "Microsoft.Framework.Logging": "1.0.0-*", + "Newtonsoft.Json": "6.0.4", + "Microsoft.IdentityModel.Protocol.Extensions": "2.0.0.0-beta1-*", + "System.IdentityModel.Tokens": "5.0.0.0-beta1-*" + }, + "frameworks": { + "aspnet50": { + "frameworkAssemblies": { + "System.Net.Http": "", + "System.Net.Http.WebRequest": "" + } + }, + "aspnetcore50": { + "dependencies": { + "System.Collections": "4.0.10-beta-*", + "System.ComponentModel": "4.0.0-beta-*", + "System.Console": "4.0.0-beta-*", + "System.Diagnostics.Debug": "4.0.10-beta-*", + "System.Diagnostics.Tools": "4.0.0-beta-*", + "System.Dynamic.Runtime": "4.0.0-beta-*", + "System.Globalization": "4.0.10-beta-*", + "System.IO": "4.0.10-beta-*", + "System.IO.Compression": "4.0.0-beta-*", + "System.Linq": "4.0.0-beta-*", + "System.Net.Http.WinHttpHandler": "4.0.0-beta-*", + "System.ObjectModel": "4.0.10-beta-*", + "System.Reflection": "4.0.10-beta-*", + "System.Resources.ResourceManager": "4.0.0-beta-*", + "System.Runtime": "4.0.20-beta-*", + "System.Runtime.Extensions": "4.0.10-beta-*", + "System.Runtime.InteropServices": "4.0.20-beta-*", + "System.Security.Claims": "4.0.0-beta-*", + "System.Security.Cryptography.Hashing.Algorithms": "4.0.0-beta-*", + "System.Security.Principal": "4.0.0-beta-*", + "System.Threading": "4.0.0-beta-*", + "System.Threading.Tasks": "4.0.10-beta-*", + "System.Net.Http": "4.0.0-*" + } + } + } +} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Security.OpenIDConnect/Resources.Designer.cs b/src/Microsoft.AspNet.Security.OpenIDConnect/Resources.Designer.cs new file mode 100644 index 000000000..f5bfc6044 --- /dev/null +++ b/src/Microsoft.AspNet.Security.OpenIDConnect/Resources.Designer.cs @@ -0,0 +1,101 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.34014 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace Microsoft.AspNet.Security.OpenIdConnect { + using System; + using System.Reflection; + + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class Resources { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Resources() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Microsoft.Owin.Security.OpenIdConnect.Resources", IntrospectionExtensions.GetTypeInfo(typeof(Resources)).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + + /// + /// Looks up a localized string similar to BackchannelTimeout cannot be less or equal to TimeSpan.Zero.. + /// + internal static string ArgsException_BackchallelLessThanZero { + get { + return ResourceManager.GetString("ArgsException_BackchallelLessThanZero", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to "OpenIdConnectMessage.Error was not null, indicating an error. Error: '{0}'. Error_Description (may be empty): '{1}'. Error_Uri (may be empty): '{2}'.". + /// + internal static string Exception_OpenIdConnectMessageError { + get { + return ResourceManager.GetString("Exception_OpenIdConnectMessageError", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to OIDC_20001: The query string for Logout is not a well formed URI. The runtime cannot redirect. Redirect uri: '{0}'.. + /// + internal static string Exception_RedirectUri_LogoutQueryString_IsNotWellFormed { + get { + return ResourceManager.GetString("Exception_RedirectUri_LogoutQueryString_IsNotWellFormed", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to An ICertificateValidator cannot be specified at the same time as an HttpMessageHandler unless it is a An ICertificateValidator cannot be specified at the same time as an HttpMessageHandler unless it is a WebRequestHandler.. + /// + internal static string Exception_ValidatorHandlerMismatch { + get { + return ResourceManager.GetString("Exception_ValidatorHandlerMismatch", resourceCulture); + } + } + } +} diff --git a/src/Microsoft.AspNet.Security/AuthenticationTicket.cs b/src/Microsoft.AspNet.Security/AuthenticationTicket.cs index b9457aa91..7b7e50998 100644 --- a/src/Microsoft.AspNet.Security/AuthenticationTicket.cs +++ b/src/Microsoft.AspNet.Security/AuthenticationTicket.cs @@ -1,14 +1,8 @@ // Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System; -using System.Collections.Generic; using System.Security.Claims; using Microsoft.AspNet.Http.Security; -using Microsoft.AspNet.HttpFeature.Security; -using Microsoft.AspNet.PipelineCore.Security; -using Microsoft.AspNet.Security.Infrastructure; namespace Microsoft.AspNet.Security { @@ -28,11 +22,34 @@ public AuthenticationTicket(ClaimsIdentity identity, AuthenticationProperties pr Properties = properties ?? new AuthenticationProperties(); } + /// + /// Initializes a new instance of the class + /// + /// the that represents the authenticated user. + /// additional properties that can be consumed by the user or runtims. + /// the authentication middleware that was responsible for this ticket. + public AuthenticationTicket(ClaimsPrincipal principal, AuthenticationProperties properties, string authenticationType) + { + AuthenticationType = authenticationType; + Principal = principal; + Properties = properties ?? new AuthenticationProperties(); + } + + /// + /// Gets the authenticated user identity. + /// + public string AuthenticationType { get; private set; } + /// /// Gets the authenticated user identity. /// public ClaimsIdentity Identity { get; private set; } + /// + /// Gets the authenticated user identity. + /// + public ClaimsPrincipal Principal{ get; private set; } + /// /// Additional state values for the authentication session. /// diff --git a/src/Microsoft.AspNet.Security/Infrastructure/AuthenticationTokenReceiveContext.cs b/src/Microsoft.AspNet.Security/Infrastructure/AuthenticationTokenReceiveContext.cs index af077b551..2e68dc308 100644 --- a/src/Microsoft.AspNet.Security/Infrastructure/AuthenticationTokenReceiveContext.cs +++ b/src/Microsoft.AspNet.Security/Infrastructure/AuthenticationTokenReceiveContext.cs @@ -1,8 +1,6 @@ // Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System; using Microsoft.AspNet.Http; using Microsoft.AspNet.Security.Notifications; @@ -10,15 +8,11 @@ namespace Microsoft.AspNet.Security.Infrastructure { public class AuthenticationTokenReceiveContext : BaseContext { - private readonly ISecureDataFormat _secureDataFormat; - public AuthenticationTokenReceiveContext( [NotNull] HttpContext context, - [NotNull] ISecureDataFormat secureDataFormat, [NotNull] string token) : base(context) { - _secureDataFormat = secureDataFormat; Token = token; } @@ -26,11 +20,6 @@ public AuthenticationTokenReceiveContext( public AuthenticationTicket Ticket { get; protected set; } - public void DeserializeTicket(string protectedData) - { - Ticket = _secureDataFormat.Unprotect(protectedData); - } - public void SetTicket([NotNull] AuthenticationTicket ticket) { Ticket = ticket; diff --git a/src/Microsoft.AspNet.Security/Notifications/AuthenticationFailedNotification.cs b/src/Microsoft.AspNet.Security/Notifications/AuthenticationFailedNotification.cs index 9e50ecf4f..5d232426f 100644 --- a/src/Microsoft.AspNet.Security/Notifications/AuthenticationFailedNotification.cs +++ b/src/Microsoft.AspNet.Security/Notifications/AuthenticationFailedNotification.cs @@ -1,19 +1,19 @@ // Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - using System; +using Microsoft.AspNet.Http; namespace Microsoft.AspNet.Security.Notifications { - public class AuthenticationFailedNotification + public class AuthenticationFailedNotification : BaseNotification { - public AuthenticationFailedNotification() + public AuthenticationFailedNotification(HttpContext context, TOptions options) : base(context, options) { } - public bool Cancel { get; set; } public Exception Exception { get; set; } + public TMessage ProtocolMessage { get; set; } } } \ No newline at end of file diff --git a/src/Microsoft.AspNet.Security/Notifications/BaseNotification.cs b/src/Microsoft.AspNet.Security/Notifications/BaseNotification.cs new file mode 100644 index 000000000..1ef13e2dc --- /dev/null +++ b/src/Microsoft.AspNet.Security/Notifications/BaseNotification.cs @@ -0,0 +1,49 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +using Microsoft.AspNet.Http; + +namespace Microsoft.AspNet.Security.Notifications +{ + public class BaseNotification : BaseContext + { + protected BaseNotification(HttpContext context, TOptions options) : base(context, options) + { + } + + public NotificationResultState State { get; set; } + + public bool HandledResponse + { + get { return State == NotificationResultState.HandledResponse; } + } + + public bool Skipped + { + get { return State == NotificationResultState.Skipped; } + } + + /// + /// Discontinue all processing for this request and return to the client. + /// The caller is responsible for generating the full response. + /// Set the to trigger SignIn. + /// + public void HandleResponse() + { + State = NotificationResultState.HandledResponse; + } + + /// + /// Discontinue processing the request in the current middleware and pass control to the next one. + /// SignIn will not be called. + /// + public void SkipToNextMiddleware() + { + State = NotificationResultState.Skipped; + } + + /// + /// Gets or set the to return if this notification signals it handled the notification. + /// + public AuthenticationTicket AuthenticationTicket { get; set; } + } +} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Security/Notifications/MessageReceivedNotification.cs b/src/Microsoft.AspNet.Security/Notifications/MessageReceivedNotification.cs index e27028917..1b1f59988 100644 --- a/src/Microsoft.AspNet.Security/Notifications/MessageReceivedNotification.cs +++ b/src/Microsoft.AspNet.Security/Notifications/MessageReceivedNotification.cs @@ -1,16 +1,16 @@ // Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. +using Microsoft.AspNet.Http; namespace Microsoft.AspNet.Security.Notifications { - public class MessageReceivedNotification + public class MessageReceivedNotification : BaseNotification { - public MessageReceivedNotification() + public MessageReceivedNotification(HttpContext context, TOptions options) : base(context, options) { } - public bool Cancel { get; set; } public TMessage ProtocolMessage { get; set; } } } \ No newline at end of file diff --git a/src/Microsoft.AspNet.Security/Notifications/NotificationResultState.cs b/src/Microsoft.AspNet.Security/Notifications/NotificationResultState.cs new file mode 100644 index 000000000..1f48e25b3 --- /dev/null +++ b/src/Microsoft.AspNet.Security/Notifications/NotificationResultState.cs @@ -0,0 +1,22 @@ +using System; + +namespace Microsoft.AspNet.Security.Notifications +{ + public enum NotificationResultState + { + /// + /// Continue with normal processing. + /// + Continue, + + /// + /// Discontinue processing the request in the current middleware and pass control to the next one. + /// + Skipped, + + /// + /// Discontinue all processing for this request. + /// + HandledResponse + } +} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Security/Notifications/RedirectFromIdentityProviderNotification.cs b/src/Microsoft.AspNet.Security/Notifications/RedirectFromIdentityProviderNotification.cs index d0bd97a76..768b384a9 100644 --- a/src/Microsoft.AspNet.Security/Notifications/RedirectFromIdentityProviderNotification.cs +++ b/src/Microsoft.AspNet.Security/Notifications/RedirectFromIdentityProviderNotification.cs @@ -1,17 +1,21 @@ // Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. +using Microsoft.AspNet.Http; namespace Microsoft.AspNet.Security.Notifications { - public class RedirectFromIdentityProviderNotification + public class RedirectFromIdentityProviderNotification : BaseNotification { - public AuthenticationTicket AuthenticationTicket { get; set; } + public RedirectFromIdentityProviderNotification(HttpContext context, TOptions options) + : base(context, options) + { + } public string SignInAsAuthenticationType { get; set; } - public bool Cancel { get; set; } - public bool IsRequestCompleted { get; set; } + + public TMessage ProtocolMessage { get; set; } } } diff --git a/src/Microsoft.AspNet.Security/Notifications/RedirectToIdentityProviderNotification.cs b/src/Microsoft.AspNet.Security/Notifications/RedirectToIdentityProviderNotification.cs index 467731fa0..524664d7e 100644 --- a/src/Microsoft.AspNet.Security/Notifications/RedirectToIdentityProviderNotification.cs +++ b/src/Microsoft.AspNet.Security/Notifications/RedirectToIdentityProviderNotification.cs @@ -1,16 +1,16 @@ // Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. +using Microsoft.AspNet.Http; namespace Microsoft.AspNet.Security.Notifications { - public class RedirectToIdentityProviderNotification + public class RedirectToIdentityProviderNotification : BaseNotification { - public RedirectToIdentityProviderNotification() + public RedirectToIdentityProviderNotification(HttpContext context, TOptions options) : base(context, options) { } - public bool Cancel { get; set; } public TMessage ProtocolMessage { get; set; } } -} \ No newline at end of file +} diff --git a/src/Microsoft.AspNet.Security/Notifications/SecurityTokenReceivedNotification.cs b/src/Microsoft.AspNet.Security/Notifications/SecurityTokenReceivedNotification.cs index f8aa2adef..7db29788a 100644 --- a/src/Microsoft.AspNet.Security/Notifications/SecurityTokenReceivedNotification.cs +++ b/src/Microsoft.AspNet.Security/Notifications/SecurityTokenReceivedNotification.cs @@ -1,16 +1,18 @@ // Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. +using Microsoft.AspNet.Http; namespace Microsoft.AspNet.Security.Notifications { - public class SecurityTokenReceivedNotification + public class SecurityTokenReceivedNotification : BaseNotification { - public SecurityTokenReceivedNotification() + public SecurityTokenReceivedNotification(HttpContext context, TOptions options) : base(context, options) { } - public bool Cancel { get; set; } public string SecurityToken { get; set; } + + public TMessage ProtocolMessage { get; set; } } -} \ No newline at end of file +} diff --git a/src/Microsoft.AspNet.Security/Notifications/SecurityTokenValidatedNotification.cs b/src/Microsoft.AspNet.Security/Notifications/SecurityTokenValidatedNotification.cs index 400b8b581..bdef232a7 100644 --- a/src/Microsoft.AspNet.Security/Notifications/SecurityTokenValidatedNotification.cs +++ b/src/Microsoft.AspNet.Security/Notifications/SecurityTokenValidatedNotification.cs @@ -1,16 +1,16 @@ // Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. +using Microsoft.AspNet.Http; namespace Microsoft.AspNet.Security.Notifications { - public class SecurityTokenValidatedNotification + public class SecurityTokenValidatedNotification : BaseNotification { - public SecurityTokenValidatedNotification() + public SecurityTokenValidatedNotification(HttpContext context, TOptions options) : base(context, options) { } - public AuthenticationTicket AuthenticationTicket { get; set; } - public bool Cancel { get; set; } + public TMessage ProtocolMessage { get; set; } } -} \ No newline at end of file +} diff --git a/test/Microsoft.AspNet.Security.Test/OAuthBearer/OAuthBearerMiddlewareTests.cs b/test/Microsoft.AspNet.Security.Test/OAuthBearer/OAuthBearerMiddlewareTests.cs new file mode 100644 index 000000000..6fa8b7afd --- /dev/null +++ b/test/Microsoft.AspNet.Security.Test/OAuthBearer/OAuthBearerMiddlewareTests.cs @@ -0,0 +1,237 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +using System; +using System.Collections.Generic; +using System.IdentityModel.Tokens; +using System.Linq; +using System.Net; +using System.Net.Http; +using System.Security.Claims; +using System.Threading.Tasks; +using System.Xml.Linq; +using Microsoft.AspNet.Builder; +using Microsoft.AspNet.Http; +using Microsoft.AspNet.Security.Notifications; +using Microsoft.AspNet.TestHost; +using Microsoft.Framework.DependencyInjection; +using Shouldly; +using Xunit; + +namespace Microsoft.AspNet.Security.OAuthBearer +{ + public class OAuthBearerMiddlewareTests + { + [Fact] + public async Task BearerTokenValidation() + { + var server = CreateServer(options => + { + options.Authority = "https://login.windows.net/tushartest.onmicrosoft.com"; + options.Audience = "https://TusharTest.onmicrosoft.com/TodoListService-ManualJwt"; + options.TokenValidationParameters = new TokenValidationParameters + { + ValidateLifetime = false + }; + }); + string newBearerToken = "Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6ImtyaU1QZG1Cdng2OHNrVDgtbVBBQjNCc2VlQSJ9.eyJhdWQiOiJodHRwczovL1R1c2hhclRlc3Qub25taWNyb3NvZnQuY29tL1RvZG9MaXN0U2VydmljZS1NYW51YWxKd3QiLCJpc3MiOiJodHRwczovL3N0cy53aW5kb3dzLm5ldC9hZmJlY2UwMy1hZWFhLTRmM2YtODVlNy1jZTA4ZGQyMGNlNTAvIiwiaWF0IjoxNDE4MzMwNjE0LCJuYmYiOjE0MTgzMzA2MTQsImV4cCI6MTQxODMzNDUxNCwidmVyIjoiMS4wIiwidGlkIjoiYWZiZWNlMDMtYWVhYS00ZjNmLTg1ZTctY2UwOGRkMjBjZTUwIiwiYW1yIjpbInB3ZCJdLCJvaWQiOiI1Mzk3OTdjMi00MDE5LTQ2NTktOWRiNS03MmM0Yzc3NzhhMzMiLCJ1cG4iOiJWaWN0b3JAVHVzaGFyVGVzdC5vbm1pY3Jvc29mdC5jb20iLCJ1bmlxdWVfbmFtZSI6IlZpY3RvckBUdXNoYXJUZXN0Lm9ubWljcm9zb2Z0LmNvbSIsInN1YiI6IkQyMm9aMW9VTzEzTUFiQXZrdnFyd2REVE80WXZJdjlzMV9GNWlVOVUwYnciLCJmYW1pbHlfbmFtZSI6Ikd1cHRhIiwiZ2l2ZW5fbmFtZSI6IlZpY3RvciIsImFwcGlkIjoiNjEzYjVhZjgtZjJjMy00MWI2LWExZGMtNDE2Yzk3ODAzMGI3IiwiYXBwaWRhY3IiOiIwIiwic2NwIjoidXNlcl9pbXBlcnNvbmF0aW9uIiwiYWNyIjoiMSJ9.N_Kw1EhoVGrHbE6hOcm7ERdZ7paBQiNdObvp2c6T6n5CE8p0fZqmUd-ya_EqwElcD6SiKSiP7gj0gpNUnOJcBl_H2X8GseaeeMxBrZdsnDL8qecc6_ygHruwlPltnLTdka67s1Ow4fDSHaqhVTEk6lzGmNEcbNAyb0CxQxU6o7Fh0yHRiWoLsT8yqYk8nKzsHXfZBNby4aRo3_hXaa4i0SZLYfDGGYPdttG4vT_u54QGGd4Wzbonv2gjDlllOVGOwoJS6kfl1h8mk0qxdiIaT_ChbDWgkWvTB7bTvBE-EgHgV0XmAo0WtJeSxgjsG3KhhEPsONmqrSjhIUV4IVnF2w"; + var response = await SendAsync(server, "http://example.com/oauth", newBearerToken); + response.Response.StatusCode.ShouldBe(HttpStatusCode.OK); + } + + [Fact] + public async Task CustomHeaderReceived() + { + var server = CreateServer(options => + { + options.Notifications.MessageReceived = HeaderReceived; + }); + + var response = await SendAsync(server, "http://example.com/oauth", "someHeader someblob"); + response.Response.StatusCode.ShouldBe(HttpStatusCode.OK); + } + + private static Task HeaderReceived(MessageReceivedNotification notification) + { + List claims = + new List + { + new Claim(ClaimTypes.Email, "bob@contoso.com"), + new Claim(ClaimsIdentity.DefaultNameClaimType, "bob"), + }; + + notification.AuthenticationTicket = new AuthenticationTicket(new ClaimsIdentity(claims, notification.Options.AuthenticationType), new Http.Security.AuthenticationProperties()); + notification.HandleResponse(); + + return Task.FromResult(null); + } + + [Fact] + public async Task CustomTokenReceived() + { + var server = CreateServer(options => + { + options.Notifications.SecurityTokenReceived = SecurityTokenReceived; + }); + + var response = await SendAsync(server, "http://example.com/oauth", "Bearer someblob"); + response.Response.StatusCode.ShouldBe(HttpStatusCode.OK); + } + + private static Task SecurityTokenReceived(SecurityTokenReceivedNotification notification) + { + List claims = + new List + { + new Claim(ClaimTypes.Email, "bob@contoso.com"), + new Claim(ClaimsIdentity.DefaultNameClaimType, "bob"), + }; + + notification.AuthenticationTicket = new AuthenticationTicket(new ClaimsIdentity(claims, notification.Options.AuthenticationType), new Http.Security.AuthenticationProperties()); + notification.HandleResponse(); + + return Task.FromResult(null); + } + + [Fact] + public async Task CustomTokenValidated() + { + var server = CreateServer(options => + { + options.Notifications.SecurityTokenValidated = SecurityTokenValidated; + options.SecurityTokenValidators = new List{new BlobTokenValidator(options.AuthenticationType)}; + }); + + var response = await SendAsync(server, "http://example.com/oauth", "Bearer someblob"); + response.Response.StatusCode.ShouldBe(HttpStatusCode.OK); + } + + private static Task SecurityTokenValidated(SecurityTokenValidatedNotification notification) + { + List claims = + new List + { + new Claim(ClaimTypes.Email, "bob@contoso.com"), + new Claim(ClaimsIdentity.DefaultNameClaimType, "bob"), + }; + + notification.AuthenticationTicket = new AuthenticationTicket(new ClaimsIdentity(claims, notification.Options.AuthenticationType), new Http.Security.AuthenticationProperties()); + notification.HandleResponse(); + + return Task.FromResult(null); + } + + class BlobTokenValidator : ISecurityTokenValidator + { + + public BlobTokenValidator(string authenticationType) + { + AuthenticationType = authenticationType; + } + + public string AuthenticationType { get; set; } + + public bool CanValidateToken + { + get + { + return true; + } + } + + public int MaximumTokenSizeInBytes + { + get + { + return 2*2*1024; + } + + set + { + throw new NotImplementedException(); + } + } + + public bool CanReadToken(string securityToken) + { + return true; + } + + public ClaimsPrincipal ValidateToken(string securityToken, TokenValidationParameters validationParameters, out SecurityToken validatedToken) + { + validatedToken = null; + List claims = + new List + { + new Claim(ClaimTypes.Email, "bob@contoso.com"), + new Claim(ClaimsIdentity.DefaultNameClaimType, "bob"), + }; + + return new ClaimsPrincipal(new ClaimsIdentity(claims, AuthenticationType)); + } + } + + private static TestServer CreateServer(Action configureOptions, Func handler = null) + { + return TestServer.Create(app => + { + app.UseServices(services => + { + services.AddDataProtection(); + }); + + if (configureOptions != null) + { + app.UseOAuthBearerAuthentication(configureOptions); + } + app.Use(async (context, next) => + { + var req = context.Request; + var res = context.Response; + if (req.Path == new PathString("/oauth")) + { + } + else + { + await next(); + } + + }); + }); + } + + private static async Task SendAsync(TestServer server, string uri, string authorizationHeader = null) + { + var request = new HttpRequestMessage(HttpMethod.Get, uri); + if (!string.IsNullOrEmpty(authorizationHeader)) + { + request.Headers.Add("Authorization", authorizationHeader); + } + + var transaction = new Transaction + { + Request = request, + Response = await server.CreateClient().SendAsync(request), + }; + + transaction.ResponseText = await transaction.Response.Content.ReadAsStringAsync(); + + if (transaction.Response.Content != null && + transaction.Response.Content.Headers.ContentType != null && + transaction.Response.Content.Headers.ContentType.MediaType == "text/xml") + { + transaction.ResponseElement = XElement.Parse(transaction.ResponseText); + } + + return transaction; + } + + private class Transaction + { + public HttpRequestMessage Request { get; set; } + public HttpResponseMessage Response { get; set; } + public IList SetCookie { get; set; } + public string ResponseText { get; set; } + public XElement ResponseElement { get; set; } + } + } +} \ No newline at end of file diff --git a/test/Microsoft.AspNet.Security.Test/OpenIdConnectMiddlewareTests/OpenIdConnectMiddlewareTests.cs b/test/Microsoft.AspNet.Security.Test/OpenIdConnectMiddlewareTests/OpenIdConnectMiddlewareTests.cs new file mode 100644 index 000000000..652c295ec --- /dev/null +++ b/test/Microsoft.AspNet.Security.Test/OpenIdConnectMiddlewareTests/OpenIdConnectMiddlewareTests.cs @@ -0,0 +1,361 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +using System; +using System.Collections.Generic; +using System.Globalization; +using System.IO; +using System.Linq; +using System.Net; +using System.Net.Http; +using System.Security.Claims; +using System.Text; +using System.Threading.Tasks; +using System.Xml; +using System.Xml.Linq; +using Microsoft.AspNet.Builder; +using Microsoft.AspNet.Http; +using Microsoft.AspNet.Http.Security; +using Microsoft.AspNet.Security.Cookies; +using Microsoft.AspNet.Security.DataHandler; +using Microsoft.AspNet.Security.DataProtection; +using Microsoft.AspNet.Security.OpenIdConnect; +using Microsoft.AspNet.TestHost; +using Microsoft.Framework.DependencyInjection; +using Newtonsoft.Json; +using Shouldly; +using Xunit; + +namespace Microsoft.AspNet.Security.Tests.OpenIdConnect +{ + public class OpenIdConnectMiddlewareTests + { + static string noncePrefix = "OpenIdConnect." + "Nonce."; + static string nonceDelimiter = "."; + + [Fact] + public async Task ChallengeWillTriggerRedirect() + { + var server = CreateServer(options => + { + options.Authority = "https://login.windows.net/common"; + options.ClientId = "Test Id"; + options.SignInAsAuthenticationType = OpenIdConnectAuthenticationDefaults.AuthenticationType; + }); + var transaction = await SendAsync(server, "https://example.com/challenge"); + transaction.Response.StatusCode.ShouldBe(HttpStatusCode.Redirect); + var location = transaction.Response.Headers.Location.ToString(); + location.ShouldContain("https://login.windows.net/common/oauth2/authorize?"); + location.ShouldContain("client_id="); + location.ShouldContain("&response_type="); + location.ShouldContain("&scope="); + location.ShouldContain("&state="); + location.ShouldContain("&response_mode="); + } + + [Fact] + public async Task ChallengeWillSetNonceCookie() + { + var server = CreateServer(options => + { + options.Authority = "https://login.windows.net/common"; + options.ClientId = "Test Id"; + }); + var transaction = await SendAsync(server, "https://example.com/challenge"); + transaction.SetCookie.Single().ShouldContain("OpenIdConnect.nonce."); + } + + [Fact] + public async Task ChallengeWillSetDefaultScope() + { + var server = CreateServer(options => + { + options.Authority = "https://login.windows.net/common"; + options.ClientId = "Test Id"; + }); + var transaction = await SendAsync(server, "https://example.com/challenge"); + transaction.Response.StatusCode.ShouldBe(HttpStatusCode.Redirect); + transaction.Response.Headers.Location.Query.ShouldContain("&scope=" + Uri.EscapeDataString("openid profile")); + } + + [Fact] + public async Task ChallengeWillUseOptionsProperties() + { + var server = CreateServer(options => + { + options.Authority = "https://login.windows.net/common"; + options.ClientId = "Test Id"; + options.SignInAsAuthenticationType = OpenIdConnectAuthenticationDefaults.AuthenticationType; + options.Scope = "https://www.googleapis.com/auth/plus.login"; + options.ResponseType = "id_token"; + }); + var transaction = await SendAsync(server, "https://example.com/challenge"); + transaction.Response.StatusCode.ShouldBe(HttpStatusCode.Redirect); + var query = transaction.Response.Headers.Location.Query; + query.ShouldContain("scope=" + Uri.EscapeDataString("https://www.googleapis.com/auth/plus.login")); + query.ShouldContain("response_type=" + Uri.EscapeDataString("id_token")); + } + + [Fact] + public async Task ChallengeWillUseNotifications() + { + ISecureDataFormat stateFormat = new PropertiesDataFormat(new EphemeralDataProtectionProvider().CreateProtector("GoogleTest")); + var server = CreateServer(options => + { + options.Authority = "https://login.windows.net/common"; + options.ClientId = "Test Id"; + options.Notifications = new OpenIdConnectAuthenticationNotifications + { + MessageReceived = notification => + { + notification.ProtocolMessage.Scope = "test openid profile"; + notification.HandleResponse(); + return Task.FromResult(null); + } + }; + }); + + var properties = new AuthenticationProperties(); + var state = stateFormat.Protect(properties); + var transaction = await SendAsync(server,"https://example.com/challenge"); + transaction.Response.StatusCode.ShouldBe(HttpStatusCode.Redirect); + } + + + [Fact] + public async Task SignOutWithDefaultRedirectUri() + { + ISecureDataFormat stateFormat = new PropertiesDataFormat(new EphemeralDataProtectionProvider().CreateProtector("GoogleTest")); + var server = CreateServer(options => + { + options.Authority = "https://login.windows.net/common"; + options.ClientId = "Test Id"; + }); + + var transaction = await SendAsync(server, "https://example.com/signout"); + transaction.Response.StatusCode.ShouldBe(HttpStatusCode.Redirect); + transaction.Response.Headers.Location.AbsoluteUri.ShouldBe("https://login.windows.net/common/oauth2/logout"); + } + + [Fact] + public async Task SignOutWithCustomRedirectUri() + { + ISecureDataFormat stateFormat = new PropertiesDataFormat(new EphemeralDataProtectionProvider().CreateProtector("GoogleTest")); + var server = CreateServer(options => + { + options.Authority = "https://login.windows.net/common"; + options.ClientId = "Test Id"; + options.PostLogoutRedirectUri = "https://example.com/logout"; + }); + + var transaction = await SendAsync(server, "https://example.com/signout"); + transaction.Response.StatusCode.ShouldBe(HttpStatusCode.Redirect); + transaction.Response.Headers.Location.AbsoluteUri.ShouldContain(Uri.EscapeDataString("https://example.com/logout")); + } + + [Fact] + // Test Cases for calculating the expiration time of cookie from cookie name + public void NonceCookieExpirationTime() + { + DateTime utcNow = DateTime.UtcNow; + + GetNonceExpirationTime(noncePrefix + DateTime.MaxValue.Ticks.ToString(CultureInfo.InvariantCulture) + nonceDelimiter, TimeSpan.FromHours(1)).ShouldBe(DateTime.MaxValue); + + GetNonceExpirationTime(noncePrefix + DateTime.MinValue.Ticks.ToString(CultureInfo.InvariantCulture) + nonceDelimiter, TimeSpan.FromHours(1)).ShouldBe(DateTime.MinValue + TimeSpan.FromHours(1)); + + GetNonceExpirationTime(noncePrefix + utcNow.Ticks.ToString(CultureInfo.InvariantCulture) + nonceDelimiter, TimeSpan.FromHours(1)).ShouldBe(utcNow + TimeSpan.FromHours(1)); + + GetNonceExpirationTime(noncePrefix, TimeSpan.FromHours(1)).ShouldBe(DateTime.MinValue); + + GetNonceExpirationTime("", TimeSpan.FromHours(1)).ShouldBe(DateTime.MinValue); + + GetNonceExpirationTime(noncePrefix + noncePrefix, TimeSpan.FromHours(1)).ShouldBe(DateTime.MinValue); + + GetNonceExpirationTime(noncePrefix + utcNow.Ticks.ToString(CultureInfo.InvariantCulture) + nonceDelimiter + utcNow.Ticks.ToString(CultureInfo.InvariantCulture) + nonceDelimiter, TimeSpan.FromHours(1)).ShouldBe(utcNow + TimeSpan.FromHours(1)); + + GetNonceExpirationTime(utcNow.Ticks.ToString(CultureInfo.InvariantCulture) + nonceDelimiter + utcNow.Ticks.ToString(CultureInfo.InvariantCulture) + nonceDelimiter, TimeSpan.FromHours(1)).ShouldBe(DateTime.MinValue); + } + + private static TestServer CreateServer(Action configureOptions, Func handler = null) + { + return TestServer.Create(app => + { + app.UseServices(services => + { + services.AddDataProtection(); + services.Configure(options => + { + options.SignInAsAuthenticationType = CookieAuthenticationDefaults.AuthenticationType; + }); + }); + + app.UseCookieAuthentication(options => + { + options.AuthenticationType = "OpenIdConnect"; + }); + app.UseOpenIdConnectAuthentication(configureOptions); + app.Use(async (context, next) => + { + var req = context.Request; + var res = context.Response; + if (req.Path == new PathString("/challenge")) + { + res.Challenge("OpenIdConnect"); + res.StatusCode = 401; + } + else if (req.Path == new PathString("/signin")) + { + res.SignIn(); + } + else if (req.Path == new PathString("/signout")) + { + res.SignOut(OpenIdConnectAuthenticationDefaults.AuthenticationType); + } + else if (handler != null) + { + await handler(context); + } + else + { + await next(); + } + }); + }); + } + + private static async Task SendAsync(TestServer server, string uri, string cookieHeader = null) + { + var request = new HttpRequestMessage(HttpMethod.Get, uri); + if (!string.IsNullOrEmpty(cookieHeader)) + { + request.Headers.Add("Cookie", cookieHeader); + } + var transaction = new Transaction + { + Request = request, + Response = await server.CreateClient().SendAsync(request), + }; + if (transaction.Response.Headers.Contains("Set-Cookie")) + { + transaction.SetCookie = transaction.Response.Headers.GetValues("Set-Cookie").ToList(); + } + transaction.ResponseText = await transaction.Response.Content.ReadAsStringAsync(); + + if (transaction.Response.Content != null && + transaction.Response.Content.Headers.ContentType != null && + transaction.Response.Content.Headers.ContentType.MediaType == "text/xml") + { + transaction.ResponseElement = XElement.Parse(transaction.ResponseText); + } + return transaction; + } + + private class Transaction + { + public HttpRequestMessage Request { get; set; } + public HttpResponseMessage Response { get; set; } + + public IList SetCookie { get; set; } + + public string ResponseText { get; set; } + public XElement ResponseElement { get; set; } + + public string AuthenticationCookieValue + { + get + { + if (SetCookie != null && SetCookie.Count > 0) + { + var authCookie = SetCookie.SingleOrDefault(c => c.Contains(".AspNet.Cookie=")); + if (authCookie != null) + { + return authCookie.Substring(0, authCookie.IndexOf(';')); + } + } + + return null; + } + } + + public string FindClaimValue(string claimType) + { + XElement claim = ResponseElement.Elements("claim").SingleOrDefault(elt => elt.Attribute("type").Value == claimType); + if (claim == null) + { + return null; + } + return claim.Attribute("value").Value; + } + } + private static void Describe(HttpResponse res, ClaimsIdentity identity) + { + res.StatusCode = 200; + res.ContentType = "text/xml"; + var xml = new XElement("xml"); + if (identity != null) + { + xml.Add(identity.Claims.Select(claim => new XElement("claim", new XAttribute("type", claim.Type), new XAttribute("value", claim.Value)))); + } + using (var memory = new MemoryStream()) + { + using (var writer = new XmlTextWriter(memory, Encoding.UTF8)) + { + xml.WriteTo(writer); + } + res.Body.Write(memory.ToArray(), 0, memory.ToArray().Length); + } + } + + private class TestHttpMessageHandler : HttpMessageHandler + { + public Func Sender { get; set; } + + protected override Task SendAsync(HttpRequestMessage request, System.Threading.CancellationToken cancellationToken) + { + if (Sender != null) + { + return Task.FromResult(Sender(request)); + } + + return Task.FromResult(null); + } + } + + private static HttpResponseMessage ReturnJsonResponse(object content) + { + var res = new HttpResponseMessage(HttpStatusCode.OK); + var text = JsonConvert.SerializeObject(content); + res.Content = new StringContent(text, Encoding.UTF8, "application/json"); + return res; + } + + private static DateTime GetNonceExpirationTime(string keyname, TimeSpan nonceLifetime) + { + DateTime nonceTime = DateTime.MinValue; + string timestamp = null; + int endOfTimestamp; + if (keyname.StartsWith(noncePrefix, StringComparison.Ordinal)) + { + timestamp = keyname.Substring(noncePrefix.Length); + endOfTimestamp = timestamp.IndexOf('.'); + + if (endOfTimestamp != -1) + { + timestamp = timestamp.Substring(0, endOfTimestamp); + try + { + nonceTime = DateTime.FromBinary(Convert.ToInt64(timestamp, CultureInfo.InvariantCulture)); + if ((nonceTime >= DateTime.UtcNow) && ((DateTime.MaxValue - nonceTime) < nonceLifetime)) + nonceTime = DateTime.MaxValue; + else + nonceTime += nonceLifetime; + } + catch + { + } + } + } + return nonceTime; + } + + } +} \ No newline at end of file diff --git a/test/Microsoft.AspNet.Security.Test/project.json b/test/Microsoft.AspNet.Security.Test/project.json index 305fe5528..504d228b6 100644 --- a/test/Microsoft.AspNet.Security.Test/project.json +++ b/test/Microsoft.AspNet.Security.Test/project.json @@ -7,6 +7,8 @@ "Microsoft.AspNet.Security.Facebook": "1.0.0-*", "Microsoft.AspNet.Security.Google": "1.0.0-*", "Microsoft.AspNet.Security.MicrosoftAccount": "1.0.0-*", + "Microsoft.AspNet.Security.OAuthBearer": "1.0.0-*", + "Microsoft.AspNet.Security.OpenIdConnect": "1.0.0-*", "Microsoft.AspNet.Security.Twitter": "1.0.0-*", "Microsoft.AspNet.TestHost": "1.0.0-*", "Moq": "4.2.1312.1622", @@ -18,7 +20,8 @@ "frameworks": { "aspnet50": { "dependencies": { - "Shouldly": "1.1.1.1" + "Shouldly": "1.1.1.1", + "System.Security.Claims": "1.0.0-*" } } } From 8e6e7f9590eb7a8225c9a9d61892539515f55f26 Mon Sep 17 00:00:00 2001 From: Chris Ross Date: Wed, 14 Jan 2015 14:53:51 -0800 Subject: [PATCH 104/216] Fix directory casing, part1. --- .../OpenIdConnectSample.kproj | 0 .../Startup.cs | 0 .../project.json | 0 .../Microsoft.AspNet.Security.OpenIdConnect.kproj | 0 .../NonceCache.cs | 0 .../Notifications/AuthorizationCodeReceivedNotification.cs | 0 .../OpenIdConnectAuthenticationDefaults.cs | 0 .../OpenIdConnectAuthenticationExtensions.cs | 0 .../OpenIdConnectAuthenticationMiddleware.cs | 0 .../OpenIdConnectAuthenticationNotifications.cs | 0 .../OpenIdConnectAuthenticationOptions.cs | 0 .../OpenidConnectAuthenticationHandler.cs | 0 .../Project.json | 0 .../Resources.Designer.cs | 0 14 files changed, 0 insertions(+), 0 deletions(-) rename samples/{OpenIDConnectSample => OpenIdConnectSample_casing}/OpenIdConnectSample.kproj (100%) rename samples/{OpenIDConnectSample => OpenIdConnectSample_casing}/Startup.cs (100%) rename samples/{OpenIDConnectSample => OpenIdConnectSample_casing}/project.json (100%) rename src/{Microsoft.AspNet.Security.OpenIDConnect => Microsoft.AspNet.Security.OpenIdConnect_casing}/Microsoft.AspNet.Security.OpenIdConnect.kproj (100%) rename src/{Microsoft.AspNet.Security.OpenIDConnect => Microsoft.AspNet.Security.OpenIdConnect_casing}/NonceCache.cs (100%) rename src/{Microsoft.AspNet.Security.OpenIDConnect => Microsoft.AspNet.Security.OpenIdConnect_casing}/Notifications/AuthorizationCodeReceivedNotification.cs (100%) rename src/{Microsoft.AspNet.Security.OpenIDConnect => Microsoft.AspNet.Security.OpenIdConnect_casing}/OpenIdConnectAuthenticationDefaults.cs (100%) rename src/{Microsoft.AspNet.Security.OpenIDConnect => Microsoft.AspNet.Security.OpenIdConnect_casing}/OpenIdConnectAuthenticationExtensions.cs (100%) rename src/{Microsoft.AspNet.Security.OpenIDConnect => Microsoft.AspNet.Security.OpenIdConnect_casing}/OpenIdConnectAuthenticationMiddleware.cs (100%) rename src/{Microsoft.AspNet.Security.OpenIDConnect => Microsoft.AspNet.Security.OpenIdConnect_casing}/OpenIdConnectAuthenticationNotifications.cs (100%) rename src/{Microsoft.AspNet.Security.OpenIDConnect => Microsoft.AspNet.Security.OpenIdConnect_casing}/OpenIdConnectAuthenticationOptions.cs (100%) rename src/{Microsoft.AspNet.Security.OpenIDConnect => Microsoft.AspNet.Security.OpenIdConnect_casing}/OpenidConnectAuthenticationHandler.cs (100%) rename src/{Microsoft.AspNet.Security.OpenIDConnect => Microsoft.AspNet.Security.OpenIdConnect_casing}/Project.json (100%) rename src/{Microsoft.AspNet.Security.OpenIDConnect => Microsoft.AspNet.Security.OpenIdConnect_casing}/Resources.Designer.cs (100%) diff --git a/samples/OpenIDConnectSample/OpenIdConnectSample.kproj b/samples/OpenIdConnectSample_casing/OpenIdConnectSample.kproj similarity index 100% rename from samples/OpenIDConnectSample/OpenIdConnectSample.kproj rename to samples/OpenIdConnectSample_casing/OpenIdConnectSample.kproj diff --git a/samples/OpenIDConnectSample/Startup.cs b/samples/OpenIdConnectSample_casing/Startup.cs similarity index 100% rename from samples/OpenIDConnectSample/Startup.cs rename to samples/OpenIdConnectSample_casing/Startup.cs diff --git a/samples/OpenIDConnectSample/project.json b/samples/OpenIdConnectSample_casing/project.json similarity index 100% rename from samples/OpenIDConnectSample/project.json rename to samples/OpenIdConnectSample_casing/project.json diff --git a/src/Microsoft.AspNet.Security.OpenIDConnect/Microsoft.AspNet.Security.OpenIdConnect.kproj b/src/Microsoft.AspNet.Security.OpenIdConnect_casing/Microsoft.AspNet.Security.OpenIdConnect.kproj similarity index 100% rename from src/Microsoft.AspNet.Security.OpenIDConnect/Microsoft.AspNet.Security.OpenIdConnect.kproj rename to src/Microsoft.AspNet.Security.OpenIdConnect_casing/Microsoft.AspNet.Security.OpenIdConnect.kproj diff --git a/src/Microsoft.AspNet.Security.OpenIDConnect/NonceCache.cs b/src/Microsoft.AspNet.Security.OpenIdConnect_casing/NonceCache.cs similarity index 100% rename from src/Microsoft.AspNet.Security.OpenIDConnect/NonceCache.cs rename to src/Microsoft.AspNet.Security.OpenIdConnect_casing/NonceCache.cs diff --git a/src/Microsoft.AspNet.Security.OpenIDConnect/Notifications/AuthorizationCodeReceivedNotification.cs b/src/Microsoft.AspNet.Security.OpenIdConnect_casing/Notifications/AuthorizationCodeReceivedNotification.cs similarity index 100% rename from src/Microsoft.AspNet.Security.OpenIDConnect/Notifications/AuthorizationCodeReceivedNotification.cs rename to src/Microsoft.AspNet.Security.OpenIdConnect_casing/Notifications/AuthorizationCodeReceivedNotification.cs diff --git a/src/Microsoft.AspNet.Security.OpenIDConnect/OpenIdConnectAuthenticationDefaults.cs b/src/Microsoft.AspNet.Security.OpenIdConnect_casing/OpenIdConnectAuthenticationDefaults.cs similarity index 100% rename from src/Microsoft.AspNet.Security.OpenIDConnect/OpenIdConnectAuthenticationDefaults.cs rename to src/Microsoft.AspNet.Security.OpenIdConnect_casing/OpenIdConnectAuthenticationDefaults.cs diff --git a/src/Microsoft.AspNet.Security.OpenIDConnect/OpenIdConnectAuthenticationExtensions.cs b/src/Microsoft.AspNet.Security.OpenIdConnect_casing/OpenIdConnectAuthenticationExtensions.cs similarity index 100% rename from src/Microsoft.AspNet.Security.OpenIDConnect/OpenIdConnectAuthenticationExtensions.cs rename to src/Microsoft.AspNet.Security.OpenIdConnect_casing/OpenIdConnectAuthenticationExtensions.cs diff --git a/src/Microsoft.AspNet.Security.OpenIDConnect/OpenIdConnectAuthenticationMiddleware.cs b/src/Microsoft.AspNet.Security.OpenIdConnect_casing/OpenIdConnectAuthenticationMiddleware.cs similarity index 100% rename from src/Microsoft.AspNet.Security.OpenIDConnect/OpenIdConnectAuthenticationMiddleware.cs rename to src/Microsoft.AspNet.Security.OpenIdConnect_casing/OpenIdConnectAuthenticationMiddleware.cs diff --git a/src/Microsoft.AspNet.Security.OpenIDConnect/OpenIdConnectAuthenticationNotifications.cs b/src/Microsoft.AspNet.Security.OpenIdConnect_casing/OpenIdConnectAuthenticationNotifications.cs similarity index 100% rename from src/Microsoft.AspNet.Security.OpenIDConnect/OpenIdConnectAuthenticationNotifications.cs rename to src/Microsoft.AspNet.Security.OpenIdConnect_casing/OpenIdConnectAuthenticationNotifications.cs diff --git a/src/Microsoft.AspNet.Security.OpenIDConnect/OpenIdConnectAuthenticationOptions.cs b/src/Microsoft.AspNet.Security.OpenIdConnect_casing/OpenIdConnectAuthenticationOptions.cs similarity index 100% rename from src/Microsoft.AspNet.Security.OpenIDConnect/OpenIdConnectAuthenticationOptions.cs rename to src/Microsoft.AspNet.Security.OpenIdConnect_casing/OpenIdConnectAuthenticationOptions.cs diff --git a/src/Microsoft.AspNet.Security.OpenIDConnect/OpenidConnectAuthenticationHandler.cs b/src/Microsoft.AspNet.Security.OpenIdConnect_casing/OpenidConnectAuthenticationHandler.cs similarity index 100% rename from src/Microsoft.AspNet.Security.OpenIDConnect/OpenidConnectAuthenticationHandler.cs rename to src/Microsoft.AspNet.Security.OpenIdConnect_casing/OpenidConnectAuthenticationHandler.cs diff --git a/src/Microsoft.AspNet.Security.OpenIDConnect/Project.json b/src/Microsoft.AspNet.Security.OpenIdConnect_casing/Project.json similarity index 100% rename from src/Microsoft.AspNet.Security.OpenIDConnect/Project.json rename to src/Microsoft.AspNet.Security.OpenIdConnect_casing/Project.json diff --git a/src/Microsoft.AspNet.Security.OpenIDConnect/Resources.Designer.cs b/src/Microsoft.AspNet.Security.OpenIdConnect_casing/Resources.Designer.cs similarity index 100% rename from src/Microsoft.AspNet.Security.OpenIDConnect/Resources.Designer.cs rename to src/Microsoft.AspNet.Security.OpenIdConnect_casing/Resources.Designer.cs From 91242245f3b99d0cee574f7100e3b264c5732775 Mon Sep 17 00:00:00 2001 From: Chris Ross Date: Wed, 14 Jan 2015 14:54:47 -0800 Subject: [PATCH 105/216] Fix directory casing, part 2. --- .../OpenIdConnectSample.kproj | 0 .../Startup.cs | 0 .../project.json | 0 .../Microsoft.AspNet.Security.OpenIdConnect.kproj | 0 .../NonceCache.cs | 0 .../Notifications/AuthorizationCodeReceivedNotification.cs | 0 .../OpenIdConnectAuthenticationDefaults.cs | 0 .../OpenIdConnectAuthenticationExtensions.cs | 0 .../OpenIdConnectAuthenticationMiddleware.cs | 0 .../OpenIdConnectAuthenticationNotifications.cs | 0 .../OpenIdConnectAuthenticationOptions.cs | 0 .../OpenidConnectAuthenticationHandler.cs | 0 .../Project.json | 0 .../Resources.Designer.cs | 0 14 files changed, 0 insertions(+), 0 deletions(-) rename samples/{OpenIdConnectSample_casing => OpenIdConnectSample}/OpenIdConnectSample.kproj (100%) rename samples/{OpenIdConnectSample_casing => OpenIdConnectSample}/Startup.cs (100%) rename samples/{OpenIdConnectSample_casing => OpenIdConnectSample}/project.json (100%) rename src/{Microsoft.AspNet.Security.OpenIdConnect_casing => Microsoft.AspNet.Security.OpenIdConnect}/Microsoft.AspNet.Security.OpenIdConnect.kproj (100%) rename src/{Microsoft.AspNet.Security.OpenIdConnect_casing => Microsoft.AspNet.Security.OpenIdConnect}/NonceCache.cs (100%) rename src/{Microsoft.AspNet.Security.OpenIdConnect_casing => Microsoft.AspNet.Security.OpenIdConnect}/Notifications/AuthorizationCodeReceivedNotification.cs (100%) rename src/{Microsoft.AspNet.Security.OpenIdConnect_casing => Microsoft.AspNet.Security.OpenIdConnect}/OpenIdConnectAuthenticationDefaults.cs (100%) rename src/{Microsoft.AspNet.Security.OpenIdConnect_casing => Microsoft.AspNet.Security.OpenIdConnect}/OpenIdConnectAuthenticationExtensions.cs (100%) rename src/{Microsoft.AspNet.Security.OpenIdConnect_casing => Microsoft.AspNet.Security.OpenIdConnect}/OpenIdConnectAuthenticationMiddleware.cs (100%) rename src/{Microsoft.AspNet.Security.OpenIdConnect_casing => Microsoft.AspNet.Security.OpenIdConnect}/OpenIdConnectAuthenticationNotifications.cs (100%) rename src/{Microsoft.AspNet.Security.OpenIdConnect_casing => Microsoft.AspNet.Security.OpenIdConnect}/OpenIdConnectAuthenticationOptions.cs (100%) rename src/{Microsoft.AspNet.Security.OpenIdConnect_casing => Microsoft.AspNet.Security.OpenIdConnect}/OpenidConnectAuthenticationHandler.cs (100%) rename src/{Microsoft.AspNet.Security.OpenIdConnect_casing => Microsoft.AspNet.Security.OpenIdConnect}/Project.json (100%) rename src/{Microsoft.AspNet.Security.OpenIdConnect_casing => Microsoft.AspNet.Security.OpenIdConnect}/Resources.Designer.cs (100%) diff --git a/samples/OpenIdConnectSample_casing/OpenIdConnectSample.kproj b/samples/OpenIdConnectSample/OpenIdConnectSample.kproj similarity index 100% rename from samples/OpenIdConnectSample_casing/OpenIdConnectSample.kproj rename to samples/OpenIdConnectSample/OpenIdConnectSample.kproj diff --git a/samples/OpenIdConnectSample_casing/Startup.cs b/samples/OpenIdConnectSample/Startup.cs similarity index 100% rename from samples/OpenIdConnectSample_casing/Startup.cs rename to samples/OpenIdConnectSample/Startup.cs diff --git a/samples/OpenIdConnectSample_casing/project.json b/samples/OpenIdConnectSample/project.json similarity index 100% rename from samples/OpenIdConnectSample_casing/project.json rename to samples/OpenIdConnectSample/project.json diff --git a/src/Microsoft.AspNet.Security.OpenIdConnect_casing/Microsoft.AspNet.Security.OpenIdConnect.kproj b/src/Microsoft.AspNet.Security.OpenIdConnect/Microsoft.AspNet.Security.OpenIdConnect.kproj similarity index 100% rename from src/Microsoft.AspNet.Security.OpenIdConnect_casing/Microsoft.AspNet.Security.OpenIdConnect.kproj rename to src/Microsoft.AspNet.Security.OpenIdConnect/Microsoft.AspNet.Security.OpenIdConnect.kproj diff --git a/src/Microsoft.AspNet.Security.OpenIdConnect_casing/NonceCache.cs b/src/Microsoft.AspNet.Security.OpenIdConnect/NonceCache.cs similarity index 100% rename from src/Microsoft.AspNet.Security.OpenIdConnect_casing/NonceCache.cs rename to src/Microsoft.AspNet.Security.OpenIdConnect/NonceCache.cs diff --git a/src/Microsoft.AspNet.Security.OpenIdConnect_casing/Notifications/AuthorizationCodeReceivedNotification.cs b/src/Microsoft.AspNet.Security.OpenIdConnect/Notifications/AuthorizationCodeReceivedNotification.cs similarity index 100% rename from src/Microsoft.AspNet.Security.OpenIdConnect_casing/Notifications/AuthorizationCodeReceivedNotification.cs rename to src/Microsoft.AspNet.Security.OpenIdConnect/Notifications/AuthorizationCodeReceivedNotification.cs diff --git a/src/Microsoft.AspNet.Security.OpenIdConnect_casing/OpenIdConnectAuthenticationDefaults.cs b/src/Microsoft.AspNet.Security.OpenIdConnect/OpenIdConnectAuthenticationDefaults.cs similarity index 100% rename from src/Microsoft.AspNet.Security.OpenIdConnect_casing/OpenIdConnectAuthenticationDefaults.cs rename to src/Microsoft.AspNet.Security.OpenIdConnect/OpenIdConnectAuthenticationDefaults.cs diff --git a/src/Microsoft.AspNet.Security.OpenIdConnect_casing/OpenIdConnectAuthenticationExtensions.cs b/src/Microsoft.AspNet.Security.OpenIdConnect/OpenIdConnectAuthenticationExtensions.cs similarity index 100% rename from src/Microsoft.AspNet.Security.OpenIdConnect_casing/OpenIdConnectAuthenticationExtensions.cs rename to src/Microsoft.AspNet.Security.OpenIdConnect/OpenIdConnectAuthenticationExtensions.cs diff --git a/src/Microsoft.AspNet.Security.OpenIdConnect_casing/OpenIdConnectAuthenticationMiddleware.cs b/src/Microsoft.AspNet.Security.OpenIdConnect/OpenIdConnectAuthenticationMiddleware.cs similarity index 100% rename from src/Microsoft.AspNet.Security.OpenIdConnect_casing/OpenIdConnectAuthenticationMiddleware.cs rename to src/Microsoft.AspNet.Security.OpenIdConnect/OpenIdConnectAuthenticationMiddleware.cs diff --git a/src/Microsoft.AspNet.Security.OpenIdConnect_casing/OpenIdConnectAuthenticationNotifications.cs b/src/Microsoft.AspNet.Security.OpenIdConnect/OpenIdConnectAuthenticationNotifications.cs similarity index 100% rename from src/Microsoft.AspNet.Security.OpenIdConnect_casing/OpenIdConnectAuthenticationNotifications.cs rename to src/Microsoft.AspNet.Security.OpenIdConnect/OpenIdConnectAuthenticationNotifications.cs diff --git a/src/Microsoft.AspNet.Security.OpenIdConnect_casing/OpenIdConnectAuthenticationOptions.cs b/src/Microsoft.AspNet.Security.OpenIdConnect/OpenIdConnectAuthenticationOptions.cs similarity index 100% rename from src/Microsoft.AspNet.Security.OpenIdConnect_casing/OpenIdConnectAuthenticationOptions.cs rename to src/Microsoft.AspNet.Security.OpenIdConnect/OpenIdConnectAuthenticationOptions.cs diff --git a/src/Microsoft.AspNet.Security.OpenIdConnect_casing/OpenidConnectAuthenticationHandler.cs b/src/Microsoft.AspNet.Security.OpenIdConnect/OpenidConnectAuthenticationHandler.cs similarity index 100% rename from src/Microsoft.AspNet.Security.OpenIdConnect_casing/OpenidConnectAuthenticationHandler.cs rename to src/Microsoft.AspNet.Security.OpenIdConnect/OpenidConnectAuthenticationHandler.cs diff --git a/src/Microsoft.AspNet.Security.OpenIdConnect_casing/Project.json b/src/Microsoft.AspNet.Security.OpenIdConnect/Project.json similarity index 100% rename from src/Microsoft.AspNet.Security.OpenIdConnect_casing/Project.json rename to src/Microsoft.AspNet.Security.OpenIdConnect/Project.json diff --git a/src/Microsoft.AspNet.Security.OpenIdConnect_casing/Resources.Designer.cs b/src/Microsoft.AspNet.Security.OpenIdConnect/Resources.Designer.cs similarity index 100% rename from src/Microsoft.AspNet.Security.OpenIdConnect_casing/Resources.Designer.cs rename to src/Microsoft.AspNet.Security.OpenIdConnect/Resources.Designer.cs From 38fb911afc8f44fdbebb63efa36e8ffdc7e0a213 Mon Sep 17 00:00:00 2001 From: Chris Ross Date: Wed, 14 Jan 2015 15:13:24 -0800 Subject: [PATCH 106/216] Clean up auth types, copywrite headers, file names, exceptions. --- samples/OpenIdConnectSample/Startup.cs | 10 ++++---- .../OAuthBearerAuthenticationHandler.cs | 23 ++++++++----------- .../{NonceCache.cs => INonceCache.cs} | 3 ++- .../AuthorizationCodeReceivedNotification.cs | 3 ++- .../OpenIdConnectAuthenticationDefaults.cs | 4 ++-- .../OpenIdConnectAuthenticationExtensions.cs | 3 ++- .../OpenIdConnectAuthenticationMiddleware.cs | 3 ++- ...penIdConnectAuthenticationNotifications.cs | 3 ++- .../OpenIdConnectAuthenticationOptions.cs | 3 ++- .../OpenidConnectAuthenticationHandler.cs | 23 ++++++------------- .../OAuthBearer/OAuthBearerMiddlewareTests.cs | 3 ++- .../OpenIdConnectMiddlewareTests.cs | 3 ++- 12 files changed, 38 insertions(+), 46 deletions(-) rename src/Microsoft.AspNet.Security.OpenIdConnect/{NonceCache.cs => INonceCache.cs} (69%) rename test/Microsoft.AspNet.Security.Test/{OpenIdConnectMiddlewareTests => OpenIdConnect}/OpenIdConnectMiddlewareTests.cs (99%) diff --git a/samples/OpenIdConnectSample/Startup.cs b/samples/OpenIdConnectSample/Startup.cs index 17850d03b..bd443424e 100644 --- a/samples/OpenIdConnectSample/Startup.cs +++ b/samples/OpenIdConnectSample/Startup.cs @@ -1,9 +1,10 @@ using Microsoft.AspNet.Builder; using Microsoft.AspNet.Http; -using Microsoft.Framework.DependencyInjection; -using Microsoft.AspNet.Security.OpenIdConnect; using Microsoft.AspNet.Http.Security; using Microsoft.AspNet.Security; +using Microsoft.AspNet.Security.Cookies; +using Microsoft.AspNet.Security.OpenIdConnect; +using Microsoft.Framework.DependencyInjection; namespace OpenIdConnectSample { @@ -16,14 +17,13 @@ public void Configure(IApplicationBuilder app) services.AddDataProtection(); services.Configure(options => { - options.SignInAsAuthenticationType = OpenIdConnectAuthenticationDefaults.AuthenticationType; + options.SignInAsAuthenticationType = CookieAuthenticationDefaults.AuthenticationType; }); }); app.UseCookieAuthentication(options => { - options.AuthenticationType = OpenIdConnectAuthenticationDefaults.AuthenticationType; }); app.UseOpenIdConnectAuthentication(options => @@ -31,8 +31,6 @@ public void Configure(IApplicationBuilder app) options.ClientId = "fe78e0b4-6fe7-47e6-812c-fb75cee266a4"; options.Authority = "https://login.windows.net/cyrano.onmicrosoft.com"; options.RedirectUri = "http://localhost:42023"; - options.SignInAsAuthenticationType = OpenIdConnectAuthenticationDefaults.AuthenticationType; - options.AuthenticationType = OpenIdConnectAuthenticationDefaults.AuthenticationType; }); app.Run(async context => diff --git a/src/Microsoft.AspNet.Security.OAuthBearer/OAuthBearerAuthenticationHandler.cs b/src/Microsoft.AspNet.Security.OAuthBearer/OAuthBearerAuthenticationHandler.cs index 1c2eb287a..b81af0c73 100644 --- a/src/Microsoft.AspNet.Security.OAuthBearer/OAuthBearerAuthenticationHandler.cs +++ b/src/Microsoft.AspNet.Security.OAuthBearer/OAuthBearerAuthenticationHandler.cs @@ -5,7 +5,6 @@ using System.Collections.Generic; using System.IdentityModel.Tokens; using System.Linq; -using System.Runtime.ExceptionServices; using System.Security.Claims; using System.Threading.Tasks; using Microsoft.AspNet.Http; @@ -38,7 +37,6 @@ protected override AuthenticationTicket AuthenticateCore() /// protected override async Task AuthenticateCoreAsync() { - ExceptionDispatchInfo authFailedEx = null; string token = null; try { @@ -144,16 +142,10 @@ protected override async Task AuthenticateCoreAsync() } catch (Exception ex) { - // We can't await inside a catch block, capture and handle outside. - authFailedEx = ExceptionDispatchInfo.Capture(ex); - } - - if (authFailedEx != null) - { - _logger.WriteError("Exception occurred while processing message", authFailedEx.SourceException); + _logger.WriteError("Exception occurred while processing message", ex); // Refresh the configuration for exceptions that may be caused by key rollovers. The user can also request a refresh in the notification. - if (Options.RefreshOnIssuerKeyNotFound && authFailedEx.SourceException.GetType().Equals(typeof(SecurityTokenSignatureKeyNotFoundException))) + if (Options.RefreshOnIssuerKeyNotFound && ex.GetType().Equals(typeof(SecurityTokenSignatureKeyNotFoundException))) { Options.ConfigurationManager.RequestRefresh(); } @@ -162,7 +154,7 @@ protected override async Task AuthenticateCoreAsync() new AuthenticationFailedNotification(Context, Options) { ProtocolMessage = Context, - Exception = authFailedEx.SourceException + Exception = ex }; await Options.Notifications.AuthenticationFailed(authenticationFailedNotification); @@ -176,10 +168,8 @@ protected override async Task AuthenticateCoreAsync() return null; } - authFailedEx.Throw(); + throw; } - - return null; } protected override void ApplyResponseChallenge() @@ -189,6 +179,11 @@ protected override void ApplyResponseChallenge() protected override async Task ApplyResponseChallengeAsync() { + if ((Response.StatusCode != 401) || (ChallengeContext == null)) + { + return; + } + await Options.Notifications.ApplyChallenge(new AuthenticationChallengeNotification(Context, Options)); } diff --git a/src/Microsoft.AspNet.Security.OpenIdConnect/NonceCache.cs b/src/Microsoft.AspNet.Security.OpenIdConnect/INonceCache.cs similarity index 69% rename from src/Microsoft.AspNet.Security.OpenIdConnect/NonceCache.cs rename to src/Microsoft.AspNet.Security.OpenIdConnect/INonceCache.cs index 11c09b345..3f5255f56 100644 --- a/src/Microsoft.AspNet.Security.OpenIdConnect/NonceCache.cs +++ b/src/Microsoft.AspNet.Security.OpenIdConnect/INonceCache.cs @@ -1,4 +1,5 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. namespace Microsoft.AspNet.Security.OpenIdConnect { diff --git a/src/Microsoft.AspNet.Security.OpenIdConnect/Notifications/AuthorizationCodeReceivedNotification.cs b/src/Microsoft.AspNet.Security.OpenIdConnect/Notifications/AuthorizationCodeReceivedNotification.cs index cbcdc0618..9c7694e56 100644 --- a/src/Microsoft.AspNet.Security.OpenIdConnect/Notifications/AuthorizationCodeReceivedNotification.cs +++ b/src/Microsoft.AspNet.Security.OpenIdConnect/Notifications/AuthorizationCodeReceivedNotification.cs @@ -1,4 +1,5 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using Microsoft.AspNet.Http; using Microsoft.AspNet.Security.OpenIdConnect; diff --git a/src/Microsoft.AspNet.Security.OpenIdConnect/OpenIdConnectAuthenticationDefaults.cs b/src/Microsoft.AspNet.Security.OpenIdConnect/OpenIdConnectAuthenticationDefaults.cs index d6271488a..5942efb4d 100644 --- a/src/Microsoft.AspNet.Security.OpenIdConnect/OpenIdConnectAuthenticationDefaults.cs +++ b/src/Microsoft.AspNet.Security.OpenIdConnect/OpenIdConnectAuthenticationDefaults.cs @@ -1,5 +1,5 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. namespace Microsoft.AspNet.Security.OpenIdConnect { diff --git a/src/Microsoft.AspNet.Security.OpenIdConnect/OpenIdConnectAuthenticationExtensions.cs b/src/Microsoft.AspNet.Security.OpenIdConnect/OpenIdConnectAuthenticationExtensions.cs index 81a74b65c..5d4a72b21 100644 --- a/src/Microsoft.AspNet.Security.OpenIdConnect/OpenIdConnectAuthenticationExtensions.cs +++ b/src/Microsoft.AspNet.Security.OpenIdConnect/OpenIdConnectAuthenticationExtensions.cs @@ -1,4 +1,5 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; using Microsoft.AspNet.Security.OpenIdConnect; diff --git a/src/Microsoft.AspNet.Security.OpenIdConnect/OpenIdConnectAuthenticationMiddleware.cs b/src/Microsoft.AspNet.Security.OpenIdConnect/OpenIdConnectAuthenticationMiddleware.cs index bfe82b51f..bbe59f50d 100644 --- a/src/Microsoft.AspNet.Security.OpenIdConnect/OpenIdConnectAuthenticationMiddleware.cs +++ b/src/Microsoft.AspNet.Security.OpenIdConnect/OpenIdConnectAuthenticationMiddleware.cs @@ -1,4 +1,5 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; using System.Collections.ObjectModel; diff --git a/src/Microsoft.AspNet.Security.OpenIdConnect/OpenIdConnectAuthenticationNotifications.cs b/src/Microsoft.AspNet.Security.OpenIdConnect/OpenIdConnectAuthenticationNotifications.cs index 36ee2fd25..327bbfa59 100644 --- a/src/Microsoft.AspNet.Security.OpenIdConnect/OpenIdConnectAuthenticationNotifications.cs +++ b/src/Microsoft.AspNet.Security.OpenIdConnect/OpenIdConnectAuthenticationNotifications.cs @@ -1,4 +1,5 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; using System.Threading.Tasks; diff --git a/src/Microsoft.AspNet.Security.OpenIdConnect/OpenIdConnectAuthenticationOptions.cs b/src/Microsoft.AspNet.Security.OpenIdConnect/OpenIdConnectAuthenticationOptions.cs index 5022cbf3c..5f1b5077e 100644 --- a/src/Microsoft.AspNet.Security.OpenIdConnect/OpenIdConnectAuthenticationOptions.cs +++ b/src/Microsoft.AspNet.Security.OpenIdConnect/OpenIdConnectAuthenticationOptions.cs @@ -1,4 +1,5 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; using System.Collections.Generic; diff --git a/src/Microsoft.AspNet.Security.OpenIdConnect/OpenidConnectAuthenticationHandler.cs b/src/Microsoft.AspNet.Security.OpenIdConnect/OpenidConnectAuthenticationHandler.cs index 530503910..317cd42e8 100644 --- a/src/Microsoft.AspNet.Security.OpenIdConnect/OpenidConnectAuthenticationHandler.cs +++ b/src/Microsoft.AspNet.Security.OpenIdConnect/OpenidConnectAuthenticationHandler.cs @@ -1,11 +1,11 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; using System.Globalization; using System.IdentityModel.Tokens; using System.IO; using System.Linq; -using System.Runtime.ExceptionServices; using System.Security.Claims; using System.Threading.Tasks; using Microsoft.AspNet.Http; @@ -122,7 +122,7 @@ protected override async Task ApplyResponseChallengeAsync() } // order for redirect_uri - // 1. challenge.Properties.RedirectUri + // 1. challenge.Properties.RedirectUri // 2. CurrentUri AuthenticationProperties properties = new AuthenticationProperties(ChallengeContext.Properties); if (string.IsNullOrEmpty(properties.RedirectUri)) @@ -224,7 +224,6 @@ protected override async Task AuthenticateCoreAsync() return null; } - ExceptionDispatchInfo authFailedEx = null; try { var messageReceivedNotification = new MessageReceivedNotification(Context, Options) @@ -410,16 +409,10 @@ protected override async Task AuthenticateCoreAsync() } catch (Exception exception) { - // We can't await inside a catch block, capture and handle outside. - authFailedEx = ExceptionDispatchInfo.Capture(exception); - } - - if (authFailedEx != null) - { - _logger.WriteError("Exception occurred while processing message", authFailedEx.SourceException); + _logger.WriteError("Exception occurred while processing message", exception); // Refresh the configuration for exceptions that may be caused by key rollovers. The user can also request a refresh in the notification. - if (Options.RefreshOnIssuerKeyNotFound && authFailedEx.SourceException.GetType().Equals(typeof(SecurityTokenSignatureKeyNotFoundException))) + if (Options.RefreshOnIssuerKeyNotFound && exception.GetType().Equals(typeof(SecurityTokenSignatureKeyNotFoundException))) { Options.ConfigurationManager.RequestRefresh(); } @@ -427,7 +420,7 @@ protected override async Task AuthenticateCoreAsync() var authenticationFailedNotification = new AuthenticationFailedNotification(Context, Options) { ProtocolMessage = openIdConnectMessage, - Exception = authFailedEx.SourceException + Exception = exception }; await Options.Notifications.AuthenticationFailed(authenticationFailedNotification); @@ -441,10 +434,8 @@ protected override async Task AuthenticateCoreAsync() return null; } - authFailedEx.Throw(); + throw; } - - return null; } /// diff --git a/test/Microsoft.AspNet.Security.Test/OAuthBearer/OAuthBearerMiddlewareTests.cs b/test/Microsoft.AspNet.Security.Test/OAuthBearer/OAuthBearerMiddlewareTests.cs index 6fa8b7afd..eff8e2884 100644 --- a/test/Microsoft.AspNet.Security.Test/OAuthBearer/OAuthBearerMiddlewareTests.cs +++ b/test/Microsoft.AspNet.Security.Test/OAuthBearer/OAuthBearerMiddlewareTests.cs @@ -1,4 +1,5 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; using System.Collections.Generic; diff --git a/test/Microsoft.AspNet.Security.Test/OpenIdConnectMiddlewareTests/OpenIdConnectMiddlewareTests.cs b/test/Microsoft.AspNet.Security.Test/OpenIdConnect/OpenIdConnectMiddlewareTests.cs similarity index 99% rename from test/Microsoft.AspNet.Security.Test/OpenIdConnectMiddlewareTests/OpenIdConnectMiddlewareTests.cs rename to test/Microsoft.AspNet.Security.Test/OpenIdConnect/OpenIdConnectMiddlewareTests.cs index 652c295ec..e3a5df471 100644 --- a/test/Microsoft.AspNet.Security.Test/OpenIdConnectMiddlewareTests/OpenIdConnectMiddlewareTests.cs +++ b/test/Microsoft.AspNet.Security.Test/OpenIdConnect/OpenIdConnectMiddlewareTests.cs @@ -1,4 +1,5 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; using System.Collections.Generic; From 61bdaec1e2631ce68e057d044697ad2b1507aa5a Mon Sep 17 00:00:00 2001 From: Chris Ross Date: Wed, 14 Jan 2015 17:04:10 -0800 Subject: [PATCH 107/216] Handle QueryBuilder namespace change. --- .../FacebookAuthenticationHandler.cs | 1 + .../OAuthAuthenticationHandler.cs | 1 + 2 files changed, 2 insertions(+) diff --git a/src/Microsoft.AspNet.Security.Facebook/FacebookAuthenticationHandler.cs b/src/Microsoft.AspNet.Security.Facebook/FacebookAuthenticationHandler.cs index 455cf1a4c..dd2b43ffe 100644 --- a/src/Microsoft.AspNet.Security.Facebook/FacebookAuthenticationHandler.cs +++ b/src/Microsoft.AspNet.Security.Facebook/FacebookAuthenticationHandler.cs @@ -9,6 +9,7 @@ using System.Text; using System.Threading.Tasks; using Microsoft.AspNet.Http; +using Microsoft.AspNet.Http.Extensions; using Microsoft.AspNet.Http.Security; using Microsoft.AspNet.PipelineCore.Collections; using Microsoft.AspNet.Security.OAuth; diff --git a/src/Microsoft.AspNet.Security.OAuth/OAuthAuthenticationHandler.cs b/src/Microsoft.AspNet.Security.OAuth/OAuthAuthenticationHandler.cs index 5a4ffebbd..b165ca41c 100644 --- a/src/Microsoft.AspNet.Security.OAuth/OAuthAuthenticationHandler.cs +++ b/src/Microsoft.AspNet.Security.OAuth/OAuthAuthenticationHandler.cs @@ -8,6 +8,7 @@ using System.Security.Claims; using System.Threading.Tasks; using Microsoft.AspNet.Http; +using Microsoft.AspNet.Http.Extensions; using Microsoft.AspNet.Http.Security; using Microsoft.AspNet.Security.Infrastructure; using Microsoft.AspNet.WebUtilities; From 123e649ee2888d3d51012f8edafdfd843b20472f Mon Sep 17 00:00:00 2001 From: Pranav K Date: Thu, 15 Jan 2015 07:54:10 -0800 Subject: [PATCH 108/216] * Removing transitive dependencies from project.json * Fix casing for project.json --- .../Project.json | 48 ------------------- .../project.json | 19 ++++++++ .../project.json | 3 +- 3 files changed, 20 insertions(+), 50 deletions(-) delete mode 100644 src/Microsoft.AspNet.Security.OpenIdConnect/Project.json create mode 100644 src/Microsoft.AspNet.Security.OpenIdConnect/project.json diff --git a/src/Microsoft.AspNet.Security.OpenIdConnect/Project.json b/src/Microsoft.AspNet.Security.OpenIdConnect/Project.json deleted file mode 100644 index 7a6d95a05..000000000 --- a/src/Microsoft.AspNet.Security.OpenIdConnect/Project.json +++ /dev/null @@ -1,48 +0,0 @@ -{ - "version": "1.0.0-*", - "dependencies": { - "Microsoft.AspNet.Http.Extensions": "1.0.0-*", - "Microsoft.AspNet.Security": "1.0.0-*", - "Microsoft.AspNet.Security.DataProtection": "1.0.0-*", - "Microsoft.AspNet.WebUtilities": "1.0.0-*", - "Microsoft.Framework.Logging": "1.0.0-*", - "Newtonsoft.Json": "6.0.4", - "Microsoft.IdentityModel.Protocol.Extensions": "2.0.0.0-beta1-*", - "System.IdentityModel.Tokens": "5.0.0.0-beta1-*" - }, - "frameworks": { - "aspnet50": { - "frameworkAssemblies": { - "System.Net.Http": "", - "System.Net.Http.WebRequest": "" - } - }, - "aspnetcore50": { - "dependencies": { - "System.Collections": "4.0.10-beta-*", - "System.ComponentModel": "4.0.0-beta-*", - "System.Console": "4.0.0-beta-*", - "System.Diagnostics.Debug": "4.0.10-beta-*", - "System.Diagnostics.Tools": "4.0.0-beta-*", - "System.Dynamic.Runtime": "4.0.0-beta-*", - "System.Globalization": "4.0.10-beta-*", - "System.IO": "4.0.10-beta-*", - "System.IO.Compression": "4.0.0-beta-*", - "System.Linq": "4.0.0-beta-*", - "System.Net.Http.WinHttpHandler": "4.0.0-beta-*", - "System.ObjectModel": "4.0.10-beta-*", - "System.Reflection": "4.0.10-beta-*", - "System.Resources.ResourceManager": "4.0.0-beta-*", - "System.Runtime": "4.0.20-beta-*", - "System.Runtime.Extensions": "4.0.10-beta-*", - "System.Runtime.InteropServices": "4.0.20-beta-*", - "System.Security.Claims": "4.0.0-beta-*", - "System.Security.Cryptography.Hashing.Algorithms": "4.0.0-beta-*", - "System.Security.Principal": "4.0.0-beta-*", - "System.Threading": "4.0.0-beta-*", - "System.Threading.Tasks": "4.0.10-beta-*", - "System.Net.Http": "4.0.0-*" - } - } - } -} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Security.OpenIdConnect/project.json b/src/Microsoft.AspNet.Security.OpenIdConnect/project.json new file mode 100644 index 000000000..728e82b19 --- /dev/null +++ b/src/Microsoft.AspNet.Security.OpenIdConnect/project.json @@ -0,0 +1,19 @@ +{ + "version": "1.0.0-*", + "dependencies": { + "Microsoft.AspNet.Security": "1.0.0-*", + "Microsoft.IdentityModel.Protocol.Extensions": "2.0.0.0-beta1-*" + }, + "frameworks": { + "aspnet50": { + "frameworkAssemblies": { + "System.Net.Http.WebRequest": "" + } + }, + "aspnetcore50": { + "dependencies": { + "System.Net.Http.WinHttpHandler": "4.0.0-beta-*" + } + } + } +} \ No newline at end of file diff --git a/test/Microsoft.AspNet.Security.Test/project.json b/test/Microsoft.AspNet.Security.Test/project.json index 504d228b6..1ab85d584 100644 --- a/test/Microsoft.AspNet.Security.Test/project.json +++ b/test/Microsoft.AspNet.Security.Test/project.json @@ -20,8 +20,7 @@ "frameworks": { "aspnet50": { "dependencies": { - "Shouldly": "1.1.1.1", - "System.Security.Claims": "1.0.0-*" + "Shouldly": "1.1.1.1" } } } From f7c502a9e6150e07499c048cb2d92086f2e0f531 Mon Sep 17 00:00:00 2001 From: Chris Ross Date: Thu, 15 Jan 2015 13:57:07 -0800 Subject: [PATCH 109/216] Handle PipelineCore rename. --- .../FacebookAuthenticationHandler.cs | 2 +- .../TwitterAuthenticationHandler.cs | 2 +- src/Microsoft.AspNet.Security/AuthenticationOptions.cs | 5 ----- .../Infrastructure/HttpContextExtensions.cs | 2 +- src/Microsoft.AspNet.Security/project.json | 2 +- .../Cookies/Infrastructure/CookieChunkingTests.cs | 2 +- test/Microsoft.AspNet.Security.Test/SecurityHelperTests.cs | 2 +- 7 files changed, 6 insertions(+), 11 deletions(-) diff --git a/src/Microsoft.AspNet.Security.Facebook/FacebookAuthenticationHandler.cs b/src/Microsoft.AspNet.Security.Facebook/FacebookAuthenticationHandler.cs index dd2b43ffe..7eabae101 100644 --- a/src/Microsoft.AspNet.Security.Facebook/FacebookAuthenticationHandler.cs +++ b/src/Microsoft.AspNet.Security.Facebook/FacebookAuthenticationHandler.cs @@ -9,9 +9,9 @@ using System.Text; using System.Threading.Tasks; using Microsoft.AspNet.Http; +using Microsoft.AspNet.Http.Core.Collections; using Microsoft.AspNet.Http.Extensions; using Microsoft.AspNet.Http.Security; -using Microsoft.AspNet.PipelineCore.Collections; using Microsoft.AspNet.Security.OAuth; using Microsoft.AspNet.WebUtilities; using Microsoft.Framework.Logging; diff --git a/src/Microsoft.AspNet.Security.Twitter/TwitterAuthenticationHandler.cs b/src/Microsoft.AspNet.Security.Twitter/TwitterAuthenticationHandler.cs index de4dee266..46dcd43f4 100644 --- a/src/Microsoft.AspNet.Security.Twitter/TwitterAuthenticationHandler.cs +++ b/src/Microsoft.AspNet.Security.Twitter/TwitterAuthenticationHandler.cs @@ -10,8 +10,8 @@ using System.Text; using System.Threading.Tasks; using Microsoft.AspNet.Http; +using Microsoft.AspNet.Http.Core.Collections; using Microsoft.AspNet.Http.Security; -using Microsoft.AspNet.PipelineCore.Collections; using Microsoft.AspNet.Security.Infrastructure; using Microsoft.AspNet.Security.Twitter.Messages; using Microsoft.AspNet.WebUtilities; diff --git a/src/Microsoft.AspNet.Security/AuthenticationOptions.cs b/src/Microsoft.AspNet.Security/AuthenticationOptions.cs index e25383cfe..411e13481 100644 --- a/src/Microsoft.AspNet.Security/AuthenticationOptions.cs +++ b/src/Microsoft.AspNet.Security/AuthenticationOptions.cs @@ -1,12 +1,7 @@ // Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System; -using System.Collections.Generic; using Microsoft.AspNet.Http.Security; -using Microsoft.AspNet.HttpFeature.Security; -using Microsoft.AspNet.PipelineCore.Security; namespace Microsoft.AspNet.Security { diff --git a/src/Microsoft.AspNet.Security/Infrastructure/HttpContextExtensions.cs b/src/Microsoft.AspNet.Security/Infrastructure/HttpContextExtensions.cs index 59c29fe82..642809e18 100644 --- a/src/Microsoft.AspNet.Security/Infrastructure/HttpContextExtensions.cs +++ b/src/Microsoft.AspNet.Security/Infrastructure/HttpContextExtensions.cs @@ -2,8 +2,8 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using Microsoft.AspNet.Http; +using Microsoft.AspNet.Http.Core.Security; using Microsoft.AspNet.HttpFeature.Security; -using Microsoft.AspNet.PipelineCore.Security; namespace Microsoft.AspNet.Security.Infrastructure { diff --git a/src/Microsoft.AspNet.Security/project.json b/src/Microsoft.AspNet.Security/project.json index cac89fbad..6e7c66c59 100644 --- a/src/Microsoft.AspNet.Security/project.json +++ b/src/Microsoft.AspNet.Security/project.json @@ -4,7 +4,7 @@ "dependencies": { "Microsoft.AspNet.RequestContainer": "1.0.0-*", "Microsoft.AspNet.HttpFeature": { "version": "1.0.0-*", "type": "build" }, - "Microsoft.AspNet.PipelineCore": "1.0.0-*", + "Microsoft.AspNet.Http.Core": "1.0.0-*", "Microsoft.AspNet.Security.DataProtection": "1.0.0-*", "Microsoft.Framework.Logging": "1.0.0-*" }, diff --git a/test/Microsoft.AspNet.Security.Test/Cookies/Infrastructure/CookieChunkingTests.cs b/test/Microsoft.AspNet.Security.Test/Cookies/Infrastructure/CookieChunkingTests.cs index 4df8763bd..04bbadf68 100644 --- a/test/Microsoft.AspNet.Security.Test/Cookies/Infrastructure/CookieChunkingTests.cs +++ b/test/Microsoft.AspNet.Security.Test/Cookies/Infrastructure/CookieChunkingTests.cs @@ -4,7 +4,7 @@ using System; using System.Collections.Generic; using Microsoft.AspNet.Http; -using Microsoft.AspNet.PipelineCore; +using Microsoft.AspNet.Http.Core; using Xunit; namespace Microsoft.AspNet.Security.Cookies.Infrastructure diff --git a/test/Microsoft.AspNet.Security.Test/SecurityHelperTests.cs b/test/Microsoft.AspNet.Security.Test/SecurityHelperTests.cs index 76f8f6e0a..dae0aed31 100644 --- a/test/Microsoft.AspNet.Security.Test/SecurityHelperTests.cs +++ b/test/Microsoft.AspNet.Security.Test/SecurityHelperTests.cs @@ -6,7 +6,7 @@ using System.Security.Claims; using System.Security.Principal; using Microsoft.AspNet.Http; -using Microsoft.AspNet.PipelineCore; +using Microsoft.AspNet.Http.Core; using Microsoft.AspNet.Security.Infrastructure; using Shouldly; using Xunit; From 4a635835af1049679103fdca97716e814408addc Mon Sep 17 00:00:00 2001 From: Hao Kung Date: Thu, 15 Jan 2015 23:37:35 -0800 Subject: [PATCH 110/216] Initial iteration of new Authorization Service --- .../AuthorizationContext.cs | 61 ++ .../AuthorizationHandler.cs | 58 ++ .../AuthorizationOptions.cs | 23 + .../AuthorizationPolicy.cs | 25 +- .../AuthorizationPolicyBuilder.cs | 58 ++ .../AuthorizationPolicyContext.cs | 60 -- .../AuthorizationServiceExtensions.cs | 82 --- .../ClaimsAuthorizationHandler.cs | 32 + .../ClaimsAuthorizationRequirement.cs | 15 + .../DefaultAuthorizationService.cs | 98 +-- .../DenyAnonymousAuthorizationHandler.cs | 20 + .../DenyAnonymousAuthorizationRequirement.cs | 9 + ...tionPolicy.cs => IAuthorizationHandler.cs} | 8 +- .../IAuthorizationRequirement.cs | 9 + .../IAuthorizationService.cs | 30 +- .../PassThroughAuthorizationHandler.cs | 20 + .../ServiceCollectionExtensions.cs | 32 + .../DefaultAuthorizationServiceTests.cs | 577 +++++++++++++----- .../FakePolicy.cs | 52 -- .../TestApplicationEnvironment.cs | 37 -- 20 files changed, 821 insertions(+), 485 deletions(-) create mode 100644 src/Microsoft.AspNet.Security/AuthorizationContext.cs create mode 100644 src/Microsoft.AspNet.Security/AuthorizationHandler.cs create mode 100644 src/Microsoft.AspNet.Security/AuthorizationOptions.cs create mode 100644 src/Microsoft.AspNet.Security/AuthorizationPolicyBuilder.cs delete mode 100644 src/Microsoft.AspNet.Security/AuthorizationPolicyContext.cs delete mode 100644 src/Microsoft.AspNet.Security/AuthorizationServiceExtensions.cs create mode 100644 src/Microsoft.AspNet.Security/ClaimsAuthorizationHandler.cs create mode 100644 src/Microsoft.AspNet.Security/ClaimsAuthorizationRequirement.cs create mode 100644 src/Microsoft.AspNet.Security/DenyAnonymousAuthorizationHandler.cs create mode 100644 src/Microsoft.AspNet.Security/DenyAnonymousAuthorizationRequirement.cs rename src/Microsoft.AspNet.Security/{IAuthorizationPolicy.cs => IAuthorizationHandler.cs} (50%) create mode 100644 src/Microsoft.AspNet.Security/IAuthorizationRequirement.cs create mode 100644 src/Microsoft.AspNet.Security/PassThroughAuthorizationHandler.cs create mode 100644 src/Microsoft.AspNet.Security/ServiceCollectionExtensions.cs delete mode 100644 test/Microsoft.AspNet.Security.Test/FakePolicy.cs delete mode 100644 test/Microsoft.AspNet.Security.Test/TestApplicationEnvironment.cs diff --git a/src/Microsoft.AspNet.Security/AuthorizationContext.cs b/src/Microsoft.AspNet.Security/AuthorizationContext.cs new file mode 100644 index 000000000..0c6dc0619 --- /dev/null +++ b/src/Microsoft.AspNet.Security/AuthorizationContext.cs @@ -0,0 +1,61 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System.Collections.Generic; +using System.Linq; +using System.Security.Claims; +using Microsoft.AspNet.Http; + +namespace Microsoft.AspNet.Security +{ + /// + /// Contains authorization information used by . + /// + public class AuthorizationContext + { + private HashSet _pendingRequirements = new HashSet(); + private bool _failCalled; + private bool _succeedCalled; + + public AuthorizationContext( + [NotNull] AuthorizationPolicy policy, + HttpContext context, + object resource) + { + Policy = policy; + Context = context; + Resource = resource; + foreach (var req in Policy.Requirements) + { + _pendingRequirements.Add(req); + } + } + + public AuthorizationPolicy Policy { get; private set; } + public ClaimsPrincipal User { get { return Context.User; } } + public HttpContext Context { get; private set; } + public object Resource { get; private set; } + + public IEnumerable PendingRequirements { get { return _pendingRequirements; } } + + public bool HasFailed { get { return _failCalled; } } + + public bool HasSucceeded { + get + { + return !_failCalled && _succeedCalled && !PendingRequirements.Any(); + } + } + + public void Fail() + { + _failCalled = true; + } + + public void Succeed(IAuthorizationRequirement requirement) + { + _succeedCalled = true; + _pendingRequirements.Remove(requirement); + } + } +} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Security/AuthorizationHandler.cs b/src/Microsoft.AspNet.Security/AuthorizationHandler.cs new file mode 100644 index 000000000..d91331870 --- /dev/null +++ b/src/Microsoft.AspNet.Security/AuthorizationHandler.cs @@ -0,0 +1,58 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Linq; +using System.Threading.Tasks; + +namespace Microsoft.AspNet.Security +{ + // Music store use case + + // await AuthorizeAsync(user, "Edit", albumInstance); + + // No policy name needed because this is auto based on resource (operation is the policy name) + //RegisterOperation which auto generates the policy for Authorize + //bool AuthorizeAsync(ClaimsPrincipal, string operation, TResource instance) + //bool AuthorizeAsync(IAuthorization, ClaimsPrincipal, string operation, TResource instance) + public abstract class AuthorizationHandler : IAuthorizationHandler + where TRequirement : IAuthorizationRequirement + { + public async Task HandleAsync(AuthorizationContext context) + { + foreach (var req in context.Policy.Requirements.OfType()) + { + if (await CheckAsync(context, req)) + { + context.Succeed(req); + } + else + { + context.Fail(); + } + } + } + + public abstract Task CheckAsync(AuthorizationContext context, TRequirement requirement); + } + + // TODO: + //public abstract class AuthorizationHandler : AuthorizationHandler + // where TResource : class + // where TRequirement : IAuthorizationRequirement + //{ + // public override Task HandleAsync(AuthorizationContext context) + // { + // var resource = context.Resource as TResource; + // if (resource != null) + // { + // return HandleAsync(context, resource); + // } + + // return Task.FromResult(0); + + // } + + // public abstract Task HandleAsync(AuthorizationContext context, TResource resource); + //} +} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Security/AuthorizationOptions.cs b/src/Microsoft.AspNet.Security/AuthorizationOptions.cs new file mode 100644 index 000000000..667ee4fcb --- /dev/null +++ b/src/Microsoft.AspNet.Security/AuthorizationOptions.cs @@ -0,0 +1,23 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System.Collections.Generic; + +namespace Microsoft.AspNet.Security +{ + public class AuthorizationOptions + { + // TODO: make this case insensitive + private IDictionary PolicyMap { get; } = new Dictionary(); + + public void AddPolicy([NotNull] string name, [NotNull] AuthorizationPolicy policy) + { + PolicyMap[name] = policy; + } + + public AuthorizationPolicy GetPolicy([NotNull] string name) + { + return PolicyMap.ContainsKey(name) ? PolicyMap[name] : null; + } + } +} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Security/AuthorizationPolicy.cs b/src/Microsoft.AspNet.Security/AuthorizationPolicy.cs index a58ae858a..d142eb1b6 100644 --- a/src/Microsoft.AspNet.Security/AuthorizationPolicy.cs +++ b/src/Microsoft.AspNet.Security/AuthorizationPolicy.cs @@ -2,31 +2,18 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System.Collections.Generic; -using System.Security.Claims; -using System.Threading.Tasks; namespace Microsoft.AspNet.Security { - /// - /// This class provides a base implementation for - /// - public abstract class AuthorizationPolicy : IAuthorizationPolicy + public class AuthorizationPolicy { - public int Order { get; set; } - - public virtual Task ApplyingAsync(AuthorizationPolicyContext context) + public AuthorizationPolicy(IEnumerable requirements, IEnumerable activeAuthenticationTypes) { - return Task.FromResult(0); + Requirements = requirements; + ActiveAuthenticationTypes = activeAuthenticationTypes; } - public virtual Task ApplyAsync(AuthorizationPolicyContext context) - { - return Task.FromResult(0); - } - - public virtual Task AppliedAsync(AuthorizationPolicyContext context) - { - return Task.FromResult(0); - } + public IEnumerable Requirements { get; private set; } + public IEnumerable ActiveAuthenticationTypes { get; private set; } } } diff --git a/src/Microsoft.AspNet.Security/AuthorizationPolicyBuilder.cs b/src/Microsoft.AspNet.Security/AuthorizationPolicyBuilder.cs new file mode 100644 index 000000000..520bc7746 --- /dev/null +++ b/src/Microsoft.AspNet.Security/AuthorizationPolicyBuilder.cs @@ -0,0 +1,58 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System.Collections.Generic; +using System.Security.Claims; + +namespace Microsoft.AspNet.Security +{ + public class AuthorizationPolicyBuilder + { + public AuthorizationPolicyBuilder(params string[] activeAuthenticationTypes) + { + foreach (var authType in activeAuthenticationTypes) { + ActiveAuthenticationTypes.Add(authType); + } + } + + public IList Requirements { get; set; } = new List(); + public IList ActiveAuthenticationTypes { get; set; } = new List(); + + public AuthorizationPolicyBuilder RequiresClaim([NotNull] string claimType, params string[] requiredValues) + { + Requirements.Add(new ClaimsAuthorizationRequirement + { + ClaimType = claimType, + AllowedValues = requiredValues + }); + return this; + } + + public AuthorizationPolicyBuilder RequiresClaim([NotNull] string claimType) + { + Requirements.Add(new ClaimsAuthorizationRequirement + { + ClaimType = claimType, + AllowedValues = null + }); + return this; + } + + public AuthorizationPolicyBuilder RequiresRole([NotNull] params string[] roles) + { + RequiresClaim(ClaimTypes.Role, roles); + return this; + } + + public AuthorizationPolicyBuilder RequireAuthenticatedUser() + { + Requirements.Add(new DenyAnonymousAuthorizationRequirement()); + return this; + } + + public AuthorizationPolicy Build() + { + return new AuthorizationPolicy(Requirements, ActiveAuthenticationTypes); + } + } +} diff --git a/src/Microsoft.AspNet.Security/AuthorizationPolicyContext.cs b/src/Microsoft.AspNet.Security/AuthorizationPolicyContext.cs deleted file mode 100644 index b394bfcb6..000000000 --- a/src/Microsoft.AspNet.Security/AuthorizationPolicyContext.cs +++ /dev/null @@ -1,60 +0,0 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System.Collections.Generic; -using System.Security.Claims; -using System.Linq; - -namespace Microsoft.AspNet.Security -{ - /// - /// Contains authorization information used by . - /// - public class AuthorizationPolicyContext - { - public AuthorizationPolicyContext(IEnumerable claims, ClaimsPrincipal user, object resource ) - { - Claims = (claims ?? Enumerable.Empty()).ToList(); - User = user; - Resource = resource; - - // user claims are copied to a new and mutable list - UserClaims = user != null - ? user.Claims.ToList() - : new List(); - } - - /// - /// The list of claims the is checking. - /// - public IList Claims { get; private set; } - - /// - /// The user to check the claims against. - /// - public ClaimsPrincipal User { get; private set; } - - /// - /// The claims of the user. - /// - /// - /// This list can be modified by policies for retries. - /// - public IList UserClaims { get; private set; } - - /// - /// An optional resource associated to the check. - /// - public object Resource { get; private set; } - - /// - /// Gets or set whether the permission will be granted to the user. - /// - public bool Authorized { get; set; } - - /// - /// When set to true, the authorization check will be processed again. - /// - public bool Retry { get; set; } - } -} diff --git a/src/Microsoft.AspNet.Security/AuthorizationServiceExtensions.cs b/src/Microsoft.AspNet.Security/AuthorizationServiceExtensions.cs deleted file mode 100644 index 17ec58196..000000000 --- a/src/Microsoft.AspNet.Security/AuthorizationServiceExtensions.cs +++ /dev/null @@ -1,82 +0,0 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Security.Claims; -using System.Threading.Tasks; - -namespace Microsoft.AspNet.Security -{ - public static class AuthorizationServiceExtensions - { - /// - /// Checks if a user has specific claims. - /// - /// The claim to check against a specific user. - /// The user to check claims against. - /// true when the user fulfills one of the claims, false otherwise. - public static Task AuthorizeAsync([NotNull] this IAuthorizationService service, Claim claim, ClaimsPrincipal user) - { - return service.AuthorizeAsync(new Claim[] { claim }, user); - } - - /// - /// Checks if a user has specific claims. - /// - /// The claim to check against a specific user. - /// The user to check claims against. - /// true when the user fulfills one of the claims, false otherwise. - public static bool Authorize([NotNull] this IAuthorizationService service, Claim claim, ClaimsPrincipal user) - { - return service.Authorize(new Claim[] { claim }, user); - } - - /// - /// Checks if a user has specific claims for a specific context obj. - /// - /// The claim to check against a specific user. - /// The user to check claims against. - /// The resource the claims should be check with. - /// true when the user fulfills one of the claims, false otherwise. - public static Task AuthorizeAsync([NotNull] this IAuthorizationService service, Claim claim, ClaimsPrincipal user, object resource) - { - return service.AuthorizeAsync(new Claim[] { claim }, user, resource); - } - - /// - /// Checks if a user has specific claims for a specific context obj. - /// - /// The claimsto check against a specific user. - /// The user to check claims against. - /// The resource the claims should be check with. - /// true when the user fulfills one of the claims, false otherwise. - public static bool Authorize([NotNull] this IAuthorizationService service, Claim claim, ClaimsPrincipal user, object resource) - { - return service.Authorize(new Claim[] { claim }, user, resource); - } - - /// - /// Checks if a user has specific claims. - /// - /// The claims to check against a specific user. - /// The user to check claims against. - /// true when the user fulfills one of the claims, false otherwise. - public static Task AuthorizeAsync([NotNull] this IAuthorizationService service, IEnumerable claims, ClaimsPrincipal user) - { - return service.AuthorizeAsync(claims, user, null); - } - - /// - /// Checks if a user has specific claims. - /// - /// The claims to check against a specific user. - /// The user to check claims against. - /// true when the user fulfills one of the claims, false otherwise. - public static bool Authorize([NotNull] this IAuthorizationService service, IEnumerable claims, ClaimsPrincipal user) - { - return service.Authorize(claims, user, null); - } - } -} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Security/ClaimsAuthorizationHandler.cs b/src/Microsoft.AspNet.Security/ClaimsAuthorizationHandler.cs new file mode 100644 index 000000000..9f3f58c3a --- /dev/null +++ b/src/Microsoft.AspNet.Security/ClaimsAuthorizationHandler.cs @@ -0,0 +1,32 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Linq; +using System.Threading.Tasks; + +namespace Microsoft.AspNet.Security +{ + public class ClaimsAuthorizationHandler : AuthorizationHandler + { + public override Task CheckAsync(AuthorizationContext context, ClaimsAuthorizationRequirement requirement) + { + if (context.Context.User == null) + { + return Task.FromResult(false); + } + + bool found = false; + if (requirement.AllowedValues == null || !requirement.AllowedValues.Any()) + { + found = context.Context.User.Claims.Any(c => string.Equals(c.Type, requirement.ClaimType, StringComparison.OrdinalIgnoreCase)); + } + else + { + found = context.Context.User.Claims.Any(c => string.Equals(c.Type, requirement.ClaimType, StringComparison.OrdinalIgnoreCase) + && requirement.AllowedValues.Contains(c.Value, StringComparer.Ordinal)); + } + return Task.FromResult(found); + } + } +} diff --git a/src/Microsoft.AspNet.Security/ClaimsAuthorizationRequirement.cs b/src/Microsoft.AspNet.Security/ClaimsAuthorizationRequirement.cs new file mode 100644 index 000000000..8ec5e7c7e --- /dev/null +++ b/src/Microsoft.AspNet.Security/ClaimsAuthorizationRequirement.cs @@ -0,0 +1,15 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System.Collections.Generic; + +namespace Microsoft.AspNet.Security +{ + // Must contain a claim with the specified name, and at least one of the required values + // If AllowedValues is null or empty, that means any claim is valid + public class ClaimsAuthorizationRequirement : IAuthorizationRequirement + { + public string ClaimType { get; set; } + public IEnumerable AllowedValues { get; set; } + } +} diff --git a/src/Microsoft.AspNet.Security/DefaultAuthorizationService.cs b/src/Microsoft.AspNet.Security/DefaultAuthorizationService.cs index 0b05a6d3d..d20cf6544 100644 --- a/src/Microsoft.AspNet.Security/DefaultAuthorizationService.cs +++ b/src/Microsoft.AspNet.Security/DefaultAuthorizationService.cs @@ -1,101 +1,67 @@ // Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -using System; using System.Collections.Generic; using System.Linq; using System.Security.Claims; using System.Threading.Tasks; +using Microsoft.AspNet.Http; +using Microsoft.Framework.OptionsModel; namespace Microsoft.AspNet.Security { public class DefaultAuthorizationService : IAuthorizationService { - private readonly IList _policies; - public int MaxRetries = 99; + private readonly IList _handlers; + private readonly AuthorizationOptions _options; - public DefaultAuthorizationService(IEnumerable policies) + public DefaultAuthorizationService(IOptions options, IEnumerable handlers) { - if (policies == null) - { - _policies = Enumerable.Empty().ToArray(); - } - else - { - _policies = policies.OrderBy(x => x.Order).ToArray(); - } + _handlers = handlers.ToArray(); + _options = options.Options; } - public async Task AuthorizeAsync(IEnumerable claims, ClaimsPrincipal user, object resource) + public Task AuthorizeAsync([NotNull] string policyName, HttpContext context, object resource = null) { - var context = new AuthorizationPolicyContext(claims, user, resource); - - foreach (var policy in _policies) + var policy = _options.GetPolicy(policyName); + if (policy == null) { - await policy.ApplyingAsync(context); + return Task.FromResult(false); } + return AuthorizeAsync(policy, context, resource); + } - // we only apply the policies for a limited number of times to prevent - // infinite loops - - int retries; - for (retries = 0; retries < MaxRetries; retries++) + public async Task AuthorizeAsync([NotNull] AuthorizationPolicy policy, [NotNull] HttpContext context, object resource = null) + { + var user = context.User; + try { - // we don't need to check for owned claims if the permission is already granted - if (!context.Authorized) + // Generate the user identities if policy specified the AuthTypes + if (policy.ActiveAuthenticationTypes != null && policy.ActiveAuthenticationTypes.Any() ) { - if (context.User != null) + var principal = new ClaimsPrincipal(); + + var results = await context.AuthenticateAsync(policy.ActiveAuthenticationTypes); + // REVIEW: re requesting the identities fails for MVC currently, so we only request if not found + foreach (var result in results) { - if (ClaimsMatch(context.Claims, context.UserClaims)) - { - context.Authorized = true; - } + principal.AddIdentity(result.Identity); } + context.User = principal; } - // reset the retry flag - context.Retry = false; - - // give a chance for policies to change claims or the grant - foreach (var policy in _policies) - { - await policy.ApplyAsync(context); - } + var authContext = new AuthorizationContext(policy, context, resource); - // if no policies have changed the context, stop checking - if (!context.Retry) + foreach (var handler in _handlers) { - break; + await handler.HandleAsync(authContext); } + return authContext.HasSucceeded; } - - if (retries == MaxRetries) + finally { - throw new InvalidOperationException("Too many authorization retries."); + context.User = user; } - - foreach (var policy in _policies) - { - await policy.AppliedAsync(context); - } - - return context.Authorized; - } - - public bool Authorize(IEnumerable claims, ClaimsPrincipal user, object resource) - { - return AuthorizeAsync(claims, user, resource).GetAwaiter().GetResult(); - } - - private bool ClaimsMatch([NotNull] IEnumerable x, [NotNull] IEnumerable y) - { - return x.Any(claim => - y.Any(userClaim => - string.Equals(claim.Type, userClaim.Type, StringComparison.OrdinalIgnoreCase) && - string.Equals(claim.Value, userClaim.Value, StringComparison.Ordinal) - ) - ); - } } } \ No newline at end of file diff --git a/src/Microsoft.AspNet.Security/DenyAnonymousAuthorizationHandler.cs b/src/Microsoft.AspNet.Security/DenyAnonymousAuthorizationHandler.cs new file mode 100644 index 000000000..878a32ec9 --- /dev/null +++ b/src/Microsoft.AspNet.Security/DenyAnonymousAuthorizationHandler.cs @@ -0,0 +1,20 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System.Threading.Tasks; + +namespace Microsoft.AspNet.Security +{ + public class DenyAnonymousAuthorizationHandler : AuthorizationHandler + { + public override Task CheckAsync(AuthorizationContext context, DenyAnonymousAuthorizationRequirement requirement) + { + var user = context.User; + var userIsAnonymous = + user == null || + user.Identity == null || + !user.Identity.IsAuthenticated; + return Task.FromResult(!userIsAnonymous); + } + } +} diff --git a/src/Microsoft.AspNet.Security/DenyAnonymousAuthorizationRequirement.cs b/src/Microsoft.AspNet.Security/DenyAnonymousAuthorizationRequirement.cs new file mode 100644 index 000000000..286d5fd69 --- /dev/null +++ b/src/Microsoft.AspNet.Security/DenyAnonymousAuthorizationRequirement.cs @@ -0,0 +1,9 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using Microsoft.AspNet.Security; + +namespace Microsoft.AspNet.Security +{ + public class DenyAnonymousAuthorizationRequirement : IAuthorizationRequirement { } +} diff --git a/src/Microsoft.AspNet.Security/IAuthorizationPolicy.cs b/src/Microsoft.AspNet.Security/IAuthorizationHandler.cs similarity index 50% rename from src/Microsoft.AspNet.Security/IAuthorizationPolicy.cs rename to src/Microsoft.AspNet.Security/IAuthorizationHandler.cs index 0f121d558..975a305b8 100644 --- a/src/Microsoft.AspNet.Security/IAuthorizationPolicy.cs +++ b/src/Microsoft.AspNet.Security/IAuthorizationHandler.cs @@ -5,11 +5,9 @@ namespace Microsoft.AspNet.Security { - public interface IAuthorizationPolicy + public interface IAuthorizationHandler { - int Order { get; set; } - Task ApplyingAsync(AuthorizationPolicyContext context); - Task ApplyAsync(AuthorizationPolicyContext context); - Task AppliedAsync(AuthorizationPolicyContext context); + Task HandleAsync(AuthorizationContext context); + //void Handle(AuthorizationContext context); } } diff --git a/src/Microsoft.AspNet.Security/IAuthorizationRequirement.cs b/src/Microsoft.AspNet.Security/IAuthorizationRequirement.cs new file mode 100644 index 000000000..bd25247df --- /dev/null +++ b/src/Microsoft.AspNet.Security/IAuthorizationRequirement.cs @@ -0,0 +1,9 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +namespace Microsoft.AspNet.Security +{ + public interface IAuthorizationRequirement + { + } +} diff --git a/src/Microsoft.AspNet.Security/IAuthorizationService.cs b/src/Microsoft.AspNet.Security/IAuthorizationService.cs index 9fcef75a2..8bcafda3d 100644 --- a/src/Microsoft.AspNet.Security/IAuthorizationService.cs +++ b/src/Microsoft.AspNet.Security/IAuthorizationService.cs @@ -1,34 +1,32 @@ // Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -using System.Collections.Generic; -using System.Security.Claims; using System.Threading.Tasks; +using Microsoft.AspNet.Http; namespace Microsoft.AspNet.Security { /// - /// Checks claims based permissions for a user. + /// Checks policy based permissions for a user /// public interface IAuthorizationService { /// - /// Checks if a user has specific claims for a specific context obj. + /// Checks if a user meets a specific authorization policy /// - /// The claims to check against a specific user. - /// The user to check claims against. - /// The resource the claims should be check with. - /// true when the user fulfills one of the claims, false otherwise. - Task AuthorizeAsync(IEnumerable claims, ClaimsPrincipal user, object resource); + /// The policy to check against a specific context. + /// The HttpContext to check the policy against. + /// The resource the policy should be checked with. + /// true when the user fulfills the policy, false otherwise. + Task AuthorizeAsync(string policyName, HttpContext context, object resource = null); /// - /// Checks if a user has specific claims for a specific context obj. + /// Checks if a user meets a specific authorization policy /// - /// The claims to check against a specific user. - /// The user to check claims against. - /// The resource the claims should be check with. - /// true when the user fulfills one of the claims, false otherwise. - bool Authorize(IEnumerable claims, ClaimsPrincipal user, object resource); - + /// The policy to check against a specific context. + /// The HttpContext to check the policy against. + /// The resource the policy should be checked with. + /// true when the user fulfills the policy, false otherwise. + Task AuthorizeAsync(AuthorizationPolicy policy, HttpContext context, object resource = null); } } \ No newline at end of file diff --git a/src/Microsoft.AspNet.Security/PassThroughAuthorizationHandler.cs b/src/Microsoft.AspNet.Security/PassThroughAuthorizationHandler.cs new file mode 100644 index 000000000..0dfc6ab28 --- /dev/null +++ b/src/Microsoft.AspNet.Security/PassThroughAuthorizationHandler.cs @@ -0,0 +1,20 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Linq; +using System.Threading.Tasks; + +namespace Microsoft.AspNet.Security +{ + public class PassThroughAuthorizationHandler : IAuthorizationHandler + { + public async Task HandleAsync(AuthorizationContext context) + { + foreach (var handler in context.Policy.Requirements.OfType()) + { + await handler.HandleAsync(context); + } + } + } +} diff --git a/src/Microsoft.AspNet.Security/ServiceCollectionExtensions.cs b/src/Microsoft.AspNet.Security/ServiceCollectionExtensions.cs new file mode 100644 index 000000000..cceec4cc2 --- /dev/null +++ b/src/Microsoft.AspNet.Security/ServiceCollectionExtensions.cs @@ -0,0 +1,32 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using Microsoft.AspNet.Security; +using Microsoft.Framework.ConfigurationModel; + +namespace Microsoft.Framework.DependencyInjection +{ + public static class ServiceCollectionExtensions + { + public static IServiceCollection ConfigureAuthorization([NotNull] this IServiceCollection services, [NotNull] Action configure) + { + return services.Configure(configure); + } + + // Review: Need UseDefaultSubkey parameter? + public static IServiceCollection AddAuthorization([NotNull] this IServiceCollection services, IConfiguration config = null, Action configureOptions = null) + { + var describe = new ServiceDescriber(config); + services.AddOptions(config); + services.TryAdd(describe.Transient()); + services.Add(describe.Transient()); + services.Add(describe.Transient()); + if (configureOptions != null) + { + services.Configure(configureOptions); + } + return services; + } + } +} diff --git a/test/Microsoft.AspNet.Security.Test/DefaultAuthorizationServiceTests.cs b/test/Microsoft.AspNet.Security.Test/DefaultAuthorizationServiceTests.cs index a5a003b80..00f6cde0a 100644 --- a/test/Microsoft.AspNet.Security.Test/DefaultAuthorizationServiceTests.cs +++ b/test/Microsoft.AspNet.Security.Test/DefaultAuthorizationServiceTests.cs @@ -3,307 +3,588 @@ using System; using System.Collections.Generic; -using System.Linq; using System.Security.Claims; using System.Threading.Tasks; -using Microsoft.AspNet.Security; +using Microsoft.AspNet.Http; +using Microsoft.AspNet.Http.Security; +using Microsoft.Framework.DependencyInjection; +using Microsoft.Framework.DependencyInjection.Fallback; +using Microsoft.Framework.OptionsModel; +using Moq; using Xunit; namespace Microsoft.AspNet.Security.Test { public class DefaultAuthorizationServiceTests { + private IAuthorizationService BuildAuthorizationService(Action setupServices = null) + { + var services = new ServiceCollection(); + services.AddAuthorization(); + if (setupServices != null) + { + setupServices(services); + } + return services.BuildServiceProvider().GetRequiredService(); + } + + private Mock SetupContext(params ClaimsIdentity[] ids) + { + var context = new Mock(); + context.SetupProperty(c => c.User); + var user = new ClaimsPrincipal(); + user.AddIdentities(ids); + context.Object.User = user; + if (ids != null) + { + var results = new List(); + foreach (var id in ids) + { + results.Add(new AuthenticationResult(id, new AuthenticationProperties(), new AuthenticationDescription())); + } + context.Setup(c => c.AuthenticateAsync(It.IsAny>())).ReturnsAsync(results).Verifiable(); + } + return context; + } + [Fact] - public void Check_ShouldAllowIfClaimIsPresent() + public async Task Authorize_ShouldAllowIfClaimIsPresent() { // Arrange - var authorizationService = new DefaultAuthorizationService(Enumerable.Empty()); - var user = new ClaimsPrincipal( - new ClaimsIdentity( new Claim[] { new Claim("Permission", "CanViewPage") }, "Basic") - ); + var authorizationService = BuildAuthorizationService(services => + { + services.Configure(options => + { + options.AddPolicy("Basic", new AuthorizationPolicyBuilder() + .RequiresClaim("Permission", "CanViewPage") + .Build()); + }); + }); + var context = SetupContext(new ClaimsIdentity(new Claim[] { new Claim("Permission", "CanViewPage") }, "Basic")); // Act - var allowed = authorizationService.Authorize(new Claim[] { new Claim("Permission", "CanViewPage") }, user); + var allowed = await authorizationService.AuthorizeAsync("Basic", context.Object); // Assert Assert.True(allowed); } [Fact] - public void Check_ShouldAllowIfClaimIsAmongValues() + public async Task Authorize_ShouldAllowIfClaimIsPresentWithSpecifiedAuthType() { // Arrange - var authorizationService = new DefaultAuthorizationService(Enumerable.Empty()); - var user = new ClaimsPrincipal( + var authorizationService = BuildAuthorizationService(services => + { + services.Configure(options => + { + var policy = new AuthorizationPolicyBuilder("Basic").RequiresClaim("Permission", "CanViewPage"); + options.AddPolicy("Basic", policy.Build()); + }); + }); + var context = SetupContext(new ClaimsIdentity(new Claim[] { new Claim("Permission", "CanViewPage") }, "Basic")); + + // Act + var allowed = await authorizationService.AuthorizeAsync("Basic", context.Object); + + // Assert + Assert.True(allowed); + } + + [Fact] + public async Task Authorize_ShouldAllowIfClaimIsAmongValues() + { + // Arrange + var authorizationService = BuildAuthorizationService(services => + { + services.Configure(options => + { + var policy = new AuthorizationPolicyBuilder().RequiresClaim("Permission", "CanViewPage", "CanViewAnything"); + options.AddPolicy("Basic", policy.Build()); + }); + }); + var context = SetupContext( new ClaimsIdentity( - new Claim[] { - new Claim("Permission", "CanViewPage"), + new Claim[] { + new Claim("Permission", "CanViewPage"), new Claim("Permission", "CanViewAnything") - }, + }, "Basic") ); // Act - var allowed = authorizationService.Authorize(new Claim[] { new Claim("Permission", "CanViewPage") }, user); + var allowed = await authorizationService.AuthorizeAsync("Basic", context.Object); // Assert Assert.True(allowed); } [Fact] - public void Check_ShouldNotAllowIfClaimTypeIsNotPresent() + public async Task Authorize_ShouldFailWhenAllRequirementsNotHandled() { // Arrange - var authorizationService = new DefaultAuthorizationService(Enumerable.Empty()); - var user = new ClaimsPrincipal( + var authorizationService = BuildAuthorizationService(services => + { + services.Configure(options => + { + var policy = new AuthorizationPolicyBuilder().RequiresClaim("Permission", "CanViewPage", "CanViewAnything"); + options.AddPolicy("Basic", policy.Build()); + }); + }); + var context = SetupContext( new ClaimsIdentity( - new Claim[] { - new Claim("SomethingElse", "CanViewPage"), + new Claim[] { + new Claim("SomethingElse", "CanViewPage"), }, "Basic") ); // Act - var allowed = authorizationService.Authorize(new Claim[] { new Claim("Permission", "CanViewPage") }, user); + var allowed = await authorizationService.AuthorizeAsync("Basic", context.Object); // Assert Assert.False(allowed); } [Fact] - public void Check_ShouldNotAllowIfClaimValueIsNotPresent() + public async Task Authorize_ShouldNotAllowIfClaimTypeIsNotPresent() { // Arrange - var authorizationService = new DefaultAuthorizationService(Enumerable.Empty()); - var user = new ClaimsPrincipal( + var authorizationService = BuildAuthorizationService(services => + { + services.Configure(options => + { + var policy = new AuthorizationPolicyBuilder().RequiresClaim("Permission", "CanViewPage", "CanViewAnything"); + options.AddPolicy("Basic", policy.Build()); + }); + }); + var context = SetupContext( new ClaimsIdentity( - new Claim[] { - new Claim("Permission", "CanViewComment"), + new Claim[] { + new Claim("SomethingElse", "CanViewPage"), }, "Basic") ); // Act - var allowed = authorizationService.Authorize(new Claim[] { new Claim("Permission", "CanViewPage") }, user); + var allowed = await authorizationService.AuthorizeAsync("Basic", context.Object); // Assert Assert.False(allowed); } [Fact] - public void Check_ShouldNotAllowIfNoClaims() + public async Task Authorize_ShouldNotAllowIfClaimValueIsNotPresent() { // Arrange - var authorizationService = new DefaultAuthorizationService(Enumerable.Empty()); - var user = new ClaimsPrincipal( + var authorizationService = BuildAuthorizationService(services => + { + services.Configure(options => + { + var policy = new AuthorizationPolicyBuilder().RequiresClaim("Permission", "CanViewPage"); + options.AddPolicy("Basic", policy.Build()); + }); + }); + var context = SetupContext( + new ClaimsIdentity( + new Claim[] { + new Claim("Permission", "CanViewComment"), + }, + "Basic") + ); + + // Act + var allowed = await authorizationService.AuthorizeAsync("Basic", context.Object); + + // Assert + Assert.False(allowed); + } + + [Fact] + public async Task Authorize_ShouldNotAllowIfNoClaims() + { + // Arrange + var authorizationService = BuildAuthorizationService(services => + { + services.Configure(options => + { + var policy = new AuthorizationPolicyBuilder().RequiresClaim("Permission", "CanViewPage"); + options.AddPolicy("Basic", policy.Build()); + }); + }); + var context = SetupContext( new ClaimsIdentity( new Claim[0], "Basic") ); // Act - var allowed = authorizationService.Authorize(new Claim[] { new Claim("Permission", "CanViewPage") }, user); + var allowed = await authorizationService.AuthorizeAsync("Basic", context.Object); + + // Assert + Assert.False(allowed); + } + + [Fact] + public async Task Authorize_ShouldNotAllowIfUserIsNull() + { + // Arrange + var authorizationService = BuildAuthorizationService(services => + { + services.Configure(options => + { + var policy = new AuthorizationPolicyBuilder().RequiresClaim("Permission", "CanViewPage"); + options.AddPolicy("Basic", policy.Build()); + }); + }); + var context = SetupContext(); + context.Object.User = null; + + // Act + var allowed = await authorizationService.AuthorizeAsync("Basic", context.Object); // Assert Assert.False(allowed); } [Fact] - public void Check_ShouldNotAllowIfUserIsNull() + public async Task Authorize_ShouldNotAllowIfNotCorrectAuthType() { // Arrange - var authorizationService = new DefaultAuthorizationService(Enumerable.Empty()); - ClaimsPrincipal user = null; + var authorizationService = BuildAuthorizationService(services => + { + services.Configure(options => + { + var policy = new AuthorizationPolicyBuilder("Basic").RequiresClaim("Permission", "CanViewPage"); + options.AddPolicy("Basic", policy.Build()); + }); + }); + var context = SetupContext(new ClaimsIdentity()); // Act - var allowed = authorizationService.Authorize(new Claim[] { new Claim("Permission", "CanViewPage") }, user); + var allowed = await authorizationService.AuthorizeAsync("Basic", context.Object); // Assert Assert.False(allowed); } [Fact] - public void Check_ShouldNotAllowIfUserIsNotAuthenticated() + public async Task Authorize_ShouldAllowWithNoAuthType() + { + // Arrange + var authorizationService = BuildAuthorizationService(services => + { + services.Configure(options => + { + var policy = new AuthorizationPolicyBuilder().RequiresClaim("Permission", "CanViewPage"); + options.AddPolicy("Basic", policy.Build()); + }); + }); + var context = SetupContext( + new ClaimsIdentity( + new Claim[] { + new Claim("Permission", "CanViewPage"), + }, + "Basic") + ); + + // Act + var allowed = await authorizationService.AuthorizeAsync("Basic", context.Object); + + // Assert + Assert.True(allowed); + } + + [Fact] + public async Task Authorize_ShouldNotAllowIfUnknownPolicy() { // Arrange - var authorizationService = new DefaultAuthorizationService(Enumerable.Empty()); - var user = new ClaimsPrincipal( + var authorizationService = BuildAuthorizationService(); + var context = SetupContext( new ClaimsIdentity( - new Claim[] { - new Claim("Permission", "CanViewComment"), + new Claim[] { + new Claim("Permission", "CanViewComment"), }, null) ); // Act - var allowed = authorizationService.Authorize(new Claim[] { new Claim("Permission", "CanViewPage") }, user); + var allowed = await authorizationService.AuthorizeAsync("Basic", context.Object); // Assert Assert.False(allowed); } [Fact] - public void Check_ShouldApplyPoliciesInOrder() + public async Task Authorize_CustomRolePolicy() { // Arrange - string result = ""; - var policies = new IAuthorizationPolicy[] { - new FakePolicy() { - Order = 20, - ApplyingAsyncAction = (context) => { result += "20"; } - }, - new FakePolicy() { - Order = -1, - ApplyingAsyncAction = (context) => { result += "-1"; } - }, - new FakePolicy() { - Order = 30, - ApplyingAsyncAction = (context) => { result += "30"; } - }, - }; - - var authorizationService = new DefaultAuthorizationService(policies); - + var policy = new AuthorizationPolicyBuilder().RequiresRole("Administrator") + .RequiresClaim(ClaimTypes.Role, "User"); + var authorizationService = BuildAuthorizationService(); + var context = SetupContext( + new ClaimsIdentity( + new Claim[] { + new Claim(ClaimTypes.Role, "User"), + new Claim(ClaimTypes.Role, "Administrator") + }, + "Basic") + ); + // Act - var allowed = authorizationService.Authorize(Enumerable.Empty(), null); + var allowed = await authorizationService.AuthorizeAsync(policy.Build(), context.Object); // Assert - Assert.Equal("-12030", result); + Assert.True(allowed); } [Fact] - public void Check_ShouldInvokeApplyingApplyAppliedInOrder() + public async Task Authorize_HasAnyClaimOfTypePolicy() { // Arrange - string result = ""; - var policies = new IAuthorizationPolicy[] { - new FakePolicy() { - Order = 20, - ApplyingAsyncAction = (context) => { result += "Applying20"; }, - ApplyAsyncAction = (context) => { result += "Apply20"; }, - AppliedAsyncAction = (context) => { result += "Applied20"; } - }, - new FakePolicy() { - Order = -1, - ApplyingAsyncAction = (context) => { result += "Applying-1"; }, - ApplyAsyncAction = (context) => { result += "Apply-1"; }, - AppliedAsyncAction = (context) => { result += "Applied-1"; } - }, - new FakePolicy() { - Order = 30, - ApplyingAsyncAction = (context) => { result += "Applying30"; }, - ApplyAsyncAction = (context) => { result += "Apply30"; }, - AppliedAsyncAction = (context) => { result += "Applied30"; } - }, - }; - - var authorizationService = new DefaultAuthorizationService(policies); - + var policy = new AuthorizationPolicyBuilder().RequiresClaim(ClaimTypes.Role); + var authorizationService = BuildAuthorizationService(); + var context = SetupContext( + new ClaimsIdentity( + new Claim[] { + new Claim(ClaimTypes.Role, ""), + }, + "Basic") + ); + // Act - var allowed = authorizationService.Authorize(Enumerable.Empty(), null); + var allowed = await authorizationService.AuthorizeAsync(policy.Build(), context.Object); // Assert - Assert.Equal("Applying-1Applying20Applying30Apply-1Apply20Apply30Applied-1Applied20Applied30", result); + Assert.True(allowed); } [Fact] - public void Check_ShouldConvertNullClaimsToEmptyList() + public async Task Authorize_PolicyCanAuthenticationTypeWithNameClaim() { // Arrange - IList claims = null; - var policies = new IAuthorizationPolicy[] { - new FakePolicy() { - Order = 20, - ApplyingAsyncAction = (context) => { claims = context.Claims; } - } - }; + var policy = new AuthorizationPolicyBuilder("AuthType").RequiresClaim(ClaimTypes.Name); + var authorizationService = BuildAuthorizationService(); + var context = SetupContext( + new ClaimsIdentity(new Claim[] { new Claim(ClaimTypes.Name, "Name") }, "AuthType") + ); - var authorizationService = new DefaultAuthorizationService(policies); - // Act - var allowed = authorizationService.Authorize(Enumerable.Empty(), null); + var allowed = await authorizationService.AuthorizeAsync(policy.Build(), context.Object); // Assert - Assert.NotNull(claims); - Assert.Equal(0, claims.Count); + Assert.True(allowed); } [Fact] - public void Check_ShouldThrowWhenPoliciesDontStop() + public async Task RolePolicyCanRequireSingleRole() { // Arrange - var policies = new IAuthorizationPolicy[] { - new FakePolicy() { - ApplyAsyncAction = (context) => { context.Retry = true; } - } - }; + var policy = new AuthorizationPolicyBuilder("AuthType").RequiresRole("Admin"); + var authorizationService = BuildAuthorizationService(); + var context = SetupContext( + new ClaimsIdentity(new Claim[] { new Claim(ClaimTypes.Role, "Admin") }, "AuthType") + ); - var authorizationService = new DefaultAuthorizationService(policies); + // Act + var allowed = await authorizationService.AuthorizeAsync(policy.Build(), context.Object); + + // Assert + Assert.True(allowed); + } + + [Fact] + public async Task RolePolicyCanRequireOneOfManyRoles() + { + // Arrange + var policy = new AuthorizationPolicyBuilder("AuthType").RequiresRole("Admin", "Users"); + var authorizationService = BuildAuthorizationService(); + var context = SetupContext( + new ClaimsIdentity(new Claim[] { new Claim(ClaimTypes.Role, "Users") }, "AuthType")); // Act + var allowed = await authorizationService.AuthorizeAsync(policy.Build(), context.Object); + // Assert - Exception ex = Assert.Throws(() => authorizationService.Authorize(Enumerable.Empty(), null)); + Assert.True(allowed); } - + [Fact] - public void Check_ApplyCanMutateCheckedClaims() + public async Task RolePolicyCanBlockWrongRole() { + // Arrange + var policy = new AuthorizationPolicyBuilder().RequiresClaim("Permission", "CanViewPage"); + var authorizationService = BuildAuthorizationService(); + var context = SetupContext( + new ClaimsIdentity( + new Claim[] { + new Claim(ClaimTypes.Role, "Nope"), + }, + "AuthType") + ); + + // Act + var allowed = await authorizationService.AuthorizeAsync(policy.Build(), context.Object); + + // Assert + Assert.False(allowed); + } + [Fact] + public async Task RolePolicyCanBlockNoRole() + { // Arrange - var user = new ClaimsPrincipal( - new ClaimsIdentity( new Claim[] { new Claim("Permission", "CanDeleteComments") }, "Basic") + + var authorizationService = BuildAuthorizationService(services => + { + services.Configure(options => + { + var policy = new AuthorizationPolicyBuilder().RequiresRole("Admin", "Users"); + options.AddPolicy("Basic", policy.Build()); + }); + }); + var context = SetupContext( + new ClaimsIdentity( + new Claim[] { + }, + "AuthType") ); - var policies = new IAuthorizationPolicy[] { - new FakePolicy() { - ApplyAsyncAction = (context) => { - // for instance, if user owns the comment - if(!context.Claims.Any(claim => claim.Type == "Permission" && claim.Value == "CanDeleteComments")) - { - context.Claims.Add(new Claim("Permission", "CanDeleteComments")); - context.Retry = true; - } - } - } - }; + // Act + var allowed = await authorizationService.AuthorizeAsync("Basic", context.Object); + + // Assert + Assert.False(allowed); + } + + [Fact] + public async Task PolicyFailsWithNoRequirements() + { + // Arrange + var authorizationService = BuildAuthorizationService(services => + { + services.Configure(options => + { + var policy = new AuthorizationPolicyBuilder(); + options.AddPolicy("Basic", policy.Build()); + }); + }); + var context = SetupContext( + new ClaimsIdentity( + new Claim[] { + new Claim(ClaimTypes.Name, "Name"), + }, + "AuthType") + ); - var authorizationService = new DefaultAuthorizationService(policies); - // Act - var allowed = authorizationService.Authorize(Enumerable.Empty(), user); + var allowed = await authorizationService.AuthorizeAsync("Basic", context.Object); + + // Assert + Assert.False(allowed); + } + + [Fact] + public async Task CanApproveAnyAuthenticatedUser() + { + // Arrange + var authorizationService = BuildAuthorizationService(services => + { + services.Configure(options => + { + var policy = new AuthorizationPolicyBuilder().RequireAuthenticatedUser(); + options.AddPolicy("Any", policy.Build()); + }); + }); + var context = SetupContext( + new ClaimsIdentity( + new Claim[] { + new Claim(ClaimTypes.Name, "Name"), + }, + "AuthType") + ); + + // Act + var allowed = await authorizationService.AuthorizeAsync("Any", context.Object); // Assert Assert.True(allowed); } [Fact] - public void Check_PoliciesCanMutateUsersClaims() + public async Task CanBlockNonAuthenticatedUser() { + // Arrange + var authorizationService = BuildAuthorizationService(services => + { + services.Configure(options => + { + var policy = new AuthorizationPolicyBuilder().RequireAuthenticatedUser(); + options.AddPolicy("Any", policy.Build()); + }); + }); + var context = SetupContext(new ClaimsIdentity()); + + // Act + var allowed = await authorizationService.AuthorizeAsync("Any", context.Object); + + // Assert + Assert.False(allowed); + } + public class CustomRequirement : IAuthorizationRequirement { } + public class CustomHandler : AuthorizationHandler + { + public override Task CheckAsync(AuthorizationContext context, CustomRequirement requirement) + { + return Task.FromResult(true); + } + } + + [Fact] + public async Task CustomReqWithNoHandlerFails() + { // Arrange - var user = new ClaimsPrincipal( - new ClaimsIdentity(new Claim[0], "Basic") - ); + var authorizationService = BuildAuthorizationService(services => + { + services.Configure(options => + { + var policy = new AuthorizationPolicyBuilder(); + policy.Requirements.Add(new CustomRequirement()); + options.AddPolicy("Custom", policy.Build()); + }); + }); + var context = SetupContext(); - var policies = new IAuthorizationPolicy[] { - new FakePolicy() { - ApplyAsyncAction = (context) => { - if (!context.Authorized) - { - context.UserClaims.Add(new Claim("Permission", "CanDeleteComments")); - context.Retry = true; - } - } - } - }; + // Act + var allowed = await authorizationService.AuthorizeAsync("Custom", context.Object); + + // Assert + Assert.False(allowed); + } + + + [Fact] + public async Task CustomReqWithHandlerSucceeds() + { + // Arrange + var authorizationService = BuildAuthorizationService(services => + { + services.AddTransient(); + services.Configure(options => + { + var policy = new AuthorizationPolicyBuilder(); + policy.Requirements.Add(new CustomRequirement()); + options.AddPolicy("Custom", policy.Build()); + }); + }); + var context = SetupContext(); - var authorizationService = new DefaultAuthorizationService(policies); - // Act - var allowed = authorizationService.Authorize(new Claim("Permission", "CanDeleteComments"), user); + var allowed = await authorizationService.AuthorizeAsync("Custom", context.Object); // Assert Assert.True(allowed); } + } -} +} \ No newline at end of file diff --git a/test/Microsoft.AspNet.Security.Test/FakePolicy.cs b/test/Microsoft.AspNet.Security.Test/FakePolicy.cs deleted file mode 100644 index be9139b89..000000000 --- a/test/Microsoft.AspNet.Security.Test/FakePolicy.cs +++ /dev/null @@ -1,52 +0,0 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System; -using System.Threading.Tasks; -using Microsoft.AspNet.Security; - -namespace Microsoft.AspNet.Security.Test -{ - public class FakePolicy : IAuthorizationPolicy - { - - public int Order { get; set; } - - public Task ApplyingAsync(AuthorizationPolicyContext context) - { - if (ApplyingAsyncAction != null) - { - ApplyingAsyncAction(context); - } - - return Task.FromResult(0); - } - - public Task ApplyAsync(AuthorizationPolicyContext context) - { - if (ApplyAsyncAction != null) - { - ApplyAsyncAction(context); - } - - return Task.FromResult(0); - - } - - public Task AppliedAsync(AuthorizationPolicyContext context) - { - if (AppliedAsyncAction != null) - { - AppliedAsyncAction(context); - } - - return Task.FromResult(0); - } - - public Action ApplyingAsyncAction { get; set;} - - public Action ApplyAsyncAction { get; set;} - - public Action AppliedAsyncAction { get; set;} - } -} diff --git a/test/Microsoft.AspNet.Security.Test/TestApplicationEnvironment.cs b/test/Microsoft.AspNet.Security.Test/TestApplicationEnvironment.cs deleted file mode 100644 index 01ef364c1..000000000 --- a/test/Microsoft.AspNet.Security.Test/TestApplicationEnvironment.cs +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System; -using System.Runtime.Versioning; -using Microsoft.Framework.Runtime; - -namespace Microsoft.AspNet.Security -{ - public class TestApplicationEnvironment : IApplicationEnvironment - { - public string ApplicationBasePath - { - get { return Environment.CurrentDirectory; } - } - - public string ApplicationName - { - get { return "Test App environment"; } - } - - public string Configuration - { - get { return "Test"; } - } - - public FrameworkName RuntimeFramework - { - get { return new FrameworkName(".NETFramework", new Version(4, 5)); } - } - - public string Version - { - get { return "1.0.0"; } - } - } -} \ No newline at end of file From de56109c160dd0b870ecce582ee36d98f5516a29 Mon Sep 17 00:00:00 2001 From: tushar gupta Date: Thu, 15 Jan 2015 17:21:00 -0800 Subject: [PATCH 111/216] Fixing Issue #120 --- .../OAuthBearerAuthenticationHandler.cs | 7 +++++++ .../OAuthBearer/OAuthBearerMiddlewareTests.cs | 18 +++++++++++++++++- 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/src/Microsoft.AspNet.Security.OAuthBearer/OAuthBearerAuthenticationHandler.cs b/src/Microsoft.AspNet.Security.OAuthBearer/OAuthBearerAuthenticationHandler.cs index b81af0c73..c1f03a074 100644 --- a/src/Microsoft.AspNet.Security.OAuthBearer/OAuthBearerAuthenticationHandler.cs +++ b/src/Microsoft.AspNet.Security.OAuthBearer/OAuthBearerAuthenticationHandler.cs @@ -60,6 +60,13 @@ protected override async Task AuthenticateCoreAsync() } string authorization = Request.Headers.Get("Authorization"); + + // If no authorization header found, nothing to process further + if (String.IsNullOrEmpty(authorization)) + { + return null; + } + if (authorization.StartsWith("Bearer ", StringComparison.OrdinalIgnoreCase)) { token = authorization.Substring("Bearer ".Length).Trim(); diff --git a/test/Microsoft.AspNet.Security.Test/OAuthBearer/OAuthBearerMiddlewareTests.cs b/test/Microsoft.AspNet.Security.Test/OAuthBearer/OAuthBearerMiddlewareTests.cs index eff8e2884..2139f5630 100644 --- a/test/Microsoft.AspNet.Security.Test/OAuthBearer/OAuthBearerMiddlewareTests.cs +++ b/test/Microsoft.AspNet.Security.Test/OAuthBearer/OAuthBearerMiddlewareTests.cs @@ -66,6 +66,22 @@ private static Task HeaderReceived(MessageReceivedNotification(null); } + [Fact] + public async Task NoHeaderReceived() + { + var server = CreateServer(options => { }); + var response = await SendAsync(server, "http://example.com/oauth"); + response.Response.StatusCode.ShouldBe(HttpStatusCode.OK); + } + + [Fact] + public async Task HeaderWithoutBearerReceived() + { + var server = CreateServer(options => { }); + var response = await SendAsync(server, "http://example.com/oauth","Token"); + response.Response.StatusCode.ShouldBe(HttpStatusCode.OK); + } + [Fact] public async Task CustomTokenReceived() { @@ -235,4 +251,4 @@ private class Transaction public XElement ResponseElement { get; set; } } } -} \ No newline at end of file +} From cdbd003bb1753b524ca52f9da8cd5848b9e6863d Mon Sep 17 00:00:00 2001 From: tushar gupta Date: Fri, 16 Jan 2015 11:49:57 -0800 Subject: [PATCH 112/216] Adding token property to MessageReceivedNotification --- .../OAuthBearerAuthenticationHandler.cs | 32 +++++++++++-------- .../MessageReceivedNotification.cs | 5 +++ .../OAuthBearer/OAuthBearerMiddlewareTests.cs | 17 ++++++++++ 3 files changed, 41 insertions(+), 13 deletions(-) diff --git a/src/Microsoft.AspNet.Security.OAuthBearer/OAuthBearerAuthenticationHandler.cs b/src/Microsoft.AspNet.Security.OAuthBearer/OAuthBearerAuthenticationHandler.cs index c1f03a074..a4555790d 100644 --- a/src/Microsoft.AspNet.Security.OAuthBearer/OAuthBearerAuthenticationHandler.cs +++ b/src/Microsoft.AspNet.Security.OAuthBearer/OAuthBearerAuthenticationHandler.cs @@ -59,23 +59,29 @@ protected override async Task AuthenticateCoreAsync() return null; } - string authorization = Request.Headers.Get("Authorization"); + // If application retrieved token from somewhere else, use that. + token = messageReceivedNotification.Token; - // If no authorization header found, nothing to process further - if (String.IsNullOrEmpty(authorization)) + if (string.IsNullOrEmpty(token)) { - return null; - } + string authorization = Request.Headers.Get("Authorization"); - if (authorization.StartsWith("Bearer ", StringComparison.OrdinalIgnoreCase)) - { - token = authorization.Substring("Bearer ".Length).Trim(); - } + // If no authorization header found, nothing to process further + if (string.IsNullOrEmpty(authorization)) + { + return null; + } - // If no token found, no further work possible - if (string.IsNullOrEmpty(token)) - { - return null; + if (authorization.StartsWith("Bearer ", StringComparison.OrdinalIgnoreCase)) + { + token = authorization.Substring("Bearer ".Length).Trim(); + } + + // If no token found, no further work possible + if (string.IsNullOrEmpty(token)) + { + return null; + } } // notify user token was received diff --git a/src/Microsoft.AspNet.Security/Notifications/MessageReceivedNotification.cs b/src/Microsoft.AspNet.Security/Notifications/MessageReceivedNotification.cs index 1b1f59988..f583746c3 100644 --- a/src/Microsoft.AspNet.Security/Notifications/MessageReceivedNotification.cs +++ b/src/Microsoft.AspNet.Security/Notifications/MessageReceivedNotification.cs @@ -12,5 +12,10 @@ public MessageReceivedNotification(HttpContext context, TOptions options) : base } public TMessage ProtocolMessage { get; set; } + + /// + /// Bearer Token. This will give application an opportunity to retrieve token from an alternation location. + /// + public string Token { get; set; } } } \ No newline at end of file diff --git a/test/Microsoft.AspNet.Security.Test/OAuthBearer/OAuthBearerMiddlewareTests.cs b/test/Microsoft.AspNet.Security.Test/OAuthBearer/OAuthBearerMiddlewareTests.cs index 2139f5630..26f202e08 100644 --- a/test/Microsoft.AspNet.Security.Test/OAuthBearer/OAuthBearerMiddlewareTests.cs +++ b/test/Microsoft.AspNet.Security.Test/OAuthBearer/OAuthBearerMiddlewareTests.cs @@ -137,6 +137,23 @@ private static Task SecurityTokenValidated(SecurityTokenValidatedNotification(null); } + [Fact] + public async Task RetrievingTokenFromAlternateLocation() + { + var server = CreateServer(options => { + options.Notifications.MessageReceived = MessageReceived; + options.Notifications.SecurityTokenReceived = SecurityTokenReceived; + }); + var response = await SendAsync(server, "http://example.com/oauth", "Bearer Token"); + response.Response.StatusCode.ShouldBe(HttpStatusCode.OK); + } + + private static Task MessageReceived(MessageReceivedNotification notification) + { + notification.Token = "CustomToken"; + return Task.FromResult(null); + } + class BlobTokenValidator : ISecurityTokenValidator { From c53394e847f3959c1002a20ce581ac4f978e8c5b Mon Sep 17 00:00:00 2001 From: tushar gupta Date: Fri, 16 Jan 2015 14:35:11 -0800 Subject: [PATCH 113/216] Cleaning up comments and some TODOs. --- .../OpenIdConnectAuthenticationOptions.cs | 6 +++--- .../OpenidConnectAuthenticationHandler.cs | 11 +++++------ src/Microsoft.AspNet.Security/AuthenticationTicket.cs | 6 +++--- .../Notifications/BaseNotification.cs | 4 +++- .../Notifications/NotificationResultState.cs | 6 +++++- 5 files changed, 19 insertions(+), 14 deletions(-) diff --git a/src/Microsoft.AspNet.Security.OpenIdConnect/OpenIdConnectAuthenticationOptions.cs b/src/Microsoft.AspNet.Security.OpenIdConnect/OpenIdConnectAuthenticationOptions.cs index 5f1b5077e..a5f1bcd30 100644 --- a/src/Microsoft.AspNet.Security.OpenIdConnect/OpenIdConnectAuthenticationOptions.cs +++ b/src/Microsoft.AspNet.Security.OpenIdConnect/OpenIdConnectAuthenticationOptions.cs @@ -148,7 +148,7 @@ public string Caption /// recommends adding a nonce to a request as a mitigation against replay attacks when requesting id_tokens. /// By default the runtime uses cookies with unique names generated from a hash of the nonce. /// - public INonceCache NoneCache { get; set; } + public INonceCache NonceCache { get; set; } /// /// Gets or sets the discovery endpoint for obtaining metadata @@ -181,7 +181,7 @@ public string Caption public OpenIdConnectAuthenticationNotifications Notifications { get; set; } /// - /// Gets or sets the that is used ensure the 'id_token' received + /// Gets or sets the that is used to ensure that the 'id_token' received /// is valid per: http://openid.net/specs/openid-connect-core-1_0.html#IDTokenValidation /// /// if 'value' is null. @@ -262,7 +262,7 @@ public ISecureDataFormat StateDataFormat /// /// Gets or sets the type used to secure strings used by the middleware. - // + /// public ISecureDataFormat StringDataFormat { get diff --git a/src/Microsoft.AspNet.Security.OpenIdConnect/OpenidConnectAuthenticationHandler.cs b/src/Microsoft.AspNet.Security.OpenIdConnect/OpenidConnectAuthenticationHandler.cs index 317cd42e8..96156f653 100644 --- a/src/Microsoft.AspNet.Security.OpenIdConnect/OpenidConnectAuthenticationHandler.cs +++ b/src/Microsoft.AspNet.Security.OpenIdConnect/OpenidConnectAuthenticationHandler.cs @@ -77,7 +77,7 @@ protected override async Task ApplyResponseGrantAsync() // Set End_Session_Endpoint in order: // 1. properties.Redirect // 2. Options.Wreply - AuthenticationProperties properties = new AuthenticationProperties(); // TODO signout.Properties; + AuthenticationProperties properties = new AuthenticationProperties(); if (properties != null && !string.IsNullOrEmpty(properties.RedirectUri)) { openIdConnectMessage.PostLogoutRedirectUri = properties.RedirectUri; @@ -111,7 +111,7 @@ protected override void ApplyResponseChallenge() } /// - /// Responds to a 401 Challenge sends an OpenIdConnect message to the 'identity authority' to obtain an identity. + /// Responds to a 401 Challenge. Sends an OpenIdConnect message to the 'identity authority' to obtain an identity. /// /// protected override async Task ApplyResponseChallengeAsync() @@ -158,9 +158,9 @@ protected override async Task ApplyResponseChallengeAsync() if (Options.ProtocolValidator.RequireNonce) { openIdConnectMessage.Nonce = Options.ProtocolValidator.GenerateNonce(); - if (Options.NoneCache != null) + if (Options.NonceCache != null) { - Options.NoneCache.AddNonce(openIdConnectMessage.Nonce); + Options.NonceCache.AddNonce(openIdConnectMessage.Nonce); } else { @@ -215,7 +215,6 @@ protected override async Task AuthenticateCoreAsync() IFormCollection form = await Request.ReadFormAsync(); Request.Body.Seek(0, SeekOrigin.Begin); - // TODO: a delegate on OpenIdConnectAuthenticationOptions would allow for users to hook their own custom message. openIdConnectMessage = new OpenIdConnectMessage(form); } @@ -466,7 +465,7 @@ private void RememberNonce(string nonce) /// /// the nonce that was found in the jwt token. /// 'nonceExpectedValue' if a cookie is found that matches, null otherwise. - /// Examins that start with the prefix: 'OpenIdConnectAuthenticationDefaults.Nonce'. + /// Examine that start with the prefix: 'OpenIdConnectAuthenticationDefaults.Nonce'. /// is used to obtain the actual 'nonce'. If the nonce is found, then is called. private string RetrieveNonce(string nonceExpectedValue) { diff --git a/src/Microsoft.AspNet.Security/AuthenticationTicket.cs b/src/Microsoft.AspNet.Security/AuthenticationTicket.cs index 7b7e50998..82128f10c 100644 --- a/src/Microsoft.AspNet.Security/AuthenticationTicket.cs +++ b/src/Microsoft.AspNet.Security/AuthenticationTicket.cs @@ -26,7 +26,7 @@ public AuthenticationTicket(ClaimsIdentity identity, AuthenticationProperties pr /// Initializes a new instance of the class /// /// the that represents the authenticated user. - /// additional properties that can be consumed by the user or runtims. + /// additional properties that can be consumed by the user or runtime. /// the authentication middleware that was responsible for this ticket. public AuthenticationTicket(ClaimsPrincipal principal, AuthenticationProperties properties, string authenticationType) { @@ -36,7 +36,7 @@ public AuthenticationTicket(ClaimsPrincipal principal, AuthenticationProperties } /// - /// Gets the authenticated user identity. + /// Gets the authentication type. /// public string AuthenticationType { get; private set; } @@ -46,7 +46,7 @@ public AuthenticationTicket(ClaimsPrincipal principal, AuthenticationProperties public ClaimsIdentity Identity { get; private set; } /// - /// Gets the authenticated user identity. + /// Gets the claims-principal with authenticated user identities. /// public ClaimsPrincipal Principal{ get; private set; } diff --git a/src/Microsoft.AspNet.Security/Notifications/BaseNotification.cs b/src/Microsoft.AspNet.Security/Notifications/BaseNotification.cs index 1ef13e2dc..d1ea6fef7 100644 --- a/src/Microsoft.AspNet.Security/Notifications/BaseNotification.cs +++ b/src/Microsoft.AspNet.Security/Notifications/BaseNotification.cs @@ -1,4 +1,6 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + using Microsoft.AspNet.Http; diff --git a/src/Microsoft.AspNet.Security/Notifications/NotificationResultState.cs b/src/Microsoft.AspNet.Security/Notifications/NotificationResultState.cs index 1f48e25b3..78d6c85ca 100644 --- a/src/Microsoft.AspNet.Security/Notifications/NotificationResultState.cs +++ b/src/Microsoft.AspNet.Security/Notifications/NotificationResultState.cs @@ -1,4 +1,8 @@ -using System; +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + + +using System; namespace Microsoft.AspNet.Security.Notifications { From 123065c0ae9e069714c08b8511aa7ea9a6ccbde5 Mon Sep 17 00:00:00 2001 From: Hao Kung Date: Sat, 17 Jan 2015 17:11:34 -0800 Subject: [PATCH 114/216] Add some sugar for AuthZ - Register passthrough handler by default - AddPolicy overload that takesAction - Chaining policy overloads/methods - More fluent apis for PolicyBuilder Fixes #122, #114 --- .../AuthorizationOptions.cs | 8 + .../AuthorizationPolicyBuilder.cs | 37 +++- .../PassThroughAuthorizationHandler.cs | 1 - .../ServiceCollectionExtensions.cs | 1 + .../DefaultAuthorizationServiceTests.cs | 201 +++++++++++++----- 5 files changed, 189 insertions(+), 59 deletions(-) diff --git a/src/Microsoft.AspNet.Security/AuthorizationOptions.cs b/src/Microsoft.AspNet.Security/AuthorizationOptions.cs index 667ee4fcb..8a53e574d 100644 --- a/src/Microsoft.AspNet.Security/AuthorizationOptions.cs +++ b/src/Microsoft.AspNet.Security/AuthorizationOptions.cs @@ -1,6 +1,7 @@ // Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. +using System; using System.Collections.Generic; namespace Microsoft.AspNet.Security @@ -15,6 +16,13 @@ public void AddPolicy([NotNull] string name, [NotNull] AuthorizationPolicy polic PolicyMap[name] = policy; } + public void AddPolicy([NotNull] string name, [NotNull] Action configurePolicy) + { + var policyBuilder = new AuthorizationPolicyBuilder(); + configurePolicy(policyBuilder); + PolicyMap[name] = policyBuilder.Build(); + } + public AuthorizationPolicy GetPolicy([NotNull] string name) { return PolicyMap.ContainsKey(name) ? PolicyMap[name] : null; diff --git a/src/Microsoft.AspNet.Security/AuthorizationPolicyBuilder.cs b/src/Microsoft.AspNet.Security/AuthorizationPolicyBuilder.cs index 520bc7746..7b8617f54 100644 --- a/src/Microsoft.AspNet.Security/AuthorizationPolicyBuilder.cs +++ b/src/Microsoft.AspNet.Security/AuthorizationPolicyBuilder.cs @@ -2,6 +2,7 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System.Collections.Generic; +using System.Linq; using System.Security.Claims; namespace Microsoft.AspNet.Security @@ -10,14 +11,42 @@ public class AuthorizationPolicyBuilder { public AuthorizationPolicyBuilder(params string[] activeAuthenticationTypes) { - foreach (var authType in activeAuthenticationTypes) { - ActiveAuthenticationTypes.Add(authType); - } + AddAuthenticationTypes(activeAuthenticationTypes); + } + + public AuthorizationPolicyBuilder(AuthorizationPolicy policy) + { + Combine(policy); } public IList Requirements { get; set; } = new List(); public IList ActiveAuthenticationTypes { get; set; } = new List(); + public AuthorizationPolicyBuilder AddAuthenticationTypes(params string[] activeAuthTypes) + { + foreach (var authType in activeAuthTypes) + { + ActiveAuthenticationTypes.Add(authType); + } + return this; + } + + public AuthorizationPolicyBuilder AddRequirements(params IAuthorizationRequirement[] requirements) + { + foreach (var req in requirements) + { + Requirements.Add(req); + } + return this; + } + + public AuthorizationPolicyBuilder Combine(AuthorizationPolicy policy) + { + AddAuthenticationTypes(policy.ActiveAuthenticationTypes.ToArray()); + AddRequirements(policy.Requirements.ToArray()); + return this; + } + public AuthorizationPolicyBuilder RequiresClaim([NotNull] string claimType, params string[] requiredValues) { Requirements.Add(new ClaimsAuthorizationRequirement @@ -55,4 +84,4 @@ public AuthorizationPolicy Build() return new AuthorizationPolicy(Requirements, ActiveAuthenticationTypes); } } -} +} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Security/PassThroughAuthorizationHandler.cs b/src/Microsoft.AspNet.Security/PassThroughAuthorizationHandler.cs index 0dfc6ab28..837b2f267 100644 --- a/src/Microsoft.AspNet.Security/PassThroughAuthorizationHandler.cs +++ b/src/Microsoft.AspNet.Security/PassThroughAuthorizationHandler.cs @@ -1,7 +1,6 @@ // Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -using System; using System.Linq; using System.Threading.Tasks; diff --git a/src/Microsoft.AspNet.Security/ServiceCollectionExtensions.cs b/src/Microsoft.AspNet.Security/ServiceCollectionExtensions.cs index cceec4cc2..41b0978cd 100644 --- a/src/Microsoft.AspNet.Security/ServiceCollectionExtensions.cs +++ b/src/Microsoft.AspNet.Security/ServiceCollectionExtensions.cs @@ -22,6 +22,7 @@ public static IServiceCollection AddAuthorization([NotNull] this IServiceCollect services.TryAdd(describe.Transient()); services.Add(describe.Transient()); services.Add(describe.Transient()); + services.Add(describe.Transient()); if (configureOptions != null) { services.Configure(configureOptions); diff --git a/test/Microsoft.AspNet.Security.Test/DefaultAuthorizationServiceTests.cs b/test/Microsoft.AspNet.Security.Test/DefaultAuthorizationServiceTests.cs index 00f6cde0a..1ba705439 100644 --- a/test/Microsoft.AspNet.Security.Test/DefaultAuthorizationServiceTests.cs +++ b/test/Microsoft.AspNet.Security.Test/DefaultAuthorizationServiceTests.cs @@ -9,7 +9,6 @@ using Microsoft.AspNet.Http.Security; using Microsoft.Framework.DependencyInjection; using Microsoft.Framework.DependencyInjection.Fallback; -using Microsoft.Framework.OptionsModel; using Moq; using Xunit; @@ -53,11 +52,9 @@ public async Task Authorize_ShouldAllowIfClaimIsPresent() // Arrange var authorizationService = BuildAuthorizationService(services => { - services.Configure(options => + services.ConfigureAuthorization(options => { - options.AddPolicy("Basic", new AuthorizationPolicyBuilder() - .RequiresClaim("Permission", "CanViewPage") - .Build()); + options.AddPolicy("Basic", policy => policy.RequiresClaim("Permission", "CanViewPage")); }); }); var context = SetupContext(new ClaimsIdentity(new Claim[] { new Claim("Permission", "CanViewPage") }, "Basic")); @@ -75,10 +72,9 @@ public async Task Authorize_ShouldAllowIfClaimIsPresentWithSpecifiedAuthType() // Arrange var authorizationService = BuildAuthorizationService(services => { - services.Configure(options => + services.ConfigureAuthorization(options => { - var policy = new AuthorizationPolicyBuilder("Basic").RequiresClaim("Permission", "CanViewPage"); - options.AddPolicy("Basic", policy.Build()); + options.AddPolicy("Basic", policy => policy.RequiresClaim("Permission", "CanViewPage")); }); }); var context = SetupContext(new ClaimsIdentity(new Claim[] { new Claim("Permission", "CanViewPage") }, "Basic")); @@ -96,10 +92,9 @@ public async Task Authorize_ShouldAllowIfClaimIsAmongValues() // Arrange var authorizationService = BuildAuthorizationService(services => { - services.Configure(options => + services.ConfigureAuthorization(options => { - var policy = new AuthorizationPolicyBuilder().RequiresClaim("Permission", "CanViewPage", "CanViewAnything"); - options.AddPolicy("Basic", policy.Build()); + options.AddPolicy("Basic", policy => policy.RequiresClaim("Permission", "CanViewPage", "CanViewAnything")); }); }); var context = SetupContext( @@ -124,10 +119,9 @@ public async Task Authorize_ShouldFailWhenAllRequirementsNotHandled() // Arrange var authorizationService = BuildAuthorizationService(services => { - services.Configure(options => + services.ConfigureAuthorization(options => { - var policy = new AuthorizationPolicyBuilder().RequiresClaim("Permission", "CanViewPage", "CanViewAnything"); - options.AddPolicy("Basic", policy.Build()); + options.AddPolicy("Basic", policy => policy.RequiresClaim("Permission", "CanViewPage", "CanViewAnything")); }); }); var context = SetupContext( @@ -151,10 +145,9 @@ public async Task Authorize_ShouldNotAllowIfClaimTypeIsNotPresent() // Arrange var authorizationService = BuildAuthorizationService(services => { - services.Configure(options => + services.ConfigureAuthorization(options => { - var policy = new AuthorizationPolicyBuilder().RequiresClaim("Permission", "CanViewPage", "CanViewAnything"); - options.AddPolicy("Basic", policy.Build()); + options.AddPolicy("Basic", policy => policy.RequiresClaim("Permission", "CanViewPage", "CanViewAnything")); }); }); var context = SetupContext( @@ -178,10 +171,9 @@ public async Task Authorize_ShouldNotAllowIfClaimValueIsNotPresent() // Arrange var authorizationService = BuildAuthorizationService(services => { - services.Configure(options => + services.ConfigureAuthorization(options => { - var policy = new AuthorizationPolicyBuilder().RequiresClaim("Permission", "CanViewPage"); - options.AddPolicy("Basic", policy.Build()); + options.AddPolicy("Basic", policy => policy.RequiresClaim("Permission", "CanViewPage")); }); }); var context = SetupContext( @@ -205,10 +197,9 @@ public async Task Authorize_ShouldNotAllowIfNoClaims() // Arrange var authorizationService = BuildAuthorizationService(services => { - services.Configure(options => + services.ConfigureAuthorization(options => { - var policy = new AuthorizationPolicyBuilder().RequiresClaim("Permission", "CanViewPage"); - options.AddPolicy("Basic", policy.Build()); + options.AddPolicy("Basic", policy => policy.RequiresClaim("Permission", "CanViewPage")); }); }); var context = SetupContext( @@ -230,10 +221,9 @@ public async Task Authorize_ShouldNotAllowIfUserIsNull() // Arrange var authorizationService = BuildAuthorizationService(services => { - services.Configure(options => + services.ConfigureAuthorization(options => { - var policy = new AuthorizationPolicyBuilder().RequiresClaim("Permission", "CanViewPage"); - options.AddPolicy("Basic", policy.Build()); + options.AddPolicy("Basic", policy => policy.RequiresClaim("Permission", "CanViewPage")); }); }); var context = SetupContext(); @@ -252,10 +242,9 @@ public async Task Authorize_ShouldNotAllowIfNotCorrectAuthType() // Arrange var authorizationService = BuildAuthorizationService(services => { - services.Configure(options => + services.ConfigureAuthorization(options => { - var policy = new AuthorizationPolicyBuilder("Basic").RequiresClaim("Permission", "CanViewPage"); - options.AddPolicy("Basic", policy.Build()); + options.AddPolicy("Basic", policy => policy.RequiresClaim("Permission", "CanViewPage")); }); }); var context = SetupContext(new ClaimsIdentity()); @@ -273,10 +262,9 @@ public async Task Authorize_ShouldAllowWithNoAuthType() // Arrange var authorizationService = BuildAuthorizationService(services => { - services.Configure(options => + services.ConfigureAuthorization(options => { - var policy = new AuthorizationPolicyBuilder().RequiresClaim("Permission", "CanViewPage"); - options.AddPolicy("Basic", policy.Build()); + options.AddPolicy("Basic", policy => policy.RequiresClaim("Permission", "CanViewPage")); }); }); var context = SetupContext( @@ -433,13 +421,11 @@ public async Task RolePolicyCanBlockWrongRole() public async Task RolePolicyCanBlockNoRole() { // Arrange - var authorizationService = BuildAuthorizationService(services => { - services.Configure(options => + services.ConfigureAuthorization(options => { - var policy = new AuthorizationPolicyBuilder().RequiresRole("Admin", "Users"); - options.AddPolicy("Basic", policy.Build()); + options.AddPolicy("Basic", policy => policy.RequiresRole("Admin", "Users")); }); }); var context = SetupContext( @@ -462,10 +448,9 @@ public async Task PolicyFailsWithNoRequirements() // Arrange var authorizationService = BuildAuthorizationService(services => { - services.Configure(options => + services.ConfigureAuthorization(options => { - var policy = new AuthorizationPolicyBuilder(); - options.AddPolicy("Basic", policy.Build()); + options.AddPolicy("Basic", policy => { }); }); }); var context = SetupContext( @@ -489,10 +474,9 @@ public async Task CanApproveAnyAuthenticatedUser() // Arrange var authorizationService = BuildAuthorizationService(services => { - services.Configure(options => + services.ConfigureAuthorization(options => { - var policy = new AuthorizationPolicyBuilder().RequireAuthenticatedUser(); - options.AddPolicy("Any", policy.Build()); + options.AddPolicy("Any", policy => policy.RequireAuthenticatedUser()); }); }); var context = SetupContext( @@ -516,10 +500,9 @@ public async Task CanBlockNonAuthenticatedUser() // Arrange var authorizationService = BuildAuthorizationService(services => { - services.Configure(options => + services.ConfigureAuthorization(options => { - var policy = new AuthorizationPolicyBuilder().RequireAuthenticatedUser(); - options.AddPolicy("Any", policy.Build()); + options.AddPolicy("Any", policy => policy.RequireAuthenticatedUser()); }); }); var context = SetupContext(new ClaimsIdentity()); @@ -546,11 +529,9 @@ public async Task CustomReqWithNoHandlerFails() // Arrange var authorizationService = BuildAuthorizationService(services => { - services.Configure(options => + services.ConfigureAuthorization(options => { - var policy = new AuthorizationPolicyBuilder(); - policy.Requirements.Add(new CustomRequirement()); - options.AddPolicy("Custom", policy.Build()); + options.AddPolicy("Custom", policy => policy.Requirements.Add(new CustomRequirement())); }); }); var context = SetupContext(); @@ -562,7 +543,6 @@ public async Task CustomReqWithNoHandlerFails() Assert.False(allowed); } - [Fact] public async Task CustomReqWithHandlerSucceeds() { @@ -570,11 +550,9 @@ public async Task CustomReqWithHandlerSucceeds() var authorizationService = BuildAuthorizationService(services => { services.AddTransient(); - services.Configure(options => + services.ConfigureAuthorization(options => { - var policy = new AuthorizationPolicyBuilder(); - policy.Requirements.Add(new CustomRequirement()); - options.AddPolicy("Custom", policy.Build()); + options.AddPolicy("Custom", policy => policy.Requirements.Add(new CustomRequirement())); }); }); var context = SetupContext(); @@ -586,5 +564,120 @@ public async Task CustomReqWithHandlerSucceeds() Assert.True(allowed); } + public class PassThroughRequirement : AuthorizationHandler, IAuthorizationRequirement + { + public PassThroughRequirement(bool succeed) + { + Succeed = succeed; + } + + public bool Succeed { get; set; } + + public override Task CheckAsync(AuthorizationContext context, PassThroughRequirement requirement) + { + return Task.FromResult(Succeed); + } + } + + [Theory] + [InlineData(true)] + [InlineData(false)] + public async Task PassThroughRequirementWillSucceedWithoutCustomHandler(bool shouldSucceed) + { + // Arrange + var authorizationService = BuildAuthorizationService(services => + { + services.ConfigureAuthorization(options => + { + options.AddPolicy("Passthrough", policy => policy.Requirements.Add(new PassThroughRequirement(shouldSucceed))); + }); + }); + var context = SetupContext(); + + // Act + var allowed = await authorizationService.AuthorizeAsync("Passthrough", context.Object); + + // Assert + Assert.Equal(shouldSucceed, allowed); + } + + public async Task CanCombinePolicies() + { + // Arrange + var authorizationService = BuildAuthorizationService(services => + { + services.ConfigureAuthorization(options => + { + var basePolicy = new AuthorizationPolicyBuilder().RequiresClaim("Base", "Value").Build(); + options.AddPolicy("Combineed", policy => policy.Combine(basePolicy).RequiresClaim("Claim", "Exists")); + }); + }); + var context = SetupContext( + new ClaimsIdentity( + new Claim[] { + new Claim("Base", "Value"), + new Claim("Claim", "Exists") + }, + "AuthType") + ); + + // Act + var allowed = await authorizationService.AuthorizeAsync("Combined", context.Object); + + // Assert + Assert.True(allowed); + } + + public async Task CombinePoliciesWillFailIfBasePolicyFails() + { + // Arrange + var authorizationService = BuildAuthorizationService(services => + { + services.ConfigureAuthorization(options => + { + var basePolicy = new AuthorizationPolicyBuilder().RequiresClaim("Base", "Value").Build(); + options.AddPolicy("Combined", policy => policy.Combine(basePolicy).RequiresClaim("Claim", "Exists")); + }); + }); + var context = SetupContext( + new ClaimsIdentity( + new Claim[] { + new Claim("Claim", "Exists") + }, + "AuthType") + ); + + // Act + var allowed = await authorizationService.AuthorizeAsync("Combined", context.Object); + + // Assert + Assert.False(allowed); + } + + public async Task CombinedPoliciesWillFailIfExtraRequirementFails() + { + // Arrange + var authorizationService = BuildAuthorizationService(services => + { + services.ConfigureAuthorization(options => + { + var basePolicy = new AuthorizationPolicyBuilder().RequiresClaim("Base", "Value").Build(); + options.AddPolicy("Combined", policy => policy.Combine(basePolicy).RequiresClaim("Claim", "Exists")); + }); + }); + var context = SetupContext( + new ClaimsIdentity( + new Claim[] { + new Claim("Base", "Value"), + }, + "AuthType") + ); + + // Act + var allowed = await authorizationService.AuthorizeAsync("Combined", context.Object); + + // Assert + Assert.False(allowed); + } } } \ No newline at end of file From ac03ad3edfdb08341aa4b176744ab0244b59677a Mon Sep 17 00:00:00 2001 From: Stephen Halter Date: Sun, 18 Jan 2015 20:55:49 -0800 Subject: [PATCH 115/216] Handle HttpFeature rename --- .../Notifications/CookieValidateIdentityContext.cs | 2 +- .../Infrastructure/AuthenticationHandler.cs | 2 +- .../Infrastructure/HttpContextExtensions.cs | 2 +- src/Microsoft.AspNet.Security/project.json | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Microsoft.AspNet.Security.Cookies/Notifications/CookieValidateIdentityContext.cs b/src/Microsoft.AspNet.Security.Cookies/Notifications/CookieValidateIdentityContext.cs index ea1682204..771d75d40 100644 --- a/src/Microsoft.AspNet.Security.Cookies/Notifications/CookieValidateIdentityContext.cs +++ b/src/Microsoft.AspNet.Security.Cookies/Notifications/CookieValidateIdentityContext.cs @@ -7,7 +7,7 @@ using System.Security.Principal; using Microsoft.AspNet.Http; using Microsoft.AspNet.Http.Security; -using Microsoft.AspNet.HttpFeature.Security; +using Microsoft.AspNet.Http.Interfaces.Security; using Microsoft.AspNet.Security.Infrastructure; using Microsoft.AspNet.Security.Notifications; diff --git a/src/Microsoft.AspNet.Security/Infrastructure/AuthenticationHandler.cs b/src/Microsoft.AspNet.Security/Infrastructure/AuthenticationHandler.cs index 2c9691c48..d7a0db8fc 100644 --- a/src/Microsoft.AspNet.Security/Infrastructure/AuthenticationHandler.cs +++ b/src/Microsoft.AspNet.Security/Infrastructure/AuthenticationHandler.cs @@ -12,7 +12,7 @@ using System.Threading.Tasks; using Microsoft.AspNet.Http; using Microsoft.AspNet.Http.Security; -using Microsoft.AspNet.HttpFeature.Security; +using Microsoft.AspNet.Http.Interfaces.Security; using Microsoft.AspNet.Security.DataHandler.Encoder; using Microsoft.Framework.Logging; diff --git a/src/Microsoft.AspNet.Security/Infrastructure/HttpContextExtensions.cs b/src/Microsoft.AspNet.Security/Infrastructure/HttpContextExtensions.cs index 642809e18..5ba7a9ce4 100644 --- a/src/Microsoft.AspNet.Security/Infrastructure/HttpContextExtensions.cs +++ b/src/Microsoft.AspNet.Security/Infrastructure/HttpContextExtensions.cs @@ -3,7 +3,7 @@ using Microsoft.AspNet.Http; using Microsoft.AspNet.Http.Core.Security; -using Microsoft.AspNet.HttpFeature.Security; +using Microsoft.AspNet.Http.Interfaces.Security; namespace Microsoft.AspNet.Security.Infrastructure { diff --git a/src/Microsoft.AspNet.Security/project.json b/src/Microsoft.AspNet.Security/project.json index 6e7c66c59..b147d3031 100644 --- a/src/Microsoft.AspNet.Security/project.json +++ b/src/Microsoft.AspNet.Security/project.json @@ -3,7 +3,7 @@ "description": "ASP.NET 5 common types used by the various authentication middleware.", "dependencies": { "Microsoft.AspNet.RequestContainer": "1.0.0-*", - "Microsoft.AspNet.HttpFeature": { "version": "1.0.0-*", "type": "build" }, + "Microsoft.AspNet.Http.Interfaces": { "version": "1.0.0-*", "type": "build" }, "Microsoft.AspNet.Http.Core": "1.0.0-*", "Microsoft.AspNet.Security.DataProtection": "1.0.0-*", "Microsoft.Framework.Logging": "1.0.0-*" From 1f14d9aa503a8b70a72fc06a92151abd542e90b0 Mon Sep 17 00:00:00 2001 From: Pranav K Date: Tue, 20 Jan 2015 01:36:43 -0800 Subject: [PATCH 116/216] Updating build.cmd and build.sh to use dotnetsdk --- build.cmd | 6 +++--- build.sh | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/build.cmd b/build.cmd index 86ca5bbbf..c8041fdd9 100644 --- a/build.cmd +++ b/build.cmd @@ -20,9 +20,9 @@ IF EXIST packages\KoreBuild goto run .nuget\NuGet.exe install Sake -version 0.2 -o packages -ExcludeVersion IF "%SKIP_KRE_INSTALL%"=="1" goto run -CALL packages\KoreBuild\build\kvm upgrade -runtime CLR -x86 -CALL packages\KoreBuild\build\kvm install default -runtime CoreCLR -x86 +CALL packages\KoreBuild\build\dotnetsdk upgrade -runtime CLR -x86 +CALL packages\KoreBuild\build\dotnetsdk install default -runtime CoreCLR -x86 :run -CALL packages\KoreBuild\build\kvm use default -runtime CLR -x86 +CALL packages\KoreBuild\build\dotnetsdk use default -runtime CLR -x86 packages\Sake\tools\Sake.exe -I packages\KoreBuild\build -f makefile.shade %* diff --git a/build.sh b/build.sh index c7873ef58..350d7e389 100644 --- a/build.sh +++ b/build.sh @@ -28,11 +28,11 @@ if test ! -d packages/KoreBuild; then fi if ! type k > /dev/null 2>&1; then - source packages/KoreBuild/build/kvm.sh + source packages/KoreBuild/build/dotnetsdk.sh fi if ! type k > /dev/null 2>&1; then - kvm upgrade + dotnetsdk upgrade fi mono packages/Sake/tools/Sake.exe -I packages/KoreBuild/build -f makefile.shade "$@" From de5c079bf0587ce33865595205dfb5562eacf583 Mon Sep 17 00:00:00 2001 From: Suhas Joshi Date: Tue, 20 Jan 2015 17:25:24 -0800 Subject: [PATCH 117/216] Updating NuGet.config --- NuGet.Config | 1 - 1 file changed, 1 deletion(-) diff --git a/NuGet.Config b/NuGet.Config index 2d3b0cb85..53454b200 100644 --- a/NuGet.Config +++ b/NuGet.Config @@ -1,7 +1,6 @@  - From 231994217b1bfbd7506362c625822380a7ec03e0 Mon Sep 17 00:00:00 2001 From: Wei Wang Date: Tue, 20 Jan 2015 18:34:21 -0800 Subject: [PATCH 118/216] Rename SKIP_KRE_INSTALL to SKIP_DOTNET_INSTALL --- build.cmd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.cmd b/build.cmd index c8041fdd9..220a1ff56 100644 --- a/build.cmd +++ b/build.cmd @@ -19,7 +19,7 @@ IF EXIST packages\KoreBuild goto run .nuget\NuGet.exe install KoreBuild -ExcludeVersion -o packages -nocache -pre .nuget\NuGet.exe install Sake -version 0.2 -o packages -ExcludeVersion -IF "%SKIP_KRE_INSTALL%"=="1" goto run +IF "%SKIP_DOTNET_INSTALL%"=="1" goto run CALL packages\KoreBuild\build\dotnetsdk upgrade -runtime CLR -x86 CALL packages\KoreBuild\build\dotnetsdk install default -runtime CoreCLR -x86 From 5328c7f53945e614529b168f2a95fdc844ac43f8 Mon Sep 17 00:00:00 2001 From: Aligned Date: Wed, 21 Jan 2015 11:55:35 -0600 Subject: [PATCH 119/216] Change ASP.NET vNext to ASP.Net 5 in the Readme.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index ab7b29e97..06a74de41 100644 --- a/README.md +++ b/README.md @@ -3,4 +3,4 @@ ASP.NET Security ASP.NET Security contains the security and authorization middlewares for ASP.NET vNext. -This project is part of ASP.NET vNext. You can find samples, documentation and getting started instructions for ASP.NET vNext at the [Home](https://github.com/aspnet/home) repo. +This project is part of ASP.NET 5. You can find samples, documentation and getting started instructions for ASP.NET 5 at the [Home](https://github.com/aspnet/home) repo. From 4193fa29b7f0e1238411197fc0988c419167724a Mon Sep 17 00:00:00 2001 From: Suhas Joshi Date: Wed, 21 Jan 2015 15:52:54 -0800 Subject: [PATCH 120/216] Updating to release NuGet.config --- NuGet.Config | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/NuGet.Config b/NuGet.Config index 4ee105534..2d3b0cb85 100644 --- a/NuGet.Config +++ b/NuGet.Config @@ -1,8 +1,7 @@  - + - From d7b389e595a6a79793548e4d3671141d3e1fed48 Mon Sep 17 00:00:00 2001 From: Pranav K Date: Wed, 21 Jan 2015 16:53:45 -0800 Subject: [PATCH 121/216] Updating release NuGet.config to include AzureADNighty feed --- NuGet.Config | 1 + 1 file changed, 1 insertion(+) diff --git a/NuGet.Config b/NuGet.Config index 2d3b0cb85..d699f07ad 100644 --- a/NuGet.Config +++ b/NuGet.Config @@ -3,5 +3,6 @@ + From e5518e6fc25874920e203dfcd923868ad5de6cbb Mon Sep 17 00:00:00 2001 From: BrentSchmaltz Date: Tue, 27 Jan 2015 08:15:28 -0800 Subject: [PATCH 122/216] ChallengeContext will be null with [Authorize] attribute OpenIdConnect set Ticket.Principal, get identity from there. --- .../OpenidConnectAuthenticationHandler.cs | 24 +++++++++++++++---- .../Infrastructure/AuthenticationHandler.cs | 7 ++++-- 2 files changed, 25 insertions(+), 6 deletions(-) diff --git a/src/Microsoft.AspNet.Security.OpenIdConnect/OpenidConnectAuthenticationHandler.cs b/src/Microsoft.AspNet.Security.OpenIdConnect/OpenidConnectAuthenticationHandler.cs index 96156f653..b237b6be9 100644 --- a/src/Microsoft.AspNet.Security.OpenIdConnect/OpenidConnectAuthenticationHandler.cs +++ b/src/Microsoft.AspNet.Security.OpenIdConnect/OpenidConnectAuthenticationHandler.cs @@ -91,6 +91,7 @@ protected override async Task ApplyResponseGrantAsync() { ProtocolMessage = openIdConnectMessage }; + await Options.Notifications.RedirectToIdentityProvider(notification); if (!notification.HandledResponse) @@ -100,6 +101,7 @@ protected override async Task ApplyResponseGrantAsync() { _logger.WriteWarning("The logout redirect URI is malformed: " + redirectUri); } + Response.Redirect(redirectUri); } } @@ -116,7 +118,13 @@ protected override void ApplyResponseChallenge() /// protected override async Task ApplyResponseChallengeAsync() { - if ((Response.StatusCode != 401) || (ChallengeContext == null)) + if (Response.StatusCode != 401) + { + return; + } + + // Active middleware should redirect on 401 even if there wasn't an explicit challenge. + if (ChallengeContext == null && Options.AuthenticationMode == AuthenticationMode.Passive) { return; } @@ -124,7 +132,16 @@ protected override async Task ApplyResponseChallengeAsync() // order for redirect_uri // 1. challenge.Properties.RedirectUri // 2. CurrentUri - AuthenticationProperties properties = new AuthenticationProperties(ChallengeContext.Properties); + AuthenticationProperties properties; + if (ChallengeContext == null) + { + properties = new AuthenticationProperties(); + } + else + { + properties = new AuthenticationProperties(ChallengeContext.Properties); + } + if (string.IsNullOrEmpty(properties.RedirectUri)) { properties.RedirectUri = CurrentUri; @@ -154,7 +171,6 @@ protected override async Task ApplyResponseChallengeAsync() State = OpenIdConnectAuthenticationDefaults.AuthenticationPropertiesKey + "=" + Uri.EscapeDataString(Options.StateDataFormat.Protect(properties)) }; - // TODO - brentschmaltz, if INonceCache is set should we even consider if ProtocolValidator is set? if (Options.ProtocolValidator.RequireNonce) { openIdConnectMessage.Nonce = Options.ProtocolValidator.GenerateNonce(); @@ -179,7 +195,7 @@ protected override async Task ApplyResponseChallengeAsync() string redirectUri = notification.ProtocolMessage.CreateAuthenticationRequestUrl(); if (!Uri.IsWellFormedUriString(redirectUri, UriKind.Absolute)) { - _logger.WriteWarning("The authenticate redirect URI is malformed: " + redirectUri); + _logger.WriteWarning("Uri.IsWellFormedUriString(redirectUri, UriKind.Absolute) returned 'false', redirectUri is: " + (redirectUri ?? "null")); } Response.Redirect(redirectUri); diff --git a/src/Microsoft.AspNet.Security/Infrastructure/AuthenticationHandler.cs b/src/Microsoft.AspNet.Security/Infrastructure/AuthenticationHandler.cs index d7a0db8fc..fc847f4fa 100644 --- a/src/Microsoft.AspNet.Security/Infrastructure/AuthenticationHandler.cs +++ b/src/Microsoft.AspNet.Security/Infrastructure/AuthenticationHandler.cs @@ -77,9 +77,12 @@ protected async Task BaseInitializeAsync(AuthenticationOptions options, HttpCont if (BaseOptions.AuthenticationMode == AuthenticationMode.Active) { AuthenticationTicket ticket = await AuthenticateAsync(); - if (ticket != null && ticket.Identity != null) + if (ticket != null) { - SecurityHelper.AddUserIdentity(Context, ticket.Identity); + if ( ticket.Identity != null) + SecurityHelper.AddUserIdentity(Context, ticket.Identity); + else if (ticket.Principal != null) + SecurityHelper.AddUserIdentity(Context, ticket.Principal.Identity); } } } From e04358f7f92f709cfb235ab48967d38e4c6b4535 Mon Sep 17 00:00:00 2001 From: BrentSchmaltz Date: Tue, 27 Jan 2015 09:58:47 -0800 Subject: [PATCH 123/216] Missing resource file. --- .../Resources.resx | 132 ++++++++++++++++++ 1 file changed, 132 insertions(+) create mode 100644 src/Microsoft.AspNet.Security.OpenIdConnect/Resources.resx diff --git a/src/Microsoft.AspNet.Security.OpenIdConnect/Resources.resx b/src/Microsoft.AspNet.Security.OpenIdConnect/Resources.resx new file mode 100644 index 000000000..7abad90eb --- /dev/null +++ b/src/Microsoft.AspNet.Security.OpenIdConnect/Resources.resx @@ -0,0 +1,132 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + BackchannelTimeout cannot be less or equal to TimeSpan.Zero. + + + "OpenIdConnectMessage.Error was not null, indicating an error. Error: '{0}'. Error_Description (may be empty): '{1}'. Error_Uri (may be empty): '{2}'." + + + OIDC_20001: The query string for Logout is not a well formed URI. The runtime cannot redirect. Redirect uri: '{0}'. + + + An ICertificateValidator cannot be specified at the same time as an HttpMessageHandler unless it is a WebRequestHandler. + + \ No newline at end of file From 3483842ab76d4198fc230c7a1905b0ada9b4bf89 Mon Sep 17 00:00:00 2001 From: BrentSchmaltz Date: Wed, 28 Jan 2015 10:27:55 -0800 Subject: [PATCH 124/216] Rollback of setting Principal on AuthenticationTicket. adjust formating of messages. --- .../OpenidConnectAuthenticationHandler.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Microsoft.AspNet.Security.OpenIdConnect/OpenidConnectAuthenticationHandler.cs b/src/Microsoft.AspNet.Security.OpenIdConnect/OpenidConnectAuthenticationHandler.cs index b237b6be9..94fe21147 100644 --- a/src/Microsoft.AspNet.Security.OpenIdConnect/OpenidConnectAuthenticationHandler.cs +++ b/src/Microsoft.AspNet.Security.OpenIdConnect/OpenidConnectAuthenticationHandler.cs @@ -99,7 +99,7 @@ protected override async Task ApplyResponseGrantAsync() string redirectUri = notification.ProtocolMessage.CreateLogoutRequestUrl(); if (!Uri.IsWellFormedUriString(redirectUri, UriKind.Absolute)) { - _logger.WriteWarning("The logout redirect URI is malformed: " + redirectUri); + _logger.WriteWarning("The logout redirect URI is malformed: {0}", (redirectUri ?? "null")); } Response.Redirect(redirectUri); @@ -195,7 +195,7 @@ protected override async Task ApplyResponseChallengeAsync() string redirectUri = notification.ProtocolMessage.CreateAuthenticationRequestUrl(); if (!Uri.IsWellFormedUriString(redirectUri, UriKind.Absolute)) { - _logger.WriteWarning("Uri.IsWellFormedUriString(redirectUri, UriKind.Absolute) returned 'false', redirectUri is: " + (redirectUri ?? "null")); + _logger.WriteWarning("Uri.IsWellFormedUriString(redirectUri, UriKind.Absolute) returned 'false', redirectUri is: {0}", (redirectUri ?? "null")); } Response.Redirect(redirectUri); @@ -343,7 +343,7 @@ protected override async Task AuthenticateCoreAsync() throw new InvalidOperationException("No SecurityTokenValidator found for token: " + openIdConnectMessage.IdToken); } - ticket = new AuthenticationTicket(principal, properties, Options.AuthenticationType); + ticket = new AuthenticationTicket(principal.Identity as ClaimsIdentity, properties); if (!string.IsNullOrWhiteSpace(openIdConnectMessage.SessionState)) { ticket.Properties.Dictionary[OpenIdConnectSessionProperties.SessionState] = openIdConnectMessage.SessionState; From 6367c0d2494cbb3d709c8ca1806bcb83759b34aa Mon Sep 17 00:00:00 2001 From: Wei Wang Date: Wed, 28 Jan 2015 18:30:59 -0800 Subject: [PATCH 125/216] Update build.cmd and build.sh to use kvm --- build.cmd | 6 +++--- build.sh | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/build.cmd b/build.cmd index 220a1ff56..5885abe38 100644 --- a/build.cmd +++ b/build.cmd @@ -20,9 +20,9 @@ IF EXIST packages\KoreBuild goto run .nuget\NuGet.exe install Sake -version 0.2 -o packages -ExcludeVersion IF "%SKIP_DOTNET_INSTALL%"=="1" goto run -CALL packages\KoreBuild\build\dotnetsdk upgrade -runtime CLR -x86 -CALL packages\KoreBuild\build\dotnetsdk install default -runtime CoreCLR -x86 +CALL packages\KoreBuild\build\kvm upgrade -runtime CLR -x86 +CALL packages\KoreBuild\build\kvm install default -runtime CoreCLR -x86 :run -CALL packages\KoreBuild\build\dotnetsdk use default -runtime CLR -x86 +CALL packages\KoreBuild\build\kvm use default -runtime CLR -x86 packages\Sake\tools\Sake.exe -I packages\KoreBuild\build -f makefile.shade %* diff --git a/build.sh b/build.sh index 350d7e389..c7873ef58 100644 --- a/build.sh +++ b/build.sh @@ -28,11 +28,11 @@ if test ! -d packages/KoreBuild; then fi if ! type k > /dev/null 2>&1; then - source packages/KoreBuild/build/dotnetsdk.sh + source packages/KoreBuild/build/kvm.sh fi if ! type k > /dev/null 2>&1; then - dotnetsdk upgrade + kvm upgrade fi mono packages/Sake/tools/Sake.exe -I packages/KoreBuild/build -f makefile.shade "$@" From 24e68d81ea4cba4157aca19b7b4bd81a3d56e873 Mon Sep 17 00:00:00 2001 From: Wei Wang Date: Wed, 28 Jan 2015 18:31:11 -0800 Subject: [PATCH 126/216] Change SKIP_DOTNET_INSTALL to SKIP_KRE_INSTALL --- build.cmd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.cmd b/build.cmd index 5885abe38..86ca5bbbf 100644 --- a/build.cmd +++ b/build.cmd @@ -19,7 +19,7 @@ IF EXIST packages\KoreBuild goto run .nuget\NuGet.exe install KoreBuild -ExcludeVersion -o packages -nocache -pre .nuget\NuGet.exe install Sake -version 0.2 -o packages -ExcludeVersion -IF "%SKIP_DOTNET_INSTALL%"=="1" goto run +IF "%SKIP_KRE_INSTALL%"=="1" goto run CALL packages\KoreBuild\build\kvm upgrade -runtime CLR -x86 CALL packages\KoreBuild\build\kvm install default -runtime CoreCLR -x86 From f9d3f6fe173bccab15dabc33065cacd680ec9b96 Mon Sep 17 00:00:00 2001 From: Pranav K Date: Thu, 29 Jan 2015 18:12:51 -0800 Subject: [PATCH 127/216] Fixing release NuGet.config --- NuGet.Config | 1 + 1 file changed, 1 insertion(+) diff --git a/NuGet.Config b/NuGet.Config index ee06e9006..d699f07ad 100644 --- a/NuGet.Config +++ b/NuGet.Config @@ -1,6 +1,7 @@  + From 4e83a678c03492a4913258be6eb16cecaff80d5e Mon Sep 17 00:00:00 2001 From: Praburaj Date: Mon, 2 Feb 2015 13:46:28 -0800 Subject: [PATCH 128/216] Creating authentication ticket by passing in a principal This fixes bug : https://github.com/aspnet/Security/issues/144 --- .../OpenidConnectAuthenticationHandler.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Microsoft.AspNet.Security.OpenIdConnect/OpenidConnectAuthenticationHandler.cs b/src/Microsoft.AspNet.Security.OpenIdConnect/OpenidConnectAuthenticationHandler.cs index 94fe21147..b30346e85 100644 --- a/src/Microsoft.AspNet.Security.OpenIdConnect/OpenidConnectAuthenticationHandler.cs +++ b/src/Microsoft.AspNet.Security.OpenIdConnect/OpenidConnectAuthenticationHandler.cs @@ -224,7 +224,7 @@ protected override async Task AuthenticateCoreAsync() // assumption: if the ContentType is "application/x-www-form-urlencoded" it should be safe to read as it is small. if (string.Equals(Request.Method, "POST", StringComparison.OrdinalIgnoreCase) && !string.IsNullOrWhiteSpace(Request.ContentType) - // May have media/type; charset=utf-8, allow partial match. + // May have media/type; charset=utf-8, allow partial match. && Request.ContentType.StartsWith("application/x-www-form-urlencoded", StringComparison.OrdinalIgnoreCase) && Request.Body.CanRead) { @@ -343,7 +343,7 @@ protected override async Task AuthenticateCoreAsync() throw new InvalidOperationException("No SecurityTokenValidator found for token: " + openIdConnectMessage.IdToken); } - ticket = new AuthenticationTicket(principal.Identity as ClaimsIdentity, properties); + ticket = new AuthenticationTicket(principal, properties, Options.AuthenticationType); if (!string.IsNullOrWhiteSpace(openIdConnectMessage.SessionState)) { ticket.Properties.Dictionary[OpenIdConnectSessionProperties.SessionState] = openIdConnectMessage.SessionState; From b17d718d273c99e60da961553afa012fd3bd806f Mon Sep 17 00:00:00 2001 From: Brennan Date: Wed, 4 Feb 2015 14:24:28 -0800 Subject: [PATCH 129/216] Updating .kproj files --- .../OpenIdConnectSample/OpenIdConnectSample.kproj | 14 +------------- .../Microsoft.AspNet.Security.OAuthBearer.kproj | 7 +------ .../Microsoft.AspNet.Security.OpenIdConnect.kproj | 14 +------------- 3 files changed, 3 insertions(+), 32 deletions(-) diff --git a/samples/OpenIdConnectSample/OpenIdConnectSample.kproj b/samples/OpenIdConnectSample/OpenIdConnectSample.kproj index c6ab693ae..1f6d87ba4 100644 --- a/samples/OpenIdConnectSample/OpenIdConnectSample.kproj +++ b/samples/OpenIdConnectSample/OpenIdConnectSample.kproj @@ -7,24 +7,12 @@ bef0f5c3-ef4e-4649-9c49-d5e279a3ca2b - OpenIDConnectSample ..\..\artifacts\obj\$(MSBuildProjectName) ..\..\artifacts\bin\$(MSBuildProjectName)\ - - OpenIDConnectSample - 2.0 42023 - - - - - - - - - \ No newline at end of file + diff --git a/src/Microsoft.AspNet.Security.OAuthBearer/Microsoft.AspNet.Security.OAuthBearer.kproj b/src/Microsoft.AspNet.Security.OAuthBearer/Microsoft.AspNet.Security.OAuthBearer.kproj index 55d65389e..f83bb90de 100644 --- a/src/Microsoft.AspNet.Security.OAuthBearer/Microsoft.AspNet.Security.OAuthBearer.kproj +++ b/src/Microsoft.AspNet.Security.OAuthBearer/Microsoft.AspNet.Security.OAuthBearer.kproj @@ -14,9 +14,4 @@ 2.0 - - - - - - \ No newline at end of file + diff --git a/src/Microsoft.AspNet.Security.OpenIdConnect/Microsoft.AspNet.Security.OpenIdConnect.kproj b/src/Microsoft.AspNet.Security.OpenIdConnect/Microsoft.AspNet.Security.OpenIdConnect.kproj index ed1a12239..6167f967f 100644 --- a/src/Microsoft.AspNet.Security.OpenIdConnect/Microsoft.AspNet.Security.OpenIdConnect.kproj +++ b/src/Microsoft.AspNet.Security.OpenIdConnect/Microsoft.AspNet.Security.OpenIdConnect.kproj @@ -7,23 +7,11 @@ 674d128e-83bb-481a-a9d9-6d47872e1fc8 - Microsoft.AspNet.Security.OpenIdConnect ..\..\artifacts\obj\$(MSBuildProjectName) ..\..\artifacts\bin\$(MSBuildProjectName)\ 2.0 - - True - - - True - - - - - - - \ No newline at end of file + From 710c2d7d2118e16a76da0b6d2be9583a9dfdf3da Mon Sep 17 00:00:00 2001 From: Praburaj Date: Thu, 5 Feb 2015 15:11:15 -0800 Subject: [PATCH 130/216] Removing the AzureAD feed from security repo Wilson packages are now part of aspnet myget feeds. Removing azure feed from restore sources. --- NuGet.Config | 1 - 1 file changed, 1 deletion(-) diff --git a/NuGet.Config b/NuGet.Config index d699f07ad..2d3b0cb85 100644 --- a/NuGet.Config +++ b/NuGet.Config @@ -3,6 +3,5 @@ - From 74bb8e089de5d29955c911072904a6e03c3e7f85 Mon Sep 17 00:00:00 2001 From: Pranav K Date: Fri, 6 Feb 2015 09:55:22 -0800 Subject: [PATCH 131/216] Reacting to System.Dynamic.Runtime version changes --- src/Microsoft.AspNet.Security.MicrosoftAccount/project.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Microsoft.AspNet.Security.MicrosoftAccount/project.json b/src/Microsoft.AspNet.Security.MicrosoftAccount/project.json index 530d34c57..e641098e5 100644 --- a/src/Microsoft.AspNet.Security.MicrosoftAccount/project.json +++ b/src/Microsoft.AspNet.Security.MicrosoftAccount/project.json @@ -8,7 +8,7 @@ "aspnet50": {}, "aspnetcore50": { "dependencies": { - "System.Dynamic.Runtime": "4.0.0-beta-*", + "System.Dynamic.Runtime": "4.0.10-beta-*", "System.ObjectModel": "4.0.10-beta-*" } } From bb2352c638e3fafdd975296e4ae560a20ab6d5a0 Mon Sep 17 00:00:00 2001 From: David Fowler Date: Tue, 10 Feb 2015 11:01:03 -0800 Subject: [PATCH 132/216] Remove build time deps and fixed formatting --- .../project.json | 20 +++++++++---------- .../project.json | 4 ++-- .../project.json | 4 ++-- .../project.json | 4 ++-- .../project.json | 2 +- src/Microsoft.AspNet.Security/project.json | 2 +- 6 files changed, 18 insertions(+), 18 deletions(-) diff --git a/src/Microsoft.AspNet.Security.Cookies/project.json b/src/Microsoft.AspNet.Security.Cookies/project.json index ac92e94e8..82f92b75b 100644 --- a/src/Microsoft.AspNet.Security.Cookies/project.json +++ b/src/Microsoft.AspNet.Security.Cookies/project.json @@ -1,12 +1,12 @@ { - "version": "1.0.0-*", - "description": "ASP.NET middleware that enables an application to use cookie based authentication, similar to ASP.NET's forms authentication.", - "dependencies": { - "Microsoft.AspNet.Security": "1.0.0-*", - "Newtonsoft.Json": "6.0.6" - }, - "frameworks": { - "aspnet50": {}, - "aspnetcore50": {} - } + "version": "1.0.0-*", + "description": "ASP.NET middleware that enables an application to use cookie based authentication, similar to ASP.NET's forms authentication.", + "dependencies": { + "Microsoft.AspNet.Security": "1.0.0-*", + "Newtonsoft.Json": "6.0.6" + }, + "frameworks": { + "aspnet50": { }, + "aspnetcore50": { } + } } diff --git a/src/Microsoft.AspNet.Security.Facebook/project.json b/src/Microsoft.AspNet.Security.Facebook/project.json index a850104f7..3aad11e61 100644 --- a/src/Microsoft.AspNet.Security.Facebook/project.json +++ b/src/Microsoft.AspNet.Security.Facebook/project.json @@ -5,7 +5,7 @@ "Microsoft.AspNet.Security.OAuth": "1.0.0-*" }, "frameworks": { - "aspnet50": {}, - "aspnetcore50": {} + "aspnet50": { }, + "aspnetcore50": { } } } diff --git a/src/Microsoft.AspNet.Security.Google/project.json b/src/Microsoft.AspNet.Security.Google/project.json index 84ede5d46..a4815b181 100644 --- a/src/Microsoft.AspNet.Security.Google/project.json +++ b/src/Microsoft.AspNet.Security.Google/project.json @@ -5,7 +5,7 @@ "Microsoft.AspNet.Security.OAuth": "1.0.0-*" }, "frameworks": { - "aspnet50": {}, - "aspnetcore50": {} + "aspnet50": { }, + "aspnetcore50": { } } } diff --git a/src/Microsoft.AspNet.Security.MicrosoftAccount/project.json b/src/Microsoft.AspNet.Security.MicrosoftAccount/project.json index e641098e5..82c106b74 100644 --- a/src/Microsoft.AspNet.Security.MicrosoftAccount/project.json +++ b/src/Microsoft.AspNet.Security.MicrosoftAccount/project.json @@ -2,10 +2,10 @@ "version": "1.0.0-*", "description": "ASP.NET 5 middleware that enables an application to support the Microsoft Account authentication workflow.", "dependencies": { - "Microsoft.AspNet.Security.OAuth": "1.0.0-*", + "Microsoft.AspNet.Security.OAuth": "1.0.0-*" }, "frameworks": { - "aspnet50": {}, + "aspnet50": { }, "aspnetcore50": { "dependencies": { "System.Dynamic.Runtime": "4.0.10-beta-*", diff --git a/src/Microsoft.AspNet.Security.Twitter/project.json b/src/Microsoft.AspNet.Security.Twitter/project.json index db7442b59..b9eba0a30 100644 --- a/src/Microsoft.AspNet.Security.Twitter/project.json +++ b/src/Microsoft.AspNet.Security.Twitter/project.json @@ -13,7 +13,7 @@ }, "aspnetcore50": { "dependencies": { - "System.Net.Http.WinHttpHandler": "4.0.0-beta-*", + "System.Net.Http.WinHttpHandler": "4.0.0-beta-*" } } } diff --git a/src/Microsoft.AspNet.Security/project.json b/src/Microsoft.AspNet.Security/project.json index b147d3031..af2d2fb98 100644 --- a/src/Microsoft.AspNet.Security/project.json +++ b/src/Microsoft.AspNet.Security/project.json @@ -3,7 +3,7 @@ "description": "ASP.NET 5 common types used by the various authentication middleware.", "dependencies": { "Microsoft.AspNet.RequestContainer": "1.0.0-*", - "Microsoft.AspNet.Http.Interfaces": { "version": "1.0.0-*", "type": "build" }, + "Microsoft.AspNet.Http.Interfaces": "1.0.0-*", "Microsoft.AspNet.Http.Core": "1.0.0-*", "Microsoft.AspNet.Security.DataProtection": "1.0.0-*", "Microsoft.Framework.Logging": "1.0.0-*" From 04c6b1f10192a74ca82132efebd90e75c60a5777 Mon Sep 17 00:00:00 2001 From: Praburaj Date: Tue, 10 Feb 2015 11:25:30 -0800 Subject: [PATCH 133/216] Adding necessary dependencies to OpenIdConnect directly OpenIdconnect project is betting on the dependencies included by Microsoft.IdentityModel.Protocol.Extensions for the types that are referenced directly in this library but not used in Protocol.Extensions library. This change is to enable Wilson clean up its unused dependencies. --- src/Microsoft.AspNet.Security.OpenIdConnect/project.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Microsoft.AspNet.Security.OpenIdConnect/project.json b/src/Microsoft.AspNet.Security.OpenIdConnect/project.json index 728e82b19..a02c8145f 100644 --- a/src/Microsoft.AspNet.Security.OpenIdConnect/project.json +++ b/src/Microsoft.AspNet.Security.OpenIdConnect/project.json @@ -2,16 +2,18 @@ "version": "1.0.0-*", "dependencies": { "Microsoft.AspNet.Security": "1.0.0-*", - "Microsoft.IdentityModel.Protocol.Extensions": "2.0.0.0-beta1-*" + "Microsoft.IdentityModel.Protocol.Extensions": "2.0.0-beta1-*" }, "frameworks": { "aspnet50": { "frameworkAssemblies": { + "System.Net.Http": "", "System.Net.Http.WebRequest": "" } }, "aspnetcore50": { "dependencies": { + "System.Collections.Specialized": "4.0.0-beta-*", "System.Net.Http.WinHttpHandler": "4.0.0-beta-*" } } From 58661b27341aa0c29a6cc069082e24868627acca Mon Sep 17 00:00:00 2001 From: Wei Wang Date: Mon, 16 Feb 2015 13:50:24 -0800 Subject: [PATCH 134/216] Add project.lock.json to .gitignore --- .gitignore | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 08e21e25b..ac82da756 100644 --- a/.gitignore +++ b/.gitignore @@ -23,4 +23,5 @@ nuget.exe *.ncrunchsolution *.*sdf *.ipch -*.sln.ide \ No newline at end of file +*.sln.ide +project.lock.json From 5094b85ac92df0035f15e94b87d72cd4bc716905 Mon Sep 17 00:00:00 2001 From: Hao Kung Date: Mon, 16 Feb 2015 15:04:10 -0800 Subject: [PATCH 135/216] Latest AuthZ iteration - Core Auth API now takes list of IAuthorizationRequirements, or policy name. - Overload that takes AuthorizationPolicy instance moved to extension method. - Remove HttpContext from API and replace with ClaimsPrincipal instead - Add Operation requirement - Add Sync overloads - Add ClaimsTransformationOptions (TBD where to use this) Fixes https://github.com/aspnet/Security/issues/132 Fixes https://github.com/aspnet/Security/issues/116 Fixes https://github.com/aspnet/Security/issues/11 Fixes https://github.com/aspnet/Security/issues/117 --- .../AuthorizationContext.cs | 21 +- .../AuthorizationHandler.cs | 80 +++--- .../AuthorizationPolicy.cs | 66 ++++- .../AuthorizationPolicyBuilder.cs | 14 +- .../AuthorizationServiceExtensions.cs | 49 ++++ .../AuthorizeAttribute.cs | 25 ++ .../ClaimsAuthorizationHandler.cs | 32 +-- .../ClaimsTransformationOptions.cs | 15 + .../DefaultAuthorizationService.cs | 54 ++-- .../DenyAnonymousAuthorizationHandler.cs | 7 +- .../IAuthorizationHandler.cs | 2 +- .../IAuthorizationService.cs | 32 ++- .../OperationAuthorizationRequirement.cs | 10 + .../PassThroughAuthorizationHandler.cs | 10 +- .../Properties/Resources.Designer.cs | 94 +++++++ .../Resources.Designer.cs | 99 ------- src/Microsoft.AspNet.Security/Resources.resx | 3 + .../ServiceCollectionExtensions.cs | 5 + .../AuthorizationPolicyFacts.cs | 37 +++ .../DefaultAuthorizationServiceTests.cs | 257 ++++++++++++------ 20 files changed, 624 insertions(+), 288 deletions(-) create mode 100644 src/Microsoft.AspNet.Security/AuthorizationServiceExtensions.cs create mode 100644 src/Microsoft.AspNet.Security/AuthorizeAttribute.cs create mode 100644 src/Microsoft.AspNet.Security/ClaimsTransformationOptions.cs create mode 100644 src/Microsoft.AspNet.Security/OperationAuthorizationRequirement.cs create mode 100644 src/Microsoft.AspNet.Security/Properties/Resources.Designer.cs delete mode 100644 src/Microsoft.AspNet.Security/Resources.Designer.cs create mode 100644 test/Microsoft.AspNet.Security.Test/AuthorizationPolicyFacts.cs diff --git a/src/Microsoft.AspNet.Security/AuthorizationContext.cs b/src/Microsoft.AspNet.Security/AuthorizationContext.cs index 0c6dc0619..81d00bdc9 100644 --- a/src/Microsoft.AspNet.Security/AuthorizationContext.cs +++ b/src/Microsoft.AspNet.Security/AuthorizationContext.cs @@ -4,7 +4,6 @@ using System.Collections.Generic; using System.Linq; using System.Security.Claims; -using Microsoft.AspNet.Http; namespace Microsoft.AspNet.Security { @@ -13,27 +12,23 @@ namespace Microsoft.AspNet.Security /// public class AuthorizationContext { - private HashSet _pendingRequirements = new HashSet(); + private HashSet _pendingRequirements; private bool _failCalled; private bool _succeedCalled; public AuthorizationContext( - [NotNull] AuthorizationPolicy policy, - HttpContext context, + [NotNull] IEnumerable requirements, + ClaimsPrincipal user, object resource) { - Policy = policy; - Context = context; + Requirements = requirements; + User = user; Resource = resource; - foreach (var req in Policy.Requirements) - { - _pendingRequirements.Add(req); - } + _pendingRequirements = new HashSet(requirements); } - public AuthorizationPolicy Policy { get; private set; } - public ClaimsPrincipal User { get { return Context.User; } } - public HttpContext Context { get; private set; } + public IEnumerable Requirements { get; private set; } + public ClaimsPrincipal User { get; private set; } public object Resource { get; private set; } public IEnumerable PendingRequirements { get { return _pendingRequirements; } } diff --git a/src/Microsoft.AspNet.Security/AuthorizationHandler.cs b/src/Microsoft.AspNet.Security/AuthorizationHandler.cs index d91331870..e1b27e863 100644 --- a/src/Microsoft.AspNet.Security/AuthorizationHandler.cs +++ b/src/Microsoft.AspNet.Security/AuthorizationHandler.cs @@ -1,58 +1,68 @@ // Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -using System; using System.Linq; using System.Threading.Tasks; namespace Microsoft.AspNet.Security { - // Music store use case + public abstract class AuthorizationHandler : IAuthorizationHandler + where TRequirement : IAuthorizationRequirement + { + public void Handle(AuthorizationContext context) + { + foreach (var req in context.Requirements.OfType()) + { + Handle(context, req); + } + } - // await AuthorizeAsync(user, "Edit", albumInstance); + public virtual Task HandleAsync(AuthorizationContext context) + { + Handle(context); + return Task.FromResult(0); + } - // No policy name needed because this is auto based on resource (operation is the policy name) - //RegisterOperation which auto generates the policy for Authorize - //bool AuthorizeAsync(ClaimsPrincipal, string operation, TResource instance) - //bool AuthorizeAsync(IAuthorization, ClaimsPrincipal, string operation, TResource instance) - public abstract class AuthorizationHandler : IAuthorizationHandler + // REVIEW: do we need an async hook too? + public abstract void Handle(AuthorizationContext context, TRequirement requirement); + } + + public abstract class AuthorizationHandler : IAuthorizationHandler + where TResource : class where TRequirement : IAuthorizationRequirement { - public async Task HandleAsync(AuthorizationContext context) + public virtual async Task HandleAsync(AuthorizationContext context) { - foreach (var req in context.Policy.Requirements.OfType()) + var resource = context.Resource as TResource; + // REVIEW: should we allow null resources? + if (resource != null) { - if (await CheckAsync(context, req)) + foreach (var req in context.Requirements.OfType()) { - context.Succeed(req); + await HandleAsync(context, req, resource); } - else + } + } + + public virtual Task HandleAsync(AuthorizationContext context, TRequirement requirement, TResource resource) + { + Handle(context, requirement, resource); + return Task.FromResult(0); + } + + public virtual void Handle(AuthorizationContext context) + { + var resource = context.Resource as TResource; + // REVIEW: should we allow null resources? + if (resource != null) + { + foreach (var req in context.Requirements.OfType()) { - context.Fail(); + Handle(context, req, resource); } } } - public abstract Task CheckAsync(AuthorizationContext context, TRequirement requirement); + public abstract void Handle(AuthorizationContext context, TRequirement requirement, TResource resource); } - - // TODO: - //public abstract class AuthorizationHandler : AuthorizationHandler - // where TResource : class - // where TRequirement : IAuthorizationRequirement - //{ - // public override Task HandleAsync(AuthorizationContext context) - // { - // var resource = context.Resource as TResource; - // if (resource != null) - // { - // return HandleAsync(context, resource); - // } - - // return Task.FromResult(0); - - // } - - // public abstract Task HandleAsync(AuthorizationContext context, TResource resource); - //} } \ No newline at end of file diff --git a/src/Microsoft.AspNet.Security/AuthorizationPolicy.cs b/src/Microsoft.AspNet.Security/AuthorizationPolicy.cs index d142eb1b6..924f9dbd2 100644 --- a/src/Microsoft.AspNet.Security/AuthorizationPolicy.cs +++ b/src/Microsoft.AspNet.Security/AuthorizationPolicy.cs @@ -1,7 +1,9 @@ // Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. +using System; using System.Collections.Generic; +using System.Linq; namespace Microsoft.AspNet.Security { @@ -9,11 +11,67 @@ public class AuthorizationPolicy { public AuthorizationPolicy(IEnumerable requirements, IEnumerable activeAuthenticationTypes) { - Requirements = requirements; - ActiveAuthenticationTypes = activeAuthenticationTypes; + Requirements = new List(requirements).AsReadOnly(); + ActiveAuthenticationTypes = new List(activeAuthenticationTypes).AsReadOnly(); } - public IEnumerable Requirements { get; private set; } - public IEnumerable ActiveAuthenticationTypes { get; private set; } + public IReadOnlyList Requirements { get; private set; } + public IReadOnlyList ActiveAuthenticationTypes { get; private set; } + + public static AuthorizationPolicy Combine([NotNull] params AuthorizationPolicy[] policies) + { + return Combine((IEnumerable)policies); + } + + // TODO: Add unit tests + public static AuthorizationPolicy Combine([NotNull] IEnumerable policies) + { + var builder = new AuthorizationPolicyBuilder(); + foreach (var policy in policies) + { + builder.Combine(policy); + } + return builder.Build(); + } + + public static AuthorizationPolicy Combine([NotNull] AuthorizationOptions options, [NotNull] IEnumerable attributes) + { + var policyBuilder = new AuthorizationPolicyBuilder(); + bool any = false; + foreach (var authorizeAttribute in attributes.OfType()) + { + any = true; + var requireAnyAuthenticated = true; + if (!string.IsNullOrWhiteSpace(authorizeAttribute.Policy)) + { + var policy = options.GetPolicy(authorizeAttribute.Policy); + if (policy == null) + { + throw new InvalidOperationException(Resources.FormatException_AuthorizationPolicyNotFound(authorizeAttribute.Policy)); + } + policyBuilder.Combine(policy); + requireAnyAuthenticated = false; + } + var rolesSplit = authorizeAttribute.Roles?.Split(','); + if (rolesSplit != null && rolesSplit.Any()) + { + policyBuilder.RequiresRole(rolesSplit); + requireAnyAuthenticated = false; + } + string[] authTypesSplit = authorizeAttribute.ActiveAuthenticationTypes?.Split(','); + if (authTypesSplit != null && authTypesSplit.Any()) + { + foreach (var authType in authTypesSplit) + { + policyBuilder.ActiveAuthenticationTypes.Add(authType); + } + } + if (requireAnyAuthenticated) + { + policyBuilder.RequireAuthenticatedUser(); + } + } + return any ? policyBuilder.Build() : null; + } } } diff --git a/src/Microsoft.AspNet.Security/AuthorizationPolicyBuilder.cs b/src/Microsoft.AspNet.Security/AuthorizationPolicyBuilder.cs index 7b8617f54..bf97fbae2 100644 --- a/src/Microsoft.AspNet.Security/AuthorizationPolicyBuilder.cs +++ b/src/Microsoft.AspNet.Security/AuthorizationPolicyBuilder.cs @@ -40,7 +40,7 @@ public AuthorizationPolicyBuilder AddRequirements(params IAuthorizationRequireme return this; } - public AuthorizationPolicyBuilder Combine(AuthorizationPolicy policy) + public AuthorizationPolicyBuilder Combine([NotNull] AuthorizationPolicy policy) { AddAuthenticationTypes(policy.ActiveAuthenticationTypes.ToArray()); AddRequirements(policy.Requirements.ToArray()); @@ -48,6 +48,11 @@ public AuthorizationPolicyBuilder Combine(AuthorizationPolicy policy) } public AuthorizationPolicyBuilder RequiresClaim([NotNull] string claimType, params string[] requiredValues) + { + return RequiresClaim(claimType, (IEnumerable)requiredValues); + } + + public AuthorizationPolicyBuilder RequiresClaim([NotNull] string claimType, IEnumerable requiredValues) { Requirements.Add(new ClaimsAuthorizationRequirement { @@ -68,6 +73,11 @@ public AuthorizationPolicyBuilder RequiresClaim([NotNull] string claimType) } public AuthorizationPolicyBuilder RequiresRole([NotNull] params string[] roles) + { + return RequiresRole((IEnumerable)roles); + } + + public AuthorizationPolicyBuilder RequiresRole([NotNull] IEnumerable roles) { RequiresClaim(ClaimTypes.Role, roles); return this; @@ -81,7 +91,7 @@ public AuthorizationPolicyBuilder RequireAuthenticatedUser() public AuthorizationPolicy Build() { - return new AuthorizationPolicy(Requirements, ActiveAuthenticationTypes); + return new AuthorizationPolicy(Requirements, ActiveAuthenticationTypes.Distinct()); } } } \ No newline at end of file diff --git a/src/Microsoft.AspNet.Security/AuthorizationServiceExtensions.cs b/src/Microsoft.AspNet.Security/AuthorizationServiceExtensions.cs new file mode 100644 index 000000000..e3e416c89 --- /dev/null +++ b/src/Microsoft.AspNet.Security/AuthorizationServiceExtensions.cs @@ -0,0 +1,49 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System.Linq; +using System.Security.Claims; +using System.Threading.Tasks; + +namespace Microsoft.AspNet.Security +{ + public static class AuthorizationServiceExtensions + { + /// + /// Checks if a user meets a specific authorization policy + /// + /// The authorization service. + /// The user to check the policy against. + /// The resource the policy should be checked with. + /// The policy to check against a specific context. + /// true when the user fulfills the policy, false otherwise. + public static Task AuthorizeAsync([NotNull] this IAuthorizationService service, ClaimsPrincipal user, object resource, [NotNull] AuthorizationPolicy policy) + { + if (policy.ActiveAuthenticationTypes != null && policy.ActiveAuthenticationTypes.Any() && user != null) + { + // Filter the user to only contain the active authentication types + user = new ClaimsPrincipal(user.Identities.Where(i => policy.ActiveAuthenticationTypes.Contains(i.AuthenticationType))); + } + return service.AuthorizeAsync(user, resource, policy.Requirements.ToArray()); + } + + /// + /// Checks if a user meets a specific authorization policy + /// + /// The authorization service. + /// The user to check the policy against. + /// The resource the policy should be checked with. + /// The policy to check against a specific context. + /// true when the user fulfills the policy, false otherwise. + public static bool Authorize([NotNull] this IAuthorizationService service, ClaimsPrincipal user, object resource, [NotNull] AuthorizationPolicy policy) + { + if (policy.ActiveAuthenticationTypes != null && policy.ActiveAuthenticationTypes.Any() && user != null) + { + // Filter the user to only contain the active authentication types + user = new ClaimsPrincipal(user.Identities.Where(i => policy.ActiveAuthenticationTypes.Contains(i.AuthenticationType))); + } + return service.Authorize(user, resource, policy.Requirements.ToArray()); + } + + } +} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Security/AuthorizeAttribute.cs b/src/Microsoft.AspNet.Security/AuthorizeAttribute.cs new file mode 100644 index 000000000..bdaefafbf --- /dev/null +++ b/src/Microsoft.AspNet.Security/AuthorizeAttribute.cs @@ -0,0 +1,25 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; + +namespace Microsoft.AspNet.Security +{ + [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true, Inherited = true)] + public class AuthorizeAttribute : Attribute + { + public AuthorizeAttribute() { } + + public AuthorizeAttribute(string policy) + { + Policy = policy; + } + + public string Policy { get; set; } + + // REVIEW: can we get rid of the , deliminated in Roles/AuthTypes + public string Roles { get; set; } + + public string ActiveAuthenticationTypes { get; set; } + } +} diff --git a/src/Microsoft.AspNet.Security/ClaimsAuthorizationHandler.cs b/src/Microsoft.AspNet.Security/ClaimsAuthorizationHandler.cs index 9f3f58c3a..9aa95ef60 100644 --- a/src/Microsoft.AspNet.Security/ClaimsAuthorizationHandler.cs +++ b/src/Microsoft.AspNet.Security/ClaimsAuthorizationHandler.cs @@ -3,30 +3,30 @@ using System; using System.Linq; -using System.Threading.Tasks; namespace Microsoft.AspNet.Security { public class ClaimsAuthorizationHandler : AuthorizationHandler { - public override Task CheckAsync(AuthorizationContext context, ClaimsAuthorizationRequirement requirement) + public override void Handle(AuthorizationContext context, ClaimsAuthorizationRequirement requirement) { - if (context.Context.User == null) + if (context.User != null) { - return Task.FromResult(false); + bool found = false; + if (requirement.AllowedValues == null || !requirement.AllowedValues.Any()) + { + found = context.User.Claims.Any(c => string.Equals(c.Type, requirement.ClaimType, StringComparison.OrdinalIgnoreCase)); + } + else + { + found = context.User.Claims.Any(c => string.Equals(c.Type, requirement.ClaimType, StringComparison.OrdinalIgnoreCase) + && requirement.AllowedValues.Contains(c.Value, StringComparer.Ordinal)); + } + if (found) + { + context.Succeed(requirement); + } } - - bool found = false; - if (requirement.AllowedValues == null || !requirement.AllowedValues.Any()) - { - found = context.Context.User.Claims.Any(c => string.Equals(c.Type, requirement.ClaimType, StringComparison.OrdinalIgnoreCase)); - } - else - { - found = context.Context.User.Claims.Any(c => string.Equals(c.Type, requirement.ClaimType, StringComparison.OrdinalIgnoreCase) - && requirement.AllowedValues.Contains(c.Value, StringComparer.Ordinal)); - } - return Task.FromResult(found); } } } diff --git a/src/Microsoft.AspNet.Security/ClaimsTransformationOptions.cs b/src/Microsoft.AspNet.Security/ClaimsTransformationOptions.cs new file mode 100644 index 000000000..4684ad69d --- /dev/null +++ b/src/Microsoft.AspNet.Security/ClaimsTransformationOptions.cs @@ -0,0 +1,15 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + + +using System; +using System.Security.Claims; +using System.Threading.Tasks; + +namespace Microsoft.AspNet.Security +{ + public class ClaimsTransformationOptions + { + public Func> TransformAsync { get; set; } + } +} diff --git a/src/Microsoft.AspNet.Security/DefaultAuthorizationService.cs b/src/Microsoft.AspNet.Security/DefaultAuthorizationService.cs index d20cf6544..943fbce9f 100644 --- a/src/Microsoft.AspNet.Security/DefaultAuthorizationService.cs +++ b/src/Microsoft.AspNet.Security/DefaultAuthorizationService.cs @@ -5,7 +5,6 @@ using System.Linq; using System.Security.Claims; using System.Threading.Tasks; -using Microsoft.AspNet.Http; using Microsoft.Framework.OptionsModel; namespace Microsoft.AspNet.Security @@ -21,47 +20,44 @@ public DefaultAuthorizationService(IOptions options, IEnum _options = options.Options; } - public Task AuthorizeAsync([NotNull] string policyName, HttpContext context, object resource = null) + public bool Authorize(ClaimsPrincipal user, object resource, string policyName) { var policy = _options.GetPolicy(policyName); if (policy == null) { - return Task.FromResult(false); + return false; } - return AuthorizeAsync(policy, context, resource); + return this.Authorize(user, resource, policy); } - public async Task AuthorizeAsync([NotNull] AuthorizationPolicy policy, [NotNull] HttpContext context, object resource = null) + public bool Authorize(ClaimsPrincipal user, object resource, params IAuthorizationRequirement[] requirements) { - var user = context.User; - try + var authContext = new AuthorizationContext(requirements, user, resource); + foreach (var handler in _handlers) { - // Generate the user identities if policy specified the AuthTypes - if (policy.ActiveAuthenticationTypes != null && policy.ActiveAuthenticationTypes.Any() ) - { - var principal = new ClaimsPrincipal(); - - var results = await context.AuthenticateAsync(policy.ActiveAuthenticationTypes); - // REVIEW: re requesting the identities fails for MVC currently, so we only request if not found - foreach (var result in results) - { - principal.AddIdentity(result.Identity); - } - context.User = principal; - } - - var authContext = new AuthorizationContext(policy, context, resource); + handler.Handle(authContext); + } + return authContext.HasSucceeded; + } - foreach (var handler in _handlers) - { - await handler.HandleAsync(authContext); - } - return authContext.HasSucceeded; + public async Task AuthorizeAsync(ClaimsPrincipal user, object resource, params IAuthorizationRequirement[] requirements) + { + var authContext = new AuthorizationContext(requirements, user, resource); + foreach (var handler in _handlers) + { + await handler.HandleAsync(authContext); } - finally + return authContext.HasSucceeded; + } + + public Task AuthorizeAsync(ClaimsPrincipal user, object resource, string policyName) + { + var policy = _options.GetPolicy(policyName); + if (policy == null) { - context.User = user; + return Task.FromResult(false); } + return this.AuthorizeAsync(user, resource, policy); } } } \ No newline at end of file diff --git a/src/Microsoft.AspNet.Security/DenyAnonymousAuthorizationHandler.cs b/src/Microsoft.AspNet.Security/DenyAnonymousAuthorizationHandler.cs index 878a32ec9..952ed30b8 100644 --- a/src/Microsoft.AspNet.Security/DenyAnonymousAuthorizationHandler.cs +++ b/src/Microsoft.AspNet.Security/DenyAnonymousAuthorizationHandler.cs @@ -7,14 +7,17 @@ namespace Microsoft.AspNet.Security { public class DenyAnonymousAuthorizationHandler : AuthorizationHandler { - public override Task CheckAsync(AuthorizationContext context, DenyAnonymousAuthorizationRequirement requirement) + public override void Handle(AuthorizationContext context, DenyAnonymousAuthorizationRequirement requirement) { var user = context.User; var userIsAnonymous = user == null || user.Identity == null || !user.Identity.IsAuthenticated; - return Task.FromResult(!userIsAnonymous); + if (!userIsAnonymous) + { + context.Succeed(requirement); + } } } } diff --git a/src/Microsoft.AspNet.Security/IAuthorizationHandler.cs b/src/Microsoft.AspNet.Security/IAuthorizationHandler.cs index 975a305b8..82eea9ff2 100644 --- a/src/Microsoft.AspNet.Security/IAuthorizationHandler.cs +++ b/src/Microsoft.AspNet.Security/IAuthorizationHandler.cs @@ -8,6 +8,6 @@ namespace Microsoft.AspNet.Security public interface IAuthorizationHandler { Task HandleAsync(AuthorizationContext context); - //void Handle(AuthorizationContext context); + void Handle(AuthorizationContext context); } } diff --git a/src/Microsoft.AspNet.Security/IAuthorizationService.cs b/src/Microsoft.AspNet.Security/IAuthorizationService.cs index 8bcafda3d..317e1ae28 100644 --- a/src/Microsoft.AspNet.Security/IAuthorizationService.cs +++ b/src/Microsoft.AspNet.Security/IAuthorizationService.cs @@ -1,8 +1,8 @@ // Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. +using System.Security.Claims; using System.Threading.Tasks; -using Microsoft.AspNet.Http; namespace Microsoft.AspNet.Security { @@ -11,22 +11,40 @@ namespace Microsoft.AspNet.Security /// public interface IAuthorizationService { + /// + /// Checks if a user meets a specific set of requirements for the specified resource + /// + /// + /// + /// + /// + Task AuthorizeAsync(ClaimsPrincipal user, object resource, params IAuthorizationRequirement[] requirements); + + /// + /// Checks if a user meets a specific set of requirements for the specified resource + /// + /// + /// + /// + /// + bool Authorize(ClaimsPrincipal user, object resource, params IAuthorizationRequirement[] requirements); + /// /// Checks if a user meets a specific authorization policy /// - /// The policy to check against a specific context. - /// The HttpContext to check the policy against. + /// The user to check the policy against. /// The resource the policy should be checked with. + /// The name of the policy to check against a specific context. /// true when the user fulfills the policy, false otherwise. - Task AuthorizeAsync(string policyName, HttpContext context, object resource = null); + Task AuthorizeAsync(ClaimsPrincipal user, object resource, string policyName); /// /// Checks if a user meets a specific authorization policy /// - /// The policy to check against a specific context. - /// The HttpContext to check the policy against. + /// The user to check the policy against. /// The resource the policy should be checked with. + /// The name of the policy to check against a specific context. /// true when the user fulfills the policy, false otherwise. - Task AuthorizeAsync(AuthorizationPolicy policy, HttpContext context, object resource = null); + bool Authorize(ClaimsPrincipal user, object resource, string policyName); } } \ No newline at end of file diff --git a/src/Microsoft.AspNet.Security/OperationAuthorizationRequirement.cs b/src/Microsoft.AspNet.Security/OperationAuthorizationRequirement.cs new file mode 100644 index 000000000..e7e08d195 --- /dev/null +++ b/src/Microsoft.AspNet.Security/OperationAuthorizationRequirement.cs @@ -0,0 +1,10 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +namespace Microsoft.AspNet.Security +{ + public class OperationAuthorizationRequirement : IAuthorizationRequirement + { + public string Name { get; set; } + } +} diff --git a/src/Microsoft.AspNet.Security/PassThroughAuthorizationHandler.cs b/src/Microsoft.AspNet.Security/PassThroughAuthorizationHandler.cs index 837b2f267..a2173f1e0 100644 --- a/src/Microsoft.AspNet.Security/PassThroughAuthorizationHandler.cs +++ b/src/Microsoft.AspNet.Security/PassThroughAuthorizationHandler.cs @@ -10,10 +10,18 @@ public class PassThroughAuthorizationHandler : IAuthorizationHandler { public async Task HandleAsync(AuthorizationContext context) { - foreach (var handler in context.Policy.Requirements.OfType()) + foreach (var handler in context.Requirements.OfType()) { await handler.HandleAsync(context); } } + + public void Handle(AuthorizationContext context) + { + foreach (var handler in context.Requirements.OfType()) + { + handler.Handle(context); + } + } } } diff --git a/src/Microsoft.AspNet.Security/Properties/Resources.Designer.cs b/src/Microsoft.AspNet.Security/Properties/Resources.Designer.cs new file mode 100644 index 000000000..3490d3ea7 --- /dev/null +++ b/src/Microsoft.AspNet.Security/Properties/Resources.Designer.cs @@ -0,0 +1,94 @@ +// +namespace Microsoft.AspNet.Security +{ + using System.Globalization; + using System.Reflection; + using System.Resources; + + internal static class Resources + { + private static readonly ResourceManager _resourceManager + = new ResourceManager("Microsoft.AspNet.Security.Resources", typeof(Resources).GetTypeInfo().Assembly); + + /// + /// The default data protection provider may only be used when the IApplicationBuilder.Properties contains an appropriate 'host.AppName' key. + /// + internal static string Exception_DefaultDpapiRequiresAppNameKey + { + get { return GetString("Exception_DefaultDpapiRequiresAppNameKey"); } + } + + /// + /// The default data protection provider may only be used when the IApplicationBuilder.Properties contains an appropriate 'host.AppName' key. + /// + internal static string FormatException_DefaultDpapiRequiresAppNameKey() + { + return GetString("Exception_DefaultDpapiRequiresAppNameKey"); + } + + /// + /// The state passed to UnhookAuthentication may only be the return value from HookAuthentication. + /// + internal static string Exception_UnhookAuthenticationStateType + { + get { return GetString("Exception_UnhookAuthenticationStateType"); } + } + + /// + /// The state passed to UnhookAuthentication may only be the return value from HookAuthentication. + /// + internal static string FormatException_UnhookAuthenticationStateType() + { + return GetString("Exception_UnhookAuthenticationStateType"); + } + + /// + /// The AuthenticationTokenProvider's required synchronous events have not been registered. + /// + internal static string Exception_AuthenticationTokenDoesNotProvideSyncMethods + { + get { return GetString("Exception_AuthenticationTokenDoesNotProvideSyncMethods"); } + } + + /// + /// The AuthenticationTokenProvider's required synchronous events have not been registered. + /// + internal static string FormatException_AuthenticationTokenDoesNotProvideSyncMethods() + { + return GetString("Exception_AuthenticationTokenDoesNotProvideSyncMethods"); + } + + /// + /// The AuthorizationPolicy named: '{0}' was not found. + /// + internal static string Exception_AuthorizationPolicyNotFound + { + get { return GetString("Exception_AuthorizationPolicyNotFound"); } + } + + /// + /// The AuthorizationPolicy named: '{0}' was not found. + /// + internal static string FormatException_AuthorizationPolicyNotFound(object p0) + { + return string.Format(CultureInfo.CurrentCulture, GetString("Exception_AuthorizationPolicyNotFound"), p0); + } + + private static string GetString(string name, params string[] formatterNames) + { + var value = _resourceManager.GetString(name); + + System.Diagnostics.Debug.Assert(value != null); + + if (formatterNames != null) + { + for (var i = 0; i < formatterNames.Length; i++) + { + value = value.Replace("{" + formatterNames[i] + "}", "{" + i + "}"); + } + } + + return value; + } + } +} diff --git a/src/Microsoft.AspNet.Security/Resources.Designer.cs b/src/Microsoft.AspNet.Security/Resources.Designer.cs deleted file mode 100644 index 485da1825..000000000 --- a/src/Microsoft.AspNet.Security/Resources.Designer.cs +++ /dev/null @@ -1,99 +0,0 @@ -//------------------------------------------------------------------------------ -// -// This code was generated by a tool. -// Runtime Version:4.0.30319.34003 -// -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace Microsoft.AspNet.Security { - using System; - - - /// - /// A strongly-typed resource class, for looking up localized strings, etc. - /// - // This class was auto-generated by the StronglyTypedResourceBuilder - // class via a tool like ResGen or Visual Studio. - // To add or remove a member, edit your .ResX file then rerun ResGen - // with the /str option, or rebuild your VS project. - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - internal class Resources { - - private static global::System.Resources.ResourceManager resourceMan; - - private static global::System.Globalization.CultureInfo resourceCulture; - - [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - internal Resources() { - } - - /// - /// Returns the cached ResourceManager instance used by this class. - /// - [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Resources.ResourceManager ResourceManager { - get { - if (object.ReferenceEquals(resourceMan, null)) { - global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Microsoft.AspNet.Security.Resources", System.Reflection.IntrospectionExtensions.GetTypeInfo(typeof(Resources)).Assembly); - resourceMan = temp; - } - return resourceMan; - } - } - - /// - /// Overrides the current thread's CurrentUICulture property for all - /// resource lookups using this strongly typed resource class. - /// - [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Globalization.CultureInfo Culture { - get { - return resourceCulture; - } - set { - resourceCulture = value; - } - } - - /// - /// Looks up a localized string similar to The AuthenticationTokenProvider's required synchronous events have not been registered.. - /// - internal static string Exception_AuthenticationTokenDoesNotProvideSyncMethods { - get { - return ResourceManager.GetString("Exception_AuthenticationTokenDoesNotProvideSyncMethods", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to The default data protection provider may only be used when the IApplicationBuilder.Properties contains an appropriate 'host.AppName' key.. - /// - internal static string Exception_DefaultDpapiRequiresAppNameKey { - get { - return ResourceManager.GetString("Exception_DefaultDpapiRequiresAppNameKey", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to A default value for SignInAsAuthenticationType was not found in IApplicationBuilder Properties. This can happen if your authentication middleware are added in the wrong order, or if one is missing.. - /// - internal static string Exception_MissingDefaultSignInAsAuthenticationType { - get { - return ResourceManager.GetString("Exception_MissingDefaultSignInAsAuthenticationType", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to The state passed to UnhookAuthentication may only be the return value from HookAuthentication.. - /// - internal static string Exception_UnhookAuthenticationStateType { - get { - return ResourceManager.GetString("Exception_UnhookAuthenticationStateType", resourceCulture); - } - } - } -} diff --git a/src/Microsoft.AspNet.Security/Resources.resx b/src/Microsoft.AspNet.Security/Resources.resx index 77060045e..3e72c4a2c 100644 --- a/src/Microsoft.AspNet.Security/Resources.resx +++ b/src/Microsoft.AspNet.Security/Resources.resx @@ -126,4 +126,7 @@ The AuthenticationTokenProvider's required synchronous events have not been registered. + + The AuthorizationPolicy named: '{0}' was not found. + \ No newline at end of file diff --git a/src/Microsoft.AspNet.Security/ServiceCollectionExtensions.cs b/src/Microsoft.AspNet.Security/ServiceCollectionExtensions.cs index 41b0978cd..2cb0f5aca 100644 --- a/src/Microsoft.AspNet.Security/ServiceCollectionExtensions.cs +++ b/src/Microsoft.AspNet.Security/ServiceCollectionExtensions.cs @@ -9,6 +9,11 @@ namespace Microsoft.Framework.DependencyInjection { public static class ServiceCollectionExtensions { + public static IServiceCollection ConfigureClaimsTransformation([NotNull] this IServiceCollection services, [NotNull] Action configure) + { + return services.Configure(configure); + } + public static IServiceCollection ConfigureAuthorization([NotNull] this IServiceCollection services, [NotNull] Action configure) { return services.Configure(configure); diff --git a/test/Microsoft.AspNet.Security.Test/AuthorizationPolicyFacts.cs b/test/Microsoft.AspNet.Security.Test/AuthorizationPolicyFacts.cs new file mode 100644 index 000000000..57c71dde4 --- /dev/null +++ b/test/Microsoft.AspNet.Security.Test/AuthorizationPolicyFacts.cs @@ -0,0 +1,37 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System.Linq; +using Xunit; + +namespace Microsoft.AspNet.Security.Test +{ + public class AuthorizationPolicyFacts + { + [Fact] + public void CanCombineAuthorizeAttributes() + { + // Arrange + var attributes = new AuthorizeAttribute[] { + new AuthorizeAttribute(), + new AuthorizeAttribute("1") { ActiveAuthenticationTypes = "dupe" }, + new AuthorizeAttribute("2") { ActiveAuthenticationTypes = "dupe" }, + new AuthorizeAttribute { Roles = "r1,r2", ActiveAuthenticationTypes = "roles" }, + }; + var options = new AuthorizationOptions(); + options.AddPolicy("1", policy => policy.RequiresClaim("1")); + options.AddPolicy("2", policy => policy.RequiresClaim("2")); + + // Act + var combined = AuthorizationPolicy.Combine(options, attributes); + + // Assert + Assert.Equal(2, combined.ActiveAuthenticationTypes.Count()); + Assert.True(combined.ActiveAuthenticationTypes.Contains("dupe")); + Assert.True(combined.ActiveAuthenticationTypes.Contains("roles")); + Assert.Equal(4, combined.Requirements.Count()); + Assert.True(combined.Requirements.Any(r => r is DenyAnonymousAuthorizationRequirement)); + Assert.Equal(3, combined.Requirements.OfType().Count()); + } + } +} \ No newline at end of file diff --git a/test/Microsoft.AspNet.Security.Test/DefaultAuthorizationServiceTests.cs b/test/Microsoft.AspNet.Security.Test/DefaultAuthorizationServiceTests.cs index 1ba705439..9beae1c6d 100644 --- a/test/Microsoft.AspNet.Security.Test/DefaultAuthorizationServiceTests.cs +++ b/test/Microsoft.AspNet.Security.Test/DefaultAuthorizationServiceTests.cs @@ -3,13 +3,11 @@ using System; using System.Collections.Generic; +using System.Linq; using System.Security.Claims; using System.Threading.Tasks; -using Microsoft.AspNet.Http; -using Microsoft.AspNet.Http.Security; using Microsoft.Framework.DependencyInjection; using Microsoft.Framework.DependencyInjection.Fallback; -using Moq; using Xunit; namespace Microsoft.AspNet.Security.Test @@ -27,23 +25,12 @@ private IAuthorizationService BuildAuthorizationService(Action(); } - private Mock SetupContext(params ClaimsIdentity[] ids) + [Fact] + public void AuthorizeCombineThrowsOnUnknownPolicy() { - var context = new Mock(); - context.SetupProperty(c => c.User); - var user = new ClaimsPrincipal(); - user.AddIdentities(ids); - context.Object.User = user; - if (ids != null) - { - var results = new List(); - foreach (var id in ids) - { - results.Add(new AuthenticationResult(id, new AuthenticationProperties(), new AuthenticationDescription())); - } - context.Setup(c => c.AuthenticateAsync(It.IsAny>())).ReturnsAsync(results).Verifiable(); - } - return context; + Assert.Throws(() => AuthorizationPolicy.Combine(new AuthorizationOptions(), new AuthorizeAttribute[] { + new AuthorizeAttribute { Policy = "Wut" } + })); } [Fact] @@ -57,10 +44,10 @@ public async Task Authorize_ShouldAllowIfClaimIsPresent() options.AddPolicy("Basic", policy => policy.RequiresClaim("Permission", "CanViewPage")); }); }); - var context = SetupContext(new ClaimsIdentity(new Claim[] { new Claim("Permission", "CanViewPage") }, "Basic")); + var user = new ClaimsPrincipal(new ClaimsIdentity(new Claim[] { new Claim("Permission", "CanViewPage") }, "Basic")); // Act - var allowed = await authorizationService.AuthorizeAsync("Basic", context.Object); + var allowed = await authorizationService.AuthorizeAsync(user, null, "Basic"); // Assert Assert.True(allowed); @@ -77,10 +64,10 @@ public async Task Authorize_ShouldAllowIfClaimIsPresentWithSpecifiedAuthType() options.AddPolicy("Basic", policy => policy.RequiresClaim("Permission", "CanViewPage")); }); }); - var context = SetupContext(new ClaimsIdentity(new Claim[] { new Claim("Permission", "CanViewPage") }, "Basic")); + var user = new ClaimsPrincipal(new ClaimsIdentity(new Claim[] { new Claim("Permission", "CanViewPage") }, "Basic")); // Act - var allowed = await authorizationService.AuthorizeAsync("Basic", context.Object); + var allowed = await authorizationService.AuthorizeAsync(user, null, "Basic"); // Assert Assert.True(allowed); @@ -97,7 +84,7 @@ public async Task Authorize_ShouldAllowIfClaimIsAmongValues() options.AddPolicy("Basic", policy => policy.RequiresClaim("Permission", "CanViewPage", "CanViewAnything")); }); }); - var context = SetupContext( + var user = new ClaimsPrincipal( new ClaimsIdentity( new Claim[] { new Claim("Permission", "CanViewPage"), @@ -107,7 +94,7 @@ public async Task Authorize_ShouldAllowIfClaimIsAmongValues() ); // Act - var allowed = await authorizationService.AuthorizeAsync("Basic", context.Object); + var allowed = await authorizationService.AuthorizeAsync(user, null, "Basic"); // Assert Assert.True(allowed); @@ -124,7 +111,7 @@ public async Task Authorize_ShouldFailWhenAllRequirementsNotHandled() options.AddPolicy("Basic", policy => policy.RequiresClaim("Permission", "CanViewPage", "CanViewAnything")); }); }); - var context = SetupContext( + var user = new ClaimsPrincipal( new ClaimsIdentity( new Claim[] { new Claim("SomethingElse", "CanViewPage"), @@ -133,7 +120,7 @@ public async Task Authorize_ShouldFailWhenAllRequirementsNotHandled() ); // Act - var allowed = await authorizationService.AuthorizeAsync("Basic", context.Object); + var allowed = await authorizationService.AuthorizeAsync(user, null, "Basic"); // Assert Assert.False(allowed); @@ -150,7 +137,7 @@ public async Task Authorize_ShouldNotAllowIfClaimTypeIsNotPresent() options.AddPolicy("Basic", policy => policy.RequiresClaim("Permission", "CanViewPage", "CanViewAnything")); }); }); - var context = SetupContext( + var user = new ClaimsPrincipal( new ClaimsIdentity( new Claim[] { new Claim("SomethingElse", "CanViewPage"), @@ -159,7 +146,7 @@ public async Task Authorize_ShouldNotAllowIfClaimTypeIsNotPresent() ); // Act - var allowed = await authorizationService.AuthorizeAsync("Basic", context.Object); + var allowed = await authorizationService.AuthorizeAsync(user, null, "Basic"); // Assert Assert.False(allowed); @@ -176,7 +163,7 @@ public async Task Authorize_ShouldNotAllowIfClaimValueIsNotPresent() options.AddPolicy("Basic", policy => policy.RequiresClaim("Permission", "CanViewPage")); }); }); - var context = SetupContext( + var user = new ClaimsPrincipal( new ClaimsIdentity( new Claim[] { new Claim("Permission", "CanViewComment"), @@ -185,7 +172,7 @@ public async Task Authorize_ShouldNotAllowIfClaimValueIsNotPresent() ); // Act - var allowed = await authorizationService.AuthorizeAsync("Basic", context.Object); + var allowed = await authorizationService.AuthorizeAsync(user, null, "Basic"); // Assert Assert.False(allowed); @@ -202,14 +189,14 @@ public async Task Authorize_ShouldNotAllowIfNoClaims() options.AddPolicy("Basic", policy => policy.RequiresClaim("Permission", "CanViewPage")); }); }); - var context = SetupContext( + var user = new ClaimsPrincipal( new ClaimsIdentity( new Claim[0], "Basic") ); // Act - var allowed = await authorizationService.AuthorizeAsync("Basic", context.Object); + var allowed = await authorizationService.AuthorizeAsync(user, null, "Basic"); // Assert Assert.False(allowed); @@ -226,11 +213,9 @@ public async Task Authorize_ShouldNotAllowIfUserIsNull() options.AddPolicy("Basic", policy => policy.RequiresClaim("Permission", "CanViewPage")); }); }); - var context = SetupContext(); - context.Object.User = null; // Act - var allowed = await authorizationService.AuthorizeAsync("Basic", context.Object); + var allowed = await authorizationService.AuthorizeAsync(null, null, "Basic"); // Assert Assert.False(allowed); @@ -247,10 +232,10 @@ public async Task Authorize_ShouldNotAllowIfNotCorrectAuthType() options.AddPolicy("Basic", policy => policy.RequiresClaim("Permission", "CanViewPage")); }); }); - var context = SetupContext(new ClaimsIdentity()); + var user = new ClaimsPrincipal(new ClaimsIdentity()); // Act - var allowed = await authorizationService.AuthorizeAsync("Basic", context.Object); + var allowed = await authorizationService.AuthorizeAsync(user, null, "Basic"); // Assert Assert.False(allowed); @@ -267,7 +252,7 @@ public async Task Authorize_ShouldAllowWithNoAuthType() options.AddPolicy("Basic", policy => policy.RequiresClaim("Permission", "CanViewPage")); }); }); - var context = SetupContext( + var user = new ClaimsPrincipal( new ClaimsIdentity( new Claim[] { new Claim("Permission", "CanViewPage"), @@ -276,7 +261,7 @@ public async Task Authorize_ShouldAllowWithNoAuthType() ); // Act - var allowed = await authorizationService.AuthorizeAsync("Basic", context.Object); + var allowed = await authorizationService.AuthorizeAsync(user, null, "Basic"); // Assert Assert.True(allowed); @@ -287,7 +272,7 @@ public async Task Authorize_ShouldNotAllowIfUnknownPolicy() { // Arrange var authorizationService = BuildAuthorizationService(); - var context = SetupContext( + var user = new ClaimsPrincipal( new ClaimsIdentity( new Claim[] { new Claim("Permission", "CanViewComment"), @@ -296,7 +281,7 @@ public async Task Authorize_ShouldNotAllowIfUnknownPolicy() ); // Act - var allowed = await authorizationService.AuthorizeAsync("Basic", context.Object); + var allowed = await authorizationService.AuthorizeAsync(user, null, "Basic"); // Assert Assert.False(allowed); @@ -309,7 +294,7 @@ public async Task Authorize_CustomRolePolicy() var policy = new AuthorizationPolicyBuilder().RequiresRole("Administrator") .RequiresClaim(ClaimTypes.Role, "User"); var authorizationService = BuildAuthorizationService(); - var context = SetupContext( + var user = new ClaimsPrincipal( new ClaimsIdentity( new Claim[] { new Claim(ClaimTypes.Role, "User"), @@ -319,7 +304,7 @@ public async Task Authorize_CustomRolePolicy() ); // Act - var allowed = await authorizationService.AuthorizeAsync(policy.Build(), context.Object); + var allowed = await authorizationService.AuthorizeAsync(user, null, policy.Build()); // Assert Assert.True(allowed); @@ -331,7 +316,7 @@ public async Task Authorize_HasAnyClaimOfTypePolicy() // Arrange var policy = new AuthorizationPolicyBuilder().RequiresClaim(ClaimTypes.Role); var authorizationService = BuildAuthorizationService(); - var context = SetupContext( + var user = new ClaimsPrincipal( new ClaimsIdentity( new Claim[] { new Claim(ClaimTypes.Role, ""), @@ -340,7 +325,7 @@ public async Task Authorize_HasAnyClaimOfTypePolicy() ); // Act - var allowed = await authorizationService.AuthorizeAsync(policy.Build(), context.Object); + var allowed = await authorizationService.AuthorizeAsync(user, null, policy.Build()); // Assert Assert.True(allowed); @@ -352,12 +337,46 @@ public async Task Authorize_PolicyCanAuthenticationTypeWithNameClaim() // Arrange var policy = new AuthorizationPolicyBuilder("AuthType").RequiresClaim(ClaimTypes.Name); var authorizationService = BuildAuthorizationService(); - var context = SetupContext( + var user = new ClaimsPrincipal( new ClaimsIdentity(new Claim[] { new Claim(ClaimTypes.Name, "Name") }, "AuthType") ); // Act - var allowed = await authorizationService.AuthorizeAsync(policy.Build(), context.Object); + var allowed = await authorizationService.AuthorizeAsync(user, null, policy.Build()); + + // Assert + Assert.True(allowed); + } + + [Fact] + public async Task Authorize_PolicyWillFilterAuthenticationType() + { + // Arrange + var policy = new AuthorizationPolicyBuilder("Bogus").RequiresClaim(ClaimTypes.Name); + var authorizationService = BuildAuthorizationService(); + var user = new ClaimsPrincipal( + new ClaimsIdentity(new Claim[] { new Claim(ClaimTypes.Name, "Name") }, "AuthType") + ); + + // Act + var allowed = await authorizationService.AuthorizeAsync(user, null, policy.Build()); + + // Assert + Assert.False(allowed); + } + + [Fact] + public async Task Authorize_PolicyCanFilterMultipleAuthenticationType() + { + // Arrange + var policy = new AuthorizationPolicyBuilder("One", "Two").RequiresClaim(ClaimTypes.Name, "one").RequiresClaim(ClaimTypes.Name, "two"); + var authorizationService = BuildAuthorizationService(); + var user = new ClaimsPrincipal(); + user.AddIdentity(new ClaimsIdentity(new Claim[] { new Claim(ClaimTypes.Name, "one") }, "One")); + user.AddIdentity(new ClaimsIdentity(new Claim[] { new Claim(ClaimTypes.Name, "two") }, "Two")); + + // Act + var allowed = await authorizationService.AuthorizeAsync(user, null, policy.Build()); // Assert Assert.True(allowed); @@ -369,12 +388,12 @@ public async Task RolePolicyCanRequireSingleRole() // Arrange var policy = new AuthorizationPolicyBuilder("AuthType").RequiresRole("Admin"); var authorizationService = BuildAuthorizationService(); - var context = SetupContext( + var user = new ClaimsPrincipal( new ClaimsIdentity(new Claim[] { new Claim(ClaimTypes.Role, "Admin") }, "AuthType") ); // Act - var allowed = await authorizationService.AuthorizeAsync(policy.Build(), context.Object); + var allowed = await authorizationService.AuthorizeAsync(user, null, policy.Build()); // Assert Assert.True(allowed); @@ -386,11 +405,11 @@ public async Task RolePolicyCanRequireOneOfManyRoles() // Arrange var policy = new AuthorizationPolicyBuilder("AuthType").RequiresRole("Admin", "Users"); var authorizationService = BuildAuthorizationService(); - var context = SetupContext( + var user = new ClaimsPrincipal( new ClaimsIdentity(new Claim[] { new Claim(ClaimTypes.Role, "Users") }, "AuthType")); // Act - var allowed = await authorizationService.AuthorizeAsync(policy.Build(), context.Object); + var allowed = await authorizationService.AuthorizeAsync(user, null, policy.Build()); // Assert Assert.True(allowed); @@ -402,7 +421,7 @@ public async Task RolePolicyCanBlockWrongRole() // Arrange var policy = new AuthorizationPolicyBuilder().RequiresClaim("Permission", "CanViewPage"); var authorizationService = BuildAuthorizationService(); - var context = SetupContext( + var user = new ClaimsPrincipal( new ClaimsIdentity( new Claim[] { new Claim(ClaimTypes.Role, "Nope"), @@ -411,7 +430,7 @@ public async Task RolePolicyCanBlockWrongRole() ); // Act - var allowed = await authorizationService.AuthorizeAsync(policy.Build(), context.Object); + var allowed = await authorizationService.AuthorizeAsync(user, null, policy.Build()); // Assert Assert.False(allowed); @@ -428,7 +447,7 @@ public async Task RolePolicyCanBlockNoRole() options.AddPolicy("Basic", policy => policy.RequiresRole("Admin", "Users")); }); }); - var context = SetupContext( + var user = new ClaimsPrincipal( new ClaimsIdentity( new Claim[] { }, @@ -436,7 +455,7 @@ public async Task RolePolicyCanBlockNoRole() ); // Act - var allowed = await authorizationService.AuthorizeAsync("Basic", context.Object); + var allowed = await authorizationService.AuthorizeAsync(user, null, "Basic"); // Assert Assert.False(allowed); @@ -453,7 +472,7 @@ public async Task PolicyFailsWithNoRequirements() options.AddPolicy("Basic", policy => { }); }); }); - var context = SetupContext( + var user = new ClaimsPrincipal( new ClaimsIdentity( new Claim[] { new Claim(ClaimTypes.Name, "Name"), @@ -462,7 +481,7 @@ public async Task PolicyFailsWithNoRequirements() ); // Act - var allowed = await authorizationService.AuthorizeAsync("Basic", context.Object); + var allowed = await authorizationService.AuthorizeAsync(user, null, "Basic"); // Assert Assert.False(allowed); @@ -479,7 +498,7 @@ public async Task CanApproveAnyAuthenticatedUser() options.AddPolicy("Any", policy => policy.RequireAuthenticatedUser()); }); }); - var context = SetupContext( + var user = new ClaimsPrincipal( new ClaimsIdentity( new Claim[] { new Claim(ClaimTypes.Name, "Name"), @@ -488,7 +507,7 @@ public async Task CanApproveAnyAuthenticatedUser() ); // Act - var allowed = await authorizationService.AuthorizeAsync("Any", context.Object); + var allowed = await authorizationService.AuthorizeAsync(user, null, "Any"); // Assert Assert.True(allowed); @@ -505,10 +524,10 @@ public async Task CanBlockNonAuthenticatedUser() options.AddPolicy("Any", policy => policy.RequireAuthenticatedUser()); }); }); - var context = SetupContext(new ClaimsIdentity()); + var user = new ClaimsPrincipal(new ClaimsIdentity()); // Act - var allowed = await authorizationService.AuthorizeAsync("Any", context.Object); + var allowed = await authorizationService.AuthorizeAsync(user, null, "Any"); // Assert Assert.False(allowed); @@ -517,9 +536,9 @@ public async Task CanBlockNonAuthenticatedUser() public class CustomRequirement : IAuthorizationRequirement { } public class CustomHandler : AuthorizationHandler { - public override Task CheckAsync(AuthorizationContext context, CustomRequirement requirement) + public override void Handle(AuthorizationContext context, CustomRequirement requirement) { - return Task.FromResult(true); + context.Succeed(requirement); } } @@ -534,10 +553,10 @@ public async Task CustomReqWithNoHandlerFails() options.AddPolicy("Custom", policy => policy.Requirements.Add(new CustomRequirement())); }); }); - var context = SetupContext(); + var user = new ClaimsPrincipal(); // Act - var allowed = await authorizationService.AuthorizeAsync("Custom", context.Object); + var allowed = await authorizationService.AuthorizeAsync(user, null, "Custom"); // Assert Assert.False(allowed); @@ -555,10 +574,10 @@ public async Task CustomReqWithHandlerSucceeds() options.AddPolicy("Custom", policy => policy.Requirements.Add(new CustomRequirement())); }); }); - var context = SetupContext(); + var user = new ClaimsPrincipal(); // Act - var allowed = await authorizationService.AuthorizeAsync("Custom", context.Object); + var allowed = await authorizationService.AuthorizeAsync(user, null, "Custom"); // Assert Assert.True(allowed); @@ -573,9 +592,11 @@ public PassThroughRequirement(bool succeed) public bool Succeed { get; set; } - public override Task CheckAsync(AuthorizationContext context, PassThroughRequirement requirement) + public override void Handle(AuthorizationContext context, PassThroughRequirement requirement) { - return Task.FromResult(Succeed); + if (Succeed) { + context.Succeed(requirement); + } } } @@ -592,10 +613,10 @@ public async Task PassThroughRequirementWillSucceedWithoutCustomHandler(bool sho options.AddPolicy("Passthrough", policy => policy.Requirements.Add(new PassThroughRequirement(shouldSucceed))); }); }); - var context = SetupContext(); + var user = new ClaimsPrincipal(); // Act - var allowed = await authorizationService.AuthorizeAsync("Passthrough", context.Object); + var allowed = await authorizationService.AuthorizeAsync(user, null, "Passthrough"); // Assert Assert.Equal(shouldSucceed, allowed); @@ -609,10 +630,10 @@ public async Task CanCombinePolicies() services.ConfigureAuthorization(options => { var basePolicy = new AuthorizationPolicyBuilder().RequiresClaim("Base", "Value").Build(); - options.AddPolicy("Combineed", policy => policy.Combine(basePolicy).RequiresClaim("Claim", "Exists")); + options.AddPolicy("Combined", policy => policy.Combine(basePolicy).RequiresClaim("Claim", "Exists")); }); }); - var context = SetupContext( + var user = new ClaimsPrincipal( new ClaimsIdentity( new Claim[] { new Claim("Base", "Value"), @@ -622,7 +643,7 @@ public async Task CanCombinePolicies() ); // Act - var allowed = await authorizationService.AuthorizeAsync("Combined", context.Object); + var allowed = await authorizationService.AuthorizeAsync(user, null, "Combined"); // Assert Assert.True(allowed); @@ -639,7 +660,7 @@ public async Task CombinePoliciesWillFailIfBasePolicyFails() options.AddPolicy("Combined", policy => policy.Combine(basePolicy).RequiresClaim("Claim", "Exists")); }); }); - var context = SetupContext( + var user = new ClaimsPrincipal( new ClaimsIdentity( new Claim[] { new Claim("Claim", "Exists") @@ -648,7 +669,7 @@ public async Task CombinePoliciesWillFailIfBasePolicyFails() ); // Act - var allowed = await authorizationService.AuthorizeAsync("Combined", context.Object); + var allowed = await authorizationService.AuthorizeAsync(user, null, "Combined"); // Assert Assert.False(allowed); @@ -665,7 +686,7 @@ public async Task CombinedPoliciesWillFailIfExtraRequirementFails() options.AddPolicy("Combined", policy => policy.Combine(basePolicy).RequiresClaim("Claim", "Exists")); }); }); - var context = SetupContext( + var user = new ClaimsPrincipal( new ClaimsIdentity( new Claim[] { new Claim("Base", "Value"), @@ -674,10 +695,88 @@ public async Task CombinedPoliciesWillFailIfExtraRequirementFails() ); // Act - var allowed = await authorizationService.AuthorizeAsync("Combined", context.Object); + var allowed = await authorizationService.AuthorizeAsync(user, null, "Combined"); // Assert Assert.False(allowed); } + + public class ExpenseReport { } + + public static class Operations + { + public static OperationAuthorizationRequirement Edit = new OperationAuthorizationRequirement { Name = "Edit" }; + public static OperationAuthorizationRequirement Create = new OperationAuthorizationRequirement { Name = "Create" }; + public static OperationAuthorizationRequirement Delete = new OperationAuthorizationRequirement { Name = "Delete" }; + } + + public class ExpenseReportAuthorizationHandler : AuthorizationHandler + { + public ExpenseReportAuthorizationHandler(IEnumerable authorized) + { + _allowed = authorized; + } + + private IEnumerable _allowed; + + public override void Handle(AuthorizationContext context, OperationAuthorizationRequirement requirement, ExpenseReport resource) + { + if (_allowed.Contains(requirement)) + { + context.Succeed(requirement); + } + } + } + + public class SuperUserHandler : AuthorizationHandler + { + public override void Handle(AuthorizationContext context, OperationAuthorizationRequirement requirement) + { + if (context.User.HasClaim("SuperUser", "yes")) + { + context.Succeed(requirement); + } + } + } + + public async Task CanAuthorizeAllSuperuserOperations() + { + // Arrange + var authorizationService = BuildAuthorizationService(services => + { + services.AddInstance(new ExpenseReportAuthorizationHandler(new OperationAuthorizationRequirement[] { Operations.Edit })); + services.AddTransient(); + }); + var user = new ClaimsPrincipal( + new ClaimsIdentity( + new Claim[] { + new Claim("SuperUser", "yes"), + }, + "AuthType") + ); + + // Act + // Assert + Assert.True(await authorizationService.AuthorizeAsync(user, null, Operations.Edit)); + Assert.True(await authorizationService.AuthorizeAsync(user, null, Operations.Delete)); + Assert.True(await authorizationService.AuthorizeAsync(user, null, Operations.Create)); + } + + public async Task CanAuthorizeOnlyAllowedOperations() + { + // Arrange + var authorizationService = BuildAuthorizationService(services => + { + services.AddInstance(new ExpenseReportAuthorizationHandler(new OperationAuthorizationRequirement[] { Operations.Edit })); + services.AddTransient(); + }); + var user = new ClaimsPrincipal(); + + // Act + // Assert + Assert.True(await authorizationService.AuthorizeAsync(user, null, Operations.Edit)); + Assert.False(await authorizationService.AuthorizeAsync(user, null, Operations.Delete)); + Assert.False(await authorizationService.AuthorizeAsync(user, null, Operations.Create)); + } } } \ No newline at end of file From a15cb4ffe559d2c7bb2f0e748e4a10446bd530a6 Mon Sep 17 00:00:00 2001 From: Levi B Date: Tue, 17 Feb 2015 11:08:12 -0800 Subject: [PATCH 136/216] React to HttpRequest.IsSecure renaming --- .../CookieAuthenticationHandler.cs | 2 +- .../OpenidConnectAuthenticationHandler.cs | 4 ++-- .../TwitterAuthenticationHandler.cs | 4 ++-- .../Infrastructure/AuthenticationHandler.cs | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/Microsoft.AspNet.Security.Cookies/CookieAuthenticationHandler.cs b/src/Microsoft.AspNet.Security.Cookies/CookieAuthenticationHandler.cs index e29023257..c8f964ee7 100644 --- a/src/Microsoft.AspNet.Security.Cookies/CookieAuthenticationHandler.cs +++ b/src/Microsoft.AspNet.Security.Cookies/CookieAuthenticationHandler.cs @@ -150,7 +150,7 @@ protected override async Task ApplyResponseGrantAsync() }; if (Options.CookieSecure == CookieSecureOption.SameAsRequest) { - cookieOptions.Secure = Request.IsSecure; + cookieOptions.Secure = Request.IsHttps; } else { diff --git a/src/Microsoft.AspNet.Security.OpenIdConnect/OpenidConnectAuthenticationHandler.cs b/src/Microsoft.AspNet.Security.OpenIdConnect/OpenidConnectAuthenticationHandler.cs index b30346e85..b51eb5903 100644 --- a/src/Microsoft.AspNet.Security.OpenIdConnect/OpenidConnectAuthenticationHandler.cs +++ b/src/Microsoft.AspNet.Security.OpenIdConnect/OpenidConnectAuthenticationHandler.cs @@ -472,7 +472,7 @@ private void RememberNonce(string nonce) new CookieOptions { HttpOnly = true, - Secure = Request.IsSecure + Secure = Request.IsHttps }); } @@ -502,7 +502,7 @@ private string RetrieveNonce(string nonceExpectedValue) var cookieOptions = new CookieOptions { HttpOnly = true, - Secure = Request.IsSecure + Secure = Request.IsHttps }; Response.Cookies.Delete(nonceKey, cookieOptions); diff --git a/src/Microsoft.AspNet.Security.Twitter/TwitterAuthenticationHandler.cs b/src/Microsoft.AspNet.Security.Twitter/TwitterAuthenticationHandler.cs index 46dcd43f4..b16c4a218 100644 --- a/src/Microsoft.AspNet.Security.Twitter/TwitterAuthenticationHandler.cs +++ b/src/Microsoft.AspNet.Security.Twitter/TwitterAuthenticationHandler.cs @@ -108,7 +108,7 @@ protected override async Task AuthenticateCoreAsync() var cookieOptions = new CookieOptions { HttpOnly = true, - Secure = Request.IsSecure + Secure = Request.IsHttps }; Response.Cookies.Delete(StateCookie, cookieOptions); @@ -167,7 +167,7 @@ protected override async Task ApplyResponseChallengeAsync() var cookieOptions = new CookieOptions { HttpOnly = true, - Secure = Request.IsSecure + Secure = Request.IsHttps }; Response.Cookies.Append(StateCookie, Options.StateDataFormat.Protect(requestToken), cookieOptions); diff --git a/src/Microsoft.AspNet.Security/Infrastructure/AuthenticationHandler.cs b/src/Microsoft.AspNet.Security/Infrastructure/AuthenticationHandler.cs index fc847f4fa..92b7889d5 100644 --- a/src/Microsoft.AspNet.Security/Infrastructure/AuthenticationHandler.cs +++ b/src/Microsoft.AspNet.Security/Infrastructure/AuthenticationHandler.cs @@ -393,7 +393,7 @@ protected void GenerateCorrelationId([NotNull] AuthenticationProperties properti var cookieOptions = new CookieOptions { HttpOnly = true, - Secure = Request.IsSecure + Secure = Request.IsHttps }; properties.Dictionary[correlationKey] = correlationId; @@ -415,7 +415,7 @@ protected bool ValidateCorrelationId([NotNull] AuthenticationProperties properti var cookieOptions = new CookieOptions { HttpOnly = true, - Secure = Request.IsSecure + Secure = Request.IsHttps }; Response.Cookies.Delete(correlationKey, cookieOptions); From d864b725619cedab51d625a597d5cec0ea03e77b Mon Sep 17 00:00:00 2001 From: Levi B Date: Wed, 25 Feb 2015 17:11:21 -0800 Subject: [PATCH 137/216] React to DataProtection rename --- samples/SocialSample/Startup.cs | 2 +- .../CookieAuthenticationMiddleware.cs | 4 ++-- .../FacebookAuthenticationMiddleware.cs | 2 +- .../GoogleAuthenticationMiddleware.cs | 2 +- .../MicrosoftAccountAuthenticationMiddleware.cs | 2 +- .../OAuthAuthenticationMiddleware.cs | 12 ++++++------ src/Microsoft.AspNet.Security.OAuth/project.json | 4 ++-- .../OAuthBearerAuthenticationMiddleware.cs | 1 - .../OpenIdConnectAuthenticationMiddleware.cs | 6 +++--- .../TwitterAuthenticationMiddleware.cs | 4 ++-- .../DataHandler/PropertiesDataFormat.cs | 2 +- .../DataHandler/SecureDataFormat.cs | 2 +- .../DataHandler/TicketDataFormat.cs | 2 +- .../DataProtection/DataProtectionHelpers.cs | 13 ------------- src/Microsoft.AspNet.Security/project.json | 2 +- .../Facebook/FacebookMiddlewareTests.cs | 1 - .../Google/GoogleMiddlewareTests.cs | 8 ++++---- .../MicrosoftAccountMiddlewareTests.cs | 8 ++++---- .../OpenIdConnect/OpenIdConnectMiddlewareTests.cs | 2 +- .../Twitter/TwitterMiddlewareTests.cs | 6 +++--- 20 files changed, 35 insertions(+), 50 deletions(-) delete mode 100644 src/Microsoft.AspNet.Security/DataProtection/DataProtectionHelpers.cs diff --git a/samples/SocialSample/Startup.cs b/samples/SocialSample/Startup.cs index 6e7b5c632..d0b8d9280 100644 --- a/samples/SocialSample/Startup.cs +++ b/samples/SocialSample/Startup.cs @@ -2,11 +2,11 @@ using System.Net.Http.Headers; using System.Security.Claims; using Microsoft.AspNet.Builder; +using Microsoft.AspNet.DataProtection; using Microsoft.AspNet.Http; using Microsoft.AspNet.Http.Security; using Microsoft.AspNet.Security; using Microsoft.AspNet.Security.Cookies; -using Microsoft.AspNet.Security.DataProtection; using Microsoft.AspNet.Security.Google; using Microsoft.AspNet.Security.MicrosoftAccount; using Microsoft.AspNet.Security.OAuth; diff --git a/src/Microsoft.AspNet.Security.Cookies/CookieAuthenticationMiddleware.cs b/src/Microsoft.AspNet.Security.Cookies/CookieAuthenticationMiddleware.cs index 8f1cc4b54..ba8136559 100644 --- a/src/Microsoft.AspNet.Security.Cookies/CookieAuthenticationMiddleware.cs +++ b/src/Microsoft.AspNet.Security.Cookies/CookieAuthenticationMiddleware.cs @@ -4,9 +4,9 @@ using System; using Microsoft.AspNet.Builder; +using Microsoft.AspNet.DataProtection; using Microsoft.AspNet.Security.Cookies.Infrastructure; using Microsoft.AspNet.Security.DataHandler; -using Microsoft.AspNet.Security.DataProtection; using Microsoft.AspNet.Security.Infrastructure; using Microsoft.Framework.Logging; using Microsoft.Framework.OptionsModel; @@ -35,7 +35,7 @@ public CookieAuthenticationMiddleware(RequestDelegate next, } if (Options.TicketDataFormat == null) { - IDataProtector dataProtector = dataProtectionProvider.CreateDataProtector( + IDataProtector dataProtector = dataProtectionProvider.CreateProtector( typeof(CookieAuthenticationMiddleware).FullName, Options.AuthenticationType, "v2"); Options.TicketDataFormat = new TicketDataFormat(dataProtector); } diff --git a/src/Microsoft.AspNet.Security.Facebook/FacebookAuthenticationMiddleware.cs b/src/Microsoft.AspNet.Security.Facebook/FacebookAuthenticationMiddleware.cs index 5f6eb525e..4873ea2fd 100644 --- a/src/Microsoft.AspNet.Security.Facebook/FacebookAuthenticationMiddleware.cs +++ b/src/Microsoft.AspNet.Security.Facebook/FacebookAuthenticationMiddleware.cs @@ -4,7 +4,7 @@ using System; using System.Globalization; using Microsoft.AspNet.Builder; -using Microsoft.AspNet.Security.DataProtection; +using Microsoft.AspNet.DataProtection; using Microsoft.AspNet.Security.Infrastructure; using Microsoft.AspNet.Security.OAuth; using Microsoft.Framework.Logging; diff --git a/src/Microsoft.AspNet.Security.Google/GoogleAuthenticationMiddleware.cs b/src/Microsoft.AspNet.Security.Google/GoogleAuthenticationMiddleware.cs index 7de253070..a72c0524f 100644 --- a/src/Microsoft.AspNet.Security.Google/GoogleAuthenticationMiddleware.cs +++ b/src/Microsoft.AspNet.Security.Google/GoogleAuthenticationMiddleware.cs @@ -6,8 +6,8 @@ using System.Globalization; using System.Net.Http; using Microsoft.AspNet.Builder; +using Microsoft.AspNet.DataProtection; using Microsoft.AspNet.Security.DataHandler; -using Microsoft.AspNet.Security.DataProtection; using Microsoft.AspNet.Security.Infrastructure; using Microsoft.AspNet.Security.OAuth; using Microsoft.Framework.Logging; diff --git a/src/Microsoft.AspNet.Security.MicrosoftAccount/MicrosoftAccountAuthenticationMiddleware.cs b/src/Microsoft.AspNet.Security.MicrosoftAccount/MicrosoftAccountAuthenticationMiddleware.cs index ce50b7033..5d0afe1f3 100644 --- a/src/Microsoft.AspNet.Security.MicrosoftAccount/MicrosoftAccountAuthenticationMiddleware.cs +++ b/src/Microsoft.AspNet.Security.MicrosoftAccount/MicrosoftAccountAuthenticationMiddleware.cs @@ -4,7 +4,7 @@ using System; using System.Globalization; using Microsoft.AspNet.Builder; -using Microsoft.AspNet.Security.DataProtection; +using Microsoft.AspNet.DataProtection; using Microsoft.AspNet.Security.Infrastructure; using Microsoft.AspNet.Security.OAuth; using Microsoft.Framework.Logging; diff --git a/src/Microsoft.AspNet.Security.OAuth/OAuthAuthenticationMiddleware.cs b/src/Microsoft.AspNet.Security.OAuth/OAuthAuthenticationMiddleware.cs index 18dd9c9a8..c525af881 100644 --- a/src/Microsoft.AspNet.Security.OAuth/OAuthAuthenticationMiddleware.cs +++ b/src/Microsoft.AspNet.Security.OAuth/OAuthAuthenticationMiddleware.cs @@ -1,16 +1,16 @@ // Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. +using System; +using System.Diagnostics.CodeAnalysis; +using System.Globalization; +using System.Net.Http; using Microsoft.AspNet.Builder; +using Microsoft.AspNet.DataProtection; using Microsoft.AspNet.Security.DataHandler; -using Microsoft.AspNet.Security.DataProtection; using Microsoft.AspNet.Security.Infrastructure; using Microsoft.Framework.Logging; using Microsoft.Framework.OptionsModel; -using System; -using System.Diagnostics.CodeAnalysis; -using System.Globalization; -using System.Net.Http; namespace Microsoft.AspNet.Security.OAuth { @@ -70,7 +70,7 @@ public OAuthAuthenticationMiddleware( if (Options.StateDataFormat == null) { - IDataProtector dataProtector = dataProtectionProvider.CreateDataProtector( + IDataProtector dataProtector = dataProtectionProvider.CreateProtector( this.GetType().FullName, Options.AuthenticationType, "v1"); Options.StateDataFormat = new PropertiesDataFormat(dataProtector); } diff --git a/src/Microsoft.AspNet.Security.OAuth/project.json b/src/Microsoft.AspNet.Security.OAuth/project.json index 39ba020fc..d29f6d914 100644 --- a/src/Microsoft.AspNet.Security.OAuth/project.json +++ b/src/Microsoft.AspNet.Security.OAuth/project.json @@ -2,8 +2,8 @@ "version": "1.0.0-*", "description": "ASP.NET 5 middleware that enables an application to support any standard OAuth 2.0 authentication workflow.", "dependencies": { - "Microsoft.AspNet.Security": "1.0.0-*", - "Microsoft.AspNet.Security.DataProtection": "1.0.0-*", + "Microsoft.AspNet.DataProtection": "1.0.0-*", + "Microsoft.AspNet.Security": "1.0.0-*" }, "frameworks": { "aspnet50": { diff --git a/src/Microsoft.AspNet.Security.OAuthBearer/OAuthBearerAuthenticationMiddleware.cs b/src/Microsoft.AspNet.Security.OAuthBearer/OAuthBearerAuthenticationMiddleware.cs index 0403896ae..d1ae0ad1a 100644 --- a/src/Microsoft.AspNet.Security.OAuthBearer/OAuthBearerAuthenticationMiddleware.cs +++ b/src/Microsoft.AspNet.Security.OAuthBearer/OAuthBearerAuthenticationMiddleware.cs @@ -7,7 +7,6 @@ using System.IdentityModel.Tokens; using System.Net.Http; using Microsoft.AspNet.Builder; -using Microsoft.AspNet.Security.DataProtection; using Microsoft.AspNet.Security.Infrastructure; using Microsoft.Framework.Logging; using Microsoft.Framework.OptionsModel; diff --git a/src/Microsoft.AspNet.Security.OpenIdConnect/OpenIdConnectAuthenticationMiddleware.cs b/src/Microsoft.AspNet.Security.OpenIdConnect/OpenIdConnectAuthenticationMiddleware.cs index bbe59f50d..9e6baf45d 100644 --- a/src/Microsoft.AspNet.Security.OpenIdConnect/OpenIdConnectAuthenticationMiddleware.cs +++ b/src/Microsoft.AspNet.Security.OpenIdConnect/OpenIdConnectAuthenticationMiddleware.cs @@ -8,11 +8,11 @@ using System.Net.Http; using System.Text; using Microsoft.AspNet.Builder; +using Microsoft.AspNet.DataProtection; using Microsoft.AspNet.Http; using Microsoft.AspNet.Security.DataHandler; using Microsoft.AspNet.Security.DataHandler.Encoder; using Microsoft.AspNet.Security.DataHandler.Serializer; -using Microsoft.AspNet.Security.DataProtection; using Microsoft.AspNet.Security.Infrastructure; using Microsoft.Framework.Logging; using Microsoft.Framework.OptionsModel; @@ -53,7 +53,7 @@ public OpenIdConnectAuthenticationMiddleware( if (Options.StateDataFormat == null) { - var dataProtector = dataProtectionProvider.CreateDataProtector( + var dataProtector = dataProtectionProvider.CreateProtector( typeof(OpenIdConnectAuthenticationMiddleware).FullName, typeof(string).FullName, Options.AuthenticationType, @@ -64,7 +64,7 @@ public OpenIdConnectAuthenticationMiddleware( if (Options.StringDataFormat == null) { - var dataProtector = dataProtectionProvider.CreateDataProtector( + var dataProtector = dataProtectionProvider.CreateProtector( typeof(OpenIdConnectAuthenticationMiddleware).FullName, typeof(string).FullName, Options.AuthenticationType, diff --git a/src/Microsoft.AspNet.Security.Twitter/TwitterAuthenticationMiddleware.cs b/src/Microsoft.AspNet.Security.Twitter/TwitterAuthenticationMiddleware.cs index 6c4204a4b..98cdbdf37 100644 --- a/src/Microsoft.AspNet.Security.Twitter/TwitterAuthenticationMiddleware.cs +++ b/src/Microsoft.AspNet.Security.Twitter/TwitterAuthenticationMiddleware.cs @@ -6,9 +6,9 @@ using System.Globalization; using System.Net.Http; using Microsoft.AspNet.Builder; +using Microsoft.AspNet.DataProtection; using Microsoft.AspNet.Security.DataHandler; using Microsoft.AspNet.Security.DataHandler.Encoder; -using Microsoft.AspNet.Security.DataProtection; using Microsoft.AspNet.Security.Infrastructure; using Microsoft.AspNet.Security.Twitter.Messages; using Microsoft.Framework.Logging; @@ -60,7 +60,7 @@ public TwitterAuthenticationMiddleware( } if (Options.StateDataFormat == null) { - IDataProtector dataProtector = dataProtectionProvider.CreateDataProtector( + IDataProtector dataProtector = dataProtectionProvider.CreateProtector( typeof(TwitterAuthenticationMiddleware).FullName, Options.AuthenticationType, "v1"); Options.StateDataFormat = new SecureDataFormat( Serializers.RequestToken, diff --git a/src/Microsoft.AspNet.Security/DataHandler/PropertiesDataFormat.cs b/src/Microsoft.AspNet.Security/DataHandler/PropertiesDataFormat.cs index 050f9d24e..19a11a252 100644 --- a/src/Microsoft.AspNet.Security/DataHandler/PropertiesDataFormat.cs +++ b/src/Microsoft.AspNet.Security/DataHandler/PropertiesDataFormat.cs @@ -1,10 +1,10 @@ // Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. +using Microsoft.AspNet.DataProtection; using Microsoft.AspNet.Http.Security; using Microsoft.AspNet.Security.DataHandler.Encoder; using Microsoft.AspNet.Security.DataHandler.Serializer; -using Microsoft.AspNet.Security.DataProtection; namespace Microsoft.AspNet.Security.DataHandler { diff --git a/src/Microsoft.AspNet.Security/DataHandler/SecureDataFormat.cs b/src/Microsoft.AspNet.Security/DataHandler/SecureDataFormat.cs index e10d17db1..0c314fbf2 100644 --- a/src/Microsoft.AspNet.Security/DataHandler/SecureDataFormat.cs +++ b/src/Microsoft.AspNet.Security/DataHandler/SecureDataFormat.cs @@ -3,9 +3,9 @@ using System.Diagnostics.CodeAnalysis; +using Microsoft.AspNet.DataProtection; using Microsoft.AspNet.Security.DataHandler.Encoder; using Microsoft.AspNet.Security.DataHandler.Serializer; -using Microsoft.AspNet.Security.DataProtection; namespace Microsoft.AspNet.Security.DataHandler { diff --git a/src/Microsoft.AspNet.Security/DataHandler/TicketDataFormat.cs b/src/Microsoft.AspNet.Security/DataHandler/TicketDataFormat.cs index acc731e0b..b54f16666 100644 --- a/src/Microsoft.AspNet.Security/DataHandler/TicketDataFormat.cs +++ b/src/Microsoft.AspNet.Security/DataHandler/TicketDataFormat.cs @@ -2,9 +2,9 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. +using Microsoft.AspNet.DataProtection; using Microsoft.AspNet.Security.DataHandler.Encoder; using Microsoft.AspNet.Security.DataHandler.Serializer; -using Microsoft.AspNet.Security.DataProtection; namespace Microsoft.AspNet.Security.DataHandler { diff --git a/src/Microsoft.AspNet.Security/DataProtection/DataProtectionHelpers.cs b/src/Microsoft.AspNet.Security/DataProtection/DataProtectionHelpers.cs deleted file mode 100644 index 986bc8dc8..000000000 --- a/src/Microsoft.AspNet.Security/DataProtection/DataProtectionHelpers.cs +++ /dev/null @@ -1,13 +0,0 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -namespace Microsoft.AspNet.Security.DataProtection -{ - public static class DataProtectionHelpers - { - public static IDataProtector CreateDataProtector([NotNull] this IDataProtectionProvider dataProtectionProvider, params string[] purposes) - { - return dataProtectionProvider.CreateProtector(string.Join(";", purposes)); - } - } -} diff --git a/src/Microsoft.AspNet.Security/project.json b/src/Microsoft.AspNet.Security/project.json index af2d2fb98..62d223318 100644 --- a/src/Microsoft.AspNet.Security/project.json +++ b/src/Microsoft.AspNet.Security/project.json @@ -2,10 +2,10 @@ "version": "1.0.0-*", "description": "ASP.NET 5 common types used by the various authentication middleware.", "dependencies": { + "Microsoft.AspNet.DataProtection": "1.0.0-*", "Microsoft.AspNet.RequestContainer": "1.0.0-*", "Microsoft.AspNet.Http.Interfaces": "1.0.0-*", "Microsoft.AspNet.Http.Core": "1.0.0-*", - "Microsoft.AspNet.Security.DataProtection": "1.0.0-*", "Microsoft.Framework.Logging": "1.0.0-*" }, "frameworks": { diff --git a/test/Microsoft.AspNet.Security.Test/Facebook/FacebookMiddlewareTests.cs b/test/Microsoft.AspNet.Security.Test/Facebook/FacebookMiddlewareTests.cs index 7377d1a1f..42137b142 100644 --- a/test/Microsoft.AspNet.Security.Test/Facebook/FacebookMiddlewareTests.cs +++ b/test/Microsoft.AspNet.Security.Test/Facebook/FacebookMiddlewareTests.cs @@ -9,7 +9,6 @@ using System.Threading.Tasks; using Microsoft.AspNet.Builder; using Microsoft.AspNet.Http; -using Microsoft.AspNet.Security.DataProtection; using Microsoft.AspNet.TestHost; using Microsoft.Framework.DependencyInjection; using Shouldly; diff --git a/test/Microsoft.AspNet.Security.Test/Google/GoogleMiddlewareTests.cs b/test/Microsoft.AspNet.Security.Test/Google/GoogleMiddlewareTests.cs index 5b6046aa9..e019512f7 100644 --- a/test/Microsoft.AspNet.Security.Test/Google/GoogleMiddlewareTests.cs +++ b/test/Microsoft.AspNet.Security.Test/Google/GoogleMiddlewareTests.cs @@ -12,17 +12,17 @@ using System.Xml; using System.Xml.Linq; using Microsoft.AspNet.Builder; +using Microsoft.AspNet.DataProtection; using Microsoft.AspNet.Http; using Microsoft.AspNet.Http.Security; using Microsoft.AspNet.Security.Cookies; +using Microsoft.AspNet.Security.DataHandler; using Microsoft.AspNet.TestHost; +using Microsoft.Framework.DependencyInjection; +using Microsoft.Framework.OptionsModel; using Newtonsoft.Json; using Shouldly; using Xunit; -using Microsoft.Framework.OptionsModel; -using Microsoft.Framework.DependencyInjection; -using Microsoft.AspNet.Security.DataProtection; -using Microsoft.AspNet.Security.DataHandler; namespace Microsoft.AspNet.Security.Google { diff --git a/test/Microsoft.AspNet.Security.Test/MicrosoftAccount/MicrosoftAccountMiddlewareTests.cs b/test/Microsoft.AspNet.Security.Test/MicrosoftAccount/MicrosoftAccountMiddlewareTests.cs index 8fd06d8c9..0f3a9355c 100644 --- a/test/Microsoft.AspNet.Security.Test/MicrosoftAccount/MicrosoftAccountMiddlewareTests.cs +++ b/test/Microsoft.AspNet.Security.Test/MicrosoftAccount/MicrosoftAccountMiddlewareTests.cs @@ -12,18 +12,18 @@ using System.Xml; using System.Xml.Linq; using Microsoft.AspNet.Builder; +using Microsoft.AspNet.DataProtection; using Microsoft.AspNet.Http; using Microsoft.AspNet.Http.Security; using Microsoft.AspNet.Security.Cookies; +using Microsoft.AspNet.Security.DataHandler; using Microsoft.AspNet.Security.MicrosoftAccount; using Microsoft.AspNet.TestHost; +using Microsoft.Framework.DependencyInjection; +using Microsoft.Framework.OptionsModel; using Newtonsoft.Json; using Shouldly; using Xunit; -using Microsoft.Framework.OptionsModel; -using Microsoft.Framework.DependencyInjection; -using Microsoft.AspNet.Security.DataHandler; -using Microsoft.AspNet.Security.DataProtection; namespace Microsoft.AspNet.Security.Tests.MicrosoftAccount { diff --git a/test/Microsoft.AspNet.Security.Test/OpenIdConnect/OpenIdConnectMiddlewareTests.cs b/test/Microsoft.AspNet.Security.Test/OpenIdConnect/OpenIdConnectMiddlewareTests.cs index e3a5df471..d2d22a342 100644 --- a/test/Microsoft.AspNet.Security.Test/OpenIdConnect/OpenIdConnectMiddlewareTests.cs +++ b/test/Microsoft.AspNet.Security.Test/OpenIdConnect/OpenIdConnectMiddlewareTests.cs @@ -14,11 +14,11 @@ using System.Xml; using System.Xml.Linq; using Microsoft.AspNet.Builder; +using Microsoft.AspNet.DataProtection; using Microsoft.AspNet.Http; using Microsoft.AspNet.Http.Security; using Microsoft.AspNet.Security.Cookies; using Microsoft.AspNet.Security.DataHandler; -using Microsoft.AspNet.Security.DataProtection; using Microsoft.AspNet.Security.OpenIdConnect; using Microsoft.AspNet.TestHost; using Microsoft.Framework.DependencyInjection; diff --git a/test/Microsoft.AspNet.Security.Test/Twitter/TwitterMiddlewareTests.cs b/test/Microsoft.AspNet.Security.Test/Twitter/TwitterMiddlewareTests.cs index 36a829404..cb98aef0c 100644 --- a/test/Microsoft.AspNet.Security.Test/Twitter/TwitterMiddlewareTests.cs +++ b/test/Microsoft.AspNet.Security.Test/Twitter/TwitterMiddlewareTests.cs @@ -8,16 +8,16 @@ using System.Text; using System.Threading.Tasks; using Microsoft.AspNet.Builder; +using Microsoft.AspNet.DataProtection; using Microsoft.AspNet.Http; using Microsoft.AspNet.Security.Cookies; using Microsoft.AspNet.Security.Twitter; using Microsoft.AspNet.TestHost; +using Microsoft.Framework.DependencyInjection; +using Microsoft.Framework.OptionsModel; using Newtonsoft.Json; using Shouldly; using Xunit; -using Microsoft.Framework.OptionsModel; -using Microsoft.Framework.DependencyInjection; -using Microsoft.AspNet.Security.DataProtection; namespace Microsoft.AspNet.Security.Twitter { From 775eb5ece452e10a27aa166f52b58a6c0b615d18 Mon Sep 17 00:00:00 2001 From: Hao Kung Date: Mon, 2 Mar 2015 15:33:52 -0800 Subject: [PATCH 138/216] Split Security into AuthN/AuthZ AuthenticationType -> Scheme Move Active/Passive into AutomaticAuthenticationHandler Security -> Authorization/Authentication assemblies 401-403 logic Switch from ClaimsIdentity to ClaimsPrincipal --- samples/CookieSample/Startup.cs | 5 +- samples/CookieSample/project.json | 2 +- .../MemoryCacheSessionStore.cs | 4 +- samples/CookieSessionSample/Startup.cs | 5 +- samples/CookieSessionSample/project.json | 2 +- samples/OpenIdConnectSample/Startup.cs | 12 +- samples/OpenIdConnectSample/project.json | 4 +- samples/SocialSample/Startup.cs | 37 ++--- samples/SocialSample/project.json | 10 +- .../CookieAuthenticationDefaults.cs | 7 +- .../CookieAuthenticationExtensions.cs | 4 +- .../CookieAuthenticationHandler.cs | 51 +++---- .../CookieAuthenticationMiddleware.cs | 14 +- .../CookieAuthenticationOptions.cs | 13 +- .../CookieSecureOption.cs | 2 +- .../Infrastructure/ChunkingCookieManager.cs | 2 +- .../Infrastructure/Constants.cs | 2 +- .../IAuthenticationSessionStore.cs | 2 +- .../Infrastructure/ICookieManager.cs | 2 +- ...osoft.AspNet.Authentication.Cookies.kproj} | 4 +- .../NotNullAttribute.cs | 2 +- .../CookieApplyRedirectContext.cs | 4 +- .../CookieAuthenticationNotifications.cs | 10 +- .../Notifications/CookieExceptionContext.cs | 4 +- .../CookieResponseSignInContext.cs | 24 ++-- .../CookieResponseSignOutContext.cs | 4 +- .../CookieResponseSignedInContext.cs | 24 ++-- .../CookieValidateIdentityContext.cs | 36 +++-- .../Notifications/DefaultBehavior.cs | 2 +- .../ICookieAuthenticationNotifications.cs | 8 +- .../Resources.Designer.cs | 4 +- .../Resources.resx | 0 .../project.json | 2 +- .../FacebookAuthenticationDefaults.cs | 4 +- .../FacebookAuthenticationExtensions.cs | 2 +- .../FacebookAuthenticationHandler.cs | 25 ++-- .../FacebookAuthenticationMiddleware.cs | 6 +- .../FacebookAuthenticationOptions.cs | 8 +- ...soft.AspNet.Authentication.Facebook.kproj} | 4 +- .../NotNullAttribute.cs | 12 ++ .../FacebookAuthenticatedContext.cs | 4 +- .../FacebookAuthenticationNotifications.cs | 4 +- .../IFacebookAuthenticationNotifications.cs | 4 +- .../Resources.Designer.cs | 4 +- .../Resources.resx | 0 .../project.json | 2 +- .../GoogleAuthenticationDefaults.cs | 4 +- .../GoogleAuthenticationExtensions.cs | 2 +- .../GoogleAuthenticationHandler.cs | 37 ++--- .../GoogleAuthenticationMiddleware.cs | 8 +- .../GoogleAuthenticationOptions.cs | 10 +- ...rosoft.AspNet.Authentication.Google.kproj} | 4 +- .../NotNullAttribute.cs | 2 +- .../GoogleAuthenticatedContext.cs | 6 +- .../GoogleAuthenticationNotifications.cs | 4 +- .../IGoogleAuthenticationNotifications.cs | 4 +- .../Resources.Designer.cs | 4 +- .../Resources.resx | 0 .../project.json | 2 +- ...Net.Authentication.MicrosoftAccount.kproj} | 0 .../MicrosoftAccountAuthenticationDefaults.cs | 4 +- ...icrosoftAccountAuthenticationExtensions.cs | 2 +- .../MicrosoftAccountAuthenticationHandler.cs | 23 ++-- ...icrosoftAccountAuthenticationMiddleware.cs | 6 +- .../MicrosoftAccountAuthenticationOptions.cs | 8 +- .../NotNullAttribute.cs | 12 ++ ...osoftAccountAuthenticationNotifications.cs | 4 +- .../MicrosoftAccountAuthenticatedContext.cs | 4 +- ...osoftAccountAuthenticationNotifications.cs | 4 +- .../Resources.Designer.cs | 4 +- .../Resources.resx | 0 .../project.json | 2 +- ...crosoft.AspNet.Authentication.OAuth.kproj} | 4 +- .../NotNullAttribute.cs | 2 +- .../Notifications/BaseValidatingContext.cs | 4 +- .../BaseValidatingTicketContext.cs | 9 +- .../IOAuthAuthenticationNotifications.cs | 2 +- .../OAuthApplyRedirectContext.cs | 6 +- .../OAuthAuthenticatedContext.cs | 10 +- .../OAuthAuthenticationNotifications.cs | 2 +- .../Notifications/OAuthChallengeContext.cs | 4 +- .../OAuthGetUserInformationContext.cs | 10 +- .../Notifications/OAuthRequestTokenContext.cs | 4 +- .../OAuthReturnEndpointContext.cs | 4 +- .../OAuthAuthenticationDefaults.cs | 14 +- .../OAuthAuthenticationExtensions.cs | 12 +- .../OAuthAuthenticationHandler.cs | 33 ++--- .../OAuthAuthenticationMiddleware.cs | 20 +-- .../OAuthAuthenticationOptions.cs | 12 +- .../OAuthAuthenticationOptions`1.cs | 2 +- .../Resources.Designer.cs | 4 +- .../Resources.resx | 0 .../TokenResponse.cs | 2 +- .../project.json | 2 +- ...t.AspNet.Authentication.OAuthBearer.kproj} | 0 .../NotNullAttribute.cs | 2 +- .../AuthenticationChallengeNotification.cs | 4 +- .../OAuthBearerAuthenticationNotifications.cs | 4 +- .../OAuthBearerAuthenticationDefaults.cs | 6 +- .../OAuthBearerAuthenticationExtensions.cs | 2 +- .../OAuthBearerAuthenticationHandler.cs | 17 ++- .../OAuthBearerAuthenticationMiddleware.cs | 4 +- .../OAuthBearerAuthenticationOptions.cs | 10 +- .../Resources.Designer.cs | 4 +- .../Resources.resx | 0 .../project.json | 2 +- .../INonceCache.cs | 2 +- ...AspNet.Authentication.OpenIdConnect.kproj} | 0 .../AuthorizationCodeReceivedNotification.cs | 4 +- .../OpenIdConnectAuthenticationDefaults.cs | 6 +- .../OpenIdConnectAuthenticationExtensions.cs | 2 +- .../OpenIdConnectAuthenticationMiddleware.cs | 16 +-- ...penIdConnectAuthenticationNotifications.cs | 4 +- .../OpenIdConnectAuthenticationOptions.cs | 21 +-- .../OpenidConnectAuthenticationHandler.cs | 16 +-- .../Resources.Designer.cs | 2 +- .../Resources.resx | 0 .../project.json | 2 +- .../Messages/AccessToken.cs | 2 +- .../Messages/RequestToken.cs | 4 +- .../Messages/RequestTokenSerializer.cs | 6 +- .../Messages/Serializers.cs | 4 +- ...osoft.AspNet.Authentication.Twitter.kproj} | 4 +- .../NotNullAttribute.cs | 12 ++ .../ITwitterAuthenticationNotifications.cs | 2 +- .../TwitterApplyRedirectContext.cs | 6 +- .../TwitterAuthenticatedContext.cs | 10 +- .../TwitterAuthenticationNotifications.cs | 2 +- .../TwitterReturnEndpointContext.cs | 4 +- .../Resources.Designer.cs | 4 +- .../Resources.resx | 0 .../TwitterAuthenticationDefaults.cs | 4 +- .../TwitterAuthenticationExtensions.cs | 4 +- .../TwitterAuthenticationHandler.cs | 58 ++++---- .../TwitterAuthenticationMiddleware.cs | 19 ++- .../TwitterAuthenticationOptions.cs | 11 +- .../project.json | 2 +- .../AuthenticationHandler.cs | 84 ++++++------ .../AuthenticationHandler`1.cs | 5 +- .../AuthenticationMiddleware.cs | 5 +- .../AuthenticationOptions.cs | 34 +++++ .../AuthenticationTicket.cs | 29 ++-- .../AuthenticationTokenCreateContext.cs | 4 +- .../AuthenticationTokenProvider.cs | 2 +- .../AuthenticationTokenReceiveContext.cs | 4 +- .../AutomaticAuthenticationHandler.cs | 112 +++++++++++++++ .../AutomaticAuthenticationOptions.cs | 20 +++ ...ertificateSubjectKeyIdentifierValidator.cs | 2 +- ...ertificateSubjectPublicKeyInfoValidator.cs | 2 +- .../CertificateThumbprintValidator.cs | 2 +- .../Constants.cs | 2 +- .../DataHandler/Encoder/Base64TextEncoder.cs | 2 +- .../Encoder/Base64UrlTextEncoder.cs | 2 +- .../DataHandler/Encoder/ITextEncoder.cs | 2 +- .../DataHandler/Encoder/TextEncodings.cs | 2 +- .../DataHandler/ISecureDataFormat.cs | 2 +- .../DataHandler/PropertiesDataFormat.cs | 8 +- .../DataHandler/SecureDataFormat.cs | 8 +- .../DataHandler/Serializer/DataSerializers.cs | 4 +- .../DataHandler/Serializer/IDataSerializer.cs | 2 +- .../Serializer/PropertiesSerializer.cs | 4 +- .../Serializer/TicketSerializer.cs | 65 +++++---- .../DataHandler/TicketDataFormat.cs | 7 +- .../ExternalAuthenticationOptions.cs | 4 +- .../HttpContextExtensions.cs | 6 +- .../IAuthenticationTokenProvider.cs | 2 +- .../ICertificateValidator.cs | 2 +- .../ISystemClock.cs | 2 +- .../Microsoft.AspNet.Authentication.kproj} | 4 +- .../NotNullAttribute.cs | 2 +- .../AuthenticationFailedNotification.cs | 2 +- .../Notifications/BaseContext.cs | 2 +- .../Notifications/BaseContext`1.cs | 2 +- .../Notifications/BaseNotification.cs | 2 +- .../Notifications/EndpointContext.cs | 2 +- .../Notifications/EndpointContext`1.cs | 2 +- .../MessageReceivedNotification.cs | 2 +- .../Notifications/NotificationResultState.cs | 2 +- ...edirectFromIdentityProviderNotification.cs | 4 +- .../RedirectToIdentityProviderNotification.cs | 2 +- .../Notifications/ReturnEndpointContext.cs | 10 +- .../SecurityTokenReceivedNotification.cs | 2 +- .../SecurityTokenValidatedNotification.cs | 2 +- .../Properties/Resources.Designer.cs | 78 +++++++++++ .../Resources.resx | 129 ++++++++++++++++++ .../SecurityHelper.cs | 39 ++++++ .../SignInContext.cs} | 12 +- .../SubjectPublicKeyInfoAlgorithm.cs | 2 +- .../SystemClock.cs | 2 +- .../Win32.cs | 0 .../project.json | 0 .../AuthorizationContext.cs | 2 +- .../AuthorizationHandler.cs | 2 +- .../AuthorizationOptions.cs | 2 +- .../AuthorizationPolicy.cs | 14 +- .../AuthorizationPolicyBuilder.cs | 38 +++--- .../AuthorizationServiceExtensions.cs | 24 ++-- .../AuthorizeAttribute.cs | 4 +- .../ClaimsAuthorizationHandler.cs | 2 +- .../ClaimsAuthorizationRequirement.cs | 2 +- .../ClaimsTransformationOptions.cs | 2 +- .../DefaultAuthorizationService.cs | 2 +- .../DenyAnonymousAuthorizationHandler.cs | 2 +- .../DenyAnonymousAuthorizationRequirement.cs | 4 +- .../IAuthorizationHandler.cs | 2 +- .../IAuthorizationRequirement.cs | 2 +- .../IAuthorizationService.cs | 2 +- .../Microsoft.AspNet.Authorization.kproj | 17 +++ .../NotNullAttribute.cs | 2 +- .../OperationAuthorizationRequirement.cs | 2 +- .../PassThroughAuthorizationHandler.cs | 2 +- .../Properties/Resources.Designer.cs | 4 +- .../Resources.resx | 0 .../ServiceCollectionExtensions.cs | 2 +- .../project.json | 13 ++ .../NotNullAttribute.cs | 12 -- .../NotNullAttribute.cs | 12 -- .../AuthenticationMode.cs | 24 ---- .../AuthenticationOptions.cs | 41 ------ .../Infrastructure/SecurityHelper.cs | 84 ------------ .../AuthenticationHandlerFacts.cs | 110 +++++++++++++++ ...icateSubjectKeyIdentifierValidatorTests.cs | 2 +- ...icateSubjectPublicKeyInfoValidatorTests.cs | 2 +- .../CertificateThumbprintValidatorTests.cs | 2 +- .../Cookies/CookieMiddlewareTests.cs | 104 ++++++++++++-- .../Infrastructure/CookieChunkingTests.cs | 2 +- .../Encoder/Base64UrlTextEncoderTests.cs | 2 +- .../Facebook/FacebookMiddlewareTests.cs | 10 +- .../Google/GoogleMiddlewareTests.cs | 76 ++--------- ...crosoft.AspNet.Authentication.Tests.kproj} | 0 .../MicrosoftAccountMiddlewareTests.cs | 27 ++-- .../OAuthBearer/OAuthBearerMiddlewareTests.cs | 51 +++++-- .../OpenIdConnectMiddlewareTests.cs | 23 ++-- .../SecurityHelperTests.cs | 63 +++++++++ .../TestClock.cs | 4 +- .../Twitter/TwitterMiddlewareTests.cs | 10 +- .../katanatest.redmond.corp.microsoft.com.cer | Bin .../project.json | 27 ++++ .../selfSigned.cer | Bin .../AuthorizationPolicyFacts.cs | 19 +-- .../DefaultAuthorizationServiceTests.cs | 116 +++++++++++----- ...Microsoft.AspNet.Authorization.Tests.kproj | 17 +++ .../project.json | 20 +++ .../SecurityHelperTests.cs | 103 -------------- .../project.json | 27 ---- 245 files changed, 1701 insertions(+), 1169 deletions(-) rename src/{Microsoft.AspNet.Security.Cookies => Microsoft.AspNet.Authentication.Cookies}/CookieAuthenticationDefaults.cs (92%) rename src/{Microsoft.AspNet.Security.Cookies => Microsoft.AspNet.Authentication.Cookies}/CookieAuthenticationExtensions.cs (97%) rename src/{Microsoft.AspNet.Security.Cookies => Microsoft.AspNet.Authentication.Cookies}/CookieAuthenticationHandler.cs (87%) rename src/{Microsoft.AspNet.Security.Cookies => Microsoft.AspNet.Authentication.Cookies}/CookieAuthenticationMiddleware.cs (84%) rename src/{Microsoft.AspNet.Security.Cookies => Microsoft.AspNet.Authentication.Cookies}/CookieAuthenticationOptions.cs (95%) rename src/{Microsoft.AspNet.Security.Cookies => Microsoft.AspNet.Authentication.Cookies}/CookieSecureOption.cs (97%) rename src/{Microsoft.AspNet.Security.Cookies => Microsoft.AspNet.Authentication.Cookies}/Infrastructure/ChunkingCookieManager.cs (99%) rename src/{Microsoft.AspNet.Security.Cookies => Microsoft.AspNet.Authentication.Cookies}/Infrastructure/Constants.cs (84%) rename src/{Microsoft.AspNet.Security.Cookies => Microsoft.AspNet.Authentication.Cookies}/Infrastructure/IAuthenticationSessionStore.cs (96%) rename src/{Microsoft.AspNet.Security.Cookies => Microsoft.AspNet.Authentication.Cookies}/Infrastructure/ICookieManager.cs (95%) rename src/{Microsoft.AspNet.Security.Cookies/Microsoft.AspNet.Security.Cookies.kproj => Microsoft.AspNet.Authentication.Cookies/Microsoft.AspNet.Authentication.Cookies.kproj} (95%) rename src/{Microsoft.AspNet.Security.Facebook => Microsoft.AspNet.Authentication.Cookies}/NotNullAttribute.cs (87%) rename src/{Microsoft.AspNet.Security.Cookies => Microsoft.AspNet.Authentication.Cookies}/Notifications/CookieApplyRedirectContext.cs (93%) rename src/{Microsoft.AspNet.Security.Cookies => Microsoft.AspNet.Authentication.Cookies}/Notifications/CookieAuthenticationNotifications.cs (92%) rename src/{Microsoft.AspNet.Security.Cookies => Microsoft.AspNet.Authentication.Cookies}/Notifications/CookieExceptionContext.cs (96%) rename src/{Microsoft.AspNet.Security.Cookies => Microsoft.AspNet.Authentication.Cookies}/Notifications/CookieResponseSignInContext.cs (74%) rename src/{Microsoft.AspNet.Security.Cookies => Microsoft.AspNet.Authentication.Cookies}/Notifications/CookieResponseSignOutContext.cs (91%) rename src/{Microsoft.AspNet.Security.Cookies => Microsoft.AspNet.Authentication.Cookies}/Notifications/CookieResponseSignedInContext.cs (67%) rename src/{Microsoft.AspNet.Security.Cookies => Microsoft.AspNet.Authentication.Cookies}/Notifications/CookieValidateIdentityContext.cs (53%) rename src/{Microsoft.AspNet.Security.Cookies => Microsoft.AspNet.Authentication.Cookies}/Notifications/DefaultBehavior.cs (97%) rename src/{Microsoft.AspNet.Security.Cookies => Microsoft.AspNet.Authentication.Cookies}/Notifications/ICookieAuthenticationNotifications.cs (88%) rename src/{Microsoft.AspNet.Security.Cookies => Microsoft.AspNet.Authentication.Cookies}/Resources.Designer.cs (95%) rename src/{Microsoft.AspNet.Security.Cookies => Microsoft.AspNet.Authentication.Cookies}/Resources.resx (100%) rename src/{Microsoft.AspNet.Security.Cookies => Microsoft.AspNet.Authentication.Cookies}/project.json (85%) rename src/{Microsoft.AspNet.Security.Facebook => Microsoft.AspNet.Authentication.Facebook}/FacebookAuthenticationDefaults.cs (82%) rename src/{Microsoft.AspNet.Security.Facebook => Microsoft.AspNet.Authentication.Facebook}/FacebookAuthenticationExtensions.cs (96%) rename src/{Microsoft.AspNet.Security.Facebook => Microsoft.AspNet.Authentication.Facebook}/FacebookAuthenticationHandler.cs (78%) rename src/{Microsoft.AspNet.Security.Facebook => Microsoft.AspNet.Authentication.Facebook}/FacebookAuthenticationMiddleware.cs (95%) rename src/{Microsoft.AspNet.Security.Facebook => Microsoft.AspNet.Authentication.Facebook}/FacebookAuthenticationOptions.cs (88%) rename src/{Microsoft.AspNet.Security.Facebook/Microsoft.AspNet.Security.Facebook.kproj => Microsoft.AspNet.Authentication.Facebook/Microsoft.AspNet.Authentication.Facebook.kproj} (95%) create mode 100644 src/Microsoft.AspNet.Authentication.Facebook/NotNullAttribute.cs rename src/{Microsoft.AspNet.Security.Facebook => Microsoft.AspNet.Authentication.Facebook}/Notifications/FacebookAuthenticatedContext.cs (95%) rename src/{Microsoft.AspNet.Security.Facebook => Microsoft.AspNet.Authentication.Facebook}/Notifications/FacebookAuthenticationNotifications.cs (94%) rename src/{Microsoft.AspNet.Security.Facebook => Microsoft.AspNet.Authentication.Facebook}/Notifications/IFacebookAuthenticationNotifications.cs (90%) rename src/{Microsoft.AspNet.Security.Facebook => Microsoft.AspNet.Authentication.Facebook}/Resources.Designer.cs (94%) rename src/{Microsoft.AspNet.Security.Facebook => Microsoft.AspNet.Authentication.Facebook}/Resources.resx (100%) rename src/{Microsoft.AspNet.Security.Facebook => Microsoft.AspNet.Authentication.Facebook}/project.json (81%) rename src/{Microsoft.AspNet.Security.Google => Microsoft.AspNet.Authentication.Google}/GoogleAuthenticationDefaults.cs (83%) rename src/{Microsoft.AspNet.Security.Google => Microsoft.AspNet.Authentication.Google}/GoogleAuthenticationExtensions.cs (97%) rename src/{Microsoft.AspNet.Security.Google => Microsoft.AspNet.Authentication.Google}/GoogleAuthenticationHandler.cs (78%) rename src/{Microsoft.AspNet.Security.Google => Microsoft.AspNet.Authentication.Google}/GoogleAuthenticationMiddleware.cs (94%) rename src/{Microsoft.AspNet.Security.Google => Microsoft.AspNet.Authentication.Google}/GoogleAuthenticationOptions.cs (81%) rename src/{Microsoft.AspNet.Security.Google/Microsoft.AspNet.Security.Google.kproj => Microsoft.AspNet.Authentication.Google/Microsoft.AspNet.Authentication.Google.kproj} (95%) rename src/{Microsoft.AspNet.Security.Cookies => Microsoft.AspNet.Authentication.Google}/NotNullAttribute.cs (87%) rename src/{Microsoft.AspNet.Security.Google => Microsoft.AspNet.Authentication.Google}/Notifications/GoogleAuthenticatedContext.cs (96%) rename src/{Microsoft.AspNet.Security.Google => Microsoft.AspNet.Authentication.Google}/Notifications/GoogleAuthenticationNotifications.cs (94%) rename src/{Microsoft.AspNet.Security.Google => Microsoft.AspNet.Authentication.Google}/Notifications/IGoogleAuthenticationNotifications.cs (91%) rename src/{Microsoft.AspNet.Security.Google => Microsoft.AspNet.Authentication.Google}/Resources.Designer.cs (95%) rename src/{Microsoft.AspNet.Security.Google => Microsoft.AspNet.Authentication.Google}/Resources.resx (100%) rename src/{Microsoft.AspNet.Security.Google => Microsoft.AspNet.Authentication.Google}/project.json (81%) rename src/{Microsoft.AspNet.Security.MicrosoftAccount/Microsoft.AspNet.Security.MicrosoftAccount.kproj => Microsoft.AspNet.Authentication.MicrosoftAccount/Microsoft.AspNet.Authentication.MicrosoftAccount.kproj} (100%) rename src/{Microsoft.AspNet.Security.MicrosoftAccount => Microsoft.AspNet.Authentication.MicrosoftAccount}/MicrosoftAccountAuthenticationDefaults.cs (81%) rename src/{Microsoft.AspNet.Security.MicrosoftAccount => Microsoft.AspNet.Authentication.MicrosoftAccount}/MicrosoftAccountAuthenticationExtensions.cs (95%) rename src/{Microsoft.AspNet.Security.MicrosoftAccount => Microsoft.AspNet.Authentication.MicrosoftAccount}/MicrosoftAccountAuthenticationHandler.cs (73%) rename src/{Microsoft.AspNet.Security.MicrosoftAccount => Microsoft.AspNet.Authentication.MicrosoftAccount}/MicrosoftAccountAuthenticationMiddleware.cs (95%) rename src/{Microsoft.AspNet.Security.MicrosoftAccount => Microsoft.AspNet.Authentication.MicrosoftAccount}/MicrosoftAccountAuthenticationOptions.cs (80%) create mode 100644 src/Microsoft.AspNet.Authentication.MicrosoftAccount/NotNullAttribute.cs rename src/{Microsoft.AspNet.Security.MicrosoftAccount => Microsoft.AspNet.Authentication.MicrosoftAccount}/Notifications/IMicrosoftAccountAuthenticationNotifications.cs (90%) rename src/{Microsoft.AspNet.Security.MicrosoftAccount => Microsoft.AspNet.Authentication.MicrosoftAccount}/Notifications/MicrosoftAccountAuthenticatedContext.cs (96%) rename src/{Microsoft.AspNet.Security.MicrosoftAccount => Microsoft.AspNet.Authentication.MicrosoftAccount}/Notifications/MicrosoftAccountAuthenticationNotifications.cs (93%) rename src/{Microsoft.AspNet.Security.MicrosoftAccount => Microsoft.AspNet.Authentication.MicrosoftAccount}/Resources.Designer.cs (95%) rename src/{Microsoft.AspNet.Security.MicrosoftAccount => Microsoft.AspNet.Authentication.MicrosoftAccount}/Resources.resx (100%) rename src/{Microsoft.AspNet.Security.MicrosoftAccount => Microsoft.AspNet.Authentication.MicrosoftAccount}/project.json (87%) rename src/{Microsoft.AspNet.Security.OAuth/Microsoft.AspNet.Security.OAuth.kproj => Microsoft.AspNet.Authentication.OAuth/Microsoft.AspNet.Authentication.OAuth.kproj} (95%) rename src/{Microsoft.AspNet.Security.Google => Microsoft.AspNet.Authentication.OAuth}/NotNullAttribute.cs (87%) rename src/{Microsoft.AspNet.Security.OAuth => Microsoft.AspNet.Authentication.OAuth}/Notifications/BaseValidatingContext.cs (97%) rename src/{Microsoft.AspNet.Security.OAuth => Microsoft.AspNet.Authentication.OAuth}/Notifications/BaseValidatingTicketContext.cs (87%) rename src/{Microsoft.AspNet.Security.OAuth => Microsoft.AspNet.Authentication.OAuth}/Notifications/IOAuthAuthenticationNotifications.cs (97%) rename src/{Microsoft.AspNet.Security.OAuth => Microsoft.AspNet.Authentication.OAuth}/Notifications/OAuthApplyRedirectContext.cs (90%) rename src/{Microsoft.AspNet.Security.OAuth => Microsoft.AspNet.Authentication.OAuth}/Notifications/OAuthAuthenticatedContext.cs (92%) rename src/{Microsoft.AspNet.Security.OAuth => Microsoft.AspNet.Authentication.OAuth}/Notifications/OAuthAuthenticationNotifications.cs (98%) rename src/{Microsoft.AspNet.Security.OAuth => Microsoft.AspNet.Authentication.OAuth}/Notifications/OAuthChallengeContext.cs (90%) rename src/{Microsoft.AspNet.Security.OAuth => Microsoft.AspNet.Authentication.OAuth}/Notifications/OAuthGetUserInformationContext.cs (90%) rename src/{Microsoft.AspNet.Security.OAuth => Microsoft.AspNet.Authentication.OAuth}/Notifications/OAuthRequestTokenContext.cs (90%) rename src/{Microsoft.AspNet.Security.OAuth => Microsoft.AspNet.Authentication.OAuth}/Notifications/OAuthReturnEndpointContext.cs (89%) rename src/{Microsoft.AspNet.Security.OAuth => Microsoft.AspNet.Authentication.OAuth}/OAuthAuthenticationDefaults.cs (87%) rename src/{Microsoft.AspNet.Security.OAuth => Microsoft.AspNet.Authentication.OAuth}/OAuthAuthenticationExtensions.cs (81%) rename src/{Microsoft.AspNet.Security.OAuth => Microsoft.AspNet.Authentication.OAuth}/OAuthAuthenticationHandler.cs (85%) rename src/{Microsoft.AspNet.Security.OAuth => Microsoft.AspNet.Authentication.OAuth}/OAuthAuthenticationMiddleware.cs (92%) rename src/{Microsoft.AspNet.Security.OAuth => Microsoft.AspNet.Authentication.OAuth}/OAuthAuthenticationOptions.cs (92%) rename src/{Microsoft.AspNet.Security.OAuth => Microsoft.AspNet.Authentication.OAuth}/OAuthAuthenticationOptions`1.cs (93%) rename src/{Microsoft.AspNet.Security.OAuthBearer => Microsoft.AspNet.Authentication.OAuth}/Resources.Designer.cs (95%) rename src/{Microsoft.AspNet.Security.OAuth => Microsoft.AspNet.Authentication.OAuth}/Resources.resx (100%) rename src/{Microsoft.AspNet.Security.OAuth => Microsoft.AspNet.Authentication.OAuth}/TokenResponse.cs (94%) rename src/{Microsoft.AspNet.Security.OAuth => Microsoft.AspNet.Authentication.OAuth}/project.json (91%) rename src/{Microsoft.AspNet.Security.OAuthBearer/Microsoft.AspNet.Security.OAuthBearer.kproj => Microsoft.AspNet.Authentication.OAuthBearer/Microsoft.AspNet.Authentication.OAuthBearer.kproj} (100%) rename src/{Microsoft.AspNet.Security.MicrosoftAccount => Microsoft.AspNet.Authentication.OAuthBearer}/NotNullAttribute.cs (86%) rename src/{Microsoft.AspNet.Security.OAuthBearer => Microsoft.AspNet.Authentication.OAuthBearer}/Notifications/AuthenticationChallengeNotification.cs (81%) rename src/{Microsoft.AspNet.Security.OAuthBearer => Microsoft.AspNet.Authentication.OAuthBearer}/Notifications/OAuthBearerAuthenticationNotifications.cs (96%) rename src/{Microsoft.AspNet.Security.OAuthBearer => Microsoft.AspNet.Authentication.OAuthBearer}/OAuthBearerAuthenticationDefaults.cs (68%) rename src/{Microsoft.AspNet.Security.OAuthBearer => Microsoft.AspNet.Authentication.OAuthBearer}/OAuthBearerAuthenticationExtensions.cs (97%) rename src/{Microsoft.AspNet.Security.OAuthBearer => Microsoft.AspNet.Authentication.OAuthBearer}/OAuthBearerAuthenticationHandler.cs (94%) rename src/{Microsoft.AspNet.Security.OAuthBearer => Microsoft.AspNet.Authentication.OAuthBearer}/OAuthBearerAuthenticationMiddleware.cs (98%) rename src/{Microsoft.AspNet.Security.OAuthBearer => Microsoft.AspNet.Authentication.OAuthBearer}/OAuthBearerAuthenticationOptions.cs (95%) rename src/{Microsoft.AspNet.Security.OAuth => Microsoft.AspNet.Authentication.OAuthBearer}/Resources.Designer.cs (95%) rename src/{Microsoft.AspNet.Security.OAuthBearer => Microsoft.AspNet.Authentication.OAuthBearer}/Resources.resx (100%) rename src/{Microsoft.AspNet.Security.OAuthBearer => Microsoft.AspNet.Authentication.OAuthBearer}/project.json (92%) rename src/{Microsoft.AspNet.Security.OpenIdConnect => Microsoft.AspNet.Authentication.OpenIdConnect}/INonceCache.cs (86%) rename src/{Microsoft.AspNet.Security.OpenIdConnect/Microsoft.AspNet.Security.OpenIdConnect.kproj => Microsoft.AspNet.Authentication.OpenIdConnect/Microsoft.AspNet.Authentication.OpenIdConnect.kproj} (100%) rename src/{Microsoft.AspNet.Security.OpenIdConnect => Microsoft.AspNet.Authentication.OpenIdConnect}/Notifications/AuthorizationCodeReceivedNotification.cs (94%) rename src/{Microsoft.AspNet.Security.OpenIdConnect => Microsoft.AspNet.Authentication.OpenIdConnect}/OpenIdConnectAuthenticationDefaults.cs (90%) rename src/{Microsoft.AspNet.Security.OpenIdConnect => Microsoft.AspNet.Authentication.OpenIdConnect}/OpenIdConnectAuthenticationExtensions.cs (96%) rename src/{Microsoft.AspNet.Security.OpenIdConnect => Microsoft.AspNet.Authentication.OpenIdConnect}/OpenIdConnectAuthenticationMiddleware.cs (94%) rename src/{Microsoft.AspNet.Security.OpenIdConnect => Microsoft.AspNet.Authentication.OpenIdConnect}/OpenIdConnectAuthenticationNotifications.cs (96%) rename src/{Microsoft.AspNet.Security.OpenIdConnect => Microsoft.AspNet.Authentication.OpenIdConnect}/OpenIdConnectAuthenticationOptions.cs (94%) rename src/{Microsoft.AspNet.Security.OpenIdConnect => Microsoft.AspNet.Authentication.OpenIdConnect}/OpenidConnectAuthenticationHandler.cs (97%) rename src/{Microsoft.AspNet.Security.OpenIdConnect => Microsoft.AspNet.Authentication.OpenIdConnect}/Resources.Designer.cs (98%) rename src/{Microsoft.AspNet.Security.OpenIdConnect => Microsoft.AspNet.Authentication.OpenIdConnect}/Resources.resx (100%) rename src/{Microsoft.AspNet.Security.OpenIdConnect => Microsoft.AspNet.Authentication.OpenIdConnect}/project.json (90%) rename src/{Microsoft.AspNet.Security.Twitter => Microsoft.AspNet.Authentication.Twitter}/Messages/AccessToken.cs (91%) rename src/{Microsoft.AspNet.Security.Twitter => Microsoft.AspNet.Authentication.Twitter}/Messages/RequestToken.cs (89%) rename src/{Microsoft.AspNet.Security.Twitter => Microsoft.AspNet.Authentication.Twitter}/Messages/RequestTokenSerializer.cs (95%) rename src/{Microsoft.AspNet.Security.Twitter => Microsoft.AspNet.Authentication.Twitter}/Messages/Serializers.cs (85%) rename src/{Microsoft.AspNet.Security.Twitter/Microsoft.AspNet.Security.Twitter.kproj => Microsoft.AspNet.Authentication.Twitter/Microsoft.AspNet.Authentication.Twitter.kproj} (95%) create mode 100644 src/Microsoft.AspNet.Authentication.Twitter/NotNullAttribute.cs rename src/{Microsoft.AspNet.Security.Twitter => Microsoft.AspNet.Authentication.Twitter}/Notifications/ITwitterAuthenticationNotifications.cs (97%) rename src/{Microsoft.AspNet.Security.Twitter => Microsoft.AspNet.Authentication.Twitter}/Notifications/TwitterApplyRedirectContext.cs (91%) rename src/{Microsoft.AspNet.Security.Twitter => Microsoft.AspNet.Authentication.Twitter}/Notifications/TwitterAuthenticatedContext.cs (88%) rename src/{Microsoft.AspNet.Security.Twitter => Microsoft.AspNet.Authentication.Twitter}/Notifications/TwitterAuthenticationNotifications.cs (98%) rename src/{Microsoft.AspNet.Security.Twitter => Microsoft.AspNet.Authentication.Twitter}/Notifications/TwitterReturnEndpointContext.cs (88%) rename src/{Microsoft.AspNet.Security.Twitter => Microsoft.AspNet.Authentication.Twitter}/Resources.Designer.cs (95%) rename src/{Microsoft.AspNet.Security.Twitter => Microsoft.AspNet.Authentication.Twitter}/Resources.resx (100%) rename src/{Microsoft.AspNet.Security.Twitter => Microsoft.AspNet.Authentication.Twitter}/TwitterAuthenticationDefaults.cs (69%) rename src/{Microsoft.AspNet.Security.Twitter => Microsoft.AspNet.Authentication.Twitter}/TwitterAuthenticationExtensions.cs (93%) rename src/{Microsoft.AspNet.Security.Twitter => Microsoft.AspNet.Authentication.Twitter}/TwitterAuthenticationHandler.cs (86%) rename src/{Microsoft.AspNet.Security.Twitter => Microsoft.AspNet.Authentication.Twitter}/TwitterAuthenticationMiddleware.cs (90%) rename src/{Microsoft.AspNet.Security.Twitter => Microsoft.AspNet.Authentication.Twitter}/TwitterAuthenticationOptions.cs (92%) rename src/{Microsoft.AspNet.Security.Twitter => Microsoft.AspNet.Authentication.Twitter}/project.json (90%) rename src/{Microsoft.AspNet.Security/Infrastructure => Microsoft.AspNet.Authentication}/AuthenticationHandler.cs (83%) rename src/{Microsoft.AspNet.Security/Infrastructure => Microsoft.AspNet.Authentication}/AuthenticationHandler`1.cs (90%) rename src/{Microsoft.AspNet.Security/Infrastructure => Microsoft.AspNet.Authentication}/AuthenticationMiddleware.cs (95%) create mode 100644 src/Microsoft.AspNet.Authentication/AuthenticationOptions.cs rename src/{Microsoft.AspNet.Security => Microsoft.AspNet.Authentication}/AuthenticationTicket.cs (59%) rename src/{Microsoft.AspNet.Security/Infrastructure => Microsoft.AspNet.Authentication}/AuthenticationTokenCreateContext.cs (91%) rename src/{Microsoft.AspNet.Security/Infrastructure => Microsoft.AspNet.Authentication}/AuthenticationTokenProvider.cs (98%) rename src/{Microsoft.AspNet.Security/Infrastructure => Microsoft.AspNet.Authentication}/AuthenticationTokenReceiveContext.cs (88%) create mode 100644 src/Microsoft.AspNet.Authentication/AutomaticAuthenticationHandler.cs create mode 100644 src/Microsoft.AspNet.Authentication/AutomaticAuthenticationOptions.cs rename src/{Microsoft.AspNet.Security => Microsoft.AspNet.Authentication}/CertificateSubjectKeyIdentifierValidator.cs (98%) rename src/{Microsoft.AspNet.Security => Microsoft.AspNet.Authentication}/CertificateSubjectPublicKeyInfoValidator.cs (99%) rename src/{Microsoft.AspNet.Security => Microsoft.AspNet.Authentication}/CertificateThumbprintValidator.cs (98%) rename src/{Microsoft.AspNet.Security/Infrastructure => Microsoft.AspNet.Authentication}/Constants.cs (88%) rename src/{Microsoft.AspNet.Security => Microsoft.AspNet.Authentication}/DataHandler/Encoder/Base64TextEncoder.cs (88%) rename src/{Microsoft.AspNet.Security => Microsoft.AspNet.Authentication}/DataHandler/Encoder/Base64UrlTextEncoder.cs (93%) rename src/{Microsoft.AspNet.Security => Microsoft.AspNet.Authentication}/DataHandler/Encoder/ITextEncoder.cs (83%) rename src/{Microsoft.AspNet.Security => Microsoft.AspNet.Authentication}/DataHandler/Encoder/TextEncodings.cs (91%) rename src/{Microsoft.AspNet.Security => Microsoft.AspNet.Authentication}/DataHandler/ISecureDataFormat.cs (88%) rename src/{Microsoft.AspNet.Security => Microsoft.AspNet.Authentication}/DataHandler/PropertiesDataFormat.cs (69%) rename src/{Microsoft.AspNet.Security => Microsoft.AspNet.Authentication}/DataHandler/SecureDataFormat.cs (92%) rename src/{Microsoft.AspNet.Security => Microsoft.AspNet.Authentication}/DataHandler/Serializer/DataSerializers.cs (84%) rename src/{Microsoft.AspNet.Security => Microsoft.AspNet.Authentication}/DataHandler/Serializer/IDataSerializer.cs (83%) rename src/{Microsoft.AspNet.Security => Microsoft.AspNet.Authentication}/DataHandler/Serializer/PropertiesSerializer.cs (95%) rename src/{Microsoft.AspNet.Security => Microsoft.AspNet.Authentication}/DataHandler/Serializer/TicketSerializer.cs (52%) rename src/{Microsoft.AspNet.Security => Microsoft.AspNet.Authentication}/DataHandler/TicketDataFormat.cs (72%) rename src/{Microsoft.AspNet.Security => Microsoft.AspNet.Authentication}/ExternalAuthenticationOptions.cs (72%) rename src/{Microsoft.AspNet.Security/Infrastructure => Microsoft.AspNet.Authentication}/HttpContextExtensions.cs (82%) rename src/{Microsoft.AspNet.Security/Infrastructure => Microsoft.AspNet.Authentication}/IAuthenticationTokenProvider.cs (91%) rename src/{Microsoft.AspNet.Security => Microsoft.AspNet.Authentication}/ICertificateValidator.cs (97%) rename src/{Microsoft.AspNet.Security/Infrastructure => Microsoft.AspNet.Authentication}/ISystemClock.cs (90%) rename src/{Microsoft.AspNet.Security/Microsoft.AspNet.Security.kproj => Microsoft.AspNet.Authentication/Microsoft.AspNet.Authentication.kproj} (95%) rename src/{Microsoft.AspNet.Security.OAuth => Microsoft.AspNet.Authentication}/NotNullAttribute.cs (89%) rename src/{Microsoft.AspNet.Security => Microsoft.AspNet.Authentication}/Notifications/AuthenticationFailedNotification.cs (91%) rename src/{Microsoft.AspNet.Security => Microsoft.AspNet.Authentication}/Notifications/BaseContext.cs (92%) rename src/{Microsoft.AspNet.Security => Microsoft.AspNet.Authentication}/Notifications/BaseContext`1.cs (93%) rename src/{Microsoft.AspNet.Security => Microsoft.AspNet.Authentication}/Notifications/BaseNotification.cs (96%) rename src/{Microsoft.AspNet.Security => Microsoft.AspNet.Authentication}/Notifications/EndpointContext.cs (90%) rename src/{Microsoft.AspNet.Security => Microsoft.AspNet.Authentication}/Notifications/EndpointContext`1.cs (95%) rename src/{Microsoft.AspNet.Security => Microsoft.AspNet.Authentication}/Notifications/MessageReceivedNotification.cs (92%) rename src/{Microsoft.AspNet.Security => Microsoft.AspNet.Authentication}/Notifications/NotificationResultState.cs (92%) rename src/{Microsoft.AspNet.Security => Microsoft.AspNet.Authentication}/Notifications/RedirectFromIdentityProviderNotification.cs (84%) rename src/{Microsoft.AspNet.Security => Microsoft.AspNet.Authentication}/Notifications/RedirectToIdentityProviderNotification.cs (90%) rename src/{Microsoft.AspNet.Security => Microsoft.AspNet.Authentication}/Notifications/ReturnEndpointContext.cs (77%) rename src/{Microsoft.AspNet.Security => Microsoft.AspNet.Authentication}/Notifications/SecurityTokenReceivedNotification.cs (91%) rename src/{Microsoft.AspNet.Security => Microsoft.AspNet.Authentication}/Notifications/SecurityTokenValidatedNotification.cs (90%) create mode 100644 src/Microsoft.AspNet.Authentication/Properties/Resources.Designer.cs create mode 100644 src/Microsoft.AspNet.Authentication/Resources.resx create mode 100644 src/Microsoft.AspNet.Authentication/SecurityHelper.cs rename src/{Microsoft.AspNet.Security/Infrastructure/SignInIdentityContext.cs => Microsoft.AspNet.Authentication/SignInContext.cs} (53%) rename src/{Microsoft.AspNet.Security => Microsoft.AspNet.Authentication}/SubjectPublicKeyInfoAlgorithm.cs (94%) rename src/{Microsoft.AspNet.Security/Infrastructure => Microsoft.AspNet.Authentication}/SystemClock.cs (94%) rename src/{Microsoft.AspNet.Security => Microsoft.AspNet.Authentication}/Win32.cs (100%) rename src/{Microsoft.AspNet.Security => Microsoft.AspNet.Authentication}/project.json (100%) rename src/{Microsoft.AspNet.Security => Microsoft.AspNet.Authorization}/AuthorizationContext.cs (97%) rename src/{Microsoft.AspNet.Security => Microsoft.AspNet.Authorization}/AuthorizationHandler.cs (98%) rename src/{Microsoft.AspNet.Security => Microsoft.AspNet.Authorization}/AuthorizationOptions.cs (96%) rename src/{Microsoft.AspNet.Security => Microsoft.AspNet.Authorization}/AuthorizationPolicy.cs (87%) rename src/{Microsoft.AspNet.Security => Microsoft.AspNet.Authorization}/AuthorizationPolicyBuilder.cs (60%) rename src/{Microsoft.AspNet.Security => Microsoft.AspNet.Authorization}/AuthorizationServiceExtensions.cs (69%) rename src/{Microsoft.AspNet.Security => Microsoft.AspNet.Authorization}/AuthorizeAttribute.cs (86%) rename src/{Microsoft.AspNet.Security => Microsoft.AspNet.Authorization}/ClaimsAuthorizationHandler.cs (96%) rename src/{Microsoft.AspNet.Security => Microsoft.AspNet.Authorization}/ClaimsAuthorizationRequirement.cs (93%) rename src/{Microsoft.AspNet.Security => Microsoft.AspNet.Authorization}/ClaimsTransformationOptions.cs (90%) rename src/{Microsoft.AspNet.Security => Microsoft.AspNet.Authorization}/DefaultAuthorizationService.cs (98%) rename src/{Microsoft.AspNet.Security => Microsoft.AspNet.Authorization}/DenyAnonymousAuthorizationHandler.cs (95%) rename src/{Microsoft.AspNet.Security => Microsoft.AspNet.Authorization}/DenyAnonymousAuthorizationRequirement.cs (77%) rename src/{Microsoft.AspNet.Security => Microsoft.AspNet.Authorization}/IAuthorizationHandler.cs (90%) rename src/{Microsoft.AspNet.Security => Microsoft.AspNet.Authorization}/IAuthorizationRequirement.cs (85%) rename src/{Microsoft.AspNet.Security => Microsoft.AspNet.Authorization}/IAuthorizationService.cs (98%) create mode 100644 src/Microsoft.AspNet.Authorization/Microsoft.AspNet.Authorization.kproj rename src/{Microsoft.AspNet.Security/Infrastructure => Microsoft.AspNet.Authorization}/NotNullAttribute.cs (89%) rename src/{Microsoft.AspNet.Security => Microsoft.AspNet.Authorization}/OperationAuthorizationRequirement.cs (88%) rename src/{Microsoft.AspNet.Security => Microsoft.AspNet.Authorization}/PassThroughAuthorizationHandler.cs (95%) rename src/{Microsoft.AspNet.Security => Microsoft.AspNet.Authorization}/Properties/Resources.Designer.cs (95%) rename src/{Microsoft.AspNet.Security => Microsoft.AspNet.Authorization}/Resources.resx (100%) rename src/{Microsoft.AspNet.Security => Microsoft.AspNet.Authorization}/ServiceCollectionExtensions.cs (97%) create mode 100644 src/Microsoft.AspNet.Authorization/project.json delete mode 100644 src/Microsoft.AspNet.Security.OAuthBearer/NotNullAttribute.cs delete mode 100644 src/Microsoft.AspNet.Security.Twitter/NotNullAttribute.cs delete mode 100644 src/Microsoft.AspNet.Security/AuthenticationMode.cs delete mode 100644 src/Microsoft.AspNet.Security/AuthenticationOptions.cs delete mode 100644 src/Microsoft.AspNet.Security/Infrastructure/SecurityHelper.cs create mode 100644 test/Microsoft.AspNet.Authentication.Test/AuthenticationHandlerFacts.cs rename test/{Microsoft.AspNet.Security.Test => Microsoft.AspNet.Authentication.Test}/CertificateSubjectKeyIdentifierValidatorTests.cs (99%) rename test/{Microsoft.AspNet.Security.Test => Microsoft.AspNet.Authentication.Test}/CertificateSubjectPublicKeyInfoValidatorTests.cs (99%) rename test/{Microsoft.AspNet.Security.Test => Microsoft.AspNet.Authentication.Test}/CertificateThumbprintValidatorTests.cs (99%) rename test/{Microsoft.AspNet.Security.Test => Microsoft.AspNet.Authentication.Test}/Cookies/CookieMiddlewareTests.cs (83%) rename test/{Microsoft.AspNet.Security.Test => Microsoft.AspNet.Authentication.Test}/Cookies/Infrastructure/CookieChunkingTests.cs (99%) rename test/{Microsoft.AspNet.Security.Test => Microsoft.AspNet.Authentication.Test}/DataHandler/Encoder/Base64UrlTextEncoderTests.cs (94%) rename test/{Microsoft.AspNet.Security.Test => Microsoft.AspNet.Authentication.Test}/Facebook/FacebookMiddlewareTests.cs (94%) rename test/{Microsoft.AspNet.Security.Test => Microsoft.AspNet.Authentication.Test}/Google/GoogleMiddlewareTests.cs (88%) rename test/{Microsoft.AspNet.Security.Test/Microsoft.AspNet.Security.Tests.kproj => Microsoft.AspNet.Authentication.Test/Microsoft.AspNet.Authentication.Tests.kproj} (100%) rename test/{Microsoft.AspNet.Security.Test => Microsoft.AspNet.Authentication.Test}/MicrosoftAccount/MicrosoftAccountMiddlewareTests.cs (92%) rename test/{Microsoft.AspNet.Security.Test => Microsoft.AspNet.Authentication.Test}/OAuthBearer/OAuthBearerMiddlewareTests.cs (82%) rename test/{Microsoft.AspNet.Security.Test => Microsoft.AspNet.Authentication.Test}/OpenIdConnect/OpenIdConnectMiddlewareTests.cs (94%) create mode 100644 test/Microsoft.AspNet.Authentication.Test/SecurityHelperTests.cs rename test/{Microsoft.AspNet.Security.Test => Microsoft.AspNet.Authentication.Test}/TestClock.cs (86%) rename test/{Microsoft.AspNet.Security.Test => Microsoft.AspNet.Authentication.Test}/Twitter/TwitterMiddlewareTests.cs (96%) rename test/{Microsoft.AspNet.Security.Test => Microsoft.AspNet.Authentication.Test}/katanatest.redmond.corp.microsoft.com.cer (100%) create mode 100644 test/Microsoft.AspNet.Authentication.Test/project.json rename test/{Microsoft.AspNet.Security.Test => Microsoft.AspNet.Authentication.Test}/selfSigned.cer (100%) rename test/{Microsoft.AspNet.Security.Test => Microsoft.AspNet.Authorization.Test}/AuthorizationPolicyFacts.cs (67%) rename test/{Microsoft.AspNet.Security.Test => Microsoft.AspNet.Authorization.Test}/DefaultAuthorizationServiceTests.cs (89%) create mode 100644 test/Microsoft.AspNet.Authorization.Test/Microsoft.AspNet.Authorization.Tests.kproj create mode 100644 test/Microsoft.AspNet.Authorization.Test/project.json delete mode 100644 test/Microsoft.AspNet.Security.Test/SecurityHelperTests.cs delete mode 100644 test/Microsoft.AspNet.Security.Test/project.json diff --git a/samples/CookieSample/Startup.cs b/samples/CookieSample/Startup.cs index 7e481c220..d5b0814fa 100644 --- a/samples/CookieSample/Startup.cs +++ b/samples/CookieSample/Startup.cs @@ -1,7 +1,7 @@ using System.Security.Claims; using Microsoft.AspNet.Builder; using Microsoft.AspNet.Http; -using Microsoft.AspNet.Security.Cookies; +using Microsoft.AspNet.Authentication.Cookies; using Microsoft.Framework.DependencyInjection; namespace CookieSample @@ -23,8 +23,7 @@ public void Configure(IApplicationBuilder app) { if (context.User == null || !context.User.Identity.IsAuthenticated) { - context.Response.SignIn(new ClaimsIdentity(new[] { new Claim("name", "bob") }, CookieAuthenticationDefaults.AuthenticationType)); - + context.Response.SignIn(CookieAuthenticationDefaults.AuthenticationScheme, new ClaimsPrincipal(new ClaimsIdentity(new[] { new Claim("name", "bob") }))); context.Response.ContentType = "text/plain"; await context.Response.WriteAsync("Hello First timer"); return; diff --git a/samples/CookieSample/project.json b/samples/CookieSample/project.json index 2cda02680..4840de91a 100644 --- a/samples/CookieSample/project.json +++ b/samples/CookieSample/project.json @@ -1,6 +1,6 @@ { "dependencies": { - "Microsoft.AspNet.Security.Cookies": "1.0.0-*", + "Microsoft.AspNet.Authentication.Cookies": "1.0.0-*", "Microsoft.AspNet.Server.WebListener": "1.0.0-*", "Microsoft.AspNet.Server.IIS": "1.0.0-*", "Kestrel": "1.0.0-*" diff --git a/samples/CookieSessionSample/MemoryCacheSessionStore.cs b/samples/CookieSessionSample/MemoryCacheSessionStore.cs index 9877ded68..4bb62d3ab 100644 --- a/samples/CookieSessionSample/MemoryCacheSessionStore.cs +++ b/samples/CookieSessionSample/MemoryCacheSessionStore.cs @@ -1,7 +1,7 @@ using System; using System.Threading.Tasks; -using Microsoft.AspNet.Security; -using Microsoft.AspNet.Security.Cookies.Infrastructure; +using Microsoft.AspNet.Authentication; +using Microsoft.AspNet.Authentication.Cookies.Infrastructure; using Microsoft.Framework.Cache.Memory; namespace CookieSessionSample diff --git a/samples/CookieSessionSample/Startup.cs b/samples/CookieSessionSample/Startup.cs index ff72c0469..dacb7956f 100644 --- a/samples/CookieSessionSample/Startup.cs +++ b/samples/CookieSessionSample/Startup.cs @@ -2,7 +2,7 @@ using System.Security.Claims; using Microsoft.AspNet.Builder; using Microsoft.AspNet.Http; -using Microsoft.AspNet.Security.Cookies; +using Microsoft.AspNet.Authentication.Cookies; using Microsoft.Framework.DependencyInjection; namespace CookieSessionSample @@ -32,8 +32,7 @@ public void Configure(IApplicationBuilder app) { claims.Add(new Claim(ClaimTypes.Role, "SomeRandomGroup" + i, ClaimValueTypes.String, "IssuedByBob", "OriginalIssuerJoe")); } - context.Response.SignIn(new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationType)); - + context.Response.SignIn(CookieAuthenticationDefaults.AuthenticationScheme, new ClaimsPrincipal(new ClaimsIdentity(claims))); context.Response.ContentType = "text/plain"; await context.Response.WriteAsync("Hello First timer"); return; diff --git a/samples/CookieSessionSample/project.json b/samples/CookieSessionSample/project.json index 684c76517..18401fb77 100644 --- a/samples/CookieSessionSample/project.json +++ b/samples/CookieSessionSample/project.json @@ -1,6 +1,6 @@ { "dependencies": { - "Microsoft.AspNet.Security.Cookies": "1.0.0-*", + "Microsoft.AspNet.Authentication.Cookies": "1.0.0-*", "Microsoft.AspNet.Server.WebListener": "1.0.0-*", "Microsoft.Framework.Cache.Memory": "1.0.0-*", "Kestrel": "1.0.0-*", diff --git a/samples/OpenIdConnectSample/Startup.cs b/samples/OpenIdConnectSample/Startup.cs index bd443424e..c232bc349 100644 --- a/samples/OpenIdConnectSample/Startup.cs +++ b/samples/OpenIdConnectSample/Startup.cs @@ -1,9 +1,9 @@ using Microsoft.AspNet.Builder; using Microsoft.AspNet.Http; -using Microsoft.AspNet.Http.Security; -using Microsoft.AspNet.Security; -using Microsoft.AspNet.Security.Cookies; -using Microsoft.AspNet.Security.OpenIdConnect; +using Microsoft.AspNet.Http.Authentication; +using Microsoft.AspNet.Authentication; +using Microsoft.AspNet.Authentication.Cookies; +using Microsoft.AspNet.Authentication.OpenIdConnect; using Microsoft.Framework.DependencyInjection; namespace OpenIdConnectSample @@ -17,7 +17,7 @@ public void Configure(IApplicationBuilder app) services.AddDataProtection(); services.Configure(options => { - options.SignInAsAuthenticationType = CookieAuthenticationDefaults.AuthenticationType; + options.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme; }); }); @@ -37,7 +37,7 @@ public void Configure(IApplicationBuilder app) { if (context.User == null || !context.User.Identity.IsAuthenticated) { - context.Response.Challenge(new AuthenticationProperties { RedirectUri = "/" }, OpenIdConnectAuthenticationDefaults.AuthenticationType); + context.Response.Challenge(new AuthenticationProperties { RedirectUri = "/" }, OpenIdConnectAuthenticationDefaults.AuthenticationScheme); context.Response.ContentType = "text/plain"; await context.Response.WriteAsync("Hello First timer"); diff --git a/samples/OpenIdConnectSample/project.json b/samples/OpenIdConnectSample/project.json index 65652110b..382c6b169 100644 --- a/samples/OpenIdConnectSample/project.json +++ b/samples/OpenIdConnectSample/project.json @@ -1,9 +1,9 @@ { "dependencies": { "Kestrel": "1.0.0-*", - "Microsoft.AspNet.Security.Cookies": "1.0.0-*", + "Microsoft.AspNet.Authentication.Cookies": "1.0.0-*", "Microsoft.AspNet.Server.IIS": "1.0.0-*", - "Microsoft.AspNet.Security.OpenIdConnect": "1.0.0-*", + "Microsoft.AspNet.Authentication.OpenIdConnect": "1.0.0-*", "Microsoft.AspNet.Server.WebListener": "1.0.0-*" }, "frameworks": { diff --git a/samples/SocialSample/Startup.cs b/samples/SocialSample/Startup.cs index d0b8d9280..dab45953d 100644 --- a/samples/SocialSample/Startup.cs +++ b/samples/SocialSample/Startup.cs @@ -4,12 +4,12 @@ using Microsoft.AspNet.Builder; using Microsoft.AspNet.DataProtection; using Microsoft.AspNet.Http; -using Microsoft.AspNet.Http.Security; -using Microsoft.AspNet.Security; -using Microsoft.AspNet.Security.Cookies; -using Microsoft.AspNet.Security.Google; -using Microsoft.AspNet.Security.MicrosoftAccount; -using Microsoft.AspNet.Security.OAuth; +using Microsoft.AspNet.Http.Authentication; +using Microsoft.AspNet.Authentication; +using Microsoft.AspNet.Authentication.Cookies; +using Microsoft.AspNet.Authentication.Google; +using Microsoft.AspNet.Authentication.MicrosoftAccount; +using Microsoft.AspNet.Authentication.OAuth; using Microsoft.Framework.DependencyInjection; using Newtonsoft.Json.Linq; @@ -26,7 +26,7 @@ public void Configure(IApplicationBuilder app) services.AddDataProtection(); services.Configure(options => { - options.SignInAsAuthenticationType = CookieAuthenticationDefaults.AuthenticationType; + options.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme; }); }); @@ -121,6 +121,7 @@ k web options.AuthorizationEndpoint = "https://github.com/login/oauth/authorize"; options.TokenEndpoint = "https://github.com/login/oauth/access_token"; options.UserInformationEndpoint = "https://api.github.com/user"; + options.ClaimsIssuer = "OAuth2-Github"; // Retrieving user information is unique to each provider. options.Notifications = new OAuthAuthenticationNotifications() { @@ -136,7 +137,7 @@ k web JObject user = JObject.Parse(text); var identity = new ClaimsIdentity( - context.Options.AuthenticationType, + context.Options.AuthenticationScheme, ClaimsIdentity.DefaultNameClaimType, ClaimsIdentity.DefaultRoleClaimType); @@ -144,25 +145,25 @@ k web var id = user.TryGetValue("id", out value) ? value.ToString() : null; if (!string.IsNullOrEmpty(id)) { - identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, id, ClaimValueTypes.String, context.Options.AuthenticationType)); + identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, id, ClaimValueTypes.String, context.Options.ClaimsIssuer)); } var userName = user.TryGetValue("login", out value) ? value.ToString() : null; if (!string.IsNullOrEmpty(userName)) { - identity.AddClaim(new Claim(ClaimsIdentity.DefaultNameClaimType, userName, ClaimValueTypes.String, context.Options.AuthenticationType)); + identity.AddClaim(new Claim(ClaimsIdentity.DefaultNameClaimType, userName, ClaimValueTypes.String, context.Options.ClaimsIssuer)); } var name = user.TryGetValue("name", out value) ? value.ToString() : null; if (!string.IsNullOrEmpty(name)) { - identity.AddClaim(new Claim("urn:github:name", name, ClaimValueTypes.String, context.Options.AuthenticationType)); + identity.AddClaim(new Claim("urn:github:name", name, ClaimValueTypes.String, context.Options.ClaimsIssuer)); } var link = user.TryGetValue("url", out value) ? value.ToString() : null; if (!string.IsNullOrEmpty(link)) { - identity.AddClaim(new Claim("urn:github:url", link, ClaimValueTypes.String, context.Options.AuthenticationType)); + identity.AddClaim(new Claim("urn:github:url", link, ClaimValueTypes.String, context.Options.ClaimsIssuer)); } - context.Identity = identity; + context.Principal = new ClaimsPrincipal(identity); }, }; }); @@ -172,7 +173,7 @@ k web { signoutApp.Run(async context => { - string authType = context.Request.Query["authtype"]; + string authType = context.Request.Query["authscheme"]; if (!string.IsNullOrEmpty(authType)) { // By default the client will be redirect back to the URL that issued the challenge (/login?authtype=foo), @@ -183,10 +184,10 @@ k web context.Response.ContentType = "text/html"; await context.Response.WriteAsync(""); - await context.Response.WriteAsync("Choose an authentication type:
"); - foreach (var type in context.GetAuthenticationTypes()) + await context.Response.WriteAsync("Choose an authentication scheme:
"); + foreach (var type in context.GetAuthenticationSchemes()) { - await context.Response.WriteAsync("" + (type.Caption ?? "(suppressed)") + "
"); + await context.Response.WriteAsync("" + (type.Caption ?? "(suppressed)") + "
"); } await context.Response.WriteAsync(""); }); @@ -197,7 +198,7 @@ k web { signoutApp.Run(async context => { - context.Response.SignOut(CookieAuthenticationDefaults.AuthenticationType); + context.Response.SignOut(CookieAuthenticationDefaults.AuthenticationScheme); context.Response.ContentType = "text/html"; await context.Response.WriteAsync(""); await context.Response.WriteAsync("You have been logged out. Goodbye " + context.User.Identity.Name + "
"); diff --git a/samples/SocialSample/project.json b/samples/SocialSample/project.json index f457d3a9d..d925cf66b 100644 --- a/samples/SocialSample/project.json +++ b/samples/SocialSample/project.json @@ -1,11 +1,11 @@ { "dependencies": { "Microsoft.AspNet.Diagnostics": "1.0.0-*", - "Microsoft.AspNet.Security.Cookies": "1.0.0-*", - "Microsoft.AspNet.Security.Facebook": "1.0.0-*", - "Microsoft.AspNet.Security.Google": "1.0.0-*", - "Microsoft.AspNet.Security.MicrosoftAccount": "1.0.0-*", - "Microsoft.AspNet.Security.Twitter": "1.0.0-*", + "Microsoft.AspNet.Authentication.Cookies": "1.0.0-*", + "Microsoft.AspNet.Authentication.Facebook": "1.0.0-*", + "Microsoft.AspNet.Authentication.Google": "1.0.0-*", + "Microsoft.AspNet.Authentication.MicrosoftAccount": "1.0.0-*", + "Microsoft.AspNet.Authentication.Twitter": "1.0.0-*", "Microsoft.AspNet.Server.IIS": "1.0.0-*", "Microsoft.AspNet.Server.WebListener": "1.0.0-*", "Kestrel": "1.0.0-*" diff --git a/src/Microsoft.AspNet.Security.Cookies/CookieAuthenticationDefaults.cs b/src/Microsoft.AspNet.Authentication.Cookies/CookieAuthenticationDefaults.cs similarity index 92% rename from src/Microsoft.AspNet.Security.Cookies/CookieAuthenticationDefaults.cs rename to src/Microsoft.AspNet.Authentication.Cookies/CookieAuthenticationDefaults.cs index 6ee3c8c5b..d02b337f3 100644 --- a/src/Microsoft.AspNet.Security.Cookies/CookieAuthenticationDefaults.cs +++ b/src/Microsoft.AspNet.Authentication.Cookies/CookieAuthenticationDefaults.cs @@ -1,11 +1,10 @@ // Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - using System.Diagnostics.CodeAnalysis; using Microsoft.AspNet.Http; -namespace Microsoft.AspNet.Security.Cookies +namespace Microsoft.AspNet.Authentication.Cookies { /// /// Default values related to cookie-based authentication middleware @@ -13,9 +12,9 @@ namespace Microsoft.AspNet.Security.Cookies public static class CookieAuthenticationDefaults { /// - /// The default value used for CookieAuthenticationOptions.AuthenticationType + /// The default value used for CookieAuthenticationOptions.AuthenticationScheme /// - public const string AuthenticationType = "Cookies"; + public const string AuthenticationScheme = "Cookies"; /// /// The prefix used to provide a default CookieAuthenticationOptions.CookieName diff --git a/src/Microsoft.AspNet.Security.Cookies/CookieAuthenticationExtensions.cs b/src/Microsoft.AspNet.Authentication.Cookies/CookieAuthenticationExtensions.cs similarity index 97% rename from src/Microsoft.AspNet.Security.Cookies/CookieAuthenticationExtensions.cs rename to src/Microsoft.AspNet.Authentication.Cookies/CookieAuthenticationExtensions.cs index 191d44da8..08f4cc71a 100644 --- a/src/Microsoft.AspNet.Security.Cookies/CookieAuthenticationExtensions.cs +++ b/src/Microsoft.AspNet.Authentication.Cookies/CookieAuthenticationExtensions.cs @@ -1,10 +1,10 @@ // Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -using Microsoft.AspNet.Security.Cookies; +using System; +using Microsoft.AspNet.Authentication.Cookies; using Microsoft.Framework.DependencyInjection; using Microsoft.Framework.OptionsModel; -using System; namespace Microsoft.AspNet.Builder { diff --git a/src/Microsoft.AspNet.Security.Cookies/CookieAuthenticationHandler.cs b/src/Microsoft.AspNet.Authentication.Cookies/CookieAuthenticationHandler.cs similarity index 87% rename from src/Microsoft.AspNet.Security.Cookies/CookieAuthenticationHandler.cs rename to src/Microsoft.AspNet.Authentication.Cookies/CookieAuthenticationHandler.cs index c8f964ee7..5a72a142e 100644 --- a/src/Microsoft.AspNet.Security.Cookies/CookieAuthenticationHandler.cs +++ b/src/Microsoft.AspNet.Authentication.Cookies/CookieAuthenticationHandler.cs @@ -7,20 +7,19 @@ using System.Security.Claims; using System.Threading.Tasks; using Microsoft.AspNet.Http; -using Microsoft.AspNet.Http.Security; -using Microsoft.AspNet.Security.Infrastructure; +using Microsoft.AspNet.Http.Authentication; using Microsoft.Framework.Logging; -namespace Microsoft.AspNet.Security.Cookies +namespace Microsoft.AspNet.Authentication.Cookies { - internal class CookieAuthenticationHandler : AuthenticationHandler + internal class CookieAuthenticationHandler : AutomaticAuthenticationHandler { private const string HeaderNameCacheControl = "Cache-Control"; private const string HeaderNamePragma = "Pragma"; private const string HeaderNameExpires = "Expires"; private const string HeaderValueNoCache = "no-cache"; private const string HeaderValueMinusOne = "-1"; - private const string SessionIdClaim = "Microsoft.AspNet.Security.Cookies-SessionId"; + private const string SessionIdClaim = "Microsoft.AspNet.Authentication.Cookies-SessionId"; private readonly ILogger _logger; @@ -60,7 +59,7 @@ protected override async Task AuthenticateCoreAsync() if (Options.SessionStore != null) { - Claim claim = ticket.Identity.Claims.FirstOrDefault(c => c.Type.Equals(SessionIdClaim)); + Claim claim = ticket.Principal.Claims.FirstOrDefault(c => c.Type.Equals(SessionIdClaim)); if (claim == null) { _logger.WriteWarning(@"SessionId missing"); @@ -103,11 +102,11 @@ protected override async Task AuthenticateCoreAsync() } } - var context = new CookieValidateIdentityContext(Context, ticket, Options); + var context = new CookieValidatePrincipalContext(Context, ticket, Options); - await Options.Notifications.ValidateIdentity(context); + await Options.Notifications.ValidatePrincipal(context); - return new AuthenticationTicket(context.Identity, context.Properties); + return new AuthenticationTicket(context.Principal, context.Properties, Options.AuthenticationScheme); } catch (Exception exception) { @@ -129,7 +128,7 @@ protected override void ApplyResponseGrant() protected override async Task ApplyResponseGrantAsync() { - var signin = SignInIdentityContext; + var signin = SignInContext; bool shouldSignin = signin != null; var signout = SignOutContext; bool shouldSignout = signout != null; @@ -162,8 +161,8 @@ protected override async Task ApplyResponseGrantAsync() var signInContext = new CookieResponseSignInContext( Context, Options, - Options.AuthenticationType, - signin.Identity, + Options.AuthenticationScheme, + signin.Principal, signin.Properties, cookieOptions); @@ -191,7 +190,7 @@ protected override async Task ApplyResponseGrantAsync() signInContext.CookieOptions.Expires = expiresUtc.ToUniversalTime().DateTime; } - model = new AuthenticationTicket(signInContext.Identity, signInContext.Properties); + model = new AuthenticationTicket(signInContext.Principal, signInContext.Properties, signInContext.AuthenticationScheme); if (Options.SessionStore != null) { if (_sessionKey != null) @@ -199,10 +198,11 @@ protected override async Task ApplyResponseGrantAsync() await Options.SessionStore.RemoveAsync(_sessionKey); } _sessionKey = await Options.SessionStore.StoreAsync(model); - ClaimsIdentity identity = new ClaimsIdentity( - new[] { new Claim(SessionIdClaim, _sessionKey) }, - Options.AuthenticationType); - model = new AuthenticationTicket(identity, null); + var principal = new ClaimsPrincipal( + new ClaimsIdentity( + new[] { new Claim(SessionIdClaim, _sessionKey) }, + Options.AuthenticationScheme)); + model = new AuthenticationTicket(principal, null, Options.AuthenticationScheme); } string cookieValue = Options.TicketDataFormat.Protect(model); @@ -215,8 +215,8 @@ protected override async Task ApplyResponseGrantAsync() var signedInContext = new CookieResponseSignedInContext( Context, Options, - Options.AuthenticationType, - signInContext.Identity, + Options.AuthenticationScheme, + signInContext.Principal, signInContext.Properties); Options.Notifications.ResponseSignedIn(signedInContext); @@ -248,10 +248,11 @@ protected override async Task ApplyResponseGrantAsync() if (Options.SessionStore != null && _sessionKey != null) { await Options.SessionStore.RenewAsync(_sessionKey, model); - ClaimsIdentity identity = new ClaimsIdentity( - new[] { new Claim(SessionIdClaim, _sessionKey) }, - Options.AuthenticationType); - model = new AuthenticationTicket(identity, null); + var principal = new ClaimsPrincipal( + new ClaimsIdentity( + new[] { new Claim(SessionIdClaim, _sessionKey) }, + Options.AuthenticationScheme)); + model = new AuthenticationTicket(principal, null, Options.AuthenticationScheme); } string cookieValue = Options.TicketDataFormat.Protect(model); @@ -327,8 +328,8 @@ protected override void ApplyResponseChallenge() return; } - // Active middleware should redirect on 401 even if there wasn't an explicit challenge. - if (ChallengeContext == null && Options.AuthenticationMode == AuthenticationMode.Passive) + // Automatic middleware should redirect on 401 even if there wasn't an explicit challenge. + if (ChallengeContext == null && !Options.AutomaticAuthentication) { return; } diff --git a/src/Microsoft.AspNet.Security.Cookies/CookieAuthenticationMiddleware.cs b/src/Microsoft.AspNet.Authentication.Cookies/CookieAuthenticationMiddleware.cs similarity index 84% rename from src/Microsoft.AspNet.Security.Cookies/CookieAuthenticationMiddleware.cs rename to src/Microsoft.AspNet.Authentication.Cookies/CookieAuthenticationMiddleware.cs index ba8136559..ba933d235 100644 --- a/src/Microsoft.AspNet.Security.Cookies/CookieAuthenticationMiddleware.cs +++ b/src/Microsoft.AspNet.Authentication.Cookies/CookieAuthenticationMiddleware.cs @@ -1,17 +1,17 @@ // Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - using System; +using Microsoft.AspNet.Authentication.Cookies.Infrastructure; +using Microsoft.AspNet.Authentication.DataHandler; +using Microsoft.AspNet.Authentication.Cookies.Infrastructure; +using Microsoft.AspNet.Authentication.DataHandler; using Microsoft.AspNet.Builder; using Microsoft.AspNet.DataProtection; -using Microsoft.AspNet.Security.Cookies.Infrastructure; -using Microsoft.AspNet.Security.DataHandler; -using Microsoft.AspNet.Security.Infrastructure; using Microsoft.Framework.Logging; using Microsoft.Framework.OptionsModel; -namespace Microsoft.AspNet.Security.Cookies +namespace Microsoft.AspNet.Authentication.Cookies { public class CookieAuthenticationMiddleware : AuthenticationMiddleware { @@ -31,12 +31,12 @@ public CookieAuthenticationMiddleware(RequestDelegate next, } if (String.IsNullOrEmpty(Options.CookieName)) { - Options.CookieName = CookieAuthenticationDefaults.CookiePrefix + Options.AuthenticationType; + Options.CookieName = CookieAuthenticationDefaults.CookiePrefix + Options.AuthenticationScheme; } if (Options.TicketDataFormat == null) { IDataProtector dataProtector = dataProtectionProvider.CreateProtector( - typeof(CookieAuthenticationMiddleware).FullName, Options.AuthenticationType, "v2"); + typeof(CookieAuthenticationMiddleware).FullName, Options.AuthenticationScheme, "v2"); Options.TicketDataFormat = new TicketDataFormat(dataProtector); } if (Options.CookieManager == null) diff --git a/src/Microsoft.AspNet.Security.Cookies/CookieAuthenticationOptions.cs b/src/Microsoft.AspNet.Authentication.Cookies/CookieAuthenticationOptions.cs similarity index 95% rename from src/Microsoft.AspNet.Security.Cookies/CookieAuthenticationOptions.cs rename to src/Microsoft.AspNet.Authentication.Cookies/CookieAuthenticationOptions.cs index ec6e10206..12ff4f995 100644 --- a/src/Microsoft.AspNet.Security.Cookies/CookieAuthenticationOptions.cs +++ b/src/Microsoft.AspNet.Authentication.Cookies/CookieAuthenticationOptions.cs @@ -1,19 +1,17 @@ // Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - using System; using System.Diagnostics.CodeAnalysis; using Microsoft.AspNet.Http; -using Microsoft.AspNet.Security.Cookies.Infrastructure; -using Microsoft.AspNet.Security.Infrastructure; +using Microsoft.AspNet.Authentication.Cookies.Infrastructure; -namespace Microsoft.AspNet.Security.Cookies +namespace Microsoft.AspNet.Authentication.Cookies { /// /// Contains the options used by the CookiesAuthenticationMiddleware /// - public class CookieAuthenticationOptions : AuthenticationOptions + public class CookieAuthenticationOptions : AutomaticAuthenticationOptions { private string _cookieName; @@ -22,7 +20,8 @@ public class CookieAuthenticationOptions : AuthenticationOptions /// public CookieAuthenticationOptions() { - AuthenticationType = CookieAuthenticationDefaults.AuthenticationType; + AutomaticAuthentication = true; + AuthenticationScheme = CookieAuthenticationDefaults.AuthenticationScheme; ReturnUrlParameter = CookieAuthenticationDefaults.ReturnUrlParameter; ExpireTimeSpan = TimeSpan.FromDays(14); SlidingExpiration = true; @@ -34,7 +33,7 @@ public CookieAuthenticationOptions() /// /// Determines the cookie name used to persist the identity. The default value is ".AspNet.Cookies". - /// This value should be changed if you change the name of the AuthenticationType, especially if your + /// This value should be changed if you change the name of the AuthenticationScheme, especially if your /// system uses the cookie authentication middleware multiple times. /// public string CookieName diff --git a/src/Microsoft.AspNet.Security.Cookies/CookieSecureOption.cs b/src/Microsoft.AspNet.Authentication.Cookies/CookieSecureOption.cs similarity index 97% rename from src/Microsoft.AspNet.Security.Cookies/CookieSecureOption.cs rename to src/Microsoft.AspNet.Authentication.Cookies/CookieSecureOption.cs index c98ae0751..c8309612b 100644 --- a/src/Microsoft.AspNet.Security.Cookies/CookieSecureOption.cs +++ b/src/Microsoft.AspNet.Authentication.Cookies/CookieSecureOption.cs @@ -2,7 +2,7 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -namespace Microsoft.AspNet.Security.Cookies +namespace Microsoft.AspNet.Authentication.Cookies { /// /// Determines how the identity cookie's security property is set. diff --git a/src/Microsoft.AspNet.Security.Cookies/Infrastructure/ChunkingCookieManager.cs b/src/Microsoft.AspNet.Authentication.Cookies/Infrastructure/ChunkingCookieManager.cs similarity index 99% rename from src/Microsoft.AspNet.Security.Cookies/Infrastructure/ChunkingCookieManager.cs rename to src/Microsoft.AspNet.Authentication.Cookies/Infrastructure/ChunkingCookieManager.cs index 07fc0db34..1f953593b 100644 --- a/src/Microsoft.AspNet.Security.Cookies/Infrastructure/ChunkingCookieManager.cs +++ b/src/Microsoft.AspNet.Authentication.Cookies/Infrastructure/ChunkingCookieManager.cs @@ -7,7 +7,7 @@ using System.Linq; using Microsoft.AspNet.Http; -namespace Microsoft.AspNet.Security.Cookies.Infrastructure +namespace Microsoft.AspNet.Authentication.Cookies.Infrastructure { /// /// This handles cookies that are limited by per cookie length. It breaks down long cookies for responses, and reassembles them diff --git a/src/Microsoft.AspNet.Security.Cookies/Infrastructure/Constants.cs b/src/Microsoft.AspNet.Authentication.Cookies/Infrastructure/Constants.cs similarity index 84% rename from src/Microsoft.AspNet.Security.Cookies/Infrastructure/Constants.cs rename to src/Microsoft.AspNet.Authentication.Cookies/Infrastructure/Constants.cs index ef8db8e9e..b3c3bb3a7 100644 --- a/src/Microsoft.AspNet.Security.Cookies/Infrastructure/Constants.cs +++ b/src/Microsoft.AspNet.Authentication.Cookies/Infrastructure/Constants.cs @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -namespace Microsoft.AspNet.Security.Cookies.Infrastructure +namespace Microsoft.AspNet.Authentication.Cookies.Infrastructure { internal static class Constants { diff --git a/src/Microsoft.AspNet.Security.Cookies/Infrastructure/IAuthenticationSessionStore.cs b/src/Microsoft.AspNet.Authentication.Cookies/Infrastructure/IAuthenticationSessionStore.cs similarity index 96% rename from src/Microsoft.AspNet.Security.Cookies/Infrastructure/IAuthenticationSessionStore.cs rename to src/Microsoft.AspNet.Authentication.Cookies/Infrastructure/IAuthenticationSessionStore.cs index 9f449b098..6a6fa574b 100644 --- a/src/Microsoft.AspNet.Security.Cookies/Infrastructure/IAuthenticationSessionStore.cs +++ b/src/Microsoft.AspNet.Authentication.Cookies/Infrastructure/IAuthenticationSessionStore.cs @@ -2,7 +2,7 @@ using System.Threading.Tasks; -namespace Microsoft.AspNet.Security.Cookies.Infrastructure +namespace Microsoft.AspNet.Authentication.Cookies.Infrastructure { /// /// This provides an abstract storage mechanic to preserve identity information on the server diff --git a/src/Microsoft.AspNet.Security.Cookies/Infrastructure/ICookieManager.cs b/src/Microsoft.AspNet.Authentication.Cookies/Infrastructure/ICookieManager.cs similarity index 95% rename from src/Microsoft.AspNet.Security.Cookies/Infrastructure/ICookieManager.cs rename to src/Microsoft.AspNet.Authentication.Cookies/Infrastructure/ICookieManager.cs index b523b1bad..966d3f935 100644 --- a/src/Microsoft.AspNet.Security.Cookies/Infrastructure/ICookieManager.cs +++ b/src/Microsoft.AspNet.Authentication.Cookies/Infrastructure/ICookieManager.cs @@ -3,7 +3,7 @@ using Microsoft.AspNet.Http; -namespace Microsoft.AspNet.Security.Cookies.Infrastructure +namespace Microsoft.AspNet.Authentication.Cookies.Infrastructure { /// /// This is used by the CookieAuthenticationMiddleware to process request and response cookies. diff --git a/src/Microsoft.AspNet.Security.Cookies/Microsoft.AspNet.Security.Cookies.kproj b/src/Microsoft.AspNet.Authentication.Cookies/Microsoft.AspNet.Authentication.Cookies.kproj similarity index 95% rename from src/Microsoft.AspNet.Security.Cookies/Microsoft.AspNet.Security.Cookies.kproj rename to src/Microsoft.AspNet.Authentication.Cookies/Microsoft.AspNet.Authentication.Cookies.kproj index 31c09ed57..3480de791 100644 --- a/src/Microsoft.AspNet.Security.Cookies/Microsoft.AspNet.Security.Cookies.kproj +++ b/src/Microsoft.AspNet.Authentication.Cookies/Microsoft.AspNet.Authentication.Cookies.kproj @@ -1,4 +1,4 @@ - + 14.0 @@ -14,4 +14,4 @@ 2.0 - + \ No newline at end of file diff --git a/src/Microsoft.AspNet.Security.Facebook/NotNullAttribute.cs b/src/Microsoft.AspNet.Authentication.Cookies/NotNullAttribute.cs similarity index 87% rename from src/Microsoft.AspNet.Security.Facebook/NotNullAttribute.cs rename to src/Microsoft.AspNet.Authentication.Cookies/NotNullAttribute.cs index 6a4d82b16..44c9fcbb2 100644 --- a/src/Microsoft.AspNet.Security.Facebook/NotNullAttribute.cs +++ b/src/Microsoft.AspNet.Authentication.Cookies/NotNullAttribute.cs @@ -3,7 +3,7 @@ using System; -namespace Microsoft.AspNet.Security.Facebook +namespace Microsoft.AspNet.Authentication.Cookies { [AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false)] internal sealed class NotNullAttribute : Attribute diff --git a/src/Microsoft.AspNet.Security.Cookies/Notifications/CookieApplyRedirectContext.cs b/src/Microsoft.AspNet.Authentication.Cookies/Notifications/CookieApplyRedirectContext.cs similarity index 93% rename from src/Microsoft.AspNet.Security.Cookies/Notifications/CookieApplyRedirectContext.cs rename to src/Microsoft.AspNet.Authentication.Cookies/Notifications/CookieApplyRedirectContext.cs index 34907eaba..877e9c5ea 100644 --- a/src/Microsoft.AspNet.Security.Cookies/Notifications/CookieApplyRedirectContext.cs +++ b/src/Microsoft.AspNet.Authentication.Cookies/Notifications/CookieApplyRedirectContext.cs @@ -4,9 +4,9 @@ using System.Diagnostics.CodeAnalysis; using Microsoft.AspNet.Http; -using Microsoft.AspNet.Security.Notifications; +using Microsoft.AspNet.Authentication.Notifications; -namespace Microsoft.AspNet.Security.Cookies +namespace Microsoft.AspNet.Authentication.Cookies { /// /// Context passed when a Challenge, SignIn, or SignOut causes a redirect in the cookie middleware diff --git a/src/Microsoft.AspNet.Security.Cookies/Notifications/CookieAuthenticationNotifications.cs b/src/Microsoft.AspNet.Authentication.Cookies/Notifications/CookieAuthenticationNotifications.cs similarity index 92% rename from src/Microsoft.AspNet.Security.Cookies/Notifications/CookieAuthenticationNotifications.cs rename to src/Microsoft.AspNet.Authentication.Cookies/Notifications/CookieAuthenticationNotifications.cs index c38489ed8..f4c29dca4 100644 --- a/src/Microsoft.AspNet.Security.Cookies/Notifications/CookieAuthenticationNotifications.cs +++ b/src/Microsoft.AspNet.Authentication.Cookies/Notifications/CookieAuthenticationNotifications.cs @@ -5,7 +5,7 @@ using System; using System.Threading.Tasks; -namespace Microsoft.AspNet.Security.Cookies +namespace Microsoft.AspNet.Authentication.Cookies { /// /// This default implementation of the ICookieAuthenticationNotifications may be used if the @@ -19,7 +19,7 @@ public class CookieAuthenticationNotifications : ICookieAuthenticationNotificati /// public CookieAuthenticationNotifications() { - OnValidateIdentity = context => Task.FromResult(0); + OnValidatePrincipal = context => Task.FromResult(0); OnResponseSignIn = context => { }; OnResponseSignedIn = context => { }; OnResponseSignOut = context => { }; @@ -30,7 +30,7 @@ public CookieAuthenticationNotifications() /// /// A delegate assigned to this property will be invoked when the related method is called /// - public Func OnValidateIdentity { get; set; } + public Func OnValidatePrincipal { get; set; } /// /// A delegate assigned to this property will be invoked when the related method is called @@ -62,9 +62,9 @@ public CookieAuthenticationNotifications() /// /// /// - public virtual Task ValidateIdentity(CookieValidateIdentityContext context) + public virtual Task ValidatePrincipal(CookieValidatePrincipalContext context) { - return OnValidateIdentity.Invoke(context); + return OnValidatePrincipal.Invoke(context); } /// diff --git a/src/Microsoft.AspNet.Security.Cookies/Notifications/CookieExceptionContext.cs b/src/Microsoft.AspNet.Authentication.Cookies/Notifications/CookieExceptionContext.cs similarity index 96% rename from src/Microsoft.AspNet.Security.Cookies/Notifications/CookieExceptionContext.cs rename to src/Microsoft.AspNet.Authentication.Cookies/Notifications/CookieExceptionContext.cs index e8e4fc80b..852e90b68 100644 --- a/src/Microsoft.AspNet.Security.Cookies/Notifications/CookieExceptionContext.cs +++ b/src/Microsoft.AspNet.Authentication.Cookies/Notifications/CookieExceptionContext.cs @@ -4,9 +4,9 @@ using System; using System.Diagnostics.CodeAnalysis; using Microsoft.AspNet.Http; -using Microsoft.AspNet.Security.Notifications; +using Microsoft.AspNet.Authentication.Notifications; -namespace Microsoft.AspNet.Security.Cookies +namespace Microsoft.AspNet.Authentication.Cookies { /// /// Context object passed to the ICookieAuthenticationProvider method Exception. diff --git a/src/Microsoft.AspNet.Security.Cookies/Notifications/CookieResponseSignInContext.cs b/src/Microsoft.AspNet.Authentication.Cookies/Notifications/CookieResponseSignInContext.cs similarity index 74% rename from src/Microsoft.AspNet.Security.Cookies/Notifications/CookieResponseSignInContext.cs rename to src/Microsoft.AspNet.Authentication.Cookies/Notifications/CookieResponseSignInContext.cs index 28b47c6fe..bf448a8dd 100644 --- a/src/Microsoft.AspNet.Security.Cookies/Notifications/CookieResponseSignInContext.cs +++ b/src/Microsoft.AspNet.Authentication.Cookies/Notifications/CookieResponseSignInContext.cs @@ -4,10 +4,10 @@ using System.Security.Claims; using Microsoft.AspNet.Http; -using Microsoft.AspNet.Http.Security; -using Microsoft.AspNet.Security.Notifications; +using Microsoft.AspNet.Http.Authentication; +using Microsoft.AspNet.Authentication.Notifications; -namespace Microsoft.AspNet.Security.Cookies +namespace Microsoft.AspNet.Authentication.Cookies { /// /// Context object passed to the ICookieAuthenticationProvider method ResponseSignIn. @@ -19,35 +19,35 @@ public class CookieResponseSignInContext : BaseContext /// The HTTP request context /// The middleware options - /// Initializes AuthenticationType property - /// Initializes Identity property + /// Initializes AuthenticationScheme property + /// Initializes Principal property /// Initializes Extra property /// Initializes options for the authentication cookie. public CookieResponseSignInContext( HttpContext context, CookieAuthenticationOptions options, - string authenticationType, - ClaimsIdentity identity, + string authenticationScheme, + ClaimsPrincipal principal, AuthenticationProperties properties, CookieOptions cookieOptions) : base(context, options) { - AuthenticationType = authenticationType; - Identity = identity; + AuthenticationScheme = authenticationScheme; + Principal = principal; Properties = properties; CookieOptions = cookieOptions; } /// - /// The name of the AuthenticationType creating a cookie + /// The name of the AuthenticationScheme creating a cookie /// - public string AuthenticationType { get; private set; } + public string AuthenticationScheme { get; private set; } /// /// Contains the claims about to be converted into the outgoing cookie. /// May be replaced or altered during the ResponseSignIn call. /// - public ClaimsIdentity Identity { get; set; } + public ClaimsPrincipal Principal { get; set; } /// /// Contains the extra data about to be contained in the outgoing cookie. diff --git a/src/Microsoft.AspNet.Security.Cookies/Notifications/CookieResponseSignOutContext.cs b/src/Microsoft.AspNet.Authentication.Cookies/Notifications/CookieResponseSignOutContext.cs similarity index 91% rename from src/Microsoft.AspNet.Security.Cookies/Notifications/CookieResponseSignOutContext.cs rename to src/Microsoft.AspNet.Authentication.Cookies/Notifications/CookieResponseSignOutContext.cs index a7cf4129a..4ba06bad3 100644 --- a/src/Microsoft.AspNet.Security.Cookies/Notifications/CookieResponseSignOutContext.cs +++ b/src/Microsoft.AspNet.Authentication.Cookies/Notifications/CookieResponseSignOutContext.cs @@ -3,9 +3,9 @@ using Microsoft.AspNet.Http; -using Microsoft.AspNet.Security.Notifications; +using Microsoft.AspNet.Authentication.Notifications; -namespace Microsoft.AspNet.Security.Cookies +namespace Microsoft.AspNet.Authentication.Cookies { /// /// Context object passed to the ICookieAuthenticationProvider method ResponseSignOut diff --git a/src/Microsoft.AspNet.Security.Cookies/Notifications/CookieResponseSignedInContext.cs b/src/Microsoft.AspNet.Authentication.Cookies/Notifications/CookieResponseSignedInContext.cs similarity index 67% rename from src/Microsoft.AspNet.Security.Cookies/Notifications/CookieResponseSignedInContext.cs rename to src/Microsoft.AspNet.Authentication.Cookies/Notifications/CookieResponseSignedInContext.cs index 3366fb9f7..ec0c3b876 100644 --- a/src/Microsoft.AspNet.Security.Cookies/Notifications/CookieResponseSignedInContext.cs +++ b/src/Microsoft.AspNet.Authentication.Cookies/Notifications/CookieResponseSignedInContext.cs @@ -3,10 +3,10 @@ using System.Security.Claims; using Microsoft.AspNet.Http; -using Microsoft.AspNet.Http.Security; -using Microsoft.AspNet.Security.Notifications; +using Microsoft.AspNet.Http.Authentication; +using Microsoft.AspNet.Authentication.Notifications; -namespace Microsoft.AspNet.Security.Cookies +namespace Microsoft.AspNet.Authentication.Cookies { /// /// Context object passed to the ICookieAuthenticationNotifications method ResponseSignedIn. @@ -18,31 +18,31 @@ public class CookieResponseSignedInContext : BaseContext /// The HTTP request context /// The middleware options - /// Initializes AuthenticationType property - /// Initializes Identity property + /// Initializes AuthenticationScheme property + /// Initializes Principal property /// Initializes Properties property public CookieResponseSignedInContext( HttpContext context, CookieAuthenticationOptions options, - string authenticationType, - ClaimsIdentity identity, + string authenticationScheme, + ClaimsPrincipal principal, AuthenticationProperties properties) : base(context, options) { - AuthenticationType = authenticationType; - Identity = identity; + AuthenticationScheme = authenticationScheme; + Principal = principal; Properties = properties; } /// - /// The name of the AuthenticationType creating a cookie + /// The name of the AuthenticationScheme creating a cookie /// - public string AuthenticationType { get; private set; } + public string AuthenticationScheme { get; private set; } /// /// Contains the claims that were converted into the outgoing cookie. /// - public ClaimsIdentity Identity { get; private set; } + public ClaimsPrincipal Principal { get; private set; } /// /// Contains the extra data that was contained in the outgoing cookie. diff --git a/src/Microsoft.AspNet.Security.Cookies/Notifications/CookieValidateIdentityContext.cs b/src/Microsoft.AspNet.Authentication.Cookies/Notifications/CookieValidateIdentityContext.cs similarity index 53% rename from src/Microsoft.AspNet.Security.Cookies/Notifications/CookieValidateIdentityContext.cs rename to src/Microsoft.AspNet.Authentication.Cookies/Notifications/CookieValidateIdentityContext.cs index 771d75d40..328d93d2b 100644 --- a/src/Microsoft.AspNet.Security.Cookies/Notifications/CookieValidateIdentityContext.cs +++ b/src/Microsoft.AspNet.Authentication.Cookies/Notifications/CookieValidateIdentityContext.cs @@ -1,22 +1,18 @@ // Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System; using System.Security.Claims; using System.Security.Principal; using Microsoft.AspNet.Http; -using Microsoft.AspNet.Http.Security; -using Microsoft.AspNet.Http.Interfaces.Security; -using Microsoft.AspNet.Security.Infrastructure; -using Microsoft.AspNet.Security.Notifications; +using Microsoft.AspNet.Http.Authentication; +using Microsoft.AspNet.Authentication.Notifications; -namespace Microsoft.AspNet.Security.Cookies +namespace Microsoft.AspNet.Authentication.Cookies { /// - /// Context object passed to the ICookieAuthenticationProvider method ValidateIdentity. + /// Context object passed to the ICookieAuthenticationProvider method ValidatePrincipal. /// - public class CookieValidateIdentityContext : BaseContext + public class CookieValidatePrincipalContext : BaseContext { /// /// Creates a new instance of the context object. @@ -24,18 +20,18 @@ public class CookieValidateIdentityContext : BaseContext /// Contains the initial values for identity and extra data /// - public CookieValidateIdentityContext([NotNull] HttpContext context, [NotNull] AuthenticationTicket ticket, [NotNull] CookieAuthenticationOptions options) + public CookieValidatePrincipalContext([NotNull] HttpContext context, [NotNull] AuthenticationTicket ticket, [NotNull] CookieAuthenticationOptions options) : base(context, options) { - Identity = ticket.Identity; + Principal = ticket.Principal; Properties = ticket.Properties; } /// - /// Contains the claims identity arriving with the request. May be altered to change the + /// Contains the claims principal arriving with the request. May be altered to change the /// details of the authenticated user. /// - public ClaimsIdentity Identity { get; private set; } + public ClaimsPrincipal Principal { get; private set; } /// /// Contains the extra meta-data arriving with the request ticket. May be altered. @@ -43,22 +39,22 @@ public CookieValidateIdentityContext([NotNull] HttpContext context, [NotNull] Au public AuthenticationProperties Properties { get; private set; } /// - /// Called to replace the claims identity. The supplied identity will replace the value of the - /// Identity property, which determines the identity of the authenticated request. + /// Called to replace the claims principal. The supplied principal will replace the value of the + /// Principal property, which determines the identity of the authenticated request. /// /// The identity used as the replacement - public void ReplaceIdentity(IIdentity identity) + public void ReplacePrincipal(IPrincipal principal) { - Identity = new ClaimsIdentity(identity); + Principal = new ClaimsPrincipal(principal); } /// - /// Called to reject the incoming identity. This may be done if the application has determined the + /// Called to reject the incoming principal. This may be done if the application has determined the /// account is no longer active, and the request should be treated as if it was anonymous. /// - public void RejectIdentity() + public void RejectPrincipal() { - Identity = null; + Principal = null; } } } diff --git a/src/Microsoft.AspNet.Security.Cookies/Notifications/DefaultBehavior.cs b/src/Microsoft.AspNet.Authentication.Cookies/Notifications/DefaultBehavior.cs similarity index 97% rename from src/Microsoft.AspNet.Security.Cookies/Notifications/DefaultBehavior.cs rename to src/Microsoft.AspNet.Authentication.Cookies/Notifications/DefaultBehavior.cs index 65515c329..0e0ed537c 100644 --- a/src/Microsoft.AspNet.Security.Cookies/Notifications/DefaultBehavior.cs +++ b/src/Microsoft.AspNet.Authentication.Cookies/Notifications/DefaultBehavior.cs @@ -6,7 +6,7 @@ using Microsoft.AspNet.Http; using Newtonsoft.Json; -namespace Microsoft.AspNet.Security.Cookies +namespace Microsoft.AspNet.Authentication.Cookies { internal static class DefaultBehavior { diff --git a/src/Microsoft.AspNet.Security.Cookies/Notifications/ICookieAuthenticationNotifications.cs b/src/Microsoft.AspNet.Authentication.Cookies/Notifications/ICookieAuthenticationNotifications.cs similarity index 88% rename from src/Microsoft.AspNet.Security.Cookies/Notifications/ICookieAuthenticationNotifications.cs rename to src/Microsoft.AspNet.Authentication.Cookies/Notifications/ICookieAuthenticationNotifications.cs index edfb6b69c..0ede97ce6 100644 --- a/src/Microsoft.AspNet.Security.Cookies/Notifications/ICookieAuthenticationNotifications.cs +++ b/src/Microsoft.AspNet.Authentication.Cookies/Notifications/ICookieAuthenticationNotifications.cs @@ -4,7 +4,7 @@ using System.Threading.Tasks; -namespace Microsoft.AspNet.Security.Cookies +namespace Microsoft.AspNet.Authentication.Cookies { /// /// Specifies callback methods which the invokes to enable developer control over the authentication process. /> @@ -12,12 +12,12 @@ namespace Microsoft.AspNet.Security.Cookies public interface ICookieAuthenticationNotifications { /// - /// Called each time a request identity has been validated by the middleware. By implementing this method the - /// application may alter or reject the identity which has arrived with the request. + /// Called each time a request principal has been validated by the middleware. By implementing this method the + /// application may alter or reject the principal which has arrived with the request. /// /// Contains information about the login session as well as the user . /// A representing the completed operation. - Task ValidateIdentity(CookieValidateIdentityContext context); + Task ValidatePrincipal(CookieValidatePrincipalContext context); /// /// Called when an endpoint has provided sign in information before it is converted into a cookie. By diff --git a/src/Microsoft.AspNet.Security.Cookies/Resources.Designer.cs b/src/Microsoft.AspNet.Authentication.Cookies/Resources.Designer.cs similarity index 95% rename from src/Microsoft.AspNet.Security.Cookies/Resources.Designer.cs rename to src/Microsoft.AspNet.Authentication.Cookies/Resources.Designer.cs index 1a0258ba6..ef0e62fb4 100644 --- a/src/Microsoft.AspNet.Security.Cookies/Resources.Designer.cs +++ b/src/Microsoft.AspNet.Authentication.Cookies/Resources.Designer.cs @@ -8,7 +8,7 @@ // //------------------------------------------------------------------------------ -namespace Microsoft.AspNet.Security.Cookies { +namespace Microsoft.AspNet.Authentication.Cookies { using System; @@ -39,7 +39,7 @@ internal Resources() { internal static global::System.Resources.ResourceManager ResourceManager { get { if (object.ReferenceEquals(resourceMan, null)) { - global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Microsoft.AspNet.Security.Cookies.Resources", System.Reflection.IntrospectionExtensions.GetTypeInfo(typeof(Resources)).Assembly); + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Microsoft.AspNet.Authentication.Cookies.Resources", System.Reflection.IntrospectionExtensions.GetTypeInfo(typeof(Resources)).Assembly); resourceMan = temp; } return resourceMan; diff --git a/src/Microsoft.AspNet.Security.Cookies/Resources.resx b/src/Microsoft.AspNet.Authentication.Cookies/Resources.resx similarity index 100% rename from src/Microsoft.AspNet.Security.Cookies/Resources.resx rename to src/Microsoft.AspNet.Authentication.Cookies/Resources.resx diff --git a/src/Microsoft.AspNet.Security.Cookies/project.json b/src/Microsoft.AspNet.Authentication.Cookies/project.json similarity index 85% rename from src/Microsoft.AspNet.Security.Cookies/project.json rename to src/Microsoft.AspNet.Authentication.Cookies/project.json index 82f92b75b..07d23fdca 100644 --- a/src/Microsoft.AspNet.Security.Cookies/project.json +++ b/src/Microsoft.AspNet.Authentication.Cookies/project.json @@ -2,7 +2,7 @@ "version": "1.0.0-*", "description": "ASP.NET middleware that enables an application to use cookie based authentication, similar to ASP.NET's forms authentication.", "dependencies": { - "Microsoft.AspNet.Security": "1.0.0-*", + "Microsoft.AspNet.Authentication": "1.0.0-*", "Newtonsoft.Json": "6.0.6" }, "frameworks": { diff --git a/src/Microsoft.AspNet.Security.Facebook/FacebookAuthenticationDefaults.cs b/src/Microsoft.AspNet.Authentication.Facebook/FacebookAuthenticationDefaults.cs similarity index 82% rename from src/Microsoft.AspNet.Security.Facebook/FacebookAuthenticationDefaults.cs rename to src/Microsoft.AspNet.Authentication.Facebook/FacebookAuthenticationDefaults.cs index 72addbef8..92b56413a 100644 --- a/src/Microsoft.AspNet.Security.Facebook/FacebookAuthenticationDefaults.cs +++ b/src/Microsoft.AspNet.Authentication.Facebook/FacebookAuthenticationDefaults.cs @@ -1,11 +1,11 @@ // Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -namespace Microsoft.AspNet.Security.Facebook +namespace Microsoft.AspNet.Authentication.Facebook { public static class FacebookAuthenticationDefaults { - public const string AuthenticationType = "Facebook"; + public const string AuthenticationScheme = "Facebook"; public const string AuthorizationEndpoint = "https://www.facebook.com/v2.2/dialog/oauth"; diff --git a/src/Microsoft.AspNet.Security.Facebook/FacebookAuthenticationExtensions.cs b/src/Microsoft.AspNet.Authentication.Facebook/FacebookAuthenticationExtensions.cs similarity index 96% rename from src/Microsoft.AspNet.Security.Facebook/FacebookAuthenticationExtensions.cs rename to src/Microsoft.AspNet.Authentication.Facebook/FacebookAuthenticationExtensions.cs index 51c5eac0e..3664bb592 100644 --- a/src/Microsoft.AspNet.Security.Facebook/FacebookAuthenticationExtensions.cs +++ b/src/Microsoft.AspNet.Authentication.Facebook/FacebookAuthenticationExtensions.cs @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -using Microsoft.AspNet.Security.Facebook; +using Microsoft.AspNet.Authentication.Facebook; using Microsoft.Framework.DependencyInjection; using Microsoft.Framework.OptionsModel; using System; diff --git a/src/Microsoft.AspNet.Security.Facebook/FacebookAuthenticationHandler.cs b/src/Microsoft.AspNet.Authentication.Facebook/FacebookAuthenticationHandler.cs similarity index 78% rename from src/Microsoft.AspNet.Security.Facebook/FacebookAuthenticationHandler.cs rename to src/Microsoft.AspNet.Authentication.Facebook/FacebookAuthenticationHandler.cs index 7eabae101..5f2d5b886 100644 --- a/src/Microsoft.AspNet.Security.Facebook/FacebookAuthenticationHandler.cs +++ b/src/Microsoft.AspNet.Authentication.Facebook/FacebookAuthenticationHandler.cs @@ -11,13 +11,13 @@ using Microsoft.AspNet.Http; using Microsoft.AspNet.Http.Core.Collections; using Microsoft.AspNet.Http.Extensions; -using Microsoft.AspNet.Http.Security; -using Microsoft.AspNet.Security.OAuth; +using Microsoft.AspNet.Http.Authentication; +using Microsoft.AspNet.Authentication.OAuth; using Microsoft.AspNet.WebUtilities; using Microsoft.Framework.Logging; using Newtonsoft.Json.Linq; -namespace Microsoft.AspNet.Security.Facebook +namespace Microsoft.AspNet.Authentication.Facebook { internal class FacebookAuthenticationHandler : OAuthAuthenticationHandler { @@ -65,41 +65,42 @@ protected override async Task GetUserInformationAsync(Auth JObject user = JObject.Parse(text); var context = new FacebookAuthenticatedContext(Context, Options, user, tokens); - context.Identity = new ClaimsIdentity( - Options.AuthenticationType, + var identity = new ClaimsIdentity( + Options.AuthenticationScheme, ClaimsIdentity.DefaultNameClaimType, ClaimsIdentity.DefaultRoleClaimType); if (!string.IsNullOrEmpty(context.Id)) { - context.Identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, context.Id, ClaimValueTypes.String, Options.AuthenticationType)); + identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, context.Id, ClaimValueTypes.String, Options.AuthenticationScheme)); } if (!string.IsNullOrEmpty(context.UserName)) { - context.Identity.AddClaim(new Claim(ClaimsIdentity.DefaultNameClaimType, context.UserName, ClaimValueTypes.String, Options.AuthenticationType)); + identity.AddClaim(new Claim(ClaimsIdentity.DefaultNameClaimType, context.UserName, ClaimValueTypes.String, Options.AuthenticationScheme)); } if (!string.IsNullOrEmpty(context.Email)) { - context.Identity.AddClaim(new Claim(ClaimTypes.Email, context.Email, ClaimValueTypes.String, Options.AuthenticationType)); + identity.AddClaim(new Claim(ClaimTypes.Email, context.Email, ClaimValueTypes.String, Options.AuthenticationScheme)); } if (!string.IsNullOrEmpty(context.Name)) { - context.Identity.AddClaim(new Claim("urn:facebook:name", context.Name, ClaimValueTypes.String, Options.AuthenticationType)); + identity.AddClaim(new Claim("urn:facebook:name", context.Name, ClaimValueTypes.String, Options.AuthenticationScheme)); // Many Facebook accounts do not set the UserName field. Fall back to the Name field instead. if (string.IsNullOrEmpty(context.UserName)) { - context.Identity.AddClaim(new Claim(ClaimsIdentity.DefaultNameClaimType, context.Name, ClaimValueTypes.String, Options.AuthenticationType)); + identity.AddClaim(new Claim(ClaimsIdentity.DefaultNameClaimType, context.Name, ClaimValueTypes.String, Options.AuthenticationScheme)); } } if (!string.IsNullOrEmpty(context.Link)) { - context.Identity.AddClaim(new Claim("urn:facebook:link", context.Link, ClaimValueTypes.String, Options.AuthenticationType)); + identity.AddClaim(new Claim("urn:facebook:link", context.Link, ClaimValueTypes.String, Options.AuthenticationScheme)); } context.Properties = properties; + context.Principal = new ClaimsPrincipal(identity); await Options.Notifications.Authenticated(context); - return new AuthenticationTicket(context.Identity, context.Properties); + return new AuthenticationTicket(context.Principal, context.Properties, context.Options.AuthenticationScheme); } private string GenerateAppSecretProof(string accessToken) diff --git a/src/Microsoft.AspNet.Security.Facebook/FacebookAuthenticationMiddleware.cs b/src/Microsoft.AspNet.Authentication.Facebook/FacebookAuthenticationMiddleware.cs similarity index 95% rename from src/Microsoft.AspNet.Security.Facebook/FacebookAuthenticationMiddleware.cs rename to src/Microsoft.AspNet.Authentication.Facebook/FacebookAuthenticationMiddleware.cs index 4873ea2fd..b74a5be1d 100644 --- a/src/Microsoft.AspNet.Security.Facebook/FacebookAuthenticationMiddleware.cs +++ b/src/Microsoft.AspNet.Authentication.Facebook/FacebookAuthenticationMiddleware.cs @@ -4,13 +4,13 @@ using System; using System.Globalization; using Microsoft.AspNet.Builder; +using Microsoft.AspNet.Authentication; +using Microsoft.AspNet.Authentication.OAuth; using Microsoft.AspNet.DataProtection; -using Microsoft.AspNet.Security.Infrastructure; -using Microsoft.AspNet.Security.OAuth; using Microsoft.Framework.Logging; using Microsoft.Framework.OptionsModel; -namespace Microsoft.AspNet.Security.Facebook +namespace Microsoft.AspNet.Authentication.Facebook { /// /// An ASP.NET middleware for authenticating users using Facebook. diff --git a/src/Microsoft.AspNet.Security.Facebook/FacebookAuthenticationOptions.cs b/src/Microsoft.AspNet.Authentication.Facebook/FacebookAuthenticationOptions.cs similarity index 88% rename from src/Microsoft.AspNet.Security.Facebook/FacebookAuthenticationOptions.cs rename to src/Microsoft.AspNet.Authentication.Facebook/FacebookAuthenticationOptions.cs index 172057184..119bd25b8 100644 --- a/src/Microsoft.AspNet.Security.Facebook/FacebookAuthenticationOptions.cs +++ b/src/Microsoft.AspNet.Authentication.Facebook/FacebookAuthenticationOptions.cs @@ -2,9 +2,9 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using Microsoft.AspNet.Http; -using Microsoft.AspNet.Security.OAuth; +using Microsoft.AspNet.Authentication.OAuth; -namespace Microsoft.AspNet.Security.Facebook +namespace Microsoft.AspNet.Authentication.Facebook { /// /// Configuration options for . @@ -16,8 +16,8 @@ public class FacebookAuthenticationOptions : OAuthAuthenticationOptions public FacebookAuthenticationOptions() { - AuthenticationType = FacebookAuthenticationDefaults.AuthenticationType; - Caption = AuthenticationType; + AuthenticationScheme = FacebookAuthenticationDefaults.AuthenticationScheme; + Caption = AuthenticationScheme; CallbackPath = new PathString("/signin-facebook"); SendAppSecretProof = true; AuthorizationEndpoint = FacebookAuthenticationDefaults.AuthorizationEndpoint; diff --git a/src/Microsoft.AspNet.Security.Facebook/Microsoft.AspNet.Security.Facebook.kproj b/src/Microsoft.AspNet.Authentication.Facebook/Microsoft.AspNet.Authentication.Facebook.kproj similarity index 95% rename from src/Microsoft.AspNet.Security.Facebook/Microsoft.AspNet.Security.Facebook.kproj rename to src/Microsoft.AspNet.Authentication.Facebook/Microsoft.AspNet.Authentication.Facebook.kproj index 8a4224835..ed5242e07 100644 --- a/src/Microsoft.AspNet.Security.Facebook/Microsoft.AspNet.Security.Facebook.kproj +++ b/src/Microsoft.AspNet.Authentication.Facebook/Microsoft.AspNet.Authentication.Facebook.kproj @@ -1,4 +1,4 @@ - + 14.0 @@ -14,4 +14,4 @@ 2.0 - + \ No newline at end of file diff --git a/src/Microsoft.AspNet.Authentication.Facebook/NotNullAttribute.cs b/src/Microsoft.AspNet.Authentication.Facebook/NotNullAttribute.cs new file mode 100644 index 000000000..5ce6d99dd --- /dev/null +++ b/src/Microsoft.AspNet.Authentication.Facebook/NotNullAttribute.cs @@ -0,0 +1,12 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; + +namespace Microsoft.AspNet.Authentication.Facebook +{ + [AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false)] + internal sealed class NotNullAttribute : Attribute + { + } +} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Security.Facebook/Notifications/FacebookAuthenticatedContext.cs b/src/Microsoft.AspNet.Authentication.Facebook/Notifications/FacebookAuthenticatedContext.cs similarity index 95% rename from src/Microsoft.AspNet.Security.Facebook/Notifications/FacebookAuthenticatedContext.cs rename to src/Microsoft.AspNet.Authentication.Facebook/Notifications/FacebookAuthenticatedContext.cs index aa4e07daa..b64f6dd38 100644 --- a/src/Microsoft.AspNet.Security.Facebook/Notifications/FacebookAuthenticatedContext.cs +++ b/src/Microsoft.AspNet.Authentication.Facebook/Notifications/FacebookAuthenticatedContext.cs @@ -3,10 +3,10 @@ using System.Net.Http; using Microsoft.AspNet.Http; -using Microsoft.AspNet.Security.OAuth; +using Microsoft.AspNet.Authentication.OAuth; using Newtonsoft.Json.Linq; -namespace Microsoft.AspNet.Security.Facebook +namespace Microsoft.AspNet.Authentication.Facebook { /// /// Contains information about the login session as well as the user . diff --git a/src/Microsoft.AspNet.Security.Facebook/Notifications/FacebookAuthenticationNotifications.cs b/src/Microsoft.AspNet.Authentication.Facebook/Notifications/FacebookAuthenticationNotifications.cs similarity index 94% rename from src/Microsoft.AspNet.Security.Facebook/Notifications/FacebookAuthenticationNotifications.cs rename to src/Microsoft.AspNet.Authentication.Facebook/Notifications/FacebookAuthenticationNotifications.cs index f86287cc1..b89ad5c3b 100644 --- a/src/Microsoft.AspNet.Security.Facebook/Notifications/FacebookAuthenticationNotifications.cs +++ b/src/Microsoft.AspNet.Authentication.Facebook/Notifications/FacebookAuthenticationNotifications.cs @@ -3,9 +3,9 @@ using System; using System.Threading.Tasks; -using Microsoft.AspNet.Security.OAuth; +using Microsoft.AspNet.Authentication.OAuth; -namespace Microsoft.AspNet.Security.Facebook +namespace Microsoft.AspNet.Authentication.Facebook { /// /// The default implementation. diff --git a/src/Microsoft.AspNet.Security.Facebook/Notifications/IFacebookAuthenticationNotifications.cs b/src/Microsoft.AspNet.Authentication.Facebook/Notifications/IFacebookAuthenticationNotifications.cs similarity index 90% rename from src/Microsoft.AspNet.Security.Facebook/Notifications/IFacebookAuthenticationNotifications.cs rename to src/Microsoft.AspNet.Authentication.Facebook/Notifications/IFacebookAuthenticationNotifications.cs index 0849a84a0..247715f93 100644 --- a/src/Microsoft.AspNet.Security.Facebook/Notifications/IFacebookAuthenticationNotifications.cs +++ b/src/Microsoft.AspNet.Authentication.Facebook/Notifications/IFacebookAuthenticationNotifications.cs @@ -2,9 +2,9 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System.Threading.Tasks; -using Microsoft.AspNet.Security.OAuth; +using Microsoft.AspNet.Authentication.OAuth; -namespace Microsoft.AspNet.Security.Facebook +namespace Microsoft.AspNet.Authentication.Facebook { /// /// Specifies callback methods which the invokes to enable developer control over the authentication process. diff --git a/src/Microsoft.AspNet.Security.Facebook/Resources.Designer.cs b/src/Microsoft.AspNet.Authentication.Facebook/Resources.Designer.cs similarity index 94% rename from src/Microsoft.AspNet.Security.Facebook/Resources.Designer.cs rename to src/Microsoft.AspNet.Authentication.Facebook/Resources.Designer.cs index 18a738d70..dd3f0e3fa 100644 --- a/src/Microsoft.AspNet.Security.Facebook/Resources.Designer.cs +++ b/src/Microsoft.AspNet.Authentication.Facebook/Resources.Designer.cs @@ -8,7 +8,7 @@ // //------------------------------------------------------------------------------ -namespace Microsoft.AspNet.Security.Facebook { +namespace Microsoft.AspNet.Authentication.Facebook { using System; @@ -39,7 +39,7 @@ internal Resources() { internal static global::System.Resources.ResourceManager ResourceManager { get { if (object.ReferenceEquals(resourceMan, null)) { - global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Microsoft.AspNet.Security.Facebook.Resources", System.Reflection.IntrospectionExtensions.GetTypeInfo(typeof(Resources)).Assembly); + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Microsoft.AspNet.Authentication.Facebook.Resources", System.Reflection.IntrospectionExtensions.GetTypeInfo(typeof(Resources)).Assembly); resourceMan = temp; } return resourceMan; diff --git a/src/Microsoft.AspNet.Security.Facebook/Resources.resx b/src/Microsoft.AspNet.Authentication.Facebook/Resources.resx similarity index 100% rename from src/Microsoft.AspNet.Security.Facebook/Resources.resx rename to src/Microsoft.AspNet.Authentication.Facebook/Resources.resx diff --git a/src/Microsoft.AspNet.Security.Facebook/project.json b/src/Microsoft.AspNet.Authentication.Facebook/project.json similarity index 81% rename from src/Microsoft.AspNet.Security.Facebook/project.json rename to src/Microsoft.AspNet.Authentication.Facebook/project.json index 3aad11e61..fd1a44d15 100644 --- a/src/Microsoft.AspNet.Security.Facebook/project.json +++ b/src/Microsoft.AspNet.Authentication.Facebook/project.json @@ -2,7 +2,7 @@ "version": "1.0.0-*", "description": "ASP.NET 5 middleware that enables an application to support Facebook's OAuth 2.0 authentication workflow.", "dependencies": { - "Microsoft.AspNet.Security.OAuth": "1.0.0-*" + "Microsoft.AspNet.Authentication.OAuth": "1.0.0-*" }, "frameworks": { "aspnet50": { }, diff --git a/src/Microsoft.AspNet.Security.Google/GoogleAuthenticationDefaults.cs b/src/Microsoft.AspNet.Authentication.Google/GoogleAuthenticationDefaults.cs similarity index 83% rename from src/Microsoft.AspNet.Security.Google/GoogleAuthenticationDefaults.cs rename to src/Microsoft.AspNet.Authentication.Google/GoogleAuthenticationDefaults.cs index acf982906..3c163c111 100644 --- a/src/Microsoft.AspNet.Security.Google/GoogleAuthenticationDefaults.cs +++ b/src/Microsoft.AspNet.Authentication.Google/GoogleAuthenticationDefaults.cs @@ -1,11 +1,11 @@ // Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -namespace Microsoft.AspNet.Security.Google +namespace Microsoft.AspNet.Authentication.Google { public static class GoogleAuthenticationDefaults { - public const string AuthenticationType = "Google"; + public const string AuthenticationScheme = "Google"; public const string AuthorizationEndpoint = "https://accounts.google.com/o/oauth2/auth"; diff --git a/src/Microsoft.AspNet.Security.Google/GoogleAuthenticationExtensions.cs b/src/Microsoft.AspNet.Authentication.Google/GoogleAuthenticationExtensions.cs similarity index 97% rename from src/Microsoft.AspNet.Security.Google/GoogleAuthenticationExtensions.cs rename to src/Microsoft.AspNet.Authentication.Google/GoogleAuthenticationExtensions.cs index 474df5e32..fd46b062a 100644 --- a/src/Microsoft.AspNet.Security.Google/GoogleAuthenticationExtensions.cs +++ b/src/Microsoft.AspNet.Authentication.Google/GoogleAuthenticationExtensions.cs @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -using Microsoft.AspNet.Security.Google; +using Microsoft.AspNet.Authentication.Google; using Microsoft.Framework.DependencyInjection; using Microsoft.Framework.OptionsModel; using System; diff --git a/src/Microsoft.AspNet.Security.Google/GoogleAuthenticationHandler.cs b/src/Microsoft.AspNet.Authentication.Google/GoogleAuthenticationHandler.cs similarity index 78% rename from src/Microsoft.AspNet.Security.Google/GoogleAuthenticationHandler.cs rename to src/Microsoft.AspNet.Authentication.Google/GoogleAuthenticationHandler.cs index 1d75c889f..71e51f06a 100644 --- a/src/Microsoft.AspNet.Security.Google/GoogleAuthenticationHandler.cs +++ b/src/Microsoft.AspNet.Authentication.Google/GoogleAuthenticationHandler.cs @@ -7,13 +7,13 @@ using System.Net.Http.Headers; using System.Security.Claims; using System.Threading.Tasks; -using Microsoft.AspNet.Http.Security; -using Microsoft.AspNet.Security.OAuth; +using Microsoft.AspNet.Http.Authentication; +using Microsoft.AspNet.Authentication.OAuth; using Microsoft.AspNet.WebUtilities; using Microsoft.Framework.Logging; using Newtonsoft.Json.Linq; -namespace Microsoft.AspNet.Security.Google +namespace Microsoft.AspNet.Authentication.Google { internal class GoogleAuthenticationHandler : OAuthAuthenticationHandler { @@ -33,46 +33,47 @@ protected override async Task GetUserInformationAsync(Auth JObject user = JObject.Parse(text); var context = new GoogleAuthenticatedContext(Context, Options, user, tokens); - context.Identity = new ClaimsIdentity( - Options.AuthenticationType, + var identity = new ClaimsIdentity( + Options.AuthenticationScheme, ClaimsIdentity.DefaultNameClaimType, ClaimsIdentity.DefaultRoleClaimType); if (!string.IsNullOrEmpty(context.Id)) { - context.Identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, context.Id, - ClaimValueTypes.String, Options.AuthenticationType)); + identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, context.Id, + ClaimValueTypes.String, Options.AuthenticationScheme)); } if (!string.IsNullOrEmpty(context.GivenName)) { - context.Identity.AddClaim(new Claim(ClaimTypes.GivenName, context.GivenName, - ClaimValueTypes.String, Options.AuthenticationType)); + identity.AddClaim(new Claim(ClaimTypes.GivenName, context.GivenName, + ClaimValueTypes.String, Options.AuthenticationScheme)); } if (!string.IsNullOrEmpty(context.FamilyName)) { - context.Identity.AddClaim(new Claim(ClaimTypes.Surname, context.FamilyName, - ClaimValueTypes.String, Options.AuthenticationType)); + identity.AddClaim(new Claim(ClaimTypes.Surname, context.FamilyName, + ClaimValueTypes.String, Options.AuthenticationScheme)); } if (!string.IsNullOrEmpty(context.Name)) { - context.Identity.AddClaim(new Claim(ClaimTypes.Name, context.Name, ClaimValueTypes.String, - Options.AuthenticationType)); + identity.AddClaim(new Claim(ClaimTypes.Name, context.Name, ClaimValueTypes.String, + Options.AuthenticationScheme)); } if (!string.IsNullOrEmpty(context.Email)) { - context.Identity.AddClaim(new Claim(ClaimTypes.Email, context.Email, ClaimValueTypes.String, - Options.AuthenticationType)); + identity.AddClaim(new Claim(ClaimTypes.Email, context.Email, ClaimValueTypes.String, + Options.AuthenticationScheme)); } if (!string.IsNullOrEmpty(context.Profile)) { - context.Identity.AddClaim(new Claim("urn:google:profile", context.Profile, ClaimValueTypes.String, - Options.AuthenticationType)); + identity.AddClaim(new Claim("urn:google:profile", context.Profile, ClaimValueTypes.String, + Options.AuthenticationScheme)); } context.Properties = properties; + context.Principal = new ClaimsPrincipal(identity); await Options.Notifications.Authenticated(context); - return new AuthenticationTicket(context.Identity, context.Properties); + return new AuthenticationTicket(context.Principal, context.Properties, context.Options.AuthenticationScheme); } // TODO: Abstract this properties override pattern into the base class? diff --git a/src/Microsoft.AspNet.Security.Google/GoogleAuthenticationMiddleware.cs b/src/Microsoft.AspNet.Authentication.Google/GoogleAuthenticationMiddleware.cs similarity index 94% rename from src/Microsoft.AspNet.Security.Google/GoogleAuthenticationMiddleware.cs rename to src/Microsoft.AspNet.Authentication.Google/GoogleAuthenticationMiddleware.cs index a72c0524f..0da3f4928 100644 --- a/src/Microsoft.AspNet.Security.Google/GoogleAuthenticationMiddleware.cs +++ b/src/Microsoft.AspNet.Authentication.Google/GoogleAuthenticationMiddleware.cs @@ -5,15 +5,15 @@ using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.Net.Http; +using Microsoft.AspNet.Authentication; +using Microsoft.AspNet.Authentication.DataHandler; using Microsoft.AspNet.Builder; using Microsoft.AspNet.DataProtection; -using Microsoft.AspNet.Security.DataHandler; -using Microsoft.AspNet.Security.Infrastructure; -using Microsoft.AspNet.Security.OAuth; +using Microsoft.AspNet.Authentication.OAuth; using Microsoft.Framework.Logging; using Microsoft.Framework.OptionsModel; -namespace Microsoft.AspNet.Security.Google +namespace Microsoft.AspNet.Authentication.Google { /// /// An ASP.NET middleware for authenticating users using Google OAuth 2.0. diff --git a/src/Microsoft.AspNet.Security.Google/GoogleAuthenticationOptions.cs b/src/Microsoft.AspNet.Authentication.Google/GoogleAuthenticationOptions.cs similarity index 81% rename from src/Microsoft.AspNet.Security.Google/GoogleAuthenticationOptions.cs rename to src/Microsoft.AspNet.Authentication.Google/GoogleAuthenticationOptions.cs index 4cfb97bbb..e562a8f2c 100644 --- a/src/Microsoft.AspNet.Security.Google/GoogleAuthenticationOptions.cs +++ b/src/Microsoft.AspNet.Authentication.Google/GoogleAuthenticationOptions.cs @@ -5,10 +5,10 @@ using System.Collections.Generic; using System.Net.Http; using Microsoft.AspNet.Http; -using Microsoft.AspNet.Http.Security; -using Microsoft.AspNet.Security.OAuth; +using Microsoft.AspNet.Http.Authentication; +using Microsoft.AspNet.Authentication.OAuth; -namespace Microsoft.AspNet.Security.Google +namespace Microsoft.AspNet.Authentication.Google { /// /// Configuration options for . @@ -20,8 +20,8 @@ public class GoogleAuthenticationOptions : OAuthAuthenticationOptions public GoogleAuthenticationOptions() { - AuthenticationType = GoogleAuthenticationDefaults.AuthenticationType; - Caption = AuthenticationType; + AuthenticationScheme = GoogleAuthenticationDefaults.AuthenticationScheme; + Caption = AuthenticationScheme; CallbackPath = new PathString("/signin-google"); AuthorizationEndpoint = GoogleAuthenticationDefaults.AuthorizationEndpoint; TokenEndpoint = GoogleAuthenticationDefaults.TokenEndpoint; diff --git a/src/Microsoft.AspNet.Security.Google/Microsoft.AspNet.Security.Google.kproj b/src/Microsoft.AspNet.Authentication.Google/Microsoft.AspNet.Authentication.Google.kproj similarity index 95% rename from src/Microsoft.AspNet.Security.Google/Microsoft.AspNet.Security.Google.kproj rename to src/Microsoft.AspNet.Authentication.Google/Microsoft.AspNet.Authentication.Google.kproj index 32f8d92b2..6c85b04ce 100644 --- a/src/Microsoft.AspNet.Security.Google/Microsoft.AspNet.Security.Google.kproj +++ b/src/Microsoft.AspNet.Authentication.Google/Microsoft.AspNet.Authentication.Google.kproj @@ -1,4 +1,4 @@ - + 14.0 @@ -14,4 +14,4 @@ 2.0 - + \ No newline at end of file diff --git a/src/Microsoft.AspNet.Security.Cookies/NotNullAttribute.cs b/src/Microsoft.AspNet.Authentication.Google/NotNullAttribute.cs similarity index 87% rename from src/Microsoft.AspNet.Security.Cookies/NotNullAttribute.cs rename to src/Microsoft.AspNet.Authentication.Google/NotNullAttribute.cs index 0460d0016..504a02c4d 100644 --- a/src/Microsoft.AspNet.Security.Cookies/NotNullAttribute.cs +++ b/src/Microsoft.AspNet.Authentication.Google/NotNullAttribute.cs @@ -3,7 +3,7 @@ using System; -namespace Microsoft.AspNet.Security.Cookies +namespace Microsoft.AspNet.Authentication.Google { [AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false)] internal sealed class NotNullAttribute : Attribute diff --git a/src/Microsoft.AspNet.Security.Google/Notifications/GoogleAuthenticatedContext.cs b/src/Microsoft.AspNet.Authentication.Google/Notifications/GoogleAuthenticatedContext.cs similarity index 96% rename from src/Microsoft.AspNet.Security.Google/Notifications/GoogleAuthenticatedContext.cs rename to src/Microsoft.AspNet.Authentication.Google/Notifications/GoogleAuthenticatedContext.cs index 10fa2b370..a18ba2040 100644 --- a/src/Microsoft.AspNet.Security.Google/Notifications/GoogleAuthenticatedContext.cs +++ b/src/Microsoft.AspNet.Authentication.Google/Notifications/GoogleAuthenticatedContext.cs @@ -6,11 +6,11 @@ using System.Net.Http; using System.Security.Claims; using Microsoft.AspNet.Http; -using Microsoft.AspNet.Http.Security; -using Microsoft.AspNet.Security.OAuth; +using Microsoft.AspNet.Http.Authentication; +using Microsoft.AspNet.Authentication.OAuth; using Newtonsoft.Json.Linq; -namespace Microsoft.AspNet.Security.Google +namespace Microsoft.AspNet.Authentication.Google { /// /// Contains information about the login session as well as the user . diff --git a/src/Microsoft.AspNet.Security.Google/Notifications/GoogleAuthenticationNotifications.cs b/src/Microsoft.AspNet.Authentication.Google/Notifications/GoogleAuthenticationNotifications.cs similarity index 94% rename from src/Microsoft.AspNet.Security.Google/Notifications/GoogleAuthenticationNotifications.cs rename to src/Microsoft.AspNet.Authentication.Google/Notifications/GoogleAuthenticationNotifications.cs index ef2e5d3ce..27d24e3cd 100644 --- a/src/Microsoft.AspNet.Security.Google/Notifications/GoogleAuthenticationNotifications.cs +++ b/src/Microsoft.AspNet.Authentication.Google/Notifications/GoogleAuthenticationNotifications.cs @@ -3,9 +3,9 @@ using System; using System.Threading.Tasks; -using Microsoft.AspNet.Security.OAuth; +using Microsoft.AspNet.Authentication.OAuth; -namespace Microsoft.AspNet.Security.Google +namespace Microsoft.AspNet.Authentication.Google { /// /// The default implementation. diff --git a/src/Microsoft.AspNet.Security.Google/Notifications/IGoogleAuthenticationNotifications.cs b/src/Microsoft.AspNet.Authentication.Google/Notifications/IGoogleAuthenticationNotifications.cs similarity index 91% rename from src/Microsoft.AspNet.Security.Google/Notifications/IGoogleAuthenticationNotifications.cs rename to src/Microsoft.AspNet.Authentication.Google/Notifications/IGoogleAuthenticationNotifications.cs index 9cf9d2dd5..e9f7c492e 100644 --- a/src/Microsoft.AspNet.Security.Google/Notifications/IGoogleAuthenticationNotifications.cs +++ b/src/Microsoft.AspNet.Authentication.Google/Notifications/IGoogleAuthenticationNotifications.cs @@ -2,9 +2,9 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System.Threading.Tasks; -using Microsoft.AspNet.Security.OAuth; +using Microsoft.AspNet.Authentication.OAuth; -namespace Microsoft.AspNet.Security.Google +namespace Microsoft.AspNet.Authentication.Google { /// /// Specifies callback methods which the invokes to enable developer control over the authentication process. diff --git a/src/Microsoft.AspNet.Security.Google/Resources.Designer.cs b/src/Microsoft.AspNet.Authentication.Google/Resources.Designer.cs similarity index 95% rename from src/Microsoft.AspNet.Security.Google/Resources.Designer.cs rename to src/Microsoft.AspNet.Authentication.Google/Resources.Designer.cs index 235dcbeef..efa7d64ed 100644 --- a/src/Microsoft.AspNet.Security.Google/Resources.Designer.cs +++ b/src/Microsoft.AspNet.Authentication.Google/Resources.Designer.cs @@ -8,7 +8,7 @@ // //------------------------------------------------------------------------------ -namespace Microsoft.AspNet.Security.Google { +namespace Microsoft.AspNet.Authentication.Google { using System; @@ -39,7 +39,7 @@ internal Resources() { internal static global::System.Resources.ResourceManager ResourceManager { get { if (object.ReferenceEquals(resourceMan, null)) { - global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Microsoft.AspNet.Security.Google.Resources", System.Reflection.IntrospectionExtensions.GetTypeInfo(typeof(Resources)).Assembly); + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Microsoft.AspNet.Authentication.Google.Resources", System.Reflection.IntrospectionExtensions.GetTypeInfo(typeof(Resources)).Assembly); resourceMan = temp; } return resourceMan; diff --git a/src/Microsoft.AspNet.Security.Google/Resources.resx b/src/Microsoft.AspNet.Authentication.Google/Resources.resx similarity index 100% rename from src/Microsoft.AspNet.Security.Google/Resources.resx rename to src/Microsoft.AspNet.Authentication.Google/Resources.resx diff --git a/src/Microsoft.AspNet.Security.Google/project.json b/src/Microsoft.AspNet.Authentication.Google/project.json similarity index 81% rename from src/Microsoft.AspNet.Security.Google/project.json rename to src/Microsoft.AspNet.Authentication.Google/project.json index a4815b181..cdaa62882 100644 --- a/src/Microsoft.AspNet.Security.Google/project.json +++ b/src/Microsoft.AspNet.Authentication.Google/project.json @@ -2,7 +2,7 @@ "version": "1.0.0-*", "description": "ASP.NET 5 contains middlewares to support Google's OpenId and OAuth 2.0 authentication workflows.", "dependencies": { - "Microsoft.AspNet.Security.OAuth": "1.0.0-*" + "Microsoft.AspNet.Authentication.OAuth": "1.0.0-*" }, "frameworks": { "aspnet50": { }, diff --git a/src/Microsoft.AspNet.Security.MicrosoftAccount/Microsoft.AspNet.Security.MicrosoftAccount.kproj b/src/Microsoft.AspNet.Authentication.MicrosoftAccount/Microsoft.AspNet.Authentication.MicrosoftAccount.kproj similarity index 100% rename from src/Microsoft.AspNet.Security.MicrosoftAccount/Microsoft.AspNet.Security.MicrosoftAccount.kproj rename to src/Microsoft.AspNet.Authentication.MicrosoftAccount/Microsoft.AspNet.Authentication.MicrosoftAccount.kproj diff --git a/src/Microsoft.AspNet.Security.MicrosoftAccount/MicrosoftAccountAuthenticationDefaults.cs b/src/Microsoft.AspNet.Authentication.MicrosoftAccount/MicrosoftAccountAuthenticationDefaults.cs similarity index 81% rename from src/Microsoft.AspNet.Security.MicrosoftAccount/MicrosoftAccountAuthenticationDefaults.cs rename to src/Microsoft.AspNet.Authentication.MicrosoftAccount/MicrosoftAccountAuthenticationDefaults.cs index 825ab4121..22ca51751 100644 --- a/src/Microsoft.AspNet.Security.MicrosoftAccount/MicrosoftAccountAuthenticationDefaults.cs +++ b/src/Microsoft.AspNet.Authentication.MicrosoftAccount/MicrosoftAccountAuthenticationDefaults.cs @@ -1,11 +1,11 @@ // Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -namespace Microsoft.AspNet.Security.MicrosoftAccount +namespace Microsoft.AspNet.Authentication.MicrosoftAccount { public static class MicrosoftAccountAuthenticationDefaults { - public const string AuthenticationType = "Microsoft"; + public const string AuthenticationScheme = "Microsoft"; public const string AuthorizationEndpoint = "https://login.live.com/oauth20_authorize.srf"; diff --git a/src/Microsoft.AspNet.Security.MicrosoftAccount/MicrosoftAccountAuthenticationExtensions.cs b/src/Microsoft.AspNet.Authentication.MicrosoftAccount/MicrosoftAccountAuthenticationExtensions.cs similarity index 95% rename from src/Microsoft.AspNet.Security.MicrosoftAccount/MicrosoftAccountAuthenticationExtensions.cs rename to src/Microsoft.AspNet.Authentication.MicrosoftAccount/MicrosoftAccountAuthenticationExtensions.cs index 912271da6..397a1b32b 100644 --- a/src/Microsoft.AspNet.Security.MicrosoftAccount/MicrosoftAccountAuthenticationExtensions.cs +++ b/src/Microsoft.AspNet.Authentication.MicrosoftAccount/MicrosoftAccountAuthenticationExtensions.cs @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -using Microsoft.AspNet.Security.MicrosoftAccount; +using Microsoft.AspNet.Authentication.MicrosoftAccount; using Microsoft.Framework.DependencyInjection; using Microsoft.Framework.OptionsModel; using System; diff --git a/src/Microsoft.AspNet.Security.MicrosoftAccount/MicrosoftAccountAuthenticationHandler.cs b/src/Microsoft.AspNet.Authentication.MicrosoftAccount/MicrosoftAccountAuthenticationHandler.cs similarity index 73% rename from src/Microsoft.AspNet.Security.MicrosoftAccount/MicrosoftAccountAuthenticationHandler.cs rename to src/Microsoft.AspNet.Authentication.MicrosoftAccount/MicrosoftAccountAuthenticationHandler.cs index 502eaec13..bb953cc13 100644 --- a/src/Microsoft.AspNet.Security.MicrosoftAccount/MicrosoftAccountAuthenticationHandler.cs +++ b/src/Microsoft.AspNet.Authentication.MicrosoftAccount/MicrosoftAccountAuthenticationHandler.cs @@ -8,12 +8,12 @@ using System.Security.Claims; using System.Threading.Tasks; using Microsoft.AspNet.Http; -using Microsoft.AspNet.Http.Security; -using Microsoft.AspNet.Security.OAuth; +using Microsoft.AspNet.Http.Authentication; +using Microsoft.AspNet.Authentication.OAuth; using Microsoft.Framework.Logging; using Newtonsoft.Json.Linq; -namespace Microsoft.AspNet.Security.MicrosoftAccount +namespace Microsoft.AspNet.Authentication.MicrosoftAccount { internal class MicrosoftAccountAuthenticationHandler : OAuthAuthenticationHandler { @@ -33,26 +33,27 @@ protected override async Task GetUserInformationAsync(Auth var context = new MicrosoftAccountAuthenticatedContext(Context, Options, accountInformation, tokens); context.Properties = properties; - context.Identity = new ClaimsIdentity( + var identity = new ClaimsIdentity( new[] { - new Claim(ClaimTypes.NameIdentifier, context.Id, ClaimValueTypes.String, Options.AuthenticationType), - new Claim(ClaimTypes.Name, context.Name, ClaimValueTypes.String, Options.AuthenticationType), - new Claim("urn:microsoftaccount:id", context.Id, ClaimValueTypes.String, Options.AuthenticationType), - new Claim("urn:microsoftaccount:name", context.Name, ClaimValueTypes.String, Options.AuthenticationType) + new Claim(ClaimTypes.NameIdentifier, context.Id, ClaimValueTypes.String, Options.AuthenticationScheme), + new Claim(ClaimTypes.Name, context.Name, ClaimValueTypes.String, Options.AuthenticationScheme), + new Claim("urn:microsoftaccount:id", context.Id, ClaimValueTypes.String, Options.AuthenticationScheme), + new Claim("urn:microsoftaccount:name", context.Name, ClaimValueTypes.String, Options.AuthenticationScheme) }, - Options.AuthenticationType, + Options.AuthenticationScheme, ClaimsIdentity.DefaultNameClaimType, ClaimsIdentity.DefaultRoleClaimType); if (!string.IsNullOrWhiteSpace(context.Email)) { - context.Identity.AddClaim(new Claim(ClaimTypes.Email, context.Email, ClaimValueTypes.String, Options.AuthenticationType)); + identity.AddClaim(new Claim(ClaimTypes.Email, context.Email, ClaimValueTypes.String, Options.AuthenticationScheme)); } + context.Principal = new ClaimsPrincipal(identity); await Options.Notifications.Authenticated(context); - return new AuthenticationTicket(context.Identity, context.Properties); + return new AuthenticationTicket(context.Principal, context.Properties, context.Options.AuthenticationScheme); } } } diff --git a/src/Microsoft.AspNet.Security.MicrosoftAccount/MicrosoftAccountAuthenticationMiddleware.cs b/src/Microsoft.AspNet.Authentication.MicrosoftAccount/MicrosoftAccountAuthenticationMiddleware.cs similarity index 95% rename from src/Microsoft.AspNet.Security.MicrosoftAccount/MicrosoftAccountAuthenticationMiddleware.cs rename to src/Microsoft.AspNet.Authentication.MicrosoftAccount/MicrosoftAccountAuthenticationMiddleware.cs index 5d0afe1f3..ac2ebc184 100644 --- a/src/Microsoft.AspNet.Security.MicrosoftAccount/MicrosoftAccountAuthenticationMiddleware.cs +++ b/src/Microsoft.AspNet.Authentication.MicrosoftAccount/MicrosoftAccountAuthenticationMiddleware.cs @@ -3,14 +3,14 @@ using System; using System.Globalization; +using Microsoft.AspNet.Authentication; +using Microsoft.AspNet.Authentication.OAuth; using Microsoft.AspNet.Builder; using Microsoft.AspNet.DataProtection; -using Microsoft.AspNet.Security.Infrastructure; -using Microsoft.AspNet.Security.OAuth; using Microsoft.Framework.Logging; using Microsoft.Framework.OptionsModel; -namespace Microsoft.AspNet.Security.MicrosoftAccount +namespace Microsoft.AspNet.Authentication.MicrosoftAccount { /// /// An ASP.NET middleware for authenticating users using the Microsoft Account service. diff --git a/src/Microsoft.AspNet.Security.MicrosoftAccount/MicrosoftAccountAuthenticationOptions.cs b/src/Microsoft.AspNet.Authentication.MicrosoftAccount/MicrosoftAccountAuthenticationOptions.cs similarity index 80% rename from src/Microsoft.AspNet.Security.MicrosoftAccount/MicrosoftAccountAuthenticationOptions.cs rename to src/Microsoft.AspNet.Authentication.MicrosoftAccount/MicrosoftAccountAuthenticationOptions.cs index 8755de63b..f97f84b94 100644 --- a/src/Microsoft.AspNet.Security.MicrosoftAccount/MicrosoftAccountAuthenticationOptions.cs +++ b/src/Microsoft.AspNet.Authentication.MicrosoftAccount/MicrosoftAccountAuthenticationOptions.cs @@ -2,9 +2,9 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using Microsoft.AspNet.Http; -using Microsoft.AspNet.Security.OAuth; +using Microsoft.AspNet.Authentication.OAuth; -namespace Microsoft.AspNet.Security.MicrosoftAccount +namespace Microsoft.AspNet.Authentication.MicrosoftAccount { /// /// Configuration options for . @@ -16,8 +16,8 @@ public class MicrosoftAccountAuthenticationOptions : OAuthAuthenticationOptions< /// public MicrosoftAccountAuthenticationOptions() { - AuthenticationType = MicrosoftAccountAuthenticationDefaults.AuthenticationType; - Caption = AuthenticationType; + AuthenticationScheme = MicrosoftAccountAuthenticationDefaults.AuthenticationScheme; + Caption = AuthenticationScheme; CallbackPath = new PathString("/signin-microsoft"); AuthorizationEndpoint = MicrosoftAccountAuthenticationDefaults.AuthorizationEndpoint; TokenEndpoint = MicrosoftAccountAuthenticationDefaults.TokenEndpoint; diff --git a/src/Microsoft.AspNet.Authentication.MicrosoftAccount/NotNullAttribute.cs b/src/Microsoft.AspNet.Authentication.MicrosoftAccount/NotNullAttribute.cs new file mode 100644 index 000000000..f2afa991f --- /dev/null +++ b/src/Microsoft.AspNet.Authentication.MicrosoftAccount/NotNullAttribute.cs @@ -0,0 +1,12 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; + +namespace Microsoft.AspNet.Authentication.MicrosoftAccount +{ + [AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false)] + internal sealed class NotNullAttribute : Attribute + { + } +} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Security.MicrosoftAccount/Notifications/IMicrosoftAccountAuthenticationNotifications.cs b/src/Microsoft.AspNet.Authentication.MicrosoftAccount/Notifications/IMicrosoftAccountAuthenticationNotifications.cs similarity index 90% rename from src/Microsoft.AspNet.Security.MicrosoftAccount/Notifications/IMicrosoftAccountAuthenticationNotifications.cs rename to src/Microsoft.AspNet.Authentication.MicrosoftAccount/Notifications/IMicrosoftAccountAuthenticationNotifications.cs index d6eb0f642..f96040925 100644 --- a/src/Microsoft.AspNet.Security.MicrosoftAccount/Notifications/IMicrosoftAccountAuthenticationNotifications.cs +++ b/src/Microsoft.AspNet.Authentication.MicrosoftAccount/Notifications/IMicrosoftAccountAuthenticationNotifications.cs @@ -2,9 +2,9 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System.Threading.Tasks; -using Microsoft.AspNet.Security.OAuth; +using Microsoft.AspNet.Authentication.OAuth; -namespace Microsoft.AspNet.Security.MicrosoftAccount +namespace Microsoft.AspNet.Authentication.MicrosoftAccount { /// /// Specifies callback methods which the invokes to enable developer control over the authentication process. diff --git a/src/Microsoft.AspNet.Security.MicrosoftAccount/Notifications/MicrosoftAccountAuthenticatedContext.cs b/src/Microsoft.AspNet.Authentication.MicrosoftAccount/Notifications/MicrosoftAccountAuthenticatedContext.cs similarity index 96% rename from src/Microsoft.AspNet.Security.MicrosoftAccount/Notifications/MicrosoftAccountAuthenticatedContext.cs rename to src/Microsoft.AspNet.Authentication.MicrosoftAccount/Notifications/MicrosoftAccountAuthenticatedContext.cs index 8b1a53312..50aea11a9 100644 --- a/src/Microsoft.AspNet.Security.MicrosoftAccount/Notifications/MicrosoftAccountAuthenticatedContext.cs +++ b/src/Microsoft.AspNet.Authentication.MicrosoftAccount/Notifications/MicrosoftAccountAuthenticatedContext.cs @@ -6,10 +6,10 @@ using System.Linq; using System.Net.Http; using Microsoft.AspNet.Http; -using Microsoft.AspNet.Security.OAuth; +using Microsoft.AspNet.Authentication.OAuth; using Newtonsoft.Json.Linq; -namespace Microsoft.AspNet.Security.MicrosoftAccount +namespace Microsoft.AspNet.Authentication.MicrosoftAccount { /// /// Contains information about the login session as well as the user . diff --git a/src/Microsoft.AspNet.Security.MicrosoftAccount/Notifications/MicrosoftAccountAuthenticationNotifications.cs b/src/Microsoft.AspNet.Authentication.MicrosoftAccount/Notifications/MicrosoftAccountAuthenticationNotifications.cs similarity index 93% rename from src/Microsoft.AspNet.Security.MicrosoftAccount/Notifications/MicrosoftAccountAuthenticationNotifications.cs rename to src/Microsoft.AspNet.Authentication.MicrosoftAccount/Notifications/MicrosoftAccountAuthenticationNotifications.cs index 26db09d15..70dc8faa5 100644 --- a/src/Microsoft.AspNet.Security.MicrosoftAccount/Notifications/MicrosoftAccountAuthenticationNotifications.cs +++ b/src/Microsoft.AspNet.Authentication.MicrosoftAccount/Notifications/MicrosoftAccountAuthenticationNotifications.cs @@ -3,9 +3,9 @@ using System; using System.Threading.Tasks; -using Microsoft.AspNet.Security.OAuth; +using Microsoft.AspNet.Authentication.OAuth; -namespace Microsoft.AspNet.Security.MicrosoftAccount +namespace Microsoft.AspNet.Authentication.MicrosoftAccount { /// /// Default implementation. diff --git a/src/Microsoft.AspNet.Security.MicrosoftAccount/Resources.Designer.cs b/src/Microsoft.AspNet.Authentication.MicrosoftAccount/Resources.Designer.cs similarity index 95% rename from src/Microsoft.AspNet.Security.MicrosoftAccount/Resources.Designer.cs rename to src/Microsoft.AspNet.Authentication.MicrosoftAccount/Resources.Designer.cs index 62f1707ef..080d4bc07 100644 --- a/src/Microsoft.AspNet.Security.MicrosoftAccount/Resources.Designer.cs +++ b/src/Microsoft.AspNet.Authentication.MicrosoftAccount/Resources.Designer.cs @@ -8,7 +8,7 @@ // //------------------------------------------------------------------------------ -namespace Microsoft.AspNet.Security.MicrosoftAccount { +namespace Microsoft.AspNet.Authentication.MicrosoftAccount { using System; @@ -39,7 +39,7 @@ internal Resources() { internal static global::System.Resources.ResourceManager ResourceManager { get { if (object.ReferenceEquals(resourceMan, null)) { - global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Microsoft.AspNet.Security.MicrosoftAccount.Resources", System.Reflection.IntrospectionExtensions.GetTypeInfo(typeof(Resources)).Assembly); + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Microsoft.AspNet.Authentication.MicrosoftAccount.Resources", System.Reflection.IntrospectionExtensions.GetTypeInfo(typeof(Resources)).Assembly); resourceMan = temp; } return resourceMan; diff --git a/src/Microsoft.AspNet.Security.MicrosoftAccount/Resources.resx b/src/Microsoft.AspNet.Authentication.MicrosoftAccount/Resources.resx similarity index 100% rename from src/Microsoft.AspNet.Security.MicrosoftAccount/Resources.resx rename to src/Microsoft.AspNet.Authentication.MicrosoftAccount/Resources.resx diff --git a/src/Microsoft.AspNet.Security.MicrosoftAccount/project.json b/src/Microsoft.AspNet.Authentication.MicrosoftAccount/project.json similarity index 87% rename from src/Microsoft.AspNet.Security.MicrosoftAccount/project.json rename to src/Microsoft.AspNet.Authentication.MicrosoftAccount/project.json index 82c106b74..5aa85f926 100644 --- a/src/Microsoft.AspNet.Security.MicrosoftAccount/project.json +++ b/src/Microsoft.AspNet.Authentication.MicrosoftAccount/project.json @@ -2,7 +2,7 @@ "version": "1.0.0-*", "description": "ASP.NET 5 middleware that enables an application to support the Microsoft Account authentication workflow.", "dependencies": { - "Microsoft.AspNet.Security.OAuth": "1.0.0-*" + "Microsoft.AspNet.Authentication.OAuth": "1.0.0-*" }, "frameworks": { "aspnet50": { }, diff --git a/src/Microsoft.AspNet.Security.OAuth/Microsoft.AspNet.Security.OAuth.kproj b/src/Microsoft.AspNet.Authentication.OAuth/Microsoft.AspNet.Authentication.OAuth.kproj similarity index 95% rename from src/Microsoft.AspNet.Security.OAuth/Microsoft.AspNet.Security.OAuth.kproj rename to src/Microsoft.AspNet.Authentication.OAuth/Microsoft.AspNet.Authentication.OAuth.kproj index abcb5afde..868328f6d 100644 --- a/src/Microsoft.AspNet.Security.OAuth/Microsoft.AspNet.Security.OAuth.kproj +++ b/src/Microsoft.AspNet.Authentication.OAuth/Microsoft.AspNet.Authentication.OAuth.kproj @@ -1,4 +1,4 @@ - + 14.0 @@ -14,4 +14,4 @@ 2.0 - + \ No newline at end of file diff --git a/src/Microsoft.AspNet.Security.Google/NotNullAttribute.cs b/src/Microsoft.AspNet.Authentication.OAuth/NotNullAttribute.cs similarity index 87% rename from src/Microsoft.AspNet.Security.Google/NotNullAttribute.cs rename to src/Microsoft.AspNet.Authentication.OAuth/NotNullAttribute.cs index e87e361e4..49f587eb5 100644 --- a/src/Microsoft.AspNet.Security.Google/NotNullAttribute.cs +++ b/src/Microsoft.AspNet.Authentication.OAuth/NotNullAttribute.cs @@ -3,7 +3,7 @@ using System; -namespace Microsoft.AspNet.Security.Google +namespace Microsoft.AspNet.Authentication.OAuth { [AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false)] internal sealed class NotNullAttribute : Attribute diff --git a/src/Microsoft.AspNet.Security.OAuth/Notifications/BaseValidatingContext.cs b/src/Microsoft.AspNet.Authentication.OAuth/Notifications/BaseValidatingContext.cs similarity index 97% rename from src/Microsoft.AspNet.Security.OAuth/Notifications/BaseValidatingContext.cs rename to src/Microsoft.AspNet.Authentication.OAuth/Notifications/BaseValidatingContext.cs index 0957d9fd6..84e8c0df4 100644 --- a/src/Microsoft.AspNet.Security.OAuth/Notifications/BaseValidatingContext.cs +++ b/src/Microsoft.AspNet.Authentication.OAuth/Notifications/BaseValidatingContext.cs @@ -2,9 +2,9 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using Microsoft.AspNet.Http; -using Microsoft.AspNet.Security.Notifications; +using Microsoft.AspNet.Authentication.Notifications; -namespace Microsoft.AspNet.Security.OAuth +namespace Microsoft.AspNet.Authentication.OAuth { /// /// Base class used for certain event contexts diff --git a/src/Microsoft.AspNet.Security.OAuth/Notifications/BaseValidatingTicketContext.cs b/src/Microsoft.AspNet.Authentication.OAuth/Notifications/BaseValidatingTicketContext.cs similarity index 87% rename from src/Microsoft.AspNet.Security.OAuth/Notifications/BaseValidatingTicketContext.cs rename to src/Microsoft.AspNet.Authentication.OAuth/Notifications/BaseValidatingTicketContext.cs index c6528619b..f44af9328 100644 --- a/src/Microsoft.AspNet.Security.OAuth/Notifications/BaseValidatingTicketContext.cs +++ b/src/Microsoft.AspNet.Authentication.OAuth/Notifications/BaseValidatingTicketContext.cs @@ -3,9 +3,9 @@ using System.Security.Claims; using Microsoft.AspNet.Http; -using Microsoft.AspNet.Http.Security; +using Microsoft.AspNet.Http.Authentication; -namespace Microsoft.AspNet.Security.OAuth +namespace Microsoft.AspNet.Authentication.OAuth { /// /// Base class used for certain event contexts @@ -49,10 +49,11 @@ public bool Validated(AuthenticationTicket ticket) /// /// Assigned to the Ticket.Identity property /// True if the validation has taken effect. - public bool Validated(ClaimsIdentity identity) + public bool Validated(ClaimsPrincipal principal) { AuthenticationProperties properties = Ticket != null ? Ticket.Properties : new AuthenticationProperties(); - return Validated(new AuthenticationTicket(identity, properties)); + // TODO: Ticket can be null, need to revisit + return Validated(new AuthenticationTicket(principal, properties, Ticket.AuthenticationScheme)); } } } diff --git a/src/Microsoft.AspNet.Security.OAuth/Notifications/IOAuthAuthenticationNotifications.cs b/src/Microsoft.AspNet.Authentication.OAuth/Notifications/IOAuthAuthenticationNotifications.cs similarity index 97% rename from src/Microsoft.AspNet.Security.OAuth/Notifications/IOAuthAuthenticationNotifications.cs rename to src/Microsoft.AspNet.Authentication.OAuth/Notifications/IOAuthAuthenticationNotifications.cs index b00b0175e..2161d70fd 100644 --- a/src/Microsoft.AspNet.Security.OAuth/Notifications/IOAuthAuthenticationNotifications.cs +++ b/src/Microsoft.AspNet.Authentication.OAuth/Notifications/IOAuthAuthenticationNotifications.cs @@ -3,7 +3,7 @@ using System.Threading.Tasks; -namespace Microsoft.AspNet.Security.OAuth +namespace Microsoft.AspNet.Authentication.OAuth { /// /// Specifies callback methods which the invokes to enable developer control over the authentication process. diff --git a/src/Microsoft.AspNet.Security.OAuth/Notifications/OAuthApplyRedirectContext.cs b/src/Microsoft.AspNet.Authentication.OAuth/Notifications/OAuthApplyRedirectContext.cs similarity index 90% rename from src/Microsoft.AspNet.Security.OAuth/Notifications/OAuthApplyRedirectContext.cs rename to src/Microsoft.AspNet.Authentication.OAuth/Notifications/OAuthApplyRedirectContext.cs index df1f6a424..070e1994e 100644 --- a/src/Microsoft.AspNet.Security.OAuth/Notifications/OAuthApplyRedirectContext.cs +++ b/src/Microsoft.AspNet.Authentication.OAuth/Notifications/OAuthApplyRedirectContext.cs @@ -2,10 +2,10 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using Microsoft.AspNet.Http; -using Microsoft.AspNet.Http.Security; -using Microsoft.AspNet.Security.Notifications; +using Microsoft.AspNet.Http.Authentication; +using Microsoft.AspNet.Authentication.Notifications; -namespace Microsoft.AspNet.Security.OAuth +namespace Microsoft.AspNet.Authentication.OAuth { /// /// Context passed when a Challenge causes a redirect to authorize endpoint in the Microsoft account middleware. diff --git a/src/Microsoft.AspNet.Security.OAuth/Notifications/OAuthAuthenticatedContext.cs b/src/Microsoft.AspNet.Authentication.OAuth/Notifications/OAuthAuthenticatedContext.cs similarity index 92% rename from src/Microsoft.AspNet.Security.OAuth/Notifications/OAuthAuthenticatedContext.cs rename to src/Microsoft.AspNet.Authentication.OAuth/Notifications/OAuthAuthenticatedContext.cs index 581707153..7283a80c6 100644 --- a/src/Microsoft.AspNet.Security.OAuth/Notifications/OAuthAuthenticatedContext.cs +++ b/src/Microsoft.AspNet.Authentication.OAuth/Notifications/OAuthAuthenticatedContext.cs @@ -5,11 +5,11 @@ using System.Globalization; using System.Security.Claims; using Microsoft.AspNet.Http; -using Microsoft.AspNet.Http.Security; -using Microsoft.AspNet.Security.Notifications; +using Microsoft.AspNet.Http.Authentication; +using Microsoft.AspNet.Authentication.Notifications; using Newtonsoft.Json.Linq; -namespace Microsoft.AspNet.Security.OAuth +namespace Microsoft.AspNet.Authentication.OAuth { /// /// Contains information about the login session as well as the user . @@ -66,11 +66,11 @@ public OAuthAuthenticatedContext(HttpContext context, OAuthAuthenticationOptions /// /// Gets the representing the user. /// - public ClaimsIdentity Identity { get; set; } + public ClaimsPrincipal Principal { get; set; } /// /// Gets or sets a property bag for common authentication properties. /// public AuthenticationProperties Properties { get; set; } } -} +} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Security.OAuth/Notifications/OAuthAuthenticationNotifications.cs b/src/Microsoft.AspNet.Authentication.OAuth/Notifications/OAuthAuthenticationNotifications.cs similarity index 98% rename from src/Microsoft.AspNet.Security.OAuth/Notifications/OAuthAuthenticationNotifications.cs rename to src/Microsoft.AspNet.Authentication.OAuth/Notifications/OAuthAuthenticationNotifications.cs index a91f8f0b0..a20821889 100644 --- a/src/Microsoft.AspNet.Security.OAuth/Notifications/OAuthAuthenticationNotifications.cs +++ b/src/Microsoft.AspNet.Authentication.OAuth/Notifications/OAuthAuthenticationNotifications.cs @@ -4,7 +4,7 @@ using System; using System.Threading.Tasks; -namespace Microsoft.AspNet.Security.OAuth +namespace Microsoft.AspNet.Authentication.OAuth { /// /// Default implementation. diff --git a/src/Microsoft.AspNet.Security.OAuth/Notifications/OAuthChallengeContext.cs b/src/Microsoft.AspNet.Authentication.OAuth/Notifications/OAuthChallengeContext.cs similarity index 90% rename from src/Microsoft.AspNet.Security.OAuth/Notifications/OAuthChallengeContext.cs rename to src/Microsoft.AspNet.Authentication.OAuth/Notifications/OAuthChallengeContext.cs index 6f5016914..55dd72008 100644 --- a/src/Microsoft.AspNet.Security.OAuth/Notifications/OAuthChallengeContext.cs +++ b/src/Microsoft.AspNet.Authentication.OAuth/Notifications/OAuthChallengeContext.cs @@ -2,9 +2,9 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using Microsoft.AspNet.Http; -using Microsoft.AspNet.Security.Notifications; +using Microsoft.AspNet.Authentication.Notifications; -namespace Microsoft.AspNet.Security.OAuth +namespace Microsoft.AspNet.Authentication.OAuth { /// /// Specifies the HTTP response header for the bearer authentication scheme. diff --git a/src/Microsoft.AspNet.Security.OAuth/Notifications/OAuthGetUserInformationContext.cs b/src/Microsoft.AspNet.Authentication.OAuth/Notifications/OAuthGetUserInformationContext.cs similarity index 90% rename from src/Microsoft.AspNet.Security.OAuth/Notifications/OAuthGetUserInformationContext.cs rename to src/Microsoft.AspNet.Authentication.OAuth/Notifications/OAuthGetUserInformationContext.cs index 15d76c6eb..8d2405ebf 100644 --- a/src/Microsoft.AspNet.Security.OAuth/Notifications/OAuthGetUserInformationContext.cs +++ b/src/Microsoft.AspNet.Authentication.OAuth/Notifications/OAuthGetUserInformationContext.cs @@ -6,10 +6,10 @@ using System.Net.Http; using System.Security.Claims; using Microsoft.AspNet.Http; -using Microsoft.AspNet.Http.Security; -using Microsoft.AspNet.Security.Notifications; +using Microsoft.AspNet.Http.Authentication; +using Microsoft.AspNet.Authentication.Notifications; -namespace Microsoft.AspNet.Security.OAuth +namespace Microsoft.AspNet.Authentication.OAuth { /// /// Contains information about the login session as well as the user . @@ -63,9 +63,9 @@ public OAuthGetUserInformationContext(HttpContext context, OAuthAuthenticationOp public HttpClient Backchannel { get; protected set; } /// - /// Gets the representing the user. + /// Gets the representing the user. /// - public ClaimsIdentity Identity { get; set; } + public ClaimsPrincipal Principal { get; set; } /// /// Gets or sets a property bag for common authentication properties. diff --git a/src/Microsoft.AspNet.Security.OAuth/Notifications/OAuthRequestTokenContext.cs b/src/Microsoft.AspNet.Authentication.OAuth/Notifications/OAuthRequestTokenContext.cs similarity index 90% rename from src/Microsoft.AspNet.Security.OAuth/Notifications/OAuthRequestTokenContext.cs rename to src/Microsoft.AspNet.Authentication.OAuth/Notifications/OAuthRequestTokenContext.cs index 785fa175d..cd9294a42 100644 --- a/src/Microsoft.AspNet.Security.OAuth/Notifications/OAuthRequestTokenContext.cs +++ b/src/Microsoft.AspNet.Authentication.OAuth/Notifications/OAuthRequestTokenContext.cs @@ -2,9 +2,9 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using Microsoft.AspNet.Http; -using Microsoft.AspNet.Security.Notifications; +using Microsoft.AspNet.Authentication.Notifications; -namespace Microsoft.AspNet.Security.OAuth +namespace Microsoft.AspNet.Authentication.OAuth { /// /// Specifies the HTTP request header for the bearer authentication scheme. diff --git a/src/Microsoft.AspNet.Security.OAuth/Notifications/OAuthReturnEndpointContext.cs b/src/Microsoft.AspNet.Authentication.OAuth/Notifications/OAuthReturnEndpointContext.cs similarity index 89% rename from src/Microsoft.AspNet.Security.OAuth/Notifications/OAuthReturnEndpointContext.cs rename to src/Microsoft.AspNet.Authentication.OAuth/Notifications/OAuthReturnEndpointContext.cs index 6f465ef3d..ce9ffd4ea 100644 --- a/src/Microsoft.AspNet.Security.OAuth/Notifications/OAuthReturnEndpointContext.cs +++ b/src/Microsoft.AspNet.Authentication.OAuth/Notifications/OAuthReturnEndpointContext.cs @@ -2,9 +2,9 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using Microsoft.AspNet.Http; -using Microsoft.AspNet.Security.Notifications; +using Microsoft.AspNet.Authentication.Notifications; -namespace Microsoft.AspNet.Security.OAuth +namespace Microsoft.AspNet.Authentication.OAuth { /// /// Provides context information to middleware providers. diff --git a/src/Microsoft.AspNet.Security.OAuth/OAuthAuthenticationDefaults.cs b/src/Microsoft.AspNet.Authentication.OAuth/OAuthAuthenticationDefaults.cs similarity index 87% rename from src/Microsoft.AspNet.Security.OAuth/OAuthAuthenticationDefaults.cs rename to src/Microsoft.AspNet.Authentication.OAuth/OAuthAuthenticationDefaults.cs index 758417ecf..90dc2b616 100644 --- a/src/Microsoft.AspNet.Security.OAuth/OAuthAuthenticationDefaults.cs +++ b/src/Microsoft.AspNet.Authentication.OAuth/OAuthAuthenticationDefaults.cs @@ -6,7 +6,7 @@ using System.Security.Claims; using System.Threading.Tasks; -namespace Microsoft.AspNet.Security.OAuth +namespace Microsoft.AspNet.Authentication.OAuth { public static class OAuthAuthenticationDefaults { @@ -14,25 +14,25 @@ public static class OAuthAuthenticationDefaults { // If the developer doesn't specify a user-info callback, just give them the tokens. var identity = new ClaimsIdentity( - context.Options.AuthenticationType, + context.Options.AuthenticationScheme, ClaimsIdentity.DefaultNameClaimType, ClaimsIdentity.DefaultRoleClaimType); - identity.AddClaim(new Claim("access_token", context.AccessToken, ClaimValueTypes.String, context.Options.AuthenticationType)); + identity.AddClaim(new Claim("access_token", context.AccessToken, ClaimValueTypes.String, context.Options.AuthenticationScheme)); if (!string.IsNullOrEmpty(context.RefreshToken)) { - identity.AddClaim(new Claim("refresh_token", context.RefreshToken, ClaimValueTypes.String, context.Options.AuthenticationType)); + identity.AddClaim(new Claim("refresh_token", context.RefreshToken, ClaimValueTypes.String, context.Options.AuthenticationScheme)); } if (!string.IsNullOrEmpty(context.TokenType)) { - identity.AddClaim(new Claim("token_type", context.TokenType, ClaimValueTypes.String, context.Options.AuthenticationType)); + identity.AddClaim(new Claim("token_type", context.TokenType, ClaimValueTypes.String, context.Options.AuthenticationScheme)); } if (context.ExpiresIn.HasValue) { identity.AddClaim(new Claim("expires_in", context.ExpiresIn.Value.TotalSeconds.ToString(CultureInfo.InvariantCulture), - ClaimValueTypes.String, context.Options.AuthenticationType)); + ClaimValueTypes.String, context.Options.AuthenticationScheme)); } - context.Identity = identity; + context.Principal = new ClaimsPrincipal(identity); return Task.FromResult(0); }; } diff --git a/src/Microsoft.AspNet.Security.OAuth/OAuthAuthenticationExtensions.cs b/src/Microsoft.AspNet.Authentication.OAuth/OAuthAuthenticationExtensions.cs similarity index 81% rename from src/Microsoft.AspNet.Security.OAuth/OAuthAuthenticationExtensions.cs rename to src/Microsoft.AspNet.Authentication.OAuth/OAuthAuthenticationExtensions.cs index 3e4947de2..903f823e1 100644 --- a/src/Microsoft.AspNet.Security.OAuth/OAuthAuthenticationExtensions.cs +++ b/src/Microsoft.AspNet.Authentication.OAuth/OAuthAuthenticationExtensions.cs @@ -3,8 +3,8 @@ using System; using System.Globalization; -using Microsoft.AspNet.Security.OAuth; -using Microsoft.AspNet.Security.Infrastructure; +using Microsoft.AspNet.Authentication.OAuth; +using Microsoft.AspNet.Authentication; using Microsoft.Framework.OptionsModel; namespace Microsoft.AspNet.Builder @@ -20,13 +20,13 @@ public static class OAuthAuthenticationExtensions /// The passed to the configure method. /// The middleware configuration options. /// The updated . - public static IApplicationBuilder UseOAuthAuthentication([NotNull] this IApplicationBuilder app, [NotNull] string authenticationType, Action> configureOptions = null) + public static IApplicationBuilder UseOAuthAuthentication([NotNull] this IApplicationBuilder app, [NotNull] string authenticationScheme, Action> configureOptions = null) { return app.UseMiddleware, IOAuthAuthenticationNotifications>>( new ConfigureOptions>(options => { - options.AuthenticationType = authenticationType; - options.Caption = authenticationType; + options.AuthenticationScheme = authenticationScheme; + options.Caption = authenticationScheme; if (configureOptions != null) { configureOptions(options); @@ -37,7 +37,7 @@ public static IApplicationBuilder UseOAuthAuthentication([NotNull] this IApplica } }) { - Name = authenticationType, + Name = authenticationScheme, }); } } diff --git a/src/Microsoft.AspNet.Security.OAuth/OAuthAuthenticationHandler.cs b/src/Microsoft.AspNet.Authentication.OAuth/OAuthAuthenticationHandler.cs similarity index 85% rename from src/Microsoft.AspNet.Security.OAuth/OAuthAuthenticationHandler.cs rename to src/Microsoft.AspNet.Authentication.OAuth/OAuthAuthenticationHandler.cs index b165ca41c..8e193befe 100644 --- a/src/Microsoft.AspNet.Security.OAuth/OAuthAuthenticationHandler.cs +++ b/src/Microsoft.AspNet.Authentication.OAuth/OAuthAuthenticationHandler.cs @@ -9,13 +9,13 @@ using System.Threading.Tasks; using Microsoft.AspNet.Http; using Microsoft.AspNet.Http.Extensions; -using Microsoft.AspNet.Http.Security; -using Microsoft.AspNet.Security.Infrastructure; +using Microsoft.AspNet.Http.Authentication; +using Microsoft.AspNet.Authentication; using Microsoft.AspNet.WebUtilities; using Microsoft.Framework.Logging; using Newtonsoft.Json.Linq; -namespace Microsoft.AspNet.Security.OAuth +namespace Microsoft.AspNet.Authentication.OAuth { public class OAuthAuthenticationHandler : AuthenticationHandler where TOptions : OAuthAuthenticationOptions @@ -52,26 +52,21 @@ public async Task InvokeReturnPathAsync() var context = new OAuthReturnEndpointContext(Context, ticket) { - SignInAsAuthenticationType = Options.SignInAsAuthenticationType, + SignInScheme = Options.SignInScheme, RedirectUri = ticket.Properties.RedirectUri, }; ticket.Properties.RedirectUri = null; await Options.Notifications.ReturnEndpoint(context); - if (context.SignInAsAuthenticationType != null && context.Identity != null) + if (context.SignInScheme != null && context.Principal != null) { - ClaimsIdentity signInIdentity = context.Identity; - if (!string.Equals(signInIdentity.AuthenticationType, context.SignInAsAuthenticationType, StringComparison.Ordinal)) - { - signInIdentity = new ClaimsIdentity(signInIdentity.Claims, context.SignInAsAuthenticationType, signInIdentity.NameClaimType, signInIdentity.RoleClaimType); - } - Context.Response.SignIn(context.Properties, signInIdentity); + Context.Response.SignIn(context.SignInScheme, context.Principal, context.Properties); } if (!context.IsRequestCompleted && context.RedirectUri != null) { - if (context.Identity == null) + if (context.Principal == null) { // add a redirect hint that sign-in failed in some way context.RedirectUri = QueryHelpers.AddQueryString(context.RedirectUri, "error", "access_denied"); @@ -116,13 +111,13 @@ protected override async Task AuthenticateCoreAsync() // OAuth2 10.12 CSRF if (!ValidateCorrelationId(properties, Logger)) { - return new AuthenticationTicket(null, properties); + return new AuthenticationTicket(properties, Options.AuthenticationScheme); } if (string.IsNullOrEmpty(code)) { // Null if the remote server returns an error. - return new AuthenticationTicket(null, properties); + return new AuthenticationTicket(properties, Options.AuthenticationScheme); } string requestPrefix = Request.Scheme + "://" + Request.Host; @@ -133,7 +128,7 @@ protected override async Task AuthenticateCoreAsync() if (string.IsNullOrWhiteSpace(tokens.AccessToken)) { Logger.WriteWarning("Access token was not found"); - return new AuthenticationTicket(null, properties); + return new AuthenticationTicket(properties, Options.AuthenticationScheme); } return await GetUserInformationAsync(properties, tokens); @@ -141,7 +136,7 @@ protected override async Task AuthenticateCoreAsync() catch (Exception ex) { Logger.WriteError("Authentication failed", ex); - return new AuthenticationTicket(null, properties); + return new AuthenticationTicket(properties, Options.AuthenticationScheme); } } @@ -176,7 +171,7 @@ protected virtual async Task GetUserInformationAsync(Authe Properties = properties, }; await Options.Notifications.GetUserInformationAsync(context); - return new AuthenticationTicket(context.Identity, context.Properties); + return new AuthenticationTicket(context.Principal, context.Properties, Options.AuthenticationScheme); } protected override void ApplyResponseChallenge() @@ -186,8 +181,8 @@ protected override void ApplyResponseChallenge() return; } - // Active middleware should redirect on 401 even if there wasn't an explicit challenge. - if (ChallengeContext == null && Options.AuthenticationMode == AuthenticationMode.Passive) + // Only redirect on challenges + if (ChallengeContext == null) { return; } diff --git a/src/Microsoft.AspNet.Security.OAuth/OAuthAuthenticationMiddleware.cs b/src/Microsoft.AspNet.Authentication.OAuth/OAuthAuthenticationMiddleware.cs similarity index 92% rename from src/Microsoft.AspNet.Security.OAuth/OAuthAuthenticationMiddleware.cs rename to src/Microsoft.AspNet.Authentication.OAuth/OAuthAuthenticationMiddleware.cs index c525af881..b8e10ff99 100644 --- a/src/Microsoft.AspNet.Security.OAuth/OAuthAuthenticationMiddleware.cs +++ b/src/Microsoft.AspNet.Authentication.OAuth/OAuthAuthenticationMiddleware.cs @@ -5,14 +5,14 @@ using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.Net.Http; +using Microsoft.AspNet.Authentication; +using Microsoft.AspNet.Authentication.DataHandler; using Microsoft.AspNet.Builder; using Microsoft.AspNet.DataProtection; -using Microsoft.AspNet.Security.DataHandler; -using Microsoft.AspNet.Security.Infrastructure; using Microsoft.Framework.Logging; using Microsoft.Framework.OptionsModel; -namespace Microsoft.AspNet.Security.OAuth +namespace Microsoft.AspNet.Authentication.OAuth { /// /// An ASP.NET middleware for authenticating users using OAuth services. @@ -41,9 +41,9 @@ public OAuthAuthenticationMiddleware( : base(next, services, options, configureOptions) { // todo: review error handling - if (string.IsNullOrWhiteSpace(Options.AuthenticationType)) + if (string.IsNullOrWhiteSpace(Options.AuthenticationScheme)) { - throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, Resources.Exception_OptionMustBeProvided, "AuthenticationType")); + throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, Resources.Exception_OptionMustBeProvided, "AuthenticationScheme")); } if (string.IsNullOrWhiteSpace(Options.ClientId)) @@ -71,7 +71,7 @@ public OAuthAuthenticationMiddleware( if (Options.StateDataFormat == null) { IDataProtector dataProtector = dataProtectionProvider.CreateProtector( - this.GetType().FullName, Options.AuthenticationType, "v1"); + this.GetType().FullName, Options.AuthenticationScheme, "v1"); Options.StateDataFormat = new PropertiesDataFormat(dataProtector); } @@ -80,13 +80,13 @@ public OAuthAuthenticationMiddleware( Backchannel.Timeout = Options.BackchannelTimeout; Backchannel.MaxResponseContentBufferSize = 1024 * 1024 * 10; // 10 MB - if (string.IsNullOrEmpty(Options.SignInAsAuthenticationType)) + if (string.IsNullOrEmpty(Options.SignInScheme)) { - Options.SignInAsAuthenticationType = externalOptions.Options.SignInAsAuthenticationType; + Options.SignInScheme = externalOptions.Options.SignInScheme; } - if (string.IsNullOrEmpty(Options.SignInAsAuthenticationType)) + if (string.IsNullOrEmpty(Options.SignInScheme)) { - throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, Resources.Exception_OptionMustBeProvided, "SignInAsAuthenticationType")); + throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, Resources.Exception_OptionMustBeProvided, "SignInScheme")); } } diff --git a/src/Microsoft.AspNet.Security.OAuth/OAuthAuthenticationOptions.cs b/src/Microsoft.AspNet.Authentication.OAuth/OAuthAuthenticationOptions.cs similarity index 92% rename from src/Microsoft.AspNet.Security.OAuth/OAuthAuthenticationOptions.cs rename to src/Microsoft.AspNet.Authentication.OAuth/OAuthAuthenticationOptions.cs index cee784185..7a910e059 100644 --- a/src/Microsoft.AspNet.Security.OAuth/OAuthAuthenticationOptions.cs +++ b/src/Microsoft.AspNet.Authentication.OAuth/OAuthAuthenticationOptions.cs @@ -6,9 +6,9 @@ using System.Net.Http; using System.Threading.Tasks; using Microsoft.AspNet.Http; -using Microsoft.AspNet.Http.Security; +using Microsoft.AspNet.Http.Authentication; -namespace Microsoft.AspNet.Security.OAuth +namespace Microsoft.AspNet.Authentication.OAuth { /// /// Configuration options for . @@ -20,7 +20,6 @@ public class OAuthAuthenticationOptions : AuthenticationOptions /// public OAuthAuthenticationOptions() { - AuthenticationMode = AuthenticationMode.Passive; Scope = new List(); BackchannelTimeout = TimeSpan.FromSeconds(60); } @@ -102,7 +101,12 @@ public string Caption /// /// Gets or sets the name of another authentication middleware which will be responsible for actually issuing a user . /// - public string SignInAsAuthenticationType { get; set; } + public string SignInScheme { get; set; } + + /// + /// Gets or sets the issuer that should be used for any claims that are created + /// + public string ClaimsIssuer { get; set; } /// /// Gets or sets the type used to secure data handled by the middleware. diff --git a/src/Microsoft.AspNet.Security.OAuth/OAuthAuthenticationOptions`1.cs b/src/Microsoft.AspNet.Authentication.OAuth/OAuthAuthenticationOptions`1.cs similarity index 93% rename from src/Microsoft.AspNet.Security.OAuth/OAuthAuthenticationOptions`1.cs rename to src/Microsoft.AspNet.Authentication.OAuth/OAuthAuthenticationOptions`1.cs index 2eb1bfb89..2a37062d3 100644 --- a/src/Microsoft.AspNet.Security.OAuth/OAuthAuthenticationOptions`1.cs +++ b/src/Microsoft.AspNet.Authentication.OAuth/OAuthAuthenticationOptions`1.cs @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -namespace Microsoft.AspNet.Security.OAuth +namespace Microsoft.AspNet.Authentication.OAuth { /// /// Configuration options for . diff --git a/src/Microsoft.AspNet.Security.OAuthBearer/Resources.Designer.cs b/src/Microsoft.AspNet.Authentication.OAuth/Resources.Designer.cs similarity index 95% rename from src/Microsoft.AspNet.Security.OAuthBearer/Resources.Designer.cs rename to src/Microsoft.AspNet.Authentication.OAuth/Resources.Designer.cs index 37abb160e..635838274 100644 --- a/src/Microsoft.AspNet.Security.OAuthBearer/Resources.Designer.cs +++ b/src/Microsoft.AspNet.Authentication.OAuth/Resources.Designer.cs @@ -8,7 +8,7 @@ // //------------------------------------------------------------------------------ -namespace Microsoft.AspNet.Security.OAuthBearer { +namespace Microsoft.AspNet.Authentication.OAuth { using System; @@ -39,7 +39,7 @@ internal Resources() { internal static global::System.Resources.ResourceManager ResourceManager { get { if (object.ReferenceEquals(resourceMan, null)) { - global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Microsoft.AspNet.Security.OAuth.Resources", System.Reflection.IntrospectionExtensions.GetTypeInfo(typeof(Resources)).Assembly); + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Microsoft.AspNet.Authentication.OAuth.Resources", System.Reflection.IntrospectionExtensions.GetTypeInfo(typeof(Resources)).Assembly); resourceMan = temp; } return resourceMan; diff --git a/src/Microsoft.AspNet.Security.OAuth/Resources.resx b/src/Microsoft.AspNet.Authentication.OAuth/Resources.resx similarity index 100% rename from src/Microsoft.AspNet.Security.OAuth/Resources.resx rename to src/Microsoft.AspNet.Authentication.OAuth/Resources.resx diff --git a/src/Microsoft.AspNet.Security.OAuth/TokenResponse.cs b/src/Microsoft.AspNet.Authentication.OAuth/TokenResponse.cs similarity index 94% rename from src/Microsoft.AspNet.Security.OAuth/TokenResponse.cs rename to src/Microsoft.AspNet.Authentication.OAuth/TokenResponse.cs index 84c3e95aa..4acc2d6e0 100644 --- a/src/Microsoft.AspNet.Security.OAuth/TokenResponse.cs +++ b/src/Microsoft.AspNet.Authentication.OAuth/TokenResponse.cs @@ -3,7 +3,7 @@ using Newtonsoft.Json.Linq; -namespace Microsoft.AspNet.Security.OAuth +namespace Microsoft.AspNet.Authentication.OAuth { public class TokenResponse { diff --git a/src/Microsoft.AspNet.Security.OAuth/project.json b/src/Microsoft.AspNet.Authentication.OAuth/project.json similarity index 91% rename from src/Microsoft.AspNet.Security.OAuth/project.json rename to src/Microsoft.AspNet.Authentication.OAuth/project.json index d29f6d914..ea68b78fa 100644 --- a/src/Microsoft.AspNet.Security.OAuth/project.json +++ b/src/Microsoft.AspNet.Authentication.OAuth/project.json @@ -3,7 +3,7 @@ "description": "ASP.NET 5 middleware that enables an application to support any standard OAuth 2.0 authentication workflow.", "dependencies": { "Microsoft.AspNet.DataProtection": "1.0.0-*", - "Microsoft.AspNet.Security": "1.0.0-*" + "Microsoft.AspNet.Authentication": "1.0.0-*" }, "frameworks": { "aspnet50": { diff --git a/src/Microsoft.AspNet.Security.OAuthBearer/Microsoft.AspNet.Security.OAuthBearer.kproj b/src/Microsoft.AspNet.Authentication.OAuthBearer/Microsoft.AspNet.Authentication.OAuthBearer.kproj similarity index 100% rename from src/Microsoft.AspNet.Security.OAuthBearer/Microsoft.AspNet.Security.OAuthBearer.kproj rename to src/Microsoft.AspNet.Authentication.OAuthBearer/Microsoft.AspNet.Authentication.OAuthBearer.kproj diff --git a/src/Microsoft.AspNet.Security.MicrosoftAccount/NotNullAttribute.cs b/src/Microsoft.AspNet.Authentication.OAuthBearer/NotNullAttribute.cs similarity index 86% rename from src/Microsoft.AspNet.Security.MicrosoftAccount/NotNullAttribute.cs rename to src/Microsoft.AspNet.Authentication.OAuthBearer/NotNullAttribute.cs index f3900accc..73b3e6c56 100644 --- a/src/Microsoft.AspNet.Security.MicrosoftAccount/NotNullAttribute.cs +++ b/src/Microsoft.AspNet.Authentication.OAuthBearer/NotNullAttribute.cs @@ -3,7 +3,7 @@ using System; -namespace Microsoft.AspNet.Security.MicrosoftAccount +namespace Microsoft.AspNet.Authentication.OAuthBearer { [AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false)] internal sealed class NotNullAttribute : Attribute diff --git a/src/Microsoft.AspNet.Security.OAuthBearer/Notifications/AuthenticationChallengeNotification.cs b/src/Microsoft.AspNet.Authentication.OAuthBearer/Notifications/AuthenticationChallengeNotification.cs similarity index 81% rename from src/Microsoft.AspNet.Security.OAuthBearer/Notifications/AuthenticationChallengeNotification.cs rename to src/Microsoft.AspNet.Authentication.OAuthBearer/Notifications/AuthenticationChallengeNotification.cs index f2685af0c..53e02673c 100644 --- a/src/Microsoft.AspNet.Security.OAuthBearer/Notifications/AuthenticationChallengeNotification.cs +++ b/src/Microsoft.AspNet.Authentication.OAuthBearer/Notifications/AuthenticationChallengeNotification.cs @@ -2,9 +2,9 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using Microsoft.AspNet.Http; -using Microsoft.AspNet.Security.Notifications; +using Microsoft.AspNet.Authentication.Notifications; -namespace Microsoft.AspNet.Security.OAuthBearer +namespace Microsoft.AspNet.Authentication.OAuthBearer { public class AuthenticationChallengeNotification : BaseNotification { diff --git a/src/Microsoft.AspNet.Security.OAuthBearer/Notifications/OAuthBearerAuthenticationNotifications.cs b/src/Microsoft.AspNet.Authentication.OAuthBearer/Notifications/OAuthBearerAuthenticationNotifications.cs similarity index 96% rename from src/Microsoft.AspNet.Security.OAuthBearer/Notifications/OAuthBearerAuthenticationNotifications.cs rename to src/Microsoft.AspNet.Authentication.OAuthBearer/Notifications/OAuthBearerAuthenticationNotifications.cs index 808615e1d..3c87d520a 100644 --- a/src/Microsoft.AspNet.Security.OAuthBearer/Notifications/OAuthBearerAuthenticationNotifications.cs +++ b/src/Microsoft.AspNet.Authentication.OAuthBearer/Notifications/OAuthBearerAuthenticationNotifications.cs @@ -4,12 +4,12 @@ using System; using System.Threading.Tasks; using Microsoft.AspNet.Http; -using Microsoft.AspNet.Security.Notifications; +using Microsoft.AspNet.Authentication.Notifications; /// /// Specifies events which the invokes to enable developer control over the authentication process. /> /// -namespace Microsoft.AspNet.Security.OAuthBearer +namespace Microsoft.AspNet.Authentication.OAuthBearer { /// /// OAuth bearer token middleware provider diff --git a/src/Microsoft.AspNet.Security.OAuthBearer/OAuthBearerAuthenticationDefaults.cs b/src/Microsoft.AspNet.Authentication.OAuthBearer/OAuthBearerAuthenticationDefaults.cs similarity index 68% rename from src/Microsoft.AspNet.Security.OAuthBearer/OAuthBearerAuthenticationDefaults.cs rename to src/Microsoft.AspNet.Authentication.OAuthBearer/OAuthBearerAuthenticationDefaults.cs index 5b62827cc..e16483ef0 100644 --- a/src/Microsoft.AspNet.Security.OAuthBearer/OAuthBearerAuthenticationDefaults.cs +++ b/src/Microsoft.AspNet.Authentication.OAuthBearer/OAuthBearerAuthenticationDefaults.cs @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -namespace Microsoft.AspNet.Security.OAuthBearer +namespace Microsoft.AspNet.Authentication.OAuthBearer { /// /// Default values used by authorization server and bearer authentication. @@ -9,9 +9,9 @@ namespace Microsoft.AspNet.Security.OAuthBearer public static class OAuthBearerAuthenticationDefaults { /// - /// Default value for AuthenticationType property in the OAuthBearerAuthenticationOptions and + /// Default value for AuthenticationScheme property in the OAuthBearerAuthenticationOptions and /// OAuthAuthorizationServerOptions. /// - public const string AuthenticationType = "Bearer"; + public const string AuthenticationScheme = "Bearer"; } } diff --git a/src/Microsoft.AspNet.Security.OAuthBearer/OAuthBearerAuthenticationExtensions.cs b/src/Microsoft.AspNet.Authentication.OAuthBearer/OAuthBearerAuthenticationExtensions.cs similarity index 97% rename from src/Microsoft.AspNet.Security.OAuthBearer/OAuthBearerAuthenticationExtensions.cs rename to src/Microsoft.AspNet.Authentication.OAuthBearer/OAuthBearerAuthenticationExtensions.cs index 0f31dfaf8..b1a629334 100644 --- a/src/Microsoft.AspNet.Security.OAuthBearer/OAuthBearerAuthenticationExtensions.cs +++ b/src/Microsoft.AspNet.Authentication.OAuthBearer/OAuthBearerAuthenticationExtensions.cs @@ -2,7 +2,7 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; -using Microsoft.AspNet.Security.OAuthBearer; +using Microsoft.AspNet.Authentication.OAuthBearer; using Microsoft.Framework.DependencyInjection; using Microsoft.Framework.OptionsModel; diff --git a/src/Microsoft.AspNet.Security.OAuthBearer/OAuthBearerAuthenticationHandler.cs b/src/Microsoft.AspNet.Authentication.OAuthBearer/OAuthBearerAuthenticationHandler.cs similarity index 94% rename from src/Microsoft.AspNet.Security.OAuthBearer/OAuthBearerAuthenticationHandler.cs rename to src/Microsoft.AspNet.Authentication.OAuthBearer/OAuthBearerAuthenticationHandler.cs index a4555790d..56d3d1025 100644 --- a/src/Microsoft.AspNet.Security.OAuthBearer/OAuthBearerAuthenticationHandler.cs +++ b/src/Microsoft.AspNet.Authentication.OAuthBearer/OAuthBearerAuthenticationHandler.cs @@ -8,15 +8,15 @@ using System.Security.Claims; using System.Threading.Tasks; using Microsoft.AspNet.Http; -using Microsoft.AspNet.Http.Security; -using Microsoft.AspNet.Security.Infrastructure; -using Microsoft.AspNet.Security.Notifications; +using Microsoft.AspNet.Http.Authentication; +using Microsoft.AspNet.Authentication; +using Microsoft.AspNet.Authentication.Notifications; using Microsoft.Framework.Logging; using Microsoft.IdentityModel.Protocols; -namespace Microsoft.AspNet.Security.OAuthBearer +namespace Microsoft.AspNet.Authentication.OAuthBearer { - public class OAuthBearerAuthenticationHandler : AuthenticationHandler + public class OAuthBearerAuthenticationHandler : AutomaticAuthenticationHandler { private readonly ILogger _logger; private OpenIdConnectConfiguration _configuration; @@ -130,7 +130,7 @@ protected override async Task AuthenticateCoreAsync() if (validator.CanReadToken(token)) { ClaimsPrincipal principal = validator.ValidateToken(token, validationParameters, out validatedToken); - AuthenticationTicket ticket = new AuthenticationTicket(principal, new AuthenticationProperties(), Options.AuthenticationType); + AuthenticationTicket ticket = new AuthenticationTicket(principal, new AuthenticationProperties(), Options.AuthenticationScheme); var securityTokenValidatedNotification = new SecurityTokenValidatedNotification(Context, Options) { ProtocolMessage = Context, @@ -192,6 +192,11 @@ protected override void ApplyResponseChallenge() protected override async Task ApplyResponseChallengeAsync() { + if (ShouldConvertChallengeToForbidden()) + { + Response.StatusCode = 403; + } + if ((Response.StatusCode != 401) || (ChallengeContext == null)) { return; diff --git a/src/Microsoft.AspNet.Security.OAuthBearer/OAuthBearerAuthenticationMiddleware.cs b/src/Microsoft.AspNet.Authentication.OAuthBearer/OAuthBearerAuthenticationMiddleware.cs similarity index 98% rename from src/Microsoft.AspNet.Security.OAuthBearer/OAuthBearerAuthenticationMiddleware.cs rename to src/Microsoft.AspNet.Authentication.OAuthBearer/OAuthBearerAuthenticationMiddleware.cs index d1ae0ad1a..824405e0e 100644 --- a/src/Microsoft.AspNet.Security.OAuthBearer/OAuthBearerAuthenticationMiddleware.cs +++ b/src/Microsoft.AspNet.Authentication.OAuthBearer/OAuthBearerAuthenticationMiddleware.cs @@ -6,13 +6,13 @@ using System.Diagnostics.CodeAnalysis; using System.IdentityModel.Tokens; using System.Net.Http; +using Microsoft.AspNet.Authentication; using Microsoft.AspNet.Builder; -using Microsoft.AspNet.Security.Infrastructure; using Microsoft.Framework.Logging; using Microsoft.Framework.OptionsModel; using Microsoft.IdentityModel.Protocols; -namespace Microsoft.AspNet.Security.OAuthBearer +namespace Microsoft.AspNet.Authentication.OAuthBearer { /// /// Bearer authentication middleware component which is added to an HTTP pipeline. This class is not diff --git a/src/Microsoft.AspNet.Security.OAuthBearer/OAuthBearerAuthenticationOptions.cs b/src/Microsoft.AspNet.Authentication.OAuthBearer/OAuthBearerAuthenticationOptions.cs similarity index 95% rename from src/Microsoft.AspNet.Security.OAuthBearer/OAuthBearerAuthenticationOptions.cs rename to src/Microsoft.AspNet.Authentication.OAuthBearer/OAuthBearerAuthenticationOptions.cs index 08acf5bf4..64935c384 100644 --- a/src/Microsoft.AspNet.Security.OAuthBearer/OAuthBearerAuthenticationOptions.cs +++ b/src/Microsoft.AspNet.Authentication.OAuthBearer/OAuthBearerAuthenticationOptions.cs @@ -5,15 +5,15 @@ using System.Collections.Generic; using System.IdentityModel.Tokens; using System.Net.Http; -using Microsoft.AspNet.Security.Infrastructure; +using Microsoft.AspNet.Authentication; using Microsoft.IdentityModel.Protocols; -namespace Microsoft.AspNet.Security.OAuthBearer +namespace Microsoft.AspNet.Authentication.OAuthBearer { /// /// Options class provides information needed to control Bearer Authentication middleware behavior /// - public class OAuthBearerAuthenticationOptions : AuthenticationOptions + public class OAuthBearerAuthenticationOptions : AutomaticAuthenticationOptions { private ICollection _securityTokenValidators; private TokenValidationParameters _tokenValidationParameters; @@ -23,9 +23,9 @@ public class OAuthBearerAuthenticationOptions : AuthenticationOptions /// public OAuthBearerAuthenticationOptions() : base() { - AuthenticationType = OAuthBearerAuthenticationDefaults.AuthenticationType; + AuthenticationScheme = OAuthBearerAuthenticationDefaults.AuthenticationScheme; BackchannelTimeout = TimeSpan.FromMinutes(1); - Challenge = OAuthBearerAuthenticationDefaults.AuthenticationType; + Challenge = OAuthBearerAuthenticationDefaults.AuthenticationScheme; Notifications = new OAuthBearerAuthenticationNotifications(); RefreshOnIssuerKeyNotFound = true; SystemClock = new SystemClock(); diff --git a/src/Microsoft.AspNet.Security.OAuth/Resources.Designer.cs b/src/Microsoft.AspNet.Authentication.OAuthBearer/Resources.Designer.cs similarity index 95% rename from src/Microsoft.AspNet.Security.OAuth/Resources.Designer.cs rename to src/Microsoft.AspNet.Authentication.OAuthBearer/Resources.Designer.cs index 892b42b5f..27298f47d 100644 --- a/src/Microsoft.AspNet.Security.OAuth/Resources.Designer.cs +++ b/src/Microsoft.AspNet.Authentication.OAuthBearer/Resources.Designer.cs @@ -8,7 +8,7 @@ // //------------------------------------------------------------------------------ -namespace Microsoft.AspNet.Security.OAuth { +namespace Microsoft.AspNet.Authentication.OAuthBearer { using System; @@ -39,7 +39,7 @@ internal Resources() { internal static global::System.Resources.ResourceManager ResourceManager { get { if (object.ReferenceEquals(resourceMan, null)) { - global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Microsoft.AspNet.Security.OAuth.Resources", System.Reflection.IntrospectionExtensions.GetTypeInfo(typeof(Resources)).Assembly); + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Microsoft.AspNet.Authentication.OAuth.Resources", System.Reflection.IntrospectionExtensions.GetTypeInfo(typeof(Resources)).Assembly); resourceMan = temp; } return resourceMan; diff --git a/src/Microsoft.AspNet.Security.OAuthBearer/Resources.resx b/src/Microsoft.AspNet.Authentication.OAuthBearer/Resources.resx similarity index 100% rename from src/Microsoft.AspNet.Security.OAuthBearer/Resources.resx rename to src/Microsoft.AspNet.Authentication.OAuthBearer/Resources.resx diff --git a/src/Microsoft.AspNet.Security.OAuthBearer/project.json b/src/Microsoft.AspNet.Authentication.OAuthBearer/project.json similarity index 92% rename from src/Microsoft.AspNet.Security.OAuthBearer/project.json rename to src/Microsoft.AspNet.Authentication.OAuthBearer/project.json index affb7e5b1..a6143df77 100644 --- a/src/Microsoft.AspNet.Security.OAuthBearer/project.json +++ b/src/Microsoft.AspNet.Authentication.OAuthBearer/project.json @@ -2,7 +2,7 @@ "version": "1.0.0-*", "description": "ASP.NET 5 middleware that enables an application to receive a OAuth bearer token.", "dependencies": { - "Microsoft.AspNet.Security": "1.0.0-*", + "Microsoft.AspNet.Authentication": "1.0.0-*", "Microsoft.IdentityModel.Protocol.Extensions": "2.0.0-beta1-*", "System.IdentityModel.Tokens": "5.0.0-beta1-*" }, diff --git a/src/Microsoft.AspNet.Security.OpenIdConnect/INonceCache.cs b/src/Microsoft.AspNet.Authentication.OpenIdConnect/INonceCache.cs similarity index 86% rename from src/Microsoft.AspNet.Security.OpenIdConnect/INonceCache.cs rename to src/Microsoft.AspNet.Authentication.OpenIdConnect/INonceCache.cs index 3f5255f56..a1f2d3543 100644 --- a/src/Microsoft.AspNet.Security.OpenIdConnect/INonceCache.cs +++ b/src/Microsoft.AspNet.Authentication.OpenIdConnect/INonceCache.cs @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -namespace Microsoft.AspNet.Security.OpenIdConnect +namespace Microsoft.AspNet.Authentication.OpenIdConnect { public interface INonceCache { diff --git a/src/Microsoft.AspNet.Security.OpenIdConnect/Microsoft.AspNet.Security.OpenIdConnect.kproj b/src/Microsoft.AspNet.Authentication.OpenIdConnect/Microsoft.AspNet.Authentication.OpenIdConnect.kproj similarity index 100% rename from src/Microsoft.AspNet.Security.OpenIdConnect/Microsoft.AspNet.Security.OpenIdConnect.kproj rename to src/Microsoft.AspNet.Authentication.OpenIdConnect/Microsoft.AspNet.Authentication.OpenIdConnect.kproj diff --git a/src/Microsoft.AspNet.Security.OpenIdConnect/Notifications/AuthorizationCodeReceivedNotification.cs b/src/Microsoft.AspNet.Authentication.OpenIdConnect/Notifications/AuthorizationCodeReceivedNotification.cs similarity index 94% rename from src/Microsoft.AspNet.Security.OpenIdConnect/Notifications/AuthorizationCodeReceivedNotification.cs rename to src/Microsoft.AspNet.Authentication.OpenIdConnect/Notifications/AuthorizationCodeReceivedNotification.cs index 9c7694e56..167f7f8dd 100644 --- a/src/Microsoft.AspNet.Security.OpenIdConnect/Notifications/AuthorizationCodeReceivedNotification.cs +++ b/src/Microsoft.AspNet.Authentication.OpenIdConnect/Notifications/AuthorizationCodeReceivedNotification.cs @@ -2,12 +2,12 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using Microsoft.AspNet.Http; -using Microsoft.AspNet.Security.OpenIdConnect; +using Microsoft.AspNet.Authentication.OpenIdConnect; using Microsoft.IdentityModel.Protocols; using System.Diagnostics.CodeAnalysis; using System.IdentityModel.Tokens; -namespace Microsoft.AspNet.Security.Notifications +namespace Microsoft.AspNet.Authentication.Notifications { /// /// This Notification can be used to be informed when an 'AuthorizationCode' is received over the OpenIdConnect protocol. diff --git a/src/Microsoft.AspNet.Security.OpenIdConnect/OpenIdConnectAuthenticationDefaults.cs b/src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenIdConnectAuthenticationDefaults.cs similarity index 90% rename from src/Microsoft.AspNet.Security.OpenIdConnect/OpenIdConnectAuthenticationDefaults.cs rename to src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenIdConnectAuthenticationDefaults.cs index 5942efb4d..21dc57f48 100644 --- a/src/Microsoft.AspNet.Security.OpenIdConnect/OpenIdConnectAuthenticationDefaults.cs +++ b/src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenIdConnectAuthenticationDefaults.cs @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -namespace Microsoft.AspNet.Security.OpenIdConnect +namespace Microsoft.AspNet.Authentication.OpenIdConnect { /// /// Default values related to OpenIdConnect authentication middleware @@ -9,9 +9,9 @@ namespace Microsoft.AspNet.Security.OpenIdConnect public static class OpenIdConnectAuthenticationDefaults { /// - /// The default value used for OpenIdConnectAuthenticationOptions.AuthenticationType + /// The default value used for OpenIdConnectAuthenticationOptions.AuthenticationScheme /// - public const string AuthenticationType = "OpenIdConnect"; + public const string AuthenticationScheme = "OpenIdConnect"; /// /// The prefix used to provide a default OpenIdConnectAuthenticationOptions.CookieName diff --git a/src/Microsoft.AspNet.Security.OpenIdConnect/OpenIdConnectAuthenticationExtensions.cs b/src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenIdConnectAuthenticationExtensions.cs similarity index 96% rename from src/Microsoft.AspNet.Security.OpenIdConnect/OpenIdConnectAuthenticationExtensions.cs rename to src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenIdConnectAuthenticationExtensions.cs index 5d4a72b21..989aac48e 100644 --- a/src/Microsoft.AspNet.Security.OpenIdConnect/OpenIdConnectAuthenticationExtensions.cs +++ b/src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenIdConnectAuthenticationExtensions.cs @@ -2,7 +2,7 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; -using Microsoft.AspNet.Security.OpenIdConnect; +using Microsoft.AspNet.Authentication.OpenIdConnect; using Microsoft.Framework.OptionsModel; namespace Microsoft.AspNet.Builder diff --git a/src/Microsoft.AspNet.Security.OpenIdConnect/OpenIdConnectAuthenticationMiddleware.cs b/src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenIdConnectAuthenticationMiddleware.cs similarity index 94% rename from src/Microsoft.AspNet.Security.OpenIdConnect/OpenIdConnectAuthenticationMiddleware.cs rename to src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenIdConnectAuthenticationMiddleware.cs index 9e6baf45d..543e8eeeb 100644 --- a/src/Microsoft.AspNet.Security.OpenIdConnect/OpenIdConnectAuthenticationMiddleware.cs +++ b/src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenIdConnectAuthenticationMiddleware.cs @@ -10,15 +10,15 @@ using Microsoft.AspNet.Builder; using Microsoft.AspNet.DataProtection; using Microsoft.AspNet.Http; -using Microsoft.AspNet.Security.DataHandler; -using Microsoft.AspNet.Security.DataHandler.Encoder; -using Microsoft.AspNet.Security.DataHandler.Serializer; -using Microsoft.AspNet.Security.Infrastructure; +using Microsoft.AspNet.Authentication; +using Microsoft.AspNet.Authentication.DataHandler; +using Microsoft.AspNet.Authentication.DataHandler.Encoder; +using Microsoft.AspNet.Authentication.DataHandler.Serializer; using Microsoft.Framework.Logging; using Microsoft.Framework.OptionsModel; using Microsoft.IdentityModel.Protocols; -namespace Microsoft.AspNet.Security.OpenIdConnect +namespace Microsoft.AspNet.Authentication.OpenIdConnect { /// /// ASP.NET middleware for obtaining identities using OpenIdConnect protocol. @@ -48,7 +48,7 @@ public OpenIdConnectAuthenticationMiddleware( if (string.IsNullOrWhiteSpace(Options.TokenValidationParameters.AuthenticationType)) { - Options.TokenValidationParameters.AuthenticationType = externalOptions.Options.SignInAsAuthenticationType; + Options.TokenValidationParameters.AuthenticationType = externalOptions.Options.SignInScheme; } if (Options.StateDataFormat == null) @@ -56,7 +56,7 @@ public OpenIdConnectAuthenticationMiddleware( var dataProtector = dataProtectionProvider.CreateProtector( typeof(OpenIdConnectAuthenticationMiddleware).FullName, typeof(string).FullName, - Options.AuthenticationType, + Options.AuthenticationScheme, "v1"); Options.StateDataFormat = new PropertiesDataFormat(dataProtector); @@ -67,7 +67,7 @@ public OpenIdConnectAuthenticationMiddleware( var dataProtector = dataProtectionProvider.CreateProtector( typeof(OpenIdConnectAuthenticationMiddleware).FullName, typeof(string).FullName, - Options.AuthenticationType, + Options.AuthenticationScheme, "v1"); Options.StringDataFormat = new SecureDataFormat(new StringSerializer(), dataProtector, TextEncodings.Base64Url); diff --git a/src/Microsoft.AspNet.Security.OpenIdConnect/OpenIdConnectAuthenticationNotifications.cs b/src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenIdConnectAuthenticationNotifications.cs similarity index 96% rename from src/Microsoft.AspNet.Security.OpenIdConnect/OpenIdConnectAuthenticationNotifications.cs rename to src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenIdConnectAuthenticationNotifications.cs index 327bbfa59..a4f15d6e9 100644 --- a/src/Microsoft.AspNet.Security.OpenIdConnect/OpenIdConnectAuthenticationNotifications.cs +++ b/src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenIdConnectAuthenticationNotifications.cs @@ -3,10 +3,10 @@ using System; using System.Threading.Tasks; -using Microsoft.AspNet.Security.Notifications; +using Microsoft.AspNet.Authentication.Notifications; using Microsoft.IdentityModel.Protocols; -namespace Microsoft.AspNet.Security.OpenIdConnect +namespace Microsoft.AspNet.Authentication.OpenIdConnect { /// /// Specifies events which the invokes to enable developer control over the authentication process. diff --git a/src/Microsoft.AspNet.Security.OpenIdConnect/OpenIdConnectAuthenticationOptions.cs b/src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenIdConnectAuthenticationOptions.cs similarity index 94% rename from src/Microsoft.AspNet.Security.OpenIdConnect/OpenIdConnectAuthenticationOptions.cs rename to src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenIdConnectAuthenticationOptions.cs index a5f1bcd30..d88501086 100644 --- a/src/Microsoft.AspNet.Security.OpenIdConnect/OpenIdConnectAuthenticationOptions.cs +++ b/src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenIdConnectAuthenticationOptions.cs @@ -7,10 +7,10 @@ using System.IdentityModel.Tokens; using System.Net.Http; using Microsoft.AspNet.Http; -using Microsoft.AspNet.Http.Security; +using Microsoft.AspNet.Http.Authentication; using Microsoft.IdentityModel.Protocols; -namespace Microsoft.AspNet.Security.OpenIdConnect +namespace Microsoft.AspNet.Authentication.OpenIdConnect { /// /// Configuration options for @@ -28,7 +28,7 @@ public class OpenIdConnectAuthenticationOptions : AuthenticationOptions /// Initializes a new /// public OpenIdConnectAuthenticationOptions() - : this(OpenIdConnectAuthenticationDefaults.AuthenticationType) + : this(OpenIdConnectAuthenticationDefaults.AuthenticationScheme) { } @@ -45,15 +45,16 @@ public OpenIdConnectAuthenticationOptions() /// RefreshOnIssuerKeyNotFound: true /// ResponseType: /// Scope: . - /// TokenValidationParameters: new with AuthenticationType = authenticationType. + /// TokenValidationParameters: new with AuthenticationScheme = authenticationScheme. /// UseTokenLifetime: true. /// - /// will be used to when creating the for the AuthenticationType property. + /// will be used to when creating the for the AuthenticationScheme property. [SuppressMessage("Microsoft.Globalization", "CA1303:Do not pass literals as localized parameters", MessageId = "Microsoft.Owin.Security.OpenIdConnect.OpenIdConnectAuthenticationOptions.set_Caption(System.String)", Justification = "Not a LOC field")] - public OpenIdConnectAuthenticationOptions(string authenticationType) + public OpenIdConnectAuthenticationOptions(string authenticationScheme) { - AuthenticationMode = AuthenticationMode.Active; - AuthenticationType = authenticationType; + // REVIEW: why was this active by default?? + //AuthenticationMode = AuthenticationMode.Active; + AuthenticationScheme = authenticationScheme; BackchannelTimeout = TimeSpan.FromMinutes(1); Caption = OpenIdConnectAuthenticationDefaults.Caption; ProtocolValidator = new OpenIdConnectProtocolValidator(); @@ -232,9 +233,9 @@ public OpenIdConnectProtocolValidator ProtocolValidator public string Scope { get; set; } /// - /// Gets or sets the AuthenticationType used when creating the . + /// Gets or sets the AuthenticationScheme used when creating the . /// - public string SignInAsAuthenticationType + public string SignInScheme { get { return TokenValidationParameters.AuthenticationType; } set { TokenValidationParameters.AuthenticationType = value; } diff --git a/src/Microsoft.AspNet.Security.OpenIdConnect/OpenidConnectAuthenticationHandler.cs b/src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenidConnectAuthenticationHandler.cs similarity index 97% rename from src/Microsoft.AspNet.Security.OpenIdConnect/OpenidConnectAuthenticationHandler.cs rename to src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenidConnectAuthenticationHandler.cs index b51eb5903..67711ac5e 100644 --- a/src/Microsoft.AspNet.Security.OpenIdConnect/OpenidConnectAuthenticationHandler.cs +++ b/src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenidConnectAuthenticationHandler.cs @@ -9,13 +9,13 @@ using System.Security.Claims; using System.Threading.Tasks; using Microsoft.AspNet.Http; -using Microsoft.AspNet.Http.Security; -using Microsoft.AspNet.Security.Infrastructure; -using Microsoft.AspNet.Security.Notifications; +using Microsoft.AspNet.Http.Authentication; +using Microsoft.AspNet.Authentication; +using Microsoft.AspNet.Authentication.Notifications; using Microsoft.Framework.Logging; using Microsoft.IdentityModel.Protocols; -namespace Microsoft.AspNet.Security.OpenIdConnect +namespace Microsoft.AspNet.Authentication.OpenIdConnect { /// /// A per-request authentication handler for the OpenIdConnectAuthenticationMiddleware. @@ -123,8 +123,8 @@ protected override async Task ApplyResponseChallengeAsync() return; } - // Active middleware should redirect on 401 even if there wasn't an explicit challenge. - if (ChallengeContext == null && Options.AuthenticationMode == AuthenticationMode.Passive) + // Only redirect on challenges + if (ChallengeContext == null) { return; } @@ -343,7 +343,7 @@ protected override async Task AuthenticateCoreAsync() throw new InvalidOperationException("No SecurityTokenValidator found for token: " + openIdConnectMessage.IdToken); } - ticket = new AuthenticationTicket(principal, properties, Options.AuthenticationType); + ticket = new AuthenticationTicket(principal, properties, Options.AuthenticationScheme); if (!string.IsNullOrWhiteSpace(openIdConnectMessage.SessionState)) { ticket.Properties.Dictionary[OpenIdConnectSessionProperties.SessionState] = openIdConnectMessage.SessionState; @@ -566,7 +566,7 @@ private async Task InvokeReplyPathAsync() { if (ticket.Principal != null) { - Request.HttpContext.Response.SignIn(ticket.Properties, ticket.Principal.Identities); + Request.HttpContext.Response.SignIn(ticket.AuthenticationScheme, ticket.Principal, ticket.Properties); } // Redirect back to the original secured resource, if any. diff --git a/src/Microsoft.AspNet.Security.OpenIdConnect/Resources.Designer.cs b/src/Microsoft.AspNet.Authentication.OpenIdConnect/Resources.Designer.cs similarity index 98% rename from src/Microsoft.AspNet.Security.OpenIdConnect/Resources.Designer.cs rename to src/Microsoft.AspNet.Authentication.OpenIdConnect/Resources.Designer.cs index f5bfc6044..ee19db011 100644 --- a/src/Microsoft.AspNet.Security.OpenIdConnect/Resources.Designer.cs +++ b/src/Microsoft.AspNet.Authentication.OpenIdConnect/Resources.Designer.cs @@ -8,7 +8,7 @@ // //------------------------------------------------------------------------------ -namespace Microsoft.AspNet.Security.OpenIdConnect { +namespace Microsoft.AspNet.Authentication.OpenIdConnect { using System; using System.Reflection; diff --git a/src/Microsoft.AspNet.Security.OpenIdConnect/Resources.resx b/src/Microsoft.AspNet.Authentication.OpenIdConnect/Resources.resx similarity index 100% rename from src/Microsoft.AspNet.Security.OpenIdConnect/Resources.resx rename to src/Microsoft.AspNet.Authentication.OpenIdConnect/Resources.resx diff --git a/src/Microsoft.AspNet.Security.OpenIdConnect/project.json b/src/Microsoft.AspNet.Authentication.OpenIdConnect/project.json similarity index 90% rename from src/Microsoft.AspNet.Security.OpenIdConnect/project.json rename to src/Microsoft.AspNet.Authentication.OpenIdConnect/project.json index a02c8145f..c25baafc3 100644 --- a/src/Microsoft.AspNet.Security.OpenIdConnect/project.json +++ b/src/Microsoft.AspNet.Authentication.OpenIdConnect/project.json @@ -1,7 +1,7 @@ { "version": "1.0.0-*", "dependencies": { - "Microsoft.AspNet.Security": "1.0.0-*", + "Microsoft.AspNet.Authentication": "1.0.0-*", "Microsoft.IdentityModel.Protocol.Extensions": "2.0.0-beta1-*" }, "frameworks": { diff --git a/src/Microsoft.AspNet.Security.Twitter/Messages/AccessToken.cs b/src/Microsoft.AspNet.Authentication.Twitter/Messages/AccessToken.cs similarity index 91% rename from src/Microsoft.AspNet.Security.Twitter/Messages/AccessToken.cs rename to src/Microsoft.AspNet.Authentication.Twitter/Messages/AccessToken.cs index f935da72a..2c3351453 100644 --- a/src/Microsoft.AspNet.Security.Twitter/Messages/AccessToken.cs +++ b/src/Microsoft.AspNet.Authentication.Twitter/Messages/AccessToken.cs @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -namespace Microsoft.AspNet.Security.Twitter.Messages +namespace Microsoft.AspNet.Authentication.Twitter.Messages { /// /// The Twitter access token retrieved from the access token endpoint. diff --git a/src/Microsoft.AspNet.Security.Twitter/Messages/RequestToken.cs b/src/Microsoft.AspNet.Authentication.Twitter/Messages/RequestToken.cs similarity index 89% rename from src/Microsoft.AspNet.Security.Twitter/Messages/RequestToken.cs rename to src/Microsoft.AspNet.Authentication.Twitter/Messages/RequestToken.cs index f801e555f..51c5c08e4 100644 --- a/src/Microsoft.AspNet.Security.Twitter/Messages/RequestToken.cs +++ b/src/Microsoft.AspNet.Authentication.Twitter/Messages/RequestToken.cs @@ -1,9 +1,9 @@ // Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -using Microsoft.AspNet.Http.Security; +using Microsoft.AspNet.Http.Authentication; -namespace Microsoft.AspNet.Security.Twitter.Messages +namespace Microsoft.AspNet.Authentication.Twitter.Messages { /// /// The Twitter request token obtained from the request token endpoint. diff --git a/src/Microsoft.AspNet.Security.Twitter/Messages/RequestTokenSerializer.cs b/src/Microsoft.AspNet.Authentication.Twitter/Messages/RequestTokenSerializer.cs similarity index 95% rename from src/Microsoft.AspNet.Security.Twitter/Messages/RequestTokenSerializer.cs rename to src/Microsoft.AspNet.Authentication.Twitter/Messages/RequestTokenSerializer.cs index 725dcc341..b575c70ee 100644 --- a/src/Microsoft.AspNet.Security.Twitter/Messages/RequestTokenSerializer.cs +++ b/src/Microsoft.AspNet.Authentication.Twitter/Messages/RequestTokenSerializer.cs @@ -4,10 +4,10 @@ using System; using System.Diagnostics.CodeAnalysis; using System.IO; -using Microsoft.AspNet.Http.Security; -using Microsoft.AspNet.Security.DataHandler.Serializer; +using Microsoft.AspNet.Http.Authentication; +using Microsoft.AspNet.Authentication.DataHandler.Serializer; -namespace Microsoft.AspNet.Security.Twitter.Messages +namespace Microsoft.AspNet.Authentication.Twitter.Messages { /// /// Serializes and deserializes Twitter request and access tokens so that they can be used by other application components. diff --git a/src/Microsoft.AspNet.Security.Twitter/Messages/Serializers.cs b/src/Microsoft.AspNet.Authentication.Twitter/Messages/Serializers.cs similarity index 85% rename from src/Microsoft.AspNet.Security.Twitter/Messages/Serializers.cs rename to src/Microsoft.AspNet.Authentication.Twitter/Messages/Serializers.cs index 3d2e1a458..749abaa3f 100644 --- a/src/Microsoft.AspNet.Security.Twitter/Messages/Serializers.cs +++ b/src/Microsoft.AspNet.Authentication.Twitter/Messages/Serializers.cs @@ -1,9 +1,9 @@ // Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -using Microsoft.AspNet.Security.DataHandler.Serializer; +using Microsoft.AspNet.Authentication.DataHandler.Serializer; -namespace Microsoft.AspNet.Security.Twitter.Messages +namespace Microsoft.AspNet.Authentication.Twitter.Messages { /// /// Provides access to a request token serializer. diff --git a/src/Microsoft.AspNet.Security.Twitter/Microsoft.AspNet.Security.Twitter.kproj b/src/Microsoft.AspNet.Authentication.Twitter/Microsoft.AspNet.Authentication.Twitter.kproj similarity index 95% rename from src/Microsoft.AspNet.Security.Twitter/Microsoft.AspNet.Security.Twitter.kproj rename to src/Microsoft.AspNet.Authentication.Twitter/Microsoft.AspNet.Authentication.Twitter.kproj index e073a505c..fb70dba2a 100644 --- a/src/Microsoft.AspNet.Security.Twitter/Microsoft.AspNet.Security.Twitter.kproj +++ b/src/Microsoft.AspNet.Authentication.Twitter/Microsoft.AspNet.Authentication.Twitter.kproj @@ -1,4 +1,4 @@ - + 14.0 @@ -14,4 +14,4 @@ 2.0 - + \ No newline at end of file diff --git a/src/Microsoft.AspNet.Authentication.Twitter/NotNullAttribute.cs b/src/Microsoft.AspNet.Authentication.Twitter/NotNullAttribute.cs new file mode 100644 index 000000000..c961a0c8f --- /dev/null +++ b/src/Microsoft.AspNet.Authentication.Twitter/NotNullAttribute.cs @@ -0,0 +1,12 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; + +namespace Microsoft.AspNet.Authentication.Twitter +{ + [AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false)] + internal sealed class NotNullAttribute : Attribute + { + } +} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Security.Twitter/Notifications/ITwitterAuthenticationNotifications.cs b/src/Microsoft.AspNet.Authentication.Twitter/Notifications/ITwitterAuthenticationNotifications.cs similarity index 97% rename from src/Microsoft.AspNet.Security.Twitter/Notifications/ITwitterAuthenticationNotifications.cs rename to src/Microsoft.AspNet.Authentication.Twitter/Notifications/ITwitterAuthenticationNotifications.cs index 55fd54892..3bf685ec3 100644 --- a/src/Microsoft.AspNet.Security.Twitter/Notifications/ITwitterAuthenticationNotifications.cs +++ b/src/Microsoft.AspNet.Authentication.Twitter/Notifications/ITwitterAuthenticationNotifications.cs @@ -3,7 +3,7 @@ using System.Threading.Tasks; -namespace Microsoft.AspNet.Security.Twitter +namespace Microsoft.AspNet.Authentication.Twitter { /// /// Specifies callback methods which the invokes to enable developer control over the authentication process. /> diff --git a/src/Microsoft.AspNet.Security.Twitter/Notifications/TwitterApplyRedirectContext.cs b/src/Microsoft.AspNet.Authentication.Twitter/Notifications/TwitterApplyRedirectContext.cs similarity index 91% rename from src/Microsoft.AspNet.Security.Twitter/Notifications/TwitterApplyRedirectContext.cs rename to src/Microsoft.AspNet.Authentication.Twitter/Notifications/TwitterApplyRedirectContext.cs index a328730de..ffac97680 100644 --- a/src/Microsoft.AspNet.Security.Twitter/Notifications/TwitterApplyRedirectContext.cs +++ b/src/Microsoft.AspNet.Authentication.Twitter/Notifications/TwitterApplyRedirectContext.cs @@ -2,10 +2,10 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using Microsoft.AspNet.Http; -using Microsoft.AspNet.Http.Security; -using Microsoft.AspNet.Security.Notifications; +using Microsoft.AspNet.Http.Authentication; +using Microsoft.AspNet.Authentication.Notifications; -namespace Microsoft.AspNet.Security.Twitter +namespace Microsoft.AspNet.Authentication.Twitter { /// /// The Context passed when a Challenge causes a redirect to authorize endpoint in the Twitter middleware. diff --git a/src/Microsoft.AspNet.Security.Twitter/Notifications/TwitterAuthenticatedContext.cs b/src/Microsoft.AspNet.Authentication.Twitter/Notifications/TwitterAuthenticatedContext.cs similarity index 88% rename from src/Microsoft.AspNet.Security.Twitter/Notifications/TwitterAuthenticatedContext.cs rename to src/Microsoft.AspNet.Authentication.Twitter/Notifications/TwitterAuthenticatedContext.cs index 0c050d9e8..9055c809d 100644 --- a/src/Microsoft.AspNet.Security.Twitter/Notifications/TwitterAuthenticatedContext.cs +++ b/src/Microsoft.AspNet.Authentication.Twitter/Notifications/TwitterAuthenticatedContext.cs @@ -3,10 +3,10 @@ using System.Security.Claims; using Microsoft.AspNet.Http; -using Microsoft.AspNet.Http.Security; -using Microsoft.AspNet.Security.Notifications; +using Microsoft.AspNet.Http.Authentication; +using Microsoft.AspNet.Authentication.Notifications; -namespace Microsoft.AspNet.Security.Twitter +namespace Microsoft.AspNet.Authentication.Twitter { /// /// Contains information about the login session as well as the user . @@ -56,9 +56,9 @@ public TwitterAuthenticatedContext( public string AccessTokenSecret { get; private set; } /// - /// Gets the representing the user + /// Gets the representing the user /// - public ClaimsIdentity Identity { get; set; } + public ClaimsPrincipal Principal { get; set; } /// /// Gets or sets a property bag for common authentication properties diff --git a/src/Microsoft.AspNet.Security.Twitter/Notifications/TwitterAuthenticationNotifications.cs b/src/Microsoft.AspNet.Authentication.Twitter/Notifications/TwitterAuthenticationNotifications.cs similarity index 98% rename from src/Microsoft.AspNet.Security.Twitter/Notifications/TwitterAuthenticationNotifications.cs rename to src/Microsoft.AspNet.Authentication.Twitter/Notifications/TwitterAuthenticationNotifications.cs index 2c6ff19d5..492dbb7f6 100644 --- a/src/Microsoft.AspNet.Security.Twitter/Notifications/TwitterAuthenticationNotifications.cs +++ b/src/Microsoft.AspNet.Authentication.Twitter/Notifications/TwitterAuthenticationNotifications.cs @@ -4,7 +4,7 @@ using System; using System.Threading.Tasks; -namespace Microsoft.AspNet.Security.Twitter +namespace Microsoft.AspNet.Authentication.Twitter { /// /// Default implementation. diff --git a/src/Microsoft.AspNet.Security.Twitter/Notifications/TwitterReturnEndpointContext.cs b/src/Microsoft.AspNet.Authentication.Twitter/Notifications/TwitterReturnEndpointContext.cs similarity index 88% rename from src/Microsoft.AspNet.Security.Twitter/Notifications/TwitterReturnEndpointContext.cs rename to src/Microsoft.AspNet.Authentication.Twitter/Notifications/TwitterReturnEndpointContext.cs index e420b5d1f..a4eb87eed 100644 --- a/src/Microsoft.AspNet.Security.Twitter/Notifications/TwitterReturnEndpointContext.cs +++ b/src/Microsoft.AspNet.Authentication.Twitter/Notifications/TwitterReturnEndpointContext.cs @@ -2,9 +2,9 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using Microsoft.AspNet.Http; -using Microsoft.AspNet.Security.Notifications; +using Microsoft.AspNet.Authentication.Notifications; -namespace Microsoft.AspNet.Security.Twitter +namespace Microsoft.AspNet.Authentication.Twitter { /// /// Provides context information to middleware providers. diff --git a/src/Microsoft.AspNet.Security.Twitter/Resources.Designer.cs b/src/Microsoft.AspNet.Authentication.Twitter/Resources.Designer.cs similarity index 95% rename from src/Microsoft.AspNet.Security.Twitter/Resources.Designer.cs rename to src/Microsoft.AspNet.Authentication.Twitter/Resources.Designer.cs index deda3cc77..5e6c599ae 100644 --- a/src/Microsoft.AspNet.Security.Twitter/Resources.Designer.cs +++ b/src/Microsoft.AspNet.Authentication.Twitter/Resources.Designer.cs @@ -8,7 +8,7 @@ // //------------------------------------------------------------------------------ -namespace Microsoft.AspNet.Security.Twitter { +namespace Microsoft.AspNet.Authentication.Twitter { using System; @@ -39,7 +39,7 @@ internal Resources() { internal static global::System.Resources.ResourceManager ResourceManager { get { if (object.ReferenceEquals(resourceMan, null)) { - global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Microsoft.AspNet.Security.Twitter.Resources", System.Reflection.IntrospectionExtensions.GetTypeInfo(typeof(Resources)).Assembly); + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Microsoft.AspNet.Authentication.Twitter.Resources", System.Reflection.IntrospectionExtensions.GetTypeInfo(typeof(Resources)).Assembly); resourceMan = temp; } return resourceMan; diff --git a/src/Microsoft.AspNet.Security.Twitter/Resources.resx b/src/Microsoft.AspNet.Authentication.Twitter/Resources.resx similarity index 100% rename from src/Microsoft.AspNet.Security.Twitter/Resources.resx rename to src/Microsoft.AspNet.Authentication.Twitter/Resources.resx diff --git a/src/Microsoft.AspNet.Security.Twitter/TwitterAuthenticationDefaults.cs b/src/Microsoft.AspNet.Authentication.Twitter/TwitterAuthenticationDefaults.cs similarity index 69% rename from src/Microsoft.AspNet.Security.Twitter/TwitterAuthenticationDefaults.cs rename to src/Microsoft.AspNet.Authentication.Twitter/TwitterAuthenticationDefaults.cs index 1f29a04b1..aa1faa20f 100644 --- a/src/Microsoft.AspNet.Security.Twitter/TwitterAuthenticationDefaults.cs +++ b/src/Microsoft.AspNet.Authentication.Twitter/TwitterAuthenticationDefaults.cs @@ -1,10 +1,10 @@ // Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -namespace Microsoft.AspNet.Security.Twitter +namespace Microsoft.AspNet.Authentication.Twitter { public static class TwitterAuthenticationDefaults { - public const string AuthenticationType = "Twitter"; + public const string AuthenticationScheme = "Twitter"; } } diff --git a/src/Microsoft.AspNet.Security.Twitter/TwitterAuthenticationExtensions.cs b/src/Microsoft.AspNet.Authentication.Twitter/TwitterAuthenticationExtensions.cs similarity index 93% rename from src/Microsoft.AspNet.Security.Twitter/TwitterAuthenticationExtensions.cs rename to src/Microsoft.AspNet.Authentication.Twitter/TwitterAuthenticationExtensions.cs index 5e97d8224..bff189792 100644 --- a/src/Microsoft.AspNet.Security.Twitter/TwitterAuthenticationExtensions.cs +++ b/src/Microsoft.AspNet.Authentication.Twitter/TwitterAuthenticationExtensions.cs @@ -1,8 +1,8 @@ // Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -using Microsoft.AspNet.Security.Infrastructure; -using Microsoft.AspNet.Security.Twitter; +using Microsoft.AspNet.Authentication; +using Microsoft.AspNet.Authentication.Twitter; using Microsoft.Framework.DependencyInjection; using Microsoft.Framework.OptionsModel; using System; diff --git a/src/Microsoft.AspNet.Security.Twitter/TwitterAuthenticationHandler.cs b/src/Microsoft.AspNet.Authentication.Twitter/TwitterAuthenticationHandler.cs similarity index 86% rename from src/Microsoft.AspNet.Security.Twitter/TwitterAuthenticationHandler.cs rename to src/Microsoft.AspNet.Authentication.Twitter/TwitterAuthenticationHandler.cs index b16c4a218..c6361295b 100644 --- a/src/Microsoft.AspNet.Security.Twitter/TwitterAuthenticationHandler.cs +++ b/src/Microsoft.AspNet.Authentication.Twitter/TwitterAuthenticationHandler.cs @@ -11,13 +11,13 @@ using System.Threading.Tasks; using Microsoft.AspNet.Http; using Microsoft.AspNet.Http.Core.Collections; -using Microsoft.AspNet.Http.Security; -using Microsoft.AspNet.Security.Infrastructure; -using Microsoft.AspNet.Security.Twitter.Messages; +using Microsoft.AspNet.Http.Authentication; +using Microsoft.AspNet.Authentication; +using Microsoft.AspNet.Authentication.Twitter.Messages; using Microsoft.AspNet.WebUtilities; using Microsoft.Framework.Logging; -namespace Microsoft.AspNet.Security.Twitter +namespace Microsoft.AspNet.Authentication.Twitter { internal class TwitterAuthenticationHandler : AuthenticationHandler { @@ -72,37 +72,38 @@ protected override async Task AuthenticateCoreAsync() if (string.IsNullOrWhiteSpace(returnedToken)) { _logger.WriteWarning("Missing oauth_token"); - return new AuthenticationTicket(null, properties); + return new AuthenticationTicket(properties, Options.AuthenticationScheme); } if (returnedToken != requestToken.Token) { _logger.WriteWarning("Unmatched token"); - return new AuthenticationTicket(null, properties); + return new AuthenticationTicket(properties, Options.AuthenticationScheme); } string oauthVerifier = query.Get("oauth_verifier"); if (string.IsNullOrWhiteSpace(oauthVerifier)) { _logger.WriteWarning("Missing or blank oauth_verifier"); - return new AuthenticationTicket(null, properties); + return new AuthenticationTicket(properties, Options.AuthenticationScheme); } AccessToken accessToken = await ObtainAccessTokenAsync(Options.ConsumerKey, Options.ConsumerSecret, requestToken, oauthVerifier); var context = new TwitterAuthenticatedContext(Context, accessToken.UserId, accessToken.ScreenName, accessToken.Token, accessToken.TokenSecret); - context.Identity = new ClaimsIdentity( - new[] - { - new Claim(ClaimTypes.NameIdentifier, accessToken.UserId, "http://www.w3.org/2001/XMLSchema#string", Options.AuthenticationType), - new Claim(ClaimTypes.Name, accessToken.ScreenName, "http://www.w3.org/2001/XMLSchema#string", Options.AuthenticationType), - new Claim("urn:twitter:userid", accessToken.UserId, "http://www.w3.org/2001/XMLSchema#string", Options.AuthenticationType), - new Claim("urn:twitter:screenname", accessToken.ScreenName, "http://www.w3.org/2001/XMLSchema#string", Options.AuthenticationType) - }, - Options.AuthenticationType, - ClaimsIdentity.DefaultNameClaimType, - ClaimsIdentity.DefaultRoleClaimType); + context.Principal = new ClaimsPrincipal( + new ClaimsIdentity( + new[] + { + new Claim(ClaimTypes.NameIdentifier, accessToken.UserId, "http://www.w3.org/2001/XMLSchema#string", Options.AuthenticationScheme), + new Claim(ClaimTypes.Name, accessToken.ScreenName, "http://www.w3.org/2001/XMLSchema#string", Options.AuthenticationScheme), + new Claim("urn:twitter:userid", accessToken.UserId, "http://www.w3.org/2001/XMLSchema#string", Options.AuthenticationScheme), + new Claim("urn:twitter:screenname", accessToken.ScreenName, "http://www.w3.org/2001/XMLSchema#string", Options.AuthenticationScheme) + }, + Options.AuthenticationScheme, + ClaimsIdentity.DefaultNameClaimType, + ClaimsIdentity.DefaultRoleClaimType)); context.Properties = requestToken.Properties; var cookieOptions = new CookieOptions @@ -115,12 +116,12 @@ protected override async Task AuthenticateCoreAsync() await Options.Notifications.Authenticated(context); - return new AuthenticationTicket(context.Identity, context.Properties); + return new AuthenticationTicket(context.Principal, context.Properties, Options.AuthenticationScheme); } catch (Exception ex) { _logger.WriteError("Authentication failed", ex); - return new AuthenticationTicket(null, properties); + return new AuthenticationTicket(properties, Options.AuthenticationScheme); } } protected override void ApplyResponseChallenge() @@ -135,8 +136,8 @@ protected override async Task ApplyResponseChallengeAsync() return; } - // Active middleware should redirect on 401 even if there wasn't an explicit challenge. - if (ChallengeContext == null && Options.AuthenticationMode == AuthenticationMode.Passive) + // Only redirect on challenges + if (ChallengeContext == null) { return; } @@ -195,26 +196,21 @@ public async Task InvokeReturnPathAsync() var context = new TwitterReturnEndpointContext(Context, model) { - SignInAsAuthenticationType = Options.SignInAsAuthenticationType, + SignInScheme = Options.SignInScheme, RedirectUri = model.Properties.RedirectUri }; model.Properties.RedirectUri = null; await Options.Notifications.ReturnEndpoint(context); - if (context.SignInAsAuthenticationType != null && context.Identity != null) + if (context.SignInScheme != null && context.Principal != null) { - ClaimsIdentity signInIdentity = context.Identity; - if (!string.Equals(signInIdentity.AuthenticationType, context.SignInAsAuthenticationType, StringComparison.Ordinal)) - { - signInIdentity = new ClaimsIdentity(signInIdentity.Claims, context.SignInAsAuthenticationType, signInIdentity.NameClaimType, signInIdentity.RoleClaimType); - } - Context.Response.SignIn(context.Properties, signInIdentity); + Context.Response.SignIn(context.SignInScheme, context.Principal, context.Properties); } if (!context.IsRequestCompleted && context.RedirectUri != null) { - if (context.Identity == null) + if (context.Principal == null) { // add a redirect hint that sign-in failed in some way context.RedirectUri = QueryHelpers.AddQueryString(context.RedirectUri, "error", "access_denied"); diff --git a/src/Microsoft.AspNet.Security.Twitter/TwitterAuthenticationMiddleware.cs b/src/Microsoft.AspNet.Authentication.Twitter/TwitterAuthenticationMiddleware.cs similarity index 90% rename from src/Microsoft.AspNet.Security.Twitter/TwitterAuthenticationMiddleware.cs rename to src/Microsoft.AspNet.Authentication.Twitter/TwitterAuthenticationMiddleware.cs index 98cdbdf37..686908092 100644 --- a/src/Microsoft.AspNet.Security.Twitter/TwitterAuthenticationMiddleware.cs +++ b/src/Microsoft.AspNet.Authentication.Twitter/TwitterAuthenticationMiddleware.cs @@ -5,16 +5,15 @@ using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.Net.Http; +using Microsoft.AspNet.Authentication.DataHandler; +using Microsoft.AspNet.Authentication.DataHandler.Encoder; +using Microsoft.AspNet.Authentication.Twitter.Messages; using Microsoft.AspNet.Builder; using Microsoft.AspNet.DataProtection; -using Microsoft.AspNet.Security.DataHandler; -using Microsoft.AspNet.Security.DataHandler.Encoder; -using Microsoft.AspNet.Security.Infrastructure; -using Microsoft.AspNet.Security.Twitter.Messages; using Microsoft.Framework.Logging; using Microsoft.Framework.OptionsModel; -namespace Microsoft.AspNet.Security.Twitter +namespace Microsoft.AspNet.Authentication.Twitter { /// /// ASP.NET middleware for authenticating users using Twitter @@ -61,20 +60,20 @@ public TwitterAuthenticationMiddleware( if (Options.StateDataFormat == null) { IDataProtector dataProtector = dataProtectionProvider.CreateProtector( - typeof(TwitterAuthenticationMiddleware).FullName, Options.AuthenticationType, "v1"); + typeof(TwitterAuthenticationMiddleware).FullName, Options.AuthenticationScheme, "v1"); Options.StateDataFormat = new SecureDataFormat( Serializers.RequestToken, dataProtector, TextEncodings.Base64Url); } - if (string.IsNullOrEmpty(Options.SignInAsAuthenticationType)) + if (string.IsNullOrEmpty(Options.SignInScheme)) { - Options.SignInAsAuthenticationType = externalOptions.Options.SignInAsAuthenticationType; + Options.SignInScheme = externalOptions.Options.SignInScheme; } - if (string.IsNullOrEmpty(Options.SignInAsAuthenticationType)) + if (string.IsNullOrEmpty(Options.SignInScheme)) { - throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, Resources.Exception_OptionMustBeProvided, "SignInAsAuthenticationType")); + throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, Resources.Exception_OptionMustBeProvided, "SignInScheme")); } _httpClient = new HttpClient(ResolveHttpMessageHandler(Options)); diff --git a/src/Microsoft.AspNet.Security.Twitter/TwitterAuthenticationOptions.cs b/src/Microsoft.AspNet.Authentication.Twitter/TwitterAuthenticationOptions.cs similarity index 92% rename from src/Microsoft.AspNet.Security.Twitter/TwitterAuthenticationOptions.cs rename to src/Microsoft.AspNet.Authentication.Twitter/TwitterAuthenticationOptions.cs index 91207863d..30e78f276 100644 --- a/src/Microsoft.AspNet.Security.Twitter/TwitterAuthenticationOptions.cs +++ b/src/Microsoft.AspNet.Authentication.Twitter/TwitterAuthenticationOptions.cs @@ -4,9 +4,9 @@ using System; using System.Net.Http; using Microsoft.AspNet.Http; -using Microsoft.AspNet.Security.Twitter.Messages; +using Microsoft.AspNet.Authentication.Twitter.Messages; -namespace Microsoft.AspNet.Security.Twitter +namespace Microsoft.AspNet.Authentication.Twitter { /// /// Options for the Twitter authentication middleware. @@ -18,10 +18,9 @@ public class TwitterAuthenticationOptions : AuthenticationOptions /// public TwitterAuthenticationOptions() { - AuthenticationType = TwitterAuthenticationDefaults.AuthenticationType; - Caption = AuthenticationType; + AuthenticationScheme = TwitterAuthenticationDefaults.AuthenticationScheme; + Caption = AuthenticationScheme; CallbackPath = new PathString("/signin-twitter"); - AuthenticationMode = AuthenticationMode.Passive; BackchannelTimeout = TimeSpan.FromSeconds(60); #if ASPNET50 // Twitter lists its valid Subject Key Identifiers at https://dev.twitter.com/docs/security/using-ssl @@ -92,7 +91,7 @@ public string Caption /// /// Gets or sets the name of another authentication middleware which will be responsible for actually issuing a user . /// - public string SignInAsAuthenticationType { get; set; } + public string SignInScheme { get; set; } /// /// Gets or sets the type used to secure data handled by the middleware. diff --git a/src/Microsoft.AspNet.Security.Twitter/project.json b/src/Microsoft.AspNet.Authentication.Twitter/project.json similarity index 90% rename from src/Microsoft.AspNet.Security.Twitter/project.json rename to src/Microsoft.AspNet.Authentication.Twitter/project.json index b9eba0a30..059a8d257 100644 --- a/src/Microsoft.AspNet.Security.Twitter/project.json +++ b/src/Microsoft.AspNet.Authentication.Twitter/project.json @@ -2,7 +2,7 @@ "version": "1.0.0-*", "description": "ASP.NET 5 middleware that enables an application to support Twitter's OAuth 2.0 authentication workflow.", "dependencies": { - "Microsoft.AspNet.Security": "1.0.0-*" + "Microsoft.AspNet.Authentication": "1.0.0-*" }, "frameworks": { "aspnet50": { diff --git a/src/Microsoft.AspNet.Security/Infrastructure/AuthenticationHandler.cs b/src/Microsoft.AspNet.Authentication/AuthenticationHandler.cs similarity index 83% rename from src/Microsoft.AspNet.Security/Infrastructure/AuthenticationHandler.cs rename to src/Microsoft.AspNet.Authentication/AuthenticationHandler.cs index 92b7889d5..f3d13d33f 100644 --- a/src/Microsoft.AspNet.Security/Infrastructure/AuthenticationHandler.cs +++ b/src/Microsoft.AspNet.Authentication/AuthenticationHandler.cs @@ -1,22 +1,19 @@ // Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - using System; using System.Collections.Generic; -using System.Diagnostics.CodeAnalysis; using System.Linq; -using System.Security.Claims; using System.Security.Cryptography; using System.Threading; using System.Threading.Tasks; +using Microsoft.AspNet.Authentication.DataHandler.Encoder; using Microsoft.AspNet.Http; -using Microsoft.AspNet.Http.Security; -using Microsoft.AspNet.Http.Interfaces.Security; -using Microsoft.AspNet.Security.DataHandler.Encoder; +using Microsoft.AspNet.Http.Authentication; +using Microsoft.AspNet.Http.Interfaces.Authentication; using Microsoft.Framework.Logging; -namespace Microsoft.AspNet.Security.Infrastructure +namespace Microsoft.AspNet.Authentication { /// /// Base class for the per-request work performed by most authentication middleware. @@ -36,7 +33,7 @@ public abstract class AuthenticationHandler : IAuthenticationHandler private AuthenticationOptions _baseOptions; protected IChallengeContext ChallengeContext { get; set; } - protected SignInIdentityContext SignInIdentityContext { get; set; } + protected SignInContext SignInContext { get; set; } protected ISignOutContext SignOutContext { get; set; } protected HttpContext Context { get; private set; } @@ -58,6 +55,8 @@ internal AuthenticationOptions BaseOptions get { return _baseOptions; } } + internal bool AuthenticateCalled { get; set; } + public IAuthenticationHandler PriorHandler { get; set; } public bool Faulted { get; set; } @@ -73,18 +72,6 @@ protected async Task BaseInitializeAsync(AuthenticationOptions options, HttpCont Response.OnSendingHeaders(OnSendingHeaderCallback, this); await InitializeCoreAsync(); - - if (BaseOptions.AuthenticationMode == AuthenticationMode.Active) - { - AuthenticationTicket ticket = await AuthenticateAsync(); - if (ticket != null) - { - if ( ticket.Identity != null) - SecurityHelper.AddUserIdentity(Context, ticket.Identity); - else if (ticket.Principal != null) - SecurityHelper.AddUserIdentity(Context, ticket.Principal.Identity); - } - } } private static void OnSendingHeaderCallback(object state) @@ -144,28 +131,29 @@ public virtual Task InvokeAsync() return Task.FromResult(false); } - public virtual void GetDescriptions(IAuthTypeContext authTypeContext) + public virtual void GetDescriptions(IDescribeSchemesContext describeContext) { - authTypeContext.Accept(BaseOptions.Description.Dictionary); + describeContext.Accept(BaseOptions.Description.Dictionary); if (PriorHandler != null) { - PriorHandler.GetDescriptions(authTypeContext); + PriorHandler.GetDescriptions(describeContext); } } public virtual void Authenticate(IAuthenticateContext context) { - if (context.AuthenticationTypes.Contains(BaseOptions.AuthenticationType, StringComparer.Ordinal)) + if (context.AuthenticationSchemes.Contains(BaseOptions.AuthenticationScheme, StringComparer.Ordinal)) { AuthenticationTicket ticket = Authenticate(); - if (ticket != null && ticket.Identity != null) + if (ticket != null && ticket.Principal != null) { - context.Authenticated(ticket.Identity, ticket.Properties.Dictionary, BaseOptions.Description.Dictionary); + AuthenticateCalled = true; + context.Authenticated(ticket.Principal, ticket.Properties.Dictionary, BaseOptions.Description.Dictionary); } else { - context.NotAuthenticated(BaseOptions.AuthenticationType, properties: null, description: BaseOptions.Description.Dictionary); + context.NotAuthenticated(BaseOptions.AuthenticationScheme, properties: null, description: BaseOptions.Description.Dictionary); } } @@ -177,16 +165,17 @@ public virtual void Authenticate(IAuthenticateContext context) public virtual async Task AuthenticateAsync(IAuthenticateContext context) { - if (context.AuthenticationTypes.Contains(BaseOptions.AuthenticationType, StringComparer.Ordinal)) + if (context.AuthenticationSchemes.Contains(BaseOptions.AuthenticationScheme, StringComparer.Ordinal)) { AuthenticationTicket ticket = await AuthenticateAsync(); - if (ticket != null && ticket.Identity != null) + if (ticket != null && ticket.Principal != null) { - context.Authenticated(ticket.Identity, ticket.Properties.Dictionary, BaseOptions.Description.Dictionary); + AuthenticateCalled = true; + context.Authenticated(ticket.Principal, ticket.Properties.Dictionary, BaseOptions.Description.Dictionary); } else { - context.NotAuthenticated(BaseOptions.AuthenticationType, properties: null, description: BaseOptions.Description.Dictionary); + context.NotAuthenticated(BaseOptions.AuthenticationScheme, properties: null, description: BaseOptions.Description.Dictionary); } } @@ -325,12 +314,11 @@ protected virtual Task ApplyResponseGrantAsync() public virtual void SignIn(ISignInContext context) { - ClaimsIdentity identity; - if (SecurityHelper.LookupSignIn(context.Identities, BaseOptions.AuthenticationType, out identity)) + if (ShouldHandleScheme(context.AuthenticationScheme)) { - SignInIdentityContext = new SignInIdentityContext(identity, new AuthenticationProperties(context.Properties)); + SignInContext = new SignInContext(context.Principal, new AuthenticationProperties(context.Properties)); SignOutContext = null; - context.Accept(BaseOptions.AuthenticationType, BaseOptions.Description.Dictionary); + context.Accept(BaseOptions.Description.Dictionary); } if (PriorHandler != null) @@ -341,11 +329,11 @@ public virtual void SignIn(ISignInContext context) public virtual void SignOut(ISignOutContext context) { - if (SecurityHelper.LookupSignOut(context.AuthenticationTypes, BaseOptions.AuthenticationType, BaseOptions.AuthenticationMode)) + if (ShouldHandleScheme(context.AuthenticationScheme)) { - SignInIdentityContext = null; + SignInContext = null; SignOutContext = context; - context.Accept(BaseOptions.AuthenticationType, BaseOptions.Description.Dictionary); + context.Accept(); } if (PriorHandler != null) @@ -356,10 +344,10 @@ public virtual void SignOut(ISignOutContext context) public virtual void Challenge(IChallengeContext context) { - if (SecurityHelper.LookupChallenge(context.AuthenticationTypes, BaseOptions.AuthenticationType, BaseOptions.AuthenticationMode)) + if (ShouldHandleScheme(context.AuthenticationSchemes)) { ChallengeContext = context; - context.Accept(BaseOptions.AuthenticationType, BaseOptions.Description.Dictionary); + context.Accept(BaseOptions.AuthenticationScheme, BaseOptions.Description.Dictionary); } if (PriorHandler != null) @@ -370,6 +358,18 @@ public virtual void Challenge(IChallengeContext context) protected abstract void ApplyResponseChallenge(); + public virtual bool ShouldHandleScheme(IEnumerable authenticationSchemes) + { + return authenticationSchemes != null && + authenticationSchemes.Any() && + authenticationSchemes.Contains(BaseOptions.AuthenticationScheme, StringComparer.Ordinal); + } + + public virtual bool ShouldHandleScheme(string authenticationScheme) + { + return string.Equals(BaseOptions.AuthenticationScheme, authenticationScheme, StringComparison.Ordinal); + } + /// /// Override this method to deal with 401 challenge concerns, if an authentication scheme in question /// deals an authentication interaction as part of it's request flow. (like adding a response header, or @@ -384,7 +384,7 @@ protected virtual Task ApplyResponseChallengeAsync() protected void GenerateCorrelationId([NotNull] AuthenticationProperties properties) { - string correlationKey = Constants.CorrelationPrefix + BaseOptions.AuthenticationType; + string correlationKey = Constants.CorrelationPrefix + BaseOptions.AuthenticationScheme; var nonceBytes = new byte[32]; CryptoRandom.GetBytes(nonceBytes); @@ -403,7 +403,7 @@ protected void GenerateCorrelationId([NotNull] AuthenticationProperties properti protected bool ValidateCorrelationId([NotNull] AuthenticationProperties properties, [NotNull] ILogger logger) { - string correlationKey = Constants.CorrelationPrefix + BaseOptions.AuthenticationType; + string correlationKey = Constants.CorrelationPrefix + BaseOptions.AuthenticationScheme; string correlationCookie = Request.Cookies[correlationKey]; if (string.IsNullOrWhiteSpace(correlationCookie)) diff --git a/src/Microsoft.AspNet.Security/Infrastructure/AuthenticationHandler`1.cs b/src/Microsoft.AspNet.Authentication/AuthenticationHandler`1.cs similarity index 90% rename from src/Microsoft.AspNet.Security/Infrastructure/AuthenticationHandler`1.cs rename to src/Microsoft.AspNet.Authentication/AuthenticationHandler`1.cs index 7d8fb0726..a70b11c60 100644 --- a/src/Microsoft.AspNet.Security/Infrastructure/AuthenticationHandler`1.cs +++ b/src/Microsoft.AspNet.Authentication/AuthenticationHandler`1.cs @@ -1,11 +1,10 @@ // Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - using System.Threading.Tasks; using Microsoft.AspNet.Http; -namespace Microsoft.AspNet.Security.Infrastructure +namespace Microsoft.AspNet.Authentication { /// /// Base class for the per-request work performed by most authentication middleware. @@ -21,7 +20,7 @@ public abstract class AuthenticationHandler : AuthenticationHandler wh /// The original options passed by the application control behavior /// The utility object to observe the current request and response /// async completion - internal Task Initialize(TOptions options, HttpContext context) + public Task Initialize(TOptions options, HttpContext context) { Options = options; return BaseInitializeAsync(options, context); diff --git a/src/Microsoft.AspNet.Security/Infrastructure/AuthenticationMiddleware.cs b/src/Microsoft.AspNet.Authentication/AuthenticationMiddleware.cs similarity index 95% rename from src/Microsoft.AspNet.Security/Infrastructure/AuthenticationMiddleware.cs rename to src/Microsoft.AspNet.Authentication/AuthenticationMiddleware.cs index a703619de..400a6e74a 100644 --- a/src/Microsoft.AspNet.Security/Infrastructure/AuthenticationMiddleware.cs +++ b/src/Microsoft.AspNet.Authentication/AuthenticationMiddleware.cs @@ -1,7 +1,6 @@ // Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - using System; using System.Threading.Tasks; using Microsoft.AspNet.Builder; @@ -9,7 +8,7 @@ using Microsoft.AspNet.RequestContainer; using Microsoft.Framework.OptionsModel; -namespace Microsoft.AspNet.Security.Infrastructure +namespace Microsoft.AspNet.Authentication { public abstract class AuthenticationMiddleware where TOptions : AuthenticationOptions, new() { @@ -31,7 +30,7 @@ protected AuthenticationMiddleware([NotNull] RequestDelegate next, [NotNull] ISe _services = services; } - public string AuthenticationType { get; set; } + public string AuthenticationScheme { get; set; } public TOptions Options { get; set; } diff --git a/src/Microsoft.AspNet.Authentication/AuthenticationOptions.cs b/src/Microsoft.AspNet.Authentication/AuthenticationOptions.cs new file mode 100644 index 000000000..09df9e5da --- /dev/null +++ b/src/Microsoft.AspNet.Authentication/AuthenticationOptions.cs @@ -0,0 +1,34 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using Microsoft.AspNet.Http.Authentication; + +namespace Microsoft.AspNet.Authentication +{ + /// + /// Base Options for all authentication middleware + /// + public abstract class AuthenticationOptions + { + private string _authenticationScheme; + + /// + /// The AuthenticationScheme in the options corresponds to the logical name for a particular authentication scheme. A different + /// value may be assigned in order to use the same authentication middleware type more than once in a pipeline. + /// + public string AuthenticationScheme + { + get { return _authenticationScheme; } + set + { + _authenticationScheme = value; + Description.AuthenticationScheme = value; + } + } + + /// + /// Additional information about the authentication type which is made available to the application. + /// + public AuthenticationDescription Description { get; set; } = new AuthenticationDescription(); + } +} diff --git a/src/Microsoft.AspNet.Security/AuthenticationTicket.cs b/src/Microsoft.AspNet.Authentication/AuthenticationTicket.cs similarity index 59% rename from src/Microsoft.AspNet.Security/AuthenticationTicket.cs rename to src/Microsoft.AspNet.Authentication/AuthenticationTicket.cs index 82128f10c..c7fb43f9a 100644 --- a/src/Microsoft.AspNet.Security/AuthenticationTicket.cs +++ b/src/Microsoft.AspNet.Authentication/AuthenticationTicket.cs @@ -2,9 +2,9 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System.Security.Claims; -using Microsoft.AspNet.Http.Security; +using Microsoft.AspNet.Http.Authentication; -namespace Microsoft.AspNet.Security +namespace Microsoft.AspNet.Authentication { /// /// Contains user identity information as well as additional authentication state. @@ -14,23 +14,19 @@ public class AuthenticationTicket /// /// Initializes a new instance of the class /// - /// - /// - public AuthenticationTicket(ClaimsIdentity identity, AuthenticationProperties properties) - { - Identity = identity; - Properties = properties ?? new AuthenticationProperties(); - } + /// additional properties that can be consumed by the user or runtime. + /// the authentication middleware that was responsible for this ticket. + public AuthenticationTicket(AuthenticationProperties properties, string authenticationScheme) : this(null, properties, authenticationScheme) { } /// /// Initializes a new instance of the class /// - /// the that represents the authenticated user. + /// the that represents the authenticated user. /// additional properties that can be consumed by the user or runtime. - /// the authentication middleware that was responsible for this ticket. - public AuthenticationTicket(ClaimsPrincipal principal, AuthenticationProperties properties, string authenticationType) + /// the authentication middleware that was responsible for this ticket. + public AuthenticationTicket(ClaimsPrincipal principal, AuthenticationProperties properties, string authenticationScheme) { - AuthenticationType = authenticationType; + AuthenticationScheme = authenticationScheme; Principal = principal; Properties = properties ?? new AuthenticationProperties(); } @@ -38,12 +34,7 @@ public AuthenticationTicket(ClaimsPrincipal principal, AuthenticationProperties /// /// Gets the authentication type. /// - public string AuthenticationType { get; private set; } - - /// - /// Gets the authenticated user identity. - /// - public ClaimsIdentity Identity { get; private set; } + public string AuthenticationScheme { get; private set; } /// /// Gets the claims-principal with authenticated user identities. diff --git a/src/Microsoft.AspNet.Security/Infrastructure/AuthenticationTokenCreateContext.cs b/src/Microsoft.AspNet.Authentication/AuthenticationTokenCreateContext.cs similarity index 91% rename from src/Microsoft.AspNet.Security/Infrastructure/AuthenticationTokenCreateContext.cs rename to src/Microsoft.AspNet.Authentication/AuthenticationTokenCreateContext.cs index 47815bbcd..eed3ac761 100644 --- a/src/Microsoft.AspNet.Security/Infrastructure/AuthenticationTokenCreateContext.cs +++ b/src/Microsoft.AspNet.Authentication/AuthenticationTokenCreateContext.cs @@ -4,9 +4,9 @@ using System; using Microsoft.AspNet.Http; -using Microsoft.AspNet.Security.Notifications; +using Microsoft.AspNet.Authentication.Notifications; -namespace Microsoft.AspNet.Security.Infrastructure +namespace Microsoft.AspNet.Authentication { public class AuthenticationTokenCreateContext : BaseContext { diff --git a/src/Microsoft.AspNet.Security/Infrastructure/AuthenticationTokenProvider.cs b/src/Microsoft.AspNet.Authentication/AuthenticationTokenProvider.cs similarity index 98% rename from src/Microsoft.AspNet.Security/Infrastructure/AuthenticationTokenProvider.cs rename to src/Microsoft.AspNet.Authentication/AuthenticationTokenProvider.cs index 7fb4fb498..7d090346f 100644 --- a/src/Microsoft.AspNet.Security/Infrastructure/AuthenticationTokenProvider.cs +++ b/src/Microsoft.AspNet.Authentication/AuthenticationTokenProvider.cs @@ -5,7 +5,7 @@ using System; using System.Threading.Tasks; -namespace Microsoft.AspNet.Security.Infrastructure +namespace Microsoft.AspNet.Authentication { public class AuthenticationTokenProvider : IAuthenticationTokenProvider { diff --git a/src/Microsoft.AspNet.Security/Infrastructure/AuthenticationTokenReceiveContext.cs b/src/Microsoft.AspNet.Authentication/AuthenticationTokenReceiveContext.cs similarity index 88% rename from src/Microsoft.AspNet.Security/Infrastructure/AuthenticationTokenReceiveContext.cs rename to src/Microsoft.AspNet.Authentication/AuthenticationTokenReceiveContext.cs index 2e68dc308..ea8e854ef 100644 --- a/src/Microsoft.AspNet.Security/Infrastructure/AuthenticationTokenReceiveContext.cs +++ b/src/Microsoft.AspNet.Authentication/AuthenticationTokenReceiveContext.cs @@ -2,9 +2,9 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using Microsoft.AspNet.Http; -using Microsoft.AspNet.Security.Notifications; +using Microsoft.AspNet.Authentication.Notifications; -namespace Microsoft.AspNet.Security.Infrastructure +namespace Microsoft.AspNet.Authentication { public class AuthenticationTokenReceiveContext : BaseContext { diff --git a/src/Microsoft.AspNet.Authentication/AutomaticAuthenticationHandler.cs b/src/Microsoft.AspNet.Authentication/AutomaticAuthenticationHandler.cs new file mode 100644 index 000000000..5032e47fa --- /dev/null +++ b/src/Microsoft.AspNet.Authentication/AutomaticAuthenticationHandler.cs @@ -0,0 +1,112 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.AspNet.Http.Interfaces.Authentication; + +namespace Microsoft.AspNet.Authentication +{ + /// + /// Base class for the per-request work performed by automatic authentication middleware. + /// + /// Specifies which type for of AutomaticAuthenticationOptions property + public abstract class AutomaticAuthenticationHandler : AuthenticationHandler where TOptions : AutomaticAuthenticationOptions + { + public virtual bool ShouldConvertChallengeToForbidden() + { + // Return 403 iff 401 and this handler's authenticate was called + // and the challenge is for the authentication type + return Response.StatusCode == 401 && + AuthenticateCalled && + ChallengeContext != null && + ShouldHandleScheme(ChallengeContext.AuthenticationSchemes); + } + + protected async override Task InitializeCoreAsync() + { + if (Options.AutomaticAuthentication) + { + AuthenticationTicket ticket = await AuthenticateAsync(); + if (ticket != null && ticket.Principal != null) + { + SecurityHelper.AddUserPrincipal(Context, ticket.Principal); + } + } + } + + public override void SignOut(ISignOutContext context) + { + // Empty or null auth scheme is allowed for automatic Authentication + if (Options.AutomaticAuthentication && string.IsNullOrWhiteSpace(context.AuthenticationScheme)) + { + SignInContext = null; + SignOutContext = context; + context.Accept(); + } + + base.SignOut(context); + } + + public override void Challenge(IChallengeContext context) + { + // Null or Empty scheme allowed for automatic authentication + if (Options.AutomaticAuthentication && + (context.AuthenticationSchemes == null || !context.AuthenticationSchemes.Any())) + { + ChallengeContext = context; + context.Accept(BaseOptions.AuthenticationScheme, BaseOptions.Description.Dictionary); + } + + base.Challenge(context); + } + + /// + /// Automatic Authentication Handlers can handle empty authentication schemes + /// + /// + public override bool ShouldHandleScheme(IEnumerable authenticationSchemes) + { + if (base.ShouldHandleScheme(authenticationSchemes)) + { + return true; + } + + return Options.AutomaticAuthentication && + (authenticationSchemes == null || !authenticationSchemes.Any()); + } + + /// + /// Automatic Authentication Handlers can handle empty authentication schemes + /// + /// + public override bool ShouldHandleScheme(string authenticationScheme) + { + if (base.ShouldHandleScheme(authenticationScheme)) + { + return true; + } + + return Options.AutomaticAuthentication && string.IsNullOrWhiteSpace(authenticationScheme); + } + + /// + /// Override this method to deal with 401 challenge concerns, if an authentication scheme in question + /// deals an authentication interaction as part of it's request flow. (like adding a response header, or + /// changing the 401 result to 302 of a login page or external sign-in location.) + /// + /// + protected override Task ApplyResponseChallengeAsync() + { + // If authenticate was called and the the status is still 401, authZ failed so set 403 and stop + if (ShouldConvertChallengeToForbidden()) + { + Response.StatusCode = 403; + return Task.FromResult(0); + } + return base.ApplyResponseChallengeAsync(); + } + + } +} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Authentication/AutomaticAuthenticationOptions.cs b/src/Microsoft.AspNet.Authentication/AutomaticAuthenticationOptions.cs new file mode 100644 index 000000000..53af20984 --- /dev/null +++ b/src/Microsoft.AspNet.Authentication/AutomaticAuthenticationOptions.cs @@ -0,0 +1,20 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using Microsoft.AspNet.Http.Authentication; + +namespace Microsoft.AspNet.Authentication +{ + /// + /// Base Options for all automatic authentication middleware + /// + public abstract class AutomaticAuthenticationOptions : AuthenticationOptions + { + /// + /// If true the authentication middleware alter the request user coming in and + /// alter 401 Unauthorized responses going out. If false the authentication middleware will only provide + /// identity and alter responses when explicitly indicated by the AuthenticationScheme. + /// + public bool AutomaticAuthentication { get; set; } + } +} diff --git a/src/Microsoft.AspNet.Security/CertificateSubjectKeyIdentifierValidator.cs b/src/Microsoft.AspNet.Authentication/CertificateSubjectKeyIdentifierValidator.cs similarity index 98% rename from src/Microsoft.AspNet.Security/CertificateSubjectKeyIdentifierValidator.cs rename to src/Microsoft.AspNet.Authentication/CertificateSubjectKeyIdentifierValidator.cs index 68cf5abd2..ca729b68f 100644 --- a/src/Microsoft.AspNet.Security/CertificateSubjectKeyIdentifierValidator.cs +++ b/src/Microsoft.AspNet.Authentication/CertificateSubjectKeyIdentifierValidator.cs @@ -7,7 +7,7 @@ using System.Net.Security; using System.Security.Cryptography.X509Certificates; -namespace Microsoft.AspNet.Security +namespace Microsoft.AspNet.Authentication { /// /// Provides pinned certificate validation based on the subject key identifier of the certificate. diff --git a/src/Microsoft.AspNet.Security/CertificateSubjectPublicKeyInfoValidator.cs b/src/Microsoft.AspNet.Authentication/CertificateSubjectPublicKeyInfoValidator.cs similarity index 99% rename from src/Microsoft.AspNet.Security/CertificateSubjectPublicKeyInfoValidator.cs rename to src/Microsoft.AspNet.Authentication/CertificateSubjectPublicKeyInfoValidator.cs index 4ad5ee81c..f2e5e9554 100644 --- a/src/Microsoft.AspNet.Security/CertificateSubjectPublicKeyInfoValidator.cs +++ b/src/Microsoft.AspNet.Authentication/CertificateSubjectPublicKeyInfoValidator.cs @@ -12,7 +12,7 @@ using System.Security.Cryptography.X509Certificates; using Microsoft.Win32; -namespace Microsoft.AspNet.Security +namespace Microsoft.AspNet.Authentication { /// /// Implements a cert pinning validator passed on diff --git a/src/Microsoft.AspNet.Security/CertificateThumbprintValidator.cs b/src/Microsoft.AspNet.Authentication/CertificateThumbprintValidator.cs similarity index 98% rename from src/Microsoft.AspNet.Security/CertificateThumbprintValidator.cs rename to src/Microsoft.AspNet.Authentication/CertificateThumbprintValidator.cs index a276536a7..822b42014 100644 --- a/src/Microsoft.AspNet.Security/CertificateThumbprintValidator.cs +++ b/src/Microsoft.AspNet.Authentication/CertificateThumbprintValidator.cs @@ -7,7 +7,7 @@ using System.Net.Security; using System.Security.Cryptography.X509Certificates; -namespace Microsoft.AspNet.Security +namespace Microsoft.AspNet.Authentication { /// /// Provides pinned certificate validation based on the certificate thumbprint. diff --git a/src/Microsoft.AspNet.Security/Infrastructure/Constants.cs b/src/Microsoft.AspNet.Authentication/Constants.cs similarity index 88% rename from src/Microsoft.AspNet.Security/Infrastructure/Constants.cs rename to src/Microsoft.AspNet.Authentication/Constants.cs index 26cfa103c..da3a23daa 100644 --- a/src/Microsoft.AspNet.Security/Infrastructure/Constants.cs +++ b/src/Microsoft.AspNet.Authentication/Constants.cs @@ -2,7 +2,7 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -namespace Microsoft.AspNet.Security.Infrastructure +namespace Microsoft.AspNet.Authentication { internal static class Constants { diff --git a/src/Microsoft.AspNet.Security/DataHandler/Encoder/Base64TextEncoder.cs b/src/Microsoft.AspNet.Authentication/DataHandler/Encoder/Base64TextEncoder.cs similarity index 88% rename from src/Microsoft.AspNet.Security/DataHandler/Encoder/Base64TextEncoder.cs rename to src/Microsoft.AspNet.Authentication/DataHandler/Encoder/Base64TextEncoder.cs index 9a208979d..0a4056450 100644 --- a/src/Microsoft.AspNet.Security/DataHandler/Encoder/Base64TextEncoder.cs +++ b/src/Microsoft.AspNet.Authentication/DataHandler/Encoder/Base64TextEncoder.cs @@ -4,7 +4,7 @@ using System; -namespace Microsoft.AspNet.Security.DataHandler.Encoder +namespace Microsoft.AspNet.Authentication.DataHandler.Encoder { public class Base64TextEncoder : ITextEncoder { diff --git a/src/Microsoft.AspNet.Security/DataHandler/Encoder/Base64UrlTextEncoder.cs b/src/Microsoft.AspNet.Authentication/DataHandler/Encoder/Base64UrlTextEncoder.cs similarity index 93% rename from src/Microsoft.AspNet.Security/DataHandler/Encoder/Base64UrlTextEncoder.cs rename to src/Microsoft.AspNet.Authentication/DataHandler/Encoder/Base64UrlTextEncoder.cs index b57fb51d9..93dd1a057 100644 --- a/src/Microsoft.AspNet.Security/DataHandler/Encoder/Base64UrlTextEncoder.cs +++ b/src/Microsoft.AspNet.Authentication/DataHandler/Encoder/Base64UrlTextEncoder.cs @@ -4,7 +4,7 @@ using System; -namespace Microsoft.AspNet.Security.DataHandler.Encoder +namespace Microsoft.AspNet.Authentication.DataHandler.Encoder { public class Base64UrlTextEncoder : ITextEncoder { diff --git a/src/Microsoft.AspNet.Security/DataHandler/Encoder/ITextEncoder.cs b/src/Microsoft.AspNet.Authentication/DataHandler/Encoder/ITextEncoder.cs similarity index 83% rename from src/Microsoft.AspNet.Security/DataHandler/Encoder/ITextEncoder.cs rename to src/Microsoft.AspNet.Authentication/DataHandler/Encoder/ITextEncoder.cs index 6ee681475..aeb577ec0 100644 --- a/src/Microsoft.AspNet.Security/DataHandler/Encoder/ITextEncoder.cs +++ b/src/Microsoft.AspNet.Authentication/DataHandler/Encoder/ITextEncoder.cs @@ -2,7 +2,7 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -namespace Microsoft.AspNet.Security.DataHandler.Encoder +namespace Microsoft.AspNet.Authentication.DataHandler.Encoder { public interface ITextEncoder { diff --git a/src/Microsoft.AspNet.Security/DataHandler/Encoder/TextEncodings.cs b/src/Microsoft.AspNet.Authentication/DataHandler/Encoder/TextEncodings.cs similarity index 91% rename from src/Microsoft.AspNet.Security/DataHandler/Encoder/TextEncodings.cs rename to src/Microsoft.AspNet.Authentication/DataHandler/Encoder/TextEncodings.cs index 67b233376..1b59cec5c 100644 --- a/src/Microsoft.AspNet.Security/DataHandler/Encoder/TextEncodings.cs +++ b/src/Microsoft.AspNet.Authentication/DataHandler/Encoder/TextEncodings.cs @@ -2,7 +2,7 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -namespace Microsoft.AspNet.Security.DataHandler.Encoder +namespace Microsoft.AspNet.Authentication.DataHandler.Encoder { public static class TextEncodings { diff --git a/src/Microsoft.AspNet.Security/DataHandler/ISecureDataFormat.cs b/src/Microsoft.AspNet.Authentication/DataHandler/ISecureDataFormat.cs similarity index 88% rename from src/Microsoft.AspNet.Security/DataHandler/ISecureDataFormat.cs rename to src/Microsoft.AspNet.Authentication/DataHandler/ISecureDataFormat.cs index eae66197f..2e3f24e84 100644 --- a/src/Microsoft.AspNet.Security/DataHandler/ISecureDataFormat.cs +++ b/src/Microsoft.AspNet.Authentication/DataHandler/ISecureDataFormat.cs @@ -2,7 +2,7 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -namespace Microsoft.AspNet.Security +namespace Microsoft.AspNet.Authentication { public interface ISecureDataFormat { diff --git a/src/Microsoft.AspNet.Security/DataHandler/PropertiesDataFormat.cs b/src/Microsoft.AspNet.Authentication/DataHandler/PropertiesDataFormat.cs similarity index 69% rename from src/Microsoft.AspNet.Security/DataHandler/PropertiesDataFormat.cs rename to src/Microsoft.AspNet.Authentication/DataHandler/PropertiesDataFormat.cs index 19a11a252..1472dd427 100644 --- a/src/Microsoft.AspNet.Security/DataHandler/PropertiesDataFormat.cs +++ b/src/Microsoft.AspNet.Authentication/DataHandler/PropertiesDataFormat.cs @@ -2,11 +2,11 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using Microsoft.AspNet.DataProtection; -using Microsoft.AspNet.Http.Security; -using Microsoft.AspNet.Security.DataHandler.Encoder; -using Microsoft.AspNet.Security.DataHandler.Serializer; +using Microsoft.AspNet.Http.Authentication; +using Microsoft.AspNet.Authentication.DataHandler.Encoder; +using Microsoft.AspNet.Authentication.DataHandler.Serializer; -namespace Microsoft.AspNet.Security.DataHandler +namespace Microsoft.AspNet.Authentication.DataHandler { public class PropertiesDataFormat : SecureDataFormat { diff --git a/src/Microsoft.AspNet.Security/DataHandler/SecureDataFormat.cs b/src/Microsoft.AspNet.Authentication/DataHandler/SecureDataFormat.cs similarity index 92% rename from src/Microsoft.AspNet.Security/DataHandler/SecureDataFormat.cs rename to src/Microsoft.AspNet.Authentication/DataHandler/SecureDataFormat.cs index 0c314fbf2..b7e240768 100644 --- a/src/Microsoft.AspNet.Security/DataHandler/SecureDataFormat.cs +++ b/src/Microsoft.AspNet.Authentication/DataHandler/SecureDataFormat.cs @@ -4,10 +4,10 @@ using System.Diagnostics.CodeAnalysis; using Microsoft.AspNet.DataProtection; -using Microsoft.AspNet.Security.DataHandler.Encoder; -using Microsoft.AspNet.Security.DataHandler.Serializer; +using Microsoft.AspNet.Authentication.DataHandler.Encoder; +using Microsoft.AspNet.Authentication.DataHandler.Serializer; -namespace Microsoft.AspNet.Security.DataHandler +namespace Microsoft.AspNet.Authentication.DataHandler { public class SecureDataFormat : ISecureDataFormat { @@ -62,4 +62,4 @@ public TData Unprotect(string protectedText) } } } -} +} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Security/DataHandler/Serializer/DataSerializers.cs b/src/Microsoft.AspNet.Authentication/DataHandler/Serializer/DataSerializers.cs similarity index 84% rename from src/Microsoft.AspNet.Security/DataHandler/Serializer/DataSerializers.cs rename to src/Microsoft.AspNet.Authentication/DataHandler/Serializer/DataSerializers.cs index a1864b44d..fd8e45fc8 100644 --- a/src/Microsoft.AspNet.Security/DataHandler/Serializer/DataSerializers.cs +++ b/src/Microsoft.AspNet.Authentication/DataHandler/Serializer/DataSerializers.cs @@ -2,9 +2,9 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -using Microsoft.AspNet.Http.Security; +using Microsoft.AspNet.Http.Authentication; -namespace Microsoft.AspNet.Security.DataHandler.Serializer +namespace Microsoft.AspNet.Authentication.DataHandler.Serializer { public static class DataSerializers { diff --git a/src/Microsoft.AspNet.Security/DataHandler/Serializer/IDataSerializer.cs b/src/Microsoft.AspNet.Authentication/DataHandler/Serializer/IDataSerializer.cs similarity index 83% rename from src/Microsoft.AspNet.Security/DataHandler/Serializer/IDataSerializer.cs rename to src/Microsoft.AspNet.Authentication/DataHandler/Serializer/IDataSerializer.cs index 60bd25bda..dc78d8c46 100644 --- a/src/Microsoft.AspNet.Security/DataHandler/Serializer/IDataSerializer.cs +++ b/src/Microsoft.AspNet.Authentication/DataHandler/Serializer/IDataSerializer.cs @@ -2,7 +2,7 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -namespace Microsoft.AspNet.Security.DataHandler.Serializer +namespace Microsoft.AspNet.Authentication.DataHandler.Serializer { public interface IDataSerializer { diff --git a/src/Microsoft.AspNet.Security/DataHandler/Serializer/PropertiesSerializer.cs b/src/Microsoft.AspNet.Authentication/DataHandler/Serializer/PropertiesSerializer.cs similarity index 95% rename from src/Microsoft.AspNet.Security/DataHandler/Serializer/PropertiesSerializer.cs rename to src/Microsoft.AspNet.Authentication/DataHandler/Serializer/PropertiesSerializer.cs index 66dcdfe3a..836828cda 100644 --- a/src/Microsoft.AspNet.Security/DataHandler/Serializer/PropertiesSerializer.cs +++ b/src/Microsoft.AspNet.Authentication/DataHandler/Serializer/PropertiesSerializer.cs @@ -6,9 +6,9 @@ using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using System.IO; -using Microsoft.AspNet.Http.Security; +using Microsoft.AspNet.Http.Authentication; -namespace Microsoft.AspNet.Security.DataHandler.Serializer +namespace Microsoft.AspNet.Authentication.DataHandler.Serializer { public class PropertiesSerializer : IDataSerializer { diff --git a/src/Microsoft.AspNet.Security/DataHandler/Serializer/TicketSerializer.cs b/src/Microsoft.AspNet.Authentication/DataHandler/Serializer/TicketSerializer.cs similarity index 52% rename from src/Microsoft.AspNet.Security/DataHandler/Serializer/TicketSerializer.cs rename to src/Microsoft.AspNet.Authentication/DataHandler/Serializer/TicketSerializer.cs index 9fe982ee8..9833dad54 100644 --- a/src/Microsoft.AspNet.Security/DataHandler/Serializer/TicketSerializer.cs +++ b/src/Microsoft.AspNet.Authentication/DataHandler/Serializer/TicketSerializer.cs @@ -6,7 +6,7 @@ using System.Linq; using System.Security.Claims; -namespace Microsoft.AspNet.Security.DataHandler.Serializer +namespace Microsoft.AspNet.Authentication.DataHandler.Serializer { public class TicketSerializer : IDataSerializer { @@ -38,18 +38,24 @@ public virtual AuthenticationTicket Deserialize(byte[] data) public static void Write([NotNull] BinaryWriter writer, [NotNull] AuthenticationTicket model) { writer.Write(FormatVersion); - ClaimsIdentity identity = model.Identity; - writer.Write(identity.AuthenticationType); - WriteWithDefault(writer, identity.NameClaimType, DefaultValues.NameClaimType); - WriteWithDefault(writer, identity.RoleClaimType, DefaultValues.RoleClaimType); - writer.Write(identity.Claims.Count()); - foreach (var claim in identity.Claims) + writer.Write(model.AuthenticationScheme); + var principal = model.Principal; + writer.Write(principal.Identities.Count()); + foreach (var identity in principal.Identities) { - WriteWithDefault(writer, claim.Type, identity.NameClaimType); - writer.Write(claim.Value); - WriteWithDefault(writer, claim.ValueType, DefaultValues.StringValueType); - WriteWithDefault(writer, claim.Issuer, DefaultValues.LocalAuthority); - WriteWithDefault(writer, claim.OriginalIssuer, claim.Issuer); + var authenticationType = string.IsNullOrWhiteSpace(identity.AuthenticationType) ? string.Empty : identity.AuthenticationType; + writer.Write(authenticationType); + WriteWithDefault(writer, identity.NameClaimType, DefaultValues.NameClaimType); + WriteWithDefault(writer, identity.RoleClaimType, DefaultValues.RoleClaimType); + writer.Write(identity.Claims.Count()); + foreach (var claim in identity.Claims) + { + WriteWithDefault(writer, claim.Type, identity.NameClaimType); + writer.Write(claim.Value); + WriteWithDefault(writer, claim.ValueType, DefaultValues.StringValueType); + WriteWithDefault(writer, claim.Issuer, DefaultValues.LocalAuthority); + WriteWithDefault(writer, claim.OriginalIssuer, claim.Issuer); + } } PropertiesSerializer.Write(writer, model.Properties); } @@ -60,24 +66,29 @@ public static AuthenticationTicket Read([NotNull] BinaryReader reader) { return null; } - - string authenticationType = reader.ReadString(); - string nameClaimType = ReadWithDefault(reader, DefaultValues.NameClaimType); - string roleClaimType = ReadWithDefault(reader, DefaultValues.RoleClaimType); - int count = reader.ReadInt32(); - var claims = new Claim[count]; - for (int index = 0; index != count; ++index) + string authenticationScheme = reader.ReadString(); + int identityCount = reader.ReadInt32(); + var identities = new ClaimsIdentity[identityCount]; + for (int i = 0; i != identityCount; ++i) { - string type = ReadWithDefault(reader, nameClaimType); - string value = reader.ReadString(); - string valueType = ReadWithDefault(reader, DefaultValues.StringValueType); - string issuer = ReadWithDefault(reader, DefaultValues.LocalAuthority); - string originalIssuer = ReadWithDefault(reader, issuer); - claims[index] = new Claim(type, value, valueType, issuer, originalIssuer); + string authenticationType = reader.ReadString(); + string nameClaimType = ReadWithDefault(reader, DefaultValues.NameClaimType); + string roleClaimType = ReadWithDefault(reader, DefaultValues.RoleClaimType); + int count = reader.ReadInt32(); + var claims = new Claim[count]; + for (int index = 0; index != count; ++index) + { + string type = ReadWithDefault(reader, nameClaimType); + string value = reader.ReadString(); + string valueType = ReadWithDefault(reader, DefaultValues.StringValueType); + string issuer = ReadWithDefault(reader, DefaultValues.LocalAuthority); + string originalIssuer = ReadWithDefault(reader, issuer); + claims[index] = new Claim(type, value, valueType, issuer, originalIssuer); + } + identities[i] = new ClaimsIdentity(claims, authenticationType, nameClaimType, roleClaimType); } - var identity = new ClaimsIdentity(claims, authenticationType, nameClaimType, roleClaimType); var properties = PropertiesSerializer.Read(reader); - return new AuthenticationTicket(identity, properties); + return new AuthenticationTicket(new ClaimsPrincipal(identities), properties, authenticationScheme); } private static void WriteWithDefault(BinaryWriter writer, string value, string defaultValue) diff --git a/src/Microsoft.AspNet.Security/DataHandler/TicketDataFormat.cs b/src/Microsoft.AspNet.Authentication/DataHandler/TicketDataFormat.cs similarity index 72% rename from src/Microsoft.AspNet.Security/DataHandler/TicketDataFormat.cs rename to src/Microsoft.AspNet.Authentication/DataHandler/TicketDataFormat.cs index b54f16666..922f5c8c0 100644 --- a/src/Microsoft.AspNet.Security/DataHandler/TicketDataFormat.cs +++ b/src/Microsoft.AspNet.Authentication/DataHandler/TicketDataFormat.cs @@ -1,12 +1,11 @@ // Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - using Microsoft.AspNet.DataProtection; -using Microsoft.AspNet.Security.DataHandler.Encoder; -using Microsoft.AspNet.Security.DataHandler.Serializer; +using Microsoft.AspNet.Authentication.DataHandler.Encoder; +using Microsoft.AspNet.Authentication.DataHandler.Serializer; -namespace Microsoft.AspNet.Security.DataHandler +namespace Microsoft.AspNet.Authentication.DataHandler { public class TicketDataFormat : SecureDataFormat { diff --git a/src/Microsoft.AspNet.Security/ExternalAuthenticationOptions.cs b/src/Microsoft.AspNet.Authentication/ExternalAuthenticationOptions.cs similarity index 72% rename from src/Microsoft.AspNet.Security/ExternalAuthenticationOptions.cs rename to src/Microsoft.AspNet.Authentication/ExternalAuthenticationOptions.cs index 671020b2b..966e2cfe1 100644 --- a/src/Microsoft.AspNet.Security/ExternalAuthenticationOptions.cs +++ b/src/Microsoft.AspNet.Authentication/ExternalAuthenticationOptions.cs @@ -4,10 +4,10 @@ using System; -namespace Microsoft.AspNet.Security +namespace Microsoft.AspNet.Authentication { public class ExternalAuthenticationOptions { - public string SignInAsAuthenticationType { get; set; } + public string SignInScheme { get; set; } } } diff --git a/src/Microsoft.AspNet.Security/Infrastructure/HttpContextExtensions.cs b/src/Microsoft.AspNet.Authentication/HttpContextExtensions.cs similarity index 82% rename from src/Microsoft.AspNet.Security/Infrastructure/HttpContextExtensions.cs rename to src/Microsoft.AspNet.Authentication/HttpContextExtensions.cs index 5ba7a9ce4..2f6b0e4d3 100644 --- a/src/Microsoft.AspNet.Security/Infrastructure/HttpContextExtensions.cs +++ b/src/Microsoft.AspNet.Authentication/HttpContextExtensions.cs @@ -2,10 +2,10 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using Microsoft.AspNet.Http; -using Microsoft.AspNet.Http.Core.Security; -using Microsoft.AspNet.Http.Interfaces.Security; +using Microsoft.AspNet.Http.Core.Authentication; +using Microsoft.AspNet.Http.Interfaces.Authentication; -namespace Microsoft.AspNet.Security.Infrastructure +namespace Microsoft.AspNet.Authentication { internal static class HttpContextExtensions { diff --git a/src/Microsoft.AspNet.Security/Infrastructure/IAuthenticationTokenProvider.cs b/src/Microsoft.AspNet.Authentication/IAuthenticationTokenProvider.cs similarity index 91% rename from src/Microsoft.AspNet.Security/Infrastructure/IAuthenticationTokenProvider.cs rename to src/Microsoft.AspNet.Authentication/IAuthenticationTokenProvider.cs index 2edcb42b2..d0c2bf34c 100644 --- a/src/Microsoft.AspNet.Security/Infrastructure/IAuthenticationTokenProvider.cs +++ b/src/Microsoft.AspNet.Authentication/IAuthenticationTokenProvider.cs @@ -4,7 +4,7 @@ using System.Threading.Tasks; -namespace Microsoft.AspNet.Security.Infrastructure +namespace Microsoft.AspNet.Authentication { public interface IAuthenticationTokenProvider { diff --git a/src/Microsoft.AspNet.Security/ICertificateValidator.cs b/src/Microsoft.AspNet.Authentication/ICertificateValidator.cs similarity index 97% rename from src/Microsoft.AspNet.Security/ICertificateValidator.cs rename to src/Microsoft.AspNet.Authentication/ICertificateValidator.cs index 26756324f..fd20f70b3 100644 --- a/src/Microsoft.AspNet.Security/ICertificateValidator.cs +++ b/src/Microsoft.AspNet.Authentication/ICertificateValidator.cs @@ -6,7 +6,7 @@ using System.Net.Security; using System.Security.Cryptography.X509Certificates; -namespace Microsoft.AspNet.Security +namespace Microsoft.AspNet.Authentication { /// /// Interface for providing pinned certificate validation, which checks HTTPS diff --git a/src/Microsoft.AspNet.Security/Infrastructure/ISystemClock.cs b/src/Microsoft.AspNet.Authentication/ISystemClock.cs similarity index 90% rename from src/Microsoft.AspNet.Security/Infrastructure/ISystemClock.cs rename to src/Microsoft.AspNet.Authentication/ISystemClock.cs index 4f799dc98..4748fb63e 100644 --- a/src/Microsoft.AspNet.Security/Infrastructure/ISystemClock.cs +++ b/src/Microsoft.AspNet.Authentication/ISystemClock.cs @@ -4,7 +4,7 @@ using System; -namespace Microsoft.AspNet.Security.Infrastructure +namespace Microsoft.AspNet.Authentication { /// /// Abstracts the system clock to facilitate testing. diff --git a/src/Microsoft.AspNet.Security/Microsoft.AspNet.Security.kproj b/src/Microsoft.AspNet.Authentication/Microsoft.AspNet.Authentication.kproj similarity index 95% rename from src/Microsoft.AspNet.Security/Microsoft.AspNet.Security.kproj rename to src/Microsoft.AspNet.Authentication/Microsoft.AspNet.Authentication.kproj index 6262851a7..b1e235900 100644 --- a/src/Microsoft.AspNet.Security/Microsoft.AspNet.Security.kproj +++ b/src/Microsoft.AspNet.Authentication/Microsoft.AspNet.Authentication.kproj @@ -1,4 +1,4 @@ - + 14.0 @@ -14,4 +14,4 @@ 2.0 - + \ No newline at end of file diff --git a/src/Microsoft.AspNet.Security.OAuth/NotNullAttribute.cs b/src/Microsoft.AspNet.Authentication/NotNullAttribute.cs similarity index 89% rename from src/Microsoft.AspNet.Security.OAuth/NotNullAttribute.cs rename to src/Microsoft.AspNet.Authentication/NotNullAttribute.cs index 3f56c4151..a30763317 100644 --- a/src/Microsoft.AspNet.Security.OAuth/NotNullAttribute.cs +++ b/src/Microsoft.AspNet.Authentication/NotNullAttribute.cs @@ -3,7 +3,7 @@ using System; -namespace Microsoft.AspNet.Security.OAuth +namespace Microsoft.AspNet.Authentication { [AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false)] internal sealed class NotNullAttribute : Attribute diff --git a/src/Microsoft.AspNet.Security/Notifications/AuthenticationFailedNotification.cs b/src/Microsoft.AspNet.Authentication/Notifications/AuthenticationFailedNotification.cs similarity index 91% rename from src/Microsoft.AspNet.Security/Notifications/AuthenticationFailedNotification.cs rename to src/Microsoft.AspNet.Authentication/Notifications/AuthenticationFailedNotification.cs index 5d232426f..16aa15751 100644 --- a/src/Microsoft.AspNet.Security/Notifications/AuthenticationFailedNotification.cs +++ b/src/Microsoft.AspNet.Authentication/Notifications/AuthenticationFailedNotification.cs @@ -4,7 +4,7 @@ using System; using Microsoft.AspNet.Http; -namespace Microsoft.AspNet.Security.Notifications +namespace Microsoft.AspNet.Authentication.Notifications { public class AuthenticationFailedNotification : BaseNotification { diff --git a/src/Microsoft.AspNet.Security/Notifications/BaseContext.cs b/src/Microsoft.AspNet.Authentication/Notifications/BaseContext.cs similarity index 92% rename from src/Microsoft.AspNet.Security/Notifications/BaseContext.cs rename to src/Microsoft.AspNet.Authentication/Notifications/BaseContext.cs index 3ae13a76d..11f65199c 100644 --- a/src/Microsoft.AspNet.Security/Notifications/BaseContext.cs +++ b/src/Microsoft.AspNet.Authentication/Notifications/BaseContext.cs @@ -4,7 +4,7 @@ using Microsoft.AspNet.Http; -namespace Microsoft.AspNet.Security.Notifications +namespace Microsoft.AspNet.Authentication.Notifications { public abstract class BaseContext { diff --git a/src/Microsoft.AspNet.Security/Notifications/BaseContext`1.cs b/src/Microsoft.AspNet.Authentication/Notifications/BaseContext`1.cs similarity index 93% rename from src/Microsoft.AspNet.Security/Notifications/BaseContext`1.cs rename to src/Microsoft.AspNet.Authentication/Notifications/BaseContext`1.cs index e0ad30626..184adfb3b 100644 --- a/src/Microsoft.AspNet.Security/Notifications/BaseContext`1.cs +++ b/src/Microsoft.AspNet.Authentication/Notifications/BaseContext`1.cs @@ -4,7 +4,7 @@ using Microsoft.AspNet.Http; -namespace Microsoft.AspNet.Security.Notifications +namespace Microsoft.AspNet.Authentication.Notifications { /// /// Base class used for certain event contexts diff --git a/src/Microsoft.AspNet.Security/Notifications/BaseNotification.cs b/src/Microsoft.AspNet.Authentication/Notifications/BaseNotification.cs similarity index 96% rename from src/Microsoft.AspNet.Security/Notifications/BaseNotification.cs rename to src/Microsoft.AspNet.Authentication/Notifications/BaseNotification.cs index d1ea6fef7..1563dbb07 100644 --- a/src/Microsoft.AspNet.Security/Notifications/BaseNotification.cs +++ b/src/Microsoft.AspNet.Authentication/Notifications/BaseNotification.cs @@ -4,7 +4,7 @@ using Microsoft.AspNet.Http; -namespace Microsoft.AspNet.Security.Notifications +namespace Microsoft.AspNet.Authentication.Notifications { public class BaseNotification : BaseContext { diff --git a/src/Microsoft.AspNet.Security/Notifications/EndpointContext.cs b/src/Microsoft.AspNet.Authentication/Notifications/EndpointContext.cs similarity index 90% rename from src/Microsoft.AspNet.Security/Notifications/EndpointContext.cs rename to src/Microsoft.AspNet.Authentication/Notifications/EndpointContext.cs index fd8251e13..1671316d1 100644 --- a/src/Microsoft.AspNet.Security/Notifications/EndpointContext.cs +++ b/src/Microsoft.AspNet.Authentication/Notifications/EndpointContext.cs @@ -4,7 +4,7 @@ using Microsoft.AspNet.Http; -namespace Microsoft.AspNet.Security.Notifications +namespace Microsoft.AspNet.Authentication.Notifications { public abstract class EndpointContext : BaseContext { diff --git a/src/Microsoft.AspNet.Security/Notifications/EndpointContext`1.cs b/src/Microsoft.AspNet.Authentication/Notifications/EndpointContext`1.cs similarity index 95% rename from src/Microsoft.AspNet.Security/Notifications/EndpointContext`1.cs rename to src/Microsoft.AspNet.Authentication/Notifications/EndpointContext`1.cs index 7b0b415e8..dde3a4fbb 100644 --- a/src/Microsoft.AspNet.Security/Notifications/EndpointContext`1.cs +++ b/src/Microsoft.AspNet.Authentication/Notifications/EndpointContext`1.cs @@ -4,7 +4,7 @@ using Microsoft.AspNet.Http; -namespace Microsoft.AspNet.Security.Notifications +namespace Microsoft.AspNet.Authentication.Notifications { /// /// Base class used for certain event contexts diff --git a/src/Microsoft.AspNet.Security/Notifications/MessageReceivedNotification.cs b/src/Microsoft.AspNet.Authentication/Notifications/MessageReceivedNotification.cs similarity index 92% rename from src/Microsoft.AspNet.Security/Notifications/MessageReceivedNotification.cs rename to src/Microsoft.AspNet.Authentication/Notifications/MessageReceivedNotification.cs index f583746c3..08f6521c0 100644 --- a/src/Microsoft.AspNet.Security/Notifications/MessageReceivedNotification.cs +++ b/src/Microsoft.AspNet.Authentication/Notifications/MessageReceivedNotification.cs @@ -3,7 +3,7 @@ using Microsoft.AspNet.Http; -namespace Microsoft.AspNet.Security.Notifications +namespace Microsoft.AspNet.Authentication.Notifications { public class MessageReceivedNotification : BaseNotification { diff --git a/src/Microsoft.AspNet.Security/Notifications/NotificationResultState.cs b/src/Microsoft.AspNet.Authentication/Notifications/NotificationResultState.cs similarity index 92% rename from src/Microsoft.AspNet.Security/Notifications/NotificationResultState.cs rename to src/Microsoft.AspNet.Authentication/Notifications/NotificationResultState.cs index 78d6c85ca..993aa7618 100644 --- a/src/Microsoft.AspNet.Security/Notifications/NotificationResultState.cs +++ b/src/Microsoft.AspNet.Authentication/Notifications/NotificationResultState.cs @@ -4,7 +4,7 @@ using System; -namespace Microsoft.AspNet.Security.Notifications +namespace Microsoft.AspNet.Authentication.Notifications { public enum NotificationResultState { diff --git a/src/Microsoft.AspNet.Security/Notifications/RedirectFromIdentityProviderNotification.cs b/src/Microsoft.AspNet.Authentication/Notifications/RedirectFromIdentityProviderNotification.cs similarity index 84% rename from src/Microsoft.AspNet.Security/Notifications/RedirectFromIdentityProviderNotification.cs rename to src/Microsoft.AspNet.Authentication/Notifications/RedirectFromIdentityProviderNotification.cs index 768b384a9..f883baf7d 100644 --- a/src/Microsoft.AspNet.Security/Notifications/RedirectFromIdentityProviderNotification.cs +++ b/src/Microsoft.AspNet.Authentication/Notifications/RedirectFromIdentityProviderNotification.cs @@ -3,7 +3,7 @@ using Microsoft.AspNet.Http; -namespace Microsoft.AspNet.Security.Notifications +namespace Microsoft.AspNet.Authentication.Notifications { public class RedirectFromIdentityProviderNotification : BaseNotification { @@ -12,7 +12,7 @@ public RedirectFromIdentityProviderNotification(HttpContext context, TOptions op { } - public string SignInAsAuthenticationType { get; set; } + public string SignInScheme { get; set; } public bool IsRequestCompleted { get; set; } diff --git a/src/Microsoft.AspNet.Security/Notifications/RedirectToIdentityProviderNotification.cs b/src/Microsoft.AspNet.Authentication/Notifications/RedirectToIdentityProviderNotification.cs similarity index 90% rename from src/Microsoft.AspNet.Security/Notifications/RedirectToIdentityProviderNotification.cs rename to src/Microsoft.AspNet.Authentication/Notifications/RedirectToIdentityProviderNotification.cs index 524664d7e..1c069b4e2 100644 --- a/src/Microsoft.AspNet.Security/Notifications/RedirectToIdentityProviderNotification.cs +++ b/src/Microsoft.AspNet.Authentication/Notifications/RedirectToIdentityProviderNotification.cs @@ -3,7 +3,7 @@ using Microsoft.AspNet.Http; -namespace Microsoft.AspNet.Security.Notifications +namespace Microsoft.AspNet.Authentication.Notifications { public class RedirectToIdentityProviderNotification : BaseNotification { diff --git a/src/Microsoft.AspNet.Security/Notifications/ReturnEndpointContext.cs b/src/Microsoft.AspNet.Authentication/Notifications/ReturnEndpointContext.cs similarity index 77% rename from src/Microsoft.AspNet.Security/Notifications/ReturnEndpointContext.cs rename to src/Microsoft.AspNet.Authentication/Notifications/ReturnEndpointContext.cs index 6d15d02fa..344c56ccc 100644 --- a/src/Microsoft.AspNet.Security/Notifications/ReturnEndpointContext.cs +++ b/src/Microsoft.AspNet.Authentication/Notifications/ReturnEndpointContext.cs @@ -5,9 +5,9 @@ using System.Diagnostics.CodeAnalysis; using System.Security.Claims; using Microsoft.AspNet.Http; -using Microsoft.AspNet.Http.Security; +using Microsoft.AspNet.Http.Authentication; -namespace Microsoft.AspNet.Security.Notifications +namespace Microsoft.AspNet.Authentication.Notifications { public abstract class ReturnEndpointContext : EndpointContext { @@ -18,15 +18,15 @@ protected ReturnEndpointContext( { if (ticket != null) { - Identity = ticket.Identity; + Principal = ticket.Principal; Properties = ticket.Properties; } } - public ClaimsIdentity Identity { get; set; } + public ClaimsPrincipal Principal { get; set; } public AuthenticationProperties Properties { get; set; } - public string SignInAsAuthenticationType { get; set; } + public string SignInScheme { get; set; } [SuppressMessage("Microsoft.Design", "CA1056:UriPropertiesShouldNotBeStrings", Justification = "By design")] public string RedirectUri { get; set; } diff --git a/src/Microsoft.AspNet.Security/Notifications/SecurityTokenReceivedNotification.cs b/src/Microsoft.AspNet.Authentication/Notifications/SecurityTokenReceivedNotification.cs similarity index 91% rename from src/Microsoft.AspNet.Security/Notifications/SecurityTokenReceivedNotification.cs rename to src/Microsoft.AspNet.Authentication/Notifications/SecurityTokenReceivedNotification.cs index 7db29788a..f7a042444 100644 --- a/src/Microsoft.AspNet.Security/Notifications/SecurityTokenReceivedNotification.cs +++ b/src/Microsoft.AspNet.Authentication/Notifications/SecurityTokenReceivedNotification.cs @@ -3,7 +3,7 @@ using Microsoft.AspNet.Http; -namespace Microsoft.AspNet.Security.Notifications +namespace Microsoft.AspNet.Authentication.Notifications { public class SecurityTokenReceivedNotification : BaseNotification { diff --git a/src/Microsoft.AspNet.Security/Notifications/SecurityTokenValidatedNotification.cs b/src/Microsoft.AspNet.Authentication/Notifications/SecurityTokenValidatedNotification.cs similarity index 90% rename from src/Microsoft.AspNet.Security/Notifications/SecurityTokenValidatedNotification.cs rename to src/Microsoft.AspNet.Authentication/Notifications/SecurityTokenValidatedNotification.cs index bdef232a7..aad6d7e3a 100644 --- a/src/Microsoft.AspNet.Security/Notifications/SecurityTokenValidatedNotification.cs +++ b/src/Microsoft.AspNet.Authentication/Notifications/SecurityTokenValidatedNotification.cs @@ -3,7 +3,7 @@ using Microsoft.AspNet.Http; -namespace Microsoft.AspNet.Security.Notifications +namespace Microsoft.AspNet.Authentication.Notifications { public class SecurityTokenValidatedNotification : BaseNotification { diff --git a/src/Microsoft.AspNet.Authentication/Properties/Resources.Designer.cs b/src/Microsoft.AspNet.Authentication/Properties/Resources.Designer.cs new file mode 100644 index 000000000..b1dc46b06 --- /dev/null +++ b/src/Microsoft.AspNet.Authentication/Properties/Resources.Designer.cs @@ -0,0 +1,78 @@ +// +namespace Microsoft.AspNet.Authentication +{ + using System.Globalization; + using System.Reflection; + using System.Resources; + + internal static class Resources + { + private static readonly ResourceManager _resourceManager + = new ResourceManager("Microsoft.AspNet.Authentication.Resources", typeof(Resources).GetTypeInfo().Assembly); + + /// + /// The default data protection provider may only be used when the IApplicationBuilder.Properties contains an appropriate 'host.AppName' key. + /// + internal static string Exception_DefaultDpapiRequiresAppNameKey + { + get { return GetString("Exception_DefaultDpapiRequiresAppNameKey"); } + } + + /// + /// The default data protection provider may only be used when the IApplicationBuilder.Properties contains an appropriate 'host.AppName' key. + /// + internal static string FormatException_DefaultDpapiRequiresAppNameKey() + { + return GetString("Exception_DefaultDpapiRequiresAppNameKey"); + } + + /// + /// The state passed to UnhookAuthentication may only be the return value from HookAuthentication. + /// + internal static string Exception_UnhookAuthenticationStateType + { + get { return GetString("Exception_UnhookAuthenticationStateType"); } + } + + /// + /// The state passed to UnhookAuthentication may only be the return value from HookAuthentication. + /// + internal static string FormatException_UnhookAuthenticationStateType() + { + return GetString("Exception_UnhookAuthenticationStateType"); + } + + /// + /// The AuthenticationTokenProvider's required synchronous events have not been registered. + /// + internal static string Exception_AuthenticationTokenDoesNotProvideSyncMethods + { + get { return GetString("Exception_AuthenticationTokenDoesNotProvideSyncMethods"); } + } + + /// + /// The AuthenticationTokenProvider's required synchronous events have not been registered. + /// + internal static string FormatException_AuthenticationTokenDoesNotProvideSyncMethods() + { + return GetString("Exception_AuthenticationTokenDoesNotProvideSyncMethods"); + } + + private static string GetString(string name, params string[] formatterNames) + { + var value = _resourceManager.GetString(name); + + System.Diagnostics.Debug.Assert(value != null); + + if (formatterNames != null) + { + for (var i = 0; i < formatterNames.Length; i++) + { + value = value.Replace("{" + formatterNames[i] + "}", "{" + i + "}"); + } + } + + return value; + } + } +} diff --git a/src/Microsoft.AspNet.Authentication/Resources.resx b/src/Microsoft.AspNet.Authentication/Resources.resx new file mode 100644 index 000000000..77060045e --- /dev/null +++ b/src/Microsoft.AspNet.Authentication/Resources.resx @@ -0,0 +1,129 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + The default data protection provider may only be used when the IApplicationBuilder.Properties contains an appropriate 'host.AppName' key. + + + The state passed to UnhookAuthentication may only be the return value from HookAuthentication. + + + The AuthenticationTokenProvider's required synchronous events have not been registered. + + \ No newline at end of file diff --git a/src/Microsoft.AspNet.Authentication/SecurityHelper.cs b/src/Microsoft.AspNet.Authentication/SecurityHelper.cs new file mode 100644 index 000000000..1e73888c6 --- /dev/null +++ b/src/Microsoft.AspNet.Authentication/SecurityHelper.cs @@ -0,0 +1,39 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Security.Claims; +using Microsoft.AspNet.Http; + +namespace Microsoft.AspNet.Authentication +{ + /// + /// Helper code used when implementing authentication middleware + /// + public static class SecurityHelper + { + /// + /// Add all ClaimsIdenities from an additional ClaimPrincipal to the ClaimsPrincipal + /// + /// + public static void AddUserPrincipal([NotNull] HttpContext context, [NotNull] ClaimsPrincipal principal) + { + ClaimsPrincipal existingPrincipal = context.User; + if (existingPrincipal != null) + { + foreach (var existingClaimsIdentity in existingPrincipal.Identities) + { + // REVIEW: No longer use auth type for anything, so we could remove this check, except for the default one HttpContext.user creates + // REVIEW: Need to ignore any identities that did not come from an authentication scheme? + if (existingClaimsIdentity.IsAuthenticated) + { + principal.AddIdentity(existingClaimsIdentity); + } + } + } + context.User = principal; + } + } +} diff --git a/src/Microsoft.AspNet.Security/Infrastructure/SignInIdentityContext.cs b/src/Microsoft.AspNet.Authentication/SignInContext.cs similarity index 53% rename from src/Microsoft.AspNet.Security/Infrastructure/SignInIdentityContext.cs rename to src/Microsoft.AspNet.Authentication/SignInContext.cs index 309e04892..efe055ba8 100644 --- a/src/Microsoft.AspNet.Security/Infrastructure/SignInIdentityContext.cs +++ b/src/Microsoft.AspNet.Authentication/SignInContext.cs @@ -2,19 +2,19 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System.Security.Claims; -using Microsoft.AspNet.Http.Security; +using Microsoft.AspNet.Http.Authentication; -namespace Microsoft.AspNet.Security.Infrastructure +namespace Microsoft.AspNet.Authentication { - public class SignInIdentityContext + public class SignInContext { - public SignInIdentityContext(ClaimsIdentity identity, AuthenticationProperties properties) + public SignInContext(ClaimsPrincipal principal, AuthenticationProperties properties) { - Identity = identity; + Principal = principal; Properties = properties; } - public ClaimsIdentity Identity { get; private set; } + public ClaimsPrincipal Principal { get; private set; } public AuthenticationProperties Properties { get; private set; } } } diff --git a/src/Microsoft.AspNet.Security/SubjectPublicKeyInfoAlgorithm.cs b/src/Microsoft.AspNet.Authentication/SubjectPublicKeyInfoAlgorithm.cs similarity index 94% rename from src/Microsoft.AspNet.Security/SubjectPublicKeyInfoAlgorithm.cs rename to src/Microsoft.AspNet.Authentication/SubjectPublicKeyInfoAlgorithm.cs index aefe5ef76..921abb953 100644 --- a/src/Microsoft.AspNet.Security/SubjectPublicKeyInfoAlgorithm.cs +++ b/src/Microsoft.AspNet.Authentication/SubjectPublicKeyInfoAlgorithm.cs @@ -2,7 +2,7 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -namespace Microsoft.AspNet.Security +namespace Microsoft.AspNet.Authentication { /// /// The algorithm used to generate the subject public key information blob hashes. diff --git a/src/Microsoft.AspNet.Security/Infrastructure/SystemClock.cs b/src/Microsoft.AspNet.Authentication/SystemClock.cs similarity index 94% rename from src/Microsoft.AspNet.Security/Infrastructure/SystemClock.cs rename to src/Microsoft.AspNet.Authentication/SystemClock.cs index 0c800d3fd..11c30564f 100644 --- a/src/Microsoft.AspNet.Security/Infrastructure/SystemClock.cs +++ b/src/Microsoft.AspNet.Authentication/SystemClock.cs @@ -4,7 +4,7 @@ using System; -namespace Microsoft.AspNet.Security.Infrastructure +namespace Microsoft.AspNet.Authentication { /// /// Provides access to the normal system clock. diff --git a/src/Microsoft.AspNet.Security/Win32.cs b/src/Microsoft.AspNet.Authentication/Win32.cs similarity index 100% rename from src/Microsoft.AspNet.Security/Win32.cs rename to src/Microsoft.AspNet.Authentication/Win32.cs diff --git a/src/Microsoft.AspNet.Security/project.json b/src/Microsoft.AspNet.Authentication/project.json similarity index 100% rename from src/Microsoft.AspNet.Security/project.json rename to src/Microsoft.AspNet.Authentication/project.json diff --git a/src/Microsoft.AspNet.Security/AuthorizationContext.cs b/src/Microsoft.AspNet.Authorization/AuthorizationContext.cs similarity index 97% rename from src/Microsoft.AspNet.Security/AuthorizationContext.cs rename to src/Microsoft.AspNet.Authorization/AuthorizationContext.cs index 81d00bdc9..4044b84f5 100644 --- a/src/Microsoft.AspNet.Security/AuthorizationContext.cs +++ b/src/Microsoft.AspNet.Authorization/AuthorizationContext.cs @@ -5,7 +5,7 @@ using System.Linq; using System.Security.Claims; -namespace Microsoft.AspNet.Security +namespace Microsoft.AspNet.Authorization { /// /// Contains authorization information used by . diff --git a/src/Microsoft.AspNet.Security/AuthorizationHandler.cs b/src/Microsoft.AspNet.Authorization/AuthorizationHandler.cs similarity index 98% rename from src/Microsoft.AspNet.Security/AuthorizationHandler.cs rename to src/Microsoft.AspNet.Authorization/AuthorizationHandler.cs index e1b27e863..c05b55b9c 100644 --- a/src/Microsoft.AspNet.Security/AuthorizationHandler.cs +++ b/src/Microsoft.AspNet.Authorization/AuthorizationHandler.cs @@ -4,7 +4,7 @@ using System.Linq; using System.Threading.Tasks; -namespace Microsoft.AspNet.Security +namespace Microsoft.AspNet.Authorization { public abstract class AuthorizationHandler : IAuthorizationHandler where TRequirement : IAuthorizationRequirement diff --git a/src/Microsoft.AspNet.Security/AuthorizationOptions.cs b/src/Microsoft.AspNet.Authorization/AuthorizationOptions.cs similarity index 96% rename from src/Microsoft.AspNet.Security/AuthorizationOptions.cs rename to src/Microsoft.AspNet.Authorization/AuthorizationOptions.cs index 8a53e574d..708ed1abc 100644 --- a/src/Microsoft.AspNet.Security/AuthorizationOptions.cs +++ b/src/Microsoft.AspNet.Authorization/AuthorizationOptions.cs @@ -4,7 +4,7 @@ using System; using System.Collections.Generic; -namespace Microsoft.AspNet.Security +namespace Microsoft.AspNet.Authorization { public class AuthorizationOptions { diff --git a/src/Microsoft.AspNet.Security/AuthorizationPolicy.cs b/src/Microsoft.AspNet.Authorization/AuthorizationPolicy.cs similarity index 87% rename from src/Microsoft.AspNet.Security/AuthorizationPolicy.cs rename to src/Microsoft.AspNet.Authorization/AuthorizationPolicy.cs index 924f9dbd2..ca9fcc203 100644 --- a/src/Microsoft.AspNet.Security/AuthorizationPolicy.cs +++ b/src/Microsoft.AspNet.Authorization/AuthorizationPolicy.cs @@ -5,18 +5,18 @@ using System.Collections.Generic; using System.Linq; -namespace Microsoft.AspNet.Security +namespace Microsoft.AspNet.Authorization { public class AuthorizationPolicy { - public AuthorizationPolicy(IEnumerable requirements, IEnumerable activeAuthenticationTypes) + public AuthorizationPolicy(IEnumerable requirements, IEnumerable activeAuthenticationSchemes) { Requirements = new List(requirements).AsReadOnly(); - ActiveAuthenticationTypes = new List(activeAuthenticationTypes).AsReadOnly(); + ActiveAuthenticationSchemes = new List(activeAuthenticationSchemes).AsReadOnly(); } public IReadOnlyList Requirements { get; private set; } - public IReadOnlyList ActiveAuthenticationTypes { get; private set; } + public IReadOnlyList ActiveAuthenticationSchemes { get; private set; } public static AuthorizationPolicy Combine([NotNull] params AuthorizationPolicy[] policies) { @@ -55,15 +55,15 @@ public static AuthorizationPolicy Combine([NotNull] AuthorizationOptions options var rolesSplit = authorizeAttribute.Roles?.Split(','); if (rolesSplit != null && rolesSplit.Any()) { - policyBuilder.RequiresRole(rolesSplit); + policyBuilder.RequireRole(rolesSplit); requireAnyAuthenticated = false; } - string[] authTypesSplit = authorizeAttribute.ActiveAuthenticationTypes?.Split(','); + string[] authTypesSplit = authorizeAttribute.ActiveAuthenticationSchemes?.Split(','); if (authTypesSplit != null && authTypesSplit.Any()) { foreach (var authType in authTypesSplit) { - policyBuilder.ActiveAuthenticationTypes.Add(authType); + policyBuilder.ActiveAuthenticationSchemes.Add(authType); } } if (requireAnyAuthenticated) diff --git a/src/Microsoft.AspNet.Security/AuthorizationPolicyBuilder.cs b/src/Microsoft.AspNet.Authorization/AuthorizationPolicyBuilder.cs similarity index 60% rename from src/Microsoft.AspNet.Security/AuthorizationPolicyBuilder.cs rename to src/Microsoft.AspNet.Authorization/AuthorizationPolicyBuilder.cs index bf97fbae2..f2f24746c 100644 --- a/src/Microsoft.AspNet.Security/AuthorizationPolicyBuilder.cs +++ b/src/Microsoft.AspNet.Authorization/AuthorizationPolicyBuilder.cs @@ -5,13 +5,13 @@ using System.Linq; using System.Security.Claims; -namespace Microsoft.AspNet.Security +namespace Microsoft.AspNet.Authorization { public class AuthorizationPolicyBuilder { - public AuthorizationPolicyBuilder(params string[] activeAuthenticationTypes) + public AuthorizationPolicyBuilder(params string[] activeAuthenticationSchemes) { - AddAuthenticationTypes(activeAuthenticationTypes); + AddAuthenticationSchemes(activeAuthenticationSchemes); } public AuthorizationPolicyBuilder(AuthorizationPolicy policy) @@ -20,13 +20,13 @@ public AuthorizationPolicyBuilder(AuthorizationPolicy policy) } public IList Requirements { get; set; } = new List(); - public IList ActiveAuthenticationTypes { get; set; } = new List(); + public IList ActiveAuthenticationSchemes { get; set; } = new List(); - public AuthorizationPolicyBuilder AddAuthenticationTypes(params string[] activeAuthTypes) + public AuthorizationPolicyBuilder AddAuthenticationSchemes(params string[] activeAuthTypes) { foreach (var authType in activeAuthTypes) { - ActiveAuthenticationTypes.Add(authType); + ActiveAuthenticationSchemes.Add(authType); } return this; } @@ -42,17 +42,17 @@ public AuthorizationPolicyBuilder AddRequirements(params IAuthorizationRequireme public AuthorizationPolicyBuilder Combine([NotNull] AuthorizationPolicy policy) { - AddAuthenticationTypes(policy.ActiveAuthenticationTypes.ToArray()); + AddAuthenticationSchemes(policy.ActiveAuthenticationSchemes.ToArray()); AddRequirements(policy.Requirements.ToArray()); return this; } - public AuthorizationPolicyBuilder RequiresClaim([NotNull] string claimType, params string[] requiredValues) + public AuthorizationPolicyBuilder RequireClaim([NotNull] string claimType, params string[] requiredValues) { - return RequiresClaim(claimType, (IEnumerable)requiredValues); + return RequireClaim(claimType, (IEnumerable)requiredValues); } - public AuthorizationPolicyBuilder RequiresClaim([NotNull] string claimType, IEnumerable requiredValues) + public AuthorizationPolicyBuilder RequireClaim([NotNull] string claimType, IEnumerable requiredValues) { Requirements.Add(new ClaimsAuthorizationRequirement { @@ -62,7 +62,7 @@ public AuthorizationPolicyBuilder RequiresClaim([NotNull] string claimType, IEnu return this; } - public AuthorizationPolicyBuilder RequiresClaim([NotNull] string claimType) + public AuthorizationPolicyBuilder RequireClaim([NotNull] string claimType) { Requirements.Add(new ClaimsAuthorizationRequirement { @@ -72,14 +72,20 @@ public AuthorizationPolicyBuilder RequiresClaim([NotNull] string claimType) return this; } - public AuthorizationPolicyBuilder RequiresRole([NotNull] params string[] roles) + public AuthorizationPolicyBuilder RequireRole([NotNull] params string[] roles) { - return RequiresRole((IEnumerable)roles); + return RequireRole((IEnumerable)roles); } - public AuthorizationPolicyBuilder RequiresRole([NotNull] IEnumerable roles) + public AuthorizationPolicyBuilder RequireRole([NotNull] IEnumerable roles) { - RequiresClaim(ClaimTypes.Role, roles); + RequireClaim(ClaimTypes.Role, roles); + return this; + } + + public AuthorizationPolicyBuilder RequireUserName([NotNull] string userName) + { + RequireClaim(ClaimTypes.Name, userName); return this; } @@ -91,7 +97,7 @@ public AuthorizationPolicyBuilder RequireAuthenticatedUser() public AuthorizationPolicy Build() { - return new AuthorizationPolicy(Requirements, ActiveAuthenticationTypes.Distinct()); + return new AuthorizationPolicy(Requirements, ActiveAuthenticationSchemes.Distinct()); } } } \ No newline at end of file diff --git a/src/Microsoft.AspNet.Security/AuthorizationServiceExtensions.cs b/src/Microsoft.AspNet.Authorization/AuthorizationServiceExtensions.cs similarity index 69% rename from src/Microsoft.AspNet.Security/AuthorizationServiceExtensions.cs rename to src/Microsoft.AspNet.Authorization/AuthorizationServiceExtensions.cs index e3e416c89..595d88077 100644 --- a/src/Microsoft.AspNet.Security/AuthorizationServiceExtensions.cs +++ b/src/Microsoft.AspNet.Authorization/AuthorizationServiceExtensions.cs @@ -5,7 +5,7 @@ using System.Security.Claims; using System.Threading.Tasks; -namespace Microsoft.AspNet.Security +namespace Microsoft.AspNet.Authorization { public static class AuthorizationServiceExtensions { @@ -19,11 +19,12 @@ public static class AuthorizationServiceExtensions /// true when the user fulfills the policy, false otherwise. public static Task AuthorizeAsync([NotNull] this IAuthorizationService service, ClaimsPrincipal user, object resource, [NotNull] AuthorizationPolicy policy) { - if (policy.ActiveAuthenticationTypes != null && policy.ActiveAuthenticationTypes.Any() && user != null) - { - // Filter the user to only contain the active authentication types - user = new ClaimsPrincipal(user.Identities.Where(i => policy.ActiveAuthenticationTypes.Contains(i.AuthenticationType))); - } + // TODO RENABLE + //if (policy.ActiveAuthenticationSchemes != null && policy.ActiveAuthenticationSchemes.Any() && user != null) + //{ + // // Filter the user to only contain the active authentication types + // user = new ClaimsPrincipal(user.Identities.Where(i => policy.ActiveAuthenticationSchemes.Contains(i.AuthenticationScheme))); + //} return service.AuthorizeAsync(user, resource, policy.Requirements.ToArray()); } @@ -37,11 +38,12 @@ public static Task AuthorizeAsync([NotNull] this IAuthorizationService ser /// true when the user fulfills the policy, false otherwise. public static bool Authorize([NotNull] this IAuthorizationService service, ClaimsPrincipal user, object resource, [NotNull] AuthorizationPolicy policy) { - if (policy.ActiveAuthenticationTypes != null && policy.ActiveAuthenticationTypes.Any() && user != null) - { - // Filter the user to only contain the active authentication types - user = new ClaimsPrincipal(user.Identities.Where(i => policy.ActiveAuthenticationTypes.Contains(i.AuthenticationType))); - } + // TODO: REeanble + //if (policy.ActiveAuthenticationSchemes != null && policy.ActiveAuthenticationSchemes.Any() && user != null) + //{ + // // Filter the user to only contain the active authentication types + // user = new ClaimsPrincipal(user.Identities.Where(i => policy.ActiveAuthenticationSchemes.Contains(i.AuthenticationScheme))); + //} return service.Authorize(user, resource, policy.Requirements.ToArray()); } diff --git a/src/Microsoft.AspNet.Security/AuthorizeAttribute.cs b/src/Microsoft.AspNet.Authorization/AuthorizeAttribute.cs similarity index 86% rename from src/Microsoft.AspNet.Security/AuthorizeAttribute.cs rename to src/Microsoft.AspNet.Authorization/AuthorizeAttribute.cs index bdaefafbf..15db20dbf 100644 --- a/src/Microsoft.AspNet.Security/AuthorizeAttribute.cs +++ b/src/Microsoft.AspNet.Authorization/AuthorizeAttribute.cs @@ -3,7 +3,7 @@ using System; -namespace Microsoft.AspNet.Security +namespace Microsoft.AspNet.Authorization { [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true, Inherited = true)] public class AuthorizeAttribute : Attribute @@ -20,6 +20,6 @@ public AuthorizeAttribute(string policy) // REVIEW: can we get rid of the , deliminated in Roles/AuthTypes public string Roles { get; set; } - public string ActiveAuthenticationTypes { get; set; } + public string ActiveAuthenticationSchemes { get; set; } } } diff --git a/src/Microsoft.AspNet.Security/ClaimsAuthorizationHandler.cs b/src/Microsoft.AspNet.Authorization/ClaimsAuthorizationHandler.cs similarity index 96% rename from src/Microsoft.AspNet.Security/ClaimsAuthorizationHandler.cs rename to src/Microsoft.AspNet.Authorization/ClaimsAuthorizationHandler.cs index 9aa95ef60..608b14936 100644 --- a/src/Microsoft.AspNet.Security/ClaimsAuthorizationHandler.cs +++ b/src/Microsoft.AspNet.Authorization/ClaimsAuthorizationHandler.cs @@ -4,7 +4,7 @@ using System; using System.Linq; -namespace Microsoft.AspNet.Security +namespace Microsoft.AspNet.Authorization { public class ClaimsAuthorizationHandler : AuthorizationHandler { diff --git a/src/Microsoft.AspNet.Security/ClaimsAuthorizationRequirement.cs b/src/Microsoft.AspNet.Authorization/ClaimsAuthorizationRequirement.cs similarity index 93% rename from src/Microsoft.AspNet.Security/ClaimsAuthorizationRequirement.cs rename to src/Microsoft.AspNet.Authorization/ClaimsAuthorizationRequirement.cs index 8ec5e7c7e..d13c9ecc9 100644 --- a/src/Microsoft.AspNet.Security/ClaimsAuthorizationRequirement.cs +++ b/src/Microsoft.AspNet.Authorization/ClaimsAuthorizationRequirement.cs @@ -3,7 +3,7 @@ using System.Collections.Generic; -namespace Microsoft.AspNet.Security +namespace Microsoft.AspNet.Authorization { // Must contain a claim with the specified name, and at least one of the required values // If AllowedValues is null or empty, that means any claim is valid diff --git a/src/Microsoft.AspNet.Security/ClaimsTransformationOptions.cs b/src/Microsoft.AspNet.Authorization/ClaimsTransformationOptions.cs similarity index 90% rename from src/Microsoft.AspNet.Security/ClaimsTransformationOptions.cs rename to src/Microsoft.AspNet.Authorization/ClaimsTransformationOptions.cs index 4684ad69d..da3a4a7bd 100644 --- a/src/Microsoft.AspNet.Security/ClaimsTransformationOptions.cs +++ b/src/Microsoft.AspNet.Authorization/ClaimsTransformationOptions.cs @@ -6,7 +6,7 @@ using System.Security.Claims; using System.Threading.Tasks; -namespace Microsoft.AspNet.Security +namespace Microsoft.AspNet.Authorization { public class ClaimsTransformationOptions { diff --git a/src/Microsoft.AspNet.Security/DefaultAuthorizationService.cs b/src/Microsoft.AspNet.Authorization/DefaultAuthorizationService.cs similarity index 98% rename from src/Microsoft.AspNet.Security/DefaultAuthorizationService.cs rename to src/Microsoft.AspNet.Authorization/DefaultAuthorizationService.cs index 943fbce9f..d99f778d9 100644 --- a/src/Microsoft.AspNet.Security/DefaultAuthorizationService.cs +++ b/src/Microsoft.AspNet.Authorization/DefaultAuthorizationService.cs @@ -7,7 +7,7 @@ using System.Threading.Tasks; using Microsoft.Framework.OptionsModel; -namespace Microsoft.AspNet.Security +namespace Microsoft.AspNet.Authorization { public class DefaultAuthorizationService : IAuthorizationService { diff --git a/src/Microsoft.AspNet.Security/DenyAnonymousAuthorizationHandler.cs b/src/Microsoft.AspNet.Authorization/DenyAnonymousAuthorizationHandler.cs similarity index 95% rename from src/Microsoft.AspNet.Security/DenyAnonymousAuthorizationHandler.cs rename to src/Microsoft.AspNet.Authorization/DenyAnonymousAuthorizationHandler.cs index 952ed30b8..4ce5d43ed 100644 --- a/src/Microsoft.AspNet.Security/DenyAnonymousAuthorizationHandler.cs +++ b/src/Microsoft.AspNet.Authorization/DenyAnonymousAuthorizationHandler.cs @@ -3,7 +3,7 @@ using System.Threading.Tasks; -namespace Microsoft.AspNet.Security +namespace Microsoft.AspNet.Authorization { public class DenyAnonymousAuthorizationHandler : AuthorizationHandler { diff --git a/src/Microsoft.AspNet.Security/DenyAnonymousAuthorizationRequirement.cs b/src/Microsoft.AspNet.Authorization/DenyAnonymousAuthorizationRequirement.cs similarity index 77% rename from src/Microsoft.AspNet.Security/DenyAnonymousAuthorizationRequirement.cs rename to src/Microsoft.AspNet.Authorization/DenyAnonymousAuthorizationRequirement.cs index 286d5fd69..ecbee9b90 100644 --- a/src/Microsoft.AspNet.Security/DenyAnonymousAuthorizationRequirement.cs +++ b/src/Microsoft.AspNet.Authorization/DenyAnonymousAuthorizationRequirement.cs @@ -1,9 +1,9 @@ // Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -using Microsoft.AspNet.Security; +using Microsoft.AspNet.Authorization; -namespace Microsoft.AspNet.Security +namespace Microsoft.AspNet.Authorization { public class DenyAnonymousAuthorizationRequirement : IAuthorizationRequirement { } } diff --git a/src/Microsoft.AspNet.Security/IAuthorizationHandler.cs b/src/Microsoft.AspNet.Authorization/IAuthorizationHandler.cs similarity index 90% rename from src/Microsoft.AspNet.Security/IAuthorizationHandler.cs rename to src/Microsoft.AspNet.Authorization/IAuthorizationHandler.cs index 82eea9ff2..bcd0cdc2b 100644 --- a/src/Microsoft.AspNet.Security/IAuthorizationHandler.cs +++ b/src/Microsoft.AspNet.Authorization/IAuthorizationHandler.cs @@ -3,7 +3,7 @@ using System.Threading.Tasks; -namespace Microsoft.AspNet.Security +namespace Microsoft.AspNet.Authorization { public interface IAuthorizationHandler { diff --git a/src/Microsoft.AspNet.Security/IAuthorizationRequirement.cs b/src/Microsoft.AspNet.Authorization/IAuthorizationRequirement.cs similarity index 85% rename from src/Microsoft.AspNet.Security/IAuthorizationRequirement.cs rename to src/Microsoft.AspNet.Authorization/IAuthorizationRequirement.cs index bd25247df..5aeef262e 100644 --- a/src/Microsoft.AspNet.Security/IAuthorizationRequirement.cs +++ b/src/Microsoft.AspNet.Authorization/IAuthorizationRequirement.cs @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -namespace Microsoft.AspNet.Security +namespace Microsoft.AspNet.Authorization { public interface IAuthorizationRequirement { diff --git a/src/Microsoft.AspNet.Security/IAuthorizationService.cs b/src/Microsoft.AspNet.Authorization/IAuthorizationService.cs similarity index 98% rename from src/Microsoft.AspNet.Security/IAuthorizationService.cs rename to src/Microsoft.AspNet.Authorization/IAuthorizationService.cs index 317e1ae28..89215c7aa 100644 --- a/src/Microsoft.AspNet.Security/IAuthorizationService.cs +++ b/src/Microsoft.AspNet.Authorization/IAuthorizationService.cs @@ -4,7 +4,7 @@ using System.Security.Claims; using System.Threading.Tasks; -namespace Microsoft.AspNet.Security +namespace Microsoft.AspNet.Authorization { /// /// Checks policy based permissions for a user diff --git a/src/Microsoft.AspNet.Authorization/Microsoft.AspNet.Authorization.kproj b/src/Microsoft.AspNet.Authorization/Microsoft.AspNet.Authorization.kproj new file mode 100644 index 000000000..43b060769 --- /dev/null +++ b/src/Microsoft.AspNet.Authorization/Microsoft.AspNet.Authorization.kproj @@ -0,0 +1,17 @@ + + + + 14.0 + $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) + + + + 6ab3e514-5894-4131-9399-dc7d5284addb + ..\..\artifacts\obj\$(MSBuildProjectName) + ..\..\artifacts\bin\$(MSBuildProjectName)\ + + + 2.0 + + + \ No newline at end of file diff --git a/src/Microsoft.AspNet.Security/Infrastructure/NotNullAttribute.cs b/src/Microsoft.AspNet.Authorization/NotNullAttribute.cs similarity index 89% rename from src/Microsoft.AspNet.Security/Infrastructure/NotNullAttribute.cs rename to src/Microsoft.AspNet.Authorization/NotNullAttribute.cs index 24f550945..64ea6d573 100644 --- a/src/Microsoft.AspNet.Security/Infrastructure/NotNullAttribute.cs +++ b/src/Microsoft.AspNet.Authorization/NotNullAttribute.cs @@ -3,7 +3,7 @@ using System; -namespace Microsoft.AspNet.Security +namespace Microsoft.AspNet.Authorization { [AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false)] internal sealed class NotNullAttribute : Attribute diff --git a/src/Microsoft.AspNet.Security/OperationAuthorizationRequirement.cs b/src/Microsoft.AspNet.Authorization/OperationAuthorizationRequirement.cs similarity index 88% rename from src/Microsoft.AspNet.Security/OperationAuthorizationRequirement.cs rename to src/Microsoft.AspNet.Authorization/OperationAuthorizationRequirement.cs index e7e08d195..64cd198eb 100644 --- a/src/Microsoft.AspNet.Security/OperationAuthorizationRequirement.cs +++ b/src/Microsoft.AspNet.Authorization/OperationAuthorizationRequirement.cs @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -namespace Microsoft.AspNet.Security +namespace Microsoft.AspNet.Authorization { public class OperationAuthorizationRequirement : IAuthorizationRequirement { diff --git a/src/Microsoft.AspNet.Security/PassThroughAuthorizationHandler.cs b/src/Microsoft.AspNet.Authorization/PassThroughAuthorizationHandler.cs similarity index 95% rename from src/Microsoft.AspNet.Security/PassThroughAuthorizationHandler.cs rename to src/Microsoft.AspNet.Authorization/PassThroughAuthorizationHandler.cs index a2173f1e0..3ae506b2d 100644 --- a/src/Microsoft.AspNet.Security/PassThroughAuthorizationHandler.cs +++ b/src/Microsoft.AspNet.Authorization/PassThroughAuthorizationHandler.cs @@ -4,7 +4,7 @@ using System.Linq; using System.Threading.Tasks; -namespace Microsoft.AspNet.Security +namespace Microsoft.AspNet.Authorization { public class PassThroughAuthorizationHandler : IAuthorizationHandler { diff --git a/src/Microsoft.AspNet.Security/Properties/Resources.Designer.cs b/src/Microsoft.AspNet.Authorization/Properties/Resources.Designer.cs similarity index 95% rename from src/Microsoft.AspNet.Security/Properties/Resources.Designer.cs rename to src/Microsoft.AspNet.Authorization/Properties/Resources.Designer.cs index 3490d3ea7..b8ab20596 100644 --- a/src/Microsoft.AspNet.Security/Properties/Resources.Designer.cs +++ b/src/Microsoft.AspNet.Authorization/Properties/Resources.Designer.cs @@ -1,5 +1,5 @@ // -namespace Microsoft.AspNet.Security +namespace Microsoft.AspNet.Authorization { using System.Globalization; using System.Reflection; @@ -8,7 +8,7 @@ namespace Microsoft.AspNet.Security internal static class Resources { private static readonly ResourceManager _resourceManager - = new ResourceManager("Microsoft.AspNet.Security.Resources", typeof(Resources).GetTypeInfo().Assembly); + = new ResourceManager("Microsoft.AspNet.Authorization.Resources", typeof(Resources).GetTypeInfo().Assembly); /// /// The default data protection provider may only be used when the IApplicationBuilder.Properties contains an appropriate 'host.AppName' key. diff --git a/src/Microsoft.AspNet.Security/Resources.resx b/src/Microsoft.AspNet.Authorization/Resources.resx similarity index 100% rename from src/Microsoft.AspNet.Security/Resources.resx rename to src/Microsoft.AspNet.Authorization/Resources.resx diff --git a/src/Microsoft.AspNet.Security/ServiceCollectionExtensions.cs b/src/Microsoft.AspNet.Authorization/ServiceCollectionExtensions.cs similarity index 97% rename from src/Microsoft.AspNet.Security/ServiceCollectionExtensions.cs rename to src/Microsoft.AspNet.Authorization/ServiceCollectionExtensions.cs index 2cb0f5aca..9146c747b 100644 --- a/src/Microsoft.AspNet.Security/ServiceCollectionExtensions.cs +++ b/src/Microsoft.AspNet.Authorization/ServiceCollectionExtensions.cs @@ -2,7 +2,7 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; -using Microsoft.AspNet.Security; +using Microsoft.AspNet.Authorization; using Microsoft.Framework.ConfigurationModel; namespace Microsoft.Framework.DependencyInjection diff --git a/src/Microsoft.AspNet.Authorization/project.json b/src/Microsoft.AspNet.Authorization/project.json new file mode 100644 index 000000000..978885f8e --- /dev/null +++ b/src/Microsoft.AspNet.Authorization/project.json @@ -0,0 +1,13 @@ +{ + "version": "1.0.0-*", + "description": "ASP.NET 5 authorization classes.", + "dependencies": { + "Microsoft.AspNet.Http.Interfaces": "1.0.0-*", + "Microsoft.Framework.Logging": "1.0.0-*", + "Microsoft.Framework.OptionsModel": "1.0.0-*" + }, + "frameworks": { + "aspnet50": { }, + "aspnetcore50": { } + } +} diff --git a/src/Microsoft.AspNet.Security.OAuthBearer/NotNullAttribute.cs b/src/Microsoft.AspNet.Security.OAuthBearer/NotNullAttribute.cs deleted file mode 100644 index 29f582749..000000000 --- a/src/Microsoft.AspNet.Security.OAuthBearer/NotNullAttribute.cs +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System; - -namespace Microsoft.AspNet.Security.OAuthBearer -{ - [AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false)] - internal sealed class NotNullAttribute : Attribute - { - } -} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Security.Twitter/NotNullAttribute.cs b/src/Microsoft.AspNet.Security.Twitter/NotNullAttribute.cs deleted file mode 100644 index 0d6e98224..000000000 --- a/src/Microsoft.AspNet.Security.Twitter/NotNullAttribute.cs +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System; - -namespace Microsoft.AspNet.Security.Twitter -{ - [AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false)] - internal sealed class NotNullAttribute : Attribute - { - } -} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Security/AuthenticationMode.cs b/src/Microsoft.AspNet.Security/AuthenticationMode.cs deleted file mode 100644 index 2b36dc973..000000000 --- a/src/Microsoft.AspNet.Security/AuthenticationMode.cs +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - - -namespace Microsoft.AspNet.Security -{ - /// - /// Controls the behavior of authentication middleware - /// - public enum AuthenticationMode - { - /// - /// In Active mode the authentication middleware will alter the user identity as the request arrives, and - /// will also alter a plain 401 as the response leaves. - /// - Active, - - /// - /// In Passive mode the authentication middleware will only provide user identity when asked, and will only - /// alter 401 responses where the authentication type named in the extra challenge data. - /// - Passive - } -} diff --git a/src/Microsoft.AspNet.Security/AuthenticationOptions.cs b/src/Microsoft.AspNet.Security/AuthenticationOptions.cs deleted file mode 100644 index 411e13481..000000000 --- a/src/Microsoft.AspNet.Security/AuthenticationOptions.cs +++ /dev/null @@ -1,41 +0,0 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using Microsoft.AspNet.Http.Security; - -namespace Microsoft.AspNet.Security -{ - /// - /// Base Options for all authentication middleware - /// - public abstract class AuthenticationOptions - { - private string _authenticationType; - - /// - /// The AuthenticationType in the options corresponds to the IIdentity AuthenticationType property. A different - /// value may be assigned in order to use the same authentication middleware type more than once in a pipeline. - /// - public string AuthenticationType - { - get { return _authenticationType; } - set - { - _authenticationType = value; - Description.AuthenticationType = value; - } - } - - /// - /// If Active the authentication middleware alter the request user coming in and - /// alter 401 Unauthorized responses going out. If Passive the authentication middleware will only provide - /// identity and alter responses when explicitly indicated by the AuthenticationType. - /// - public AuthenticationMode AuthenticationMode { get; set; } = AuthenticationMode.Active; - - /// - /// Additional information about the authentication type which is made available to the application. - /// - public AuthenticationDescription Description { get; set; } = new AuthenticationDescription(); - } -} diff --git a/src/Microsoft.AspNet.Security/Infrastructure/SecurityHelper.cs b/src/Microsoft.AspNet.Security/Infrastructure/SecurityHelper.cs deleted file mode 100644 index 876d5342f..000000000 --- a/src/Microsoft.AspNet.Security/Infrastructure/SecurityHelper.cs +++ /dev/null @@ -1,84 +0,0 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Security.Claims; -using System.Security.Principal; -using Microsoft.AspNet.Http; - -namespace Microsoft.AspNet.Security.Infrastructure -{ - /// - /// Helper code used when implementing authentication middleware - /// - public static class SecurityHelper - { - /// - /// Add an additional ClaimsIdentity to the ClaimsPrincipal - /// - /// - public static void AddUserIdentity([NotNull] HttpContext context, [NotNull] IIdentity identity) - { - var newClaimsPrincipal = new ClaimsPrincipal(identity); - - ClaimsPrincipal existingPrincipal = context.User; - if (existingPrincipal != null) - { - foreach (var existingClaimsIdentity in existingPrincipal.Identities) - { - if (existingClaimsIdentity.IsAuthenticated) - { - newClaimsPrincipal.AddIdentity(existingClaimsIdentity); - } - } - } - context.User = newClaimsPrincipal; - } - - public static bool LookupChallenge(IEnumerable authenticationTypes, string authenticationType, AuthenticationMode authenticationMode) - { - bool challengeHasAuthenticationTypes = authenticationTypes != null && authenticationTypes.Any(); - if (!challengeHasAuthenticationTypes) - { - return authenticationMode == AuthenticationMode.Active; - } - return authenticationTypes.Contains(authenticationType, StringComparer.Ordinal); - } - - /// - /// Find response sign-in details for a specific authentication middleware - /// - /// The authentication type to look for - public static bool LookupSignIn(IEnumerable identities, string authenticationType, out ClaimsIdentity identity) - { - identity = null; - foreach (var claimsIdentity in identities) - { - if (string.Equals(authenticationType, claimsIdentity.AuthenticationType, StringComparison.Ordinal)) - { - identity = claimsIdentity; - return true; - } - } - return false; - } - - /// - /// Find response sign-out details for a specific authentication middleware - /// - /// The authentication type to look for - /// The authentication mode the middleware is running under - public static bool LookupSignOut(IEnumerable authenticationTypes, string authenticationType, AuthenticationMode authenticationMode) - { - bool singOutHasAuthenticationTypes = authenticationTypes != null && authenticationTypes.Any(); - if (!singOutHasAuthenticationTypes) - { - return authenticationMode == AuthenticationMode.Active; - } - return authenticationTypes.Contains(authenticationType, StringComparer.Ordinal); - } - } -} diff --git a/test/Microsoft.AspNet.Authentication.Test/AuthenticationHandlerFacts.cs b/test/Microsoft.AspNet.Authentication.Test/AuthenticationHandlerFacts.cs new file mode 100644 index 000000000..6bd62b2b8 --- /dev/null +++ b/test/Microsoft.AspNet.Authentication.Test/AuthenticationHandlerFacts.cs @@ -0,0 +1,110 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using Microsoft.AspNet.Authentication; +using Microsoft.AspNet.Http.Core; +using Xunit; + +namespace Microsoft.AspNet.Authentication +{ + public class AuthenticationHandlerFacts + { + [Fact] + public void ShouldHandleSchemeAreDeterminedOnlyByMatchingAuthenticationScheme() + { + var handler = new TestHandler("Alpha"); + + bool passiveNoMatch = handler.ShouldHandleScheme(new[] { "Beta", "Gamma" }); + + handler = new TestHandler("Alpha"); + + bool passiveWithMatch = handler.ShouldHandleScheme(new[] { "Beta", "Alpha" }); + + Assert.False(passiveNoMatch); + Assert.True(passiveWithMatch); + } + + [Fact] + public void AutomaticHandlerInAutomaticModeHandlesEmptyChallenges() + { + var handler = new TestAutoHandler("ignored", true); + Assert.True(handler.ShouldHandleScheme(new string[0])); + } + + [Fact] + public void AutomaticHandlerShouldHandleSchemeWhenSchemeMatches() + { + var handler = new TestAutoHandler("Alpha", true); + Assert.True(handler.ShouldHandleScheme(new string[] { "Alpha" })); + } + + [Fact] + public void AutomaticHandlerShouldNotHandleChallengeWhenSchemeDoesNotMatches() + { + var handler = new TestAutoHandler("Dog", true); + Assert.False(handler.ShouldHandleScheme(new string[] { "Alpha" })); + } + + [Fact] + public void AutomaticHandlerShouldNotHandleChallengeWhenSchemesNotEmpty() + { + var handler = new TestAutoHandler(null, true); + Assert.False(handler.ShouldHandleScheme(new string[] { "Alpha" })); + } + + private class TestHandler : AuthenticationHandler + { + public TestHandler(string scheme) + { + Initialize(new TestOptions(), new DefaultHttpContext()); + Options.AuthenticationScheme = scheme; + } + + protected override void ApplyResponseChallenge() + { + throw new NotImplementedException(); + } + + protected override void ApplyResponseGrant() + { + throw new NotImplementedException(); + } + + protected override AuthenticationTicket AuthenticateCore() + { + throw new NotImplementedException(); + } + } + + private class TestOptions : AuthenticationOptions { } + + private class TestAutoOptions : AutomaticAuthenticationOptions { } + + private class TestAutoHandler : AutomaticAuthenticationHandler + { + public TestAutoHandler(string scheme, bool auto) + { + Initialize(new TestAutoOptions(), new DefaultHttpContext()); + Options.AuthenticationScheme = scheme; + Options.AutomaticAuthentication = auto; + } + + protected override void ApplyResponseChallenge() + { + throw new NotImplementedException(); + } + + protected override void ApplyResponseGrant() + { + throw new NotImplementedException(); + } + + protected override AuthenticationTicket AuthenticateCore() + { + throw new NotImplementedException(); + } + } + + } +} diff --git a/test/Microsoft.AspNet.Security.Test/CertificateSubjectKeyIdentifierValidatorTests.cs b/test/Microsoft.AspNet.Authentication.Test/CertificateSubjectKeyIdentifierValidatorTests.cs similarity index 99% rename from test/Microsoft.AspNet.Security.Test/CertificateSubjectKeyIdentifierValidatorTests.cs rename to test/Microsoft.AspNet.Authentication.Test/CertificateSubjectKeyIdentifierValidatorTests.cs index 4771b9830..f52e6f4ae 100644 --- a/test/Microsoft.AspNet.Security.Test/CertificateSubjectKeyIdentifierValidatorTests.cs +++ b/test/Microsoft.AspNet.Authentication.Test/CertificateSubjectKeyIdentifierValidatorTests.cs @@ -7,7 +7,7 @@ using Shouldly; using Xunit; -namespace Microsoft.AspNet.Security +namespace Microsoft.AspNet.Authentication { public class CertificateSubjectKeyIdentifierValidatorTests { diff --git a/test/Microsoft.AspNet.Security.Test/CertificateSubjectPublicKeyInfoValidatorTests.cs b/test/Microsoft.AspNet.Authentication.Test/CertificateSubjectPublicKeyInfoValidatorTests.cs similarity index 99% rename from test/Microsoft.AspNet.Security.Test/CertificateSubjectPublicKeyInfoValidatorTests.cs rename to test/Microsoft.AspNet.Authentication.Test/CertificateSubjectPublicKeyInfoValidatorTests.cs index 28270cd48..13b9a900a 100644 --- a/test/Microsoft.AspNet.Security.Test/CertificateSubjectPublicKeyInfoValidatorTests.cs +++ b/test/Microsoft.AspNet.Authentication.Test/CertificateSubjectPublicKeyInfoValidatorTests.cs @@ -7,7 +7,7 @@ using Shouldly; using Xunit; -namespace Microsoft.AspNet.Security +namespace Microsoft.AspNet.Authentication { public class CertificateSubjectPublicKeyInfoValidatorTests { diff --git a/test/Microsoft.AspNet.Security.Test/CertificateThumbprintValidatorTests.cs b/test/Microsoft.AspNet.Authentication.Test/CertificateThumbprintValidatorTests.cs similarity index 99% rename from test/Microsoft.AspNet.Security.Test/CertificateThumbprintValidatorTests.cs rename to test/Microsoft.AspNet.Authentication.Test/CertificateThumbprintValidatorTests.cs index 82e4a3a3d..145e883dc 100644 --- a/test/Microsoft.AspNet.Security.Test/CertificateThumbprintValidatorTests.cs +++ b/test/Microsoft.AspNet.Authentication.Test/CertificateThumbprintValidatorTests.cs @@ -7,7 +7,7 @@ using Shouldly; using Xunit; -namespace Microsoft.AspNet.Security +namespace Microsoft.AspNet.Authentication { public class CertificateThumbprintValidatorTests { diff --git a/test/Microsoft.AspNet.Security.Test/Cookies/CookieMiddlewareTests.cs b/test/Microsoft.AspNet.Authentication.Test/Cookies/CookieMiddlewareTests.cs similarity index 83% rename from test/Microsoft.AspNet.Security.Test/Cookies/CookieMiddlewareTests.cs rename to test/Microsoft.AspNet.Authentication.Test/Cookies/CookieMiddlewareTests.cs index c66d571b2..c1d5a0c32 100644 --- a/test/Microsoft.AspNet.Security.Test/Cookies/CookieMiddlewareTests.cs +++ b/test/Microsoft.AspNet.Authentication.Test/Cookies/CookieMiddlewareTests.cs @@ -14,13 +14,13 @@ using System.Xml.Linq; using Microsoft.AspNet.Builder; using Microsoft.AspNet.Http; -using Microsoft.AspNet.Http.Security; +using Microsoft.AspNet.Http.Authentication; using Microsoft.AspNet.TestHost; using Microsoft.Framework.DependencyInjection; using Shouldly; using Xunit; -namespace Microsoft.AspNet.Security.Cookies +namespace Microsoft.AspNet.Authentication.Cookies { public class CookieMiddlewareTests { @@ -69,9 +69,23 @@ public async Task ProtectedCustomRequestShouldRedirectToCustomLogin() private Task SignInAsAlice(HttpContext context) { - context.Response.SignIn( - new AuthenticationProperties(), - new ClaimsIdentity(new GenericIdentity("Alice", "Cookies"))); + context.Response.SignIn("Cookies", + new ClaimsPrincipal(new ClaimsIdentity(new GenericIdentity("Alice", "Cookies"))), + new AuthenticationProperties()); + return Task.FromResult(null); + } + + private Task SignInAsWrong(HttpContext context) + { + context.Response.SignIn("Oops", + new ClaimsPrincipal(new ClaimsIdentity(new GenericIdentity("Alice", "Cookies"))), + new AuthenticationProperties()); + return Task.FromResult(null); + } + + private Task SignOutAsWrong(HttpContext context) + { + context.Response.SignOut("Oops"); return Task.FromResult(null); } @@ -95,6 +109,30 @@ public async Task SignInCausesDefaultCookieToBeCreated() setCookie.ShouldNotContain("; secure"); } + [Fact] + public async Task SignInWrongAuthTypeThrows() + { + TestServer server = CreateServer(options => + { + options.LoginPath = new PathString("/login"); + options.CookieName = "TestCookie"; + }, SignInAsWrong); + + await Assert.ThrowsAsync(async () => await SendAsync(server, "http://example.com/testpath")); + } + + [Fact] + public async Task SignOutWrongAuthTypeThrows() + { + TestServer server = CreateServer(options => + { + options.LoginPath = new PathString("/login"); + options.CookieName = "TestCookie"; + }, SignOutAsWrong); + + await Assert.ThrowsAsync(async () => await SendAsync(server, "http://example.com/testpath")); + } + [Theory] [InlineData(CookieSecureOption.Always, "http://example.com/testpath", true)] [InlineData(CookieSecureOption.Always, "https://example.com/testpath", true)] @@ -226,10 +264,10 @@ public async Task CookieExpirationCanBeOverridenInSignin() }, context => { - context.Response.SignIn( - new AuthenticationProperties() { ExpiresUtc = clock.UtcNow.Add(TimeSpan.FromMinutes(5)) }, - new ClaimsIdentity(new GenericIdentity("Alice", "Cookies"))); - return Task.FromResult(null); + context.Response.SignIn("Cookies", + new ClaimsPrincipal(new ClaimsIdentity(new GenericIdentity("Alice", "Cookies"))), + new AuthenticationProperties() { ExpiresUtc = clock.UtcNow.Add(TimeSpan.FromMinutes(5)) }); + return Task.FromResult(null); }); Transaction transaction1 = await SendAsync(server, "http://example.com/testpath"); @@ -355,7 +393,8 @@ public async Task CookieUsesPathBaseByDefault() context => { Assert.Equal(new PathString("/base"), context.Request.PathBase); - context.Response.SignIn(new ClaimsIdentity(new GenericIdentity("Alice", "Cookies"))); + context.Response.SignIn("Cookies", + new ClaimsPrincipal(new ClaimsIdentity(new GenericIdentity("Alice", "Cookies")))); return Task.FromResult(null); }, new Uri("http://example.com/base")); @@ -364,6 +403,39 @@ public async Task CookieUsesPathBaseByDefault() Assert.True(transaction1.SetCookie.Contains("path=/base")); } + [Fact] + public async Task CookieTurns401To403IfAuthenticated() + { + var clock = new TestClock(); + TestServer server = CreateServer(options => + { + options.SystemClock = clock; + }, + SignInAsAlice); + + Transaction transaction1 = await SendAsync(server, "http://example.com/testpath"); + + Transaction transaction2 = await SendAsync(server, "http://example.com/unauthorized", transaction1.CookieNameValue); + + transaction2.Response.StatusCode.ShouldBe(HttpStatusCode.Forbidden); + } + + [Fact] + public async Task CookieDoesNothingTo401IfNotAuthenticated() + { + var clock = new TestClock(); + TestServer server = CreateServer(options => + { + options.SystemClock = clock; + }); + + Transaction transaction1 = await SendAsync(server, "http://example.com/testpath"); + + Transaction transaction2 = await SendAsync(server, "http://example.com/unauthorized", transaction1.CookieNameValue); + + transaction2.Response.StatusCode.ShouldBe(HttpStatusCode.Unauthorized); + } + private static string FindClaimValue(Transaction transaction, string claimType) { XElement claim = transaction.ResponseElement.Elements("claim").SingleOrDefault(elt => elt.Attribute("type").Value == claimType); @@ -404,13 +476,19 @@ private static TestServer CreateServer(Action confi { res.StatusCode = 401; } + else if (req.Path == new PathString("/unauthorized")) + { + // Simulate Authorization failure + var result = await context.AuthenticateAsync(CookieAuthenticationDefaults.AuthenticationScheme); + res.Challenge(CookieAuthenticationDefaults.AuthenticationScheme); + } else if (req.Path == new PathString("/protected/CustomRedirect")) { context.Response.Challenge(new AuthenticationProperties() { RedirectUri = "/CustomRedirect" }); } else if (req.Path == new PathString("/me")) { - Describe(res, new AuthenticationResult(context.User.Identity, new AuthenticationProperties(), new AuthenticationDescription())); + Describe(res, new AuthenticationResult(context.User, new AuthenticationProperties(), new AuthenticationDescription())); } else if (req.Path.StartsWithSegments(new PathString("/me"), out remainder)) { @@ -436,9 +514,9 @@ private static void Describe(HttpResponse res, AuthenticationResult result) res.StatusCode = 200; res.ContentType = "text/xml"; var xml = new XElement("xml"); - if (result != null && result.Identity != null) + if (result != null && result.Principal != null) { - xml.Add(result.Identity.Claims.Select(claim => new XElement("claim", new XAttribute("type", claim.Type), new XAttribute("value", claim.Value)))); + xml.Add(result.Principal.Claims.Select(claim => new XElement("claim", new XAttribute("type", claim.Type), new XAttribute("value", claim.Value)))); } if (result != null && result.Properties != null) { diff --git a/test/Microsoft.AspNet.Security.Test/Cookies/Infrastructure/CookieChunkingTests.cs b/test/Microsoft.AspNet.Authentication.Test/Cookies/Infrastructure/CookieChunkingTests.cs similarity index 99% rename from test/Microsoft.AspNet.Security.Test/Cookies/Infrastructure/CookieChunkingTests.cs rename to test/Microsoft.AspNet.Authentication.Test/Cookies/Infrastructure/CookieChunkingTests.cs index 04bbadf68..c4014ad77 100644 --- a/test/Microsoft.AspNet.Security.Test/Cookies/Infrastructure/CookieChunkingTests.cs +++ b/test/Microsoft.AspNet.Authentication.Test/Cookies/Infrastructure/CookieChunkingTests.cs @@ -7,7 +7,7 @@ using Microsoft.AspNet.Http.Core; using Xunit; -namespace Microsoft.AspNet.Security.Cookies.Infrastructure +namespace Microsoft.AspNet.Authentication.Cookies.Infrastructure { public class CookieChunkingTests { diff --git a/test/Microsoft.AspNet.Security.Test/DataHandler/Encoder/Base64UrlTextEncoderTests.cs b/test/Microsoft.AspNet.Authentication.Test/DataHandler/Encoder/Base64UrlTextEncoderTests.cs similarity index 94% rename from test/Microsoft.AspNet.Security.Test/DataHandler/Encoder/Base64UrlTextEncoderTests.cs rename to test/Microsoft.AspNet.Authentication.Test/DataHandler/Encoder/Base64UrlTextEncoderTests.cs index be97f2f12..8183f3879 100644 --- a/test/Microsoft.AspNet.Security.Test/DataHandler/Encoder/Base64UrlTextEncoderTests.cs +++ b/test/Microsoft.AspNet.Authentication.Test/DataHandler/Encoder/Base64UrlTextEncoderTests.cs @@ -4,7 +4,7 @@ using Shouldly; using Xunit; -namespace Microsoft.AspNet.Security.DataHandler.Encoder +namespace Microsoft.AspNet.Authentication.DataHandler.Encoder { public class Base64UrlTextEncoderTests { diff --git a/test/Microsoft.AspNet.Security.Test/Facebook/FacebookMiddlewareTests.cs b/test/Microsoft.AspNet.Authentication.Test/Facebook/FacebookMiddlewareTests.cs similarity index 94% rename from test/Microsoft.AspNet.Security.Test/Facebook/FacebookMiddlewareTests.cs rename to test/Microsoft.AspNet.Authentication.Test/Facebook/FacebookMiddlewareTests.cs index 42137b142..a0a5558e8 100644 --- a/test/Microsoft.AspNet.Security.Test/Facebook/FacebookMiddlewareTests.cs +++ b/test/Microsoft.AspNet.Authentication.Test/Facebook/FacebookMiddlewareTests.cs @@ -14,7 +14,7 @@ using Shouldly; using Xunit; -namespace Microsoft.AspNet.Security.Facebook +namespace Microsoft.AspNet.Authentication.Facebook { public class FacebookMiddlewareTests { @@ -41,11 +41,11 @@ public async Task ChallengeWillTriggerApplyRedirectEvent() }); services.ConfigureCookieAuthentication(options => { - options.AuthenticationType = "External"; + options.AuthenticationScheme = "External"; }); services.Configure(options => { - options.SignInAsAuthenticationType = "External"; + options.SignInScheme = "External"; }); }); app.UseFacebookAuthentication(); @@ -78,11 +78,11 @@ public async Task ChallengeWillTriggerRedirection() }); services.ConfigureCookieAuthentication(options => { - options.AuthenticationType = "External"; + options.AuthenticationScheme = "External"; }); services.Configure(options => { - options.SignInAsAuthenticationType = "External"; + options.SignInScheme = "External"; }); }); app.UseFacebookAuthentication(); diff --git a/test/Microsoft.AspNet.Security.Test/Google/GoogleMiddlewareTests.cs b/test/Microsoft.AspNet.Authentication.Test/Google/GoogleMiddlewareTests.cs similarity index 88% rename from test/Microsoft.AspNet.Security.Test/Google/GoogleMiddlewareTests.cs rename to test/Microsoft.AspNet.Authentication.Test/Google/GoogleMiddlewareTests.cs index e019512f7..13876a0ae 100644 --- a/test/Microsoft.AspNet.Security.Test/Google/GoogleMiddlewareTests.cs +++ b/test/Microsoft.AspNet.Authentication.Test/Google/GoogleMiddlewareTests.cs @@ -11,24 +11,22 @@ using System.Threading.Tasks; using System.Xml; using System.Xml.Linq; +using Microsoft.AspNet.Authentication.DataHandler; using Microsoft.AspNet.Builder; using Microsoft.AspNet.DataProtection; using Microsoft.AspNet.Http; -using Microsoft.AspNet.Http.Security; -using Microsoft.AspNet.Security.Cookies; -using Microsoft.AspNet.Security.DataHandler; +using Microsoft.AspNet.Http.Authentication; using Microsoft.AspNet.TestHost; using Microsoft.Framework.DependencyInjection; -using Microsoft.Framework.OptionsModel; using Newtonsoft.Json; using Shouldly; using Xunit; -namespace Microsoft.AspNet.Security.Google +namespace Microsoft.AspNet.Authentication.Google { public class GoogleMiddlewareTests { - private const string CookieAuthenticationType = "Cookie"; + private const string CookieAuthenticationScheme = "Cookie"; [Fact] public async Task ChallengeWillTriggerRedirection() @@ -52,25 +50,6 @@ public async Task ChallengeWillTriggerRedirection() location.ShouldNotContain("login_hint="); } - [Fact] - public async Task Challenge401WillTriggerRedirection() - { - var server = CreateServer(options => - { - options.ClientId = "Test Id"; - options.ClientSecret = "Test Secret"; - options.AuthenticationMode = AuthenticationMode.Active; - }); - var transaction = await SendAsync(server, "https://example.com/401"); - transaction.Response.StatusCode.ShouldBe(HttpStatusCode.Redirect); - var location = transaction.Response.Headers.Location.ToString(); - location.ShouldContain("https://accounts.google.com/o/oauth2/auth?response_type=code"); - location.ShouldContain("&client_id="); - location.ShouldContain("&redirect_uri="); - location.ShouldContain("&scope="); - location.ShouldContain("&state="); - } - [Fact] public async Task ChallengeWillSetCorrelationCookie() { @@ -84,20 +63,6 @@ public async Task ChallengeWillSetCorrelationCookie() transaction.SetCookie.Single().ShouldContain(".AspNet.Correlation.Google="); } - [Fact] - public async Task Challenge401WillSetCorrelationCookie() - { - var server = CreateServer(options => - { - options.ClientId = "Test Id"; - options.ClientSecret = "Test Secret"; - options.AuthenticationMode = AuthenticationMode.Active; - }); - var transaction = await SendAsync(server, "https://example.com/401"); - Console.WriteLine(transaction.SetCookie); - transaction.SetCookie.Single().ShouldContain(".AspNet.Correlation.Google="); - } - [Fact] public async Task ChallengeWillSetDefaultScope() { @@ -105,7 +70,6 @@ public async Task ChallengeWillSetDefaultScope() { options.ClientId = "Test Id"; options.ClientSecret = "Test Secret"; - options.AuthenticationMode = AuthenticationMode.Active; }); var transaction = await SendAsync(server, "https://example.com/challenge"); transaction.Response.StatusCode.ShouldBe(HttpStatusCode.Redirect); @@ -113,21 +77,6 @@ public async Task ChallengeWillSetDefaultScope() query.ShouldContain("&scope=" + Uri.EscapeDataString("openid profile email")); } - [Fact] - public async Task Challenge401WillSetDefaultScope() - { - var server = CreateServer(options => - { - options.ClientId = "Test Id"; - options.ClientSecret = "Test Secret"; - options.AuthenticationMode = AuthenticationMode.Active; - }); - var transaction = await SendAsync(server, "https://example.com/401"); - transaction.Response.StatusCode.ShouldBe(HttpStatusCode.Redirect); - var query = transaction.Response.Headers.Location.Query; - query.ShouldContain("&scope=" + Uri.EscapeDataString("openid profile email")); - } - [Fact] public async Task ChallengeWillUseOptionsScope() { @@ -400,7 +349,7 @@ public async Task AuthenticatedEventCanGetRefreshToken() OnAuthenticated = context => { var refreshToken = context.RefreshToken; - context.Identity.AddClaim(new Claim("RefreshToken", refreshToken)); + context.Principal.AddIdentity(new ClaimsIdentity(new Claim[] { new Claim("RefreshToken", refreshToken) }, "Google")); return Task.FromResult(null); } }; @@ -470,10 +419,10 @@ private static TestServer CreateServer(Action confi services.AddDataProtection(); services.Configure(options => { - options.SignInAsAuthenticationType = CookieAuthenticationType; + options.SignInScheme = CookieAuthenticationScheme; }); }); - app.UseCookieAuthentication(options => options.AuthenticationType = CookieAuthenticationType); + app.UseCookieAuthentication(options => options.AuthenticationScheme = CookieAuthenticationScheme); app.UseGoogleAuthentication(configureOptions); app.Use(async (context, next) => { @@ -486,7 +435,7 @@ private static TestServer CreateServer(Action confi } else if (req.Path == new PathString("/me")) { - Describe(res, (ClaimsIdentity)context.User.Identity); + Describe(res, context.User); } else if (req.Path == new PathString("/401")) { @@ -504,14 +453,17 @@ private static TestServer CreateServer(Action confi }); } - private static void Describe(HttpResponse res, ClaimsIdentity identity) + private static void Describe(HttpResponse res, ClaimsPrincipal user) { res.StatusCode = 200; res.ContentType = "text/xml"; var xml = new XElement("xml"); - if (identity != null) + if (user != null) { - xml.Add(identity.Claims.Select(claim => new XElement("claim", new XAttribute("type", claim.Type), new XAttribute("value", claim.Value)))); + foreach (var identity in user.Identities) + { + xml.Add(identity.Claims.Select(claim => new XElement("claim", new XAttribute("type", claim.Type), new XAttribute("value", claim.Value)))); + } } using (var memory = new MemoryStream()) { diff --git a/test/Microsoft.AspNet.Security.Test/Microsoft.AspNet.Security.Tests.kproj b/test/Microsoft.AspNet.Authentication.Test/Microsoft.AspNet.Authentication.Tests.kproj similarity index 100% rename from test/Microsoft.AspNet.Security.Test/Microsoft.AspNet.Security.Tests.kproj rename to test/Microsoft.AspNet.Authentication.Test/Microsoft.AspNet.Authentication.Tests.kproj diff --git a/test/Microsoft.AspNet.Security.Test/MicrosoftAccount/MicrosoftAccountMiddlewareTests.cs b/test/Microsoft.AspNet.Authentication.Test/MicrosoftAccount/MicrosoftAccountMiddlewareTests.cs similarity index 92% rename from test/Microsoft.AspNet.Security.Test/MicrosoftAccount/MicrosoftAccountMiddlewareTests.cs rename to test/Microsoft.AspNet.Authentication.Test/MicrosoftAccount/MicrosoftAccountMiddlewareTests.cs index 0f3a9355c..e7a8fccd3 100644 --- a/test/Microsoft.AspNet.Security.Test/MicrosoftAccount/MicrosoftAccountMiddlewareTests.cs +++ b/test/Microsoft.AspNet.Authentication.Test/MicrosoftAccount/MicrosoftAccountMiddlewareTests.cs @@ -11,21 +11,19 @@ using System.Threading.Tasks; using System.Xml; using System.Xml.Linq; +using Microsoft.AspNet.Authentication.DataHandler; +using Microsoft.AspNet.Authentication.MicrosoftAccount; using Microsoft.AspNet.Builder; using Microsoft.AspNet.DataProtection; using Microsoft.AspNet.Http; -using Microsoft.AspNet.Http.Security; -using Microsoft.AspNet.Security.Cookies; -using Microsoft.AspNet.Security.DataHandler; -using Microsoft.AspNet.Security.MicrosoftAccount; +using Microsoft.AspNet.Http.Authentication; using Microsoft.AspNet.TestHost; using Microsoft.Framework.DependencyInjection; -using Microsoft.Framework.OptionsModel; using Newtonsoft.Json; using Shouldly; using Xunit; -namespace Microsoft.AspNet.Security.Tests.MicrosoftAccount +namespace Microsoft.AspNet.Authentication.Tests.MicrosoftAccount { public class MicrosoftAccountMiddlewareTests { @@ -128,14 +126,14 @@ public async Task AuthenticatedEventCanGetRefreshToken() OnAuthenticated = context => { var refreshToken = context.RefreshToken; - context.Identity.AddClaim(new Claim("RefreshToken", refreshToken)); + context.Principal.AddIdentity(new ClaimsIdentity(new Claim[] { new Claim("RefreshToken", refreshToken) })); return Task.FromResult(null); } }; }, context => { - Describe(context.Response, (ClaimsIdentity)context.User.Identity); + Describe(context.Response, context.User); return true; }); var properties = new AuthenticationProperties(); @@ -168,10 +166,10 @@ private static TestServer CreateServer(Action(options => { - options.SignInAsAuthenticationType = "External"; + options.SignInScheme = "External"; }); }); - app.UseCookieAuthentication(options => options.AuthenticationType = "External"); + app.UseCookieAuthentication(options => options.AuthenticationScheme = "External"); app.UseMicrosoftAccountAuthentication(configureOptions); app.Use(async (context, next) => { @@ -218,14 +216,17 @@ private static HttpResponseMessage ReturnJsonResponse(object content) return res; } - private static void Describe(HttpResponse res, ClaimsIdentity identity) + private static void Describe(HttpResponse res, ClaimsPrincipal principal) { res.StatusCode = 200; res.ContentType = "text/xml"; var xml = new XElement("xml"); - if (identity != null) + if (principal != null) { - xml.Add(identity.Claims.Select(claim => new XElement("claim", new XAttribute("type", claim.Type), new XAttribute("value", claim.Value)))); + foreach (var identity in principal.Identities) + { + xml.Add(identity.Claims.Select(claim => new XElement("claim", new XAttribute("type", claim.Type), new XAttribute("value", claim.Value)))); + } } using (var memory = new MemoryStream()) { diff --git a/test/Microsoft.AspNet.Security.Test/OAuthBearer/OAuthBearerMiddlewareTests.cs b/test/Microsoft.AspNet.Authentication.Test/OAuthBearer/OAuthBearerMiddlewareTests.cs similarity index 82% rename from test/Microsoft.AspNet.Security.Test/OAuthBearer/OAuthBearerMiddlewareTests.cs rename to test/Microsoft.AspNet.Authentication.Test/OAuthBearer/OAuthBearerMiddlewareTests.cs index 26f202e08..ffbc1a0a4 100644 --- a/test/Microsoft.AspNet.Security.Test/OAuthBearer/OAuthBearerMiddlewareTests.cs +++ b/test/Microsoft.AspNet.Authentication.Test/OAuthBearer/OAuthBearerMiddlewareTests.cs @@ -12,13 +12,13 @@ using System.Xml.Linq; using Microsoft.AspNet.Builder; using Microsoft.AspNet.Http; -using Microsoft.AspNet.Security.Notifications; +using Microsoft.AspNet.Authentication.Notifications; using Microsoft.AspNet.TestHost; using Microsoft.Framework.DependencyInjection; using Shouldly; using Xunit; -namespace Microsoft.AspNet.Security.OAuthBearer +namespace Microsoft.AspNet.Authentication.OAuthBearer { public class OAuthBearerMiddlewareTests { @@ -60,7 +60,7 @@ private static Task HeaderReceived(MessageReceivedNotification(null); @@ -103,7 +103,7 @@ private static Task SecurityTokenReceived(SecurityTokenReceivedNotification(null); @@ -115,7 +115,7 @@ public async Task CustomTokenValidated() var server = CreateServer(options => { options.Notifications.SecurityTokenValidated = SecurityTokenValidated; - options.SecurityTokenValidators = new List{new BlobTokenValidator(options.AuthenticationType)}; + options.SecurityTokenValidators = new List{new BlobTokenValidator(options.AuthenticationScheme)}; }); var response = await SendAsync(server, "http://example.com/oauth", "Bearer someblob"); @@ -131,7 +131,7 @@ private static Task SecurityTokenValidated(SecurityTokenValidatedNotification(null); @@ -154,15 +154,40 @@ private static Task MessageReceived(MessageReceivedNotification(null); } + [Fact] + public async Task BearerTurns401To403IfAuthenticated() + { + var server = CreateServer(options => + { + options.Notifications.SecurityTokenReceived = SecurityTokenReceived; + }); + + var response = await SendAsync(server, "http://example.com/unauthorized", "Bearer Token"); + response.Response.StatusCode.ShouldBe(HttpStatusCode.Forbidden); + } + + + [Fact] + public async Task BearerDoesNothingTo401IfNotAuthenticated() + { + var server = CreateServer(options => + { + options.Notifications.SecurityTokenReceived = SecurityTokenReceived; + }); + + var response = await SendAsync(server, "http://example.com/unauthorized"); + response.Response.StatusCode.ShouldBe(HttpStatusCode.Unauthorized); + } + class BlobTokenValidator : ISecurityTokenValidator { - public BlobTokenValidator(string authenticationType) + public BlobTokenValidator(string authenticationScheme) { - AuthenticationType = authenticationType; + AuthenticationScheme = authenticationScheme; } - public string AuthenticationType { get; set; } + public string AuthenticationScheme { get; set; } public bool CanValidateToken { @@ -200,7 +225,7 @@ public ClaimsPrincipal ValidateToken(string securityToken, TokenValidationParame new Claim(ClaimsIdentity.DefaultNameClaimType, "bob"), }; - return new ClaimsPrincipal(new ClaimsIdentity(claims, AuthenticationType)); + return new ClaimsPrincipal(new ClaimsIdentity(claims, AuthenticationScheme)); } } @@ -224,6 +249,12 @@ private static TestServer CreateServer(Action if (req.Path == new PathString("/oauth")) { } + else if (req.Path == new PathString("/unauthorized")) + { + // Simulate Authorization failure + var result = await context.AuthenticateAsync(OAuthBearerAuthenticationDefaults.AuthenticationScheme); + res.Challenge(OAuthBearerAuthenticationDefaults.AuthenticationScheme); + } else { await next(); diff --git a/test/Microsoft.AspNet.Security.Test/OpenIdConnect/OpenIdConnectMiddlewareTests.cs b/test/Microsoft.AspNet.Authentication.Test/OpenIdConnect/OpenIdConnectMiddlewareTests.cs similarity index 94% rename from test/Microsoft.AspNet.Security.Test/OpenIdConnect/OpenIdConnectMiddlewareTests.cs rename to test/Microsoft.AspNet.Authentication.Test/OpenIdConnect/OpenIdConnectMiddlewareTests.cs index d2d22a342..725c2a073 100644 --- a/test/Microsoft.AspNet.Security.Test/OpenIdConnect/OpenIdConnectMiddlewareTests.cs +++ b/test/Microsoft.AspNet.Authentication.Test/OpenIdConnect/OpenIdConnectMiddlewareTests.cs @@ -16,17 +16,17 @@ using Microsoft.AspNet.Builder; using Microsoft.AspNet.DataProtection; using Microsoft.AspNet.Http; -using Microsoft.AspNet.Http.Security; -using Microsoft.AspNet.Security.Cookies; -using Microsoft.AspNet.Security.DataHandler; -using Microsoft.AspNet.Security.OpenIdConnect; +using Microsoft.AspNet.Http.Authentication; +using Microsoft.AspNet.Authentication.Cookies; +using Microsoft.AspNet.Authentication.DataHandler; +using Microsoft.AspNet.Authentication.OpenIdConnect; using Microsoft.AspNet.TestHost; using Microsoft.Framework.DependencyInjection; using Newtonsoft.Json; using Shouldly; using Xunit; -namespace Microsoft.AspNet.Security.Tests.OpenIdConnect +namespace Microsoft.AspNet.Authentication.Tests.OpenIdConnect { public class OpenIdConnectMiddlewareTests { @@ -40,7 +40,7 @@ public async Task ChallengeWillTriggerRedirect() { options.Authority = "https://login.windows.net/common"; options.ClientId = "Test Id"; - options.SignInAsAuthenticationType = OpenIdConnectAuthenticationDefaults.AuthenticationType; + options.SignInScheme = OpenIdConnectAuthenticationDefaults.AuthenticationScheme; }); var transaction = await SendAsync(server, "https://example.com/challenge"); transaction.Response.StatusCode.ShouldBe(HttpStatusCode.Redirect); @@ -85,7 +85,7 @@ public async Task ChallengeWillUseOptionsProperties() { options.Authority = "https://login.windows.net/common"; options.ClientId = "Test Id"; - options.SignInAsAuthenticationType = OpenIdConnectAuthenticationDefaults.AuthenticationType; + options.SignInScheme = OpenIdConnectAuthenticationDefaults.AuthenticationScheme; options.Scope = "https://www.googleapis.com/auth/plus.login"; options.ResponseType = "id_token"; }); @@ -185,13 +185,13 @@ private static TestServer CreateServer(Action(options => { - options.SignInAsAuthenticationType = CookieAuthenticationDefaults.AuthenticationType; + options.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme; }); }); app.UseCookieAuthentication(options => { - options.AuthenticationType = "OpenIdConnect"; + options.AuthenticationScheme = "OpenIdConnect"; }); app.UseOpenIdConnectAuthentication(configureOptions); app.Use(async (context, next) => @@ -205,11 +205,12 @@ private static TestServer CreateServer(Action(); + context.User.Identity.ShouldBeTypeOf(); + + ((ClaimsPrincipal)context.User).Identities.Count().ShouldBe(1); + } + + [Fact] + public void AddingExistingIdentityChangesDefaultButPreservesPrior() + { + HttpContext context = new DefaultHttpContext(); + context.User = new GenericPrincipal(new GenericIdentity("Test1", "Alpha"), null); + + context.User.Identity.AuthenticationType.ShouldBe("Alpha"); + context.User.Identity.Name.ShouldBe("Test1"); + + SecurityHelper.AddUserPrincipal(context, new GenericPrincipal(new GenericIdentity("Test2", "Beta"), new string[0])); + + context.User.Identity.AuthenticationType.ShouldBe("Beta"); + context.User.Identity.Name.ShouldBe("Test2"); + + SecurityHelper.AddUserPrincipal(context, new GenericPrincipal(new GenericIdentity("Test3", "Gamma"), new string[0])); + + context.User.Identity.AuthenticationType.ShouldBe("Gamma"); + context.User.Identity.Name.ShouldBe("Test3"); + + var principal = context.User; + principal.Identities.Count().ShouldBe(3); + principal.Identities.Skip(0).First().Name.ShouldBe("Test3"); + principal.Identities.Skip(1).First().Name.ShouldBe("Test2"); + principal.Identities.Skip(2).First().Name.ShouldBe("Test1"); + } + } +} diff --git a/test/Microsoft.AspNet.Security.Test/TestClock.cs b/test/Microsoft.AspNet.Authentication.Test/TestClock.cs similarity index 86% rename from test/Microsoft.AspNet.Security.Test/TestClock.cs rename to test/Microsoft.AspNet.Authentication.Test/TestClock.cs index cd8f99839..1b7dd1be8 100644 --- a/test/Microsoft.AspNet.Security.Test/TestClock.cs +++ b/test/Microsoft.AspNet.Authentication.Test/TestClock.cs @@ -2,9 +2,9 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; -using Microsoft.AspNet.Security.Infrastructure; +using Microsoft.AspNet.Authentication; -namespace Microsoft.AspNet.Security +namespace Microsoft.AspNet.Authentication { public class TestClock : ISystemClock { diff --git a/test/Microsoft.AspNet.Security.Test/Twitter/TwitterMiddlewareTests.cs b/test/Microsoft.AspNet.Authentication.Test/Twitter/TwitterMiddlewareTests.cs similarity index 96% rename from test/Microsoft.AspNet.Security.Test/Twitter/TwitterMiddlewareTests.cs rename to test/Microsoft.AspNet.Authentication.Test/Twitter/TwitterMiddlewareTests.cs index cb98aef0c..6b54b6cd9 100644 --- a/test/Microsoft.AspNet.Security.Test/Twitter/TwitterMiddlewareTests.cs +++ b/test/Microsoft.AspNet.Authentication.Test/Twitter/TwitterMiddlewareTests.cs @@ -10,8 +10,8 @@ using Microsoft.AspNet.Builder; using Microsoft.AspNet.DataProtection; using Microsoft.AspNet.Http; -using Microsoft.AspNet.Security.Cookies; -using Microsoft.AspNet.Security.Twitter; +using Microsoft.AspNet.Authentication.Cookies; +using Microsoft.AspNet.Authentication.Twitter; using Microsoft.AspNet.TestHost; using Microsoft.Framework.DependencyInjection; using Microsoft.Framework.OptionsModel; @@ -19,7 +19,7 @@ using Shouldly; using Xunit; -namespace Microsoft.AspNet.Security.Twitter +namespace Microsoft.AspNet.Authentication.Twitter { public class TwitterMiddlewareTests { @@ -115,12 +115,12 @@ private static TestServer CreateServer(Action configure, Fu services.AddDataProtection(); services.Configure(options => { - options.SignInAsAuthenticationType = "External"; + options.SignInScheme = "External"; }); }); app.UseCookieAuthentication(options => { - options.AuthenticationType = "External"; + options.AuthenticationScheme = "External"; }); if (configure != null) { diff --git a/test/Microsoft.AspNet.Security.Test/katanatest.redmond.corp.microsoft.com.cer b/test/Microsoft.AspNet.Authentication.Test/katanatest.redmond.corp.microsoft.com.cer similarity index 100% rename from test/Microsoft.AspNet.Security.Test/katanatest.redmond.corp.microsoft.com.cer rename to test/Microsoft.AspNet.Authentication.Test/katanatest.redmond.corp.microsoft.com.cer diff --git a/test/Microsoft.AspNet.Authentication.Test/project.json b/test/Microsoft.AspNet.Authentication.Test/project.json new file mode 100644 index 000000000..7d2a50c88 --- /dev/null +++ b/test/Microsoft.AspNet.Authentication.Test/project.json @@ -0,0 +1,27 @@ +{ + "compilationOptions": { + "warningsAsErrors": true + }, + "dependencies": { + "Microsoft.AspNet.Authentication.Cookies": "1.0.0-*", + "Microsoft.AspNet.Authentication.Facebook": "1.0.0-*", + "Microsoft.AspNet.Authentication.Google": "1.0.0-*", + "Microsoft.AspNet.Authentication.MicrosoftAccount": "1.0.0-*", + "Microsoft.AspNet.Authentication.OAuthBearer": "1.0.0-*", + "Microsoft.AspNet.Authentication.OpenIdConnect": "1.0.0-*", + "Microsoft.AspNet.Authentication.Twitter": "1.0.0-*", + "Microsoft.AspNet.TestHost": "1.0.0-*", + "Moq": "4.2.1312.1622", + "xunit.runner.kre": "1.0.0-*" + }, + "commands": { + "test": "xunit.runner.kre" + }, + "frameworks": { + "aspnet50": { + "dependencies": { + "Shouldly": "1.1.1.1" + } + } + } +} diff --git a/test/Microsoft.AspNet.Security.Test/selfSigned.cer b/test/Microsoft.AspNet.Authentication.Test/selfSigned.cer similarity index 100% rename from test/Microsoft.AspNet.Security.Test/selfSigned.cer rename to test/Microsoft.AspNet.Authentication.Test/selfSigned.cer diff --git a/test/Microsoft.AspNet.Security.Test/AuthorizationPolicyFacts.cs b/test/Microsoft.AspNet.Authorization.Test/AuthorizationPolicyFacts.cs similarity index 67% rename from test/Microsoft.AspNet.Security.Test/AuthorizationPolicyFacts.cs rename to test/Microsoft.AspNet.Authorization.Test/AuthorizationPolicyFacts.cs index 57c71dde4..eae8502ae 100644 --- a/test/Microsoft.AspNet.Security.Test/AuthorizationPolicyFacts.cs +++ b/test/Microsoft.AspNet.Authorization.Test/AuthorizationPolicyFacts.cs @@ -2,9 +2,10 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System.Linq; +using Microsoft.AspNet.Authorization; using Xunit; -namespace Microsoft.AspNet.Security.Test +namespace Microsoft.AspNet.Authroization.Test { public class AuthorizationPolicyFacts { @@ -14,21 +15,21 @@ public void CanCombineAuthorizeAttributes() // Arrange var attributes = new AuthorizeAttribute[] { new AuthorizeAttribute(), - new AuthorizeAttribute("1") { ActiveAuthenticationTypes = "dupe" }, - new AuthorizeAttribute("2") { ActiveAuthenticationTypes = "dupe" }, - new AuthorizeAttribute { Roles = "r1,r2", ActiveAuthenticationTypes = "roles" }, + new AuthorizeAttribute("1") { ActiveAuthenticationSchemes = "dupe" }, + new AuthorizeAttribute("2") { ActiveAuthenticationSchemes = "dupe" }, + new AuthorizeAttribute { Roles = "r1,r2", ActiveAuthenticationSchemes = "roles" }, }; var options = new AuthorizationOptions(); - options.AddPolicy("1", policy => policy.RequiresClaim("1")); - options.AddPolicy("2", policy => policy.RequiresClaim("2")); + options.AddPolicy("1", policy => policy.RequireClaim("1")); + options.AddPolicy("2", policy => policy.RequireClaim("2")); // Act var combined = AuthorizationPolicy.Combine(options, attributes); // Assert - Assert.Equal(2, combined.ActiveAuthenticationTypes.Count()); - Assert.True(combined.ActiveAuthenticationTypes.Contains("dupe")); - Assert.True(combined.ActiveAuthenticationTypes.Contains("roles")); + Assert.Equal(2, combined.ActiveAuthenticationSchemes.Count()); + Assert.True(combined.ActiveAuthenticationSchemes.Contains("dupe")); + Assert.True(combined.ActiveAuthenticationSchemes.Contains("roles")); Assert.Equal(4, combined.Requirements.Count()); Assert.True(combined.Requirements.Any(r => r is DenyAnonymousAuthorizationRequirement)); Assert.Equal(3, combined.Requirements.OfType().Count()); diff --git a/test/Microsoft.AspNet.Security.Test/DefaultAuthorizationServiceTests.cs b/test/Microsoft.AspNet.Authorization.Test/DefaultAuthorizationServiceTests.cs similarity index 89% rename from test/Microsoft.AspNet.Security.Test/DefaultAuthorizationServiceTests.cs rename to test/Microsoft.AspNet.Authorization.Test/DefaultAuthorizationServiceTests.cs index 9beae1c6d..54a4e1a7c 100644 --- a/test/Microsoft.AspNet.Security.Test/DefaultAuthorizationServiceTests.cs +++ b/test/Microsoft.AspNet.Authorization.Test/DefaultAuthorizationServiceTests.cs @@ -10,7 +10,7 @@ using Microsoft.Framework.DependencyInjection.Fallback; using Xunit; -namespace Microsoft.AspNet.Security.Test +namespace Microsoft.AspNet.Authorization.Test { public class DefaultAuthorizationServiceTests { @@ -41,7 +41,7 @@ public async Task Authorize_ShouldAllowIfClaimIsPresent() { services.ConfigureAuthorization(options => { - options.AddPolicy("Basic", policy => policy.RequiresClaim("Permission", "CanViewPage")); + options.AddPolicy("Basic", policy => policy.RequireClaim("Permission", "CanViewPage")); }); }); var user = new ClaimsPrincipal(new ClaimsIdentity(new Claim[] { new Claim("Permission", "CanViewPage") }, "Basic")); @@ -61,7 +61,7 @@ public async Task Authorize_ShouldAllowIfClaimIsPresentWithSpecifiedAuthType() { services.ConfigureAuthorization(options => { - options.AddPolicy("Basic", policy => policy.RequiresClaim("Permission", "CanViewPage")); + options.AddPolicy("Basic", policy => policy.RequireClaim("Permission", "CanViewPage")); }); }); var user = new ClaimsPrincipal(new ClaimsIdentity(new Claim[] { new Claim("Permission", "CanViewPage") }, "Basic")); @@ -81,7 +81,7 @@ public async Task Authorize_ShouldAllowIfClaimIsAmongValues() { services.ConfigureAuthorization(options => { - options.AddPolicy("Basic", policy => policy.RequiresClaim("Permission", "CanViewPage", "CanViewAnything")); + options.AddPolicy("Basic", policy => policy.RequireClaim("Permission", "CanViewPage", "CanViewAnything")); }); }); var user = new ClaimsPrincipal( @@ -108,7 +108,7 @@ public async Task Authorize_ShouldFailWhenAllRequirementsNotHandled() { services.ConfigureAuthorization(options => { - options.AddPolicy("Basic", policy => policy.RequiresClaim("Permission", "CanViewPage", "CanViewAnything")); + options.AddPolicy("Basic", policy => policy.RequireClaim("Permission", "CanViewPage", "CanViewAnything")); }); }); var user = new ClaimsPrincipal( @@ -134,7 +134,7 @@ public async Task Authorize_ShouldNotAllowIfClaimTypeIsNotPresent() { services.ConfigureAuthorization(options => { - options.AddPolicy("Basic", policy => policy.RequiresClaim("Permission", "CanViewPage", "CanViewAnything")); + options.AddPolicy("Basic", policy => policy.RequireClaim("Permission", "CanViewPage", "CanViewAnything")); }); }); var user = new ClaimsPrincipal( @@ -160,7 +160,7 @@ public async Task Authorize_ShouldNotAllowIfClaimValueIsNotPresent() { services.ConfigureAuthorization(options => { - options.AddPolicy("Basic", policy => policy.RequiresClaim("Permission", "CanViewPage")); + options.AddPolicy("Basic", policy => policy.RequireClaim("Permission", "CanViewPage")); }); }); var user = new ClaimsPrincipal( @@ -186,7 +186,7 @@ public async Task Authorize_ShouldNotAllowIfNoClaims() { services.ConfigureAuthorization(options => { - options.AddPolicy("Basic", policy => policy.RequiresClaim("Permission", "CanViewPage")); + options.AddPolicy("Basic", policy => policy.RequireClaim("Permission", "CanViewPage")); }); }); var user = new ClaimsPrincipal( @@ -210,7 +210,7 @@ public async Task Authorize_ShouldNotAllowIfUserIsNull() { services.ConfigureAuthorization(options => { - options.AddPolicy("Basic", policy => policy.RequiresClaim("Permission", "CanViewPage")); + options.AddPolicy("Basic", policy => policy.RequireClaim("Permission", "CanViewPage")); }); }); @@ -229,7 +229,7 @@ public async Task Authorize_ShouldNotAllowIfNotCorrectAuthType() { services.ConfigureAuthorization(options => { - options.AddPolicy("Basic", policy => policy.RequiresClaim("Permission", "CanViewPage")); + options.AddPolicy("Basic", policy => policy.RequireClaim("Permission", "CanViewPage")); }); }); var user = new ClaimsPrincipal(new ClaimsIdentity()); @@ -249,7 +249,7 @@ public async Task Authorize_ShouldAllowWithNoAuthType() { services.ConfigureAuthorization(options => { - options.AddPolicy("Basic", policy => policy.RequiresClaim("Permission", "CanViewPage")); + options.AddPolicy("Basic", policy => policy.RequireClaim("Permission", "CanViewPage")); }); }); var user = new ClaimsPrincipal( @@ -291,8 +291,8 @@ public async Task Authorize_ShouldNotAllowIfUnknownPolicy() public async Task Authorize_CustomRolePolicy() { // Arrange - var policy = new AuthorizationPolicyBuilder().RequiresRole("Administrator") - .RequiresClaim(ClaimTypes.Role, "User"); + var policy = new AuthorizationPolicyBuilder().RequireRole("Administrator") + .RequireClaim(ClaimTypes.Role, "User"); var authorizationService = BuildAuthorizationService(); var user = new ClaimsPrincipal( new ClaimsIdentity( @@ -314,7 +314,7 @@ public async Task Authorize_CustomRolePolicy() public async Task Authorize_HasAnyClaimOfTypePolicy() { // Arrange - var policy = new AuthorizationPolicyBuilder().RequiresClaim(ClaimTypes.Role); + var policy = new AuthorizationPolicyBuilder().RequireClaim(ClaimTypes.Role); var authorizationService = BuildAuthorizationService(); var user = new ClaimsPrincipal( new ClaimsIdentity( @@ -332,10 +332,10 @@ public async Task Authorize_HasAnyClaimOfTypePolicy() } [Fact] - public async Task Authorize_PolicyCanAuthenticationTypeWithNameClaim() + public async Task Authorize_PolicyCanAuthenticationSchemeWithNameClaim() { // Arrange - var policy = new AuthorizationPolicyBuilder("AuthType").RequiresClaim(ClaimTypes.Name); + var policy = new AuthorizationPolicyBuilder("AuthType").RequireClaim(ClaimTypes.Name); var authorizationService = BuildAuthorizationService(); var user = new ClaimsPrincipal( new ClaimsIdentity(new Claim[] { new Claim(ClaimTypes.Name, "Name") }, "AuthType") @@ -348,11 +348,11 @@ public async Task Authorize_PolicyCanAuthenticationTypeWithNameClaim() Assert.True(allowed); } - [Fact] - public async Task Authorize_PolicyWillFilterAuthenticationType() + [Fact(Skip = "Filtering TBD")] + public async Task Authorize_PolicyWillFilterAuthenticationScheme() { // Arrange - var policy = new AuthorizationPolicyBuilder("Bogus").RequiresClaim(ClaimTypes.Name); + var policy = new AuthorizationPolicyBuilder("Bogus").RequireClaim(ClaimTypes.Name); var authorizationService = BuildAuthorizationService(); var user = new ClaimsPrincipal( new ClaimsIdentity(new Claim[] { new Claim(ClaimTypes.Name, "Name") }, "AuthType") @@ -365,11 +365,11 @@ public async Task Authorize_PolicyWillFilterAuthenticationType() Assert.False(allowed); } - [Fact] - public async Task Authorize_PolicyCanFilterMultipleAuthenticationType() + [Fact(Skip = "Filtering TBD")] + public async Task Authorize_PolicyCanFilterMultipleAuthenticationScheme() { // Arrange - var policy = new AuthorizationPolicyBuilder("One", "Two").RequiresClaim(ClaimTypes.Name, "one").RequiresClaim(ClaimTypes.Name, "two"); + var policy = new AuthorizationPolicyBuilder("One", "Two").RequireClaim(ClaimTypes.Name, "one").RequireClaim(ClaimTypes.Name, "two"); var authorizationService = BuildAuthorizationService(); var user = new ClaimsPrincipal(); user.AddIdentity(new ClaimsIdentity(new Claim[] { new Claim(ClaimTypes.Name, "one") }, "One")); @@ -386,7 +386,7 @@ public async Task Authorize_PolicyCanFilterMultipleAuthenticationType() public async Task RolePolicyCanRequireSingleRole() { // Arrange - var policy = new AuthorizationPolicyBuilder("AuthType").RequiresRole("Admin"); + var policy = new AuthorizationPolicyBuilder("AuthType").RequireRole("Admin"); var authorizationService = BuildAuthorizationService(); var user = new ClaimsPrincipal( new ClaimsIdentity(new Claim[] { new Claim(ClaimTypes.Role, "Admin") }, "AuthType") @@ -403,7 +403,7 @@ public async Task RolePolicyCanRequireSingleRole() public async Task RolePolicyCanRequireOneOfManyRoles() { // Arrange - var policy = new AuthorizationPolicyBuilder("AuthType").RequiresRole("Admin", "Users"); + var policy = new AuthorizationPolicyBuilder("AuthType").RequireRole("Admin", "Users"); var authorizationService = BuildAuthorizationService(); var user = new ClaimsPrincipal( new ClaimsIdentity(new Claim[] { new Claim(ClaimTypes.Role, "Users") }, "AuthType")); @@ -419,7 +419,7 @@ public async Task RolePolicyCanRequireOneOfManyRoles() public async Task RolePolicyCanBlockWrongRole() { // Arrange - var policy = new AuthorizationPolicyBuilder().RequiresClaim("Permission", "CanViewPage"); + var policy = new AuthorizationPolicyBuilder().RequireClaim("Permission", "CanViewPage"); var authorizationService = BuildAuthorizationService(); var user = new ClaimsPrincipal( new ClaimsIdentity( @@ -444,7 +444,7 @@ public async Task RolePolicyCanBlockNoRole() { services.ConfigureAuthorization(options => { - options.AddPolicy("Basic", policy => policy.RequiresRole("Admin", "Users")); + options.AddPolicy("Basic", policy => policy.RequireRole("Admin", "Users")); }); }); var user = new ClaimsPrincipal( @@ -487,6 +487,58 @@ public async Task PolicyFailsWithNoRequirements() Assert.False(allowed); } + [Fact] + public async Task RequireUserNameFailsForWrongUserName() + { + // Arrange + var authorizationService = BuildAuthorizationService(services => + { + services.ConfigureAuthorization(options => + { + options.AddPolicy("Hao", policy => policy.RequireUserName("Hao")); + }); + }); + var user = new ClaimsPrincipal( + new ClaimsIdentity( + new Claim[] { + new Claim(ClaimTypes.Name, "Tek"), + }, + "AuthType") + ); + + // Act + var allowed = await authorizationService.AuthorizeAsync(user, null, "Any"); + + // Assert + Assert.False(allowed); + } + + [Fact] + public async Task CanRequireUserName() + { + // Arrange + var authorizationService = BuildAuthorizationService(services => + { + services.ConfigureAuthorization(options => + { + options.AddPolicy("Hao", policy => policy.RequireUserName("Hao")); + }); + }); + var user = new ClaimsPrincipal( + new ClaimsIdentity( + new Claim[] { + new Claim(ClaimTypes.Name, "Hao"), + }, + "AuthType") + ); + + // Act + var allowed = await authorizationService.AuthorizeAsync(user, null, "Hao"); + + // Assert + Assert.True(allowed); + } + [Fact] public async Task CanApproveAnyAuthenticatedUser() { @@ -629,8 +681,8 @@ public async Task CanCombinePolicies() { services.ConfigureAuthorization(options => { - var basePolicy = new AuthorizationPolicyBuilder().RequiresClaim("Base", "Value").Build(); - options.AddPolicy("Combined", policy => policy.Combine(basePolicy).RequiresClaim("Claim", "Exists")); + var basePolicy = new AuthorizationPolicyBuilder().RequireClaim("Base", "Value").Build(); + options.AddPolicy("Combined", policy => policy.Combine(basePolicy).RequireClaim("Claim", "Exists")); }); }); var user = new ClaimsPrincipal( @@ -656,8 +708,8 @@ public async Task CombinePoliciesWillFailIfBasePolicyFails() { services.ConfigureAuthorization(options => { - var basePolicy = new AuthorizationPolicyBuilder().RequiresClaim("Base", "Value").Build(); - options.AddPolicy("Combined", policy => policy.Combine(basePolicy).RequiresClaim("Claim", "Exists")); + var basePolicy = new AuthorizationPolicyBuilder().RequireClaim("Base", "Value").Build(); + options.AddPolicy("Combined", policy => policy.Combine(basePolicy).RequireClaim("Claim", "Exists")); }); }); var user = new ClaimsPrincipal( @@ -682,8 +734,8 @@ public async Task CombinedPoliciesWillFailIfExtraRequirementFails() { services.ConfigureAuthorization(options => { - var basePolicy = new AuthorizationPolicyBuilder().RequiresClaim("Base", "Value").Build(); - options.AddPolicy("Combined", policy => policy.Combine(basePolicy).RequiresClaim("Claim", "Exists")); + var basePolicy = new AuthorizationPolicyBuilder().RequireClaim("Base", "Value").Build(); + options.AddPolicy("Combined", policy => policy.Combine(basePolicy).RequireClaim("Claim", "Exists")); }); }); var user = new ClaimsPrincipal( diff --git a/test/Microsoft.AspNet.Authorization.Test/Microsoft.AspNet.Authorization.Tests.kproj b/test/Microsoft.AspNet.Authorization.Test/Microsoft.AspNet.Authorization.Tests.kproj new file mode 100644 index 000000000..316cc5177 --- /dev/null +++ b/test/Microsoft.AspNet.Authorization.Test/Microsoft.AspNet.Authorization.Tests.kproj @@ -0,0 +1,17 @@ + + + + 14.0 + $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) + + + + 7af5ad96-eb6e-4d0e-8abe-c0b543c0f4c2 + ..\..\artifacts\obj\$(MSBuildProjectName) + ..\..\artifacts\bin\$(MSBuildProjectName)\ + + + 2.0 + + + \ No newline at end of file diff --git a/test/Microsoft.AspNet.Authorization.Test/project.json b/test/Microsoft.AspNet.Authorization.Test/project.json new file mode 100644 index 000000000..68f39fe36 --- /dev/null +++ b/test/Microsoft.AspNet.Authorization.Test/project.json @@ -0,0 +1,20 @@ +{ + "compilationOptions": { + "warningsAsErrors": true + }, + "dependencies": { + "Microsoft.AspNet.Authorization": "1.0.0-*", + "Moq": "4.2.1312.1622", + "xunit.runner.kre": "1.0.0-*" + }, + "commands": { + "test": "xunit.runner.kre" + }, + "frameworks": { + "aspnet50": { + "dependencies": { + "Shouldly": "1.1.1.1" + } + } + } +} diff --git a/test/Microsoft.AspNet.Security.Test/SecurityHelperTests.cs b/test/Microsoft.AspNet.Security.Test/SecurityHelperTests.cs deleted file mode 100644 index dae0aed31..000000000 --- a/test/Microsoft.AspNet.Security.Test/SecurityHelperTests.cs +++ /dev/null @@ -1,103 +0,0 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System.Collections.Generic; -using System.Linq; -using System.Security.Claims; -using System.Security.Principal; -using Microsoft.AspNet.Http; -using Microsoft.AspNet.Http.Core; -using Microsoft.AspNet.Security.Infrastructure; -using Shouldly; -using Xunit; - -namespace Microsoft.AspNet.Security -{ - public class SecurityHelperTests - { - [Fact] - public void AddingToAnonymousIdentityDoesNotKeepAnonymousIdentity() - { - HttpContext context = new DefaultHttpContext(); - context.User.ShouldNotBe(null); - context.User.Identity.IsAuthenticated.ShouldBe(false); - - SecurityHelper.AddUserIdentity(context, new GenericIdentity("Test1", "Alpha")); - - context.User.ShouldNotBe(null); - context.User.Identity.AuthenticationType.ShouldBe("Alpha"); - context.User.Identity.Name.ShouldBe("Test1"); - - context.User.ShouldBeTypeOf(); - context.User.Identity.ShouldBeTypeOf(); - - ((ClaimsPrincipal)context.User).Identities.Count().ShouldBe(1); - } - - [Fact] - public void AddingExistingIdentityChangesDefaultButPreservesPrior() - { - HttpContext context = new DefaultHttpContext(); - context.User = new GenericPrincipal(new GenericIdentity("Test1", "Alpha"), null); - - context.User.Identity.AuthenticationType.ShouldBe("Alpha"); - context.User.Identity.Name.ShouldBe("Test1"); - - SecurityHelper.AddUserIdentity(context, new GenericIdentity("Test2", "Beta")); - - context.User.Identity.AuthenticationType.ShouldBe("Beta"); - context.User.Identity.Name.ShouldBe("Test2"); - - SecurityHelper.AddUserIdentity(context, new GenericIdentity("Test3", "Gamma")); - - context.User.Identity.AuthenticationType.ShouldBe("Gamma"); - context.User.Identity.Name.ShouldBe("Test3"); - - var principal = context.User; - principal.Identities.Count().ShouldBe(3); - principal.Identities.Skip(0).First().Name.ShouldBe("Test3"); - principal.Identities.Skip(1).First().Name.ShouldBe("Test2"); - principal.Identities.Skip(2).First().Name.ShouldBe("Test1"); - } - - [Fact] - public void NoChallengesMeansLookupsAreDeterminedOnlyByActiveOrPassiveMode() - { - HttpContext context = new DefaultHttpContext(); - - bool activeNoChallenge = SecurityHelper.LookupChallenge(new string[0], "Alpha", AuthenticationMode.Active); - bool passiveNoChallenge = SecurityHelper.LookupChallenge(new string[0], "Alpha", AuthenticationMode.Passive); - - context.Response.StatusCode = 401; - - bool activeEmptyChallenge = SecurityHelper.LookupChallenge(new string[0], "Alpha", AuthenticationMode.Active); - bool passiveEmptyChallenge = SecurityHelper.LookupChallenge(new string[0], "Alpha", AuthenticationMode.Passive); - - Assert.True(activeNoChallenge); - Assert.False(passiveNoChallenge); - Assert.True(activeEmptyChallenge); - Assert.False(passiveEmptyChallenge); - } - - [Fact] - public void WithChallengesMeansLookupsAreDeterminedOnlyByMatchingAuthenticationType() - { - HttpContext context = new DefaultHttpContext(); - - IEnumerable challengeTypes = new[] { "Beta", "Gamma" }; - - bool activeNoMatch = SecurityHelper.LookupChallenge(challengeTypes, "Alpha", AuthenticationMode.Active); - bool passiveNoMatch = SecurityHelper.LookupChallenge(challengeTypes, "Alpha", AuthenticationMode.Passive); - - challengeTypes = new[] { "Beta", "Alpha" }; - - bool activeWithMatch = SecurityHelper.LookupChallenge(challengeTypes, "Alpha", AuthenticationMode.Active); - bool passiveWithMatch = SecurityHelper.LookupChallenge(challengeTypes, "Alpha", AuthenticationMode.Passive); - - Assert.False(activeNoMatch); - Assert.False(passiveNoMatch); - Assert.True(activeWithMatch); - Assert.True(passiveWithMatch); - } - } -} diff --git a/test/Microsoft.AspNet.Security.Test/project.json b/test/Microsoft.AspNet.Security.Test/project.json deleted file mode 100644 index 1ab85d584..000000000 --- a/test/Microsoft.AspNet.Security.Test/project.json +++ /dev/null @@ -1,27 +0,0 @@ -{ - "compilationOptions": { - "warningsAsErrors": true - }, - "dependencies": { - "Microsoft.AspNet.Security.Cookies": "1.0.0-*", - "Microsoft.AspNet.Security.Facebook": "1.0.0-*", - "Microsoft.AspNet.Security.Google": "1.0.0-*", - "Microsoft.AspNet.Security.MicrosoftAccount": "1.0.0-*", - "Microsoft.AspNet.Security.OAuthBearer": "1.0.0-*", - "Microsoft.AspNet.Security.OpenIdConnect": "1.0.0-*", - "Microsoft.AspNet.Security.Twitter": "1.0.0-*", - "Microsoft.AspNet.TestHost": "1.0.0-*", - "Moq": "4.2.1312.1622", - "xunit.runner.kre": "1.0.0-*" - }, - "commands": { - "test": "xunit.runner.kre" - }, - "frameworks": { - "aspnet50": { - "dependencies": { - "Shouldly": "1.1.1.1" - } - } - } -} From d890f49fc0cab53829b628551749071d72fb2906 Mon Sep 17 00:00:00 2001 From: Hao Kung Date: Mon, 2 Mar 2015 17:43:59 -0800 Subject: [PATCH 139/216] Fix sln and kproj --- Security.sln | 282 ++++++++++-------- ...rosoft.AspNet.Authentication.Cookies.kproj | 2 +- ...osoft.AspNet.Authentication.Facebook.kproj | 2 +- ...crosoft.AspNet.Authentication.Google.kproj | 2 +- ...pNet.Authentication.MicrosoftAccount.kproj | 6 +- ...icrosoft.AspNet.Authentication.OAuth.kproj | 2 +- ....AspNet.Authentication.OpenIdConnect.kproj | 4 +- ...rosoft.AspNet.Authentication.Twitter.kproj | 2 +- .../Microsoft.AspNet.Authentication.kproj | 2 +- 9 files changed, 175 insertions(+), 129 deletions(-) diff --git a/Security.sln b/Security.sln index ccddd42c7..7fb0467af 100644 --- a/Security.sln +++ b/Security.sln @@ -1,46 +1,50 @@  Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 14 -VisualStudioVersion = 14.0.22422.0 +VisualStudioVersion = 14.0.22605.0 MinimumVisualStudioVersion = 10.0.40219.1 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{4D2B6A51-2F9F-44F5-8131-EA5CAC053652}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "samples", "samples", "{F8C0AA27-F3FB-4286-8E4C-47EF86B539FF}" EndProject -Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNet.Security", "src\Microsoft.AspNet.Security\Microsoft.AspNet.Security.kproj", "{0F174C63-1898-4024-9A3C-3FDF5CAE5C68}" -EndProject -Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNet.Security.Cookies", "src\Microsoft.AspNet.Security.Cookies\Microsoft.AspNet.Security.Cookies.kproj", "{15F1211B-B695-4A1C-B730-1AC58FC91090}" -EndProject Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "CookieSample", "samples\CookieSample\CookieSample.kproj", "{558C2C2A-AED8-49DE-BB60-D5F8AE06C714}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{7BF11F3A-60B6-4796-B504-579C67FFBA34}" EndProject -Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNet.Security.Tests", "test\Microsoft.AspNet.Security.Test\Microsoft.AspNet.Security.Tests.kproj", "{8DA26CD1-1302-4CFD-9270-9FA1B7C6138B}" -EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{C40A5A3B-ABA3-4819-9C44-D821E6DA1BA1}" ProjectSection(SolutionItems) = preProject global.json = global.json EndProjectSection EndProject -Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNet.Security.Facebook", "src\Microsoft.AspNet.Security.Facebook\Microsoft.AspNet.Security.Facebook.kproj", "{3984651C-FD44-4394-8793-3D14EE348C04}" -EndProject Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "SocialSample", "samples\SocialSample\SocialSample.kproj", "{8C73D216-332D-41D8-BFD0-45BC4BC36552}" EndProject -Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNet.Security.Google", "src\Microsoft.AspNet.Security.Google\Microsoft.AspNet.Security.Google.kproj", "{89BF8535-A849-458E-868A-A68FCF620486}" +Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "CookieSessionSample", "samples\CookieSessionSample\CookieSessionSample.kproj", "{19711880-46DA-4A26-9E0F-9B2E41D27651}" EndProject -Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNet.Security.Twitter", "src\Microsoft.AspNet.Security.Twitter\Microsoft.AspNet.Security.Twitter.kproj", "{C96B77EA-4078-4C31-BDB2-878F11C5E061}" +Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "OpenIdConnectSample", "samples\OpenIdConnectSample\OpenIdConnectSample.kproj", "{BEF0F5C3-EF4E-4649-9C49-D5E279A3CA2B}" EndProject -Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNet.Security.MicrosoftAccount", "src\Microsoft.AspNet.Security.MicrosoftAccount\Microsoft.AspNet.Security.MicrosoftAccount.kproj", "{1FCF26C2-A3C7-4308-B698-4AFC3560BC0C}" +Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNet.Authentication.Cookies", "src\Microsoft.AspNet.Authentication.Cookies\Microsoft.AspNet.Authentication.Cookies.kproj", "{FC152CC4-054B-457E-8D91-389C5DE3C561}" EndProject -Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNet.Security.OAuth", "src\Microsoft.AspNet.Security.OAuth\Microsoft.AspNet.Security.OAuth.kproj", "{4A636011-68EE-4CE5-836D-EA8E13CF71E4}" +Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNet.Authentication", "src\Microsoft.AspNet.Authentication\Microsoft.AspNet.Authentication.kproj", "{2286250A-52C8-4126-9F93-B1E45F0AD078}" EndProject -Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "CookieSessionSample", "samples\CookieSessionSample\CookieSessionSample.kproj", "{19711880-46DA-4A26-9E0F-9B2E41D27651}" +Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNet.Authentication.Facebook", "src\Microsoft.AspNet.Authentication.Facebook\Microsoft.AspNet.Authentication.Facebook.kproj", "{EEAAEE68-607B-4E33-AF3E-45C66B4DBA5A}" EndProject -Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "OpenIdConnectSample", "samples\OpenIdConnectSample\OpenIdConnectSample.kproj", "{BEF0F5C3-EF4E-4649-9C49-D5E279A3CA2B}" +Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNet.Authentication.Google", "src\Microsoft.AspNet.Authentication.Google\Microsoft.AspNet.Authentication.Google.kproj", "{76579C39-B829-490D-B8BE-1BD35FE8412E}" +EndProject +Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNet.Authentication.OpenIdConnect", "src\Microsoft.AspNet.Authentication.OpenIdConnect\Microsoft.AspNet.Authentication.OpenIdConnect.kproj", "{35115D55-B69E-46D4-BB33-C9E9E6EC5E7A}" EndProject -Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNet.Security.OAuthBearer", "src\Microsoft.AspNet.Security.OAuthBearer\Microsoft.AspNet.Security.OAuthBearer.kproj", "{2755BFE5-7421-4A31-A644-F817DF5CAA98}" +Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNet.Authentication.MicrosoftAccount", "src\Microsoft.AspNet.Authentication.MicrosoftAccount\Microsoft.AspNet.Authentication.MicrosoftAccount.kproj", "{ACB45E19-F520-4D0C-8916-B0CEB9C017FE}" EndProject -Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNet.Security.OpenIdConnect", "src\Microsoft.AspNet.Security.OpenIdConnect\Microsoft.AspNet.Security.OpenIdConnect.kproj", "{674D128E-83BB-481A-A9D9-6D47872E1FC8}" +Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNet.Authentication.Twitter", "src\Microsoft.AspNet.Authentication.Twitter\Microsoft.AspNet.Authentication.Twitter.kproj", "{0330FFF6-B4B5-42DD-8C99-26A789569000}" +EndProject +Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNet.Authentication.OAuth", "src\Microsoft.AspNet.Authentication.OAuth\Microsoft.AspNet.Authentication.OAuth.kproj", "{1657C79E-7755-4AEE-9D61-571295B69A30}" +EndProject +Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNet.Authentication.Tests", "test\Microsoft.AspNet.Authentication.Test\Microsoft.AspNet.Authentication.Tests.kproj", "{8DA26CD1-1302-4CFD-9270-9FA1B7C6138B}" +EndProject +Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNet.Authentication.OAuthBearer", "src\Microsoft.AspNet.Authentication.OAuthBearer\Microsoft.AspNet.Authentication.OAuthBearer.kproj", "{2755BFE5-7421-4A31-A644-F817DF5CAA98}" +EndProject +Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNet.Authorization.Tests", "test\Microsoft.AspNet.Authorization.Test\Microsoft.AspNet.Authorization.Tests.kproj", "{7AF5AD96-EB6E-4D0E-8ABE-C0B543C0F4C2}" +EndProject +Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNet.Authorization", "src\Microsoft.AspNet.Authorization\Microsoft.AspNet.Authorization.kproj", "{6AB3E514-5894-4131-9399-DC7D5284ADDB}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -52,26 +56,6 @@ Global Release|x86 = Release|x86 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {0F174C63-1898-4024-9A3C-3FDF5CAE5C68}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {0F174C63-1898-4024-9A3C-3FDF5CAE5C68}.Debug|Any CPU.Build.0 = Debug|Any CPU - {0F174C63-1898-4024-9A3C-3FDF5CAE5C68}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU - {0F174C63-1898-4024-9A3C-3FDF5CAE5C68}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU - {0F174C63-1898-4024-9A3C-3FDF5CAE5C68}.Debug|x86.ActiveCfg = Debug|Any CPU - {0F174C63-1898-4024-9A3C-3FDF5CAE5C68}.Release|Any CPU.ActiveCfg = Release|Any CPU - {0F174C63-1898-4024-9A3C-3FDF5CAE5C68}.Release|Any CPU.Build.0 = Release|Any CPU - {0F174C63-1898-4024-9A3C-3FDF5CAE5C68}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU - {0F174C63-1898-4024-9A3C-3FDF5CAE5C68}.Release|Mixed Platforms.Build.0 = Release|Any CPU - {0F174C63-1898-4024-9A3C-3FDF5CAE5C68}.Release|x86.ActiveCfg = Release|Any CPU - {15F1211B-B695-4A1C-B730-1AC58FC91090}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {15F1211B-B695-4A1C-B730-1AC58FC91090}.Debug|Any CPU.Build.0 = Debug|Any CPU - {15F1211B-B695-4A1C-B730-1AC58FC91090}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU - {15F1211B-B695-4A1C-B730-1AC58FC91090}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU - {15F1211B-B695-4A1C-B730-1AC58FC91090}.Debug|x86.ActiveCfg = Debug|Any CPU - {15F1211B-B695-4A1C-B730-1AC58FC91090}.Release|Any CPU.ActiveCfg = Release|Any CPU - {15F1211B-B695-4A1C-B730-1AC58FC91090}.Release|Any CPU.Build.0 = Release|Any CPU - {15F1211B-B695-4A1C-B730-1AC58FC91090}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU - {15F1211B-B695-4A1C-B730-1AC58FC91090}.Release|Mixed Platforms.Build.0 = Release|Any CPU - {15F1211B-B695-4A1C-B730-1AC58FC91090}.Release|x86.ActiveCfg = Release|Any CPU {558C2C2A-AED8-49DE-BB60-D5F8AE06C714}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {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 @@ -82,26 +66,6 @@ Global {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|x86.ActiveCfg = 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|x86.ActiveCfg = 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|x86.ActiveCfg = Release|Any CPU - {3984651C-FD44-4394-8793-3D14EE348C04}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {3984651C-FD44-4394-8793-3D14EE348C04}.Debug|Any CPU.Build.0 = Debug|Any CPU - {3984651C-FD44-4394-8793-3D14EE348C04}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU - {3984651C-FD44-4394-8793-3D14EE348C04}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU - {3984651C-FD44-4394-8793-3D14EE348C04}.Debug|x86.ActiveCfg = Debug|Any CPU - {3984651C-FD44-4394-8793-3D14EE348C04}.Release|Any CPU.ActiveCfg = Release|Any CPU - {3984651C-FD44-4394-8793-3D14EE348C04}.Release|Any CPU.Build.0 = Release|Any CPU - {3984651C-FD44-4394-8793-3D14EE348C04}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU - {3984651C-FD44-4394-8793-3D14EE348C04}.Release|Mixed Platforms.Build.0 = Release|Any CPU - {3984651C-FD44-4394-8793-3D14EE348C04}.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 @@ -112,46 +76,6 @@ Global {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|x86.ActiveCfg = Release|Any CPU - {89BF8535-A849-458E-868A-A68FCF620486}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {89BF8535-A849-458E-868A-A68FCF620486}.Debug|Any CPU.Build.0 = Debug|Any CPU - {89BF8535-A849-458E-868A-A68FCF620486}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU - {89BF8535-A849-458E-868A-A68FCF620486}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU - {89BF8535-A849-458E-868A-A68FCF620486}.Debug|x86.ActiveCfg = Debug|Any CPU - {89BF8535-A849-458E-868A-A68FCF620486}.Release|Any CPU.ActiveCfg = Release|Any CPU - {89BF8535-A849-458E-868A-A68FCF620486}.Release|Any CPU.Build.0 = Release|Any CPU - {89BF8535-A849-458E-868A-A68FCF620486}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU - {89BF8535-A849-458E-868A-A68FCF620486}.Release|Mixed Platforms.Build.0 = Release|Any CPU - {89BF8535-A849-458E-868A-A68FCF620486}.Release|x86.ActiveCfg = Release|Any CPU - {C96B77EA-4078-4C31-BDB2-878F11C5E061}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {C96B77EA-4078-4C31-BDB2-878F11C5E061}.Debug|Any CPU.Build.0 = Debug|Any CPU - {C96B77EA-4078-4C31-BDB2-878F11C5E061}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU - {C96B77EA-4078-4C31-BDB2-878F11C5E061}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU - {C96B77EA-4078-4C31-BDB2-878F11C5E061}.Debug|x86.ActiveCfg = Debug|Any CPU - {C96B77EA-4078-4C31-BDB2-878F11C5E061}.Release|Any CPU.ActiveCfg = Release|Any CPU - {C96B77EA-4078-4C31-BDB2-878F11C5E061}.Release|Any CPU.Build.0 = Release|Any CPU - {C96B77EA-4078-4C31-BDB2-878F11C5E061}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU - {C96B77EA-4078-4C31-BDB2-878F11C5E061}.Release|Mixed Platforms.Build.0 = Release|Any CPU - {C96B77EA-4078-4C31-BDB2-878F11C5E061}.Release|x86.ActiveCfg = Release|Any CPU - {1FCF26C2-A3C7-4308-B698-4AFC3560BC0C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {1FCF26C2-A3C7-4308-B698-4AFC3560BC0C}.Debug|Any CPU.Build.0 = Debug|Any CPU - {1FCF26C2-A3C7-4308-B698-4AFC3560BC0C}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU - {1FCF26C2-A3C7-4308-B698-4AFC3560BC0C}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU - {1FCF26C2-A3C7-4308-B698-4AFC3560BC0C}.Debug|x86.ActiveCfg = Debug|Any CPU - {1FCF26C2-A3C7-4308-B698-4AFC3560BC0C}.Release|Any CPU.ActiveCfg = Release|Any CPU - {1FCF26C2-A3C7-4308-B698-4AFC3560BC0C}.Release|Any CPU.Build.0 = Release|Any CPU - {1FCF26C2-A3C7-4308-B698-4AFC3560BC0C}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU - {1FCF26C2-A3C7-4308-B698-4AFC3560BC0C}.Release|Mixed Platforms.Build.0 = Release|Any CPU - {1FCF26C2-A3C7-4308-B698-4AFC3560BC0C}.Release|x86.ActiveCfg = Release|Any CPU - {4A636011-68EE-4CE5-836D-EA8E13CF71E4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {4A636011-68EE-4CE5-836D-EA8E13CF71E4}.Debug|Any CPU.Build.0 = Debug|Any CPU - {4A636011-68EE-4CE5-836D-EA8E13CF71E4}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU - {4A636011-68EE-4CE5-836D-EA8E13CF71E4}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU - {4A636011-68EE-4CE5-836D-EA8E13CF71E4}.Debug|x86.ActiveCfg = Debug|Any CPU - {4A636011-68EE-4CE5-836D-EA8E13CF71E4}.Release|Any CPU.ActiveCfg = Release|Any CPU - {4A636011-68EE-4CE5-836D-EA8E13CF71E4}.Release|Any CPU.Build.0 = Release|Any CPU - {4A636011-68EE-4CE5-836D-EA8E13CF71E4}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU - {4A636011-68EE-4CE5-836D-EA8E13CF71E4}.Release|Mixed Platforms.Build.0 = Release|Any CPU - {4A636011-68EE-4CE5-836D-EA8E13CF71E4}.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 @@ -174,6 +98,114 @@ Global {BEF0F5C3-EF4E-4649-9C49-D5E279A3CA2B}.Release|Mixed Platforms.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|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|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|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|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|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|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|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|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|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|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|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|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|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|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|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|x86.ActiveCfg = Release|Any CPU + {8DA26CD1-1302-4CFD-9270-9FA1B7C6138B}.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 @@ -186,36 +218,50 @@ Global {2755BFE5-7421-4A31-A644-F817DF5CAA98}.Release|Mixed Platforms.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 - {674D128E-83BB-481A-A9D9-6D47872E1FC8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {674D128E-83BB-481A-A9D9-6D47872E1FC8}.Debug|Any CPU.Build.0 = Debug|Any CPU - {674D128E-83BB-481A-A9D9-6D47872E1FC8}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU - {674D128E-83BB-481A-A9D9-6D47872E1FC8}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU - {674D128E-83BB-481A-A9D9-6D47872E1FC8}.Debug|x86.ActiveCfg = Debug|Any CPU - {674D128E-83BB-481A-A9D9-6D47872E1FC8}.Debug|x86.Build.0 = Debug|Any CPU - {674D128E-83BB-481A-A9D9-6D47872E1FC8}.Release|Any CPU.ActiveCfg = Release|Any CPU - {674D128E-83BB-481A-A9D9-6D47872E1FC8}.Release|Any CPU.Build.0 = Release|Any CPU - {674D128E-83BB-481A-A9D9-6D47872E1FC8}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU - {674D128E-83BB-481A-A9D9-6D47872E1FC8}.Release|Mixed Platforms.Build.0 = Release|Any CPU - {674D128E-83BB-481A-A9D9-6D47872E1FC8}.Release|x86.ActiveCfg = Release|Any CPU - {674D128E-83BB-481A-A9D9-6D47872E1FC8}.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|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|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|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|x86.ActiveCfg = Release|Any CPU + {6AB3E514-5894-4131-9399-DC7D5284ADDB}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection GlobalSection(NestedProjects) = preSolution - {0F174C63-1898-4024-9A3C-3FDF5CAE5C68} = {4D2B6A51-2F9F-44F5-8131-EA5CAC053652} - {15F1211B-B695-4A1C-B730-1AC58FC91090} = {4D2B6A51-2F9F-44F5-8131-EA5CAC053652} {558C2C2A-AED8-49DE-BB60-D5F8AE06C714} = {F8C0AA27-F3FB-4286-8E4C-47EF86B539FF} - {8DA26CD1-1302-4CFD-9270-9FA1B7C6138B} = {7BF11F3A-60B6-4796-B504-579C67FFBA34} - {3984651C-FD44-4394-8793-3D14EE348C04} = {4D2B6A51-2F9F-44F5-8131-EA5CAC053652} {8C73D216-332D-41D8-BFD0-45BC4BC36552} = {F8C0AA27-F3FB-4286-8E4C-47EF86B539FF} - {89BF8535-A849-458E-868A-A68FCF620486} = {4D2B6A51-2F9F-44F5-8131-EA5CAC053652} - {C96B77EA-4078-4C31-BDB2-878F11C5E061} = {4D2B6A51-2F9F-44F5-8131-EA5CAC053652} - {1FCF26C2-A3C7-4308-B698-4AFC3560BC0C} = {4D2B6A51-2F9F-44F5-8131-EA5CAC053652} - {4A636011-68EE-4CE5-836D-EA8E13CF71E4} = {4D2B6A51-2F9F-44F5-8131-EA5CAC053652} {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} + {ACB45E19-F520-4D0C-8916-B0CEB9C017FE} = {4D2B6A51-2F9F-44F5-8131-EA5CAC053652} + {0330FFF6-B4B5-42DD-8C99-26A789569000} = {4D2B6A51-2F9F-44F5-8131-EA5CAC053652} + {1657C79E-7755-4AEE-9D61-571295B69A30} = {4D2B6A51-2F9F-44F5-8131-EA5CAC053652} + {8DA26CD1-1302-4CFD-9270-9FA1B7C6138B} = {7BF11F3A-60B6-4796-B504-579C67FFBA34} {2755BFE5-7421-4A31-A644-F817DF5CAA98} = {4D2B6A51-2F9F-44F5-8131-EA5CAC053652} - {674D128E-83BB-481A-A9D9-6D47872E1FC8} = {4D2B6A51-2F9F-44F5-8131-EA5CAC053652} + {7AF5AD96-EB6E-4D0E-8ABE-C0B543C0F4C2} = {7BF11F3A-60B6-4796-B504-579C67FFBA34} + {6AB3E514-5894-4131-9399-DC7D5284ADDB} = {4D2B6A51-2F9F-44F5-8131-EA5CAC053652} EndGlobalSection EndGlobal diff --git a/src/Microsoft.AspNet.Authentication.Cookies/Microsoft.AspNet.Authentication.Cookies.kproj b/src/Microsoft.AspNet.Authentication.Cookies/Microsoft.AspNet.Authentication.Cookies.kproj index 3480de791..10ebb695f 100644 --- a/src/Microsoft.AspNet.Authentication.Cookies/Microsoft.AspNet.Authentication.Cookies.kproj +++ b/src/Microsoft.AspNet.Authentication.Cookies/Microsoft.AspNet.Authentication.Cookies.kproj @@ -6,7 +6,7 @@ - 15f1211b-b695-4a1c-b730-1ac58fc91090 + fc152cc4-054b-457e-8d91-389c5de3c561 ..\..\artifacts\obj\$(MSBuildProjectName) ..\..\artifacts\bin\$(MSBuildProjectName)\ diff --git a/src/Microsoft.AspNet.Authentication.Facebook/Microsoft.AspNet.Authentication.Facebook.kproj b/src/Microsoft.AspNet.Authentication.Facebook/Microsoft.AspNet.Authentication.Facebook.kproj index ed5242e07..608a152e2 100644 --- a/src/Microsoft.AspNet.Authentication.Facebook/Microsoft.AspNet.Authentication.Facebook.kproj +++ b/src/Microsoft.AspNet.Authentication.Facebook/Microsoft.AspNet.Authentication.Facebook.kproj @@ -6,7 +6,7 @@ - 3984651c-fd44-4394-8793-3d14ee348c04 + eeaaee68-607b-4e33-af3e-45c66b4dba5a ..\..\artifacts\obj\$(MSBuildProjectName) ..\..\artifacts\bin\$(MSBuildProjectName)\ diff --git a/src/Microsoft.AspNet.Authentication.Google/Microsoft.AspNet.Authentication.Google.kproj b/src/Microsoft.AspNet.Authentication.Google/Microsoft.AspNet.Authentication.Google.kproj index 6c85b04ce..36e2cade9 100644 --- a/src/Microsoft.AspNet.Authentication.Google/Microsoft.AspNet.Authentication.Google.kproj +++ b/src/Microsoft.AspNet.Authentication.Google/Microsoft.AspNet.Authentication.Google.kproj @@ -6,7 +6,7 @@ - 89bf8535-a849-458e-868a-a68fcf620486 + 76579c39-b829-490d-b8be-1bd35fe8412e ..\..\artifacts\obj\$(MSBuildProjectName) ..\..\artifacts\bin\$(MSBuildProjectName)\ diff --git a/src/Microsoft.AspNet.Authentication.MicrosoftAccount/Microsoft.AspNet.Authentication.MicrosoftAccount.kproj b/src/Microsoft.AspNet.Authentication.MicrosoftAccount/Microsoft.AspNet.Authentication.MicrosoftAccount.kproj index 88701bdb3..5935b2a13 100644 --- a/src/Microsoft.AspNet.Authentication.MicrosoftAccount/Microsoft.AspNet.Authentication.MicrosoftAccount.kproj +++ b/src/Microsoft.AspNet.Authentication.MicrosoftAccount/Microsoft.AspNet.Authentication.MicrosoftAccount.kproj @@ -1,4 +1,4 @@ - + 14.0 @@ -6,7 +6,7 @@ - 1fcf26c2-a3c7-4308-b698-4afc3560bc0c + acb45e19-f520-4d0c-8916-b0ceb9c017fe ..\..\artifacts\obj\$(MSBuildProjectName) ..\..\artifacts\bin\$(MSBuildProjectName)\ @@ -14,4 +14,4 @@ 2.0 - + \ No newline at end of file diff --git a/src/Microsoft.AspNet.Authentication.OAuth/Microsoft.AspNet.Authentication.OAuth.kproj b/src/Microsoft.AspNet.Authentication.OAuth/Microsoft.AspNet.Authentication.OAuth.kproj index 868328f6d..667114ea5 100644 --- a/src/Microsoft.AspNet.Authentication.OAuth/Microsoft.AspNet.Authentication.OAuth.kproj +++ b/src/Microsoft.AspNet.Authentication.OAuth/Microsoft.AspNet.Authentication.OAuth.kproj @@ -6,7 +6,7 @@ - 4a636011-68ee-4ce5-836d-ea8e13cf71e4 + 1657c79e-7755-4aee-9d61-571295b69a30 ..\..\artifacts\obj\$(MSBuildProjectName) ..\..\artifacts\bin\$(MSBuildProjectName)\ diff --git a/src/Microsoft.AspNet.Authentication.OpenIdConnect/Microsoft.AspNet.Authentication.OpenIdConnect.kproj b/src/Microsoft.AspNet.Authentication.OpenIdConnect/Microsoft.AspNet.Authentication.OpenIdConnect.kproj index 6167f967f..4b85e6378 100644 --- a/src/Microsoft.AspNet.Authentication.OpenIdConnect/Microsoft.AspNet.Authentication.OpenIdConnect.kproj +++ b/src/Microsoft.AspNet.Authentication.OpenIdConnect/Microsoft.AspNet.Authentication.OpenIdConnect.kproj @@ -6,7 +6,7 @@ - 674d128e-83bb-481a-a9d9-6d47872e1fc8 + 35115d55-b69e-46d4-bb33-c9e9e6ec5e7a ..\..\artifacts\obj\$(MSBuildProjectName) ..\..\artifacts\bin\$(MSBuildProjectName)\ @@ -14,4 +14,4 @@ 2.0 - + \ No newline at end of file diff --git a/src/Microsoft.AspNet.Authentication.Twitter/Microsoft.AspNet.Authentication.Twitter.kproj b/src/Microsoft.AspNet.Authentication.Twitter/Microsoft.AspNet.Authentication.Twitter.kproj index fb70dba2a..5d8846c09 100644 --- a/src/Microsoft.AspNet.Authentication.Twitter/Microsoft.AspNet.Authentication.Twitter.kproj +++ b/src/Microsoft.AspNet.Authentication.Twitter/Microsoft.AspNet.Authentication.Twitter.kproj @@ -6,7 +6,7 @@ - c96b77ea-4078-4c31-bdb2-878f11c5e061 + 0330fff6-b4b5-42dd-8c99-26a789569000 ..\..\artifacts\obj\$(MSBuildProjectName) ..\..\artifacts\bin\$(MSBuildProjectName)\ diff --git a/src/Microsoft.AspNet.Authentication/Microsoft.AspNet.Authentication.kproj b/src/Microsoft.AspNet.Authentication/Microsoft.AspNet.Authentication.kproj index b1e235900..b21c7af0e 100644 --- a/src/Microsoft.AspNet.Authentication/Microsoft.AspNet.Authentication.kproj +++ b/src/Microsoft.AspNet.Authentication/Microsoft.AspNet.Authentication.kproj @@ -6,7 +6,7 @@ - 0f174c63-1898-4024-9a3c-3fdf5cae5c68 + 2286250a-52c8-4126-9f93-b1e45f0ad078 ..\..\artifacts\obj\$(MSBuildProjectName) ..\..\artifacts\bin\$(MSBuildProjectName)\ From 0577454f13f6ec0e82a424225729ccb57e2911ac Mon Sep 17 00:00:00 2001 From: Hao Kung Date: Tue, 3 Mar 2015 15:40:54 -0800 Subject: [PATCH 140/216] Fix for OpenIdConnect --- .../OpenidConnectAuthenticationHandler.cs | 4 ++-- .../OpenIdConnect/OpenIdConnectMiddlewareTests.cs | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenidConnectAuthenticationHandler.cs b/src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenidConnectAuthenticationHandler.cs index 67711ac5e..884dfa733 100644 --- a/src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenidConnectAuthenticationHandler.cs +++ b/src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenidConnectAuthenticationHandler.cs @@ -220,7 +220,7 @@ protected override async Task AuthenticateCoreAsync() } OpenIdConnectMessage openIdConnectMessage = null; - + // assumption: if the ContentType is "application/x-www-form-urlencoded" it should be safe to read as it is small. if (string.Equals(Request.Method, "POST", StringComparison.OrdinalIgnoreCase) && !string.IsNullOrWhiteSpace(Request.ContentType) @@ -566,7 +566,7 @@ private async Task InvokeReplyPathAsync() { if (ticket.Principal != null) { - Request.HttpContext.Response.SignIn(ticket.AuthenticationScheme, ticket.Principal, ticket.Properties); + Request.HttpContext.Response.SignIn(Options.SignInScheme, ticket.Principal, ticket.Properties); } // Redirect back to the original secured resource, if any. diff --git a/test/Microsoft.AspNet.Authentication.Test/OpenIdConnect/OpenIdConnectMiddlewareTests.cs b/test/Microsoft.AspNet.Authentication.Test/OpenIdConnect/OpenIdConnectMiddlewareTests.cs index 725c2a073..96f17c86e 100644 --- a/test/Microsoft.AspNet.Authentication.Test/OpenIdConnect/OpenIdConnectMiddlewareTests.cs +++ b/test/Microsoft.AspNet.Authentication.Test/OpenIdConnect/OpenIdConnectMiddlewareTests.cs @@ -13,13 +13,13 @@ using System.Threading.Tasks; using System.Xml; using System.Xml.Linq; +using Microsoft.AspNet.Authentication.Cookies; +using Microsoft.AspNet.Authentication.DataHandler; +using Microsoft.AspNet.Authentication.OpenIdConnect; using Microsoft.AspNet.Builder; using Microsoft.AspNet.DataProtection; using Microsoft.AspNet.Http; using Microsoft.AspNet.Http.Authentication; -using Microsoft.AspNet.Authentication.Cookies; -using Microsoft.AspNet.Authentication.DataHandler; -using Microsoft.AspNet.Authentication.OpenIdConnect; using Microsoft.AspNet.TestHost; using Microsoft.Framework.DependencyInjection; using Newtonsoft.Json; From 329d8268576fdb192b599f35315ae4e0339d7e7d Mon Sep 17 00:00:00 2001 From: Brennan Date: Wed, 4 Mar 2015 17:10:56 -0800 Subject: [PATCH 141/216] Logging API changes --- .../CookieAuthenticationHandler.cs | 6 +++--- .../CookieAuthenticationMiddleware.cs | 2 +- .../OAuthAuthenticationHandler.cs | 8 ++++---- .../OAuthAuthenticationMiddleware.cs | 2 +- .../OAuthBearerAuthenticationHandler.cs | 2 +- .../OAuthBearerAuthenticationMiddleware.cs | 2 +- .../OpenIdConnectAuthenticationMiddleware.cs | 2 +- .../OpenidConnectAuthenticationHandler.cs | 12 +++++------ .../TwitterAuthenticationHandler.cs | 20 +++++++++---------- .../TwitterAuthenticationMiddleware.cs | 2 +- .../AuthenticationHandler.cs | 6 +++--- 11 files changed, 32 insertions(+), 32 deletions(-) diff --git a/src/Microsoft.AspNet.Authentication.Cookies/CookieAuthenticationHandler.cs b/src/Microsoft.AspNet.Authentication.Cookies/CookieAuthenticationHandler.cs index 5a72a142e..f747354e7 100644 --- a/src/Microsoft.AspNet.Authentication.Cookies/CookieAuthenticationHandler.cs +++ b/src/Microsoft.AspNet.Authentication.Cookies/CookieAuthenticationHandler.cs @@ -53,7 +53,7 @@ protected override async Task AuthenticateCoreAsync() if (ticket == null) { - _logger.WriteWarning(@"Unprotect ticket failed"); + _logger.LogWarning(@"Unprotect ticket failed"); return null; } @@ -62,14 +62,14 @@ protected override async Task AuthenticateCoreAsync() Claim claim = ticket.Principal.Claims.FirstOrDefault(c => c.Type.Equals(SessionIdClaim)); if (claim == null) { - _logger.WriteWarning(@"SessionId missing"); + _logger.LogWarning(@"SessionId missing"); return null; } _sessionKey = claim.Value; ticket = await Options.SessionStore.RetrieveAsync(_sessionKey); if (ticket == null) { - _logger.WriteWarning(@"Identity missing in session store"); + _logger.LogWarning(@"Identity missing in session store"); return null; } } diff --git a/src/Microsoft.AspNet.Authentication.Cookies/CookieAuthenticationMiddleware.cs b/src/Microsoft.AspNet.Authentication.Cookies/CookieAuthenticationMiddleware.cs index ba933d235..21df59253 100644 --- a/src/Microsoft.AspNet.Authentication.Cookies/CookieAuthenticationMiddleware.cs +++ b/src/Microsoft.AspNet.Authentication.Cookies/CookieAuthenticationMiddleware.cs @@ -44,7 +44,7 @@ public CookieAuthenticationMiddleware(RequestDelegate next, Options.CookieManager = new ChunkingCookieManager(); } - _logger = loggerFactory.Create(typeof(CookieAuthenticationMiddleware).FullName); + _logger = loggerFactory.CreateLogger(typeof(CookieAuthenticationMiddleware).FullName); } protected override AuthenticationHandler CreateHandler() diff --git a/src/Microsoft.AspNet.Authentication.OAuth/OAuthAuthenticationHandler.cs b/src/Microsoft.AspNet.Authentication.OAuth/OAuthAuthenticationHandler.cs index 8e193befe..6a51d85e9 100644 --- a/src/Microsoft.AspNet.Authentication.OAuth/OAuthAuthenticationHandler.cs +++ b/src/Microsoft.AspNet.Authentication.OAuth/OAuthAuthenticationHandler.cs @@ -45,7 +45,7 @@ public async Task InvokeReturnPathAsync() AuthenticationTicket ticket = await AuthenticateAsync(); if (ticket == null) { - Logger.WriteWarning("Invalid return state, unable to redirect."); + Logger.LogWarning("Invalid return state, unable to redirect."); Response.StatusCode = 500; return true; } @@ -94,7 +94,7 @@ protected override async Task AuthenticateCoreAsync() var value = query.Get("error"); if (!string.IsNullOrEmpty(value)) { - Logger.WriteVerbose("Remote server returned an error: " + Request.QueryString); + Logger.LogVerbose("Remote server returned an error: " + Request.QueryString); // TODO: Fail request rather than passing through? return null; } @@ -127,7 +127,7 @@ protected override async Task AuthenticateCoreAsync() if (string.IsNullOrWhiteSpace(tokens.AccessToken)) { - Logger.WriteWarning("Access token was not found"); + Logger.LogWarning("Access token was not found"); return new AuthenticationTicket(properties, Options.AuthenticationScheme); } @@ -135,7 +135,7 @@ protected override async Task AuthenticateCoreAsync() } catch (Exception ex) { - Logger.WriteError("Authentication failed", ex); + Logger.LogError("Authentication failed", ex); return new AuthenticationTicket(properties, Options.AuthenticationScheme); } } diff --git a/src/Microsoft.AspNet.Authentication.OAuth/OAuthAuthenticationMiddleware.cs b/src/Microsoft.AspNet.Authentication.OAuth/OAuthAuthenticationMiddleware.cs index b8e10ff99..8f937575f 100644 --- a/src/Microsoft.AspNet.Authentication.OAuth/OAuthAuthenticationMiddleware.cs +++ b/src/Microsoft.AspNet.Authentication.OAuth/OAuthAuthenticationMiddleware.cs @@ -66,7 +66,7 @@ public OAuthAuthenticationMiddleware( throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, Resources.Exception_OptionMustBeProvided, "TokenEndpoint")); } - Logger = loggerFactory.Create(this.GetType().FullName); + Logger = loggerFactory.CreateLogger(this.GetType().FullName); if (Options.StateDataFormat == null) { diff --git a/src/Microsoft.AspNet.Authentication.OAuthBearer/OAuthBearerAuthenticationHandler.cs b/src/Microsoft.AspNet.Authentication.OAuthBearer/OAuthBearerAuthenticationHandler.cs index 56d3d1025..42e6f838f 100644 --- a/src/Microsoft.AspNet.Authentication.OAuthBearer/OAuthBearerAuthenticationHandler.cs +++ b/src/Microsoft.AspNet.Authentication.OAuthBearer/OAuthBearerAuthenticationHandler.cs @@ -155,7 +155,7 @@ protected override async Task AuthenticateCoreAsync() } catch (Exception ex) { - _logger.WriteError("Exception occurred while processing message", ex); + _logger.LogError("Exception occurred while processing message", ex); // Refresh the configuration for exceptions that may be caused by key rollovers. The user can also request a refresh in the notification. if (Options.RefreshOnIssuerKeyNotFound && ex.GetType().Equals(typeof(SecurityTokenSignatureKeyNotFoundException))) diff --git a/src/Microsoft.AspNet.Authentication.OAuthBearer/OAuthBearerAuthenticationMiddleware.cs b/src/Microsoft.AspNet.Authentication.OAuthBearer/OAuthBearerAuthenticationMiddleware.cs index 824405e0e..8698bf740 100644 --- a/src/Microsoft.AspNet.Authentication.OAuthBearer/OAuthBearerAuthenticationMiddleware.cs +++ b/src/Microsoft.AspNet.Authentication.OAuthBearer/OAuthBearerAuthenticationMiddleware.cs @@ -36,7 +36,7 @@ public OAuthBearerAuthenticationMiddleware( ConfigureOptions configureOptions) : base(next, services, options, configureOptions) { - _logger = loggerFactory.Create(); + _logger = loggerFactory.CreateLogger(); if (Options.Notifications == null) { Options.Notifications = new OAuthBearerAuthenticationNotifications(); diff --git a/src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenIdConnectAuthenticationMiddleware.cs b/src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenIdConnectAuthenticationMiddleware.cs index 543e8eeeb..2a802ce10 100644 --- a/src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenIdConnectAuthenticationMiddleware.cs +++ b/src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenIdConnectAuthenticationMiddleware.cs @@ -44,7 +44,7 @@ public OpenIdConnectAuthenticationMiddleware( ConfigureOptions configureOptions) : base(next, services, options, configureOptions) { - _logger = loggerFactory.Create(); + _logger = loggerFactory.CreateLogger(); if (string.IsNullOrWhiteSpace(Options.TokenValidationParameters.AuthenticationType)) { diff --git a/src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenidConnectAuthenticationHandler.cs b/src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenidConnectAuthenticationHandler.cs index 884dfa733..046232b9e 100644 --- a/src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenidConnectAuthenticationHandler.cs +++ b/src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenidConnectAuthenticationHandler.cs @@ -99,7 +99,7 @@ protected override async Task ApplyResponseGrantAsync() string redirectUri = notification.ProtocolMessage.CreateLogoutRequestUrl(); if (!Uri.IsWellFormedUriString(redirectUri, UriKind.Absolute)) { - _logger.WriteWarning("The logout redirect URI is malformed: {0}", (redirectUri ?? "null")); + _logger.LogWarning("The logout redirect URI is malformed: {0}", (redirectUri ?? "null")); } Response.Redirect(redirectUri); @@ -195,7 +195,7 @@ protected override async Task ApplyResponseChallengeAsync() string redirectUri = notification.ProtocolMessage.CreateAuthenticationRequestUrl(); if (!Uri.IsWellFormedUriString(redirectUri, UriKind.Absolute)) { - _logger.WriteWarning("Uri.IsWellFormedUriString(redirectUri, UriKind.Absolute) returned 'false', redirectUri is: {0}", (redirectUri ?? "null")); + _logger.LogWarning("Uri.IsWellFormedUriString(redirectUri, UriKind.Absolute) returned 'false', redirectUri is: {0}", (redirectUri ?? "null")); } Response.Redirect(redirectUri); @@ -262,7 +262,7 @@ protected override async Task AuthenticateCoreAsync() AuthenticationProperties properties = GetPropertiesFromState(openIdConnectMessage.State); if (properties == null) { - _logger.WriteWarning("The state field is missing or invalid."); + _logger.LogWarning("The state field is missing or invalid."); return null; } @@ -279,7 +279,7 @@ protected override async Task AuthenticateCoreAsync() // OpenIdConnect protocol allows a Code to be received without the id_token if (string.IsNullOrWhiteSpace(openIdConnectMessage.IdToken)) { - _logger.WriteWarning("The id_token is missing."); + _logger.LogWarning("The id_token is missing."); return null; } @@ -424,7 +424,7 @@ protected override async Task AuthenticateCoreAsync() } catch (Exception exception) { - _logger.WriteError("Exception occurred while processing message", exception); + _logger.LogError("Exception occurred while processing message", exception); // Refresh the configuration for exceptions that may be caused by key rollovers. The user can also request a refresh in the notification. if (Options.RefreshOnIssuerKeyNotFound && exception.GetType().Equals(typeof(SecurityTokenSignatureKeyNotFoundException))) @@ -511,7 +511,7 @@ private string RetrieveNonce(string nonceExpectedValue) } catch (Exception ex) { - _logger.WriteWarning("Failed to un-protect the nonce cookie.", ex); + _logger.LogWarning("Failed to un-protect the nonce cookie.", ex); } } } diff --git a/src/Microsoft.AspNet.Authentication.Twitter/TwitterAuthenticationHandler.cs b/src/Microsoft.AspNet.Authentication.Twitter/TwitterAuthenticationHandler.cs index c6361295b..355fb84b2 100644 --- a/src/Microsoft.AspNet.Authentication.Twitter/TwitterAuthenticationHandler.cs +++ b/src/Microsoft.AspNet.Authentication.Twitter/TwitterAuthenticationHandler.cs @@ -62,7 +62,7 @@ protected override async Task AuthenticateCoreAsync() if (requestToken == null) { - _logger.WriteWarning("Invalid state"); + _logger.LogWarning("Invalid state"); return null; } @@ -71,20 +71,20 @@ protected override async Task AuthenticateCoreAsync() string returnedToken = query.Get("oauth_token"); if (string.IsNullOrWhiteSpace(returnedToken)) { - _logger.WriteWarning("Missing oauth_token"); + _logger.LogWarning("Missing oauth_token"); return new AuthenticationTicket(properties, Options.AuthenticationScheme); } if (returnedToken != requestToken.Token) { - _logger.WriteWarning("Unmatched token"); + _logger.LogWarning("Unmatched token"); return new AuthenticationTicket(properties, Options.AuthenticationScheme); } string oauthVerifier = query.Get("oauth_verifier"); if (string.IsNullOrWhiteSpace(oauthVerifier)) { - _logger.WriteWarning("Missing or blank oauth_verifier"); + _logger.LogWarning("Missing or blank oauth_verifier"); return new AuthenticationTicket(properties, Options.AuthenticationScheme); } @@ -120,7 +120,7 @@ protected override async Task AuthenticateCoreAsync() } catch (Exception ex) { - _logger.WriteError("Authentication failed", ex); + _logger.LogError("Authentication failed", ex); return new AuthenticationTicket(properties, Options.AuthenticationScheme); } } @@ -180,7 +180,7 @@ protected override async Task ApplyResponseChallengeAsync() } else { - _logger.WriteError("requestToken CallbackConfirmed!=true"); + _logger.LogError("requestToken CallbackConfirmed!=true"); } } @@ -189,7 +189,7 @@ public async Task InvokeReturnPathAsync() AuthenticationTicket model = await AuthenticateAsync(); if (model == null) { - _logger.WriteWarning("Invalid return state, unable to redirect."); + _logger.LogWarning("Invalid return state, unable to redirect."); Response.StatusCode = 500; return true; } @@ -224,7 +224,7 @@ public async Task InvokeReturnPathAsync() private async Task ObtainRequestTokenAsync(string consumerKey, string consumerSecret, string callBackUri, AuthenticationProperties properties) { - _logger.WriteVerbose("ObtainRequestToken"); + _logger.LogVerbose("ObtainRequestToken"); string nonce = Guid.NewGuid().ToString("N"); @@ -285,7 +285,7 @@ private async Task ObtainAccessTokenAsync(string consumerKey, strin { // https://dev.twitter.com/docs/api/1/post/oauth/access_token - _logger.WriteVerbose("ObtainAccessToken"); + _logger.LogVerbose("ObtainAccessToken"); string nonce = Guid.NewGuid().ToString("N"); @@ -342,7 +342,7 @@ private async Task ObtainAccessTokenAsync(string consumerKey, strin if (!response.IsSuccessStatusCode) { - _logger.WriteError("AccessToken request failed with a status code of " + response.StatusCode); + _logger.LogError("AccessToken request failed with a status code of " + response.StatusCode); response.EnsureSuccessStatusCode(); // throw } diff --git a/src/Microsoft.AspNet.Authentication.Twitter/TwitterAuthenticationMiddleware.cs b/src/Microsoft.AspNet.Authentication.Twitter/TwitterAuthenticationMiddleware.cs index 686908092..2efdaff96 100644 --- a/src/Microsoft.AspNet.Authentication.Twitter/TwitterAuthenticationMiddleware.cs +++ b/src/Microsoft.AspNet.Authentication.Twitter/TwitterAuthenticationMiddleware.cs @@ -51,7 +51,7 @@ public TwitterAuthenticationMiddleware( throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, Resources.Exception_OptionMustBeProvided, "ConsumerKey")); } - _logger = loggerFactory.Create(typeof(TwitterAuthenticationMiddleware).FullName); + _logger = loggerFactory.CreateLogger(typeof(TwitterAuthenticationMiddleware).FullName); if (Options.Notifications == null) { diff --git a/src/Microsoft.AspNet.Authentication/AuthenticationHandler.cs b/src/Microsoft.AspNet.Authentication/AuthenticationHandler.cs index f3d13d33f..e2c619b39 100644 --- a/src/Microsoft.AspNet.Authentication/AuthenticationHandler.cs +++ b/src/Microsoft.AspNet.Authentication/AuthenticationHandler.cs @@ -408,7 +408,7 @@ protected bool ValidateCorrelationId([NotNull] AuthenticationProperties properti string correlationCookie = Request.Cookies[correlationKey]; if (string.IsNullOrWhiteSpace(correlationCookie)) { - logger.WriteWarning("{0} cookie not found.", correlationKey); + logger.LogWarning("{0} cookie not found.", correlationKey); return false; } @@ -424,7 +424,7 @@ protected bool ValidateCorrelationId([NotNull] AuthenticationProperties properti correlationKey, out correlationExtra)) { - logger.WriteWarning("{0} state property not found.", correlationKey); + logger.LogWarning("{0} state property not found.", correlationKey); return false; } @@ -432,7 +432,7 @@ protected bool ValidateCorrelationId([NotNull] AuthenticationProperties properti if (!string.Equals(correlationCookie, correlationExtra, StringComparison.Ordinal)) { - logger.WriteWarning("{0} correlation cookie and state property mismatch.", correlationKey); + logger.LogWarning("{0} correlation cookie and state property mismatch.", correlationKey); return false; } From 580664201c6dc5e19c1045577436f4d62f920e0a Mon Sep 17 00:00:00 2001 From: Hao Kung Date: Wed, 4 Mar 2015 18:07:34 -0800 Subject: [PATCH 142/216] React to DI changes --- .../ServiceCollectionExtensions.cs | 11 +++++------ .../DefaultAuthorizationServiceTests.cs | 1 - 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/src/Microsoft.AspNet.Authorization/ServiceCollectionExtensions.cs b/src/Microsoft.AspNet.Authorization/ServiceCollectionExtensions.cs index 9146c747b..292083120 100644 --- a/src/Microsoft.AspNet.Authorization/ServiceCollectionExtensions.cs +++ b/src/Microsoft.AspNet.Authorization/ServiceCollectionExtensions.cs @@ -22,12 +22,11 @@ public static IServiceCollection ConfigureAuthorization([NotNull] this IServiceC // Review: Need UseDefaultSubkey parameter? public static IServiceCollection AddAuthorization([NotNull] this IServiceCollection services, IConfiguration config = null, Action configureOptions = null) { - var describe = new ServiceDescriber(config); - services.AddOptions(config); - services.TryAdd(describe.Transient()); - services.Add(describe.Transient()); - services.Add(describe.Transient()); - services.Add(describe.Transient()); + services.AddOptions(); + services.TryAdd(ServiceDescriptor.Transient()); + services.AddTransient(); + services.AddTransient(); + services.AddTransient(); if (configureOptions != null) { services.Configure(configureOptions); diff --git a/test/Microsoft.AspNet.Authorization.Test/DefaultAuthorizationServiceTests.cs b/test/Microsoft.AspNet.Authorization.Test/DefaultAuthorizationServiceTests.cs index 54a4e1a7c..4b9b5a33d 100644 --- a/test/Microsoft.AspNet.Authorization.Test/DefaultAuthorizationServiceTests.cs +++ b/test/Microsoft.AspNet.Authorization.Test/DefaultAuthorizationServiceTests.cs @@ -7,7 +7,6 @@ using System.Security.Claims; using System.Threading.Tasks; using Microsoft.Framework.DependencyInjection; -using Microsoft.Framework.DependencyInjection.Fallback; using Xunit; namespace Microsoft.AspNet.Authorization.Test From 1459ca1edb8dad68b0e908677a3e9f5298bf864a Mon Sep 17 00:00:00 2001 From: Hao Kung Date: Wed, 4 Mar 2015 18:07:34 -0800 Subject: [PATCH 143/216] React to DI changes --- .../ServiceCollectionExtensions.cs | 11 +++++------ .../DefaultAuthorizationServiceTests.cs | 1 - 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/src/Microsoft.AspNet.Authorization/ServiceCollectionExtensions.cs b/src/Microsoft.AspNet.Authorization/ServiceCollectionExtensions.cs index 9146c747b..292083120 100644 --- a/src/Microsoft.AspNet.Authorization/ServiceCollectionExtensions.cs +++ b/src/Microsoft.AspNet.Authorization/ServiceCollectionExtensions.cs @@ -22,12 +22,11 @@ public static IServiceCollection ConfigureAuthorization([NotNull] this IServiceC // Review: Need UseDefaultSubkey parameter? public static IServiceCollection AddAuthorization([NotNull] this IServiceCollection services, IConfiguration config = null, Action configureOptions = null) { - var describe = new ServiceDescriber(config); - services.AddOptions(config); - services.TryAdd(describe.Transient()); - services.Add(describe.Transient()); - services.Add(describe.Transient()); - services.Add(describe.Transient()); + services.AddOptions(); + services.TryAdd(ServiceDescriptor.Transient()); + services.AddTransient(); + services.AddTransient(); + services.AddTransient(); if (configureOptions != null) { services.Configure(configureOptions); diff --git a/test/Microsoft.AspNet.Authorization.Test/DefaultAuthorizationServiceTests.cs b/test/Microsoft.AspNet.Authorization.Test/DefaultAuthorizationServiceTests.cs index 54a4e1a7c..4b9b5a33d 100644 --- a/test/Microsoft.AspNet.Authorization.Test/DefaultAuthorizationServiceTests.cs +++ b/test/Microsoft.AspNet.Authorization.Test/DefaultAuthorizationServiceTests.cs @@ -7,7 +7,6 @@ using System.Security.Claims; using System.Threading.Tasks; using Microsoft.Framework.DependencyInjection; -using Microsoft.Framework.DependencyInjection.Fallback; using Xunit; namespace Microsoft.AspNet.Authorization.Test From 08017f992ae9c408f50c6ef7f5048fc7c063bf09 Mon Sep 17 00:00:00 2001 From: Levi B Date: Wed, 4 Mar 2015 23:28:20 -0800 Subject: [PATCH 144/216] Fix build breaks caused by Options refactoring. --- test/Microsoft.AspNet.Authorization.Test/project.json | 1 + 1 file changed, 1 insertion(+) diff --git a/test/Microsoft.AspNet.Authorization.Test/project.json b/test/Microsoft.AspNet.Authorization.Test/project.json index 68f39fe36..3fe88159d 100644 --- a/test/Microsoft.AspNet.Authorization.Test/project.json +++ b/test/Microsoft.AspNet.Authorization.Test/project.json @@ -4,6 +4,7 @@ }, "dependencies": { "Microsoft.AspNet.Authorization": "1.0.0-*", + "Microsoft.Framework.DependencyInjection": "1.0.0-*", "Moq": "4.2.1312.1622", "xunit.runner.kre": "1.0.0-*" }, From e2bb76280f07404f23ecbe8f4b2481082692abc2 Mon Sep 17 00:00:00 2001 From: Hao Kung Date: Thu, 5 Mar 2015 15:01:44 -0800 Subject: [PATCH 145/216] Support AccessDeniedPath for Cookie 403 redirection Fixes https://github.com/aspnet/Security/issues/166 --- .../CookieAuthenticationHandler.cs | 35 +++++++++++++++++++ .../CookieAuthenticationMiddleware.cs | 2 -- .../CookieAuthenticationOptions.cs | 9 +++++ .../OAuthBearerAuthenticationHandler.cs | 4 +-- .../AutomaticAuthenticationHandler.cs | 18 ---------- .../Cookies/CookieMiddlewareTests.cs | 21 +++++++++++ 6 files changed, 67 insertions(+), 22 deletions(-) diff --git a/src/Microsoft.AspNet.Authentication.Cookies/CookieAuthenticationHandler.cs b/src/Microsoft.AspNet.Authentication.Cookies/CookieAuthenticationHandler.cs index f747354e7..ae7e866fb 100644 --- a/src/Microsoft.AspNet.Authentication.Cookies/CookieAuthenticationHandler.cs +++ b/src/Microsoft.AspNet.Authentication.Cookies/CookieAuthenticationHandler.cs @@ -323,6 +323,41 @@ private static bool IsHostRelative(string path) protected override void ApplyResponseChallenge() { + if (ShouldConvertChallengeToForbidden()) + { + // Handle 403 by redirecting to AccessDeniedPath if set + if (Options.AccessDeniedPath.HasValue) + { + try + { + var accessDeniedUri = + Request.Scheme + + "://" + + Request.Host + + Request.PathBase + + Options.AccessDeniedPath; + + var redirectContext = new CookieApplyRedirectContext(Context, Options, accessDeniedUri); + Options.Notifications.ApplyRedirect(redirectContext); + } + catch (Exception exception) + { + var exceptionContext = new CookieExceptionContext(Context, Options, + CookieExceptionContext.ExceptionLocation.ApplyResponseChallenge, exception, ticket: null); + Options.Notifications.Exception(exceptionContext); + if (exceptionContext.Rethrow) + { + throw; + } + } + } + else + { + Response.StatusCode = 403; + } + return; + } + if (Response.StatusCode != 401 || !Options.LoginPath.HasValue ) { return; diff --git a/src/Microsoft.AspNet.Authentication.Cookies/CookieAuthenticationMiddleware.cs b/src/Microsoft.AspNet.Authentication.Cookies/CookieAuthenticationMiddleware.cs index 21df59253..e3ef3f570 100644 --- a/src/Microsoft.AspNet.Authentication.Cookies/CookieAuthenticationMiddleware.cs +++ b/src/Microsoft.AspNet.Authentication.Cookies/CookieAuthenticationMiddleware.cs @@ -4,8 +4,6 @@ using System; using Microsoft.AspNet.Authentication.Cookies.Infrastructure; using Microsoft.AspNet.Authentication.DataHandler; -using Microsoft.AspNet.Authentication.Cookies.Infrastructure; -using Microsoft.AspNet.Authentication.DataHandler; using Microsoft.AspNet.Builder; using Microsoft.AspNet.DataProtection; using Microsoft.Framework.Logging; diff --git a/src/Microsoft.AspNet.Authentication.Cookies/CookieAuthenticationOptions.cs b/src/Microsoft.AspNet.Authentication.Cookies/CookieAuthenticationOptions.cs index 12ff4f995..02e9743b4 100644 --- a/src/Microsoft.AspNet.Authentication.Cookies/CookieAuthenticationOptions.cs +++ b/src/Microsoft.AspNet.Authentication.Cookies/CookieAuthenticationOptions.cs @@ -105,6 +105,15 @@ public string CookieName [SuppressMessage("Microsoft.Naming", "CA1726:UsePreferredTerms", MessageId = "Logout", Justification = "By design")] public PathString LogoutPath { get; set; } + /// + /// The AccessDeniedPath property informs the middleware that it should change an outgoing 403 Forbidden status + /// code into a 302 redirection onto the given path. + /// + /// If the AccessDeniedPath is null or empty, the middleware will not look for 403 Forbidden status codes, and it will + /// not redirect + /// + public PathString AccessDeniedPath { get; set; } + /// /// The ReturnUrlParameter determines the name of the query string parameter which is appended by the middleware /// when a 401 Unauthorized status code is changed to a 302 redirect onto the login path. This is also the query diff --git a/src/Microsoft.AspNet.Authentication.OAuthBearer/OAuthBearerAuthenticationHandler.cs b/src/Microsoft.AspNet.Authentication.OAuthBearer/OAuthBearerAuthenticationHandler.cs index 42e6f838f..7f41be810 100644 --- a/src/Microsoft.AspNet.Authentication.OAuthBearer/OAuthBearerAuthenticationHandler.cs +++ b/src/Microsoft.AspNet.Authentication.OAuthBearer/OAuthBearerAuthenticationHandler.cs @@ -7,10 +7,9 @@ using System.Linq; using System.Security.Claims; using System.Threading.Tasks; +using Microsoft.AspNet.Authentication.Notifications; using Microsoft.AspNet.Http; using Microsoft.AspNet.Http.Authentication; -using Microsoft.AspNet.Authentication; -using Microsoft.AspNet.Authentication.Notifications; using Microsoft.Framework.Logging; using Microsoft.IdentityModel.Protocols; @@ -195,6 +194,7 @@ protected override async Task ApplyResponseChallengeAsync() if (ShouldConvertChallengeToForbidden()) { Response.StatusCode = 403; + return; } if ((Response.StatusCode != 401) || (ChallengeContext == null)) diff --git a/src/Microsoft.AspNet.Authentication/AutomaticAuthenticationHandler.cs b/src/Microsoft.AspNet.Authentication/AutomaticAuthenticationHandler.cs index 5032e47fa..d91fadfca 100644 --- a/src/Microsoft.AspNet.Authentication/AutomaticAuthenticationHandler.cs +++ b/src/Microsoft.AspNet.Authentication/AutomaticAuthenticationHandler.cs @@ -90,23 +90,5 @@ public override bool ShouldHandleScheme(string authenticationScheme) return Options.AutomaticAuthentication && string.IsNullOrWhiteSpace(authenticationScheme); } - - /// - /// Override this method to deal with 401 challenge concerns, if an authentication scheme in question - /// deals an authentication interaction as part of it's request flow. (like adding a response header, or - /// changing the 401 result to 302 of a login page or external sign-in location.) - /// - /// - protected override Task ApplyResponseChallengeAsync() - { - // If authenticate was called and the the status is still 401, authZ failed so set 403 and stop - if (ShouldConvertChallengeToForbidden()) - { - Response.StatusCode = 403; - return Task.FromResult(0); - } - return base.ApplyResponseChallengeAsync(); - } - } } \ No newline at end of file diff --git a/test/Microsoft.AspNet.Authentication.Test/Cookies/CookieMiddlewareTests.cs b/test/Microsoft.AspNet.Authentication.Test/Cookies/CookieMiddlewareTests.cs index c1d5a0c32..51d9a9452 100644 --- a/test/Microsoft.AspNet.Authentication.Test/Cookies/CookieMiddlewareTests.cs +++ b/test/Microsoft.AspNet.Authentication.Test/Cookies/CookieMiddlewareTests.cs @@ -420,6 +420,27 @@ public async Task CookieTurns401To403IfAuthenticated() transaction2.Response.StatusCode.ShouldBe(HttpStatusCode.Forbidden); } + [Fact] + public async Task CookieTurns401ToAccessDeniedWhenSetAndIfAuthenticated() + { + var clock = new TestClock(); + TestServer server = CreateServer(options => + { + options.SystemClock = clock; + options.AccessDeniedPath = new PathString("/accessdenied"); + }, + SignInAsAlice); + + Transaction transaction1 = await SendAsync(server, "http://example.com/testpath"); + + Transaction transaction2 = await SendAsync(server, "http://example.com/unauthorized", transaction1.CookieNameValue); + + transaction2.Response.StatusCode.ShouldBe(HttpStatusCode.Redirect); + + Uri location = transaction2.Response.Headers.Location; + location.LocalPath.ShouldBe("/accessdenied"); + } + [Fact] public async Task CookieDoesNothingTo401IfNotAuthenticated() { From aacc00aaeefb64279edb4b00482fa1b6dcd6fa6c Mon Sep 17 00:00:00 2001 From: Hao Kung Date: Thu, 5 Mar 2015 16:04:57 -0800 Subject: [PATCH 146/216] Move extension methods to proper namespaces Also add sugar for OpenIdConnect Fixes https://github.com/aspnet/Security/issues/107 Fixes https://github.com/aspnet/Security/issues/113 --- ...sions.cs => CookieAppBuilderExtensions.cs} | 8 +------- .../CookieServiceCollectionExtensions.cs | 20 +++++++++++++++++++ ...ons.cs => FacebookAppBuilderExtensions.cs} | 10 ++-------- .../FacebookServiceCollectionExtensions.cs | 20 +++++++++++++++++++ ...sions.cs => GoogleAppBuilderExtensions.cs} | 10 ++-------- .../GoogleServiceCollectionExtensions.cs | 19 ++++++++++++++++++ ...> MicrosoftAccountAppBuilderExtensions.cs} | 6 ------ ...osoftAccountServiceCollectionExtensions.cs | 19 ++++++++++++++++++ ....cs => OAuthBearerAppBuilderExtensions.cs} | 8 +------- .../OAuthBearerServiceCollectionExtensions.cs | 19 ++++++++++++++++++ ...penIdConnectServiceCollectionExtensions.cs | 19 ++++++++++++++++++ ...ions.cs => TwitterAppBuilderExtensions.cs} | 11 ++-------- .../TwitterServiceCollectionExtensions.cs | 19 ++++++++++++++++++ .../Twitter/TwitterMiddlewareTests.cs | 5 ----- 14 files changed, 143 insertions(+), 50 deletions(-) rename src/Microsoft.AspNet.Authentication.Cookies/{CookieAuthenticationExtensions.cs => CookieAppBuilderExtensions.cs} (80%) create mode 100644 src/Microsoft.AspNet.Authentication.Cookies/CookieServiceCollectionExtensions.cs rename src/Microsoft.AspNet.Authentication.Facebook/{FacebookAuthenticationExtensions.cs => FacebookAppBuilderExtensions.cs} (77%) create mode 100644 src/Microsoft.AspNet.Authentication.Facebook/FacebookServiceCollectionExtensions.cs rename src/Microsoft.AspNet.Authentication.Google/{GoogleAuthenticationExtensions.cs => GoogleAppBuilderExtensions.cs} (79%) create mode 100644 src/Microsoft.AspNet.Authentication.Google/GoogleServiceCollectionExtensions.cs rename src/Microsoft.AspNet.Authentication.MicrosoftAccount/{MicrosoftAccountAuthenticationExtensions.cs => MicrosoftAccountAppBuilderExtensions.cs} (77%) create mode 100644 src/Microsoft.AspNet.Authentication.MicrosoftAccount/MicrosoftAccountServiceCollectionExtensions.cs rename src/Microsoft.AspNet.Authentication.OAuthBearer/{OAuthBearerAuthenticationExtensions.cs => OAuthBearerAppBuilderExtensions.cs} (83%) create mode 100644 src/Microsoft.AspNet.Authentication.OAuthBearer/OAuthBearerServiceCollectionExtensions.cs create mode 100644 src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenIdConnectServiceCollectionExtensions.cs rename src/Microsoft.AspNet.Authentication.Twitter/{TwitterAuthenticationExtensions.cs => TwitterAppBuilderExtensions.cs} (70%) create mode 100644 src/Microsoft.AspNet.Authentication.Twitter/TwitterServiceCollectionExtensions.cs diff --git a/src/Microsoft.AspNet.Authentication.Cookies/CookieAuthenticationExtensions.cs b/src/Microsoft.AspNet.Authentication.Cookies/CookieAppBuilderExtensions.cs similarity index 80% rename from src/Microsoft.AspNet.Authentication.Cookies/CookieAuthenticationExtensions.cs rename to src/Microsoft.AspNet.Authentication.Cookies/CookieAppBuilderExtensions.cs index 08f4cc71a..5a00ca234 100644 --- a/src/Microsoft.AspNet.Authentication.Cookies/CookieAuthenticationExtensions.cs +++ b/src/Microsoft.AspNet.Authentication.Cookies/CookieAppBuilderExtensions.cs @@ -3,7 +3,6 @@ using System; using Microsoft.AspNet.Authentication.Cookies; -using Microsoft.Framework.DependencyInjection; using Microsoft.Framework.OptionsModel; namespace Microsoft.AspNet.Builder @@ -11,13 +10,8 @@ namespace Microsoft.AspNet.Builder /// /// Extension methods provided by the cookies authentication middleware /// - public static class CookieAuthenticationExtensions + public static class CookieAppBuilderExtensions { - public static IServiceCollection ConfigureCookieAuthentication([NotNull] this IServiceCollection services, [NotNull] Action configure) - { - return services.Configure(configure); - } - /// /// Adds a cookie-based authentication middleware to your web application pipeline. /// diff --git a/src/Microsoft.AspNet.Authentication.Cookies/CookieServiceCollectionExtensions.cs b/src/Microsoft.AspNet.Authentication.Cookies/CookieServiceCollectionExtensions.cs new file mode 100644 index 000000000..476dc948f --- /dev/null +++ b/src/Microsoft.AspNet.Authentication.Cookies/CookieServiceCollectionExtensions.cs @@ -0,0 +1,20 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using Microsoft.AspNet.Authentication.Cookies; +using Microsoft.Framework.DependencyInjection; + +namespace Microsoft.Framework.DependencyInjection +{ + /// + /// Extension methods provided by the cookies authentication middleware + /// + public static class CookieServiceCollectionExtensions + { + public static IServiceCollection ConfigureCookieAuthentication([NotNull] this IServiceCollection services, [NotNull] Action configure) + { + return services.Configure(configure); + } + } +} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Authentication.Facebook/FacebookAuthenticationExtensions.cs b/src/Microsoft.AspNet.Authentication.Facebook/FacebookAppBuilderExtensions.cs similarity index 77% rename from src/Microsoft.AspNet.Authentication.Facebook/FacebookAuthenticationExtensions.cs rename to src/Microsoft.AspNet.Authentication.Facebook/FacebookAppBuilderExtensions.cs index 3664bb592..c91855790 100644 --- a/src/Microsoft.AspNet.Authentication.Facebook/FacebookAuthenticationExtensions.cs +++ b/src/Microsoft.AspNet.Authentication.Facebook/FacebookAppBuilderExtensions.cs @@ -1,23 +1,17 @@ // Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. +using System; using Microsoft.AspNet.Authentication.Facebook; -using Microsoft.Framework.DependencyInjection; using Microsoft.Framework.OptionsModel; -using System; namespace Microsoft.AspNet.Builder { /// /// Extension methods for using . /// - public static class FacebookAuthenticationExtensions + public static class FacebookAppBuilderExtensions { - public static IServiceCollection ConfigureFacebookAuthentication([NotNull] this IServiceCollection services, [NotNull] Action configure) - { - return services.Configure(configure); - } - /// /// Authenticate users using Facebook. /// diff --git a/src/Microsoft.AspNet.Authentication.Facebook/FacebookServiceCollectionExtensions.cs b/src/Microsoft.AspNet.Authentication.Facebook/FacebookServiceCollectionExtensions.cs new file mode 100644 index 000000000..8d044dd40 --- /dev/null +++ b/src/Microsoft.AspNet.Authentication.Facebook/FacebookServiceCollectionExtensions.cs @@ -0,0 +1,20 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using Microsoft.AspNet.Authentication.Facebook; +using Microsoft.Framework.OptionsModel; +using System; + +namespace Microsoft.Framework.DependencyInjection +{ + /// + /// Extension methods for using . + /// + public static class FacebookServiceCollectionExtensions + { + public static IServiceCollection ConfigureFacebookAuthentication([NotNull] this IServiceCollection services, [NotNull] Action configure) + { + return services.Configure(configure); + } + } +} diff --git a/src/Microsoft.AspNet.Authentication.Google/GoogleAuthenticationExtensions.cs b/src/Microsoft.AspNet.Authentication.Google/GoogleAppBuilderExtensions.cs similarity index 79% rename from src/Microsoft.AspNet.Authentication.Google/GoogleAuthenticationExtensions.cs rename to src/Microsoft.AspNet.Authentication.Google/GoogleAppBuilderExtensions.cs index fd46b062a..8613d4368 100644 --- a/src/Microsoft.AspNet.Authentication.Google/GoogleAuthenticationExtensions.cs +++ b/src/Microsoft.AspNet.Authentication.Google/GoogleAppBuilderExtensions.cs @@ -1,23 +1,17 @@ // Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. +using System; using Microsoft.AspNet.Authentication.Google; -using Microsoft.Framework.DependencyInjection; using Microsoft.Framework.OptionsModel; -using System; namespace Microsoft.AspNet.Builder { /// /// Extension methods for using . /// - public static class GoogleAuthenticationExtensions + public static class GoogleAppBuilderExtensions { - public static IServiceCollection ConfigureGoogleAuthentication([NotNull] this IServiceCollection services, [NotNull] Action configure) - { - return services.Configure(configure); - } - /// /// Authenticate users using Google OAuth 2.0. /// diff --git a/src/Microsoft.AspNet.Authentication.Google/GoogleServiceCollectionExtensions.cs b/src/Microsoft.AspNet.Authentication.Google/GoogleServiceCollectionExtensions.cs new file mode 100644 index 000000000..a5a8b4b50 --- /dev/null +++ b/src/Microsoft.AspNet.Authentication.Google/GoogleServiceCollectionExtensions.cs @@ -0,0 +1,19 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using Microsoft.AspNet.Authentication.Google; + +namespace Microsoft.Framework.DependencyInjection +{ + /// + /// Extension methods for using . + /// + public static class GoogleServiceCollectionExtensions + { + public static IServiceCollection ConfigureGoogleAuthentication([NotNull] this IServiceCollection services, [NotNull] Action configure) + { + return services.Configure(configure); + } + } +} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Authentication.MicrosoftAccount/MicrosoftAccountAuthenticationExtensions.cs b/src/Microsoft.AspNet.Authentication.MicrosoftAccount/MicrosoftAccountAppBuilderExtensions.cs similarity index 77% rename from src/Microsoft.AspNet.Authentication.MicrosoftAccount/MicrosoftAccountAuthenticationExtensions.cs rename to src/Microsoft.AspNet.Authentication.MicrosoftAccount/MicrosoftAccountAppBuilderExtensions.cs index 397a1b32b..e068b5f5a 100644 --- a/src/Microsoft.AspNet.Authentication.MicrosoftAccount/MicrosoftAccountAuthenticationExtensions.cs +++ b/src/Microsoft.AspNet.Authentication.MicrosoftAccount/MicrosoftAccountAppBuilderExtensions.cs @@ -2,7 +2,6 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using Microsoft.AspNet.Authentication.MicrosoftAccount; -using Microsoft.Framework.DependencyInjection; using Microsoft.Framework.OptionsModel; using System; @@ -13,11 +12,6 @@ namespace Microsoft.AspNet.Builder /// public static class MicrosoftAccountAuthenticationExtensions { - public static IServiceCollection ConfigureMicrosoftAccountAuthentication([NotNull] this IServiceCollection services, [NotNull] Action configure) - { - return services.Configure(configure); - } - public static IApplicationBuilder UseMicrosoftAccountAuthentication([NotNull] this IApplicationBuilder app, Action configureOptions = null, string optionsName = "") { return app.UseMiddleware( diff --git a/src/Microsoft.AspNet.Authentication.MicrosoftAccount/MicrosoftAccountServiceCollectionExtensions.cs b/src/Microsoft.AspNet.Authentication.MicrosoftAccount/MicrosoftAccountServiceCollectionExtensions.cs new file mode 100644 index 000000000..b3e1e1110 --- /dev/null +++ b/src/Microsoft.AspNet.Authentication.MicrosoftAccount/MicrosoftAccountServiceCollectionExtensions.cs @@ -0,0 +1,19 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using Microsoft.AspNet.Authentication.MicrosoftAccount; + +namespace Microsoft.Framework.DependencyInjection +{ + /// + /// Extension methods for using + /// + public static class MicrosoftAccountServiceCollectionExtensions + { + public static IServiceCollection ConfigureMicrosoftAccountAuthentication([NotNull] this IServiceCollection services, [NotNull] Action configure) + { + return services.Configure(configure); + } + } +} diff --git a/src/Microsoft.AspNet.Authentication.OAuthBearer/OAuthBearerAuthenticationExtensions.cs b/src/Microsoft.AspNet.Authentication.OAuthBearer/OAuthBearerAppBuilderExtensions.cs similarity index 83% rename from src/Microsoft.AspNet.Authentication.OAuthBearer/OAuthBearerAuthenticationExtensions.cs rename to src/Microsoft.AspNet.Authentication.OAuthBearer/OAuthBearerAppBuilderExtensions.cs index b1a629334..88151eb16 100644 --- a/src/Microsoft.AspNet.Authentication.OAuthBearer/OAuthBearerAuthenticationExtensions.cs +++ b/src/Microsoft.AspNet.Authentication.OAuthBearer/OAuthBearerAppBuilderExtensions.cs @@ -3,7 +3,6 @@ using System; using Microsoft.AspNet.Authentication.OAuthBearer; -using Microsoft.Framework.DependencyInjection; using Microsoft.Framework.OptionsModel; namespace Microsoft.AspNet.Builder @@ -11,13 +10,8 @@ namespace Microsoft.AspNet.Builder /// /// Extension methods to add OAuth Bearer authentication capabilities to an HTTP application pipeline /// - public static class OAuthBearerAuthenticationExtensions + public static class OAuthBearerAppBuilderExtensions { - public static IServiceCollection ConfigureOAuthBearerAuthentication([NotNull] this IServiceCollection services, [NotNull] Action configure) - { - return services.ConfigureOptions(configure); - } - /// /// Adds Bearer token processing to an HTTP application pipeline. This middleware understands appropriately /// formatted and secured tokens which appear in the request header. If the Options.AuthenticationMode is Active, the diff --git a/src/Microsoft.AspNet.Authentication.OAuthBearer/OAuthBearerServiceCollectionExtensions.cs b/src/Microsoft.AspNet.Authentication.OAuthBearer/OAuthBearerServiceCollectionExtensions.cs new file mode 100644 index 000000000..5a878dcbb --- /dev/null +++ b/src/Microsoft.AspNet.Authentication.OAuthBearer/OAuthBearerServiceCollectionExtensions.cs @@ -0,0 +1,19 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using Microsoft.AspNet.Authentication.OAuthBearer; + +namespace Microsoft.Framework.DependencyInjection +{ + /// + /// Extension methods to add OAuth Bearer authentication capabilities to an HTTP application pipeline + /// + public static class OAuthBearerServiceCollectionExtensions + { + public static IServiceCollection ConfigureOAuthBearerAuthentication([NotNull] this IServiceCollection services, [NotNull] Action configure) + { + return services.ConfigureOptions(configure); + } + } +} diff --git a/src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenIdConnectServiceCollectionExtensions.cs b/src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenIdConnectServiceCollectionExtensions.cs new file mode 100644 index 000000000..390568fd3 --- /dev/null +++ b/src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenIdConnectServiceCollectionExtensions.cs @@ -0,0 +1,19 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using Microsoft.AspNet.Authentication.OpenIdConnect; + +namespace Microsoft.Framework.DependencyInjection +{ + /// + /// Extension methods to configure OpenIdConnect authentication options + /// + public static class OpenIdConnectServiceCollectionExtensions + { + public static IServiceCollection ConfigureOpenIdConnect(this IServiceCollection services, Action configure) + { + return services.ConfigureOptions(configure); + } + } +} diff --git a/src/Microsoft.AspNet.Authentication.Twitter/TwitterAuthenticationExtensions.cs b/src/Microsoft.AspNet.Authentication.Twitter/TwitterAppBuilderExtensions.cs similarity index 70% rename from src/Microsoft.AspNet.Authentication.Twitter/TwitterAuthenticationExtensions.cs rename to src/Microsoft.AspNet.Authentication.Twitter/TwitterAppBuilderExtensions.cs index bff189792..ce27cdadf 100644 --- a/src/Microsoft.AspNet.Authentication.Twitter/TwitterAuthenticationExtensions.cs +++ b/src/Microsoft.AspNet.Authentication.Twitter/TwitterAppBuilderExtensions.cs @@ -1,24 +1,17 @@ // Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -using Microsoft.AspNet.Authentication; +using System; using Microsoft.AspNet.Authentication.Twitter; -using Microsoft.Framework.DependencyInjection; using Microsoft.Framework.OptionsModel; -using System; namespace Microsoft.AspNet.Builder { /// /// Extension methods for using /// - public static class TwitterAuthenticationExtensions + public static class TwitterAppBuilderExtensions { - public static IServiceCollection ConfigureTwitterAuthentication([NotNull] this IServiceCollection services, [NotNull] Action configure) - { - return services.Configure(configure); - } - public static IApplicationBuilder UseTwitterAuthentication([NotNull] this IApplicationBuilder app, Action configureOptions = null, string optionsName = "") { return app.UseMiddleware( diff --git a/src/Microsoft.AspNet.Authentication.Twitter/TwitterServiceCollectionExtensions.cs b/src/Microsoft.AspNet.Authentication.Twitter/TwitterServiceCollectionExtensions.cs new file mode 100644 index 000000000..7c25c1737 --- /dev/null +++ b/src/Microsoft.AspNet.Authentication.Twitter/TwitterServiceCollectionExtensions.cs @@ -0,0 +1,19 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using Microsoft.AspNet.Authentication.Twitter; + +namespace Microsoft.Framework.DependencyInjection +{ + /// + /// Extension methods for using + /// + public static class TwitterAuthenticationExtensions + { + public static IServiceCollection ConfigureTwitterAuthentication([NotNull] this IServiceCollection services, [NotNull] Action configure) + { + return services.Configure(configure); + } + } +} diff --git a/test/Microsoft.AspNet.Authentication.Test/Twitter/TwitterMiddlewareTests.cs b/test/Microsoft.AspNet.Authentication.Test/Twitter/TwitterMiddlewareTests.cs index 6b54b6cd9..fd281086f 100644 --- a/test/Microsoft.AspNet.Authentication.Test/Twitter/TwitterMiddlewareTests.cs +++ b/test/Microsoft.AspNet.Authentication.Test/Twitter/TwitterMiddlewareTests.cs @@ -8,14 +8,9 @@ using System.Text; using System.Threading.Tasks; using Microsoft.AspNet.Builder; -using Microsoft.AspNet.DataProtection; using Microsoft.AspNet.Http; -using Microsoft.AspNet.Authentication.Cookies; -using Microsoft.AspNet.Authentication.Twitter; using Microsoft.AspNet.TestHost; using Microsoft.Framework.DependencyInjection; -using Microsoft.Framework.OptionsModel; -using Newtonsoft.Json; using Shouldly; using Xunit; From ce8caf0b9a17f459b5b601500f378b669a56bbd8 Mon Sep 17 00:00:00 2001 From: Praburaj Date: Thu, 5 Mar 2015 16:28:18 -0800 Subject: [PATCH 147/216] Rename Microsoft.AspNet.Http.Interfaces => Microsoft.AspNet.Http --- src/Microsoft.AspNet.Authentication/AuthenticationHandler.cs | 1 - .../AutomaticAuthenticationHandler.cs | 2 +- src/Microsoft.AspNet.Authentication/HttpContextExtensions.cs | 2 +- 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/Microsoft.AspNet.Authentication/AuthenticationHandler.cs b/src/Microsoft.AspNet.Authentication/AuthenticationHandler.cs index e2c619b39..0e768cf84 100644 --- a/src/Microsoft.AspNet.Authentication/AuthenticationHandler.cs +++ b/src/Microsoft.AspNet.Authentication/AuthenticationHandler.cs @@ -10,7 +10,6 @@ using Microsoft.AspNet.Authentication.DataHandler.Encoder; using Microsoft.AspNet.Http; using Microsoft.AspNet.Http.Authentication; -using Microsoft.AspNet.Http.Interfaces.Authentication; using Microsoft.Framework.Logging; namespace Microsoft.AspNet.Authentication diff --git a/src/Microsoft.AspNet.Authentication/AutomaticAuthenticationHandler.cs b/src/Microsoft.AspNet.Authentication/AutomaticAuthenticationHandler.cs index d91fadfca..f67f2a908 100644 --- a/src/Microsoft.AspNet.Authentication/AutomaticAuthenticationHandler.cs +++ b/src/Microsoft.AspNet.Authentication/AutomaticAuthenticationHandler.cs @@ -4,7 +4,7 @@ using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; -using Microsoft.AspNet.Http.Interfaces.Authentication; +using Microsoft.AspNet.Http.Authentication; namespace Microsoft.AspNet.Authentication { diff --git a/src/Microsoft.AspNet.Authentication/HttpContextExtensions.cs b/src/Microsoft.AspNet.Authentication/HttpContextExtensions.cs index 2f6b0e4d3..e378934cb 100644 --- a/src/Microsoft.AspNet.Authentication/HttpContextExtensions.cs +++ b/src/Microsoft.AspNet.Authentication/HttpContextExtensions.cs @@ -3,7 +3,7 @@ using Microsoft.AspNet.Http; using Microsoft.AspNet.Http.Core.Authentication; -using Microsoft.AspNet.Http.Interfaces.Authentication; +using Microsoft.AspNet.Http.Authentication; namespace Microsoft.AspNet.Authentication { From 5e7f1d7eff060aea0010b32b8bf68b36b51635b2 Mon Sep 17 00:00:00 2001 From: Hao Kung Date: Fri, 6 Mar 2015 12:37:34 -0800 Subject: [PATCH 148/216] Add Configure overloads for Auth for config/name --- .../CookieServiceCollectionExtensions.cs | 18 +++++++++++++++- .../FacebookServiceCollectionExtensions.cs | 21 ++++++++++++++++--- .../GoogleServiceCollectionExtensions.cs | 18 +++++++++++++++- ...osoftAccountServiceCollectionExtensions.cs | 18 +++++++++++++++- .../OAuthBearerServiceCollectionExtensions.cs | 18 +++++++++++++++- .../NotNullAttribute.cs | 12 +++++++++++ ...penIdConnectServiceCollectionExtensions.cs | 20 ++++++++++++++++-- .../TwitterServiceCollectionExtensions.cs | 18 +++++++++++++++- 8 files changed, 133 insertions(+), 10 deletions(-) create mode 100644 src/Microsoft.AspNet.Authentication.OpenIdConnect/NotNullAttribute.cs diff --git a/src/Microsoft.AspNet.Authentication.Cookies/CookieServiceCollectionExtensions.cs b/src/Microsoft.AspNet.Authentication.Cookies/CookieServiceCollectionExtensions.cs index 476dc948f..03632b1a6 100644 --- a/src/Microsoft.AspNet.Authentication.Cookies/CookieServiceCollectionExtensions.cs +++ b/src/Microsoft.AspNet.Authentication.Cookies/CookieServiceCollectionExtensions.cs @@ -3,6 +3,7 @@ using System; using Microsoft.AspNet.Authentication.Cookies; +using Microsoft.Framework.ConfigurationModel; using Microsoft.Framework.DependencyInjection; namespace Microsoft.Framework.DependencyInjection @@ -14,7 +15,22 @@ public static class CookieServiceCollectionExtensions { public static IServiceCollection ConfigureCookieAuthentication([NotNull] this IServiceCollection services, [NotNull] Action configure) { - return services.Configure(configure); + return services.ConfigureCookieAuthentication(configure, optionsName: ""); + } + + public static IServiceCollection ConfigureCookieAuthentication([NotNull] this IServiceCollection services, [NotNull] Action configure, string optionsName) + { + return services.Configure(configure, optionsName); + } + + public static IServiceCollection ConfigureCookieAuthentication([NotNull] this IServiceCollection services, [NotNull] IConfiguration config) + { + return services.ConfigureCookieAuthentication(config, optionsName: ""); + } + + public static IServiceCollection ConfigureCookieAuthentication([NotNull] this IServiceCollection services, [NotNull] IConfiguration config, string optionsName) + { + return services.Configure(config, optionsName); } } } \ No newline at end of file diff --git a/src/Microsoft.AspNet.Authentication.Facebook/FacebookServiceCollectionExtensions.cs b/src/Microsoft.AspNet.Authentication.Facebook/FacebookServiceCollectionExtensions.cs index 8d044dd40..f6117a10b 100644 --- a/src/Microsoft.AspNet.Authentication.Facebook/FacebookServiceCollectionExtensions.cs +++ b/src/Microsoft.AspNet.Authentication.Facebook/FacebookServiceCollectionExtensions.cs @@ -1,9 +1,9 @@ // Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -using Microsoft.AspNet.Authentication.Facebook; -using Microsoft.Framework.OptionsModel; using System; +using Microsoft.AspNet.Authentication.Facebook; +using Microsoft.Framework.ConfigurationModel; namespace Microsoft.Framework.DependencyInjection { @@ -14,7 +14,22 @@ public static class FacebookServiceCollectionExtensions { public static IServiceCollection ConfigureFacebookAuthentication([NotNull] this IServiceCollection services, [NotNull] Action configure) { - return services.Configure(configure); + return services.ConfigureFacebookAuthentication(configure, optionsName: ""); + } + + public static IServiceCollection ConfigureFacebookAuthentication([NotNull] this IServiceCollection services, [NotNull] Action configure, string optionsName) + { + return services.Configure(configure, optionsName); + } + + public static IServiceCollection ConfigureFacebookAuthentication([NotNull] this IServiceCollection services, [NotNull] IConfiguration config) + { + return services.ConfigureFacebookAuthentication(config, optionsName: ""); + } + + public static IServiceCollection ConfigureFacebookAuthentication([NotNull] this IServiceCollection services, [NotNull] IConfiguration config, string optionsName) + { + return services.Configure(config, optionsName); } } } diff --git a/src/Microsoft.AspNet.Authentication.Google/GoogleServiceCollectionExtensions.cs b/src/Microsoft.AspNet.Authentication.Google/GoogleServiceCollectionExtensions.cs index a5a8b4b50..239dbea29 100644 --- a/src/Microsoft.AspNet.Authentication.Google/GoogleServiceCollectionExtensions.cs +++ b/src/Microsoft.AspNet.Authentication.Google/GoogleServiceCollectionExtensions.cs @@ -3,6 +3,7 @@ using System; using Microsoft.AspNet.Authentication.Google; +using Microsoft.Framework.ConfigurationModel; namespace Microsoft.Framework.DependencyInjection { @@ -13,7 +14,22 @@ public static class GoogleServiceCollectionExtensions { public static IServiceCollection ConfigureGoogleAuthentication([NotNull] this IServiceCollection services, [NotNull] Action configure) { - return services.Configure(configure); + return services.ConfigureGoogleAuthentication(configure, optionsName: ""); + } + + public static IServiceCollection ConfigureGoogleAuthentication([NotNull] this IServiceCollection services, [NotNull] Action configure, string optionsName) + { + return services.Configure(configure, optionsName); + } + + public static IServiceCollection ConfigureGoogleAuthentication([NotNull] this IServiceCollection services, [NotNull] IConfiguration config) + { + return services.ConfigureGoogleAuthentication(config, optionsName: ""); + } + + public static IServiceCollection ConfigureGoogleAuthentication([NotNull] this IServiceCollection services, [NotNull] IConfiguration config, string optionsName) + { + return services.Configure(config, optionsName); } } } \ No newline at end of file diff --git a/src/Microsoft.AspNet.Authentication.MicrosoftAccount/MicrosoftAccountServiceCollectionExtensions.cs b/src/Microsoft.AspNet.Authentication.MicrosoftAccount/MicrosoftAccountServiceCollectionExtensions.cs index b3e1e1110..4fe4f1227 100644 --- a/src/Microsoft.AspNet.Authentication.MicrosoftAccount/MicrosoftAccountServiceCollectionExtensions.cs +++ b/src/Microsoft.AspNet.Authentication.MicrosoftAccount/MicrosoftAccountServiceCollectionExtensions.cs @@ -3,6 +3,7 @@ using System; using Microsoft.AspNet.Authentication.MicrosoftAccount; +using Microsoft.Framework.ConfigurationModel; namespace Microsoft.Framework.DependencyInjection { @@ -13,7 +14,22 @@ public static class MicrosoftAccountServiceCollectionExtensions { public static IServiceCollection ConfigureMicrosoftAccountAuthentication([NotNull] this IServiceCollection services, [NotNull] Action configure) { - return services.Configure(configure); + return services.ConfigureMicrosoftAccountAuthentication(configure, optionsName: ""); + } + + public static IServiceCollection ConfigureMicrosoftAccountAuthentication([NotNull] this IServiceCollection services, [NotNull] Action configure, string optionsName) + { + return services.Configure(configure, optionsName); + } + + public static IServiceCollection ConfigureMicrosoftAccountAuthentication([NotNull] this IServiceCollection services, [NotNull] IConfiguration config) + { + return services.ConfigureMicrosoftAccountAuthentication(config, optionsName: ""); + } + + public static IServiceCollection ConfigureMicrosoftAccountAuthentication([NotNull] this IServiceCollection services, [NotNull] IConfiguration config, string optionsName) + { + return services.Configure(config, optionsName); } } } diff --git a/src/Microsoft.AspNet.Authentication.OAuthBearer/OAuthBearerServiceCollectionExtensions.cs b/src/Microsoft.AspNet.Authentication.OAuthBearer/OAuthBearerServiceCollectionExtensions.cs index 5a878dcbb..b195abff8 100644 --- a/src/Microsoft.AspNet.Authentication.OAuthBearer/OAuthBearerServiceCollectionExtensions.cs +++ b/src/Microsoft.AspNet.Authentication.OAuthBearer/OAuthBearerServiceCollectionExtensions.cs @@ -3,6 +3,7 @@ using System; using Microsoft.AspNet.Authentication.OAuthBearer; +using Microsoft.Framework.ConfigurationModel; namespace Microsoft.Framework.DependencyInjection { @@ -13,7 +14,22 @@ public static class OAuthBearerServiceCollectionExtensions { public static IServiceCollection ConfigureOAuthBearerAuthentication([NotNull] this IServiceCollection services, [NotNull] Action configure) { - return services.ConfigureOptions(configure); + return services.ConfigureOAuthBearerAuthentication(configure, optionsName: ""); + } + + public static IServiceCollection ConfigureOAuthBearerAuthentication([NotNull] this IServiceCollection services, [NotNull] Action configure, string optionsName) + { + return services.Configure(configure, optionsName); + } + + public static IServiceCollection ConfigureOAuthBearerAuthentication([NotNull] this IServiceCollection services, [NotNull] IConfiguration config) + { + return services.ConfigureOAuthBearerAuthentication(config, optionsName: ""); + } + + public static IServiceCollection ConfigureOAuthBearerAuthentication([NotNull] this IServiceCollection services, [NotNull] IConfiguration config, string optionsName) + { + return services.Configure(config, optionsName); } } } diff --git a/src/Microsoft.AspNet.Authentication.OpenIdConnect/NotNullAttribute.cs b/src/Microsoft.AspNet.Authentication.OpenIdConnect/NotNullAttribute.cs new file mode 100644 index 000000000..6453923f5 --- /dev/null +++ b/src/Microsoft.AspNet.Authentication.OpenIdConnect/NotNullAttribute.cs @@ -0,0 +1,12 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; + +namespace Microsoft.AspNet.Authentication.OpenIdConnect +{ + [AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false)] + internal sealed class NotNullAttribute : Attribute + { + } +} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenIdConnectServiceCollectionExtensions.cs b/src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenIdConnectServiceCollectionExtensions.cs index 390568fd3..eca491cd5 100644 --- a/src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenIdConnectServiceCollectionExtensions.cs +++ b/src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenIdConnectServiceCollectionExtensions.cs @@ -3,6 +3,7 @@ using System; using Microsoft.AspNet.Authentication.OpenIdConnect; +using Microsoft.Framework.ConfigurationModel; namespace Microsoft.Framework.DependencyInjection { @@ -11,9 +12,24 @@ namespace Microsoft.Framework.DependencyInjection /// public static class OpenIdConnectServiceCollectionExtensions { - public static IServiceCollection ConfigureOpenIdConnect(this IServiceCollection services, Action configure) + public static IServiceCollection ConfigureOpenIdConnectAuthentication([NotNull] this IServiceCollection services, [NotNull] Action configure) { - return services.ConfigureOptions(configure); + return services.ConfigureOpenIdConnectAuthentication(configure, optionsName: ""); + } + + public static IServiceCollection ConfigureOpenIdConnectAuthentication([NotNull] this IServiceCollection services, [NotNull] Action configure, string optionsName) + { + return services.Configure(configure, optionsName); + } + + public static IServiceCollection ConfigureOpenIdConnectAuthentication([NotNull] this IServiceCollection services, [NotNull] IConfiguration config) + { + return services.ConfigureOpenIdConnectAuthentication(config, optionsName: ""); + } + + public static IServiceCollection ConfigureOpenIdConnectAuthentication([NotNull] this IServiceCollection services, [NotNull] IConfiguration config, string optionsName) + { + return services.Configure(config, optionsName); } } } diff --git a/src/Microsoft.AspNet.Authentication.Twitter/TwitterServiceCollectionExtensions.cs b/src/Microsoft.AspNet.Authentication.Twitter/TwitterServiceCollectionExtensions.cs index 7c25c1737..dad039952 100644 --- a/src/Microsoft.AspNet.Authentication.Twitter/TwitterServiceCollectionExtensions.cs +++ b/src/Microsoft.AspNet.Authentication.Twitter/TwitterServiceCollectionExtensions.cs @@ -3,6 +3,7 @@ using System; using Microsoft.AspNet.Authentication.Twitter; +using Microsoft.Framework.ConfigurationModel; namespace Microsoft.Framework.DependencyInjection { @@ -13,7 +14,22 @@ public static class TwitterAuthenticationExtensions { public static IServiceCollection ConfigureTwitterAuthentication([NotNull] this IServiceCollection services, [NotNull] Action configure) { - return services.Configure(configure); + return services.ConfigureTwitterAuthentication(configure, optionsName: ""); + } + + public static IServiceCollection ConfigureTwitterAuthentication([NotNull] this IServiceCollection services, [NotNull] Action configure, string optionsName) + { + return services.Configure(configure, optionsName); + } + + public static IServiceCollection ConfigureTwitterAuthentication([NotNull] this IServiceCollection services, [NotNull] IConfiguration config) + { + return services.ConfigureTwitterAuthentication(config, optionsName: ""); + } + + public static IServiceCollection ConfigureTwitterAuthentication([NotNull] this IServiceCollection services, [NotNull] IConfiguration config, string optionsName) + { + return services.Configure(config, optionsName); } } } From 1bd605da5e136482cf38283e31c21208130d1d00 Mon Sep 17 00:00:00 2001 From: "N. Taylor Mullen" Date: Sun, 8 Mar 2015 12:56:09 -0700 Subject: [PATCH 149/216] Update aspnet50/aspnetcore50 => dnx451/dnxcore50. --- samples/CookieSample/project.json | 6 +++--- samples/CookieSessionSample/project.json | 6 +++--- samples/OpenIdConnectSample/project.json | 4 ++-- samples/SocialSample/project.json | 6 +++--- src/Microsoft.AspNet.Authentication.Cookies/project.json | 6 +++--- src/Microsoft.AspNet.Authentication.Facebook/project.json | 6 +++--- src/Microsoft.AspNet.Authentication.Google/project.json | 6 +++--- .../project.json | 6 +++--- .../OAuthAuthenticationMiddleware.cs | 2 +- .../OAuthAuthenticationOptions.cs | 2 +- src/Microsoft.AspNet.Authentication.OAuth/project.json | 6 +++--- .../OAuthBearerAuthenticationMiddleware.cs | 2 +- .../OAuthBearerAuthenticationOptions.cs | 4 ++-- .../project.json | 6 +++--- .../OpenIdConnectAuthenticationMiddleware.cs | 2 +- .../OpenIdConnectAuthenticationOptions.cs | 2 +- .../project.json | 8 ++++---- .../TwitterAuthenticationMiddleware.cs | 4 ++-- .../TwitterAuthenticationOptions.cs | 6 +++--- src/Microsoft.AspNet.Authentication.Twitter/project.json | 6 +++--- .../CertificateSubjectKeyIdentifierValidator.cs | 4 ++-- .../CertificateSubjectPublicKeyInfoValidator.cs | 4 ++-- .../CertificateThumbprintValidator.cs | 4 ++-- .../ICertificateValidator.cs | 4 ++-- src/Microsoft.AspNet.Authentication/project.json | 6 +++--- src/Microsoft.AspNet.Authorization/project.json | 6 +++--- test/Microsoft.AspNet.Authentication.Test/project.json | 4 ++-- test/Microsoft.AspNet.Authorization.Test/project.json | 4 ++-- 28 files changed, 66 insertions(+), 66 deletions(-) diff --git a/samples/CookieSample/project.json b/samples/CookieSample/project.json index 4840de91a..ed54e27de 100644 --- a/samples/CookieSample/project.json +++ b/samples/CookieSample/project.json @@ -1,4 +1,4 @@ -{ +{ "dependencies": { "Microsoft.AspNet.Authentication.Cookies": "1.0.0-*", "Microsoft.AspNet.Server.WebListener": "1.0.0-*", @@ -10,9 +10,9 @@ "kestrel": "Microsoft.AspNet.Hosting --server Kestrel --server.urls http://localhost:5004" }, "frameworks": { - "aspnet50": { + "dnx451": { }, - "aspnetcore50": { + "dnxcore50": { } }, "webroot":"wwwroot" diff --git a/samples/CookieSessionSample/project.json b/samples/CookieSessionSample/project.json index 18401fb77..afc5e604b 100644 --- a/samples/CookieSessionSample/project.json +++ b/samples/CookieSessionSample/project.json @@ -1,4 +1,4 @@ -{ +{ "dependencies": { "Microsoft.AspNet.Authentication.Cookies": "1.0.0-*", "Microsoft.AspNet.Server.WebListener": "1.0.0-*", @@ -11,8 +11,8 @@ "kestrel": "Microsoft.AspNet.Hosting --server Kestrel --server.urls http://localhost:5004" }, "frameworks": { - "aspnet50": { }, - "aspnetcore50": { } + "dnx451": { }, + "dnxcore50": { } }, "webroot": "wwwroot" } diff --git a/samples/OpenIdConnectSample/project.json b/samples/OpenIdConnectSample/project.json index 382c6b169..dce6a6bb9 100644 --- a/samples/OpenIdConnectSample/project.json +++ b/samples/OpenIdConnectSample/project.json @@ -7,8 +7,8 @@ "Microsoft.AspNet.Server.WebListener": "1.0.0-*" }, "frameworks": { - "aspnet50": { }, - "aspnetcore50": { } + "dnx451": { }, + "dnxcore50": { } }, "commands": { "web": "Microsoft.AspNet.Hosting server=Microsoft.AspNet.Server.WebListener server.urls=http://localhost:12345", diff --git a/samples/SocialSample/project.json b/samples/SocialSample/project.json index d925cf66b..bb20bba57 100644 --- a/samples/SocialSample/project.json +++ b/samples/SocialSample/project.json @@ -1,4 +1,4 @@ -{ +{ "dependencies": { "Microsoft.AspNet.Diagnostics": "1.0.0-*", "Microsoft.AspNet.Authentication.Cookies": "1.0.0-*", @@ -16,9 +16,9 @@ "kestrel": "Microsoft.AspNet.Hosting --server Kestrel --server.urls http://localhost:54540" }, "frameworks": { - "aspnet50": { + "dnx451": { }, - "aspnetcore50": { + "dnxcore50": { } }, "webroot": "wwwroot" diff --git a/src/Microsoft.AspNet.Authentication.Cookies/project.json b/src/Microsoft.AspNet.Authentication.Cookies/project.json index 07d23fdca..331cfd3ea 100644 --- a/src/Microsoft.AspNet.Authentication.Cookies/project.json +++ b/src/Microsoft.AspNet.Authentication.Cookies/project.json @@ -1,4 +1,4 @@ -{ +{ "version": "1.0.0-*", "description": "ASP.NET middleware that enables an application to use cookie based authentication, similar to ASP.NET's forms authentication.", "dependencies": { @@ -6,7 +6,7 @@ "Newtonsoft.Json": "6.0.6" }, "frameworks": { - "aspnet50": { }, - "aspnetcore50": { } + "dnx451": { }, + "dnxcore50": { } } } diff --git a/src/Microsoft.AspNet.Authentication.Facebook/project.json b/src/Microsoft.AspNet.Authentication.Facebook/project.json index fd1a44d15..f810be04e 100644 --- a/src/Microsoft.AspNet.Authentication.Facebook/project.json +++ b/src/Microsoft.AspNet.Authentication.Facebook/project.json @@ -1,11 +1,11 @@ -{ +{ "version": "1.0.0-*", "description": "ASP.NET 5 middleware that enables an application to support Facebook's OAuth 2.0 authentication workflow.", "dependencies": { "Microsoft.AspNet.Authentication.OAuth": "1.0.0-*" }, "frameworks": { - "aspnet50": { }, - "aspnetcore50": { } + "dnx451": { }, + "dnxcore50": { } } } diff --git a/src/Microsoft.AspNet.Authentication.Google/project.json b/src/Microsoft.AspNet.Authentication.Google/project.json index cdaa62882..71b987de9 100644 --- a/src/Microsoft.AspNet.Authentication.Google/project.json +++ b/src/Microsoft.AspNet.Authentication.Google/project.json @@ -1,11 +1,11 @@ -{ +{ "version": "1.0.0-*", "description": "ASP.NET 5 contains middlewares to support Google's OpenId and OAuth 2.0 authentication workflows.", "dependencies": { "Microsoft.AspNet.Authentication.OAuth": "1.0.0-*" }, "frameworks": { - "aspnet50": { }, - "aspnetcore50": { } + "dnx451": { }, + "dnxcore50": { } } } diff --git a/src/Microsoft.AspNet.Authentication.MicrosoftAccount/project.json b/src/Microsoft.AspNet.Authentication.MicrosoftAccount/project.json index 5aa85f926..878a7137a 100644 --- a/src/Microsoft.AspNet.Authentication.MicrosoftAccount/project.json +++ b/src/Microsoft.AspNet.Authentication.MicrosoftAccount/project.json @@ -1,12 +1,12 @@ -{ +{ "version": "1.0.0-*", "description": "ASP.NET 5 middleware that enables an application to support the Microsoft Account authentication workflow.", "dependencies": { "Microsoft.AspNet.Authentication.OAuth": "1.0.0-*" }, "frameworks": { - "aspnet50": { }, - "aspnetcore50": { + "dnx451": { }, + "dnxcore50": { "dependencies": { "System.Dynamic.Runtime": "4.0.10-beta-*", "System.ObjectModel": "4.0.10-beta-*" diff --git a/src/Microsoft.AspNet.Authentication.OAuth/OAuthAuthenticationMiddleware.cs b/src/Microsoft.AspNet.Authentication.OAuth/OAuthAuthenticationMiddleware.cs index 8f937575f..0d272bf1e 100644 --- a/src/Microsoft.AspNet.Authentication.OAuth/OAuthAuthenticationMiddleware.cs +++ b/src/Microsoft.AspNet.Authentication.OAuth/OAuthAuthenticationMiddleware.cs @@ -107,7 +107,7 @@ protected override AuthenticationHandler CreateHandler() private static HttpMessageHandler ResolveHttpMessageHandler(OAuthAuthenticationOptions options) { HttpMessageHandler handler = options.BackchannelHttpHandler ?? -#if ASPNET50 +#if DNX451 new WebRequestHandler(); // If they provided a validator, apply it or fail. if (options.BackchannelCertificateValidator != null) diff --git a/src/Microsoft.AspNet.Authentication.OAuth/OAuthAuthenticationOptions.cs b/src/Microsoft.AspNet.Authentication.OAuth/OAuthAuthenticationOptions.cs index 7a910e059..3dda28812 100644 --- a/src/Microsoft.AspNet.Authentication.OAuth/OAuthAuthenticationOptions.cs +++ b/src/Microsoft.AspNet.Authentication.OAuth/OAuthAuthenticationOptions.cs @@ -51,7 +51,7 @@ public OAuthAuthenticationOptions() /// public string UserInformationEndpoint { get; set; } -#if ASPNET50 +#if DNX451 /// /// Gets or sets the a pinned certificate validator to use to validate the endpoints used /// in back channel communications belong to the auth provider. diff --git a/src/Microsoft.AspNet.Authentication.OAuth/project.json b/src/Microsoft.AspNet.Authentication.OAuth/project.json index ea68b78fa..6b52f84f7 100644 --- a/src/Microsoft.AspNet.Authentication.OAuth/project.json +++ b/src/Microsoft.AspNet.Authentication.OAuth/project.json @@ -1,4 +1,4 @@ -{ +{ "version": "1.0.0-*", "description": "ASP.NET 5 middleware that enables an application to support any standard OAuth 2.0 authentication workflow.", "dependencies": { @@ -6,13 +6,13 @@ "Microsoft.AspNet.Authentication": "1.0.0-*" }, "frameworks": { - "aspnet50": { + "dnx451": { "frameworkAssemblies": { "System.Net.Http.WebRequest": "", "System.Net.Http": "" } }, - "aspnetcore50": { + "dnxcore50": { "dependencies": { "System.Net.Http.WinHttpHandler": "4.0.0-beta-*" } diff --git a/src/Microsoft.AspNet.Authentication.OAuthBearer/OAuthBearerAuthenticationMiddleware.cs b/src/Microsoft.AspNet.Authentication.OAuthBearer/OAuthBearerAuthenticationMiddleware.cs index 8698bf740..4083af239 100644 --- a/src/Microsoft.AspNet.Authentication.OAuthBearer/OAuthBearerAuthenticationMiddleware.cs +++ b/src/Microsoft.AspNet.Authentication.OAuthBearer/OAuthBearerAuthenticationMiddleware.cs @@ -93,7 +93,7 @@ protected override AuthenticationHandler Creat private static HttpMessageHandler ResolveHttpMessageHandler(OAuthBearerAuthenticationOptions options) { HttpMessageHandler handler = options.BackchannelHttpHandler ?? -#if ASPNET50 +#if DNX451 new WebRequestHandler(); // If they provided a validator, apply it or fail. if (options.BackchannelCertificateValidator != null) diff --git a/src/Microsoft.AspNet.Authentication.OAuthBearer/OAuthBearerAuthenticationOptions.cs b/src/Microsoft.AspNet.Authentication.OAuthBearer/OAuthBearerAuthenticationOptions.cs index 64935c384..ab0b83300 100644 --- a/src/Microsoft.AspNet.Authentication.OAuthBearer/OAuthBearerAuthenticationOptions.cs +++ b/src/Microsoft.AspNet.Authentication.OAuthBearer/OAuthBearerAuthenticationOptions.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; @@ -75,7 +75,7 @@ public OAuthBearerAuthenticationOptions() : base() /// public TimeSpan BackchannelTimeout { get; set; } -#if ASPNET50 +#if DNX451 /// /// Gets or sets the a pinned certificate validator to use to validate the endpoints used /// when retrieving metadata. diff --git a/src/Microsoft.AspNet.Authentication.OAuthBearer/project.json b/src/Microsoft.AspNet.Authentication.OAuthBearer/project.json index a6143df77..d2912f83e 100644 --- a/src/Microsoft.AspNet.Authentication.OAuthBearer/project.json +++ b/src/Microsoft.AspNet.Authentication.OAuthBearer/project.json @@ -1,4 +1,4 @@ -{ +{ "version": "1.0.0-*", "description": "ASP.NET 5 middleware that enables an application to receive a OAuth bearer token.", "dependencies": { @@ -7,13 +7,13 @@ "System.IdentityModel.Tokens": "5.0.0-beta1-*" }, "frameworks": { - "aspnet50": { + "dnx451": { "frameworkAssemblies": { "System.Net.Http.WebRequest": "", "System.Net.Http": "" } }, - "aspnetcore50": { + "dnxcore50": { "dependencies": { "System.Net.Http.WinHttpHandler": "4.0.0-beta-*" } diff --git a/src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenIdConnectAuthenticationMiddleware.cs b/src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenIdConnectAuthenticationMiddleware.cs index 2a802ce10..c316c8583 100644 --- a/src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenIdConnectAuthenticationMiddleware.cs +++ b/src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenIdConnectAuthenticationMiddleware.cs @@ -139,7 +139,7 @@ protected override AuthenticationHandler Cre private static HttpMessageHandler ResolveHttpMessageHandler(OpenIdConnectAuthenticationOptions options) { HttpMessageHandler handler = options.BackchannelHttpHandler ?? -#if ASPNET50 +#if DNX451 new WebRequestHandler(); // If they provided a validator, apply it or fail. if (options.BackchannelCertificateValidator != null) diff --git a/src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenIdConnectAuthenticationOptions.cs b/src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenIdConnectAuthenticationOptions.cs index d88501086..25b70473a 100644 --- a/src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenIdConnectAuthenticationOptions.cs +++ b/src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenIdConnectAuthenticationOptions.cs @@ -78,7 +78,7 @@ public OpenIdConnectAuthenticationOptions(string authenticationScheme) /// If the IdentityProvider does not post to this address, you may end up in a 401 -> IdentityProvider -> Client -> 401 -> ... public PathString CallbackPath { get; set; } -#if ASPNET50 +#if DNX451 /// /// Gets or sets the a pinned certificate validator to use to validate the endpoints used /// when retrieving metadata. diff --git a/src/Microsoft.AspNet.Authentication.OpenIdConnect/project.json b/src/Microsoft.AspNet.Authentication.OpenIdConnect/project.json index c25baafc3..b677e4642 100644 --- a/src/Microsoft.AspNet.Authentication.OpenIdConnect/project.json +++ b/src/Microsoft.AspNet.Authentication.OpenIdConnect/project.json @@ -1,21 +1,21 @@ -{ +{ "version": "1.0.0-*", "dependencies": { "Microsoft.AspNet.Authentication": "1.0.0-*", "Microsoft.IdentityModel.Protocol.Extensions": "2.0.0-beta1-*" }, "frameworks": { - "aspnet50": { + "dnx451": { "frameworkAssemblies": { "System.Net.Http": "", "System.Net.Http.WebRequest": "" } }, - "aspnetcore50": { + "dnxcore50": { "dependencies": { "System.Collections.Specialized": "4.0.0-beta-*", "System.Net.Http.WinHttpHandler": "4.0.0-beta-*" } } } -} \ No newline at end of file +} diff --git a/src/Microsoft.AspNet.Authentication.Twitter/TwitterAuthenticationMiddleware.cs b/src/Microsoft.AspNet.Authentication.Twitter/TwitterAuthenticationMiddleware.cs index 2efdaff96..4ffedd992 100644 --- a/src/Microsoft.AspNet.Authentication.Twitter/TwitterAuthenticationMiddleware.cs +++ b/src/Microsoft.AspNet.Authentication.Twitter/TwitterAuthenticationMiddleware.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; @@ -97,7 +97,7 @@ protected override AuthenticationHandler CreateHan private static HttpMessageHandler ResolveHttpMessageHandler(TwitterAuthenticationOptions options) { HttpMessageHandler handler = options.BackchannelHttpHandler ?? -#if ASPNET50 +#if DNX451 new WebRequestHandler(); // If they provided a validator, apply it or fail. if (options.BackchannelCertificateValidator != null) diff --git a/src/Microsoft.AspNet.Authentication.Twitter/TwitterAuthenticationOptions.cs b/src/Microsoft.AspNet.Authentication.Twitter/TwitterAuthenticationOptions.cs index 30e78f276..d17daa0e9 100644 --- a/src/Microsoft.AspNet.Authentication.Twitter/TwitterAuthenticationOptions.cs +++ b/src/Microsoft.AspNet.Authentication.Twitter/TwitterAuthenticationOptions.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; @@ -22,7 +22,7 @@ public TwitterAuthenticationOptions() Caption = AuthenticationScheme; CallbackPath = new PathString("/signin-twitter"); BackchannelTimeout = TimeSpan.FromSeconds(60); -#if ASPNET50 +#if DNX451 // Twitter lists its valid Subject Key Identifiers at https://dev.twitter.com/docs/security/using-ssl BackchannelCertificateValidator = new CertificateSubjectKeyIdentifierValidator( new[] @@ -53,7 +53,7 @@ public TwitterAuthenticationOptions() /// The back channel timeout. /// public TimeSpan BackchannelTimeout { get; set; } -#if ASPNET50 +#if DNX451 /// /// Gets or sets the a pinned certificate validator to use to validate the endpoints used /// in back channel communications belong to Twitter. diff --git a/src/Microsoft.AspNet.Authentication.Twitter/project.json b/src/Microsoft.AspNet.Authentication.Twitter/project.json index 059a8d257..b8649b613 100644 --- a/src/Microsoft.AspNet.Authentication.Twitter/project.json +++ b/src/Microsoft.AspNet.Authentication.Twitter/project.json @@ -1,17 +1,17 @@ -{ +{ "version": "1.0.0-*", "description": "ASP.NET 5 middleware that enables an application to support Twitter's OAuth 2.0 authentication workflow.", "dependencies": { "Microsoft.AspNet.Authentication": "1.0.0-*" }, "frameworks": { - "aspnet50": { + "dnx451": { "frameworkAssemblies": { "System.Net.Http.WebRequest": "", "System.Net.Http": "" } }, - "aspnetcore50": { + "dnxcore50": { "dependencies": { "System.Net.Http.WinHttpHandler": "4.0.0-beta-*" } diff --git a/src/Microsoft.AspNet.Authentication/CertificateSubjectKeyIdentifierValidator.cs b/src/Microsoft.AspNet.Authentication/CertificateSubjectKeyIdentifierValidator.cs index ca729b68f..efd71f9b1 100644 --- a/src/Microsoft.AspNet.Authentication/CertificateSubjectKeyIdentifierValidator.cs +++ b/src/Microsoft.AspNet.Authentication/CertificateSubjectKeyIdentifierValidator.cs @@ -1,7 +1,7 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -#if ASPNET50 +#if DNX451 using System; using System.Collections.Generic; using System.Net.Security; diff --git a/src/Microsoft.AspNet.Authentication/CertificateSubjectPublicKeyInfoValidator.cs b/src/Microsoft.AspNet.Authentication/CertificateSubjectPublicKeyInfoValidator.cs index f2e5e9554..fdfb0155c 100644 --- a/src/Microsoft.AspNet.Authentication/CertificateSubjectPublicKeyInfoValidator.cs +++ b/src/Microsoft.AspNet.Authentication/CertificateSubjectPublicKeyInfoValidator.cs @@ -1,7 +1,7 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -#if ASPNET50 +#if DNX451 using System; using System.Collections.Generic; using System.ComponentModel; diff --git a/src/Microsoft.AspNet.Authentication/CertificateThumbprintValidator.cs b/src/Microsoft.AspNet.Authentication/CertificateThumbprintValidator.cs index 822b42014..44019b491 100644 --- a/src/Microsoft.AspNet.Authentication/CertificateThumbprintValidator.cs +++ b/src/Microsoft.AspNet.Authentication/CertificateThumbprintValidator.cs @@ -1,7 +1,7 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -#if ASPNET50 +#if DNX451 using System; using System.Collections.Generic; using System.Net.Security; diff --git a/src/Microsoft.AspNet.Authentication/ICertificateValidator.cs b/src/Microsoft.AspNet.Authentication/ICertificateValidator.cs index fd20f70b3..6cb2c4d6d 100644 --- a/src/Microsoft.AspNet.Authentication/ICertificateValidator.cs +++ b/src/Microsoft.AspNet.Authentication/ICertificateValidator.cs @@ -1,7 +1,7 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -#if ASPNET50 +#if DNX451 using System; using System.Net.Security; using System.Security.Cryptography.X509Certificates; diff --git a/src/Microsoft.AspNet.Authentication/project.json b/src/Microsoft.AspNet.Authentication/project.json index 62d223318..1cbfa5d84 100644 --- a/src/Microsoft.AspNet.Authentication/project.json +++ b/src/Microsoft.AspNet.Authentication/project.json @@ -1,4 +1,4 @@ -{ +{ "version": "1.0.0-*", "description": "ASP.NET 5 common types used by the various authentication middleware.", "dependencies": { @@ -9,7 +9,7 @@ "Microsoft.Framework.Logging": "1.0.0-*" }, "frameworks": { - "aspnet50": { }, - "aspnetcore50": { } + "dnx451": { }, + "dnxcore50": { } } } diff --git a/src/Microsoft.AspNet.Authorization/project.json b/src/Microsoft.AspNet.Authorization/project.json index 978885f8e..b2038584d 100644 --- a/src/Microsoft.AspNet.Authorization/project.json +++ b/src/Microsoft.AspNet.Authorization/project.json @@ -1,4 +1,4 @@ -{ +{ "version": "1.0.0-*", "description": "ASP.NET 5 authorization classes.", "dependencies": { @@ -7,7 +7,7 @@ "Microsoft.Framework.OptionsModel": "1.0.0-*" }, "frameworks": { - "aspnet50": { }, - "aspnetcore50": { } + "dnx451": { }, + "dnxcore50": { } } } diff --git a/test/Microsoft.AspNet.Authentication.Test/project.json b/test/Microsoft.AspNet.Authentication.Test/project.json index 7d2a50c88..1090cbc73 100644 --- a/test/Microsoft.AspNet.Authentication.Test/project.json +++ b/test/Microsoft.AspNet.Authentication.Test/project.json @@ -1,4 +1,4 @@ -{ +{ "compilationOptions": { "warningsAsErrors": true }, @@ -18,7 +18,7 @@ "test": "xunit.runner.kre" }, "frameworks": { - "aspnet50": { + "dnx451": { "dependencies": { "Shouldly": "1.1.1.1" } diff --git a/test/Microsoft.AspNet.Authorization.Test/project.json b/test/Microsoft.AspNet.Authorization.Test/project.json index 3fe88159d..c072be964 100644 --- a/test/Microsoft.AspNet.Authorization.Test/project.json +++ b/test/Microsoft.AspNet.Authorization.Test/project.json @@ -1,4 +1,4 @@ -{ +{ "compilationOptions": { "warningsAsErrors": true }, @@ -12,7 +12,7 @@ "test": "xunit.runner.kre" }, "frameworks": { - "aspnet50": { + "dnx451": { "dependencies": { "Shouldly": "1.1.1.1" } From dcaa51507f6b9dba9d10145027df04e3f3b1f84e Mon Sep 17 00:00:00 2001 From: "N. Taylor Mullen" Date: Sun, 8 Mar 2015 12:56:13 -0700 Subject: [PATCH 150/216] Update K_BUILD_VERSION/kre/KRE/.k => DNX_BUILD_VERSION/dnx/DNX/.dnx. --- build.cmd | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build.cmd b/build.cmd index 86ca5bbbf..49ba0692d 100644 --- a/build.cmd +++ b/build.cmd @@ -1,4 +1,4 @@ -@echo off +@echo off cd %~dp0 SETLOCAL @@ -19,7 +19,7 @@ IF EXIST packages\KoreBuild goto run .nuget\NuGet.exe install KoreBuild -ExcludeVersion -o packages -nocache -pre .nuget\NuGet.exe install Sake -version 0.2 -o packages -ExcludeVersion -IF "%SKIP_KRE_INSTALL%"=="1" goto run +IF "%SKIP_DNX_INSTALL%"=="1" goto run CALL packages\KoreBuild\build\kvm upgrade -runtime CLR -x86 CALL packages\KoreBuild\build\kvm install default -runtime CoreCLR -x86 From 56e3319e31364522d336028e9f6c1b366f5519cf Mon Sep 17 00:00:00 2001 From: "N. Taylor Mullen" Date: Sun, 8 Mar 2015 12:56:17 -0700 Subject: [PATCH 151/216] Update kvm/KVM/Kvm => dnvm/DNVM/Dnvm. --- build.cmd | 6 +++--- build.sh | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/build.cmd b/build.cmd index 49ba0692d..77be0a662 100644 --- a/build.cmd +++ b/build.cmd @@ -20,9 +20,9 @@ IF EXIST packages\KoreBuild goto run .nuget\NuGet.exe install Sake -version 0.2 -o packages -ExcludeVersion IF "%SKIP_DNX_INSTALL%"=="1" goto run -CALL packages\KoreBuild\build\kvm upgrade -runtime CLR -x86 -CALL packages\KoreBuild\build\kvm install default -runtime CoreCLR -x86 +CALL packages\KoreBuild\build\dnvm upgrade -runtime CLR -x86 +CALL packages\KoreBuild\build\dnvm install default -runtime CoreCLR -x86 :run -CALL packages\KoreBuild\build\kvm use default -runtime CLR -x86 +CALL packages\KoreBuild\build\dnvm use default -runtime CLR -x86 packages\Sake\tools\Sake.exe -I packages\KoreBuild\build -f makefile.shade %* diff --git a/build.sh b/build.sh index c7873ef58..74cb3421e 100644 --- a/build.sh +++ b/build.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/bin/bash if test `uname` = Darwin; then cachedir=~/Library/Caches/KBuild @@ -28,11 +28,11 @@ if test ! -d packages/KoreBuild; then fi if ! type k > /dev/null 2>&1; then - source packages/KoreBuild/build/kvm.sh + source packages/KoreBuild/build/dnvm.sh fi if ! type k > /dev/null 2>&1; then - kvm upgrade + dnvm upgrade fi mono packages/Sake/tools/Sake.exe -I packages/KoreBuild/build -f makefile.shade "$@" From fb5bfb43a90a0a19857fa3c63056d404ded4a581 Mon Sep 17 00:00:00 2001 From: "N. Taylor Mullen" Date: Sun, 8 Mar 2015 12:56:17 -0700 Subject: [PATCH 152/216] Update build.sh to use dnvm correctly. --- build.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/build.sh b/build.sh index 74cb3421e..a9ce06d08 100644 --- a/build.sh +++ b/build.sh @@ -27,7 +27,7 @@ if test ! -d packages/KoreBuild; then mono .nuget/nuget.exe install Sake -version 0.2 -o packages -ExcludeVersion fi -if ! type k > /dev/null 2>&1; then +if ! type dnvm > /dev/null 2>&1; then source packages/KoreBuild/build/dnvm.sh fi @@ -36,3 +36,4 @@ if ! type k > /dev/null 2>&1; then fi mono packages/Sake/tools/Sake.exe -I packages/KoreBuild/build -f makefile.shade "$@" + From 08fdd7ad30702491e3ecafa2d2e553323defbc08 Mon Sep 17 00:00:00 2001 From: "N. Taylor Mullen" Date: Mon, 9 Mar 2015 12:59:01 -0700 Subject: [PATCH 153/216] Remove BOM from project.json, *.cmd, *.sh and *.shade files. --- build.cmd | 2 +- build.sh | 2 +- samples/CookieSample/project.json | 2 +- samples/CookieSessionSample/project.json | 2 +- samples/OpenIdConnectSample/project.json | 2 +- samples/SocialSample/project.json | 2 +- src/Microsoft.AspNet.Authentication.Cookies/project.json | 2 +- src/Microsoft.AspNet.Authentication.Facebook/project.json | 2 +- src/Microsoft.AspNet.Authentication.Google/project.json | 2 +- .../project.json | 2 +- src/Microsoft.AspNet.Authentication.OAuth/project.json | 2 +- src/Microsoft.AspNet.Authentication.OAuthBearer/project.json | 2 +- src/Microsoft.AspNet.Authentication.OpenIdConnect/project.json | 2 +- src/Microsoft.AspNet.Authentication.Twitter/project.json | 2 +- src/Microsoft.AspNet.Authentication/project.json | 2 +- src/Microsoft.AspNet.Authorization/project.json | 2 +- test/Microsoft.AspNet.Authentication.Test/project.json | 2 +- test/Microsoft.AspNet.Authorization.Test/project.json | 2 +- 18 files changed, 18 insertions(+), 18 deletions(-) diff --git a/build.cmd b/build.cmd index 77be0a662..68a732c18 100644 --- a/build.cmd +++ b/build.cmd @@ -1,4 +1,4 @@ -@echo off +@echo off cd %~dp0 SETLOCAL diff --git a/build.sh b/build.sh index a9ce06d08..ec3263114 100644 --- a/build.sh +++ b/build.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/bin/bash if test `uname` = Darwin; then cachedir=~/Library/Caches/KBuild diff --git a/samples/CookieSample/project.json b/samples/CookieSample/project.json index ed54e27de..eea2a4c7e 100644 --- a/samples/CookieSample/project.json +++ b/samples/CookieSample/project.json @@ -1,4 +1,4 @@ -{ +{ "dependencies": { "Microsoft.AspNet.Authentication.Cookies": "1.0.0-*", "Microsoft.AspNet.Server.WebListener": "1.0.0-*", diff --git a/samples/CookieSessionSample/project.json b/samples/CookieSessionSample/project.json index afc5e604b..d2ffa0bcc 100644 --- a/samples/CookieSessionSample/project.json +++ b/samples/CookieSessionSample/project.json @@ -1,4 +1,4 @@ -{ +{ "dependencies": { "Microsoft.AspNet.Authentication.Cookies": "1.0.0-*", "Microsoft.AspNet.Server.WebListener": "1.0.0-*", diff --git a/samples/OpenIdConnectSample/project.json b/samples/OpenIdConnectSample/project.json index dce6a6bb9..e6e8d6a7b 100644 --- a/samples/OpenIdConnectSample/project.json +++ b/samples/OpenIdConnectSample/project.json @@ -1,4 +1,4 @@ -{ +{ "dependencies": { "Kestrel": "1.0.0-*", "Microsoft.AspNet.Authentication.Cookies": "1.0.0-*", diff --git a/samples/SocialSample/project.json b/samples/SocialSample/project.json index bb20bba57..30905d0b3 100644 --- a/samples/SocialSample/project.json +++ b/samples/SocialSample/project.json @@ -1,4 +1,4 @@ -{ +{ "dependencies": { "Microsoft.AspNet.Diagnostics": "1.0.0-*", "Microsoft.AspNet.Authentication.Cookies": "1.0.0-*", diff --git a/src/Microsoft.AspNet.Authentication.Cookies/project.json b/src/Microsoft.AspNet.Authentication.Cookies/project.json index 331cfd3ea..92bf3d84e 100644 --- a/src/Microsoft.AspNet.Authentication.Cookies/project.json +++ b/src/Microsoft.AspNet.Authentication.Cookies/project.json @@ -1,4 +1,4 @@ -{ +{ "version": "1.0.0-*", "description": "ASP.NET middleware that enables an application to use cookie based authentication, similar to ASP.NET's forms authentication.", "dependencies": { diff --git a/src/Microsoft.AspNet.Authentication.Facebook/project.json b/src/Microsoft.AspNet.Authentication.Facebook/project.json index f810be04e..2e24f747b 100644 --- a/src/Microsoft.AspNet.Authentication.Facebook/project.json +++ b/src/Microsoft.AspNet.Authentication.Facebook/project.json @@ -1,4 +1,4 @@ -{ +{ "version": "1.0.0-*", "description": "ASP.NET 5 middleware that enables an application to support Facebook's OAuth 2.0 authentication workflow.", "dependencies": { diff --git a/src/Microsoft.AspNet.Authentication.Google/project.json b/src/Microsoft.AspNet.Authentication.Google/project.json index 71b987de9..37f9e1b2d 100644 --- a/src/Microsoft.AspNet.Authentication.Google/project.json +++ b/src/Microsoft.AspNet.Authentication.Google/project.json @@ -1,4 +1,4 @@ -{ +{ "version": "1.0.0-*", "description": "ASP.NET 5 contains middlewares to support Google's OpenId and OAuth 2.0 authentication workflows.", "dependencies": { diff --git a/src/Microsoft.AspNet.Authentication.MicrosoftAccount/project.json b/src/Microsoft.AspNet.Authentication.MicrosoftAccount/project.json index 878a7137a..7b17282de 100644 --- a/src/Microsoft.AspNet.Authentication.MicrosoftAccount/project.json +++ b/src/Microsoft.AspNet.Authentication.MicrosoftAccount/project.json @@ -1,4 +1,4 @@ -{ +{ "version": "1.0.0-*", "description": "ASP.NET 5 middleware that enables an application to support the Microsoft Account authentication workflow.", "dependencies": { diff --git a/src/Microsoft.AspNet.Authentication.OAuth/project.json b/src/Microsoft.AspNet.Authentication.OAuth/project.json index 6b52f84f7..2d4145986 100644 --- a/src/Microsoft.AspNet.Authentication.OAuth/project.json +++ b/src/Microsoft.AspNet.Authentication.OAuth/project.json @@ -1,4 +1,4 @@ -{ +{ "version": "1.0.0-*", "description": "ASP.NET 5 middleware that enables an application to support any standard OAuth 2.0 authentication workflow.", "dependencies": { diff --git a/src/Microsoft.AspNet.Authentication.OAuthBearer/project.json b/src/Microsoft.AspNet.Authentication.OAuthBearer/project.json index d2912f83e..53c18f636 100644 --- a/src/Microsoft.AspNet.Authentication.OAuthBearer/project.json +++ b/src/Microsoft.AspNet.Authentication.OAuthBearer/project.json @@ -1,4 +1,4 @@ -{ +{ "version": "1.0.0-*", "description": "ASP.NET 5 middleware that enables an application to receive a OAuth bearer token.", "dependencies": { diff --git a/src/Microsoft.AspNet.Authentication.OpenIdConnect/project.json b/src/Microsoft.AspNet.Authentication.OpenIdConnect/project.json index b677e4642..9a24c6db4 100644 --- a/src/Microsoft.AspNet.Authentication.OpenIdConnect/project.json +++ b/src/Microsoft.AspNet.Authentication.OpenIdConnect/project.json @@ -1,4 +1,4 @@ -{ +{ "version": "1.0.0-*", "dependencies": { "Microsoft.AspNet.Authentication": "1.0.0-*", diff --git a/src/Microsoft.AspNet.Authentication.Twitter/project.json b/src/Microsoft.AspNet.Authentication.Twitter/project.json index b8649b613..79ddb1b8b 100644 --- a/src/Microsoft.AspNet.Authentication.Twitter/project.json +++ b/src/Microsoft.AspNet.Authentication.Twitter/project.json @@ -1,4 +1,4 @@ -{ +{ "version": "1.0.0-*", "description": "ASP.NET 5 middleware that enables an application to support Twitter's OAuth 2.0 authentication workflow.", "dependencies": { diff --git a/src/Microsoft.AspNet.Authentication/project.json b/src/Microsoft.AspNet.Authentication/project.json index 1cbfa5d84..255d92129 100644 --- a/src/Microsoft.AspNet.Authentication/project.json +++ b/src/Microsoft.AspNet.Authentication/project.json @@ -1,4 +1,4 @@ -{ +{ "version": "1.0.0-*", "description": "ASP.NET 5 common types used by the various authentication middleware.", "dependencies": { diff --git a/src/Microsoft.AspNet.Authorization/project.json b/src/Microsoft.AspNet.Authorization/project.json index b2038584d..ce146a3eb 100644 --- a/src/Microsoft.AspNet.Authorization/project.json +++ b/src/Microsoft.AspNet.Authorization/project.json @@ -1,4 +1,4 @@ -{ +{ "version": "1.0.0-*", "description": "ASP.NET 5 authorization classes.", "dependencies": { diff --git a/test/Microsoft.AspNet.Authentication.Test/project.json b/test/Microsoft.AspNet.Authentication.Test/project.json index 1090cbc73..0cf6401f1 100644 --- a/test/Microsoft.AspNet.Authentication.Test/project.json +++ b/test/Microsoft.AspNet.Authentication.Test/project.json @@ -1,4 +1,4 @@ -{ +{ "compilationOptions": { "warningsAsErrors": true }, diff --git a/test/Microsoft.AspNet.Authorization.Test/project.json b/test/Microsoft.AspNet.Authorization.Test/project.json index c072be964..4431189c7 100644 --- a/test/Microsoft.AspNet.Authorization.Test/project.json +++ b/test/Microsoft.AspNet.Authorization.Test/project.json @@ -1,4 +1,4 @@ -{ +{ "compilationOptions": { "warningsAsErrors": true }, From b7c8af8503831ba4becaa93b9453510b81c4d30e Mon Sep 17 00:00:00 2001 From: Praburaj Date: Fri, 6 Mar 2015 17:22:49 -0800 Subject: [PATCH 154/216] Reading AuthenticationProperties from SignOutContext This will enable users to set a specific redirect uri and call signout. --- .../OpenidConnectAuthenticationHandler.cs | 11 ++++----- .../OpenIdConnectMiddlewareTests.cs | 23 +++++++++++++++++-- 2 files changed, 26 insertions(+), 8 deletions(-) diff --git a/src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenidConnectAuthenticationHandler.cs b/src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenidConnectAuthenticationHandler.cs index 046232b9e..68e9bea24 100644 --- a/src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenidConnectAuthenticationHandler.cs +++ b/src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenidConnectAuthenticationHandler.cs @@ -8,10 +8,9 @@ using System.Linq; using System.Security.Claims; using System.Threading.Tasks; +using Microsoft.AspNet.Authentication.Notifications; using Microsoft.AspNet.Http; using Microsoft.AspNet.Http.Authentication; -using Microsoft.AspNet.Authentication; -using Microsoft.AspNet.Authentication.Notifications; using Microsoft.Framework.Logging; using Microsoft.IdentityModel.Protocols; @@ -77,8 +76,8 @@ protected override async Task ApplyResponseGrantAsync() // Set End_Session_Endpoint in order: // 1. properties.Redirect // 2. Options.Wreply - AuthenticationProperties properties = new AuthenticationProperties(); - if (properties != null && !string.IsNullOrEmpty(properties.RedirectUri)) + var properties = new AuthenticationProperties(signout.Properties); + if (!string.IsNullOrEmpty(properties.RedirectUri)) { openIdConnectMessage.PostLogoutRedirectUri = properties.RedirectUri; } @@ -220,7 +219,7 @@ protected override async Task AuthenticateCoreAsync() } OpenIdConnectMessage openIdConnectMessage = null; - + // assumption: if the ContentType is "application/x-www-form-urlencoded" it should be safe to read as it is small. if (string.Equals(Request.Method, "POST", StringComparison.OrdinalIgnoreCase) && !string.IsNullOrWhiteSpace(Request.ContentType) @@ -580,4 +579,4 @@ private async Task InvokeReplyPathAsync() return false; } } -} +} \ No newline at end of file diff --git a/test/Microsoft.AspNet.Authentication.Test/OpenIdConnect/OpenIdConnectMiddlewareTests.cs b/test/Microsoft.AspNet.Authentication.Test/OpenIdConnect/OpenIdConnectMiddlewareTests.cs index 96f17c86e..7681d5466 100644 --- a/test/Microsoft.AspNet.Authentication.Test/OpenIdConnect/OpenIdConnectMiddlewareTests.cs +++ b/test/Microsoft.AspNet.Authentication.Test/OpenIdConnect/OpenIdConnectMiddlewareTests.cs @@ -125,7 +125,6 @@ public async Task ChallengeWillUseNotifications() [Fact] public async Task SignOutWithDefaultRedirectUri() { - ISecureDataFormat stateFormat = new PropertiesDataFormat(new EphemeralDataProtectionProvider().CreateProtector("GoogleTest")); var server = CreateServer(options => { options.Authority = "https://login.windows.net/common"; @@ -140,7 +139,6 @@ public async Task SignOutWithDefaultRedirectUri() [Fact] public async Task SignOutWithCustomRedirectUri() { - ISecureDataFormat stateFormat = new PropertiesDataFormat(new EphemeralDataProtectionProvider().CreateProtector("GoogleTest")); var server = CreateServer(options => { options.Authority = "https://login.windows.net/common"; @@ -153,6 +151,21 @@ public async Task SignOutWithCustomRedirectUri() transaction.Response.Headers.Location.AbsoluteUri.ShouldContain(Uri.EscapeDataString("https://example.com/logout")); } + [Fact] + public async Task SignOutWith_Specific_RedirectUri_From_Authentication_Properites() + { + var server = CreateServer(options => + { + options.Authority = "https://login.windows.net/common"; + options.ClientId = "Test Id"; + options.PostLogoutRedirectUri = "https://example.com/logout"; + }); + + var transaction = await SendAsync(server, "https://example.com/signout_with_specific_redirect_uri"); + transaction.Response.StatusCode.ShouldBe(HttpStatusCode.Redirect); + transaction.Response.Headers.Location.AbsoluteUri.ShouldContain(Uri.EscapeDataString("http://www.example.com/specific_redirect_uri")); + } + [Fact] // Test Cases for calculating the expiration time of cookie from cookie name public void NonceCookieExpirationTime() @@ -212,6 +225,12 @@ private static TestServer CreateServer(Action Date: Tue, 10 Mar 2015 11:42:03 -0700 Subject: [PATCH 155/216] Renaming Nuget.org feed key name to Nuget. fixes https://github.com/aspnet/Universe/issues/174 --- NuGet.Config | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/NuGet.Config b/NuGet.Config index f41e9c631..da57d4726 100644 --- a/NuGet.Config +++ b/NuGet.Config @@ -2,6 +2,6 @@ - + - + \ No newline at end of file From 78406b411c37422f4d42593d4ddd12dab8a70d53 Mon Sep 17 00:00:00 2001 From: Hao Kung Date: Wed, 11 Mar 2015 11:43:48 -0700 Subject: [PATCH 156/216] Remove config from AddAuthorization --- .../ServiceCollectionExtensions.cs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/Microsoft.AspNet.Authorization/ServiceCollectionExtensions.cs b/src/Microsoft.AspNet.Authorization/ServiceCollectionExtensions.cs index 292083120..0fd1b1bb8 100644 --- a/src/Microsoft.AspNet.Authorization/ServiceCollectionExtensions.cs +++ b/src/Microsoft.AspNet.Authorization/ServiceCollectionExtensions.cs @@ -19,19 +19,19 @@ public static IServiceCollection ConfigureAuthorization([NotNull] this IServiceC return services.Configure(configure); } - // Review: Need UseDefaultSubkey parameter? - public static IServiceCollection AddAuthorization([NotNull] this IServiceCollection services, IConfiguration config = null, Action configureOptions = null) + public static IServiceCollection AddAuthorization([NotNull] this IServiceCollection services) + { + return services.AddAuthorization(configureOptions: null); + } + + public static IServiceCollection AddAuthorization([NotNull] this IServiceCollection services, Action configureOptions) { services.AddOptions(); services.TryAdd(ServiceDescriptor.Transient()); services.AddTransient(); services.AddTransient(); services.AddTransient(); - if (configureOptions != null) - { - services.Configure(configureOptions); - } return services; } } -} +} \ No newline at end of file From f8c526c12dd5d90576a3c5fbb97ffa152c361474 Mon Sep 17 00:00:00 2001 From: "N. Taylor Mullen" Date: Wed, 11 Mar 2015 14:04:40 -0700 Subject: [PATCH 157/216] Update .kproj => .xproj. --- Security.sln | 32 +++++++++---------- ...{CookieSample.kproj => CookieSample.xproj} | 0 ...Sample.kproj => CookieSessionSample.xproj} | 0 ...Sample.kproj => OpenIdConnectSample.xproj} | 0 ...{SocialSample.kproj => SocialSample.xproj} | 0 ...osoft.AspNet.Authentication.Cookies.xproj} | 0 ...soft.AspNet.Authentication.Facebook.xproj} | 0 ...rosoft.AspNet.Authentication.Google.xproj} | 0 ...Net.Authentication.MicrosoftAccount.xproj} | 0 ...crosoft.AspNet.Authentication.OAuth.xproj} | 0 ...t.AspNet.Authentication.OAuthBearer.xproj} | 0 ...AspNet.Authentication.OpenIdConnect.xproj} | 0 ...osoft.AspNet.Authentication.Twitter.xproj} | 0 ... => Microsoft.AspNet.Authentication.xproj} | 0 ...j => Microsoft.AspNet.Authorization.xproj} | 0 ...crosoft.AspNet.Authentication.Tests.xproj} | 0 ...icrosoft.AspNet.Authorization.Tests.xproj} | 0 17 files changed, 16 insertions(+), 16 deletions(-) rename samples/CookieSample/{CookieSample.kproj => CookieSample.xproj} (100%) rename samples/CookieSessionSample/{CookieSessionSample.kproj => CookieSessionSample.xproj} (100%) rename samples/OpenIdConnectSample/{OpenIdConnectSample.kproj => OpenIdConnectSample.xproj} (100%) rename samples/SocialSample/{SocialSample.kproj => SocialSample.xproj} (100%) rename src/Microsoft.AspNet.Authentication.Cookies/{Microsoft.AspNet.Authentication.Cookies.kproj => Microsoft.AspNet.Authentication.Cookies.xproj} (100%) rename src/Microsoft.AspNet.Authentication.Facebook/{Microsoft.AspNet.Authentication.Facebook.kproj => Microsoft.AspNet.Authentication.Facebook.xproj} (100%) rename src/Microsoft.AspNet.Authentication.Google/{Microsoft.AspNet.Authentication.Google.kproj => Microsoft.AspNet.Authentication.Google.xproj} (100%) rename src/Microsoft.AspNet.Authentication.MicrosoftAccount/{Microsoft.AspNet.Authentication.MicrosoftAccount.kproj => Microsoft.AspNet.Authentication.MicrosoftAccount.xproj} (100%) rename src/Microsoft.AspNet.Authentication.OAuth/{Microsoft.AspNet.Authentication.OAuth.kproj => Microsoft.AspNet.Authentication.OAuth.xproj} (100%) rename src/Microsoft.AspNet.Authentication.OAuthBearer/{Microsoft.AspNet.Authentication.OAuthBearer.kproj => Microsoft.AspNet.Authentication.OAuthBearer.xproj} (100%) rename src/Microsoft.AspNet.Authentication.OpenIdConnect/{Microsoft.AspNet.Authentication.OpenIdConnect.kproj => Microsoft.AspNet.Authentication.OpenIdConnect.xproj} (100%) rename src/Microsoft.AspNet.Authentication.Twitter/{Microsoft.AspNet.Authentication.Twitter.kproj => Microsoft.AspNet.Authentication.Twitter.xproj} (100%) rename src/Microsoft.AspNet.Authentication/{Microsoft.AspNet.Authentication.kproj => Microsoft.AspNet.Authentication.xproj} (100%) rename src/Microsoft.AspNet.Authorization/{Microsoft.AspNet.Authorization.kproj => Microsoft.AspNet.Authorization.xproj} (100%) rename test/Microsoft.AspNet.Authentication.Test/{Microsoft.AspNet.Authentication.Tests.kproj => Microsoft.AspNet.Authentication.Tests.xproj} (100%) rename test/Microsoft.AspNet.Authorization.Test/{Microsoft.AspNet.Authorization.Tests.kproj => Microsoft.AspNet.Authorization.Tests.xproj} (100%) diff --git a/Security.sln b/Security.sln index 7fb0467af..2d3fccf4e 100644 --- a/Security.sln +++ b/Security.sln @@ -7,7 +7,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{4D2B6A51-2F9 EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "samples", "samples", "{F8C0AA27-F3FB-4286-8E4C-47EF86B539FF}" EndProject -Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "CookieSample", "samples\CookieSample\CookieSample.kproj", "{558C2C2A-AED8-49DE-BB60-D5F8AE06C714}" +Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "CookieSample", "samples\CookieSample\CookieSample.xproj", "{558C2C2A-AED8-49DE-BB60-D5F8AE06C714}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{7BF11F3A-60B6-4796-B504-579C67FFBA34}" EndProject @@ -16,35 +16,35 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution global.json = global.json EndProjectSection EndProject -Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "SocialSample", "samples\SocialSample\SocialSample.kproj", "{8C73D216-332D-41D8-BFD0-45BC4BC36552}" +Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "SocialSample", "samples\SocialSample\SocialSample.xproj", "{8C73D216-332D-41D8-BFD0-45BC4BC36552}" EndProject -Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "CookieSessionSample", "samples\CookieSessionSample\CookieSessionSample.kproj", "{19711880-46DA-4A26-9E0F-9B2E41D27651}" +Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "CookieSessionSample", "samples\CookieSessionSample\CookieSessionSample.xproj", "{19711880-46DA-4A26-9E0F-9B2E41D27651}" EndProject -Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "OpenIdConnectSample", "samples\OpenIdConnectSample\OpenIdConnectSample.kproj", "{BEF0F5C3-EF4E-4649-9C49-D5E279A3CA2B}" +Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "OpenIdConnectSample", "samples\OpenIdConnectSample\OpenIdConnectSample.xproj", "{BEF0F5C3-EF4E-4649-9C49-D5E279A3CA2B}" EndProject -Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNet.Authentication.Cookies", "src\Microsoft.AspNet.Authentication.Cookies\Microsoft.AspNet.Authentication.Cookies.kproj", "{FC152CC4-054B-457E-8D91-389C5DE3C561}" +Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNet.Authentication.Cookies", "src\Microsoft.AspNet.Authentication.Cookies\Microsoft.AspNet.Authentication.Cookies.xproj", "{FC152CC4-054B-457E-8D91-389C5DE3C561}" EndProject -Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNet.Authentication", "src\Microsoft.AspNet.Authentication\Microsoft.AspNet.Authentication.kproj", "{2286250A-52C8-4126-9F93-B1E45F0AD078}" +Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNet.Authentication", "src\Microsoft.AspNet.Authentication\Microsoft.AspNet.Authentication.xproj", "{2286250A-52C8-4126-9F93-B1E45F0AD078}" EndProject -Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNet.Authentication.Facebook", "src\Microsoft.AspNet.Authentication.Facebook\Microsoft.AspNet.Authentication.Facebook.kproj", "{EEAAEE68-607B-4E33-AF3E-45C66B4DBA5A}" +Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNet.Authentication.Facebook", "src\Microsoft.AspNet.Authentication.Facebook\Microsoft.AspNet.Authentication.Facebook.xproj", "{EEAAEE68-607B-4E33-AF3E-45C66B4DBA5A}" EndProject -Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNet.Authentication.Google", "src\Microsoft.AspNet.Authentication.Google\Microsoft.AspNet.Authentication.Google.kproj", "{76579C39-B829-490D-B8BE-1BD35FE8412E}" +Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNet.Authentication.Google", "src\Microsoft.AspNet.Authentication.Google\Microsoft.AspNet.Authentication.Google.xproj", "{76579C39-B829-490D-B8BE-1BD35FE8412E}" EndProject -Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNet.Authentication.OpenIdConnect", "src\Microsoft.AspNet.Authentication.OpenIdConnect\Microsoft.AspNet.Authentication.OpenIdConnect.kproj", "{35115D55-B69E-46D4-BB33-C9E9E6EC5E7A}" +Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNet.Authentication.OpenIdConnect", "src\Microsoft.AspNet.Authentication.OpenIdConnect\Microsoft.AspNet.Authentication.OpenIdConnect.xproj", "{35115D55-B69E-46D4-BB33-C9E9E6EC5E7A}" EndProject -Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNet.Authentication.MicrosoftAccount", "src\Microsoft.AspNet.Authentication.MicrosoftAccount\Microsoft.AspNet.Authentication.MicrosoftAccount.kproj", "{ACB45E19-F520-4D0C-8916-B0CEB9C017FE}" +Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNet.Authentication.MicrosoftAccount", "src\Microsoft.AspNet.Authentication.MicrosoftAccount\Microsoft.AspNet.Authentication.MicrosoftAccount.xproj", "{ACB45E19-F520-4D0C-8916-B0CEB9C017FE}" EndProject -Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNet.Authentication.Twitter", "src\Microsoft.AspNet.Authentication.Twitter\Microsoft.AspNet.Authentication.Twitter.kproj", "{0330FFF6-B4B5-42DD-8C99-26A789569000}" +Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNet.Authentication.Twitter", "src\Microsoft.AspNet.Authentication.Twitter\Microsoft.AspNet.Authentication.Twitter.xproj", "{0330FFF6-B4B5-42DD-8C99-26A789569000}" EndProject -Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNet.Authentication.OAuth", "src\Microsoft.AspNet.Authentication.OAuth\Microsoft.AspNet.Authentication.OAuth.kproj", "{1657C79E-7755-4AEE-9D61-571295B69A30}" +Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNet.Authentication.OAuth", "src\Microsoft.AspNet.Authentication.OAuth\Microsoft.AspNet.Authentication.OAuth.xproj", "{1657C79E-7755-4AEE-9D61-571295B69A30}" EndProject -Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNet.Authentication.Tests", "test\Microsoft.AspNet.Authentication.Test\Microsoft.AspNet.Authentication.Tests.kproj", "{8DA26CD1-1302-4CFD-9270-9FA1B7C6138B}" +Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNet.Authentication.Tests", "test\Microsoft.AspNet.Authentication.Test\Microsoft.AspNet.Authentication.Tests.xproj", "{8DA26CD1-1302-4CFD-9270-9FA1B7C6138B}" EndProject -Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNet.Authentication.OAuthBearer", "src\Microsoft.AspNet.Authentication.OAuthBearer\Microsoft.AspNet.Authentication.OAuthBearer.kproj", "{2755BFE5-7421-4A31-A644-F817DF5CAA98}" +Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNet.Authentication.OAuthBearer", "src\Microsoft.AspNet.Authentication.OAuthBearer\Microsoft.AspNet.Authentication.OAuthBearer.xproj", "{2755BFE5-7421-4A31-A644-F817DF5CAA98}" EndProject -Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNet.Authorization.Tests", "test\Microsoft.AspNet.Authorization.Test\Microsoft.AspNet.Authorization.Tests.kproj", "{7AF5AD96-EB6E-4D0E-8ABE-C0B543C0F4C2}" +Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNet.Authorization.Tests", "test\Microsoft.AspNet.Authorization.Test\Microsoft.AspNet.Authorization.Tests.xproj", "{7AF5AD96-EB6E-4D0E-8ABE-C0B543C0F4C2}" EndProject -Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNet.Authorization", "src\Microsoft.AspNet.Authorization\Microsoft.AspNet.Authorization.kproj", "{6AB3E514-5894-4131-9399-DC7D5284ADDB}" +Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNet.Authorization", "src\Microsoft.AspNet.Authorization\Microsoft.AspNet.Authorization.xproj", "{6AB3E514-5894-4131-9399-DC7D5284ADDB}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution diff --git a/samples/CookieSample/CookieSample.kproj b/samples/CookieSample/CookieSample.xproj similarity index 100% rename from samples/CookieSample/CookieSample.kproj rename to samples/CookieSample/CookieSample.xproj diff --git a/samples/CookieSessionSample/CookieSessionSample.kproj b/samples/CookieSessionSample/CookieSessionSample.xproj similarity index 100% rename from samples/CookieSessionSample/CookieSessionSample.kproj rename to samples/CookieSessionSample/CookieSessionSample.xproj diff --git a/samples/OpenIdConnectSample/OpenIdConnectSample.kproj b/samples/OpenIdConnectSample/OpenIdConnectSample.xproj similarity index 100% rename from samples/OpenIdConnectSample/OpenIdConnectSample.kproj rename to samples/OpenIdConnectSample/OpenIdConnectSample.xproj diff --git a/samples/SocialSample/SocialSample.kproj b/samples/SocialSample/SocialSample.xproj similarity index 100% rename from samples/SocialSample/SocialSample.kproj rename to samples/SocialSample/SocialSample.xproj diff --git a/src/Microsoft.AspNet.Authentication.Cookies/Microsoft.AspNet.Authentication.Cookies.kproj b/src/Microsoft.AspNet.Authentication.Cookies/Microsoft.AspNet.Authentication.Cookies.xproj similarity index 100% rename from src/Microsoft.AspNet.Authentication.Cookies/Microsoft.AspNet.Authentication.Cookies.kproj rename to src/Microsoft.AspNet.Authentication.Cookies/Microsoft.AspNet.Authentication.Cookies.xproj diff --git a/src/Microsoft.AspNet.Authentication.Facebook/Microsoft.AspNet.Authentication.Facebook.kproj b/src/Microsoft.AspNet.Authentication.Facebook/Microsoft.AspNet.Authentication.Facebook.xproj similarity index 100% rename from src/Microsoft.AspNet.Authentication.Facebook/Microsoft.AspNet.Authentication.Facebook.kproj rename to src/Microsoft.AspNet.Authentication.Facebook/Microsoft.AspNet.Authentication.Facebook.xproj diff --git a/src/Microsoft.AspNet.Authentication.Google/Microsoft.AspNet.Authentication.Google.kproj b/src/Microsoft.AspNet.Authentication.Google/Microsoft.AspNet.Authentication.Google.xproj similarity index 100% rename from src/Microsoft.AspNet.Authentication.Google/Microsoft.AspNet.Authentication.Google.kproj rename to src/Microsoft.AspNet.Authentication.Google/Microsoft.AspNet.Authentication.Google.xproj diff --git a/src/Microsoft.AspNet.Authentication.MicrosoftAccount/Microsoft.AspNet.Authentication.MicrosoftAccount.kproj b/src/Microsoft.AspNet.Authentication.MicrosoftAccount/Microsoft.AspNet.Authentication.MicrosoftAccount.xproj similarity index 100% rename from src/Microsoft.AspNet.Authentication.MicrosoftAccount/Microsoft.AspNet.Authentication.MicrosoftAccount.kproj rename to src/Microsoft.AspNet.Authentication.MicrosoftAccount/Microsoft.AspNet.Authentication.MicrosoftAccount.xproj diff --git a/src/Microsoft.AspNet.Authentication.OAuth/Microsoft.AspNet.Authentication.OAuth.kproj b/src/Microsoft.AspNet.Authentication.OAuth/Microsoft.AspNet.Authentication.OAuth.xproj similarity index 100% rename from src/Microsoft.AspNet.Authentication.OAuth/Microsoft.AspNet.Authentication.OAuth.kproj rename to src/Microsoft.AspNet.Authentication.OAuth/Microsoft.AspNet.Authentication.OAuth.xproj diff --git a/src/Microsoft.AspNet.Authentication.OAuthBearer/Microsoft.AspNet.Authentication.OAuthBearer.kproj b/src/Microsoft.AspNet.Authentication.OAuthBearer/Microsoft.AspNet.Authentication.OAuthBearer.xproj similarity index 100% rename from src/Microsoft.AspNet.Authentication.OAuthBearer/Microsoft.AspNet.Authentication.OAuthBearer.kproj rename to src/Microsoft.AspNet.Authentication.OAuthBearer/Microsoft.AspNet.Authentication.OAuthBearer.xproj diff --git a/src/Microsoft.AspNet.Authentication.OpenIdConnect/Microsoft.AspNet.Authentication.OpenIdConnect.kproj b/src/Microsoft.AspNet.Authentication.OpenIdConnect/Microsoft.AspNet.Authentication.OpenIdConnect.xproj similarity index 100% rename from src/Microsoft.AspNet.Authentication.OpenIdConnect/Microsoft.AspNet.Authentication.OpenIdConnect.kproj rename to src/Microsoft.AspNet.Authentication.OpenIdConnect/Microsoft.AspNet.Authentication.OpenIdConnect.xproj diff --git a/src/Microsoft.AspNet.Authentication.Twitter/Microsoft.AspNet.Authentication.Twitter.kproj b/src/Microsoft.AspNet.Authentication.Twitter/Microsoft.AspNet.Authentication.Twitter.xproj similarity index 100% rename from src/Microsoft.AspNet.Authentication.Twitter/Microsoft.AspNet.Authentication.Twitter.kproj rename to src/Microsoft.AspNet.Authentication.Twitter/Microsoft.AspNet.Authentication.Twitter.xproj diff --git a/src/Microsoft.AspNet.Authentication/Microsoft.AspNet.Authentication.kproj b/src/Microsoft.AspNet.Authentication/Microsoft.AspNet.Authentication.xproj similarity index 100% rename from src/Microsoft.AspNet.Authentication/Microsoft.AspNet.Authentication.kproj rename to src/Microsoft.AspNet.Authentication/Microsoft.AspNet.Authentication.xproj diff --git a/src/Microsoft.AspNet.Authorization/Microsoft.AspNet.Authorization.kproj b/src/Microsoft.AspNet.Authorization/Microsoft.AspNet.Authorization.xproj similarity index 100% rename from src/Microsoft.AspNet.Authorization/Microsoft.AspNet.Authorization.kproj rename to src/Microsoft.AspNet.Authorization/Microsoft.AspNet.Authorization.xproj diff --git a/test/Microsoft.AspNet.Authentication.Test/Microsoft.AspNet.Authentication.Tests.kproj b/test/Microsoft.AspNet.Authentication.Test/Microsoft.AspNet.Authentication.Tests.xproj similarity index 100% rename from test/Microsoft.AspNet.Authentication.Test/Microsoft.AspNet.Authentication.Tests.kproj rename to test/Microsoft.AspNet.Authentication.Test/Microsoft.AspNet.Authentication.Tests.xproj diff --git a/test/Microsoft.AspNet.Authorization.Test/Microsoft.AspNet.Authorization.Tests.kproj b/test/Microsoft.AspNet.Authorization.Test/Microsoft.AspNet.Authorization.Tests.xproj similarity index 100% rename from test/Microsoft.AspNet.Authorization.Test/Microsoft.AspNet.Authorization.Tests.kproj rename to test/Microsoft.AspNet.Authorization.Test/Microsoft.AspNet.Authorization.Tests.xproj From 36de6b99a99c9236142978deff7e055e3c93d069 Mon Sep 17 00:00:00 2001 From: Doug Bunting Date: Wed, 11 Mar 2015 16:58:33 -0700 Subject: [PATCH 158/216] Do not use deprecated `dnvm -x86` switch --- build.cmd | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/build.cmd b/build.cmd index 68a732c18..41025afb2 100644 --- a/build.cmd +++ b/build.cmd @@ -20,9 +20,9 @@ IF EXIST packages\KoreBuild goto run .nuget\NuGet.exe install Sake -version 0.2 -o packages -ExcludeVersion IF "%SKIP_DNX_INSTALL%"=="1" goto run -CALL packages\KoreBuild\build\dnvm upgrade -runtime CLR -x86 -CALL packages\KoreBuild\build\dnvm install default -runtime CoreCLR -x86 +CALL packages\KoreBuild\build\dnvm upgrade -runtime CLR -arch x86 +CALL packages\KoreBuild\build\dnvm install default -runtime CoreCLR -arch x86 :run -CALL packages\KoreBuild\build\dnvm use default -runtime CLR -x86 +CALL packages\KoreBuild\build\dnvm use default -runtime CLR -arch x86 packages\Sake\tools\Sake.exe -I packages\KoreBuild\build -f makefile.shade %* From eb73ad64fdcbd7bb0ccd0ef8d313fab36942e0cb Mon Sep 17 00:00:00 2001 From: Praburaj Date: Wed, 11 Mar 2015 17:28:30 -0700 Subject: [PATCH 159/216] React to Caching package rename Dependent on https://github.com/aspnet/Caching/pull/49/files --- samples/CookieSessionSample/MemoryCacheSessionStore.cs | 2 +- samples/CookieSessionSample/project.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/samples/CookieSessionSample/MemoryCacheSessionStore.cs b/samples/CookieSessionSample/MemoryCacheSessionStore.cs index 4bb62d3ab..0ed51dfb2 100644 --- a/samples/CookieSessionSample/MemoryCacheSessionStore.cs +++ b/samples/CookieSessionSample/MemoryCacheSessionStore.cs @@ -2,7 +2,7 @@ using System.Threading.Tasks; using Microsoft.AspNet.Authentication; using Microsoft.AspNet.Authentication.Cookies.Infrastructure; -using Microsoft.Framework.Cache.Memory; +using Microsoft.Framework.Caching.Memory; namespace CookieSessionSample { diff --git a/samples/CookieSessionSample/project.json b/samples/CookieSessionSample/project.json index d2ffa0bcc..253079ceb 100644 --- a/samples/CookieSessionSample/project.json +++ b/samples/CookieSessionSample/project.json @@ -2,7 +2,7 @@ "dependencies": { "Microsoft.AspNet.Authentication.Cookies": "1.0.0-*", "Microsoft.AspNet.Server.WebListener": "1.0.0-*", - "Microsoft.Framework.Cache.Memory": "1.0.0-*", + "Microsoft.Framework.Caching.Memory": "1.0.0-*", "Kestrel": "1.0.0-*", "Microsoft.AspNet.Server.IIS": "1.0.0-*" }, From 42436d3a7e7f467ccee22d4c54a5ed884e7530e3 Mon Sep 17 00:00:00 2001 From: Brennan Date: Thu, 12 Mar 2015 16:18:52 -0700 Subject: [PATCH 160/216] Update xunit.runner.kre => xunit.runner.aspnet. --- test/Microsoft.AspNet.Authentication.Test/project.json | 4 ++-- test/Microsoft.AspNet.Authorization.Test/project.json | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/test/Microsoft.AspNet.Authentication.Test/project.json b/test/Microsoft.AspNet.Authentication.Test/project.json index 0cf6401f1..c19e99dbc 100644 --- a/test/Microsoft.AspNet.Authentication.Test/project.json +++ b/test/Microsoft.AspNet.Authentication.Test/project.json @@ -12,10 +12,10 @@ "Microsoft.AspNet.Authentication.Twitter": "1.0.0-*", "Microsoft.AspNet.TestHost": "1.0.0-*", "Moq": "4.2.1312.1622", - "xunit.runner.kre": "1.0.0-*" + "xunit.runner.aspnet": "2.0.0-aspnet-*" }, "commands": { - "test": "xunit.runner.kre" + "test": "xunit.runner.aspnet" }, "frameworks": { "dnx451": { diff --git a/test/Microsoft.AspNet.Authorization.Test/project.json b/test/Microsoft.AspNet.Authorization.Test/project.json index 4431189c7..11667dc4e 100644 --- a/test/Microsoft.AspNet.Authorization.Test/project.json +++ b/test/Microsoft.AspNet.Authorization.Test/project.json @@ -6,10 +6,10 @@ "Microsoft.AspNet.Authorization": "1.0.0-*", "Microsoft.Framework.DependencyInjection": "1.0.0-*", "Moq": "4.2.1312.1622", - "xunit.runner.kre": "1.0.0-*" + "xunit.runner.aspnet": "2.0.0-aspnet-*" }, "commands": { - "test": "xunit.runner.kre" + "test": "xunit.runner.aspnet" }, "frameworks": { "dnx451": { From c4aa387cd2d4da355eb71f49b673521d84f4042a Mon Sep 17 00:00:00 2001 From: Praburaj Date: Fri, 13 Mar 2015 14:47:28 -0700 Subject: [PATCH 161/216] Temporarily skipping a couple of tests to work around Url encoder bug https://github.com/aspnet/HttpAbstractions/issues/231 --- .../Google/GoogleMiddlewareTests.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/Microsoft.AspNet.Authentication.Test/Google/GoogleMiddlewareTests.cs b/test/Microsoft.AspNet.Authentication.Test/Google/GoogleMiddlewareTests.cs index 13876a0ae..4e02276be 100644 --- a/test/Microsoft.AspNet.Authentication.Test/Google/GoogleMiddlewareTests.cs +++ b/test/Microsoft.AspNet.Authentication.Test/Google/GoogleMiddlewareTests.cs @@ -77,7 +77,7 @@ public async Task ChallengeWillSetDefaultScope() query.ShouldContain("&scope=" + Uri.EscapeDataString("openid profile email")); } - [Fact] + [Fact(Skip = "Failing due to : https://github.com/aspnet/HttpAbstractions/issues/231")] public async Task ChallengeWillUseOptionsScope() { var server = CreateServer(options => @@ -92,7 +92,7 @@ public async Task ChallengeWillUseOptionsScope() query.ShouldContain("&scope=" + Uri.EscapeDataString("https://www.googleapis.com/auth/plus.login")); } - [Fact] + [Fact(Skip = "Failing due to : https://github.com/aspnet/HttpAbstractions/issues/231")] public async Task ChallengeWillUseAuthenticationPropertiesAsParameters() { var server = CreateServer(options => @@ -107,7 +107,7 @@ public async Task ChallengeWillUseAuthenticationPropertiesAsParameters() if (req.Path == new PathString("/challenge2")) { res.Challenge(new AuthenticationProperties( - new Dictionary() + new Dictionary() { { "scope", "https://www.googleapis.com/auth/plus.login" }, { "access_type", "offline" }, @@ -216,7 +216,7 @@ public async Task ReplyPathWillAuthenticateValidAuthorizeCodeAndState() properties.Dictionary.Add(correlationKey, correlationValue); properties.RedirectUri = "/me"; var state = stateFormat.Protect(properties); - var transaction = await SendAsync(server, + var transaction = await SendAsync(server, "https://example.com/signin-google?code=TestCode&state=" + Uri.EscapeDataString(state), correlationKey + "=" + correlationValue); transaction.Response.StatusCode.ShouldBe(HttpStatusCode.Redirect); From bd7f07052ec9d50f7712068979eed4814ee2a304 Mon Sep 17 00:00:00 2001 From: Praburaj Date: Sat, 14 Mar 2015 07:25:14 -0700 Subject: [PATCH 162/216] Using [NotNull] from the common package --- samples/CookieSample/CookieSample.xproj | 5 +++-- .../CookieSessionSample/CookieSessionSample.xproj | 5 +++-- samples/SocialSample/SocialSample.xproj | 5 +++-- .../CookieAppBuilderExtensions.cs | 1 + .../CookieAuthenticationHandler.cs | 1 + .../CookieServiceCollectionExtensions.cs | 2 +- .../Infrastructure/ChunkingCookieManager.cs | 1 + .../NotNullAttribute.cs | 12 ------------ .../Notifications/CookieValidateIdentityContext.cs | 1 + .../project.json | 3 ++- .../FacebookAppBuilderExtensions.cs | 1 + .../FacebookServiceCollectionExtensions.cs | 1 + .../NotNullAttribute.cs | 12 ------------ .../project.json | 3 ++- .../GoogleAppBuilderExtensions.cs | 1 + .../GoogleServiceCollectionExtensions.cs | 1 + .../NotNullAttribute.cs | 12 ------------ .../project.json | 3 ++- .../MicrosoftAccountAppBuilderExtensions.cs | 3 ++- .../MicrosoftAccountServiceCollectionExtensions.cs | 1 + .../NotNullAttribute.cs | 12 ------------ .../MicrosoftAccountAuthenticatedContext.cs | 4 ++-- .../project.json | 3 ++- .../NotNullAttribute.cs | 12 ------------ .../OAuthAuthenticationExtensions.cs | 3 +-- .../project.json | 3 ++- .../NotNullAttribute.cs | 12 ------------ .../OAuthBearerAppBuilderExtensions.cs | 1 + .../OAuthBearerServiceCollectionExtensions.cs | 1 + .../project.json | 1 + .../NotNullAttribute.cs | 12 ------------ .../OpenIdConnectServiceCollectionExtensions.cs | 1 + .../project.json | 1 + .../Messages/RequestTokenSerializer.cs | 4 ++-- .../NotNullAttribute.cs | 12 ------------ .../TwitterAppBuilderExtensions.cs | 1 + .../TwitterServiceCollectionExtensions.cs | 1 + .../project.json | 3 ++- .../AuthenticationHandler.cs | 1 + .../AuthenticationMiddleware.cs | 1 + .../AuthenticationTokenCreateContext.cs | 1 + .../AuthenticationTokenReceiveContext.cs | 1 + .../CertificateSubjectKeyIdentifierValidator.cs | 1 + .../CertificateSubjectPublicKeyInfoValidator.cs | 1 + .../CertificateThumbprintValidator.cs | 1 + .../DataHandler/Encoder/Base64UrlTextEncoder.cs | 1 + .../DataHandler/Serializer/PropertiesSerializer.cs | 1 + .../DataHandler/Serializer/TicketSerializer.cs | 1 + .../NotNullAttribute.cs | 12 ------------ .../SecurityHelper.cs | 1 + src/Microsoft.AspNet.Authentication/project.json | 3 ++- .../AuthorizationContext.cs | 1 + .../AuthorizationOptions.cs | 1 + .../AuthorizationPolicy.cs | 1 + .../AuthorizationPolicyBuilder.cs | 1 + .../AuthorizationServiceExtensions.cs | 1 + .../NotNullAttribute.cs | 12 ------------ .../ServiceCollectionExtensions.cs | 2 +- src/Microsoft.AspNet.Authorization/project.json | 1 + 59 files changed, 65 insertions(+), 142 deletions(-) delete mode 100644 src/Microsoft.AspNet.Authentication.Cookies/NotNullAttribute.cs delete mode 100644 src/Microsoft.AspNet.Authentication.Facebook/NotNullAttribute.cs delete mode 100644 src/Microsoft.AspNet.Authentication.Google/NotNullAttribute.cs delete mode 100644 src/Microsoft.AspNet.Authentication.MicrosoftAccount/NotNullAttribute.cs delete mode 100644 src/Microsoft.AspNet.Authentication.OAuth/NotNullAttribute.cs delete mode 100644 src/Microsoft.AspNet.Authentication.OAuthBearer/NotNullAttribute.cs delete mode 100644 src/Microsoft.AspNet.Authentication.OpenIdConnect/NotNullAttribute.cs delete mode 100644 src/Microsoft.AspNet.Authentication.Twitter/NotNullAttribute.cs delete mode 100644 src/Microsoft.AspNet.Authentication/NotNullAttribute.cs delete mode 100644 src/Microsoft.AspNet.Authorization/NotNullAttribute.cs diff --git a/samples/CookieSample/CookieSample.xproj b/samples/CookieSample/CookieSample.xproj index 0cc892155..68fbee01b 100644 --- a/samples/CookieSample/CookieSample.xproj +++ b/samples/CookieSample/CookieSample.xproj @@ -1,4 +1,4 @@ - + 14.0 @@ -12,6 +12,7 @@ 2.0 + 22569 - + \ No newline at end of file diff --git a/samples/CookieSessionSample/CookieSessionSample.xproj b/samples/CookieSessionSample/CookieSessionSample.xproj index 3dde446f7..121634187 100644 --- a/samples/CookieSessionSample/CookieSessionSample.xproj +++ b/samples/CookieSessionSample/CookieSessionSample.xproj @@ -1,4 +1,4 @@ - + 14.0 @@ -12,6 +12,7 @@ 2.0 + 22571 - + \ No newline at end of file diff --git a/samples/SocialSample/SocialSample.xproj b/samples/SocialSample/SocialSample.xproj index 640b2404b..ce1e69ddf 100644 --- a/samples/SocialSample/SocialSample.xproj +++ b/samples/SocialSample/SocialSample.xproj @@ -1,4 +1,4 @@ - + 14.0 @@ -12,6 +12,7 @@ 2.0 + 22570 - + \ No newline at end of file diff --git a/src/Microsoft.AspNet.Authentication.Cookies/CookieAppBuilderExtensions.cs b/src/Microsoft.AspNet.Authentication.Cookies/CookieAppBuilderExtensions.cs index 5a00ca234..3af76b243 100644 --- a/src/Microsoft.AspNet.Authentication.Cookies/CookieAppBuilderExtensions.cs +++ b/src/Microsoft.AspNet.Authentication.Cookies/CookieAppBuilderExtensions.cs @@ -3,6 +3,7 @@ using System; using Microsoft.AspNet.Authentication.Cookies; +using Microsoft.Framework.Internal; using Microsoft.Framework.OptionsModel; namespace Microsoft.AspNet.Builder diff --git a/src/Microsoft.AspNet.Authentication.Cookies/CookieAuthenticationHandler.cs b/src/Microsoft.AspNet.Authentication.Cookies/CookieAuthenticationHandler.cs index ae7e866fb..808a2691a 100644 --- a/src/Microsoft.AspNet.Authentication.Cookies/CookieAuthenticationHandler.cs +++ b/src/Microsoft.AspNet.Authentication.Cookies/CookieAuthenticationHandler.cs @@ -8,6 +8,7 @@ using System.Threading.Tasks; using Microsoft.AspNet.Http; using Microsoft.AspNet.Http.Authentication; +using Microsoft.Framework.Internal; using Microsoft.Framework.Logging; namespace Microsoft.AspNet.Authentication.Cookies diff --git a/src/Microsoft.AspNet.Authentication.Cookies/CookieServiceCollectionExtensions.cs b/src/Microsoft.AspNet.Authentication.Cookies/CookieServiceCollectionExtensions.cs index 03632b1a6..af6d4d377 100644 --- a/src/Microsoft.AspNet.Authentication.Cookies/CookieServiceCollectionExtensions.cs +++ b/src/Microsoft.AspNet.Authentication.Cookies/CookieServiceCollectionExtensions.cs @@ -4,7 +4,7 @@ using System; using Microsoft.AspNet.Authentication.Cookies; using Microsoft.Framework.ConfigurationModel; -using Microsoft.Framework.DependencyInjection; +using Microsoft.Framework.Internal; namespace Microsoft.Framework.DependencyInjection { diff --git a/src/Microsoft.AspNet.Authentication.Cookies/Infrastructure/ChunkingCookieManager.cs b/src/Microsoft.AspNet.Authentication.Cookies/Infrastructure/ChunkingCookieManager.cs index 1f953593b..40008e47b 100644 --- a/src/Microsoft.AspNet.Authentication.Cookies/Infrastructure/ChunkingCookieManager.cs +++ b/src/Microsoft.AspNet.Authentication.Cookies/Infrastructure/ChunkingCookieManager.cs @@ -6,6 +6,7 @@ using System.Globalization; using System.Linq; using Microsoft.AspNet.Http; +using Microsoft.Framework.Internal; namespace Microsoft.AspNet.Authentication.Cookies.Infrastructure { diff --git a/src/Microsoft.AspNet.Authentication.Cookies/NotNullAttribute.cs b/src/Microsoft.AspNet.Authentication.Cookies/NotNullAttribute.cs deleted file mode 100644 index 44c9fcbb2..000000000 --- a/src/Microsoft.AspNet.Authentication.Cookies/NotNullAttribute.cs +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System; - -namespace Microsoft.AspNet.Authentication.Cookies -{ - [AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false)] - internal sealed class NotNullAttribute : Attribute - { - } -} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Authentication.Cookies/Notifications/CookieValidateIdentityContext.cs b/src/Microsoft.AspNet.Authentication.Cookies/Notifications/CookieValidateIdentityContext.cs index 328d93d2b..f9574bf80 100644 --- a/src/Microsoft.AspNet.Authentication.Cookies/Notifications/CookieValidateIdentityContext.cs +++ b/src/Microsoft.AspNet.Authentication.Cookies/Notifications/CookieValidateIdentityContext.cs @@ -6,6 +6,7 @@ using Microsoft.AspNet.Http; using Microsoft.AspNet.Http.Authentication; using Microsoft.AspNet.Authentication.Notifications; +using Microsoft.Framework.Internal; namespace Microsoft.AspNet.Authentication.Cookies { diff --git a/src/Microsoft.AspNet.Authentication.Cookies/project.json b/src/Microsoft.AspNet.Authentication.Cookies/project.json index 92bf3d84e..c2377a44f 100644 --- a/src/Microsoft.AspNet.Authentication.Cookies/project.json +++ b/src/Microsoft.AspNet.Authentication.Cookies/project.json @@ -3,10 +3,11 @@ "description": "ASP.NET middleware that enables an application to use cookie based authentication, similar to ASP.NET's forms authentication.", "dependencies": { "Microsoft.AspNet.Authentication": "1.0.0-*", + "Microsoft.Framework.NotNullAttribute.Internal": { "type": "build", "version": "1.0.0-*" }, "Newtonsoft.Json": "6.0.6" }, "frameworks": { "dnx451": { }, "dnxcore50": { } } -} +} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Authentication.Facebook/FacebookAppBuilderExtensions.cs b/src/Microsoft.AspNet.Authentication.Facebook/FacebookAppBuilderExtensions.cs index c91855790..0758d43ac 100644 --- a/src/Microsoft.AspNet.Authentication.Facebook/FacebookAppBuilderExtensions.cs +++ b/src/Microsoft.AspNet.Authentication.Facebook/FacebookAppBuilderExtensions.cs @@ -3,6 +3,7 @@ using System; using Microsoft.AspNet.Authentication.Facebook; +using Microsoft.Framework.Internal; using Microsoft.Framework.OptionsModel; namespace Microsoft.AspNet.Builder diff --git a/src/Microsoft.AspNet.Authentication.Facebook/FacebookServiceCollectionExtensions.cs b/src/Microsoft.AspNet.Authentication.Facebook/FacebookServiceCollectionExtensions.cs index f6117a10b..26ab1c063 100644 --- a/src/Microsoft.AspNet.Authentication.Facebook/FacebookServiceCollectionExtensions.cs +++ b/src/Microsoft.AspNet.Authentication.Facebook/FacebookServiceCollectionExtensions.cs @@ -4,6 +4,7 @@ using System; using Microsoft.AspNet.Authentication.Facebook; using Microsoft.Framework.ConfigurationModel; +using Microsoft.Framework.Internal; namespace Microsoft.Framework.DependencyInjection { diff --git a/src/Microsoft.AspNet.Authentication.Facebook/NotNullAttribute.cs b/src/Microsoft.AspNet.Authentication.Facebook/NotNullAttribute.cs deleted file mode 100644 index 5ce6d99dd..000000000 --- a/src/Microsoft.AspNet.Authentication.Facebook/NotNullAttribute.cs +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System; - -namespace Microsoft.AspNet.Authentication.Facebook -{ - [AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false)] - internal sealed class NotNullAttribute : Attribute - { - } -} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Authentication.Facebook/project.json b/src/Microsoft.AspNet.Authentication.Facebook/project.json index 2e24f747b..0dab9e868 100644 --- a/src/Microsoft.AspNet.Authentication.Facebook/project.json +++ b/src/Microsoft.AspNet.Authentication.Facebook/project.json @@ -2,7 +2,8 @@ "version": "1.0.0-*", "description": "ASP.NET 5 middleware that enables an application to support Facebook's OAuth 2.0 authentication workflow.", "dependencies": { - "Microsoft.AspNet.Authentication.OAuth": "1.0.0-*" + "Microsoft.AspNet.Authentication.OAuth": "1.0.0-*", + "Microsoft.Framework.NotNullAttribute.Internal": { "type": "build", "version": "1.0.0-*" } }, "frameworks": { "dnx451": { }, diff --git a/src/Microsoft.AspNet.Authentication.Google/GoogleAppBuilderExtensions.cs b/src/Microsoft.AspNet.Authentication.Google/GoogleAppBuilderExtensions.cs index 8613d4368..dc73a1666 100644 --- a/src/Microsoft.AspNet.Authentication.Google/GoogleAppBuilderExtensions.cs +++ b/src/Microsoft.AspNet.Authentication.Google/GoogleAppBuilderExtensions.cs @@ -3,6 +3,7 @@ using System; using Microsoft.AspNet.Authentication.Google; +using Microsoft.Framework.Internal; using Microsoft.Framework.OptionsModel; namespace Microsoft.AspNet.Builder diff --git a/src/Microsoft.AspNet.Authentication.Google/GoogleServiceCollectionExtensions.cs b/src/Microsoft.AspNet.Authentication.Google/GoogleServiceCollectionExtensions.cs index 239dbea29..6928c48fc 100644 --- a/src/Microsoft.AspNet.Authentication.Google/GoogleServiceCollectionExtensions.cs +++ b/src/Microsoft.AspNet.Authentication.Google/GoogleServiceCollectionExtensions.cs @@ -4,6 +4,7 @@ using System; using Microsoft.AspNet.Authentication.Google; using Microsoft.Framework.ConfigurationModel; +using Microsoft.Framework.Internal; namespace Microsoft.Framework.DependencyInjection { diff --git a/src/Microsoft.AspNet.Authentication.Google/NotNullAttribute.cs b/src/Microsoft.AspNet.Authentication.Google/NotNullAttribute.cs deleted file mode 100644 index 504a02c4d..000000000 --- a/src/Microsoft.AspNet.Authentication.Google/NotNullAttribute.cs +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System; - -namespace Microsoft.AspNet.Authentication.Google -{ - [AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false)] - internal sealed class NotNullAttribute : Attribute - { - } -} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Authentication.Google/project.json b/src/Microsoft.AspNet.Authentication.Google/project.json index 37f9e1b2d..72beb690a 100644 --- a/src/Microsoft.AspNet.Authentication.Google/project.json +++ b/src/Microsoft.AspNet.Authentication.Google/project.json @@ -2,7 +2,8 @@ "version": "1.0.0-*", "description": "ASP.NET 5 contains middlewares to support Google's OpenId and OAuth 2.0 authentication workflows.", "dependencies": { - "Microsoft.AspNet.Authentication.OAuth": "1.0.0-*" + "Microsoft.AspNet.Authentication.OAuth": "1.0.0-*", + "Microsoft.Framework.NotNullAttribute.Internal": { "type": "build", "version": "1.0.0-*" } }, "frameworks": { "dnx451": { }, diff --git a/src/Microsoft.AspNet.Authentication.MicrosoftAccount/MicrosoftAccountAppBuilderExtensions.cs b/src/Microsoft.AspNet.Authentication.MicrosoftAccount/MicrosoftAccountAppBuilderExtensions.cs index e068b5f5a..a404845c8 100644 --- a/src/Microsoft.AspNet.Authentication.MicrosoftAccount/MicrosoftAccountAppBuilderExtensions.cs +++ b/src/Microsoft.AspNet.Authentication.MicrosoftAccount/MicrosoftAccountAppBuilderExtensions.cs @@ -1,9 +1,10 @@ // Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. +using System; using Microsoft.AspNet.Authentication.MicrosoftAccount; +using Microsoft.Framework.Internal; using Microsoft.Framework.OptionsModel; -using System; namespace Microsoft.AspNet.Builder { diff --git a/src/Microsoft.AspNet.Authentication.MicrosoftAccount/MicrosoftAccountServiceCollectionExtensions.cs b/src/Microsoft.AspNet.Authentication.MicrosoftAccount/MicrosoftAccountServiceCollectionExtensions.cs index 4fe4f1227..8f0de0755 100644 --- a/src/Microsoft.AspNet.Authentication.MicrosoftAccount/MicrosoftAccountServiceCollectionExtensions.cs +++ b/src/Microsoft.AspNet.Authentication.MicrosoftAccount/MicrosoftAccountServiceCollectionExtensions.cs @@ -4,6 +4,7 @@ using System; using Microsoft.AspNet.Authentication.MicrosoftAccount; using Microsoft.Framework.ConfigurationModel; +using Microsoft.Framework.Internal; namespace Microsoft.Framework.DependencyInjection { diff --git a/src/Microsoft.AspNet.Authentication.MicrosoftAccount/NotNullAttribute.cs b/src/Microsoft.AspNet.Authentication.MicrosoftAccount/NotNullAttribute.cs deleted file mode 100644 index f2afa991f..000000000 --- a/src/Microsoft.AspNet.Authentication.MicrosoftAccount/NotNullAttribute.cs +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System; - -namespace Microsoft.AspNet.Authentication.MicrosoftAccount -{ - [AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false)] - internal sealed class NotNullAttribute : Attribute - { - } -} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Authentication.MicrosoftAccount/Notifications/MicrosoftAccountAuthenticatedContext.cs b/src/Microsoft.AspNet.Authentication.MicrosoftAccount/Notifications/MicrosoftAccountAuthenticatedContext.cs index 50aea11a9..ed55b4de3 100644 --- a/src/Microsoft.AspNet.Authentication.MicrosoftAccount/Notifications/MicrosoftAccountAuthenticatedContext.cs +++ b/src/Microsoft.AspNet.Authentication.MicrosoftAccount/Notifications/MicrosoftAccountAuthenticatedContext.cs @@ -4,9 +4,9 @@ using System; using System.Collections.Generic; using System.Linq; -using System.Net.Http; -using Microsoft.AspNet.Http; using Microsoft.AspNet.Authentication.OAuth; +using Microsoft.AspNet.Http; +using Microsoft.Framework.Internal; using Newtonsoft.Json.Linq; namespace Microsoft.AspNet.Authentication.MicrosoftAccount diff --git a/src/Microsoft.AspNet.Authentication.MicrosoftAccount/project.json b/src/Microsoft.AspNet.Authentication.MicrosoftAccount/project.json index 7b17282de..6bd7bb375 100644 --- a/src/Microsoft.AspNet.Authentication.MicrosoftAccount/project.json +++ b/src/Microsoft.AspNet.Authentication.MicrosoftAccount/project.json @@ -2,7 +2,8 @@ "version": "1.0.0-*", "description": "ASP.NET 5 middleware that enables an application to support the Microsoft Account authentication workflow.", "dependencies": { - "Microsoft.AspNet.Authentication.OAuth": "1.0.0-*" + "Microsoft.AspNet.Authentication.OAuth": "1.0.0-*", + "Microsoft.Framework.NotNullAttribute.Internal": { "type": "build", "version": "1.0.0-*" } }, "frameworks": { "dnx451": { }, diff --git a/src/Microsoft.AspNet.Authentication.OAuth/NotNullAttribute.cs b/src/Microsoft.AspNet.Authentication.OAuth/NotNullAttribute.cs deleted file mode 100644 index 49f587eb5..000000000 --- a/src/Microsoft.AspNet.Authentication.OAuth/NotNullAttribute.cs +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System; - -namespace Microsoft.AspNet.Authentication.OAuth -{ - [AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false)] - internal sealed class NotNullAttribute : Attribute - { - } -} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Authentication.OAuth/OAuthAuthenticationExtensions.cs b/src/Microsoft.AspNet.Authentication.OAuth/OAuthAuthenticationExtensions.cs index 903f823e1..79e669d21 100644 --- a/src/Microsoft.AspNet.Authentication.OAuth/OAuthAuthenticationExtensions.cs +++ b/src/Microsoft.AspNet.Authentication.OAuth/OAuthAuthenticationExtensions.cs @@ -2,9 +2,8 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; -using System.Globalization; using Microsoft.AspNet.Authentication.OAuth; -using Microsoft.AspNet.Authentication; +using Microsoft.Framework.Internal; using Microsoft.Framework.OptionsModel; namespace Microsoft.AspNet.Builder diff --git a/src/Microsoft.AspNet.Authentication.OAuth/project.json b/src/Microsoft.AspNet.Authentication.OAuth/project.json index 2d4145986..ab9059a18 100644 --- a/src/Microsoft.AspNet.Authentication.OAuth/project.json +++ b/src/Microsoft.AspNet.Authentication.OAuth/project.json @@ -3,7 +3,8 @@ "description": "ASP.NET 5 middleware that enables an application to support any standard OAuth 2.0 authentication workflow.", "dependencies": { "Microsoft.AspNet.DataProtection": "1.0.0-*", - "Microsoft.AspNet.Authentication": "1.0.0-*" + "Microsoft.AspNet.Authentication": "1.0.0-*", + "Microsoft.Framework.NotNullAttribute.Internal": { "type": "build", "version": "1.0.0-*" } }, "frameworks": { "dnx451": { diff --git a/src/Microsoft.AspNet.Authentication.OAuthBearer/NotNullAttribute.cs b/src/Microsoft.AspNet.Authentication.OAuthBearer/NotNullAttribute.cs deleted file mode 100644 index 73b3e6c56..000000000 --- a/src/Microsoft.AspNet.Authentication.OAuthBearer/NotNullAttribute.cs +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System; - -namespace Microsoft.AspNet.Authentication.OAuthBearer -{ - [AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false)] - internal sealed class NotNullAttribute : Attribute - { - } -} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Authentication.OAuthBearer/OAuthBearerAppBuilderExtensions.cs b/src/Microsoft.AspNet.Authentication.OAuthBearer/OAuthBearerAppBuilderExtensions.cs index 88151eb16..06be46390 100644 --- a/src/Microsoft.AspNet.Authentication.OAuthBearer/OAuthBearerAppBuilderExtensions.cs +++ b/src/Microsoft.AspNet.Authentication.OAuthBearer/OAuthBearerAppBuilderExtensions.cs @@ -3,6 +3,7 @@ using System; using Microsoft.AspNet.Authentication.OAuthBearer; +using Microsoft.Framework.Internal; using Microsoft.Framework.OptionsModel; namespace Microsoft.AspNet.Builder diff --git a/src/Microsoft.AspNet.Authentication.OAuthBearer/OAuthBearerServiceCollectionExtensions.cs b/src/Microsoft.AspNet.Authentication.OAuthBearer/OAuthBearerServiceCollectionExtensions.cs index b195abff8..1b1bce814 100644 --- a/src/Microsoft.AspNet.Authentication.OAuthBearer/OAuthBearerServiceCollectionExtensions.cs +++ b/src/Microsoft.AspNet.Authentication.OAuthBearer/OAuthBearerServiceCollectionExtensions.cs @@ -4,6 +4,7 @@ using System; using Microsoft.AspNet.Authentication.OAuthBearer; using Microsoft.Framework.ConfigurationModel; +using Microsoft.Framework.Internal; namespace Microsoft.Framework.DependencyInjection { diff --git a/src/Microsoft.AspNet.Authentication.OAuthBearer/project.json b/src/Microsoft.AspNet.Authentication.OAuthBearer/project.json index 53c18f636..504d1eea1 100644 --- a/src/Microsoft.AspNet.Authentication.OAuthBearer/project.json +++ b/src/Microsoft.AspNet.Authentication.OAuthBearer/project.json @@ -3,6 +3,7 @@ "description": "ASP.NET 5 middleware that enables an application to receive a OAuth bearer token.", "dependencies": { "Microsoft.AspNet.Authentication": "1.0.0-*", + "Microsoft.Framework.NotNullAttribute.Internal": { "type": "build", "version": "1.0.0-*" }, "Microsoft.IdentityModel.Protocol.Extensions": "2.0.0-beta1-*", "System.IdentityModel.Tokens": "5.0.0-beta1-*" }, diff --git a/src/Microsoft.AspNet.Authentication.OpenIdConnect/NotNullAttribute.cs b/src/Microsoft.AspNet.Authentication.OpenIdConnect/NotNullAttribute.cs deleted file mode 100644 index 6453923f5..000000000 --- a/src/Microsoft.AspNet.Authentication.OpenIdConnect/NotNullAttribute.cs +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System; - -namespace Microsoft.AspNet.Authentication.OpenIdConnect -{ - [AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false)] - internal sealed class NotNullAttribute : Attribute - { - } -} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenIdConnectServiceCollectionExtensions.cs b/src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenIdConnectServiceCollectionExtensions.cs index eca491cd5..6f5544889 100644 --- a/src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenIdConnectServiceCollectionExtensions.cs +++ b/src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenIdConnectServiceCollectionExtensions.cs @@ -4,6 +4,7 @@ using System; using Microsoft.AspNet.Authentication.OpenIdConnect; using Microsoft.Framework.ConfigurationModel; +using Microsoft.Framework.Internal; namespace Microsoft.Framework.DependencyInjection { diff --git a/src/Microsoft.AspNet.Authentication.OpenIdConnect/project.json b/src/Microsoft.AspNet.Authentication.OpenIdConnect/project.json index 9a24c6db4..acf34b5c2 100644 --- a/src/Microsoft.AspNet.Authentication.OpenIdConnect/project.json +++ b/src/Microsoft.AspNet.Authentication.OpenIdConnect/project.json @@ -2,6 +2,7 @@ "version": "1.0.0-*", "dependencies": { "Microsoft.AspNet.Authentication": "1.0.0-*", + "Microsoft.Framework.NotNullAttribute.Internal": { "type": "build", "version": "1.0.0-*" }, "Microsoft.IdentityModel.Protocol.Extensions": "2.0.0-beta1-*" }, "frameworks": { diff --git a/src/Microsoft.AspNet.Authentication.Twitter/Messages/RequestTokenSerializer.cs b/src/Microsoft.AspNet.Authentication.Twitter/Messages/RequestTokenSerializer.cs index b575c70ee..6305f52bd 100644 --- a/src/Microsoft.AspNet.Authentication.Twitter/Messages/RequestTokenSerializer.cs +++ b/src/Microsoft.AspNet.Authentication.Twitter/Messages/RequestTokenSerializer.cs @@ -1,11 +1,11 @@ // Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -using System; using System.Diagnostics.CodeAnalysis; using System.IO; -using Microsoft.AspNet.Http.Authentication; using Microsoft.AspNet.Authentication.DataHandler.Serializer; +using Microsoft.AspNet.Http.Authentication; +using Microsoft.Framework.Internal; namespace Microsoft.AspNet.Authentication.Twitter.Messages { diff --git a/src/Microsoft.AspNet.Authentication.Twitter/NotNullAttribute.cs b/src/Microsoft.AspNet.Authentication.Twitter/NotNullAttribute.cs deleted file mode 100644 index c961a0c8f..000000000 --- a/src/Microsoft.AspNet.Authentication.Twitter/NotNullAttribute.cs +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System; - -namespace Microsoft.AspNet.Authentication.Twitter -{ - [AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false)] - internal sealed class NotNullAttribute : Attribute - { - } -} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Authentication.Twitter/TwitterAppBuilderExtensions.cs b/src/Microsoft.AspNet.Authentication.Twitter/TwitterAppBuilderExtensions.cs index ce27cdadf..e0d0e0cf7 100644 --- a/src/Microsoft.AspNet.Authentication.Twitter/TwitterAppBuilderExtensions.cs +++ b/src/Microsoft.AspNet.Authentication.Twitter/TwitterAppBuilderExtensions.cs @@ -3,6 +3,7 @@ using System; using Microsoft.AspNet.Authentication.Twitter; +using Microsoft.Framework.Internal; using Microsoft.Framework.OptionsModel; namespace Microsoft.AspNet.Builder diff --git a/src/Microsoft.AspNet.Authentication.Twitter/TwitterServiceCollectionExtensions.cs b/src/Microsoft.AspNet.Authentication.Twitter/TwitterServiceCollectionExtensions.cs index dad039952..f34d22945 100644 --- a/src/Microsoft.AspNet.Authentication.Twitter/TwitterServiceCollectionExtensions.cs +++ b/src/Microsoft.AspNet.Authentication.Twitter/TwitterServiceCollectionExtensions.cs @@ -4,6 +4,7 @@ using System; using Microsoft.AspNet.Authentication.Twitter; using Microsoft.Framework.ConfigurationModel; +using Microsoft.Framework.Internal; namespace Microsoft.Framework.DependencyInjection { diff --git a/src/Microsoft.AspNet.Authentication.Twitter/project.json b/src/Microsoft.AspNet.Authentication.Twitter/project.json index 79ddb1b8b..33d73fd1c 100644 --- a/src/Microsoft.AspNet.Authentication.Twitter/project.json +++ b/src/Microsoft.AspNet.Authentication.Twitter/project.json @@ -2,7 +2,8 @@ "version": "1.0.0-*", "description": "ASP.NET 5 middleware that enables an application to support Twitter's OAuth 2.0 authentication workflow.", "dependencies": { - "Microsoft.AspNet.Authentication": "1.0.0-*" + "Microsoft.AspNet.Authentication": "1.0.0-*", + "Microsoft.Framework.NotNullAttribute.Internal": { "type": "build", "version": "1.0.0-*" } }, "frameworks": { "dnx451": { diff --git a/src/Microsoft.AspNet.Authentication/AuthenticationHandler.cs b/src/Microsoft.AspNet.Authentication/AuthenticationHandler.cs index 0e768cf84..93d1ab629 100644 --- a/src/Microsoft.AspNet.Authentication/AuthenticationHandler.cs +++ b/src/Microsoft.AspNet.Authentication/AuthenticationHandler.cs @@ -10,6 +10,7 @@ using Microsoft.AspNet.Authentication.DataHandler.Encoder; using Microsoft.AspNet.Http; using Microsoft.AspNet.Http.Authentication; +using Microsoft.Framework.Internal; using Microsoft.Framework.Logging; namespace Microsoft.AspNet.Authentication diff --git a/src/Microsoft.AspNet.Authentication/AuthenticationMiddleware.cs b/src/Microsoft.AspNet.Authentication/AuthenticationMiddleware.cs index 400a6e74a..f78eeaa55 100644 --- a/src/Microsoft.AspNet.Authentication/AuthenticationMiddleware.cs +++ b/src/Microsoft.AspNet.Authentication/AuthenticationMiddleware.cs @@ -6,6 +6,7 @@ using Microsoft.AspNet.Builder; using Microsoft.AspNet.Http; using Microsoft.AspNet.RequestContainer; +using Microsoft.Framework.Internal; using Microsoft.Framework.OptionsModel; namespace Microsoft.AspNet.Authentication diff --git a/src/Microsoft.AspNet.Authentication/AuthenticationTokenCreateContext.cs b/src/Microsoft.AspNet.Authentication/AuthenticationTokenCreateContext.cs index eed3ac761..1045d477f 100644 --- a/src/Microsoft.AspNet.Authentication/AuthenticationTokenCreateContext.cs +++ b/src/Microsoft.AspNet.Authentication/AuthenticationTokenCreateContext.cs @@ -5,6 +5,7 @@ using System; using Microsoft.AspNet.Http; using Microsoft.AspNet.Authentication.Notifications; +using Microsoft.Framework.Internal; namespace Microsoft.AspNet.Authentication { diff --git a/src/Microsoft.AspNet.Authentication/AuthenticationTokenReceiveContext.cs b/src/Microsoft.AspNet.Authentication/AuthenticationTokenReceiveContext.cs index ea8e854ef..df309ca06 100644 --- a/src/Microsoft.AspNet.Authentication/AuthenticationTokenReceiveContext.cs +++ b/src/Microsoft.AspNet.Authentication/AuthenticationTokenReceiveContext.cs @@ -3,6 +3,7 @@ using Microsoft.AspNet.Http; using Microsoft.AspNet.Authentication.Notifications; +using Microsoft.Framework.Internal; namespace Microsoft.AspNet.Authentication { diff --git a/src/Microsoft.AspNet.Authentication/CertificateSubjectKeyIdentifierValidator.cs b/src/Microsoft.AspNet.Authentication/CertificateSubjectKeyIdentifierValidator.cs index efd71f9b1..5dd663ec7 100644 --- a/src/Microsoft.AspNet.Authentication/CertificateSubjectKeyIdentifierValidator.cs +++ b/src/Microsoft.AspNet.Authentication/CertificateSubjectKeyIdentifierValidator.cs @@ -6,6 +6,7 @@ using System.Collections.Generic; using System.Net.Security; using System.Security.Cryptography.X509Certificates; +using Microsoft.Framework.Internal; namespace Microsoft.AspNet.Authentication { diff --git a/src/Microsoft.AspNet.Authentication/CertificateSubjectPublicKeyInfoValidator.cs b/src/Microsoft.AspNet.Authentication/CertificateSubjectPublicKeyInfoValidator.cs index fdfb0155c..3c04ca9d8 100644 --- a/src/Microsoft.AspNet.Authentication/CertificateSubjectPublicKeyInfoValidator.cs +++ b/src/Microsoft.AspNet.Authentication/CertificateSubjectPublicKeyInfoValidator.cs @@ -10,6 +10,7 @@ using System.Runtime.InteropServices; using System.Security.Cryptography; using System.Security.Cryptography.X509Certificates; +using Microsoft.Framework.Internal; using Microsoft.Win32; namespace Microsoft.AspNet.Authentication diff --git a/src/Microsoft.AspNet.Authentication/CertificateThumbprintValidator.cs b/src/Microsoft.AspNet.Authentication/CertificateThumbprintValidator.cs index 44019b491..4392108f2 100644 --- a/src/Microsoft.AspNet.Authentication/CertificateThumbprintValidator.cs +++ b/src/Microsoft.AspNet.Authentication/CertificateThumbprintValidator.cs @@ -6,6 +6,7 @@ using System.Collections.Generic; using System.Net.Security; using System.Security.Cryptography.X509Certificates; +using Microsoft.Framework.Internal; namespace Microsoft.AspNet.Authentication { diff --git a/src/Microsoft.AspNet.Authentication/DataHandler/Encoder/Base64UrlTextEncoder.cs b/src/Microsoft.AspNet.Authentication/DataHandler/Encoder/Base64UrlTextEncoder.cs index 93dd1a057..41cb10abd 100644 --- a/src/Microsoft.AspNet.Authentication/DataHandler/Encoder/Base64UrlTextEncoder.cs +++ b/src/Microsoft.AspNet.Authentication/DataHandler/Encoder/Base64UrlTextEncoder.cs @@ -3,6 +3,7 @@ using System; +using Microsoft.Framework.Internal; namespace Microsoft.AspNet.Authentication.DataHandler.Encoder { diff --git a/src/Microsoft.AspNet.Authentication/DataHandler/Serializer/PropertiesSerializer.cs b/src/Microsoft.AspNet.Authentication/DataHandler/Serializer/PropertiesSerializer.cs index 836828cda..9b262e6c2 100644 --- a/src/Microsoft.AspNet.Authentication/DataHandler/Serializer/PropertiesSerializer.cs +++ b/src/Microsoft.AspNet.Authentication/DataHandler/Serializer/PropertiesSerializer.cs @@ -7,6 +7,7 @@ using System.Diagnostics.CodeAnalysis; using System.IO; using Microsoft.AspNet.Http.Authentication; +using Microsoft.Framework.Internal; namespace Microsoft.AspNet.Authentication.DataHandler.Serializer { diff --git a/src/Microsoft.AspNet.Authentication/DataHandler/Serializer/TicketSerializer.cs b/src/Microsoft.AspNet.Authentication/DataHandler/Serializer/TicketSerializer.cs index 9833dad54..40d80c28d 100644 --- a/src/Microsoft.AspNet.Authentication/DataHandler/Serializer/TicketSerializer.cs +++ b/src/Microsoft.AspNet.Authentication/DataHandler/Serializer/TicketSerializer.cs @@ -5,6 +5,7 @@ using System.IO; using System.Linq; using System.Security.Claims; +using Microsoft.Framework.Internal; namespace Microsoft.AspNet.Authentication.DataHandler.Serializer { diff --git a/src/Microsoft.AspNet.Authentication/NotNullAttribute.cs b/src/Microsoft.AspNet.Authentication/NotNullAttribute.cs deleted file mode 100644 index a30763317..000000000 --- a/src/Microsoft.AspNet.Authentication/NotNullAttribute.cs +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System; - -namespace Microsoft.AspNet.Authentication -{ - [AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false)] - internal sealed class NotNullAttribute : Attribute - { - } -} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Authentication/SecurityHelper.cs b/src/Microsoft.AspNet.Authentication/SecurityHelper.cs index 1e73888c6..cb1b1fe1c 100644 --- a/src/Microsoft.AspNet.Authentication/SecurityHelper.cs +++ b/src/Microsoft.AspNet.Authentication/SecurityHelper.cs @@ -6,6 +6,7 @@ using System.Linq; using System.Security.Claims; using Microsoft.AspNet.Http; +using Microsoft.Framework.Internal; namespace Microsoft.AspNet.Authentication { diff --git a/src/Microsoft.AspNet.Authentication/project.json b/src/Microsoft.AspNet.Authentication/project.json index 255d92129..609f641ad 100644 --- a/src/Microsoft.AspNet.Authentication/project.json +++ b/src/Microsoft.AspNet.Authentication/project.json @@ -6,7 +6,8 @@ "Microsoft.AspNet.RequestContainer": "1.0.0-*", "Microsoft.AspNet.Http.Interfaces": "1.0.0-*", "Microsoft.AspNet.Http.Core": "1.0.0-*", - "Microsoft.Framework.Logging": "1.0.0-*" + "Microsoft.Framework.Logging": "1.0.0-*", + "Microsoft.Framework.NotNullAttribute.Internal": { "type": "build", "version": "1.0.0-*" } }, "frameworks": { "dnx451": { }, diff --git a/src/Microsoft.AspNet.Authorization/AuthorizationContext.cs b/src/Microsoft.AspNet.Authorization/AuthorizationContext.cs index 4044b84f5..8b051fcdc 100644 --- a/src/Microsoft.AspNet.Authorization/AuthorizationContext.cs +++ b/src/Microsoft.AspNet.Authorization/AuthorizationContext.cs @@ -4,6 +4,7 @@ using System.Collections.Generic; using System.Linq; using System.Security.Claims; +using Microsoft.Framework.Internal; namespace Microsoft.AspNet.Authorization { diff --git a/src/Microsoft.AspNet.Authorization/AuthorizationOptions.cs b/src/Microsoft.AspNet.Authorization/AuthorizationOptions.cs index 708ed1abc..d23a0effe 100644 --- a/src/Microsoft.AspNet.Authorization/AuthorizationOptions.cs +++ b/src/Microsoft.AspNet.Authorization/AuthorizationOptions.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; +using Microsoft.Framework.Internal; namespace Microsoft.AspNet.Authorization { diff --git a/src/Microsoft.AspNet.Authorization/AuthorizationPolicy.cs b/src/Microsoft.AspNet.Authorization/AuthorizationPolicy.cs index ca9fcc203..2ade0a15f 100644 --- a/src/Microsoft.AspNet.Authorization/AuthorizationPolicy.cs +++ b/src/Microsoft.AspNet.Authorization/AuthorizationPolicy.cs @@ -4,6 +4,7 @@ using System; using System.Collections.Generic; using System.Linq; +using Microsoft.Framework.Internal; namespace Microsoft.AspNet.Authorization { diff --git a/src/Microsoft.AspNet.Authorization/AuthorizationPolicyBuilder.cs b/src/Microsoft.AspNet.Authorization/AuthorizationPolicyBuilder.cs index f2f24746c..976d997cc 100644 --- a/src/Microsoft.AspNet.Authorization/AuthorizationPolicyBuilder.cs +++ b/src/Microsoft.AspNet.Authorization/AuthorizationPolicyBuilder.cs @@ -4,6 +4,7 @@ using System.Collections.Generic; using System.Linq; using System.Security.Claims; +using Microsoft.Framework.Internal; namespace Microsoft.AspNet.Authorization { diff --git a/src/Microsoft.AspNet.Authorization/AuthorizationServiceExtensions.cs b/src/Microsoft.AspNet.Authorization/AuthorizationServiceExtensions.cs index 595d88077..03f112b73 100644 --- a/src/Microsoft.AspNet.Authorization/AuthorizationServiceExtensions.cs +++ b/src/Microsoft.AspNet.Authorization/AuthorizationServiceExtensions.cs @@ -4,6 +4,7 @@ using System.Linq; using System.Security.Claims; using System.Threading.Tasks; +using Microsoft.Framework.Internal; namespace Microsoft.AspNet.Authorization { diff --git a/src/Microsoft.AspNet.Authorization/NotNullAttribute.cs b/src/Microsoft.AspNet.Authorization/NotNullAttribute.cs deleted file mode 100644 index 64ea6d573..000000000 --- a/src/Microsoft.AspNet.Authorization/NotNullAttribute.cs +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System; - -namespace Microsoft.AspNet.Authorization -{ - [AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false)] - internal sealed class NotNullAttribute : Attribute - { - } -} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Authorization/ServiceCollectionExtensions.cs b/src/Microsoft.AspNet.Authorization/ServiceCollectionExtensions.cs index 0fd1b1bb8..e825684b3 100644 --- a/src/Microsoft.AspNet.Authorization/ServiceCollectionExtensions.cs +++ b/src/Microsoft.AspNet.Authorization/ServiceCollectionExtensions.cs @@ -3,7 +3,7 @@ using System; using Microsoft.AspNet.Authorization; -using Microsoft.Framework.ConfigurationModel; +using Microsoft.Framework.Internal; namespace Microsoft.Framework.DependencyInjection { diff --git a/src/Microsoft.AspNet.Authorization/project.json b/src/Microsoft.AspNet.Authorization/project.json index ce146a3eb..3a8701e86 100644 --- a/src/Microsoft.AspNet.Authorization/project.json +++ b/src/Microsoft.AspNet.Authorization/project.json @@ -4,6 +4,7 @@ "dependencies": { "Microsoft.AspNet.Http.Interfaces": "1.0.0-*", "Microsoft.Framework.Logging": "1.0.0-*", + "Microsoft.Framework.NotNullAttribute.Internal": { "type": "build", "version": "1.0.0-*" }, "Microsoft.Framework.OptionsModel": "1.0.0-*" }, "frameworks": { From 14d1b467c69dd6f836f5683b6e1545b7f3f859ee Mon Sep 17 00:00:00 2001 From: Hao Kung Date: Mon, 16 Mar 2015 15:14:44 -0700 Subject: [PATCH 163/216] ClaimsXform and RIP AutoAuthHandler - Initial support for ClaimsTransformation - merge automatic auth handler back into base --- .../CookieSessionSample.xproj | 2 +- samples/SocialSample/SocialSample.xproj | 2 +- samples/SocialSample/Startup.cs | 8 ++ .../CookieAuthenticationHandler.cs | 2 +- .../CookieAuthenticationMiddleware.cs | 11 +- .../CookieAuthenticationOptions.cs | 3 +- .../FacebookAuthenticationMiddleware.cs | 12 +- .../GoogleAuthenticationMiddleware.cs | 12 +- ...icrosoftAccountAuthenticationMiddleware.cs | 12 +- .../OAuthAuthenticationHandler.cs | 10 +- .../OAuthAuthenticationMiddleware.cs | 12 +- .../OAuthBearerAuthenticationHandler.cs | 4 +- .../OAuthBearerAuthenticationMiddleware.cs | 8 +- .../OAuthBearerAuthenticationOptions.cs | 2 +- .../OpenIdConnectAuthenticationMiddleware.cs | 12 +- .../OpenidConnectAuthenticationHandler.cs | 10 +- .../TwitterAuthenticationHandler.cs | 10 +- .../TwitterAuthenticationMiddleware.cs | 12 +- .../AuthenticationHandler.cs | 57 +++++++--- .../AuthenticationMiddleware.cs | 6 +- .../AuthenticationOptions.cs | 7 ++ ...thenticationServiceCollectionExtensions.cs | 26 +++++ .../AutomaticAuthenticationHandler.cs | 94 ---------------- .../AutomaticAuthenticationOptions.cs | 20 ---- ...laimsTransformationAppBuilderExtensions.cs | 26 +++++ ...aimsTransformationAuthenticationHandler.cs | 105 +++++++++++++++++ .../ClaimsTransformationMiddleware.cs | 44 ++++++++ .../ClaimsTransformationOptions.cs | 6 +- .../ServiceCollectionExtensions.cs | 5 - .../AuthenticationHandlerFacts.cs | 11 +- .../Cookies/CookieMiddlewareTests.cs | 86 +++++++++++--- .../Facebook/FacebookMiddlewareTests.cs | 1 + .../Google/GoogleMiddlewareTests.cs | 106 ++++++++++++++++-- .../MicrosoftAccountMiddlewareTests.cs | 6 +- 34 files changed, 523 insertions(+), 227 deletions(-) create mode 100644 src/Microsoft.AspNet.Authentication/AuthenticationServiceCollectionExtensions.cs delete mode 100644 src/Microsoft.AspNet.Authentication/AutomaticAuthenticationHandler.cs delete mode 100644 src/Microsoft.AspNet.Authentication/AutomaticAuthenticationOptions.cs create mode 100644 src/Microsoft.AspNet.Authentication/ClaimsTransformationAppBuilderExtensions.cs create mode 100644 src/Microsoft.AspNet.Authentication/ClaimsTransformationAuthenticationHandler.cs create mode 100644 src/Microsoft.AspNet.Authentication/ClaimsTransformationMiddleware.cs rename src/{Microsoft.AspNet.Authorization => Microsoft.AspNet.Authentication}/ClaimsTransformationOptions.cs (64%) diff --git a/samples/CookieSessionSample/CookieSessionSample.xproj b/samples/CookieSessionSample/CookieSessionSample.xproj index 121634187..e129ba553 100644 --- a/samples/CookieSessionSample/CookieSessionSample.xproj +++ b/samples/CookieSessionSample/CookieSessionSample.xproj @@ -12,7 +12,7 @@ 2.0 - 22571 + 36505 \ No newline at end of file diff --git a/samples/SocialSample/SocialSample.xproj b/samples/SocialSample/SocialSample.xproj index ce1e69ddf..74aaf1222 100644 --- a/samples/SocialSample/SocialSample.xproj +++ b/samples/SocialSample/SocialSample.xproj @@ -12,7 +12,7 @@ 2.0 - 22570 + 36504 \ No newline at end of file diff --git a/samples/SocialSample/Startup.cs b/samples/SocialSample/Startup.cs index dab45953d..bc7d61b4a 100644 --- a/samples/SocialSample/Startup.cs +++ b/samples/SocialSample/Startup.cs @@ -1,6 +1,7 @@ using System.Net.Http; using System.Net.Http.Headers; using System.Security.Claims; +using System.Threading.Tasks; using Microsoft.AspNet.Builder; using Microsoft.AspNet.DataProtection; using Microsoft.AspNet.Http; @@ -28,6 +29,13 @@ public void Configure(IApplicationBuilder app) { options.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme; }); + services.ConfigureClaimsTransformation(p => + { + var id = new ClaimsIdentity("xform"); + id.AddClaim(new Claim("ClaimsTransformation", "TransformAddedClaim")); + p.AddIdentity(id); + return p; + }); }); app.UseCookieAuthentication(options => diff --git a/src/Microsoft.AspNet.Authentication.Cookies/CookieAuthenticationHandler.cs b/src/Microsoft.AspNet.Authentication.Cookies/CookieAuthenticationHandler.cs index 808a2691a..8ccbb3653 100644 --- a/src/Microsoft.AspNet.Authentication.Cookies/CookieAuthenticationHandler.cs +++ b/src/Microsoft.AspNet.Authentication.Cookies/CookieAuthenticationHandler.cs @@ -13,7 +13,7 @@ namespace Microsoft.AspNet.Authentication.Cookies { - internal class CookieAuthenticationHandler : AutomaticAuthenticationHandler + internal class CookieAuthenticationHandler : AuthenticationHandler { private const string HeaderNameCacheControl = "Cache-Control"; private const string HeaderNamePragma = "Pragma"; diff --git a/src/Microsoft.AspNet.Authentication.Cookies/CookieAuthenticationMiddleware.cs b/src/Microsoft.AspNet.Authentication.Cookies/CookieAuthenticationMiddleware.cs index e3ef3f570..cd6b53b39 100644 --- a/src/Microsoft.AspNet.Authentication.Cookies/CookieAuthenticationMiddleware.cs +++ b/src/Microsoft.AspNet.Authentication.Cookies/CookieAuthenticationMiddleware.cs @@ -15,11 +15,12 @@ public class CookieAuthenticationMiddleware : AuthenticationMiddleware options, + public CookieAuthenticationMiddleware( + [NotNull] RequestDelegate next, + [NotNull] IServiceProvider services, + [NotNull] IDataProtectionProvider dataProtectionProvider, + [NotNull] ILoggerFactory loggerFactory, + [NotNull] IOptions options, ConfigureOptions configureOptions) : base(next, services, options, configureOptions) { diff --git a/src/Microsoft.AspNet.Authentication.Cookies/CookieAuthenticationOptions.cs b/src/Microsoft.AspNet.Authentication.Cookies/CookieAuthenticationOptions.cs index 02e9743b4..c2fc4c3a7 100644 --- a/src/Microsoft.AspNet.Authentication.Cookies/CookieAuthenticationOptions.cs +++ b/src/Microsoft.AspNet.Authentication.Cookies/CookieAuthenticationOptions.cs @@ -11,7 +11,7 @@ namespace Microsoft.AspNet.Authentication.Cookies /// /// Contains the options used by the CookiesAuthenticationMiddleware /// - public class CookieAuthenticationOptions : AutomaticAuthenticationOptions + public class CookieAuthenticationOptions : AuthenticationOptions { private string _cookieName; @@ -20,7 +20,6 @@ public class CookieAuthenticationOptions : AutomaticAuthenticationOptions /// public CookieAuthenticationOptions() { - AutomaticAuthentication = true; AuthenticationScheme = CookieAuthenticationDefaults.AuthenticationScheme; ReturnUrlParameter = CookieAuthenticationDefaults.ReturnUrlParameter; ExpireTimeSpan = TimeSpan.FromDays(14); diff --git a/src/Microsoft.AspNet.Authentication.Facebook/FacebookAuthenticationMiddleware.cs b/src/Microsoft.AspNet.Authentication.Facebook/FacebookAuthenticationMiddleware.cs index b74a5be1d..506453c54 100644 --- a/src/Microsoft.AspNet.Authentication.Facebook/FacebookAuthenticationMiddleware.cs +++ b/src/Microsoft.AspNet.Authentication.Facebook/FacebookAuthenticationMiddleware.cs @@ -25,12 +25,12 @@ public class FacebookAuthenticationMiddleware : OAuthAuthenticationMiddleware /// Configuration options for the middleware. public FacebookAuthenticationMiddleware( - RequestDelegate next, - IServiceProvider services, - IDataProtectionProvider dataProtectionProvider, - ILoggerFactory loggerFactory, - IOptions externalOptions, - IOptions options, + [NotNull] RequestDelegate next, + [NotNull] IServiceProvider services, + [NotNull] IDataProtectionProvider dataProtectionProvider, + [NotNull] ILoggerFactory loggerFactory, + [NotNull] IOptions externalOptions, + [NotNull] IOptions options, ConfigureOptions configureOptions = null) : base(next, services, dataProtectionProvider, loggerFactory, externalOptions, options, configureOptions) { diff --git a/src/Microsoft.AspNet.Authentication.Google/GoogleAuthenticationMiddleware.cs b/src/Microsoft.AspNet.Authentication.Google/GoogleAuthenticationMiddleware.cs index 0da3f4928..819642a85 100644 --- a/src/Microsoft.AspNet.Authentication.Google/GoogleAuthenticationMiddleware.cs +++ b/src/Microsoft.AspNet.Authentication.Google/GoogleAuthenticationMiddleware.cs @@ -30,12 +30,12 @@ public class GoogleAuthenticationMiddleware : OAuthAuthenticationMiddleware /// Configuration options for the middleware. public GoogleAuthenticationMiddleware( - RequestDelegate next, - IServiceProvider services, - IDataProtectionProvider dataProtectionProvider, - ILoggerFactory loggerFactory, - IOptions externalOptions, - IOptions options, + [NotNull] RequestDelegate next, + [NotNull] IServiceProvider services, + [NotNull] IDataProtectionProvider dataProtectionProvider, + [NotNull] ILoggerFactory loggerFactory, + [NotNull] IOptions externalOptions, + [NotNull] IOptions options, ConfigureOptions configureOptions = null) : base(next, services, dataProtectionProvider, loggerFactory, externalOptions, options, configureOptions) { diff --git a/src/Microsoft.AspNet.Authentication.MicrosoftAccount/MicrosoftAccountAuthenticationMiddleware.cs b/src/Microsoft.AspNet.Authentication.MicrosoftAccount/MicrosoftAccountAuthenticationMiddleware.cs index ac2ebc184..f0430bd72 100644 --- a/src/Microsoft.AspNet.Authentication.MicrosoftAccount/MicrosoftAccountAuthenticationMiddleware.cs +++ b/src/Microsoft.AspNet.Authentication.MicrosoftAccount/MicrosoftAccountAuthenticationMiddleware.cs @@ -26,12 +26,12 @@ public class MicrosoftAccountAuthenticationMiddleware : OAuthAuthenticationMiddl /// /// Configuration options for the middleware. public MicrosoftAccountAuthenticationMiddleware( - RequestDelegate next, - IServiceProvider services, - IDataProtectionProvider dataProtectionProvider, - ILoggerFactory loggerFactory, - IOptions externalOptions, - IOptions options, + [NotNull] RequestDelegate next, + [NotNull] IServiceProvider services, + [NotNull] IDataProtectionProvider dataProtectionProvider, + [NotNull] ILoggerFactory loggerFactory, + [NotNull] IOptions externalOptions, + [NotNull] IOptions options, ConfigureOptions configureOptions = null) : base(next, services, dataProtectionProvider, loggerFactory, externalOptions, options, configureOptions) { diff --git a/src/Microsoft.AspNet.Authentication.OAuth/OAuthAuthenticationHandler.cs b/src/Microsoft.AspNet.Authentication.OAuth/OAuthAuthenticationHandler.cs index 6a51d85e9..b8696a302 100644 --- a/src/Microsoft.AspNet.Authentication.OAuth/OAuthAuthenticationHandler.cs +++ b/src/Microsoft.AspNet.Authentication.OAuth/OAuthAuthenticationHandler.cs @@ -176,13 +176,19 @@ protected virtual async Task GetUserInformationAsync(Authe protected override void ApplyResponseChallenge() { + if (ShouldConvertChallengeToForbidden()) + { + Response.StatusCode = 403; + return; + } + if (Response.StatusCode != 401) { return; } - // Only redirect on challenges - if (ChallengeContext == null) + // When Automatic should redirect on 401 even if there wasn't an explicit challenge. + if (ChallengeContext == null && !Options.AutomaticAuthentication) { return; } diff --git a/src/Microsoft.AspNet.Authentication.OAuth/OAuthAuthenticationMiddleware.cs b/src/Microsoft.AspNet.Authentication.OAuth/OAuthAuthenticationMiddleware.cs index 0d272bf1e..1c96be1e4 100644 --- a/src/Microsoft.AspNet.Authentication.OAuth/OAuthAuthenticationMiddleware.cs +++ b/src/Microsoft.AspNet.Authentication.OAuth/OAuthAuthenticationMiddleware.cs @@ -31,12 +31,12 @@ public class OAuthAuthenticationMiddleware : Authentic /// /// Configuration options for the middleware. public OAuthAuthenticationMiddleware( - RequestDelegate next, - IServiceProvider services, - IDataProtectionProvider dataProtectionProvider, - ILoggerFactory loggerFactory, - IOptions externalOptions, - IOptions options, + [NotNull] RequestDelegate next, + [NotNull] IServiceProvider services, + [NotNull] IDataProtectionProvider dataProtectionProvider, + [NotNull] ILoggerFactory loggerFactory, + [NotNull] IOptions externalOptions, + [NotNull] IOptions options, ConfigureOptions configureOptions = null) : base(next, services, options, configureOptions) { diff --git a/src/Microsoft.AspNet.Authentication.OAuthBearer/OAuthBearerAuthenticationHandler.cs b/src/Microsoft.AspNet.Authentication.OAuthBearer/OAuthBearerAuthenticationHandler.cs index 7f41be810..e2a56697d 100644 --- a/src/Microsoft.AspNet.Authentication.OAuthBearer/OAuthBearerAuthenticationHandler.cs +++ b/src/Microsoft.AspNet.Authentication.OAuthBearer/OAuthBearerAuthenticationHandler.cs @@ -15,7 +15,7 @@ namespace Microsoft.AspNet.Authentication.OAuthBearer { - public class OAuthBearerAuthenticationHandler : AutomaticAuthenticationHandler + public class OAuthBearerAuthenticationHandler : AuthenticationHandler { private readonly ILogger _logger; private OpenIdConnectConfiguration _configuration; @@ -197,7 +197,7 @@ protected override async Task ApplyResponseChallengeAsync() return; } - if ((Response.StatusCode != 401) || (ChallengeContext == null)) + if ((Response.StatusCode != 401) || (ChallengeContext == null && !Options.AutomaticAuthentication)) { return; } diff --git a/src/Microsoft.AspNet.Authentication.OAuthBearer/OAuthBearerAuthenticationMiddleware.cs b/src/Microsoft.AspNet.Authentication.OAuthBearer/OAuthBearerAuthenticationMiddleware.cs index 4083af239..9b47e5c36 100644 --- a/src/Microsoft.AspNet.Authentication.OAuthBearer/OAuthBearerAuthenticationMiddleware.cs +++ b/src/Microsoft.AspNet.Authentication.OAuthBearer/OAuthBearerAuthenticationMiddleware.cs @@ -29,10 +29,10 @@ public class OAuthBearerAuthenticationMiddleware : AuthenticationMiddleware public OAuthBearerAuthenticationMiddleware( - RequestDelegate next, - IServiceProvider services, - ILoggerFactory loggerFactory, - IOptions options, + [NotNull] RequestDelegate next, + [NotNull] IServiceProvider services, + [NotNull] ILoggerFactory loggerFactory, + [NotNull] IOptions options, ConfigureOptions configureOptions) : base(next, services, options, configureOptions) { diff --git a/src/Microsoft.AspNet.Authentication.OAuthBearer/OAuthBearerAuthenticationOptions.cs b/src/Microsoft.AspNet.Authentication.OAuthBearer/OAuthBearerAuthenticationOptions.cs index ab0b83300..9bbc6300c 100644 --- a/src/Microsoft.AspNet.Authentication.OAuthBearer/OAuthBearerAuthenticationOptions.cs +++ b/src/Microsoft.AspNet.Authentication.OAuthBearer/OAuthBearerAuthenticationOptions.cs @@ -13,7 +13,7 @@ namespace Microsoft.AspNet.Authentication.OAuthBearer /// /// Options class provides information needed to control Bearer Authentication middleware behavior /// - public class OAuthBearerAuthenticationOptions : AutomaticAuthenticationOptions + public class OAuthBearerAuthenticationOptions : AuthenticationOptions { private ICollection _securityTokenValidators; private TokenValidationParameters _tokenValidationParameters; diff --git a/src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenIdConnectAuthenticationMiddleware.cs b/src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenIdConnectAuthenticationMiddleware.cs index c316c8583..1f4848140 100644 --- a/src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenIdConnectAuthenticationMiddleware.cs +++ b/src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenIdConnectAuthenticationMiddleware.cs @@ -35,12 +35,12 @@ public class OpenIdConnectAuthenticationMiddleware : AuthenticationMiddlewareConfiguration options for the middleware [SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Justification = "Managed by caller")] public OpenIdConnectAuthenticationMiddleware( - RequestDelegate next, - IServiceProvider services, - IDataProtectionProvider dataProtectionProvider, - ILoggerFactory loggerFactory, - IOptions externalOptions, - IOptions options, + [NotNull] RequestDelegate next, + [NotNull] IServiceProvider services, + [NotNull] IDataProtectionProvider dataProtectionProvider, + [NotNull] ILoggerFactory loggerFactory, + [NotNull] IOptions externalOptions, + [NotNull] IOptions options, ConfigureOptions configureOptions) : base(next, services, options, configureOptions) { diff --git a/src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenidConnectAuthenticationHandler.cs b/src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenidConnectAuthenticationHandler.cs index 68e9bea24..6a629045b 100644 --- a/src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenidConnectAuthenticationHandler.cs +++ b/src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenidConnectAuthenticationHandler.cs @@ -117,13 +117,19 @@ protected override void ApplyResponseChallenge() /// protected override async Task ApplyResponseChallengeAsync() { + if (ShouldConvertChallengeToForbidden()) + { + Response.StatusCode = 403; + return; + } + if (Response.StatusCode != 401) { return; } - // Only redirect on challenges - if (ChallengeContext == null) + // When Automatic should redirect on 401 even if there wasn't an explicit challenge. + if (ChallengeContext == null && !Options.AutomaticAuthentication) { return; } diff --git a/src/Microsoft.AspNet.Authentication.Twitter/TwitterAuthenticationHandler.cs b/src/Microsoft.AspNet.Authentication.Twitter/TwitterAuthenticationHandler.cs index 355fb84b2..6f2aade30 100644 --- a/src/Microsoft.AspNet.Authentication.Twitter/TwitterAuthenticationHandler.cs +++ b/src/Microsoft.AspNet.Authentication.Twitter/TwitterAuthenticationHandler.cs @@ -131,13 +131,19 @@ protected override void ApplyResponseChallenge() protected override async Task ApplyResponseChallengeAsync() { + if (ShouldConvertChallengeToForbidden()) + { + Response.StatusCode = 403; + return; + } + if (Response.StatusCode != 401) { return; } - // Only redirect on challenges - if (ChallengeContext == null) + // When Automatic should redirect on 401 even if there wasn't an explicit challenge. + if (ChallengeContext == null && !Options.AutomaticAuthentication) { return; } diff --git a/src/Microsoft.AspNet.Authentication.Twitter/TwitterAuthenticationMiddleware.cs b/src/Microsoft.AspNet.Authentication.Twitter/TwitterAuthenticationMiddleware.cs index 4ffedd992..11ae3b4bd 100644 --- a/src/Microsoft.AspNet.Authentication.Twitter/TwitterAuthenticationMiddleware.cs +++ b/src/Microsoft.AspNet.Authentication.Twitter/TwitterAuthenticationMiddleware.cs @@ -33,12 +33,12 @@ public class TwitterAuthenticationMiddleware : AuthenticationMiddleware /// Configuration options for the middleware public TwitterAuthenticationMiddleware( - RequestDelegate next, - IServiceProvider services, - IDataProtectionProvider dataProtectionProvider, - ILoggerFactory loggerFactory, - IOptions externalOptions, - IOptions options, + [NotNull] RequestDelegate next, + [NotNull] IServiceProvider services, + [NotNull] IDataProtectionProvider dataProtectionProvider, + [NotNull] ILoggerFactory loggerFactory, + [NotNull] IOptions externalOptions, + [NotNull] IOptions options, ConfigureOptions configureOptions = null) : base(next, services, options, configureOptions) { diff --git a/src/Microsoft.AspNet.Authentication/AuthenticationHandler.cs b/src/Microsoft.AspNet.Authentication/AuthenticationHandler.cs index 93d1ab629..d54c4a3be 100644 --- a/src/Microsoft.AspNet.Authentication/AuthenticationHandler.cs +++ b/src/Microsoft.AspNet.Authentication/AuthenticationHandler.cs @@ -72,6 +72,15 @@ protected async Task BaseInitializeAsync(AuthenticationOptions options, HttpCont Response.OnSendingHeaders(OnSendingHeaderCallback, this); await InitializeCoreAsync(); + + if (BaseOptions.AutomaticAuthentication) + { + var ticket = await AuthenticateAsync(); + if (ticket?.Principal != null) + { + SecurityHelper.AddUserPrincipal(Context, ticket.Principal); + } + } } private static void OnSendingHeaderCallback(object state) @@ -128,7 +137,7 @@ protected virtual Task TeardownCoreAsync() /// pipeline. public virtual Task InvokeAsync() { - return Task.FromResult(false); + return Task.FromResult(false); } public virtual void GetDescriptions(IDescribeSchemesContext describeContext) @@ -143,17 +152,17 @@ public virtual void GetDescriptions(IDescribeSchemesContext describeContext) public virtual void Authenticate(IAuthenticateContext context) { - if (context.AuthenticationSchemes.Contains(BaseOptions.AuthenticationScheme, StringComparer.Ordinal)) + if (ShouldHandleScheme(context.AuthenticationScheme)) { - AuthenticationTicket ticket = Authenticate(); - if (ticket != null && ticket.Principal != null) + var ticket = Authenticate(); + if (ticket?.Principal != null) { AuthenticateCalled = true; context.Authenticated(ticket.Principal, ticket.Properties.Dictionary, BaseOptions.Description.Dictionary); } else { - context.NotAuthenticated(BaseOptions.AuthenticationScheme, properties: null, description: BaseOptions.Description.Dictionary); + context.NotAuthenticated(); } } @@ -165,17 +174,17 @@ public virtual void Authenticate(IAuthenticateContext context) public virtual async Task AuthenticateAsync(IAuthenticateContext context) { - if (context.AuthenticationSchemes.Contains(BaseOptions.AuthenticationScheme, StringComparer.Ordinal)) + if (ShouldHandleScheme(context.AuthenticationScheme)) { - AuthenticationTicket ticket = await AuthenticateAsync(); - if (ticket != null && ticket.Principal != null) + var ticket = await AuthenticateAsync(); + if (ticket?.Principal != null) { AuthenticateCalled = true; context.Authenticated(ticket.Principal, ticket.Properties.Dictionary, BaseOptions.Description.Dictionary); } else { - context.NotAuthenticated(BaseOptions.AuthenticationScheme, properties: null, description: BaseOptions.Description.Dictionary); + context.NotAuthenticated(); } } @@ -360,14 +369,26 @@ public virtual void Challenge(IChallengeContext context) public virtual bool ShouldHandleScheme(IEnumerable authenticationSchemes) { - return authenticationSchemes != null && - authenticationSchemes.Any() && - authenticationSchemes.Contains(BaseOptions.AuthenticationScheme, StringComparer.Ordinal); + // If there are any schemes asked for, need to match, otherwise automatic authentication matches + return authenticationSchemes != null && authenticationSchemes.Any() + ? authenticationSchemes.Contains(BaseOptions.AuthenticationScheme, StringComparer.Ordinal) + : BaseOptions.AutomaticAuthentication; } public virtual bool ShouldHandleScheme(string authenticationScheme) { - return string.Equals(BaseOptions.AuthenticationScheme, authenticationScheme, StringComparison.Ordinal); + return string.Equals(BaseOptions.AuthenticationScheme, authenticationScheme, StringComparison.Ordinal) || + (BaseOptions.AutomaticAuthentication && string.IsNullOrWhiteSpace(authenticationScheme)); + } + + public virtual bool ShouldConvertChallengeToForbidden() + { + // Return 403 iff 401 and this handler's authenticate was called + // and the challenge is for the authentication type + return Response.StatusCode == 401 && + AuthenticateCalled && + ChallengeContext != null && + ShouldHandleScheme(ChallengeContext.AuthenticationSchemes); } /// @@ -384,11 +405,11 @@ protected virtual Task ApplyResponseChallengeAsync() protected void GenerateCorrelationId([NotNull] AuthenticationProperties properties) { - string correlationKey = Constants.CorrelationPrefix + BaseOptions.AuthenticationScheme; + var correlationKey = Constants.CorrelationPrefix + BaseOptions.AuthenticationScheme; var nonceBytes = new byte[32]; CryptoRandom.GetBytes(nonceBytes); - string correlationId = TextEncodings.Base64Url.Encode(nonceBytes); + var correlationId = TextEncodings.Base64Url.Encode(nonceBytes); var cookieOptions = new CookieOptions { @@ -403,9 +424,8 @@ protected void GenerateCorrelationId([NotNull] AuthenticationProperties properti protected bool ValidateCorrelationId([NotNull] AuthenticationProperties properties, [NotNull] ILogger logger) { - string correlationKey = Constants.CorrelationPrefix + BaseOptions.AuthenticationScheme; - - string correlationCookie = Request.Cookies[correlationKey]; + var correlationKey = Constants.CorrelationPrefix + BaseOptions.AuthenticationScheme; + var correlationCookie = Request.Cookies[correlationKey]; if (string.IsNullOrWhiteSpace(correlationCookie)) { logger.LogWarning("{0} cookie not found.", correlationKey); @@ -453,3 +473,4 @@ private void UnregisterAuthenticationHandler() } } } + diff --git a/src/Microsoft.AspNet.Authentication/AuthenticationMiddleware.cs b/src/Microsoft.AspNet.Authentication/AuthenticationMiddleware.cs index f78eeaa55..a9482ed46 100644 --- a/src/Microsoft.AspNet.Authentication/AuthenticationMiddleware.cs +++ b/src/Microsoft.AspNet.Authentication/AuthenticationMiddleware.cs @@ -16,7 +16,11 @@ namespace Microsoft.AspNet.Authentication private readonly RequestDelegate _next; private readonly IServiceProvider _services; - protected AuthenticationMiddleware([NotNull] RequestDelegate next, [NotNull] IServiceProvider services, [NotNull] IOptions options, ConfigureOptions configureOptions) + protected AuthenticationMiddleware( + [NotNull] RequestDelegate next, + [NotNull] IServiceProvider services, + [NotNull] IOptions options, + ConfigureOptions configureOptions) { if (configureOptions != null) { diff --git a/src/Microsoft.AspNet.Authentication/AuthenticationOptions.cs b/src/Microsoft.AspNet.Authentication/AuthenticationOptions.cs index 09df9e5da..c91a5bddf 100644 --- a/src/Microsoft.AspNet.Authentication/AuthenticationOptions.cs +++ b/src/Microsoft.AspNet.Authentication/AuthenticationOptions.cs @@ -26,6 +26,13 @@ public string AuthenticationScheme } } + /// + /// If true the authentication middleware alter the request user coming in and + /// alter 401 Unauthorized responses going out. If false the authentication middleware will only provide + /// identity and alter responses when explicitly indicated by the AuthenticationScheme. + /// + public bool AutomaticAuthentication { get; set; } + /// /// Additional information about the authentication type which is made available to the application. /// diff --git a/src/Microsoft.AspNet.Authentication/AuthenticationServiceCollectionExtensions.cs b/src/Microsoft.AspNet.Authentication/AuthenticationServiceCollectionExtensions.cs new file mode 100644 index 000000000..55b82acab --- /dev/null +++ b/src/Microsoft.AspNet.Authentication/AuthenticationServiceCollectionExtensions.cs @@ -0,0 +1,26 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Security.Claims; +using System.Threading.Tasks; +using Microsoft.AspNet.Authentication; +using Microsoft.AspNet.Http.Core.Authentication; +using Microsoft.Framework.Internal; + +namespace Microsoft.Framework.DependencyInjection +{ + public static class AuthenticationServiceCollectionExtensions + { + public static IServiceCollection ConfigureClaimsTransformation([NotNull] this IServiceCollection services, [NotNull] Action configure) + { + return services.Configure(configure); + } + + public static IServiceCollection ConfigureClaimsTransformation([NotNull] this IServiceCollection services, [NotNull] Func transform) + { + return services.Configure(o => o.Transformation = transform); + } + + } +} diff --git a/src/Microsoft.AspNet.Authentication/AutomaticAuthenticationHandler.cs b/src/Microsoft.AspNet.Authentication/AutomaticAuthenticationHandler.cs deleted file mode 100644 index f67f2a908..000000000 --- a/src/Microsoft.AspNet.Authentication/AutomaticAuthenticationHandler.cs +++ /dev/null @@ -1,94 +0,0 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; -using Microsoft.AspNet.Http.Authentication; - -namespace Microsoft.AspNet.Authentication -{ - /// - /// Base class for the per-request work performed by automatic authentication middleware. - /// - /// Specifies which type for of AutomaticAuthenticationOptions property - public abstract class AutomaticAuthenticationHandler : AuthenticationHandler where TOptions : AutomaticAuthenticationOptions - { - public virtual bool ShouldConvertChallengeToForbidden() - { - // Return 403 iff 401 and this handler's authenticate was called - // and the challenge is for the authentication type - return Response.StatusCode == 401 && - AuthenticateCalled && - ChallengeContext != null && - ShouldHandleScheme(ChallengeContext.AuthenticationSchemes); - } - - protected async override Task InitializeCoreAsync() - { - if (Options.AutomaticAuthentication) - { - AuthenticationTicket ticket = await AuthenticateAsync(); - if (ticket != null && ticket.Principal != null) - { - SecurityHelper.AddUserPrincipal(Context, ticket.Principal); - } - } - } - - public override void SignOut(ISignOutContext context) - { - // Empty or null auth scheme is allowed for automatic Authentication - if (Options.AutomaticAuthentication && string.IsNullOrWhiteSpace(context.AuthenticationScheme)) - { - SignInContext = null; - SignOutContext = context; - context.Accept(); - } - - base.SignOut(context); - } - - public override void Challenge(IChallengeContext context) - { - // Null or Empty scheme allowed for automatic authentication - if (Options.AutomaticAuthentication && - (context.AuthenticationSchemes == null || !context.AuthenticationSchemes.Any())) - { - ChallengeContext = context; - context.Accept(BaseOptions.AuthenticationScheme, BaseOptions.Description.Dictionary); - } - - base.Challenge(context); - } - - /// - /// Automatic Authentication Handlers can handle empty authentication schemes - /// - /// - public override bool ShouldHandleScheme(IEnumerable authenticationSchemes) - { - if (base.ShouldHandleScheme(authenticationSchemes)) - { - return true; - } - - return Options.AutomaticAuthentication && - (authenticationSchemes == null || !authenticationSchemes.Any()); - } - - /// - /// Automatic Authentication Handlers can handle empty authentication schemes - /// - /// - public override bool ShouldHandleScheme(string authenticationScheme) - { - if (base.ShouldHandleScheme(authenticationScheme)) - { - return true; - } - - return Options.AutomaticAuthentication && string.IsNullOrWhiteSpace(authenticationScheme); - } - } -} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Authentication/AutomaticAuthenticationOptions.cs b/src/Microsoft.AspNet.Authentication/AutomaticAuthenticationOptions.cs deleted file mode 100644 index 53af20984..000000000 --- a/src/Microsoft.AspNet.Authentication/AutomaticAuthenticationOptions.cs +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using Microsoft.AspNet.Http.Authentication; - -namespace Microsoft.AspNet.Authentication -{ - /// - /// Base Options for all automatic authentication middleware - /// - public abstract class AutomaticAuthenticationOptions : AuthenticationOptions - { - /// - /// If true the authentication middleware alter the request user coming in and - /// alter 401 Unauthorized responses going out. If false the authentication middleware will only provide - /// identity and alter responses when explicitly indicated by the AuthenticationScheme. - /// - public bool AutomaticAuthentication { get; set; } - } -} diff --git a/src/Microsoft.AspNet.Authentication/ClaimsTransformationAppBuilderExtensions.cs b/src/Microsoft.AspNet.Authentication/ClaimsTransformationAppBuilderExtensions.cs new file mode 100644 index 000000000..79ecb3888 --- /dev/null +++ b/src/Microsoft.AspNet.Authentication/ClaimsTransformationAppBuilderExtensions.cs @@ -0,0 +1,26 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using Microsoft.AspNet.Authentication; + +namespace Microsoft.AspNet.Builder +{ + /// + /// Extension methods provided by the claims transformation authentication middleware + /// + public static class ClaimsTransformationAppBuilderExtensions + { + /// + /// Adds a claims transformation middleware to your web application pipeline. + /// + /// The IApplicationBuilder passed to your configuration method + /// Used to configure the options for the middleware + /// The name of the options class that controls the middleware behavior, null will use the default options + /// The original app parameter + public static IApplicationBuilder UseClaimsTransformation(this IApplicationBuilder app) + { + return app.UseMiddleware(); + } + } +} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Authentication/ClaimsTransformationAuthenticationHandler.cs b/src/Microsoft.AspNet.Authentication/ClaimsTransformationAuthenticationHandler.cs new file mode 100644 index 000000000..bee68e7d7 --- /dev/null +++ b/src/Microsoft.AspNet.Authentication/ClaimsTransformationAuthenticationHandler.cs @@ -0,0 +1,105 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Security.Claims; +using System.Threading.Tasks; +using Microsoft.AspNet.Http.Authentication; +using Microsoft.AspNet.Http.Core.Authentication; + +namespace Microsoft.AspNet.Authentication +{ + /// + /// Handler that applies ClaimsTransformation to authentication + /// + public class ClaimsTransformationAuthenticationHandler : IAuthenticationHandler + { + private readonly Func _transform; + + public ClaimsTransformationAuthenticationHandler(Func transform) + { + _transform = transform; + } + + public IAuthenticationHandler PriorHandler { get; set; } + + private void ApplyTransform(IAuthenticateContext context) + { + if (_transform != null) + { + // REVIEW: this cast seems really bad (missing interface way to get the result back out?) + var authContext = context as AuthenticateContext; + if (authContext?.Result?.Principal != null) + { + context.Authenticated( + _transform.Invoke(authContext.Result.Principal), + authContext.Result.Properties.Dictionary, + authContext.Result.Description.Dictionary); + } + } + + } + + public void Authenticate(IAuthenticateContext context) + { + if (PriorHandler != null) + { + PriorHandler.Authenticate(context); + ApplyTransform(context); + } + } + + public async Task AuthenticateAsync(IAuthenticateContext context) + { + if (PriorHandler != null) + { + await PriorHandler.AuthenticateAsync(context); + ApplyTransform(context); + } + } + + public void Challenge(IChallengeContext context) + { + if (PriorHandler != null) + { + PriorHandler.Challenge(context); + } + } + + public void GetDescriptions(IDescribeSchemesContext context) + { + if (PriorHandler != null) + { + PriorHandler.GetDescriptions(context); + } + } + + public void SignIn(ISignInContext context) + { + if (PriorHandler != null) + { + PriorHandler.SignIn(context); + } + } + + public void SignOut(ISignOutContext context) + { + if (PriorHandler != null) + { + PriorHandler.SignOut(context); + } + } + + public void RegisterAuthenticationHandler(IHttpAuthenticationFeature auth) + { + PriorHandler = auth.Handler; + auth.Handler = this; + } + + public void UnregisterAuthenticationHandler(IHttpAuthenticationFeature auth) + { + auth.Handler = PriorHandler; + } + + } +} diff --git a/src/Microsoft.AspNet.Authentication/ClaimsTransformationMiddleware.cs b/src/Microsoft.AspNet.Authentication/ClaimsTransformationMiddleware.cs new file mode 100644 index 000000000..cf3a58b79 --- /dev/null +++ b/src/Microsoft.AspNet.Authentication/ClaimsTransformationMiddleware.cs @@ -0,0 +1,44 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System.Threading.Tasks; +using Microsoft.AspNet.Builder; +using Microsoft.AspNet.Http; +using Microsoft.Framework.OptionsModel; +using Microsoft.Framework.Internal; + +namespace Microsoft.AspNet.Authentication +{ + public class ClaimsTransformationMiddleware + { + private readonly RequestDelegate _next; + + public ClaimsTransformationMiddleware( + [NotNull] RequestDelegate next, + [NotNull] IOptions options) + { + // REVIEW: do we need to take ConfigureOptions?? + Options = options.Options; + _next = next; + } + + public ClaimsTransformationOptions Options { get; set; } + + public async Task Invoke(HttpContext context) + { + var handler = new ClaimsTransformationAuthenticationHandler(Options.Transformation); + handler.RegisterAuthenticationHandler(context.GetAuthentication()); + try { + if (Options.Transformation != null) + { + context.User = Options.Transformation.Invoke(context.User); + } + await _next(context); + } + finally + { + handler.UnregisterAuthenticationHandler(context.GetAuthentication()); + } + } + } +} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Authorization/ClaimsTransformationOptions.cs b/src/Microsoft.AspNet.Authentication/ClaimsTransformationOptions.cs similarity index 64% rename from src/Microsoft.AspNet.Authorization/ClaimsTransformationOptions.cs rename to src/Microsoft.AspNet.Authentication/ClaimsTransformationOptions.cs index da3a4a7bd..f8c4a3ed3 100644 --- a/src/Microsoft.AspNet.Authorization/ClaimsTransformationOptions.cs +++ b/src/Microsoft.AspNet.Authentication/ClaimsTransformationOptions.cs @@ -1,15 +1,13 @@ // Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - using System; using System.Security.Claims; -using System.Threading.Tasks; -namespace Microsoft.AspNet.Authorization +namespace Microsoft.AspNet.Authentication { public class ClaimsTransformationOptions { - public Func> TransformAsync { get; set; } + public Func Transformation { get; set; } } } diff --git a/src/Microsoft.AspNet.Authorization/ServiceCollectionExtensions.cs b/src/Microsoft.AspNet.Authorization/ServiceCollectionExtensions.cs index e825684b3..467b36aff 100644 --- a/src/Microsoft.AspNet.Authorization/ServiceCollectionExtensions.cs +++ b/src/Microsoft.AspNet.Authorization/ServiceCollectionExtensions.cs @@ -9,11 +9,6 @@ namespace Microsoft.Framework.DependencyInjection { public static class ServiceCollectionExtensions { - public static IServiceCollection ConfigureClaimsTransformation([NotNull] this IServiceCollection services, [NotNull] Action configure) - { - return services.Configure(configure); - } - public static IServiceCollection ConfigureAuthorization([NotNull] this IServiceCollection services, [NotNull] Action configure) { return services.Configure(configure); diff --git a/test/Microsoft.AspNet.Authentication.Test/AuthenticationHandlerFacts.cs b/test/Microsoft.AspNet.Authentication.Test/AuthenticationHandlerFacts.cs index 6bd62b2b8..8ed1063dd 100644 --- a/test/Microsoft.AspNet.Authentication.Test/AuthenticationHandlerFacts.cs +++ b/test/Microsoft.AspNet.Authentication.Test/AuthenticationHandlerFacts.cs @@ -2,7 +2,6 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; -using Microsoft.AspNet.Authentication; using Microsoft.AspNet.Http.Core; using Xunit; @@ -79,9 +78,15 @@ protected override AuthenticationTicket AuthenticateCore() private class TestOptions : AuthenticationOptions { } - private class TestAutoOptions : AutomaticAuthenticationOptions { } + private class TestAutoOptions : AuthenticationOptions + { + public TestAutoOptions() + { + AutomaticAuthentication = true; + } + } - private class TestAutoHandler : AutomaticAuthenticationHandler + private class TestAutoHandler : AuthenticationHandler { public TestAutoHandler(string scheme, bool auto) { diff --git a/test/Microsoft.AspNet.Authentication.Test/Cookies/CookieMiddlewareTests.cs b/test/Microsoft.AspNet.Authentication.Test/Cookies/CookieMiddlewareTests.cs index 51d9a9452..ea3885650 100644 --- a/test/Microsoft.AspNet.Authentication.Test/Cookies/CookieMiddlewareTests.cs +++ b/test/Microsoft.AspNet.Authentication.Test/Cookies/CookieMiddlewareTests.cs @@ -34,37 +34,47 @@ public async Task NormalRequestPassesThrough() response.StatusCode.ShouldBe(HttpStatusCode.OK); } - [Fact] - public async Task ProtectedRequestShouldRedirectToLogin() + [Theory] + [InlineData(true)] + [InlineData(false)] + public async Task ProtectedRequestShouldRedirectToLoginOnlyWhenAutomatic(bool auto) { TestServer server = CreateServer(options => { options.LoginPath = new PathString("/login"); + options.AutomaticAuthentication = auto; }); Transaction transaction = await SendAsync(server, "http://example.com/protected"); - transaction.Response.StatusCode.ShouldBe(HttpStatusCode.Redirect); - - Uri location = transaction.Response.Headers.Location; - location.LocalPath.ShouldBe("/login"); - location.Query.ShouldBe("?ReturnUrl=%2Fprotected"); + transaction.Response.StatusCode.ShouldBe(auto ? HttpStatusCode.Redirect : HttpStatusCode.Unauthorized); + if (auto) + { + Uri location = transaction.Response.Headers.Location; + location.LocalPath.ShouldBe("/login"); + location.Query.ShouldBe("?ReturnUrl=%2Fprotected"); + } } - [Fact] - public async Task ProtectedCustomRequestShouldRedirectToCustomLogin() + [Theory] + [InlineData(true)] + [InlineData(false)] + public async Task ProtectedCustomRequestShouldRedirectToCustomLogin(bool auto) { TestServer server = CreateServer(options => { options.LoginPath = new PathString("/login"); + options.AutomaticAuthentication = auto; }); Transaction transaction = await SendAsync(server, "http://example.com/protected/CustomRedirect"); - transaction.Response.StatusCode.ShouldBe(HttpStatusCode.Redirect); - - Uri location = transaction.Response.Headers.Location; - location.ToString().ShouldBe("/CustomRedirect"); + transaction.Response.StatusCode.ShouldBe(auto ? HttpStatusCode.Redirect : HttpStatusCode.Unauthorized); + if (auto) + { + Uri location = transaction.Response.Headers.Location; + location.ToString().ShouldBe("/CustomRedirect"); + } } private Task SignInAsAlice(HttpContext context) @@ -221,6 +231,37 @@ public async Task CookieContainsIdentity() FindClaimValue(transaction2, ClaimTypes.Name).ShouldBe("Alice"); } + [Fact] + public async Task CookieAppliesClaimsTransform() + { + var clock = new TestClock(); + TestServer server = CreateServer(options => + { + options.SystemClock = clock; + }, + SignInAsAlice, + baseAddress: null, + claimsTransform: o => o.Transformation = (p => + { + if (!p.Identities.Any(i => i.AuthenticationType == "xform")) + { + // REVIEW: Xform runs twice, once on Authenticate, and then once from the middleware + var id = new ClaimsIdentity("xform"); + id.AddClaim(new Claim("xform", "yup")); + p.AddIdentity(id); + } + return p; + })); + + Transaction transaction1 = await SendAsync(server, "http://example.com/testpath"); + + Transaction transaction2 = await SendAsync(server, "http://example.com/me/Cookies", transaction1.CookieNameValue); + + FindClaimValue(transaction2, ClaimTypes.Name).ShouldBe("Alice"); + FindClaimValue(transaction2, "xform").ShouldBe("yup"); + + } + [Fact] public async Task CookieStopsWorkingAfterExpiration() { @@ -372,6 +413,7 @@ public async Task AjaxRedirectsAsExtraHeaderOnTwoHundred() TestServer server = CreateServer(options => { options.LoginPath = new PathString("/login"); + options.AutomaticAuthentication = true; }); Transaction transaction = await SendAsync(server, "http://example.com/protected", ajaxRequest: true); @@ -478,12 +520,26 @@ private static async Task GetAuthData(TestServer server, string url, s return me; } - private static TestServer CreateServer(Action configureOptions, Func testpath = null, Uri baseAddress = null) + private static TestServer CreateServer(Action configureOptions, Func testpath = null, Uri baseAddress = null, Action claimsTransform = null) { var server = TestServer.Create(app => { - app.UseServices(services => services.AddDataProtection()); + if (claimsTransform != null) + { + app.UseServices(services => { + services.AddDataProtection(); + services.ConfigureClaimsTransformation(claimsTransform); + }); + } + else + { + app.UseServices(services => services.AddDataProtection()); + } app.UseCookieAuthentication(configureOptions); + if (claimsTransform != null) + { + app.UseClaimsTransformation(); + } app.Use(async (context, next) => { var req = context.Request; diff --git a/test/Microsoft.AspNet.Authentication.Test/Facebook/FacebookMiddlewareTests.cs b/test/Microsoft.AspNet.Authentication.Test/Facebook/FacebookMiddlewareTests.cs index a0a5558e8..ba00fb125 100644 --- a/test/Microsoft.AspNet.Authentication.Test/Facebook/FacebookMiddlewareTests.cs +++ b/test/Microsoft.AspNet.Authentication.Test/Facebook/FacebookMiddlewareTests.cs @@ -42,6 +42,7 @@ public async Task ChallengeWillTriggerApplyRedirectEvent() services.ConfigureCookieAuthentication(options => { options.AuthenticationScheme = "External"; + options.AutomaticAuthentication = true; }); services.Configure(options => { diff --git a/test/Microsoft.AspNet.Authentication.Test/Google/GoogleMiddlewareTests.cs b/test/Microsoft.AspNet.Authentication.Test/Google/GoogleMiddlewareTests.cs index 4e02276be..45ba05777 100644 --- a/test/Microsoft.AspNet.Authentication.Test/Google/GoogleMiddlewareTests.cs +++ b/test/Microsoft.AspNet.Authentication.Test/Google/GoogleMiddlewareTests.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using System.IO; using System.Linq; using System.Net; @@ -18,6 +19,7 @@ using Microsoft.AspNet.Http.Authentication; using Microsoft.AspNet.TestHost; using Microsoft.Framework.DependencyInjection; +using Microsoft.Framework.WebEncoders; using Newtonsoft.Json; using Shouldly; using Xunit; @@ -50,6 +52,25 @@ public async Task ChallengeWillTriggerRedirection() location.ShouldNotContain("login_hint="); } + [Fact] + public async Task Challenge401WillTriggerRedirection() + { + var server = CreateServer(options => + { + options.ClientId = "Test Id"; + options.ClientSecret = "Test Secret"; + options.AutomaticAuthentication = true; + }); + var transaction = await SendAsync(server, "https://example.com/401"); + transaction.Response.StatusCode.ShouldBe(HttpStatusCode.Redirect); + var location = transaction.Response.Headers.Location.ToString(); + location.ShouldContain("https://accounts.google.com/o/oauth2/auth?response_type=code"); + location.ShouldContain("&client_id="); + location.ShouldContain("&redirect_uri="); + location.ShouldContain("&scope="); + location.ShouldContain("&state="); + } + [Fact] public async Task ChallengeWillSetCorrelationCookie() { @@ -63,6 +84,20 @@ public async Task ChallengeWillSetCorrelationCookie() transaction.SetCookie.Single().ShouldContain(".AspNet.Correlation.Google="); } + [Fact] + public async Task Challenge401WillSetCorrelationCookie() + { + var server = CreateServer(options => + { + options.ClientId = "Test Id"; + options.ClientSecret = "Test Secret"; + options.AutomaticAuthentication = true; + }); + var transaction = await SendAsync(server, "https://example.com/401"); + Console.WriteLine(transaction.SetCookie); + transaction.SetCookie.Single().ShouldContain(".AspNet.Correlation.Google="); + } + [Fact] public async Task ChallengeWillSetDefaultScope() { @@ -78,18 +113,18 @@ public async Task ChallengeWillSetDefaultScope() } [Fact(Skip = "Failing due to : https://github.com/aspnet/HttpAbstractions/issues/231")] - public async Task ChallengeWillUseOptionsScope() + public async Task Challenge401WillSetDefaultScope() { var server = CreateServer(options => { options.ClientId = "Test Id"; options.ClientSecret = "Test Secret"; - options.Scope.Add("https://www.googleapis.com/auth/plus.login"); + options.AutomaticAuthentication = true; }); - var transaction = await SendAsync(server, "https://example.com/challenge"); + var transaction = await SendAsync(server, "https://example.com/401"); transaction.Response.StatusCode.ShouldBe(HttpStatusCode.Redirect); var query = transaction.Response.Headers.Location.Query; - query.ShouldContain("&scope=" + Uri.EscapeDataString("https://www.googleapis.com/auth/plus.login")); + query.ShouldContain("&scope=" + Uri.EscapeDataString("openid profile email")); } [Fact(Skip = "Failing due to : https://github.com/aspnet/HttpAbstractions/issues/231")] @@ -99,6 +134,7 @@ public async Task ChallengeWillUseAuthenticationPropertiesAsParameters() { options.ClientId = "Test Id"; options.ClientSecret = "Test Secret"; + options.AutomaticAuthentication = true; }, context => { @@ -122,10 +158,10 @@ public async Task ChallengeWillUseAuthenticationPropertiesAsParameters() var transaction = await SendAsync(server, "https://example.com/challenge2"); transaction.Response.StatusCode.ShouldBe(HttpStatusCode.Redirect); var query = transaction.Response.Headers.Location.Query; - query.ShouldContain("scope=" + Uri.EscapeDataString("https://www.googleapis.com/auth/plus.login")); + query.ShouldContain("scope=" + UrlEncoder.Default.UrlEncode("https://www.googleapis.com/auth/plus.login")); query.ShouldContain("access_type=offline"); query.ShouldContain("approval_prompt=force"); - query.ShouldContain("login_hint=" + Uri.EscapeDataString("test@example.com")); + query.ShouldContain("login_hint=" + UrlEncoder.Default.UrlEncode("test@example.com")); } [Fact] @@ -149,6 +185,35 @@ public async Task ChallengeWillTriggerApplyRedirectEvent() query.ShouldContain("custom=test"); } + // TODO: Fix these tests to path (Need some test logic for Authenticate("Google") to return a ticket still + //[Fact] + //public async Task GoogleTurns401To403WhenAuthenticated() + //{ + // TestServer server = CreateServer(options => + // { + // options.ClientId = "Test Id"; + // options.ClientSecret = "Test Secret"; + // }); + + // Transaction transaction1 = await SendAsync(server, "http://example.com/unauthorized"); + // transaction1.Response.StatusCode.ShouldBe(HttpStatusCode.Forbidden); + //} + + //[Fact] + //public async Task GoogleTurns401To403WhenAutomatic() + //{ + // TestServer server = CreateServer(options => + // { + // options.ClientId = "Test Id"; + // options.ClientSecret = "Test Secret"; + // options.AutomaticAuthentication = true; + // }); + + // Debugger.Launch(); + // Transaction transaction1 = await SendAsync(server, "http://example.com/unauthorizedAuto"); + // transaction1.Response.StatusCode.ShouldBe(HttpStatusCode.Forbidden); + //} + [Fact] public async Task ReplyPathWithoutStateQueryStringWillBeRejected() { @@ -233,6 +298,9 @@ public async Task ReplyPathWillAuthenticateValidAuthorizeCodeAndState() transaction.FindClaimValue(ClaimTypes.GivenName).ShouldBe("Test Given Name"); transaction.FindClaimValue(ClaimTypes.Surname).ShouldBe("Test Family Name"); transaction.FindClaimValue(ClaimTypes.Email).ShouldBe("Test email"); + + // Ensure claims transformation + transaction.FindClaimValue("xform").ShouldBe("yup"); } [Fact] @@ -421,9 +489,21 @@ private static TestServer CreateServer(Action confi { options.SignInScheme = CookieAuthenticationScheme; }); + services.ConfigureClaimsTransformation(p => + { + var id = new ClaimsIdentity("xform"); + id.AddClaim(new Claim("xform", "yup")); + p.AddIdentity(id); + return p; + }); + }); + app.UseCookieAuthentication(options => + { + options.AuthenticationScheme = CookieAuthenticationScheme; + options.AutomaticAuthentication = true; }); - app.UseCookieAuthentication(options => options.AuthenticationScheme = CookieAuthenticationScheme); app.UseGoogleAuthentication(configureOptions); + app.UseClaimsTransformation(); app.Use(async (context, next) => { var req = context.Request; @@ -437,6 +517,18 @@ private static TestServer CreateServer(Action confi { Describe(res, context.User); } + else if (req.Path == new PathString("/unauthorized")) + { + // Simulate Authorization failure + var result = await context.AuthenticateAsync("Google"); + res.Challenge("Google"); + } + else if (req.Path == new PathString("/unauthorizedAuto")) + { + var result = await context.AuthenticateAsync("Google"); + res.StatusCode = 401; + res.Challenge(); + } else if (req.Path == new PathString("/401")) { res.StatusCode = 401; diff --git a/test/Microsoft.AspNet.Authentication.Test/MicrosoftAccount/MicrosoftAccountMiddlewareTests.cs b/test/Microsoft.AspNet.Authentication.Test/MicrosoftAccount/MicrosoftAccountMiddlewareTests.cs index e7a8fccd3..48372859d 100644 --- a/test/Microsoft.AspNet.Authentication.Test/MicrosoftAccount/MicrosoftAccountMiddlewareTests.cs +++ b/test/Microsoft.AspNet.Authentication.Test/MicrosoftAccount/MicrosoftAccountMiddlewareTests.cs @@ -169,7 +169,11 @@ private static TestServer CreateServer(Action options.AuthenticationScheme = "External"); + app.UseCookieAuthentication(options => + { + options.AuthenticationScheme = "External"; + options.AutomaticAuthentication = true; + }); app.UseMicrosoftAccountAuthentication(configureOptions); app.Use(async (context, next) => { From 7abccd8f2282c10ae2cb8c21908d207dadbe0d7e Mon Sep 17 00:00:00 2001 From: Hao Kung Date: Mon, 16 Mar 2015 15:22:46 -0700 Subject: [PATCH 164/216] React to Shared NotNull --- .../CookieAuthenticationMiddleware.cs | 1 + .../FacebookAuthenticationMiddleware.cs | 4 ++-- .../GoogleAuthenticationMiddleware.cs | 7 ++----- .../MicrosoftAccountAuthenticationMiddleware.cs | 3 +-- .../OAuthAuthenticationMiddleware.cs | 2 +- .../OAuthBearerAuthenticationMiddleware.cs | 1 + .../OpenIdConnectAuthenticationMiddleware.cs | 2 +- .../TwitterAuthenticationMiddleware.cs | 1 + 8 files changed, 10 insertions(+), 11 deletions(-) diff --git a/src/Microsoft.AspNet.Authentication.Cookies/CookieAuthenticationMiddleware.cs b/src/Microsoft.AspNet.Authentication.Cookies/CookieAuthenticationMiddleware.cs index cd6b53b39..2082f2365 100644 --- a/src/Microsoft.AspNet.Authentication.Cookies/CookieAuthenticationMiddleware.cs +++ b/src/Microsoft.AspNet.Authentication.Cookies/CookieAuthenticationMiddleware.cs @@ -6,6 +6,7 @@ using Microsoft.AspNet.Authentication.DataHandler; using Microsoft.AspNet.Builder; using Microsoft.AspNet.DataProtection; +using Microsoft.Framework.Internal; using Microsoft.Framework.Logging; using Microsoft.Framework.OptionsModel; diff --git a/src/Microsoft.AspNet.Authentication.Facebook/FacebookAuthenticationMiddleware.cs b/src/Microsoft.AspNet.Authentication.Facebook/FacebookAuthenticationMiddleware.cs index 506453c54..d15b8d102 100644 --- a/src/Microsoft.AspNet.Authentication.Facebook/FacebookAuthenticationMiddleware.cs +++ b/src/Microsoft.AspNet.Authentication.Facebook/FacebookAuthenticationMiddleware.cs @@ -3,10 +3,10 @@ using System; using System.Globalization; -using Microsoft.AspNet.Builder; -using Microsoft.AspNet.Authentication; using Microsoft.AspNet.Authentication.OAuth; +using Microsoft.AspNet.Builder; using Microsoft.AspNet.DataProtection; +using Microsoft.Framework.Internal; using Microsoft.Framework.Logging; using Microsoft.Framework.OptionsModel; diff --git a/src/Microsoft.AspNet.Authentication.Google/GoogleAuthenticationMiddleware.cs b/src/Microsoft.AspNet.Authentication.Google/GoogleAuthenticationMiddleware.cs index 819642a85..4641bcd0e 100644 --- a/src/Microsoft.AspNet.Authentication.Google/GoogleAuthenticationMiddleware.cs +++ b/src/Microsoft.AspNet.Authentication.Google/GoogleAuthenticationMiddleware.cs @@ -3,13 +3,10 @@ using System; using System.Diagnostics.CodeAnalysis; -using System.Globalization; -using System.Net.Http; -using Microsoft.AspNet.Authentication; -using Microsoft.AspNet.Authentication.DataHandler; +using Microsoft.AspNet.Authentication.OAuth; using Microsoft.AspNet.Builder; using Microsoft.AspNet.DataProtection; -using Microsoft.AspNet.Authentication.OAuth; +using Microsoft.Framework.Internal; using Microsoft.Framework.Logging; using Microsoft.Framework.OptionsModel; diff --git a/src/Microsoft.AspNet.Authentication.MicrosoftAccount/MicrosoftAccountAuthenticationMiddleware.cs b/src/Microsoft.AspNet.Authentication.MicrosoftAccount/MicrosoftAccountAuthenticationMiddleware.cs index f0430bd72..66cdde6bd 100644 --- a/src/Microsoft.AspNet.Authentication.MicrosoftAccount/MicrosoftAccountAuthenticationMiddleware.cs +++ b/src/Microsoft.AspNet.Authentication.MicrosoftAccount/MicrosoftAccountAuthenticationMiddleware.cs @@ -2,11 +2,10 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; -using System.Globalization; -using Microsoft.AspNet.Authentication; using Microsoft.AspNet.Authentication.OAuth; using Microsoft.AspNet.Builder; using Microsoft.AspNet.DataProtection; +using Microsoft.Framework.Internal; using Microsoft.Framework.Logging; using Microsoft.Framework.OptionsModel; diff --git a/src/Microsoft.AspNet.Authentication.OAuth/OAuthAuthenticationMiddleware.cs b/src/Microsoft.AspNet.Authentication.OAuth/OAuthAuthenticationMiddleware.cs index 1c96be1e4..ef43d309b 100644 --- a/src/Microsoft.AspNet.Authentication.OAuth/OAuthAuthenticationMiddleware.cs +++ b/src/Microsoft.AspNet.Authentication.OAuth/OAuthAuthenticationMiddleware.cs @@ -5,10 +5,10 @@ using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.Net.Http; -using Microsoft.AspNet.Authentication; using Microsoft.AspNet.Authentication.DataHandler; using Microsoft.AspNet.Builder; using Microsoft.AspNet.DataProtection; +using Microsoft.Framework.Internal; using Microsoft.Framework.Logging; using Microsoft.Framework.OptionsModel; diff --git a/src/Microsoft.AspNet.Authentication.OAuthBearer/OAuthBearerAuthenticationMiddleware.cs b/src/Microsoft.AspNet.Authentication.OAuthBearer/OAuthBearerAuthenticationMiddleware.cs index 9b47e5c36..debaf1e68 100644 --- a/src/Microsoft.AspNet.Authentication.OAuthBearer/OAuthBearerAuthenticationMiddleware.cs +++ b/src/Microsoft.AspNet.Authentication.OAuthBearer/OAuthBearerAuthenticationMiddleware.cs @@ -8,6 +8,7 @@ using System.Net.Http; using Microsoft.AspNet.Authentication; using Microsoft.AspNet.Builder; +using Microsoft.Framework.Internal; using Microsoft.Framework.Logging; using Microsoft.Framework.OptionsModel; using Microsoft.IdentityModel.Protocols; diff --git a/src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenIdConnectAuthenticationMiddleware.cs b/src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenIdConnectAuthenticationMiddleware.cs index 1f4848140..0659a086e 100644 --- a/src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenIdConnectAuthenticationMiddleware.cs +++ b/src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenIdConnectAuthenticationMiddleware.cs @@ -10,13 +10,13 @@ using Microsoft.AspNet.Builder; using Microsoft.AspNet.DataProtection; using Microsoft.AspNet.Http; -using Microsoft.AspNet.Authentication; using Microsoft.AspNet.Authentication.DataHandler; using Microsoft.AspNet.Authentication.DataHandler.Encoder; using Microsoft.AspNet.Authentication.DataHandler.Serializer; using Microsoft.Framework.Logging; using Microsoft.Framework.OptionsModel; using Microsoft.IdentityModel.Protocols; +using Microsoft.Framework.Internal; namespace Microsoft.AspNet.Authentication.OpenIdConnect { diff --git a/src/Microsoft.AspNet.Authentication.Twitter/TwitterAuthenticationMiddleware.cs b/src/Microsoft.AspNet.Authentication.Twitter/TwitterAuthenticationMiddleware.cs index 11ae3b4bd..5e07f7eea 100644 --- a/src/Microsoft.AspNet.Authentication.Twitter/TwitterAuthenticationMiddleware.cs +++ b/src/Microsoft.AspNet.Authentication.Twitter/TwitterAuthenticationMiddleware.cs @@ -10,6 +10,7 @@ using Microsoft.AspNet.Authentication.Twitter.Messages; using Microsoft.AspNet.Builder; using Microsoft.AspNet.DataProtection; +using Microsoft.Framework.Internal; using Microsoft.Framework.Logging; using Microsoft.Framework.OptionsModel; From e2a8efbb64578602828336474d7083e5f7842702 Mon Sep 17 00:00:00 2001 From: Hao Kung Date: Tue, 17 Mar 2015 11:40:58 -0700 Subject: [PATCH 165/216] Cleanup Switch to logging interfaces reference Tweak DenyAnonymous logic Fixes https://github.com/aspnet/Security/issues/181 Fixes https://github.com/aspnet/Security/issues/169 --- src/Microsoft.AspNet.Authentication/project.json | 2 +- .../DefaultAuthorizationService.cs | 16 ++++++---------- .../DenyAnonymousAuthorizationHandler.cs | 7 +++---- src/Microsoft.AspNet.Authorization/project.json | 2 +- .../DefaultAuthorizationServiceTests.cs | 13 ++++++------- 5 files changed, 17 insertions(+), 23 deletions(-) diff --git a/src/Microsoft.AspNet.Authentication/project.json b/src/Microsoft.AspNet.Authentication/project.json index 609f641ad..81b89148d 100644 --- a/src/Microsoft.AspNet.Authentication/project.json +++ b/src/Microsoft.AspNet.Authentication/project.json @@ -6,7 +6,7 @@ "Microsoft.AspNet.RequestContainer": "1.0.0-*", "Microsoft.AspNet.Http.Interfaces": "1.0.0-*", "Microsoft.AspNet.Http.Core": "1.0.0-*", - "Microsoft.Framework.Logging": "1.0.0-*", + "Microsoft.Framework.Logging.Interfaces": "1.0.0-*", "Microsoft.Framework.NotNullAttribute.Internal": { "type": "build", "version": "1.0.0-*" } }, "frameworks": { diff --git a/src/Microsoft.AspNet.Authorization/DefaultAuthorizationService.cs b/src/Microsoft.AspNet.Authorization/DefaultAuthorizationService.cs index d99f778d9..c6e57eb54 100644 --- a/src/Microsoft.AspNet.Authorization/DefaultAuthorizationService.cs +++ b/src/Microsoft.AspNet.Authorization/DefaultAuthorizationService.cs @@ -23,11 +23,9 @@ public DefaultAuthorizationService(IOptions options, IEnum public bool Authorize(ClaimsPrincipal user, object resource, string policyName) { var policy = _options.GetPolicy(policyName); - if (policy == null) - { - return false; - } - return this.Authorize(user, resource, policy); + return (policy == null) + ? false + : this.Authorize(user, resource, policy); } public bool Authorize(ClaimsPrincipal user, object resource, params IAuthorizationRequirement[] requirements) @@ -53,11 +51,9 @@ public async Task AuthorizeAsync(ClaimsPrincipal user, object resource, pa public Task AuthorizeAsync(ClaimsPrincipal user, object resource, string policyName) { var policy = _options.GetPolicy(policyName); - if (policy == null) - { - return Task.FromResult(false); - } - return this.AuthorizeAsync(user, resource, policy); + return (policy == null) + ? Task.FromResult(false) + : this.AuthorizeAsync(user, resource, policy); } } } \ No newline at end of file diff --git a/src/Microsoft.AspNet.Authorization/DenyAnonymousAuthorizationHandler.cs b/src/Microsoft.AspNet.Authorization/DenyAnonymousAuthorizationHandler.cs index 4ce5d43ed..0f6cb3def 100644 --- a/src/Microsoft.AspNet.Authorization/DenyAnonymousAuthorizationHandler.cs +++ b/src/Microsoft.AspNet.Authorization/DenyAnonymousAuthorizationHandler.cs @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -using System.Threading.Tasks; +using System.Linq; namespace Microsoft.AspNet.Authorization { @@ -11,9 +11,8 @@ public override void Handle(AuthorizationContext context, DenyAnonymousAuthoriza { var user = context.User; var userIsAnonymous = - user == null || - user.Identity == null || - !user.Identity.IsAuthenticated; + user?.Identity == null || + !user.Identities.Any(i => i.IsAuthenticated); if (!userIsAnonymous) { context.Succeed(requirement); diff --git a/src/Microsoft.AspNet.Authorization/project.json b/src/Microsoft.AspNet.Authorization/project.json index 3a8701e86..6ebb367aa 100644 --- a/src/Microsoft.AspNet.Authorization/project.json +++ b/src/Microsoft.AspNet.Authorization/project.json @@ -3,7 +3,7 @@ "description": "ASP.NET 5 authorization classes.", "dependencies": { "Microsoft.AspNet.Http.Interfaces": "1.0.0-*", - "Microsoft.Framework.Logging": "1.0.0-*", + "Microsoft.Framework.Logging.Interfaces": "1.0.0-*", "Microsoft.Framework.NotNullAttribute.Internal": { "type": "build", "version": "1.0.0-*" }, "Microsoft.Framework.OptionsModel": "1.0.0-*" }, diff --git a/test/Microsoft.AspNet.Authorization.Test/DefaultAuthorizationServiceTests.cs b/test/Microsoft.AspNet.Authorization.Test/DefaultAuthorizationServiceTests.cs index 4b9b5a33d..74328a956 100644 --- a/test/Microsoft.AspNet.Authorization.Test/DefaultAuthorizationServiceTests.cs +++ b/test/Microsoft.AspNet.Authorization.Test/DefaultAuthorizationServiceTests.cs @@ -549,13 +549,12 @@ public async Task CanApproveAnyAuthenticatedUser() options.AddPolicy("Any", policy => policy.RequireAuthenticatedUser()); }); }); - var user = new ClaimsPrincipal( - new ClaimsIdentity( - new Claim[] { - new Claim(ClaimTypes.Name, "Name"), - }, - "AuthType") - ); + var user = new ClaimsPrincipal(new ClaimsIdentity()); + user.AddIdentity(new ClaimsIdentity( + new Claim[] { + new Claim(ClaimTypes.Name, "Name"), + }, + "AuthType")); // Act var allowed = await authorizationService.AuthorizeAsync(user, null, "Any"); From 33e3c944d06be7453e7e53669e3915dc52ad4792 Mon Sep 17 00:00:00 2001 From: Praburaj Date: Tue, 17 Mar 2015 17:55:13 -0700 Subject: [PATCH 166/216] Reenabling the tests Bug https://github.com/aspnet/HttpAbstractions/issues/231 is fixed --- .../Google/GoogleMiddlewareTests.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/Microsoft.AspNet.Authentication.Test/Google/GoogleMiddlewareTests.cs b/test/Microsoft.AspNet.Authentication.Test/Google/GoogleMiddlewareTests.cs index 45ba05777..c87022011 100644 --- a/test/Microsoft.AspNet.Authentication.Test/Google/GoogleMiddlewareTests.cs +++ b/test/Microsoft.AspNet.Authentication.Test/Google/GoogleMiddlewareTests.cs @@ -112,7 +112,7 @@ public async Task ChallengeWillSetDefaultScope() query.ShouldContain("&scope=" + Uri.EscapeDataString("openid profile email")); } - [Fact(Skip = "Failing due to : https://github.com/aspnet/HttpAbstractions/issues/231")] + [Fact] public async Task Challenge401WillSetDefaultScope() { var server = CreateServer(options => @@ -127,7 +127,7 @@ public async Task Challenge401WillSetDefaultScope() query.ShouldContain("&scope=" + Uri.EscapeDataString("openid profile email")); } - [Fact(Skip = "Failing due to : https://github.com/aspnet/HttpAbstractions/issues/231")] + [Fact] public async Task ChallengeWillUseAuthenticationPropertiesAsParameters() { var server = CreateServer(options => From 6086bb0a622312f49a09d27bf256b8807364e623 Mon Sep 17 00:00:00 2001 From: Praburaj Date: Wed, 18 Mar 2015 15:04:58 -0700 Subject: [PATCH 167/216] Fixing the OpenIdConnect sample --- samples/OpenIdConnectSample/Startup.cs | 1 + samples/OpenIdConnectSample/wwwroot/placeholder.html | 10 ++++++++++ 2 files changed, 11 insertions(+) create mode 100644 samples/OpenIdConnectSample/wwwroot/placeholder.html diff --git a/samples/OpenIdConnectSample/Startup.cs b/samples/OpenIdConnectSample/Startup.cs index c232bc349..40e0f5a77 100644 --- a/samples/OpenIdConnectSample/Startup.cs +++ b/samples/OpenIdConnectSample/Startup.cs @@ -24,6 +24,7 @@ public void Configure(IApplicationBuilder app) app.UseCookieAuthentication(options => { + options.AutomaticAuthentication = true; }); app.UseOpenIdConnectAuthentication(options => diff --git a/samples/OpenIdConnectSample/wwwroot/placeholder.html b/samples/OpenIdConnectSample/wwwroot/placeholder.html new file mode 100644 index 000000000..125a5a8cf --- /dev/null +++ b/samples/OpenIdConnectSample/wwwroot/placeholder.html @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file From 776593ec712931140d325808dae89668e91ac258 Mon Sep 17 00:00:00 2001 From: Hao Kung Date: Thu, 19 Mar 2015 11:04:33 -0700 Subject: [PATCH 168/216] React to hosting changes --- samples/CookieSample/Startup.cs | 10 +-- samples/CookieSessionSample/Startup.cs | 10 +-- samples/OpenIdConnectSample/Startup.cs | 15 ++-- .../CookieAuthenticationMiddleware.cs | 3 +- .../FacebookAuthenticationMiddleware.cs | 3 +- .../FacebookAuthenticatedContext.cs | 1 - .../project.json | 3 +- .../GoogleAuthenticationMiddleware.cs | 4 +- ...icrosoftAccountAuthenticationMiddleware.cs | 4 +- .../OAuthAuthenticationHandler.cs | 4 +- .../OAuthAuthenticationMiddleware.cs | 4 +- .../project.json | 3 +- .../OAuthBearerAuthenticationMiddleware.cs | 3 +- .../OpenIdConnectAuthenticationMiddleware.cs | 3 +- .../TwitterAuthenticationMiddleware.cs | 3 +- .../AuthenticationMiddleware.cs | 37 ++++---- .../project.json | 2 +- .../Cookies/CookieMiddlewareTests.cs | 19 ++--- .../Facebook/FacebookMiddlewareTests.cs | 85 ++++++++++--------- .../Google/GoogleMiddlewareTests.cs | 30 +++---- .../MicrosoftAccountMiddlewareTests.cs | 16 ++-- .../OAuthBearer/OAuthBearerMiddlewareTests.cs | 8 +- .../OpenIdConnectMiddlewareTests.cs | 19 ++--- .../Twitter/TwitterMiddlewareTests.cs | 16 ++-- 24 files changed, 139 insertions(+), 166 deletions(-) diff --git a/samples/CookieSample/Startup.cs b/samples/CookieSample/Startup.cs index d5b0814fa..d7c3e3128 100644 --- a/samples/CookieSample/Startup.cs +++ b/samples/CookieSample/Startup.cs @@ -8,13 +8,13 @@ namespace CookieSample { public class Startup { - public void Configure(IApplicationBuilder app) + public void ConfigureServices(IServiceCollection services) { - app.UseServices(services => - { - services.AddDataProtection(); - }); + services.AddDataProtection(); + } + public void Configure(IApplicationBuilder app) + { app.UseCookieAuthentication(options => { }); diff --git a/samples/CookieSessionSample/Startup.cs b/samples/CookieSessionSample/Startup.cs index dacb7956f..f93777758 100644 --- a/samples/CookieSessionSample/Startup.cs +++ b/samples/CookieSessionSample/Startup.cs @@ -9,13 +9,13 @@ namespace CookieSessionSample { public class Startup { - public void Configure(IApplicationBuilder app) + public void ConfigureServices(IServiceCollection services) { - app.UseServices(services => - { - services.AddDataProtection(); - }); + services.AddDataProtection(); + } + public void Configure(IApplicationBuilder app) + { app.UseCookieAuthentication(options => { options.SessionStore = new MemoryCacheSessionStore(); diff --git a/samples/OpenIdConnectSample/Startup.cs b/samples/OpenIdConnectSample/Startup.cs index 40e0f5a77..cb748b5d6 100644 --- a/samples/OpenIdConnectSample/Startup.cs +++ b/samples/OpenIdConnectSample/Startup.cs @@ -10,18 +10,17 @@ namespace OpenIdConnectSample { public class Startup { - public void Configure(IApplicationBuilder app) + public void ConfigureServices(IServiceCollection services) { - app.UseServices(services => + services.AddDataProtection(); + services.Configure(options => { - services.AddDataProtection(); - services.Configure(options => - { - options.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme; - }); - + options.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme; }); + } + public void Configure(IApplicationBuilder app) + { app.UseCookieAuthentication(options => { options.AutomaticAuthentication = true; diff --git a/src/Microsoft.AspNet.Authentication.Cookies/CookieAuthenticationMiddleware.cs b/src/Microsoft.AspNet.Authentication.Cookies/CookieAuthenticationMiddleware.cs index 2082f2365..0b4afe125 100644 --- a/src/Microsoft.AspNet.Authentication.Cookies/CookieAuthenticationMiddleware.cs +++ b/src/Microsoft.AspNet.Authentication.Cookies/CookieAuthenticationMiddleware.cs @@ -18,12 +18,11 @@ public class CookieAuthenticationMiddleware : AuthenticationMiddleware options, ConfigureOptions configureOptions) - : base(next, services, options, configureOptions) + : base(next, options, configureOptions) { if (Options.Notifications == null) { diff --git a/src/Microsoft.AspNet.Authentication.Facebook/FacebookAuthenticationMiddleware.cs b/src/Microsoft.AspNet.Authentication.Facebook/FacebookAuthenticationMiddleware.cs index d15b8d102..7feacb1d1 100644 --- a/src/Microsoft.AspNet.Authentication.Facebook/FacebookAuthenticationMiddleware.cs +++ b/src/Microsoft.AspNet.Authentication.Facebook/FacebookAuthenticationMiddleware.cs @@ -26,13 +26,12 @@ public class FacebookAuthenticationMiddleware : OAuthAuthenticationMiddlewareConfiguration options for the middleware. public FacebookAuthenticationMiddleware( [NotNull] RequestDelegate next, - [NotNull] IServiceProvider services, [NotNull] IDataProtectionProvider dataProtectionProvider, [NotNull] ILoggerFactory loggerFactory, [NotNull] IOptions externalOptions, [NotNull] IOptions options, ConfigureOptions configureOptions = null) - : base(next, services, dataProtectionProvider, loggerFactory, externalOptions, options, configureOptions) + : base(next, dataProtectionProvider, loggerFactory, externalOptions, options, configureOptions) { if (string.IsNullOrWhiteSpace(Options.AppId)) { diff --git a/src/Microsoft.AspNet.Authentication.Facebook/Notifications/FacebookAuthenticatedContext.cs b/src/Microsoft.AspNet.Authentication.Facebook/Notifications/FacebookAuthenticatedContext.cs index b64f6dd38..084b27347 100644 --- a/src/Microsoft.AspNet.Authentication.Facebook/Notifications/FacebookAuthenticatedContext.cs +++ b/src/Microsoft.AspNet.Authentication.Facebook/Notifications/FacebookAuthenticatedContext.cs @@ -1,7 +1,6 @@ // Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -using System.Net.Http; using Microsoft.AspNet.Http; using Microsoft.AspNet.Authentication.OAuth; using Newtonsoft.Json.Linq; diff --git a/src/Microsoft.AspNet.Authentication.Facebook/project.json b/src/Microsoft.AspNet.Authentication.Facebook/project.json index 0dab9e868..7bce6f458 100644 --- a/src/Microsoft.AspNet.Authentication.Facebook/project.json +++ b/src/Microsoft.AspNet.Authentication.Facebook/project.json @@ -3,7 +3,8 @@ "description": "ASP.NET 5 middleware that enables an application to support Facebook's OAuth 2.0 authentication workflow.", "dependencies": { "Microsoft.AspNet.Authentication.OAuth": "1.0.0-*", - "Microsoft.Framework.NotNullAttribute.Internal": { "type": "build", "version": "1.0.0-*" } + "Microsoft.Framework.NotNullAttribute.Internal": { "type": "build", "version": "1.0.0-*" }, + "Newtonsoft.Json": "6.0.6" }, "frameworks": { "dnx451": { }, diff --git a/src/Microsoft.AspNet.Authentication.Google/GoogleAuthenticationMiddleware.cs b/src/Microsoft.AspNet.Authentication.Google/GoogleAuthenticationMiddleware.cs index 4641bcd0e..73e6b180b 100644 --- a/src/Microsoft.AspNet.Authentication.Google/GoogleAuthenticationMiddleware.cs +++ b/src/Microsoft.AspNet.Authentication.Google/GoogleAuthenticationMiddleware.cs @@ -22,19 +22,17 @@ public class GoogleAuthenticationMiddleware : OAuthAuthenticationMiddleware. /// /// The next middleware in the HTTP pipeline to invoke. - /// /// /// /// Configuration options for the middleware. public GoogleAuthenticationMiddleware( [NotNull] RequestDelegate next, - [NotNull] IServiceProvider services, [NotNull] IDataProtectionProvider dataProtectionProvider, [NotNull] ILoggerFactory loggerFactory, [NotNull] IOptions externalOptions, [NotNull] IOptions options, ConfigureOptions configureOptions = null) - : base(next, services, dataProtectionProvider, loggerFactory, externalOptions, options, configureOptions) + : base(next, dataProtectionProvider, loggerFactory, externalOptions, options, configureOptions) { if (Options.Notifications == null) { diff --git a/src/Microsoft.AspNet.Authentication.MicrosoftAccount/MicrosoftAccountAuthenticationMiddleware.cs b/src/Microsoft.AspNet.Authentication.MicrosoftAccount/MicrosoftAccountAuthenticationMiddleware.cs index 66cdde6bd..7626c7061 100644 --- a/src/Microsoft.AspNet.Authentication.MicrosoftAccount/MicrosoftAccountAuthenticationMiddleware.cs +++ b/src/Microsoft.AspNet.Authentication.MicrosoftAccount/MicrosoftAccountAuthenticationMiddleware.cs @@ -20,19 +20,17 @@ public class MicrosoftAccountAuthenticationMiddleware : OAuthAuthenticationMiddl /// Initializes a new . /// /// The next middleware in the HTTP pipeline to invoke. - /// /// /// /// Configuration options for the middleware. public MicrosoftAccountAuthenticationMiddleware( [NotNull] RequestDelegate next, - [NotNull] IServiceProvider services, [NotNull] IDataProtectionProvider dataProtectionProvider, [NotNull] ILoggerFactory loggerFactory, [NotNull] IOptions externalOptions, [NotNull] IOptions options, ConfigureOptions configureOptions = null) - : base(next, services, dataProtectionProvider, loggerFactory, externalOptions, options, configureOptions) + : base(next, dataProtectionProvider, loggerFactory, externalOptions, options, configureOptions) { if (Options.Notifications == null) { diff --git a/src/Microsoft.AspNet.Authentication.OAuth/OAuthAuthenticationHandler.cs b/src/Microsoft.AspNet.Authentication.OAuth/OAuthAuthenticationHandler.cs index b8696a302..6389b8c1d 100644 --- a/src/Microsoft.AspNet.Authentication.OAuth/OAuthAuthenticationHandler.cs +++ b/src/Microsoft.AspNet.Authentication.OAuth/OAuthAuthenticationHandler.cs @@ -5,12 +5,10 @@ using System.Collections.Generic; using System.Net.Http; using System.Net.Http.Headers; -using System.Security.Claims; using System.Threading.Tasks; using Microsoft.AspNet.Http; -using Microsoft.AspNet.Http.Extensions; using Microsoft.AspNet.Http.Authentication; -using Microsoft.AspNet.Authentication; +using Microsoft.AspNet.Http.Extensions; using Microsoft.AspNet.WebUtilities; using Microsoft.Framework.Logging; using Newtonsoft.Json.Linq; diff --git a/src/Microsoft.AspNet.Authentication.OAuth/OAuthAuthenticationMiddleware.cs b/src/Microsoft.AspNet.Authentication.OAuth/OAuthAuthenticationMiddleware.cs index ef43d309b..8b8e432b3 100644 --- a/src/Microsoft.AspNet.Authentication.OAuth/OAuthAuthenticationMiddleware.cs +++ b/src/Microsoft.AspNet.Authentication.OAuth/OAuthAuthenticationMiddleware.cs @@ -26,19 +26,17 @@ public class OAuthAuthenticationMiddleware : Authentic /// Initializes a new . /// /// The next middleware in the HTTP pipeline to invoke. - /// /// /// /// Configuration options for the middleware. public OAuthAuthenticationMiddleware( [NotNull] RequestDelegate next, - [NotNull] IServiceProvider services, [NotNull] IDataProtectionProvider dataProtectionProvider, [NotNull] ILoggerFactory loggerFactory, [NotNull] IOptions externalOptions, [NotNull] IOptions options, ConfigureOptions configureOptions = null) - : base(next, services, options, configureOptions) + : base(next, options, configureOptions) { // todo: review error handling if (string.IsNullOrWhiteSpace(Options.AuthenticationScheme)) diff --git a/src/Microsoft.AspNet.Authentication.OAuth/project.json b/src/Microsoft.AspNet.Authentication.OAuth/project.json index ab9059a18..215b5155d 100644 --- a/src/Microsoft.AspNet.Authentication.OAuth/project.json +++ b/src/Microsoft.AspNet.Authentication.OAuth/project.json @@ -4,7 +4,8 @@ "dependencies": { "Microsoft.AspNet.DataProtection": "1.0.0-*", "Microsoft.AspNet.Authentication": "1.0.0-*", - "Microsoft.Framework.NotNullAttribute.Internal": { "type": "build", "version": "1.0.0-*" } + "Microsoft.Framework.NotNullAttribute.Internal": { "type": "build", "version": "1.0.0-*" }, + "Newtonsoft.Json": "6.0.6" }, "frameworks": { "dnx451": { diff --git a/src/Microsoft.AspNet.Authentication.OAuthBearer/OAuthBearerAuthenticationMiddleware.cs b/src/Microsoft.AspNet.Authentication.OAuthBearer/OAuthBearerAuthenticationMiddleware.cs index debaf1e68..9ab829c5d 100644 --- a/src/Microsoft.AspNet.Authentication.OAuthBearer/OAuthBearerAuthenticationMiddleware.cs +++ b/src/Microsoft.AspNet.Authentication.OAuthBearer/OAuthBearerAuthenticationMiddleware.cs @@ -31,11 +31,10 @@ public class OAuthBearerAuthenticationMiddleware : AuthenticationMiddleware public OAuthBearerAuthenticationMiddleware( [NotNull] RequestDelegate next, - [NotNull] IServiceProvider services, [NotNull] ILoggerFactory loggerFactory, [NotNull] IOptions options, ConfigureOptions configureOptions) - : base(next, services, options, configureOptions) + : base(next, options, configureOptions) { _logger = loggerFactory.CreateLogger(); if (Options.Notifications == null) diff --git a/src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenIdConnectAuthenticationMiddleware.cs b/src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenIdConnectAuthenticationMiddleware.cs index 0659a086e..53284a50e 100644 --- a/src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenIdConnectAuthenticationMiddleware.cs +++ b/src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenIdConnectAuthenticationMiddleware.cs @@ -36,13 +36,12 @@ public class OpenIdConnectAuthenticationMiddleware : AuthenticationMiddleware externalOptions, [NotNull] IOptions options, ConfigureOptions configureOptions) - : base(next, services, options, configureOptions) + : base(next, options, configureOptions) { _logger = loggerFactory.CreateLogger(); diff --git a/src/Microsoft.AspNet.Authentication.Twitter/TwitterAuthenticationMiddleware.cs b/src/Microsoft.AspNet.Authentication.Twitter/TwitterAuthenticationMiddleware.cs index 5e07f7eea..63534a85f 100644 --- a/src/Microsoft.AspNet.Authentication.Twitter/TwitterAuthenticationMiddleware.cs +++ b/src/Microsoft.AspNet.Authentication.Twitter/TwitterAuthenticationMiddleware.cs @@ -35,13 +35,12 @@ public class TwitterAuthenticationMiddleware : AuthenticationMiddlewareConfiguration options for the middleware public TwitterAuthenticationMiddleware( [NotNull] RequestDelegate next, - [NotNull] IServiceProvider services, [NotNull] IDataProtectionProvider dataProtectionProvider, [NotNull] ILoggerFactory loggerFactory, [NotNull] IOptions externalOptions, [NotNull] IOptions options, ConfigureOptions configureOptions = null) - : base(next, services, options, configureOptions) + : base(next, options, configureOptions) { if (string.IsNullOrWhiteSpace(Options.ConsumerSecret)) { diff --git a/src/Microsoft.AspNet.Authentication/AuthenticationMiddleware.cs b/src/Microsoft.AspNet.Authentication/AuthenticationMiddleware.cs index a9482ed46..b9eaa36f8 100644 --- a/src/Microsoft.AspNet.Authentication/AuthenticationMiddleware.cs +++ b/src/Microsoft.AspNet.Authentication/AuthenticationMiddleware.cs @@ -5,7 +5,6 @@ using System.Threading.Tasks; using Microsoft.AspNet.Builder; using Microsoft.AspNet.Http; -using Microsoft.AspNet.RequestContainer; using Microsoft.Framework.Internal; using Microsoft.Framework.OptionsModel; @@ -14,11 +13,9 @@ namespace Microsoft.AspNet.Authentication public abstract class AuthenticationMiddleware where TOptions : AuthenticationOptions, new() { private readonly RequestDelegate _next; - private readonly IServiceProvider _services; protected AuthenticationMiddleware( [NotNull] RequestDelegate next, - [NotNull] IServiceProvider services, [NotNull] IOptions options, ConfigureOptions configureOptions) { @@ -32,7 +29,6 @@ protected AuthenticationMiddleware( Options = options.Options; } _next = next; - _services = services; } public string AuthenticationScheme { get; set; } @@ -41,32 +37,29 @@ protected AuthenticationMiddleware( public async Task Invoke(HttpContext context) { - using (RequestServicesContainer.EnsureRequestServices(context, _services)) + AuthenticationHandler handler = CreateHandler(); + await handler.Initialize(Options, context); + try + { + if (!await handler.InvokeAsync()) + { + await _next(context); + } + } + catch (Exception) { - AuthenticationHandler handler = CreateHandler(); - await handler.Initialize(Options, context); try { - if (!await handler.InvokeAsync()) - { - await _next(context); - } + handler.Faulted = true; + await handler.TeardownAsync(); } catch (Exception) { - try - { - handler.Faulted = true; - await handler.TeardownAsync(); - } - catch (Exception) - { - // Don't mask the original exception - } - throw; + // Don't mask the original exception } - await handler.TeardownAsync(); + throw; } + await handler.TeardownAsync(); } protected abstract AuthenticationHandler CreateHandler(); diff --git a/src/Microsoft.AspNet.Authentication/project.json b/src/Microsoft.AspNet.Authentication/project.json index 81b89148d..83840f36c 100644 --- a/src/Microsoft.AspNet.Authentication/project.json +++ b/src/Microsoft.AspNet.Authentication/project.json @@ -3,9 +3,9 @@ "description": "ASP.NET 5 common types used by the various authentication middleware.", "dependencies": { "Microsoft.AspNet.DataProtection": "1.0.0-*", - "Microsoft.AspNet.RequestContainer": "1.0.0-*", "Microsoft.AspNet.Http.Interfaces": "1.0.0-*", "Microsoft.AspNet.Http.Core": "1.0.0-*", + "Microsoft.AspNet.Http.Extensions": "1.0.0-*", "Microsoft.Framework.Logging.Interfaces": "1.0.0-*", "Microsoft.Framework.NotNullAttribute.Internal": { "type": "build", "version": "1.0.0-*" } }, diff --git a/test/Microsoft.AspNet.Authentication.Test/Cookies/CookieMiddlewareTests.cs b/test/Microsoft.AspNet.Authentication.Test/Cookies/CookieMiddlewareTests.cs index ea3885650..0a0e5a8da 100644 --- a/test/Microsoft.AspNet.Authentication.Test/Cookies/CookieMiddlewareTests.cs +++ b/test/Microsoft.AspNet.Authentication.Test/Cookies/CookieMiddlewareTests.cs @@ -524,17 +524,6 @@ private static TestServer CreateServer(Action confi { var server = TestServer.Create(app => { - if (claimsTransform != null) - { - app.UseServices(services => { - services.AddDataProtection(); - services.ConfigureClaimsTransformation(claimsTransform); - }); - } - else - { - app.UseServices(services => services.AddDataProtection()); - } app.UseCookieAuthentication(configureOptions); if (claimsTransform != null) { @@ -581,6 +570,14 @@ private static TestServer CreateServer(Action confi await next(); } }); + }, + services => + { + services.AddDataProtection(); + if (claimsTransform != null) + { + services.ConfigureClaimsTransformation(claimsTransform); + } }); server.BaseAddress = baseAddress; return server; diff --git a/test/Microsoft.AspNet.Authentication.Test/Facebook/FacebookMiddlewareTests.cs b/test/Microsoft.AspNet.Authentication.Test/Facebook/FacebookMiddlewareTests.cs index ba00fb125..fd349582f 100644 --- a/test/Microsoft.AspNet.Authentication.Test/Facebook/FacebookMiddlewareTests.cs +++ b/test/Microsoft.AspNet.Authentication.Test/Facebook/FacebookMiddlewareTests.cs @@ -24,33 +24,33 @@ public async Task ChallengeWillTriggerApplyRedirectEvent() var server = CreateServer( app => { - app.UseServices(services => + app.UseFacebookAuthentication(); + app.UseCookieAuthentication(); + }, + services => + { + services.AddDataProtection(); + services.ConfigureFacebookAuthentication(options => { - services.AddDataProtection(); - services.ConfigureFacebookAuthentication(options => + options.AppId = "Test App Id"; + options.AppSecret = "Test App Secret"; + options.Notifications = new FacebookAuthenticationNotifications { - options.AppId = "Test App Id"; - options.AppSecret = "Test App Secret"; - options.Notifications = new FacebookAuthenticationNotifications + OnApplyRedirect = context => { - OnApplyRedirect = context => - { - context.Response.Redirect(context.RedirectUri + "&custom=test"); - } - }; - }); - services.ConfigureCookieAuthentication(options => - { - options.AuthenticationScheme = "External"; - options.AutomaticAuthentication = true; - }); - services.Configure(options => - { - options.SignInScheme = "External"; - }); + context.Response.Redirect(context.RedirectUri + "&custom=test"); + } + }; + }); + services.ConfigureCookieAuthentication(options => + { + options.AuthenticationScheme = "External"; + options.AutomaticAuthentication = true; + }); + services.Configure(options => + { + options.SignInScheme = "External"; }); - app.UseFacebookAuthentication(); - app.UseCookieAuthentication(); }, context => { @@ -69,26 +69,26 @@ public async Task ChallengeWillTriggerRedirection() var server = CreateServer( app => { - app.UseServices(services => - { - services.AddDataProtection(); - services.ConfigureFacebookAuthentication(options => - { - options.AppId = "Test App Id"; - options.AppSecret = "Test App Secret"; - }); - services.ConfigureCookieAuthentication(options => - { - options.AuthenticationScheme = "External"; - }); - services.Configure(options => - { - options.SignInScheme = "External"; - }); - }); app.UseFacebookAuthentication(); app.UseCookieAuthentication(); }, + services => + { + services.AddDataProtection(); + services.ConfigureFacebookAuthentication(options => + { + options.AppId = "Test App Id"; + options.AppSecret = "Test App Secret"; + }); + services.ConfigureCookieAuthentication(options => + { + options.AuthenticationScheme = "External"; + }); + services.Configure(options => + { + options.SignInScheme = "External"; + }); + }, context => { context.Response.Challenge("Facebook"); @@ -105,7 +105,7 @@ public async Task ChallengeWillTriggerRedirection() location.ShouldContain("state="); } - private static TestServer CreateServer(Action configure, Func handler) + private static TestServer CreateServer(Action configure, Action configureServices, Func handler) { return TestServer.Create(app => { @@ -120,7 +120,8 @@ private static TestServer CreateServer(Action configure, Fu await next(); } }); - }); + }, + configureServices); } private static async Task SendAsync(TestServer server, string uri, string cookieHeader = null) diff --git a/test/Microsoft.AspNet.Authentication.Test/Google/GoogleMiddlewareTests.cs b/test/Microsoft.AspNet.Authentication.Test/Google/GoogleMiddlewareTests.cs index c87022011..33612b7ef 100644 --- a/test/Microsoft.AspNet.Authentication.Test/Google/GoogleMiddlewareTests.cs +++ b/test/Microsoft.AspNet.Authentication.Test/Google/GoogleMiddlewareTests.cs @@ -482,21 +482,6 @@ private static TestServer CreateServer(Action confi { return TestServer.Create(app => { - app.UseServices(services => - { - services.AddDataProtection(); - services.Configure(options => - { - options.SignInScheme = CookieAuthenticationScheme; - }); - services.ConfigureClaimsTransformation(p => - { - var id = new ClaimsIdentity("xform"); - id.AddClaim(new Claim("xform", "yup")); - p.AddIdentity(id); - return p; - }); - }); app.UseCookieAuthentication(options => { options.AuthenticationScheme = CookieAuthenticationScheme; @@ -542,6 +527,21 @@ private static TestServer CreateServer(Action confi await next(); } }); + }, + services => + { + services.AddDataProtection(); + services.Configure(options => + { + options.SignInScheme = CookieAuthenticationScheme; + }); + services.ConfigureClaimsTransformation(p => + { + var id = new ClaimsIdentity("xform"); + id.AddClaim(new Claim("xform", "yup")); + p.AddIdentity(id); + return p; + }); }); } diff --git a/test/Microsoft.AspNet.Authentication.Test/MicrosoftAccount/MicrosoftAccountMiddlewareTests.cs b/test/Microsoft.AspNet.Authentication.Test/MicrosoftAccount/MicrosoftAccountMiddlewareTests.cs index 48372859d..0f22e3ac7 100644 --- a/test/Microsoft.AspNet.Authentication.Test/MicrosoftAccount/MicrosoftAccountMiddlewareTests.cs +++ b/test/Microsoft.AspNet.Authentication.Test/MicrosoftAccount/MicrosoftAccountMiddlewareTests.cs @@ -161,14 +161,6 @@ private static TestServer CreateServer(Action { - app.UseServices(services => - { - services.AddDataProtection(); - services.Configure(options => - { - options.SignInScheme = "External"; - }); - }); app.UseCookieAuthentication(options => { options.AuthenticationScheme = "External"; @@ -182,6 +174,14 @@ private static TestServer CreateServer(Action + { + services.AddDataProtection(); + services.Configure(options => + { + options.SignInScheme = "External"; + }); }); } diff --git a/test/Microsoft.AspNet.Authentication.Test/OAuthBearer/OAuthBearerMiddlewareTests.cs b/test/Microsoft.AspNet.Authentication.Test/OAuthBearer/OAuthBearerMiddlewareTests.cs index ffbc1a0a4..fcd2d411e 100644 --- a/test/Microsoft.AspNet.Authentication.Test/OAuthBearer/OAuthBearerMiddlewareTests.cs +++ b/test/Microsoft.AspNet.Authentication.Test/OAuthBearer/OAuthBearerMiddlewareTests.cs @@ -233,11 +233,6 @@ private static TestServer CreateServer(Action { return TestServer.Create(app => { - app.UseServices(services => - { - services.AddDataProtection(); - }); - if (configureOptions != null) { app.UseOAuthBearerAuthentication(configureOptions); @@ -261,7 +256,8 @@ private static TestServer CreateServer(Action } }); - }); + }, + services => services.AddDataProtection()); } private static async Task SendAsync(TestServer server, string uri, string authorizationHeader = null) diff --git a/test/Microsoft.AspNet.Authentication.Test/OpenIdConnect/OpenIdConnectMiddlewareTests.cs b/test/Microsoft.AspNet.Authentication.Test/OpenIdConnect/OpenIdConnectMiddlewareTests.cs index 7681d5466..bec9f1bf3 100644 --- a/test/Microsoft.AspNet.Authentication.Test/OpenIdConnect/OpenIdConnectMiddlewareTests.cs +++ b/test/Microsoft.AspNet.Authentication.Test/OpenIdConnect/OpenIdConnectMiddlewareTests.cs @@ -193,15 +193,6 @@ private static TestServer CreateServer(Action { - app.UseServices(services => - { - services.AddDataProtection(); - services.Configure(options => - { - options.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme; - }); - }); - app.UseCookieAuthentication(options => { options.AuthenticationScheme = "OpenIdConnect"; @@ -228,7 +219,7 @@ private static TestServer CreateServer(Action + { + services.AddDataProtection(); + services.Configure(options => + { + options.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme; + }); }); } diff --git a/test/Microsoft.AspNet.Authentication.Test/Twitter/TwitterMiddlewareTests.cs b/test/Microsoft.AspNet.Authentication.Test/Twitter/TwitterMiddlewareTests.cs index fd281086f..75220f921 100644 --- a/test/Microsoft.AspNet.Authentication.Test/Twitter/TwitterMiddlewareTests.cs +++ b/test/Microsoft.AspNet.Authentication.Test/Twitter/TwitterMiddlewareTests.cs @@ -105,14 +105,6 @@ private static TestServer CreateServer(Action configure, Fu { return TestServer.Create(app => { - app.UseServices(services => - { - services.AddDataProtection(); - services.Configure(options => - { - options.SignInScheme = "External"; - }); - }); app.UseCookieAuthentication(options => { options.AuthenticationScheme = "External"; @@ -128,6 +120,14 @@ private static TestServer CreateServer(Action configure, Fu await next(); } }); + }, + services => + { + services.AddDataProtection(); + services.Configure(options => + { + options.SignInScheme = "External"; + }); }); } From aae2e630b40cf1c5160d3c244dde16d870d7306a Mon Sep 17 00:00:00 2001 From: Hao Kung Date: Thu, 19 Mar 2015 11:43:03 -0700 Subject: [PATCH 169/216] Fix samples --- samples/SocialSample/Startup.cs | 40 ++++++++++++++++----------------- 1 file changed, 19 insertions(+), 21 deletions(-) diff --git a/samples/SocialSample/Startup.cs b/samples/SocialSample/Startup.cs index bc7d61b4a..0d0c78838 100644 --- a/samples/SocialSample/Startup.cs +++ b/samples/SocialSample/Startup.cs @@ -1,16 +1,14 @@ using System.Net.Http; using System.Net.Http.Headers; using System.Security.Claims; -using System.Threading.Tasks; -using Microsoft.AspNet.Builder; -using Microsoft.AspNet.DataProtection; -using Microsoft.AspNet.Http; -using Microsoft.AspNet.Http.Authentication; using Microsoft.AspNet.Authentication; using Microsoft.AspNet.Authentication.Cookies; using Microsoft.AspNet.Authentication.Google; using Microsoft.AspNet.Authentication.MicrosoftAccount; using Microsoft.AspNet.Authentication.OAuth; +using Microsoft.AspNet.Builder; +using Microsoft.AspNet.Http; +using Microsoft.AspNet.Http.Authentication; using Microsoft.Framework.DependencyInjection; using Newtonsoft.Json.Linq; @@ -18,25 +16,25 @@ namespace CookieSample { public class Startup { - public void Configure(IApplicationBuilder app) + public void ConfigureServices(IServiceCollection services) { - app.UseErrorPage(); - - app.UseServices(services => + services.AddDataProtection(); + services.Configure(options => { - services.AddDataProtection(); - services.Configure(options => - { - options.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme; - }); - services.ConfigureClaimsTransformation(p => - { - var id = new ClaimsIdentity("xform"); - id.AddClaim(new Claim("ClaimsTransformation", "TransformAddedClaim")); - p.AddIdentity(id); - return p; - }); + options.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme; + }); + services.ConfigureClaimsTransformation(p => + { + var id = new ClaimsIdentity("xform"); + id.AddClaim(new Claim("ClaimsTransformation", "TransformAddedClaim")); + p.AddIdentity(id); + return p; }); + } + + public void Configure(IApplicationBuilder app) + { + app.UseErrorPage(); app.UseCookieAuthentication(options => { From 4a5b9f6b6ecad91d8f7461c9c8cce5f31c020a01 Mon Sep 17 00:00:00 2001 From: Praburaj Date: Mon, 23 Mar 2015 21:34:26 -0700 Subject: [PATCH 170/216] Add a description for the OpenIdConnect package --- src/Microsoft.AspNet.Authentication.OpenIdConnect/project.json | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Microsoft.AspNet.Authentication.OpenIdConnect/project.json b/src/Microsoft.AspNet.Authentication.OpenIdConnect/project.json index acf34b5c2..ec4f879b5 100644 --- a/src/Microsoft.AspNet.Authentication.OpenIdConnect/project.json +++ b/src/Microsoft.AspNet.Authentication.OpenIdConnect/project.json @@ -1,5 +1,6 @@ { "version": "1.0.0-*", + "description": "ASP.NET 5 middleware that enables an application to support OpenIdConnect authentication workflow.", "dependencies": { "Microsoft.AspNet.Authentication": "1.0.0-*", "Microsoft.Framework.NotNullAttribute.Internal": { "type": "build", "version": "1.0.0-*" }, From 3860951100e8d542136ef5e8f22aa59e29d54928 Mon Sep 17 00:00:00 2001 From: Wei Wang Date: Tue, 24 Mar 2015 22:35:54 -0700 Subject: [PATCH 171/216] Remove k command and use dnx instead --- build.sh | 2 +- samples/SocialSample/Startup.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/build.sh b/build.sh index ec3263114..d81164353 100644 --- a/build.sh +++ b/build.sh @@ -31,7 +31,7 @@ if ! type dnvm > /dev/null 2>&1; then source packages/KoreBuild/build/dnvm.sh fi -if ! type k > /dev/null 2>&1; then +if ! type dnx > /dev/null 2>&1; then dnvm upgrade fi diff --git a/samples/SocialSample/Startup.cs b/samples/SocialSample/Startup.cs index 0d0c78838..ffc723126 100644 --- a/samples/SocialSample/Startup.cs +++ b/samples/SocialSample/Startup.cs @@ -89,7 +89,7 @@ Then you can choose to run the app as admin (see below) or add the following ACL netsh http add urlacl url=http://mssecsample.localhost.this:54540/ user=[domain\user] The sample app can then be run via: - k web + dnx . web */ app.UseOAuthAuthentication("Microsoft-AccessToken", options => { From fb871109c7cbc40535faafe3f6bb7bf92be54d09 Mon Sep 17 00:00:00 2001 From: suhasj Date: Wed, 25 Mar 2015 11:47:34 -0700 Subject: [PATCH 172/216] Updating to release NuGet.config --- NuGet.Config | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/NuGet.Config b/NuGet.Config index da57d4726..1978dc065 100644 --- a/NuGet.Config +++ b/NuGet.Config @@ -1,7 +1,7 @@  - + - \ No newline at end of file + From 101b719994ae7d4cae8adb2973277563483a02a7 Mon Sep 17 00:00:00 2001 From: Praburaj Date: Mon, 30 Mar 2015 19:10:57 -0700 Subject: [PATCH 173/216] Changing Wilson packages to beta4 --- src/Microsoft.AspNet.Authentication.OAuthBearer/project.json | 4 ++-- .../project.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Microsoft.AspNet.Authentication.OAuthBearer/project.json b/src/Microsoft.AspNet.Authentication.OAuthBearer/project.json index 504d1eea1..5a4a13138 100644 --- a/src/Microsoft.AspNet.Authentication.OAuthBearer/project.json +++ b/src/Microsoft.AspNet.Authentication.OAuthBearer/project.json @@ -4,8 +4,8 @@ "dependencies": { "Microsoft.AspNet.Authentication": "1.0.0-*", "Microsoft.Framework.NotNullAttribute.Internal": { "type": "build", "version": "1.0.0-*" }, - "Microsoft.IdentityModel.Protocol.Extensions": "2.0.0-beta1-*", - "System.IdentityModel.Tokens": "5.0.0-beta1-*" + "Microsoft.IdentityModel.Protocol.Extensions": "2.0.0-beta4-*", + "System.IdentityModel.Tokens": "5.0.0-beta4-*" }, "frameworks": { "dnx451": { diff --git a/src/Microsoft.AspNet.Authentication.OpenIdConnect/project.json b/src/Microsoft.AspNet.Authentication.OpenIdConnect/project.json index ec4f879b5..5f8e6d67a 100644 --- a/src/Microsoft.AspNet.Authentication.OpenIdConnect/project.json +++ b/src/Microsoft.AspNet.Authentication.OpenIdConnect/project.json @@ -4,7 +4,7 @@ "dependencies": { "Microsoft.AspNet.Authentication": "1.0.0-*", "Microsoft.Framework.NotNullAttribute.Internal": { "type": "build", "version": "1.0.0-*" }, - "Microsoft.IdentityModel.Protocol.Extensions": "2.0.0-beta1-*" + "Microsoft.IdentityModel.Protocol.Extensions": "2.0.0-beta4-*" }, "frameworks": { "dnx451": { From ffd2489f6cd31eb4333712008c33fdc352abd2e4 Mon Sep 17 00:00:00 2001 From: Praburaj Date: Mon, 30 Mar 2015 19:11:44 -0700 Subject: [PATCH 174/216] Revert "Changing Wilson packages to beta4" This reverts commit 101b719994ae7d4cae8adb2973277563483a02a7. --- src/Microsoft.AspNet.Authentication.OAuthBearer/project.json | 4 ++-- .../project.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Microsoft.AspNet.Authentication.OAuthBearer/project.json b/src/Microsoft.AspNet.Authentication.OAuthBearer/project.json index 5a4a13138..504d1eea1 100644 --- a/src/Microsoft.AspNet.Authentication.OAuthBearer/project.json +++ b/src/Microsoft.AspNet.Authentication.OAuthBearer/project.json @@ -4,8 +4,8 @@ "dependencies": { "Microsoft.AspNet.Authentication": "1.0.0-*", "Microsoft.Framework.NotNullAttribute.Internal": { "type": "build", "version": "1.0.0-*" }, - "Microsoft.IdentityModel.Protocol.Extensions": "2.0.0-beta4-*", - "System.IdentityModel.Tokens": "5.0.0-beta4-*" + "Microsoft.IdentityModel.Protocol.Extensions": "2.0.0-beta1-*", + "System.IdentityModel.Tokens": "5.0.0-beta1-*" }, "frameworks": { "dnx451": { diff --git a/src/Microsoft.AspNet.Authentication.OpenIdConnect/project.json b/src/Microsoft.AspNet.Authentication.OpenIdConnect/project.json index 5f8e6d67a..ec4f879b5 100644 --- a/src/Microsoft.AspNet.Authentication.OpenIdConnect/project.json +++ b/src/Microsoft.AspNet.Authentication.OpenIdConnect/project.json @@ -4,7 +4,7 @@ "dependencies": { "Microsoft.AspNet.Authentication": "1.0.0-*", "Microsoft.Framework.NotNullAttribute.Internal": { "type": "build", "version": "1.0.0-*" }, - "Microsoft.IdentityModel.Protocol.Extensions": "2.0.0-beta4-*" + "Microsoft.IdentityModel.Protocol.Extensions": "2.0.0-beta1-*" }, "frameworks": { "dnx451": { From 1a37bf17475ce64bb4664aa7fb96b07cbf28eb92 Mon Sep 17 00:00:00 2001 From: Praburaj Date: Tue, 31 Mar 2015 10:34:44 -0700 Subject: [PATCH 175/216] Changing Wilson package versions to beta4 --- src/Microsoft.AspNet.Authentication.OAuthBearer/project.json | 3 +-- src/Microsoft.AspNet.Authentication.OpenIdConnect/project.json | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/Microsoft.AspNet.Authentication.OAuthBearer/project.json b/src/Microsoft.AspNet.Authentication.OAuthBearer/project.json index 504d1eea1..570eb8346 100644 --- a/src/Microsoft.AspNet.Authentication.OAuthBearer/project.json +++ b/src/Microsoft.AspNet.Authentication.OAuthBearer/project.json @@ -4,8 +4,7 @@ "dependencies": { "Microsoft.AspNet.Authentication": "1.0.0-*", "Microsoft.Framework.NotNullAttribute.Internal": { "type": "build", "version": "1.0.0-*" }, - "Microsoft.IdentityModel.Protocol.Extensions": "2.0.0-beta1-*", - "System.IdentityModel.Tokens": "5.0.0-beta1-*" + "Microsoft.IdentityModel.Protocol.Extensions": "2.0.0-beta4-*" }, "frameworks": { "dnx451": { diff --git a/src/Microsoft.AspNet.Authentication.OpenIdConnect/project.json b/src/Microsoft.AspNet.Authentication.OpenIdConnect/project.json index ec4f879b5..5f8e6d67a 100644 --- a/src/Microsoft.AspNet.Authentication.OpenIdConnect/project.json +++ b/src/Microsoft.AspNet.Authentication.OpenIdConnect/project.json @@ -4,7 +4,7 @@ "dependencies": { "Microsoft.AspNet.Authentication": "1.0.0-*", "Microsoft.Framework.NotNullAttribute.Internal": { "type": "build", "version": "1.0.0-*" }, - "Microsoft.IdentityModel.Protocol.Extensions": "2.0.0-beta1-*" + "Microsoft.IdentityModel.Protocol.Extensions": "2.0.0-beta4-*" }, "frameworks": { "dnx451": { From 5a6c90882a77536eca98136d68c7e4171ada534e Mon Sep 17 00:00:00 2001 From: "N. Taylor Mullen" Date: Wed, 1 Apr 2015 15:55:21 -0700 Subject: [PATCH 176/216] Add travis and appveyor CI support. --- .travis.yml | 3 +++ appveyor.yml | 5 +++++ build.sh | 0 test/Microsoft.AspNet.Authentication.Test/project.json | 2 +- test/Microsoft.AspNet.Authorization.Test/project.json | 2 +- 5 files changed, 10 insertions(+), 2 deletions(-) create mode 100644 .travis.yml create mode 100644 appveyor.yml mode change 100644 => 100755 build.sh diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 000000000..0f4cb93e5 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,3 @@ +language: csharp +script: + - ./build.sh verify \ No newline at end of file diff --git a/appveyor.yml b/appveyor.yml new file mode 100644 index 000000000..88cb9ef14 --- /dev/null +++ b/appveyor.yml @@ -0,0 +1,5 @@ +build_script: + - build.cmd verify +clone_depth: 1 +test: off +deploy: off \ No newline at end of file diff --git a/build.sh b/build.sh old mode 100644 new mode 100755 diff --git a/test/Microsoft.AspNet.Authentication.Test/project.json b/test/Microsoft.AspNet.Authentication.Test/project.json index c19e99dbc..2d88d7988 100644 --- a/test/Microsoft.AspNet.Authentication.Test/project.json +++ b/test/Microsoft.AspNet.Authentication.Test/project.json @@ -1,6 +1,6 @@ { "compilationOptions": { - "warningsAsErrors": true + "warningsAsErrors": "true" }, "dependencies": { "Microsoft.AspNet.Authentication.Cookies": "1.0.0-*", diff --git a/test/Microsoft.AspNet.Authorization.Test/project.json b/test/Microsoft.AspNet.Authorization.Test/project.json index 11667dc4e..065ecb7d3 100644 --- a/test/Microsoft.AspNet.Authorization.Test/project.json +++ b/test/Microsoft.AspNet.Authorization.Test/project.json @@ -1,6 +1,6 @@ { "compilationOptions": { - "warningsAsErrors": true + "warningsAsErrors": "true" }, "dependencies": { "Microsoft.AspNet.Authorization": "1.0.0-*", From e25ae018c3655ae55e292f2faafccaae52fe45a4 Mon Sep 17 00:00:00 2001 From: "N. Taylor Mullen" Date: Wed, 1 Apr 2015 17:07:53 -0700 Subject: [PATCH 177/216] Turn off sudo for .travis.yml. --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index 0f4cb93e5..5939a529e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,3 +1,4 @@ language: csharp +sudo: false script: - ./build.sh verify \ No newline at end of file From 568a48ff83027ab0b6fd0798dcc2acd529754415 Mon Sep 17 00:00:00 2001 From: Troy Dai Date: Thu, 2 Apr 2015 09:20:31 -0700 Subject: [PATCH 178/216] Update global.json, sources=>projects --- global.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/global.json b/global.json index 840c36f6a..983ba0401 100644 --- a/global.json +++ b/global.json @@ -1,3 +1,3 @@ { - "sources": ["src"] -} \ No newline at end of file + "projects": ["src"] +} From 440e782f8b1f2c02591372d5d237749b431692e8 Mon Sep 17 00:00:00 2001 From: Doug Bunting Date: Thu, 2 Apr 2015 13:49:29 -0700 Subject: [PATCH 179/216] Update .xproj files for Microsoft.Web.AspNet.* -> Microsoft.DNX.* rename --- samples/CookieSample/CookieSample.xproj | 4 ++-- samples/CookieSessionSample/CookieSessionSample.xproj | 4 ++-- samples/OpenIdConnectSample/OpenIdConnectSample.xproj | 6 +++--- samples/SocialSample/SocialSample.xproj | 4 ++-- .../Microsoft.AspNet.Authentication.Cookies.xproj | 4 ++-- .../Microsoft.AspNet.Authentication.Facebook.xproj | 4 ++-- .../Microsoft.AspNet.Authentication.Google.xproj | 4 ++-- ...Microsoft.AspNet.Authentication.MicrosoftAccount.xproj | 4 ++-- .../Microsoft.AspNet.Authentication.OAuth.xproj | 4 ++-- .../Microsoft.AspNet.Authentication.OAuthBearer.xproj | 6 +++--- .../Microsoft.AspNet.Authentication.OpenIdConnect.xproj | 4 ++-- .../Microsoft.AspNet.Authentication.Twitter.xproj | 4 ++-- .../Microsoft.AspNet.Authentication.xproj | 4 ++-- .../Microsoft.AspNet.Authorization.xproj | 4 ++-- .../Microsoft.AspNet.Authentication.Tests.xproj | 8 ++++---- .../Microsoft.AspNet.Authorization.Tests.xproj | 4 ++-- 16 files changed, 36 insertions(+), 36 deletions(-) diff --git a/samples/CookieSample/CookieSample.xproj b/samples/CookieSample/CookieSample.xproj index 68fbee01b..50d06f00e 100644 --- a/samples/CookieSample/CookieSample.xproj +++ b/samples/CookieSample/CookieSample.xproj @@ -4,7 +4,7 @@ 14.0 $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) - + 558c2c2a-aed8-49de-bb60-d5f8ae06c714 ..\..\artifacts\obj\$(MSBuildProjectName) @@ -14,5 +14,5 @@ 2.0 22569 - + \ No newline at end of file diff --git a/samples/CookieSessionSample/CookieSessionSample.xproj b/samples/CookieSessionSample/CookieSessionSample.xproj index e129ba553..ec3d4dd5e 100644 --- a/samples/CookieSessionSample/CookieSessionSample.xproj +++ b/samples/CookieSessionSample/CookieSessionSample.xproj @@ -4,7 +4,7 @@ 14.0 $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) - + 19711880-46da-4a26-9e0f-9b2e41d27651 ..\..\artifacts\obj\$(MSBuildProjectName) @@ -14,5 +14,5 @@ 2.0 36505 - + \ No newline at end of file diff --git a/samples/OpenIdConnectSample/OpenIdConnectSample.xproj b/samples/OpenIdConnectSample/OpenIdConnectSample.xproj index 1f6d87ba4..1f0879ea4 100644 --- a/samples/OpenIdConnectSample/OpenIdConnectSample.xproj +++ b/samples/OpenIdConnectSample/OpenIdConnectSample.xproj @@ -4,7 +4,7 @@ 14.0 $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) - + bef0f5c3-ef4e-4649-9c49-d5e279a3ca2b ..\..\artifacts\obj\$(MSBuildProjectName) @@ -14,5 +14,5 @@ 2.0 42023 - - + + \ No newline at end of file diff --git a/samples/SocialSample/SocialSample.xproj b/samples/SocialSample/SocialSample.xproj index 74aaf1222..d12b8fcbf 100644 --- a/samples/SocialSample/SocialSample.xproj +++ b/samples/SocialSample/SocialSample.xproj @@ -4,7 +4,7 @@ 14.0 $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) - + 8c73d216-332d-41d8-bfd0-45bc4bc36552 ..\..\artifacts\obj\$(MSBuildProjectName) @@ -14,5 +14,5 @@ 2.0 36504 - + \ No newline at end of file diff --git a/src/Microsoft.AspNet.Authentication.Cookies/Microsoft.AspNet.Authentication.Cookies.xproj b/src/Microsoft.AspNet.Authentication.Cookies/Microsoft.AspNet.Authentication.Cookies.xproj index 10ebb695f..bc93d6322 100644 --- a/src/Microsoft.AspNet.Authentication.Cookies/Microsoft.AspNet.Authentication.Cookies.xproj +++ b/src/Microsoft.AspNet.Authentication.Cookies/Microsoft.AspNet.Authentication.Cookies.xproj @@ -4,7 +4,7 @@ 14.0 $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) - + fc152cc4-054b-457e-8d91-389c5de3c561 ..\..\artifacts\obj\$(MSBuildProjectName) @@ -13,5 +13,5 @@ 2.0 - + \ No newline at end of file diff --git a/src/Microsoft.AspNet.Authentication.Facebook/Microsoft.AspNet.Authentication.Facebook.xproj b/src/Microsoft.AspNet.Authentication.Facebook/Microsoft.AspNet.Authentication.Facebook.xproj index 608a152e2..68ee50c4b 100644 --- a/src/Microsoft.AspNet.Authentication.Facebook/Microsoft.AspNet.Authentication.Facebook.xproj +++ b/src/Microsoft.AspNet.Authentication.Facebook/Microsoft.AspNet.Authentication.Facebook.xproj @@ -4,7 +4,7 @@ 14.0 $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) - + eeaaee68-607b-4e33-af3e-45c66b4dba5a ..\..\artifacts\obj\$(MSBuildProjectName) @@ -13,5 +13,5 @@ 2.0 - + \ No newline at end of file diff --git a/src/Microsoft.AspNet.Authentication.Google/Microsoft.AspNet.Authentication.Google.xproj b/src/Microsoft.AspNet.Authentication.Google/Microsoft.AspNet.Authentication.Google.xproj index 36e2cade9..f92646ce6 100644 --- a/src/Microsoft.AspNet.Authentication.Google/Microsoft.AspNet.Authentication.Google.xproj +++ b/src/Microsoft.AspNet.Authentication.Google/Microsoft.AspNet.Authentication.Google.xproj @@ -4,7 +4,7 @@ 14.0 $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) - + 76579c39-b829-490d-b8be-1bd35fe8412e ..\..\artifacts\obj\$(MSBuildProjectName) @@ -13,5 +13,5 @@ 2.0 - + \ No newline at end of file diff --git a/src/Microsoft.AspNet.Authentication.MicrosoftAccount/Microsoft.AspNet.Authentication.MicrosoftAccount.xproj b/src/Microsoft.AspNet.Authentication.MicrosoftAccount/Microsoft.AspNet.Authentication.MicrosoftAccount.xproj index 5935b2a13..c15c0534e 100644 --- a/src/Microsoft.AspNet.Authentication.MicrosoftAccount/Microsoft.AspNet.Authentication.MicrosoftAccount.xproj +++ b/src/Microsoft.AspNet.Authentication.MicrosoftAccount/Microsoft.AspNet.Authentication.MicrosoftAccount.xproj @@ -4,7 +4,7 @@ 14.0 $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) - + acb45e19-f520-4d0c-8916-b0ceb9c017fe ..\..\artifacts\obj\$(MSBuildProjectName) @@ -13,5 +13,5 @@ 2.0 - + \ No newline at end of file diff --git a/src/Microsoft.AspNet.Authentication.OAuth/Microsoft.AspNet.Authentication.OAuth.xproj b/src/Microsoft.AspNet.Authentication.OAuth/Microsoft.AspNet.Authentication.OAuth.xproj index 667114ea5..962888b9d 100644 --- a/src/Microsoft.AspNet.Authentication.OAuth/Microsoft.AspNet.Authentication.OAuth.xproj +++ b/src/Microsoft.AspNet.Authentication.OAuth/Microsoft.AspNet.Authentication.OAuth.xproj @@ -4,7 +4,7 @@ 14.0 $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) - + 1657c79e-7755-4aee-9d61-571295b69a30 ..\..\artifacts\obj\$(MSBuildProjectName) @@ -13,5 +13,5 @@ 2.0 - + \ No newline at end of file diff --git a/src/Microsoft.AspNet.Authentication.OAuthBearer/Microsoft.AspNet.Authentication.OAuthBearer.xproj b/src/Microsoft.AspNet.Authentication.OAuthBearer/Microsoft.AspNet.Authentication.OAuthBearer.xproj index f83bb90de..ef8673b48 100644 --- a/src/Microsoft.AspNet.Authentication.OAuthBearer/Microsoft.AspNet.Authentication.OAuthBearer.xproj +++ b/src/Microsoft.AspNet.Authentication.OAuthBearer/Microsoft.AspNet.Authentication.OAuthBearer.xproj @@ -4,7 +4,7 @@ 14.0 $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) - + 2755BFE5-7421-4A31-A644-F817DF5CAA98 ..\..\artifacts\obj\$(MSBuildProjectName) @@ -13,5 +13,5 @@ 2.0 - - + + \ No newline at end of file diff --git a/src/Microsoft.AspNet.Authentication.OpenIdConnect/Microsoft.AspNet.Authentication.OpenIdConnect.xproj b/src/Microsoft.AspNet.Authentication.OpenIdConnect/Microsoft.AspNet.Authentication.OpenIdConnect.xproj index 4b85e6378..9ae8192f2 100644 --- a/src/Microsoft.AspNet.Authentication.OpenIdConnect/Microsoft.AspNet.Authentication.OpenIdConnect.xproj +++ b/src/Microsoft.AspNet.Authentication.OpenIdConnect/Microsoft.AspNet.Authentication.OpenIdConnect.xproj @@ -4,7 +4,7 @@ 14.0 $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) - + 35115d55-b69e-46d4-bb33-c9e9e6ec5e7a ..\..\artifacts\obj\$(MSBuildProjectName) @@ -13,5 +13,5 @@ 2.0 - + \ No newline at end of file diff --git a/src/Microsoft.AspNet.Authentication.Twitter/Microsoft.AspNet.Authentication.Twitter.xproj b/src/Microsoft.AspNet.Authentication.Twitter/Microsoft.AspNet.Authentication.Twitter.xproj index 5d8846c09..55deb0714 100644 --- a/src/Microsoft.AspNet.Authentication.Twitter/Microsoft.AspNet.Authentication.Twitter.xproj +++ b/src/Microsoft.AspNet.Authentication.Twitter/Microsoft.AspNet.Authentication.Twitter.xproj @@ -4,7 +4,7 @@ 14.0 $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) - + 0330fff6-b4b5-42dd-8c99-26a789569000 ..\..\artifacts\obj\$(MSBuildProjectName) @@ -13,5 +13,5 @@ 2.0 - + \ No newline at end of file diff --git a/src/Microsoft.AspNet.Authentication/Microsoft.AspNet.Authentication.xproj b/src/Microsoft.AspNet.Authentication/Microsoft.AspNet.Authentication.xproj index b21c7af0e..fe12613f9 100644 --- a/src/Microsoft.AspNet.Authentication/Microsoft.AspNet.Authentication.xproj +++ b/src/Microsoft.AspNet.Authentication/Microsoft.AspNet.Authentication.xproj @@ -4,7 +4,7 @@ 14.0 $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) - + 2286250a-52c8-4126-9f93-b1e45f0ad078 ..\..\artifacts\obj\$(MSBuildProjectName) @@ -13,5 +13,5 @@ 2.0 - + \ No newline at end of file diff --git a/src/Microsoft.AspNet.Authorization/Microsoft.AspNet.Authorization.xproj b/src/Microsoft.AspNet.Authorization/Microsoft.AspNet.Authorization.xproj index 43b060769..be8ba0e0e 100644 --- a/src/Microsoft.AspNet.Authorization/Microsoft.AspNet.Authorization.xproj +++ b/src/Microsoft.AspNet.Authorization/Microsoft.AspNet.Authorization.xproj @@ -4,7 +4,7 @@ 14.0 $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) - + 6ab3e514-5894-4131-9399-dc7d5284addb ..\..\artifacts\obj\$(MSBuildProjectName) @@ -13,5 +13,5 @@ 2.0 - + \ No newline at end of file diff --git a/test/Microsoft.AspNet.Authentication.Test/Microsoft.AspNet.Authentication.Tests.xproj b/test/Microsoft.AspNet.Authentication.Test/Microsoft.AspNet.Authentication.Tests.xproj index 77ea1e71c..3bcf72482 100644 --- a/test/Microsoft.AspNet.Authentication.Test/Microsoft.AspNet.Authentication.Tests.xproj +++ b/test/Microsoft.AspNet.Authentication.Test/Microsoft.AspNet.Authentication.Tests.xproj @@ -1,10 +1,10 @@ - + 14.0 $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) - + 8da26cd1-1302-4cfd-9270-9fa1b7c6138b ..\..\artifacts\obj\$(MSBuildProjectName) @@ -13,5 +13,5 @@ 2.0 - - + + \ No newline at end of file diff --git a/test/Microsoft.AspNet.Authorization.Test/Microsoft.AspNet.Authorization.Tests.xproj b/test/Microsoft.AspNet.Authorization.Test/Microsoft.AspNet.Authorization.Tests.xproj index 316cc5177..0e8a98e2a 100644 --- a/test/Microsoft.AspNet.Authorization.Test/Microsoft.AspNet.Authorization.Tests.xproj +++ b/test/Microsoft.AspNet.Authorization.Test/Microsoft.AspNet.Authorization.Tests.xproj @@ -4,7 +4,7 @@ 14.0 $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) - + 7af5ad96-eb6e-4d0e-8abe-c0b543c0f4c2 ..\..\artifacts\obj\$(MSBuildProjectName) @@ -13,5 +13,5 @@ 2.0 - + \ No newline at end of file From 8218a727d981b2ca2368ecaee319e1b4f785e4cd Mon Sep 17 00:00:00 2001 From: Doug Bunting Date: Thu, 2 Apr 2015 16:16:24 -0700 Subject: [PATCH 180/216] Correct .xproj filenames to match containing directories - these were the only two projects I found will naming inconsistencies --- ...ion.Tests.xproj => Microsoft.AspNet.Authentication.Test.xproj} | 0 ...tion.Tests.xproj => Microsoft.AspNet.Authorization.Test.xproj} | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename test/Microsoft.AspNet.Authentication.Test/{Microsoft.AspNet.Authentication.Tests.xproj => Microsoft.AspNet.Authentication.Test.xproj} (100%) rename test/Microsoft.AspNet.Authorization.Test/{Microsoft.AspNet.Authorization.Tests.xproj => Microsoft.AspNet.Authorization.Test.xproj} (100%) diff --git a/test/Microsoft.AspNet.Authentication.Test/Microsoft.AspNet.Authentication.Tests.xproj b/test/Microsoft.AspNet.Authentication.Test/Microsoft.AspNet.Authentication.Test.xproj similarity index 100% rename from test/Microsoft.AspNet.Authentication.Test/Microsoft.AspNet.Authentication.Tests.xproj rename to test/Microsoft.AspNet.Authentication.Test/Microsoft.AspNet.Authentication.Test.xproj diff --git a/test/Microsoft.AspNet.Authorization.Test/Microsoft.AspNet.Authorization.Tests.xproj b/test/Microsoft.AspNet.Authorization.Test/Microsoft.AspNet.Authorization.Test.xproj similarity index 100% rename from test/Microsoft.AspNet.Authorization.Test/Microsoft.AspNet.Authorization.Tests.xproj rename to test/Microsoft.AspNet.Authorization.Test/Microsoft.AspNet.Authorization.Test.xproj From 3cd702d6d83381e282646b6882811e4ab6bbff22 Mon Sep 17 00:00:00 2001 From: Doug Bunting Date: Fri, 3 Apr 2015 11:08:32 -0700 Subject: [PATCH 181/216] Update solution to match renamed .xproj files --- Security.sln | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Security.sln b/Security.sln index 2d3fccf4e..8f65fe16b 100644 --- a/Security.sln +++ b/Security.sln @@ -38,11 +38,11 @@ Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNet.Authentica EndProject Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNet.Authentication.OAuth", "src\Microsoft.AspNet.Authentication.OAuth\Microsoft.AspNet.Authentication.OAuth.xproj", "{1657C79E-7755-4AEE-9D61-571295B69A30}" EndProject -Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNet.Authentication.Tests", "test\Microsoft.AspNet.Authentication.Test\Microsoft.AspNet.Authentication.Tests.xproj", "{8DA26CD1-1302-4CFD-9270-9FA1B7C6138B}" +Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNet.Authentication.Test", "test\Microsoft.AspNet.Authentication.Test\Microsoft.AspNet.Authentication.Test.xproj", "{8DA26CD1-1302-4CFD-9270-9FA1B7C6138B}" EndProject Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNet.Authentication.OAuthBearer", "src\Microsoft.AspNet.Authentication.OAuthBearer\Microsoft.AspNet.Authentication.OAuthBearer.xproj", "{2755BFE5-7421-4A31-A644-F817DF5CAA98}" EndProject -Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNet.Authorization.Tests", "test\Microsoft.AspNet.Authorization.Test\Microsoft.AspNet.Authorization.Tests.xproj", "{7AF5AD96-EB6E-4D0E-8ABE-C0B543C0F4C2}" +Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNet.Authorization.Test", "test\Microsoft.AspNet.Authorization.Test\Microsoft.AspNet.Authorization.Test.xproj", "{7AF5AD96-EB6E-4D0E-8ABE-C0B543C0F4C2}" EndProject Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNet.Authorization", "src\Microsoft.AspNet.Authorization\Microsoft.AspNet.Authorization.xproj", "{6AB3E514-5894-4131-9399-DC7D5284ADDB}" EndProject From 28a6ef1dc4247d7cfd75ebf02118a534b407270a Mon Sep 17 00:00:00 2001 From: Wei Wang Date: Fri, 3 Apr 2015 17:22:02 -0700 Subject: [PATCH 182/216] Fix AppVeyor git line ending config --- appveyor.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/appveyor.yml b/appveyor.yml index 88cb9ef14..3fab83e13 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,3 +1,5 @@ +init: + - git config --global core.autocrlf true build_script: - build.cmd verify clone_depth: 1 From e0694a21d86c06524d516d1c0e4204c13ba64070 Mon Sep 17 00:00:00 2001 From: "N. Taylor Mullen" Date: Tue, 7 Apr 2015 14:50:16 -0700 Subject: [PATCH 183/216] Add serviceable attribute to projects. aspnet/DNX#1600 --- .../Properties/AssemblyInfo.cs | 6 ++++++ .../Properties/AssemblyInfo.cs | 6 ++++++ .../Properties/AssemblyInfo.cs | 6 ++++++ .../Properties/AssemblyInfo.cs | 6 ++++++ .../Properties/AssemblyInfo.cs | 6 ++++++ .../Properties/AssemblyInfo.cs | 6 ++++++ .../Properties/AssemblyInfo.cs | 6 ++++++ .../Properties/AssemblyInfo.cs | 6 ++++++ .../Properties/AssemblyInfo.cs | 6 ++++++ .../Properties/AssemblyInfo.cs | 6 ++++++ 10 files changed, 60 insertions(+) create mode 100644 src/Microsoft.AspNet.Authentication.Cookies/Properties/AssemblyInfo.cs create mode 100644 src/Microsoft.AspNet.Authentication.Facebook/Properties/AssemblyInfo.cs create mode 100644 src/Microsoft.AspNet.Authentication.Google/Properties/AssemblyInfo.cs create mode 100644 src/Microsoft.AspNet.Authentication.MicrosoftAccount/Properties/AssemblyInfo.cs create mode 100644 src/Microsoft.AspNet.Authentication.OAuth/Properties/AssemblyInfo.cs create mode 100644 src/Microsoft.AspNet.Authentication.OAuthBearer/Properties/AssemblyInfo.cs create mode 100644 src/Microsoft.AspNet.Authentication.OpenIdConnect/Properties/AssemblyInfo.cs create mode 100644 src/Microsoft.AspNet.Authentication.Twitter/Properties/AssemblyInfo.cs create mode 100644 src/Microsoft.AspNet.Authentication/Properties/AssemblyInfo.cs create mode 100644 src/Microsoft.AspNet.Authorization/Properties/AssemblyInfo.cs diff --git a/src/Microsoft.AspNet.Authentication.Cookies/Properties/AssemblyInfo.cs b/src/Microsoft.AspNet.Authentication.Cookies/Properties/AssemblyInfo.cs new file mode 100644 index 000000000..f5c6f4a83 --- /dev/null +++ b/src/Microsoft.AspNet.Authentication.Cookies/Properties/AssemblyInfo.cs @@ -0,0 +1,6 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System.Reflection; + +[assembly: AssemblyMetadata("Serviceable", "True")] \ No newline at end of file diff --git a/src/Microsoft.AspNet.Authentication.Facebook/Properties/AssemblyInfo.cs b/src/Microsoft.AspNet.Authentication.Facebook/Properties/AssemblyInfo.cs new file mode 100644 index 000000000..f5c6f4a83 --- /dev/null +++ b/src/Microsoft.AspNet.Authentication.Facebook/Properties/AssemblyInfo.cs @@ -0,0 +1,6 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System.Reflection; + +[assembly: AssemblyMetadata("Serviceable", "True")] \ No newline at end of file diff --git a/src/Microsoft.AspNet.Authentication.Google/Properties/AssemblyInfo.cs b/src/Microsoft.AspNet.Authentication.Google/Properties/AssemblyInfo.cs new file mode 100644 index 000000000..f5c6f4a83 --- /dev/null +++ b/src/Microsoft.AspNet.Authentication.Google/Properties/AssemblyInfo.cs @@ -0,0 +1,6 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System.Reflection; + +[assembly: AssemblyMetadata("Serviceable", "True")] \ No newline at end of file diff --git a/src/Microsoft.AspNet.Authentication.MicrosoftAccount/Properties/AssemblyInfo.cs b/src/Microsoft.AspNet.Authentication.MicrosoftAccount/Properties/AssemblyInfo.cs new file mode 100644 index 000000000..f5c6f4a83 --- /dev/null +++ b/src/Microsoft.AspNet.Authentication.MicrosoftAccount/Properties/AssemblyInfo.cs @@ -0,0 +1,6 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System.Reflection; + +[assembly: AssemblyMetadata("Serviceable", "True")] \ No newline at end of file diff --git a/src/Microsoft.AspNet.Authentication.OAuth/Properties/AssemblyInfo.cs b/src/Microsoft.AspNet.Authentication.OAuth/Properties/AssemblyInfo.cs new file mode 100644 index 000000000..f5c6f4a83 --- /dev/null +++ b/src/Microsoft.AspNet.Authentication.OAuth/Properties/AssemblyInfo.cs @@ -0,0 +1,6 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System.Reflection; + +[assembly: AssemblyMetadata("Serviceable", "True")] \ No newline at end of file diff --git a/src/Microsoft.AspNet.Authentication.OAuthBearer/Properties/AssemblyInfo.cs b/src/Microsoft.AspNet.Authentication.OAuthBearer/Properties/AssemblyInfo.cs new file mode 100644 index 000000000..f5c6f4a83 --- /dev/null +++ b/src/Microsoft.AspNet.Authentication.OAuthBearer/Properties/AssemblyInfo.cs @@ -0,0 +1,6 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System.Reflection; + +[assembly: AssemblyMetadata("Serviceable", "True")] \ No newline at end of file diff --git a/src/Microsoft.AspNet.Authentication.OpenIdConnect/Properties/AssemblyInfo.cs b/src/Microsoft.AspNet.Authentication.OpenIdConnect/Properties/AssemblyInfo.cs new file mode 100644 index 000000000..f5c6f4a83 --- /dev/null +++ b/src/Microsoft.AspNet.Authentication.OpenIdConnect/Properties/AssemblyInfo.cs @@ -0,0 +1,6 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System.Reflection; + +[assembly: AssemblyMetadata("Serviceable", "True")] \ No newline at end of file diff --git a/src/Microsoft.AspNet.Authentication.Twitter/Properties/AssemblyInfo.cs b/src/Microsoft.AspNet.Authentication.Twitter/Properties/AssemblyInfo.cs new file mode 100644 index 000000000..f5c6f4a83 --- /dev/null +++ b/src/Microsoft.AspNet.Authentication.Twitter/Properties/AssemblyInfo.cs @@ -0,0 +1,6 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System.Reflection; + +[assembly: AssemblyMetadata("Serviceable", "True")] \ No newline at end of file diff --git a/src/Microsoft.AspNet.Authentication/Properties/AssemblyInfo.cs b/src/Microsoft.AspNet.Authentication/Properties/AssemblyInfo.cs new file mode 100644 index 000000000..f5c6f4a83 --- /dev/null +++ b/src/Microsoft.AspNet.Authentication/Properties/AssemblyInfo.cs @@ -0,0 +1,6 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System.Reflection; + +[assembly: AssemblyMetadata("Serviceable", "True")] \ No newline at end of file diff --git a/src/Microsoft.AspNet.Authorization/Properties/AssemblyInfo.cs b/src/Microsoft.AspNet.Authorization/Properties/AssemblyInfo.cs new file mode 100644 index 000000000..f5c6f4a83 --- /dev/null +++ b/src/Microsoft.AspNet.Authorization/Properties/AssemblyInfo.cs @@ -0,0 +1,6 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System.Reflection; + +[assembly: AssemblyMetadata("Serviceable", "True")] \ No newline at end of file From e44fb492343cef68434b79019189c25ea75fe31a Mon Sep 17 00:00:00 2001 From: "N. Taylor Mullen" Date: Tue, 7 Apr 2015 16:16:42 -0700 Subject: [PATCH 184/216] Update .travis.yml and appveyor.yml to build quietly. --- .travis.yml | 2 +- appveyor.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 5939a529e..947bf868e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,4 +1,4 @@ language: csharp sudo: false script: - - ./build.sh verify \ No newline at end of file + - ./build.sh --quiet verify \ No newline at end of file diff --git a/appveyor.yml b/appveyor.yml index 3fab83e13..636a7618d 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,7 +1,7 @@ init: - git config --global core.autocrlf true build_script: - - build.cmd verify + - build.cmd --quiet verify clone_depth: 1 test: off deploy: off \ No newline at end of file From 4a2a742ad5e52b2f9e0529b8c6f5f9decd3e80f0 Mon Sep 17 00:00:00 2001 From: Pinpoint Date: Tue, 3 Mar 2015 16:01:14 +0100 Subject: [PATCH 185/216] Fix SecurityTokenValidated and rework the different OAuth2 Bearer middleware tests --- .../OAuthBearerAuthenticationHandler.cs | 5 +- .../OAuthBearer/OAuthBearerMiddlewareTests.cs | 257 ++++++++++++------ 2 files changed, 171 insertions(+), 91 deletions(-) diff --git a/src/Microsoft.AspNet.Authentication.OAuthBearer/OAuthBearerAuthenticationHandler.cs b/src/Microsoft.AspNet.Authentication.OAuthBearer/OAuthBearerAuthenticationHandler.cs index e2a56697d..1f2d20b76 100644 --- a/src/Microsoft.AspNet.Authentication.OAuthBearer/OAuthBearerAuthenticationHandler.cs +++ b/src/Microsoft.AspNet.Authentication.OAuthBearer/OAuthBearerAuthenticationHandler.cs @@ -136,12 +136,13 @@ protected override async Task AuthenticateCoreAsync() AuthenticationTicket = ticket }; - if (securityTokenReceivedNotification.HandledResponse) + await Options.Notifications.SecurityTokenValidated(securityTokenValidatedNotification); + if (securityTokenValidatedNotification.HandledResponse) { return securityTokenValidatedNotification.AuthenticationTicket; } - if (securityTokenReceivedNotification.Skipped) + if (securityTokenValidatedNotification.Skipped) { return null; } diff --git a/test/Microsoft.AspNet.Authentication.Test/OAuthBearer/OAuthBearerMiddlewareTests.cs b/test/Microsoft.AspNet.Authentication.Test/OAuthBearer/OAuthBearerMiddlewareTests.cs index fcd2d411e..e688497d9 100644 --- a/test/Microsoft.AspNet.Authentication.Test/OAuthBearer/OAuthBearerMiddlewareTests.cs +++ b/test/Microsoft.AspNet.Authentication.Test/OAuthBearer/OAuthBearerMiddlewareTests.cs @@ -4,7 +4,6 @@ using System; using System.Collections.Generic; using System.IdentityModel.Tokens; -using System.Linq; using System.Net; using System.Net.Http; using System.Security.Claims; @@ -12,7 +11,7 @@ using System.Xml.Linq; using Microsoft.AspNet.Builder; using Microsoft.AspNet.Http; -using Microsoft.AspNet.Authentication.Notifications; +using Microsoft.AspNet.Http.Authentication; using Microsoft.AspNet.TestHost; using Microsoft.Framework.DependencyInjection; using Shouldly; @@ -27,6 +26,8 @@ public async Task BearerTokenValidation() { var server = CreateServer(options => { + options.AutomaticAuthentication = true; + options.Authority = "https://login.windows.net/tushartest.onmicrosoft.com"; options.Audience = "https://TusharTest.onmicrosoft.com/TodoListService-ManualJwt"; options.TokenValidationParameters = new TokenValidationParameters @@ -34,6 +35,7 @@ public async Task BearerTokenValidation() ValidateLifetime = false }; }); + string newBearerToken = "Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6ImtyaU1QZG1Cdng2OHNrVDgtbVBBQjNCc2VlQSJ9.eyJhdWQiOiJodHRwczovL1R1c2hhclRlc3Qub25taWNyb3NvZnQuY29tL1RvZG9MaXN0U2VydmljZS1NYW51YWxKd3QiLCJpc3MiOiJodHRwczovL3N0cy53aW5kb3dzLm5ldC9hZmJlY2UwMy1hZWFhLTRmM2YtODVlNy1jZTA4ZGQyMGNlNTAvIiwiaWF0IjoxNDE4MzMwNjE0LCJuYmYiOjE0MTgzMzA2MTQsImV4cCI6MTQxODMzNDUxNCwidmVyIjoiMS4wIiwidGlkIjoiYWZiZWNlMDMtYWVhYS00ZjNmLTg1ZTctY2UwOGRkMjBjZTUwIiwiYW1yIjpbInB3ZCJdLCJvaWQiOiI1Mzk3OTdjMi00MDE5LTQ2NTktOWRiNS03MmM0Yzc3NzhhMzMiLCJ1cG4iOiJWaWN0b3JAVHVzaGFyVGVzdC5vbm1pY3Jvc29mdC5jb20iLCJ1bmlxdWVfbmFtZSI6IlZpY3RvckBUdXNoYXJUZXN0Lm9ubWljcm9zb2Z0LmNvbSIsInN1YiI6IkQyMm9aMW9VTzEzTUFiQXZrdnFyd2REVE80WXZJdjlzMV9GNWlVOVUwYnciLCJmYW1pbHlfbmFtZSI6Ikd1cHRhIiwiZ2l2ZW5fbmFtZSI6IlZpY3RvciIsImFwcGlkIjoiNjEzYjVhZjgtZjJjMy00MWI2LWExZGMtNDE2Yzk3ODAzMGI3IiwiYXBwaWRhY3IiOiIwIiwic2NwIjoidXNlcl9pbXBlcnNvbmF0aW9uIiwiYWNyIjoiMSJ9.N_Kw1EhoVGrHbE6hOcm7ERdZ7paBQiNdObvp2c6T6n5CE8p0fZqmUd-ya_EqwElcD6SiKSiP7gj0gpNUnOJcBl_H2X8GseaeeMxBrZdsnDL8qecc6_ygHruwlPltnLTdka67s1Ow4fDSHaqhVTEk6lzGmNEcbNAyb0CxQxU6o7Fh0yHRiWoLsT8yqYk8nKzsHXfZBNby4aRo3_hXaa4i0SZLYfDGGYPdttG4vT_u54QGGd4Wzbonv2gjDlllOVGOwoJS6kfl1h8mk0qxdiIaT_ChbDWgkWvTB7bTvBE-EgHgV0XmAo0WtJeSxgjsG3KhhEPsONmqrSjhIUV4IVnF2w"; var response = await SendAsync(server, "http://example.com/oauth", newBearerToken); response.Response.StatusCode.ShouldBe(HttpStatusCode.OK); @@ -44,26 +46,30 @@ public async Task CustomHeaderReceived() { var server = CreateServer(options => { - options.Notifications.MessageReceived = HeaderReceived; - }); - - var response = await SendAsync(server, "http://example.com/oauth", "someHeader someblob"); - response.Response.StatusCode.ShouldBe(HttpStatusCode.OK); - } + options.AutomaticAuthentication = true; - private static Task HeaderReceived(MessageReceivedNotification notification) - { - List claims = - new List + options.Notifications.MessageReceived = notification => { - new Claim(ClaimTypes.Email, "bob@contoso.com"), - new Claim(ClaimsIdentity.DefaultNameClaimType, "bob"), - }; + var claims = new[] + { + new Claim(ClaimTypes.NameIdentifier, "Bob le Magnifique"), + new Claim(ClaimTypes.Email, "bob@contoso.com"), + new Claim(ClaimsIdentity.DefaultNameClaimType, "bob") + }; - notification.AuthenticationTicket = new AuthenticationTicket(new ClaimsPrincipal(new ClaimsIdentity(claims)), new Http.Authentication.AuthenticationProperties(), notification.Options.AuthenticationScheme); - notification.HandleResponse(); + notification.AuthenticationTicket = new AuthenticationTicket( + new ClaimsPrincipal(new ClaimsIdentity(claims, notification.Options.AuthenticationScheme)), + new AuthenticationProperties(), notification.Options.AuthenticationScheme); - return Task.FromResult(null); + notification.HandleResponse(); + + return Task.FromResult(null); + }; + }); + + var response = await SendAsync(server, "http://example.com/oauth", "someHeader someblob"); + response.Response.StatusCode.ShouldBe(HttpStatusCode.OK); + response.ResponseText.ShouldBe("Bob le Magnifique"); } [Fact] @@ -71,7 +77,7 @@ public async Task NoHeaderReceived() { var server = CreateServer(options => { }); var response = await SendAsync(server, "http://example.com/oauth"); - response.Response.StatusCode.ShouldBe(HttpStatusCode.OK); + response.Response.StatusCode.ShouldBe(HttpStatusCode.Unauthorized); } [Fact] @@ -79,7 +85,7 @@ public async Task HeaderWithoutBearerReceived() { var server = CreateServer(options => { }); var response = await SendAsync(server, "http://example.com/oauth","Token"); - response.Response.StatusCode.ShouldBe(HttpStatusCode.OK); + response.Response.StatusCode.ShouldBe(HttpStatusCode.Unauthorized); } [Fact] @@ -87,26 +93,30 @@ public async Task CustomTokenReceived() { var server = CreateServer(options => { - options.Notifications.SecurityTokenReceived = SecurityTokenReceived; - }); - - var response = await SendAsync(server, "http://example.com/oauth", "Bearer someblob"); - response.Response.StatusCode.ShouldBe(HttpStatusCode.OK); - } + options.AutomaticAuthentication = true; - private static Task SecurityTokenReceived(SecurityTokenReceivedNotification notification) - { - List claims = - new List + options.Notifications.SecurityTokenReceived = notification => { - new Claim(ClaimTypes.Email, "bob@contoso.com"), - new Claim(ClaimsIdentity.DefaultNameClaimType, "bob"), - }; + var claims = new[] + { + new Claim(ClaimTypes.NameIdentifier, "Bob le Magnifique"), + new Claim(ClaimTypes.Email, "bob@contoso.com"), + new Claim(ClaimsIdentity.DefaultNameClaimType, "bob") + }; - notification.AuthenticationTicket = new AuthenticationTicket(new ClaimsPrincipal(new ClaimsIdentity(claims, notification.Options.AuthenticationScheme)), new Http.Authentication.AuthenticationProperties(), notification.Options.AuthenticationScheme); - notification.HandleResponse(); + notification.AuthenticationTicket = new AuthenticationTicket( + new ClaimsPrincipal(new ClaimsIdentity(claims, notification.Options.AuthenticationScheme)), + new AuthenticationProperties(), notification.Options.AuthenticationScheme); - return Task.FromResult(null); + notification.HandleResponse(); + + return Task.FromResult(null); + }; + }); + + var response = await SendAsync(server, "http://example.com/oauth", "Bearer someblob"); + response.Response.StatusCode.ShouldBe(HttpStatusCode.OK); + response.ResponseText.ShouldBe("Bob le Magnifique"); } [Fact] @@ -114,44 +124,70 @@ public async Task CustomTokenValidated() { var server = CreateServer(options => { - options.Notifications.SecurityTokenValidated = SecurityTokenValidated; - options.SecurityTokenValidators = new List{new BlobTokenValidator(options.AuthenticationScheme)}; + options.AutomaticAuthentication = true; + + options.Notifications.SecurityTokenValidated = notification => + { + // Retrieve the NameIdentifier claim from the identity + // returned by the custom security token validator. + var identity = (ClaimsIdentity) notification.AuthenticationTicket.Principal.Identity; + var identifier = identity.FindFirst(ClaimTypes.NameIdentifier); + + identifier.Value.ShouldBe("Bob le Tout Puissant"); + + // Remove the existing NameIdentifier claim and replace it + // with a new one containing a different value. + identity.RemoveClaim(identifier); + // Make sure to use a different name identifier + // than the one defined by BlobTokenValidator. + identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, "Bob le Magnifique")); + + return Task.FromResult(null); + }; + + options.SecurityTokenValidators = new[] { new BlobTokenValidator(options.AuthenticationScheme) }; }); var response = await SendAsync(server, "http://example.com/oauth", "Bearer someblob"); response.Response.StatusCode.ShouldBe(HttpStatusCode.OK); + response.ResponseText.ShouldBe("Bob le Magnifique"); } - private static Task SecurityTokenValidated(SecurityTokenValidatedNotification notification) + [Fact] + public async Task RetrievingTokenFromAlternateLocation() { - List claims = - new List + var server = CreateServer(options => + { + options.AutomaticAuthentication = true; + + options.Notifications.MessageReceived = notification => { - new Claim(ClaimTypes.Email, "bob@contoso.com"), - new Claim(ClaimsIdentity.DefaultNameClaimType, "bob"), + notification.Token = "CustomToken"; + return Task.FromResult(null); }; + + options.Notifications.SecurityTokenReceived = notification => + { + var claims = new[] + { + new Claim(ClaimTypes.NameIdentifier, "Bob le Magnifique"), + new Claim(ClaimTypes.Email, "bob@contoso.com"), + new Claim(ClaimsIdentity.DefaultNameClaimType, "bob") + }; - notification.AuthenticationTicket = new AuthenticationTicket(new ClaimsPrincipal(new ClaimsIdentity(claims, notification.Options.AuthenticationScheme)), new Http.Authentication.AuthenticationProperties(), notification.Options.AuthenticationScheme); - notification.HandleResponse(); + notification.AuthenticationTicket = new AuthenticationTicket( + new ClaimsPrincipal(new ClaimsIdentity(claims, notification.Options.AuthenticationScheme)), + new AuthenticationProperties(), notification.Options.AuthenticationScheme); - return Task.FromResult(null); - } + notification.HandleResponse(); - [Fact] - public async Task RetrievingTokenFromAlternateLocation() - { - var server = CreateServer(options => { - options.Notifications.MessageReceived = MessageReceived; - options.Notifications.SecurityTokenReceived = SecurityTokenReceived; + return Task.FromResult(null); + }; }); + var response = await SendAsync(server, "http://example.com/oauth", "Bearer Token"); response.Response.StatusCode.ShouldBe(HttpStatusCode.OK); - } - - private static Task MessageReceived(MessageReceivedNotification notification) - { - notification.Token = "CustomToken"; - return Task.FromResult(null); + response.ResponseText.ShouldBe("Bob le Magnifique"); } [Fact] @@ -159,20 +195,51 @@ public async Task BearerTurns401To403IfAuthenticated() { var server = CreateServer(options => { - options.Notifications.SecurityTokenReceived = SecurityTokenReceived; + options.Notifications.SecurityTokenReceived = notification => + { + var claims = new[] + { + new Claim(ClaimTypes.NameIdentifier, "Bob le Magnifique"), + new Claim(ClaimTypes.Email, "bob@contoso.com"), + new Claim(ClaimsIdentity.DefaultNameClaimType, "bob") + }; + + notification.AuthenticationTicket = new AuthenticationTicket( + new ClaimsPrincipal(new ClaimsIdentity(claims, notification.Options.AuthenticationScheme)), + new AuthenticationProperties(), notification.Options.AuthenticationScheme); + + notification.HandleResponse(); + + return Task.FromResult(null); + }; }); var response = await SendAsync(server, "http://example.com/unauthorized", "Bearer Token"); response.Response.StatusCode.ShouldBe(HttpStatusCode.Forbidden); } - - + [Fact] public async Task BearerDoesNothingTo401IfNotAuthenticated() { var server = CreateServer(options => { - options.Notifications.SecurityTokenReceived = SecurityTokenReceived; + options.Notifications.SecurityTokenReceived = notification => + { + var claims = new[] + { + new Claim(ClaimTypes.NameIdentifier, "Bob le Magnifique"), + new Claim(ClaimTypes.Email, "bob@contoso.com"), + new Claim(ClaimsIdentity.DefaultNameClaimType, "bob") + }; + + notification.AuthenticationTicket = new AuthenticationTicket( + new ClaimsPrincipal(new ClaimsIdentity(claims, notification.Options.AuthenticationScheme)), + new AuthenticationProperties(), notification.Options.AuthenticationScheme); + + notification.HandleResponse(); + + return Task.FromResult(null); + }; }); var response = await SendAsync(server, "http://example.com/unauthorized"); @@ -187,21 +254,15 @@ public BlobTokenValidator(string authenticationScheme) AuthenticationScheme = authenticationScheme; } - public string AuthenticationScheme { get; set; } - - public bool CanValidateToken - { - get - { - return true; - } - } + public string AuthenticationScheme { get; } + public bool CanValidateToken => true; + public int MaximumTokenSizeInBytes { get { - return 2*2*1024; + throw new NotImplementedException(); } set @@ -210,20 +271,20 @@ public int MaximumTokenSizeInBytes } } - public bool CanReadToken(string securityToken) - { - return true; - } + public bool CanReadToken(string securityToken) => true; public ClaimsPrincipal ValidateToken(string securityToken, TokenValidationParameters validationParameters, out SecurityToken validatedToken) { validatedToken = null; - List claims = - new List - { - new Claim(ClaimTypes.Email, "bob@contoso.com"), - new Claim(ClaimsIdentity.DefaultNameClaimType, "bob"), - }; + + var claims = new[] + { + // Make sure to use a different name identifier + // than the one defined by CustomTokenValidated. + new Claim(ClaimTypes.NameIdentifier, "Bob le Tout Puissant"), + new Claim(ClaimTypes.Email, "bob@contoso.com"), + new Claim(ClaimsIdentity.DefaultNameClaimType, "bob"), + }; return new ClaimsPrincipal(new ClaimsIdentity(claims, AuthenticationScheme)); } @@ -237,24 +298,42 @@ private static TestServer CreateServer(Action { app.UseOAuthBearerAuthentication(configureOptions); } + app.Use(async (context, next) => { - var req = context.Request; - var res = context.Response; - if (req.Path == new PathString("/oauth")) + if (context.Request.Path == new PathString("/oauth")) { + if (context.User == null || + context.User.Identity == null || + !context.User.Identity.IsAuthenticated) + { + context.Response.StatusCode = 401; + + return; + } + + var identifier = context.User.FindFirst(ClaimTypes.NameIdentifier); + if (identifier == null) + { + context.Response.StatusCode = 500; + + return; + } + + await context.Response.WriteAsync(identifier.Value); } - else if (req.Path == new PathString("/unauthorized")) + + else if (context.Request.Path == new PathString("/unauthorized")) { // Simulate Authorization failure var result = await context.AuthenticateAsync(OAuthBearerAuthenticationDefaults.AuthenticationScheme); - res.Challenge(OAuthBearerAuthenticationDefaults.AuthenticationScheme); + context.Response.Challenge(OAuthBearerAuthenticationDefaults.AuthenticationScheme); } + else { await next(); } - }); }, services => services.AddDataProtection()); From 5e03a6c1ad2d94a1e6c4757e0931d199761942a8 Mon Sep 17 00:00:00 2001 From: Pinpoint Date: Tue, 3 Mar 2015 16:13:45 +0100 Subject: [PATCH 186/216] Fix incorrect handler delegation and update SignInScheme documentation --- .../OAuthAuthenticationOptions.cs | 5 ++++- ...ler.cs => OpenIdConnectAuthenticationHandler.cs} | 2 +- .../OpenIdConnectAuthenticationMiddleware.cs | 13 +++++++++---- .../OpenIdConnectAuthenticationOptions.cs | 11 +++++------ .../TwitterAuthenticationOptions.cs | 5 ++++- .../ExternalAuthenticationOptions.cs | 5 +++++ 6 files changed, 28 insertions(+), 13 deletions(-) rename src/Microsoft.AspNet.Authentication.OpenIdConnect/{OpenidConnectAuthenticationHandler.cs => OpenIdConnectAuthenticationHandler.cs} (99%) diff --git a/src/Microsoft.AspNet.Authentication.OAuth/OAuthAuthenticationOptions.cs b/src/Microsoft.AspNet.Authentication.OAuth/OAuthAuthenticationOptions.cs index 3dda28812..bd9ab43b0 100644 --- a/src/Microsoft.AspNet.Authentication.OAuth/OAuthAuthenticationOptions.cs +++ b/src/Microsoft.AspNet.Authentication.OAuth/OAuthAuthenticationOptions.cs @@ -99,7 +99,10 @@ public string Caption public PathString CallbackPath { get; set; } /// - /// Gets or sets the name of another authentication middleware which will be responsible for actually issuing a user . + /// Gets or sets the authentication scheme corresponding to the middleware + /// responsible of persisting user's identity after a successful authentication. + /// This value typically corresponds to a cookie middleware registered in the Startup class. + /// When omitted, is used as a fallback value. /// public string SignInScheme { get; set; } diff --git a/src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenidConnectAuthenticationHandler.cs b/src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenIdConnectAuthenticationHandler.cs similarity index 99% rename from src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenidConnectAuthenticationHandler.cs rename to src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenIdConnectAuthenticationHandler.cs index 6a629045b..32f7a69c0 100644 --- a/src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenidConnectAuthenticationHandler.cs +++ b/src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenIdConnectAuthenticationHandler.cs @@ -585,4 +585,4 @@ private async Task InvokeReplyPathAsync() return false; } } -} \ No newline at end of file +} diff --git a/src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenIdConnectAuthenticationMiddleware.cs b/src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenIdConnectAuthenticationMiddleware.cs index 53284a50e..e58b7fff8 100644 --- a/src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenIdConnectAuthenticationMiddleware.cs +++ b/src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenIdConnectAuthenticationMiddleware.cs @@ -7,12 +7,12 @@ using System.IdentityModel.Tokens; using System.Net.Http; using System.Text; -using Microsoft.AspNet.Builder; -using Microsoft.AspNet.DataProtection; -using Microsoft.AspNet.Http; using Microsoft.AspNet.Authentication.DataHandler; using Microsoft.AspNet.Authentication.DataHandler.Encoder; using Microsoft.AspNet.Authentication.DataHandler.Serializer; +using Microsoft.AspNet.Builder; +using Microsoft.AspNet.DataProtection; +using Microsoft.AspNet.Http; using Microsoft.Framework.Logging; using Microsoft.Framework.OptionsModel; using Microsoft.IdentityModel.Protocols; @@ -45,9 +45,14 @@ public OpenIdConnectAuthenticationMiddleware( { _logger = loggerFactory.CreateLogger(); + if (string.IsNullOrEmpty(Options.SignInScheme)) + { + Options.SignInScheme = externalOptions.Options.SignInScheme; + } + if (string.IsNullOrWhiteSpace(Options.TokenValidationParameters.AuthenticationType)) { - Options.TokenValidationParameters.AuthenticationType = externalOptions.Options.SignInScheme; + Options.TokenValidationParameters.AuthenticationType = Options.AuthenticationScheme; } if (Options.StateDataFormat == null) diff --git a/src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenIdConnectAuthenticationOptions.cs b/src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenIdConnectAuthenticationOptions.cs index 25b70473a..f7bfde804 100644 --- a/src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenIdConnectAuthenticationOptions.cs +++ b/src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenIdConnectAuthenticationOptions.cs @@ -233,13 +233,12 @@ public OpenIdConnectProtocolValidator ProtocolValidator public string Scope { get; set; } /// - /// Gets or sets the AuthenticationScheme used when creating the . + /// Gets or sets the authentication scheme corresponding to the middleware + /// responsible of persisting user's identity after a successful authentication. + /// This value typically corresponds to a cookie middleware registered in the Startup class. + /// When omitted, is used as a fallback value. /// - public string SignInScheme - { - get { return TokenValidationParameters.AuthenticationType; } - set { TokenValidationParameters.AuthenticationType = value; } - } + public string SignInScheme { get; set; } /// /// Gets or sets the type used to secure data handled by the middleware. diff --git a/src/Microsoft.AspNet.Authentication.Twitter/TwitterAuthenticationOptions.cs b/src/Microsoft.AspNet.Authentication.Twitter/TwitterAuthenticationOptions.cs index d17daa0e9..a3179c386 100644 --- a/src/Microsoft.AspNet.Authentication.Twitter/TwitterAuthenticationOptions.cs +++ b/src/Microsoft.AspNet.Authentication.Twitter/TwitterAuthenticationOptions.cs @@ -89,7 +89,10 @@ public string Caption public PathString CallbackPath { get; set; } /// - /// Gets or sets the name of another authentication middleware which will be responsible for actually issuing a user . + /// Gets or sets the authentication scheme corresponding to the middleware + /// responsible of persisting user's identity after a successful authentication. + /// This value typically corresponds to a cookie middleware registered in the Startup class. + /// When omitted, is used as a fallback value. /// public string SignInScheme { get; set; } diff --git a/src/Microsoft.AspNet.Authentication/ExternalAuthenticationOptions.cs b/src/Microsoft.AspNet.Authentication/ExternalAuthenticationOptions.cs index 966e2cfe1..a80b80b83 100644 --- a/src/Microsoft.AspNet.Authentication/ExternalAuthenticationOptions.cs +++ b/src/Microsoft.AspNet.Authentication/ExternalAuthenticationOptions.cs @@ -8,6 +8,11 @@ namespace Microsoft.AspNet.Authentication { public class ExternalAuthenticationOptions { + /// + /// Gets or sets the authentication scheme corresponding to the default middleware + /// responsible of persisting user's identity after a successful authentication. + /// This value typically corresponds to a cookie middleware registered in the Startup class. + /// public string SignInScheme { get; set; } } } From 9ce84d39c2c852e418eae13a6a984159343b4162 Mon Sep 17 00:00:00 2001 From: Hao Kung Date: Wed, 15 Apr 2015 11:21:32 -0700 Subject: [PATCH 187/216] React to http challenge changes --- .../AuthenticationHandler.cs | 14 ++------ .../AuthenticationHandlerFacts.cs | 13 ++++--- .../DefaultAuthorizationServiceTests.cs | 34 ------------------- 3 files changed, 9 insertions(+), 52 deletions(-) diff --git a/src/Microsoft.AspNet.Authentication/AuthenticationHandler.cs b/src/Microsoft.AspNet.Authentication/AuthenticationHandler.cs index d54c4a3be..318d0ad73 100644 --- a/src/Microsoft.AspNet.Authentication/AuthenticationHandler.cs +++ b/src/Microsoft.AspNet.Authentication/AuthenticationHandler.cs @@ -353,10 +353,10 @@ public virtual void SignOut(ISignOutContext context) public virtual void Challenge(IChallengeContext context) { - if (ShouldHandleScheme(context.AuthenticationSchemes)) + if (ShouldHandleScheme(context.AuthenticationScheme)) { ChallengeContext = context; - context.Accept(BaseOptions.AuthenticationScheme, BaseOptions.Description.Dictionary); + context.Accept(); } if (PriorHandler != null) @@ -367,14 +367,6 @@ public virtual void Challenge(IChallengeContext context) protected abstract void ApplyResponseChallenge(); - public virtual bool ShouldHandleScheme(IEnumerable authenticationSchemes) - { - // If there are any schemes asked for, need to match, otherwise automatic authentication matches - return authenticationSchemes != null && authenticationSchemes.Any() - ? authenticationSchemes.Contains(BaseOptions.AuthenticationScheme, StringComparer.Ordinal) - : BaseOptions.AutomaticAuthentication; - } - public virtual bool ShouldHandleScheme(string authenticationScheme) { return string.Equals(BaseOptions.AuthenticationScheme, authenticationScheme, StringComparison.Ordinal) || @@ -388,7 +380,7 @@ public virtual bool ShouldConvertChallengeToForbidden() return Response.StatusCode == 401 && AuthenticateCalled && ChallengeContext != null && - ShouldHandleScheme(ChallengeContext.AuthenticationSchemes); + ShouldHandleScheme(ChallengeContext.AuthenticationScheme); } /// diff --git a/test/Microsoft.AspNet.Authentication.Test/AuthenticationHandlerFacts.cs b/test/Microsoft.AspNet.Authentication.Test/AuthenticationHandlerFacts.cs index 8ed1063dd..a8ec25fe0 100644 --- a/test/Microsoft.AspNet.Authentication.Test/AuthenticationHandlerFacts.cs +++ b/test/Microsoft.AspNet.Authentication.Test/AuthenticationHandlerFacts.cs @@ -14,11 +14,11 @@ public void ShouldHandleSchemeAreDeterminedOnlyByMatchingAuthenticationScheme() { var handler = new TestHandler("Alpha"); - bool passiveNoMatch = handler.ShouldHandleScheme(new[] { "Beta", "Gamma" }); + bool passiveNoMatch = handler.ShouldHandleScheme("Beta"); handler = new TestHandler("Alpha"); - bool passiveWithMatch = handler.ShouldHandleScheme(new[] { "Beta", "Alpha" }); + bool passiveWithMatch = handler.ShouldHandleScheme("Alpha"); Assert.False(passiveNoMatch); Assert.True(passiveWithMatch); @@ -28,28 +28,28 @@ public void ShouldHandleSchemeAreDeterminedOnlyByMatchingAuthenticationScheme() public void AutomaticHandlerInAutomaticModeHandlesEmptyChallenges() { var handler = new TestAutoHandler("ignored", true); - Assert.True(handler.ShouldHandleScheme(new string[0])); + Assert.True(handler.ShouldHandleScheme("")); } [Fact] public void AutomaticHandlerShouldHandleSchemeWhenSchemeMatches() { var handler = new TestAutoHandler("Alpha", true); - Assert.True(handler.ShouldHandleScheme(new string[] { "Alpha" })); + Assert.True(handler.ShouldHandleScheme("Alpha")); } [Fact] public void AutomaticHandlerShouldNotHandleChallengeWhenSchemeDoesNotMatches() { var handler = new TestAutoHandler("Dog", true); - Assert.False(handler.ShouldHandleScheme(new string[] { "Alpha" })); + Assert.False(handler.ShouldHandleScheme("Alpha")); } [Fact] public void AutomaticHandlerShouldNotHandleChallengeWhenSchemesNotEmpty() { var handler = new TestAutoHandler(null, true); - Assert.False(handler.ShouldHandleScheme(new string[] { "Alpha" })); + Assert.False(handler.ShouldHandleScheme("Alpha")); } private class TestHandler : AuthenticationHandler @@ -110,6 +110,5 @@ protected override AuthenticationTicket AuthenticateCore() throw new NotImplementedException(); } } - } } diff --git a/test/Microsoft.AspNet.Authorization.Test/DefaultAuthorizationServiceTests.cs b/test/Microsoft.AspNet.Authorization.Test/DefaultAuthorizationServiceTests.cs index 74328a956..752d2383b 100644 --- a/test/Microsoft.AspNet.Authorization.Test/DefaultAuthorizationServiceTests.cs +++ b/test/Microsoft.AspNet.Authorization.Test/DefaultAuthorizationServiceTests.cs @@ -347,40 +347,6 @@ public async Task Authorize_PolicyCanAuthenticationSchemeWithNameClaim() Assert.True(allowed); } - [Fact(Skip = "Filtering TBD")] - public async Task Authorize_PolicyWillFilterAuthenticationScheme() - { - // Arrange - var policy = new AuthorizationPolicyBuilder("Bogus").RequireClaim(ClaimTypes.Name); - var authorizationService = BuildAuthorizationService(); - var user = new ClaimsPrincipal( - new ClaimsIdentity(new Claim[] { new Claim(ClaimTypes.Name, "Name") }, "AuthType") - ); - - // Act - var allowed = await authorizationService.AuthorizeAsync(user, null, policy.Build()); - - // Assert - Assert.False(allowed); - } - - [Fact(Skip = "Filtering TBD")] - public async Task Authorize_PolicyCanFilterMultipleAuthenticationScheme() - { - // Arrange - var policy = new AuthorizationPolicyBuilder("One", "Two").RequireClaim(ClaimTypes.Name, "one").RequireClaim(ClaimTypes.Name, "two"); - var authorizationService = BuildAuthorizationService(); - var user = new ClaimsPrincipal(); - user.AddIdentity(new ClaimsIdentity(new Claim[] { new Claim(ClaimTypes.Name, "one") }, "One")); - user.AddIdentity(new ClaimsIdentity(new Claim[] { new Claim(ClaimTypes.Name, "two") }, "Two")); - - // Act - var allowed = await authorizationService.AuthorizeAsync(user, null, policy.Build()); - - // Assert - Assert.True(allowed); - } - [Fact] public async Task RolePolicyCanRequireSingleRole() { From 501bd4ff105ee3985219a01d772f737bffc3e563 Mon Sep 17 00:00:00 2001 From: Hao Kung Date: Thu, 16 Apr 2015 12:26:42 -0700 Subject: [PATCH 188/216] Merge https://github.com/brentschmaltz/Security --- .../INonceCache.cs | 6 +- .../OpenIdConnectAuthenticationDefaults.cs | 4 +- .../OpenIdConnectAuthenticationExtensions.cs | 13 +- .../OpenIdConnectAuthenticationHandler.cs | 356 ++++---- .../OpenIdConnectAuthenticationMiddleware.cs | 22 +- .../OpenIdConnectAuthenticationOptions.cs | 75 +- ...penIdConnectServiceCollectionExtensions.cs | 4 +- .../Resources.Designer.cs | 354 ++++++-- .../Resources.resx | 111 ++- .../OpenIdConnectHandlerTests.cs | 768 ++++++++++++++++++ .../OpenIdConnect/TestUtilities.cs | 109 +++ 11 files changed, 1568 insertions(+), 254 deletions(-) create mode 100644 test/Microsoft.AspNet.Authentication.Test/OpenIdConnect/OpenIdConnectHandlerTests.cs create mode 100644 test/Microsoft.AspNet.Authentication.Test/OpenIdConnect/TestUtilities.cs diff --git a/src/Microsoft.AspNet.Authentication.OpenIdConnect/INonceCache.cs b/src/Microsoft.AspNet.Authentication.OpenIdConnect/INonceCache.cs index a1f2d3543..a56117560 100644 --- a/src/Microsoft.AspNet.Authentication.OpenIdConnect/INonceCache.cs +++ b/src/Microsoft.AspNet.Authentication.OpenIdConnect/INonceCache.cs @@ -5,8 +5,8 @@ namespace Microsoft.AspNet.Authentication.OpenIdConnect { public interface INonceCache { - string AddNonce(string nonce); + bool TryAddNonce(string nonce); + bool TryRemoveNonce(string nonce); - bool HasNonce(string nonce); } -} \ No newline at end of file +} diff --git a/src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenIdConnectAuthenticationDefaults.cs b/src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenIdConnectAuthenticationDefaults.cs index 21dc57f48..cecc57a74 100644 --- a/src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenIdConnectAuthenticationDefaults.cs +++ b/src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenIdConnectAuthenticationDefaults.cs @@ -26,7 +26,7 @@ public static class OpenIdConnectAuthenticationDefaults /// /// The prefix used to for the a nonce in the cookie /// - internal const string CookieNoncePrefix = ".AspNet.OpenIdConnect.Nonce."; + public const string CookieNoncePrefix = ".AspNet.OpenIdConnect.Nonce."; /// /// The property for the RedirectUri that was used when asking for a 'authorizationCode' @@ -36,6 +36,6 @@ public static class OpenIdConnectAuthenticationDefaults /// /// Constant used to identify state in openIdConnect protocal message /// - internal const string AuthenticationPropertiesKey = "OpenIdConnect.AuthenticationProperties"; + public const string AuthenticationPropertiesKey = "OpenIdConnect.AuthenticationProperties"; } } diff --git a/src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenIdConnectAuthenticationExtensions.cs b/src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenIdConnectAuthenticationExtensions.cs index 989aac48e..4ced947e2 100644 --- a/src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenIdConnectAuthenticationExtensions.cs +++ b/src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenIdConnectAuthenticationExtensions.cs @@ -26,5 +26,16 @@ public static IApplicationBuilder UseOpenIdConnectAuthentication(this IApplicati Name = optionsName }); } + + /// + /// Adds the into the ASP.NET runtime. + /// + /// The application builder + /// Options which control the processing of the OpenIdConnect protocol and token validation. + /// The application builder + public static IApplicationBuilder UseOpenIdConnectAuthentication(this IApplicationBuilder app, IOptions options) + { + return app.UseMiddleware(options); + } } -} \ No newline at end of file +} diff --git a/src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenIdConnectAuthenticationHandler.cs b/src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenIdConnectAuthenticationHandler.cs index 32f7a69c0..c0efcd0f6 100644 --- a/src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenIdConnectAuthenticationHandler.cs +++ b/src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenIdConnectAuthenticationHandler.cs @@ -75,7 +75,7 @@ protected override async Task ApplyResponseGrantAsync() // Set End_Session_Endpoint in order: // 1. properties.Redirect - // 2. Options.Wreply + // 2. Options.PostLogoutRedirectUri var properties = new AuthenticationProperties(signout.Properties); if (!string.IsNullOrEmpty(properties.RedirectUri)) { @@ -98,7 +98,7 @@ protected override async Task ApplyResponseGrantAsync() string redirectUri = notification.ProtocolMessage.CreateLogoutRequestUrl(); if (!Uri.IsWellFormedUriString(redirectUri, UriKind.Absolute)) { - _logger.LogWarning("The logout redirect URI is malformed: {0}", (redirectUri ?? "null")); + _logger.LogWarning(Resources.OIDCH_0051_RedirectUriLogoutIsNotWellFormed, redirectUri); } Response.Redirect(redirectUri); @@ -115,28 +115,37 @@ protected override void ApplyResponseChallenge() /// Responds to a 401 Challenge. Sends an OpenIdConnect message to the 'identity authority' to obtain an identity. /// /// + /// Uses log id's OIDCH-0026 - OIDCH-0050, next num: 37 protected override async Task ApplyResponseChallengeAsync() { + if (_logger.IsEnabled(LogLevel.Debug)) + { + _logger.LogDebug(Resources.OIDCH_0026_ApplyResponseChallengeAsync, this.GetType()); + } + if (ShouldConvertChallengeToForbidden()) { + _logger.LogDebug(Resources.OIDCH_0027_401_ConvertedTo_403); Response.StatusCode = 403; return; } if (Response.StatusCode != 401) { + _logger.LogDebug(Resources.OIDCH_0028_StatusCodeNot401, Response.StatusCode); return; } // When Automatic should redirect on 401 even if there wasn't an explicit challenge. if (ChallengeContext == null && !Options.AutomaticAuthentication) { + _logger.LogDebug(Resources.OIDCH_0029_ChallengeContextEqualsNull); return; } - // order for redirect_uri + // order for local RedirectUri // 1. challenge.Properties.RedirectUri - // 2. CurrentUri + // 2. CurrentUri if Options.DefaultToCurrentUriOnRedirect is true) AuthenticationProperties properties; if (ChallengeContext == null) { @@ -147,12 +156,22 @@ protected override async Task ApplyResponseChallengeAsync() properties = new AuthenticationProperties(ChallengeContext.Properties); } - if (string.IsNullOrEmpty(properties.RedirectUri)) + if (!string.IsNullOrWhiteSpace(properties.RedirectUri)) { + _logger.LogDebug(Resources.OIDCH_0030_Using_Properties_RedirectUri, properties.RedirectUri); + } + else if (Options.DefaultToCurrentUriOnRedirect) + { + _logger.LogDebug(Resources.OIDCH_0032_UsingCurrentUriRedirectUri, CurrentUri); properties.RedirectUri = CurrentUri; } - // this value will be passed to the AuthorizationCodeReceivedNotification + if (!string.IsNullOrWhiteSpace(Options.RedirectUri)) + { + _logger.LogDebug(Resources.OIDCH_0031_Using_Options_RedirectUri, Options.RedirectUri); + } + + // When redeeming a 'code' for an AccessToken, this value is needed if (!string.IsNullOrWhiteSpace(Options.RedirectUri)) { properties.Dictionary.Add(OpenIdConnectAuthenticationDefaults.RedirectUriUsedForCodeKey, Options.RedirectUri); @@ -163,14 +182,15 @@ protected override async Task ApplyResponseChallengeAsync() _configuration = await Options.ConfigurationManager.GetConfigurationAsync(Context.RequestAborted); } - OpenIdConnectMessage openIdConnectMessage = new OpenIdConnectMessage + var message = new OpenIdConnectMessage { ClientId = Options.ClientId, - IssuerAddress = _configuration == null ? string.Empty : (_configuration.AuthorizationEndpoint ?? string.Empty), + IssuerAddress = _configuration?.AuthorizationEndpoint ?? string.Empty, RedirectUri = Options.RedirectUri, + // [brentschmaltz] - this should be a property on RedirectToIdentityProviderNotification not on the OIDCMessage. RequestType = OpenIdConnectRequestType.AuthenticationRequest, Resource = Options.Resource, - ResponseMode = OpenIdConnectResponseModes.FormPost, + ResponseMode = Options.ResponseMode, ResponseType = Options.ResponseType, Scope = Options.Scope, State = OpenIdConnectAuthenticationDefaults.AuthenticationPropertiesKey + "=" + Uri.EscapeDataString(Options.StateDataFormat.Protect(properties)) @@ -178,33 +198,45 @@ protected override async Task ApplyResponseChallengeAsync() if (Options.ProtocolValidator.RequireNonce) { - openIdConnectMessage.Nonce = Options.ProtocolValidator.GenerateNonce(); + message.Nonce = Options.ProtocolValidator.GenerateNonce(); if (Options.NonceCache != null) { - Options.NonceCache.AddNonce(openIdConnectMessage.Nonce); + if (!Options.NonceCache.TryAddNonce(message.Nonce)) + { + _logger.LogError(Resources.OIDCH_0033_TryAddNonceFailed, message.Nonce); + throw new OpenIdConnectProtocolException(string.Format(CultureInfo.InvariantCulture, Resources.OIDCH_0033_TryAddNonceFailed, message.Nonce)); + } } else { - RememberNonce(openIdConnectMessage.Nonce); + WriteNonceCookie(message.Nonce); } } - var notification = new RedirectToIdentityProviderNotification(Context, Options) + var redirectToIdentityProviderNotification = new RedirectToIdentityProviderNotification(Context, Options) { - ProtocolMessage = openIdConnectMessage + ProtocolMessage = message }; - await Options.Notifications.RedirectToIdentityProvider(notification); - if (!notification.HandledResponse) + await Options.Notifications.RedirectToIdentityProvider(redirectToIdentityProviderNotification); + if (redirectToIdentityProviderNotification.HandledResponse) { - string redirectUri = notification.ProtocolMessage.CreateAuthenticationRequestUrl(); - if (!Uri.IsWellFormedUriString(redirectUri, UriKind.Absolute)) - { - _logger.LogWarning("Uri.IsWellFormedUriString(redirectUri, UriKind.Absolute) returned 'false', redirectUri is: {0}", (redirectUri ?? "null")); - } + _logger.LogInformation(Resources.OIDCH_0034_RedirectToIdentityProviderNotificationHandledResponse); + return; + } + else if (redirectToIdentityProviderNotification.Skipped) + { + _logger.LogInformation(Resources.OIDCH_0035_RedirectToIdentityProviderNotificationSkipped); + return; + } - Response.Redirect(redirectUri); + string redirectUri = redirectToIdentityProviderNotification.ProtocolMessage.CreateAuthenticationRequestUrl(); + if (!Uri.IsWellFormedUriString(redirectUri, UriKind.Absolute)) + { + _logger.LogWarning(Resources.OIDCH_0036_UriIsNotWellFormed, redirectUri); } + + Response.Redirect(redirectUri); } protected override AuthenticationTicket AuthenticateCore() @@ -216,15 +248,21 @@ protected override AuthenticationTicket AuthenticateCore() /// Invoked to process incoming OpenIdConnect messages. /// /// An if successful. + /// Uses log id's OIDCH-0000 - OIDCH-0025 protected override async Task AuthenticateCoreAsync() { + if (_logger.IsEnabled(LogLevel.Debug)) + { + _logger.LogDebug(Resources.OIDCH_0000_AuthenticateCoreAsync, this.GetType()); + } + // Allow login to be constrained to a specific path. Need to make this runtime configurable. if (Options.CallbackPath.HasValue && Options.CallbackPath != (Request.PathBase + Request.Path)) { return null; } - OpenIdConnectMessage openIdConnectMessage = null; + OpenIdConnectMessage message = null; // assumption: if the ContentType is "application/x-www-form-urlencoded" it should be safe to read as it is small. if (string.Equals(Request.Method, "POST", StringComparison.OrdinalIgnoreCase) @@ -235,180 +273,215 @@ protected override async Task AuthenticateCoreAsync() { IFormCollection form = await Request.ReadFormAsync(); Request.Body.Seek(0, SeekOrigin.Begin); - - openIdConnectMessage = new OpenIdConnectMessage(form); + message = new OpenIdConnectMessage(form); } - if (openIdConnectMessage == null) + if (message == null) { return null; } try { - var messageReceivedNotification = new MessageReceivedNotification(Context, Options) + if (_logger.IsEnabled(LogLevel.Debug)) { - ProtocolMessage = openIdConnectMessage - }; + _logger.LogDebug(Resources.OIDCH_0001_MessageReceived, message.BuildRedirectUrl()); + } + + var messageReceivedNotification = + new MessageReceivedNotification(Context, Options) + { + ProtocolMessage = message + }; await Options.Notifications.MessageReceived(messageReceivedNotification); if (messageReceivedNotification.HandledResponse) { + _logger.LogInformation(Resources.OIDCH_0002_MessageReceivedNotificationHandledResponse); return messageReceivedNotification.AuthenticationTicket; } if (messageReceivedNotification.Skipped) { + _logger.LogInformation(Resources.OIDCH_0003_MessageReceivedNotificationSkipped); return null; } - // runtime always adds state, if we don't find it OR we failed to 'unprotect' it this is not a message we - // should process. - AuthenticationProperties properties = GetPropertiesFromState(openIdConnectMessage.State); - if (properties == null) + // runtime always adds state, if we don't find it OR we failed to 'unprotect' it this is not a message we should process. + if (string.IsNullOrWhiteSpace(message.State)) { - _logger.LogWarning("The state field is missing or invalid."); + _logger.LogError(Resources.OIDCH_0004_MessageStateIsNullOrWhiteSpace); return null; } - // devs will need to hook AuthenticationFailedNotification to avoid having 'raw' runtime errors displayed to users. - if (!string.IsNullOrWhiteSpace(openIdConnectMessage.Error)) - { - throw new OpenIdConnectProtocolException( - string.Format(CultureInfo.InvariantCulture, - openIdConnectMessage.Error, - Resources.Exception_OpenIdConnectMessageError, openIdConnectMessage.ErrorDescription ?? string.Empty, openIdConnectMessage.ErrorUri ?? string.Empty)); - } - - // code is only accepted with id_token, in this version, hence check for code is inside this if - // OpenIdConnect protocol allows a Code to be received without the id_token - if (string.IsNullOrWhiteSpace(openIdConnectMessage.IdToken)) + var properties = GetPropertiesFromState(message.State); + if (properties == null) { - _logger.LogWarning("The id_token is missing."); + _logger.LogError(Resources.OIDCH_0005_MessageStateIsInvalid); return null; } - var securityTokenReceivedNotification = new SecurityTokenReceivedNotification(Context, Options) - { - ProtocolMessage = openIdConnectMessage - }; - - await Options.Notifications.SecurityTokenReceived(securityTokenReceivedNotification); - if (securityTokenReceivedNotification.HandledResponse) + // devs will need to hook AuthenticationFailedNotification to avoid having 'raw' runtime errors displayed to users. + if (!string.IsNullOrWhiteSpace(message.Error)) { - return securityTokenReceivedNotification.AuthenticationTicket; + _logger.LogError(Resources.OIDCH_0006_MessageErrorNotNull, message.Error); + throw new OpenIdConnectProtocolException(string.Format(CultureInfo.InvariantCulture, Resources.OIDCH_0006_MessageErrorNotNull, message.Error)); } - if (securityTokenReceivedNotification.Skipped) - { - return null; - } + AuthenticationTicket ticket = null; + JwtSecurityToken jwt = null; if (_configuration == null && Options.ConfigurationManager != null) { + _logger.LogDebug(Resources.OIDCH_0007_UpdatingConfiguration); _configuration = await Options.ConfigurationManager.GetConfigurationAsync(Context.RequestAborted); } - // Copy and augment to avoid cross request race conditions for updated configurations. - TokenValidationParameters validationParameters = Options.TokenValidationParameters.Clone(); - if (_configuration != null) + // OpenIdConnect protocol allows a Code to be received without the id_token + if (!string.IsNullOrWhiteSpace(message.IdToken)) { - if (string.IsNullOrWhiteSpace(validationParameters.ValidIssuer)) + _logger.LogDebug(Resources.OIDCH_0020_IdTokenReceived, message.IdToken); + var securityTokenReceivedNotification = + new SecurityTokenReceivedNotification(Context, Options) + { + ProtocolMessage = message + }; + + await Options.Notifications.SecurityTokenReceived(securityTokenReceivedNotification); + if (securityTokenReceivedNotification.HandledResponse) { - validationParameters.ValidIssuer = _configuration.Issuer; + _logger.LogInformation(Resources.OIDCH_0008_SecurityTokenReceivedNotificationHandledResponse); + return securityTokenReceivedNotification.AuthenticationTicket; } - else if (!string.IsNullOrWhiteSpace(_configuration.Issuer)) + + if (securityTokenReceivedNotification.Skipped) { - validationParameters.ValidIssuers = (validationParameters.ValidIssuers == null ? new[] { _configuration.Issuer } : validationParameters.ValidIssuers.Concat(new[] { _configuration.Issuer })); + _logger.LogInformation(Resources.OIDCH_0009_SecurityTokenReceivedNotificationSkipped); + return null; } - validationParameters.IssuerSigningKeys = (validationParameters.IssuerSigningKeys == null ? _configuration.SigningKeys : validationParameters.IssuerSigningKeys.Concat(_configuration.SigningKeys)); - } + // Copy and augment to avoid cross request race conditions for updated configurations. + TokenValidationParameters validationParameters = Options.TokenValidationParameters.Clone(); + if (_configuration != null) + { + if (string.IsNullOrWhiteSpace(validationParameters.ValidIssuer)) + { + validationParameters.ValidIssuer = _configuration.Issuer; + } + else if (!string.IsNullOrWhiteSpace(_configuration.Issuer)) + { + validationParameters.ValidIssuers = validationParameters.ValidIssuers?.Concat(new[] { _configuration.Issuer }) ?? new[] { _configuration.Issuer }; + } - AuthenticationTicket ticket; - SecurityToken validatedToken = null; - ClaimsPrincipal principal = null; - JwtSecurityToken jwt = null; + validationParameters.IssuerSigningKeys = validationParameters.IssuerSigningKeys?.Concat(_configuration.SigningKeys) ?? _configuration.SigningKeys; + } - foreach (var validator in Options.SecurityTokenValidators) - { - if (validator.CanReadToken(openIdConnectMessage.IdToken)) + SecurityToken validatedToken = null; + ClaimsPrincipal principal = null; + foreach (var validator in Options.SecurityTokenValidators) { - principal = validator.ValidateToken(openIdConnectMessage.IdToken, validationParameters, out validatedToken); - jwt = validatedToken as JwtSecurityToken; - if (jwt == null) + if (validator.CanReadToken(message.IdToken)) { - throw new InvalidOperationException("Validated Security Token must be a JwtSecurityToken was: " + (validatedToken == null ? "null" : validatedToken.GetType().ToString())); + principal = validator.ValidateToken(message.IdToken, validationParameters, out validatedToken); + jwt = validatedToken as JwtSecurityToken; + if (jwt == null) + { + _logger.LogError(Resources.OIDCH_0010_ValidatedSecurityTokenNotJwt, validatedToken?.GetType()); + throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, Resources.OIDCH_0010_ValidatedSecurityTokenNotJwt, validatedToken?.GetType())); + } } } - } - if (validatedToken == null) - { - throw new InvalidOperationException("No SecurityTokenValidator found for token: " + openIdConnectMessage.IdToken); - } + if (validatedToken == null) + { + _logger.LogError(Resources.OIDCH_0011_UnableToValidateToken, message.IdToken); + throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, Resources.OIDCH_0011_UnableToValidateToken, message.IdToken)); + } - ticket = new AuthenticationTicket(principal, properties, Options.AuthenticationScheme); - if (!string.IsNullOrWhiteSpace(openIdConnectMessage.SessionState)) - { - ticket.Properties.Dictionary[OpenIdConnectSessionProperties.SessionState] = openIdConnectMessage.SessionState; - } + ticket = new AuthenticationTicket(principal, properties, Options.AuthenticationScheme); + if (!string.IsNullOrWhiteSpace(message.SessionState)) + { + ticket.Properties.Dictionary[OpenIdConnectSessionProperties.SessionState] = message.SessionState; + } - if (_configuration != null && !string.IsNullOrWhiteSpace(_configuration.CheckSessionIframe)) - { - ticket.Properties.Dictionary[OpenIdConnectSessionProperties.CheckSessionIFrame] = _configuration.CheckSessionIframe; - } + if (_configuration != null && !string.IsNullOrWhiteSpace(_configuration.CheckSessionIframe)) + { + ticket.Properties.Dictionary[OpenIdConnectSessionProperties.CheckSessionIFrame] = _configuration.CheckSessionIframe; + } - if (Options.UseTokenLifetime) - { - // Override any session persistence to match the token lifetime. - DateTime issued = validatedToken.ValidFrom; - if (issued != DateTime.MinValue) + // Rename? + if (Options.UseTokenLifetime) { - ticket.Properties.IssuedUtc = issued; + DateTime issued = validatedToken.ValidFrom; + if (issued != DateTime.MinValue) + { + ticket.Properties.IssuedUtc = issued; + } + + DateTime expires = validatedToken.ValidTo; + if (expires != DateTime.MinValue) + { + ticket.Properties.ExpiresUtc = expires; + } } - DateTime expires = validatedToken.ValidTo; - if (expires != DateTime.MinValue) + var securityTokenValidatedNotification = + new SecurityTokenValidatedNotification(Context, Options) + { + AuthenticationTicket = ticket, + ProtocolMessage = message + }; + + await Options.Notifications.SecurityTokenValidated(securityTokenValidatedNotification); + if (securityTokenValidatedNotification.HandledResponse) { - ticket.Properties.ExpiresUtc = expires; + _logger.LogInformation(Resources.OIDCH_0012_SecurityTokenValidatedNotificationHandledResponse); + return securityTokenValidatedNotification.AuthenticationTicket; } - ticket.Properties.AllowRefresh = false; - } + if (securityTokenValidatedNotification.Skipped) + { + _logger.LogInformation(Resources.OIDCH_0013_SecurityTokenValidatedNotificationSkipped); + return null; + } - var securityTokenValidatedNotification = new SecurityTokenValidatedNotification(Context, Options) - { - AuthenticationTicket = ticket, - ProtocolMessage = openIdConnectMessage - }; + string nonce = jwt.Payload.Nonce; + if (Options.NonceCache != null) + { + // if the nonce cannot be removed, it was used + if (!Options.NonceCache.TryRemoveNonce(nonce)) + { + nonce = null; + } + } + else + { + nonce = ReadNonceCookie(nonce); + } - await Options.Notifications.SecurityTokenValidated(securityTokenValidatedNotification); - if (securityTokenValidatedNotification.HandledResponse) - { - return securityTokenValidatedNotification.AuthenticationTicket; - } + var protocolValidationContext = new OpenIdConnectProtocolValidationContext + { + AuthorizationCode = message.Code, + Nonce = nonce, + }; - if (securityTokenValidatedNotification.Skipped) - { - return null; + Options.ProtocolValidator.Validate(jwt, protocolValidationContext); } - var protocolValidationContext = new OpenIdConnectProtocolValidationContext + if (message.Code != null) { - AuthorizationCode = openIdConnectMessage.Code, - Nonce = RetrieveNonce(jwt.Payload.Nonce), - }; + _logger.LogDebug(Resources.OIDCH_0014_CodeReceived, message.Code); + if (ticket == null) + { + ticket = new AuthenticationTicket(properties, Options.AuthenticationScheme); + } - Options.ProtocolValidator.Validate(jwt, protocolValidationContext); - if (openIdConnectMessage.Code != null) - { var authorizationCodeReceivedNotification = new AuthorizationCodeReceivedNotification(Context, Options) { AuthenticationTicket = ticket, - Code = openIdConnectMessage.Code, + Code = message.Code, JwtSecurityToken = jwt, - ProtocolMessage = openIdConnectMessage, + ProtocolMessage = message, RedirectUri = ticket.Properties.Dictionary.ContainsKey(OpenIdConnectAuthenticationDefaults.RedirectUriUsedForCodeKey) ? ticket.Properties.Dictionary[OpenIdConnectAuthenticationDefaults.RedirectUriUsedForCodeKey] : string.Empty, }; @@ -416,11 +489,13 @@ protected override async Task AuthenticateCoreAsync() await Options.Notifications.AuthorizationCodeReceived(authorizationCodeReceivedNotification); if (authorizationCodeReceivedNotification.HandledResponse) { + _logger.LogInformation(Resources.OIDCH_0015_CodeReceivedNotificationHandledResponse); return authorizationCodeReceivedNotification.AuthenticationTicket; } if (authorizationCodeReceivedNotification.Skipped) { + _logger.LogInformation(Resources.OIDCH_0016_CodeReceivedNotificationSkipped); return null; } } @@ -429,7 +504,7 @@ protected override async Task AuthenticateCoreAsync() } catch (Exception exception) { - _logger.LogError("Exception occurred while processing message", exception); + _logger.LogError(Resources.OIDCH_0017_ExceptionOccurredWhileProcessingMessage, exception); // Refresh the configuration for exceptions that may be caused by key rollovers. The user can also request a refresh in the notification. if (Options.RefreshOnIssuerKeyNotFound && exception.GetType().Equals(typeof(SecurityTokenSignatureKeyNotFoundException))) @@ -437,20 +512,23 @@ protected override async Task AuthenticateCoreAsync() Options.ConfigurationManager.RequestRefresh(); } - var authenticationFailedNotification = new AuthenticationFailedNotification(Context, Options) - { - ProtocolMessage = openIdConnectMessage, - Exception = exception - }; + var authenticationFailedNotification = + new AuthenticationFailedNotification(Context, Options) + { + ProtocolMessage = message, + Exception = exception + }; await Options.Notifications.AuthenticationFailed(authenticationFailedNotification); if (authenticationFailedNotification.HandledResponse) { + _logger.LogInformation(Resources.OIDCH_0018_AuthenticationFailedNotificationHandledResponse); return authenticationFailedNotification.AuthenticationTicket; } if (authenticationFailedNotification.Skipped) { + _logger.LogInformation(Resources.OIDCH_0019_AuthenticationFailedNotificationSkipped); return null; } @@ -464,7 +542,7 @@ protected override async Task AuthenticateCoreAsync() /// the nonce to remember. /// is called to add a cookie with the name: 'OpenIdConnectAuthenticationDefaults.Nonce + (nonce)'. /// The value of the cookie is: "N". - private void RememberNonce(string nonce) + private void WriteNonceCookie(string nonce) { if (string.IsNullOrWhiteSpace(nonce)) { @@ -484,13 +562,13 @@ private void RememberNonce(string nonce) /// /// Searches for a matching nonce. /// - /// the nonce that was found in the jwt token. - /// 'nonceExpectedValue' if a cookie is found that matches, null otherwise. + /// the nonce that we are looking for. + /// echos 'nonce' if a cookie is found that matches, null otherwise. /// Examine that start with the prefix: 'OpenIdConnectAuthenticationDefaults.Nonce'. /// is used to obtain the actual 'nonce'. If the nonce is found, then is called. - private string RetrieveNonce(string nonceExpectedValue) + private string ReadNonceCookie(string nonce) { - if (nonceExpectedValue == null) + if (nonce == null) { return null; } @@ -502,7 +580,7 @@ private string RetrieveNonce(string nonceExpectedValue) try { string nonceDecodedValue = Options.StringDataFormat.Unprotect(nonceKey.Substring(OpenIdConnectAuthenticationDefaults.CookieNoncePrefix.Length, nonceKey.Length - OpenIdConnectAuthenticationDefaults.CookieNoncePrefix.Length)); - if (nonceDecodedValue == nonceExpectedValue) + if (nonceDecodedValue == nonce) { var cookieOptions = new CookieOptions { @@ -511,7 +589,7 @@ private string RetrieveNonce(string nonceExpectedValue) }; Response.Cookies.Delete(nonceKey, cookieOptions); - return nonceExpectedValue; + return nonce; } } catch (Exception ex) diff --git a/src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenIdConnectAuthenticationMiddleware.cs b/src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenIdConnectAuthenticationMiddleware.cs index e58b7fff8..ee8eec0e5 100644 --- a/src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenIdConnectAuthenticationMiddleware.cs +++ b/src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenIdConnectAuthenticationMiddleware.cs @@ -30,9 +30,13 @@ public class OpenIdConnectAuthenticationMiddleware : AuthenticationMiddleware /// Initializes a /// - /// The next middleware in the ASP.NET pipeline to invoke - /// The ASP.NET application - /// Configuration options for the middleware + /// The next middleware in the ASP.NET pipeline to invoke. + /// provider for creating a data protector. + /// factory for creating a . + /// a instance that will supply + /// if configureOptions is null. + /// a instance that will be passed to an instance of + /// that is retrieved by calling where string == provides runtime configuration. [SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Justification = "Managed by caller")] public OpenIdConnectAuthenticationMiddleware( [NotNull] RequestDelegate next, @@ -40,21 +44,15 @@ public OpenIdConnectAuthenticationMiddleware( [NotNull] ILoggerFactory loggerFactory, [NotNull] IOptions externalOptions, [NotNull] IOptions options, - ConfigureOptions configureOptions) + ConfigureOptions configureOptions = null) : base(next, options, configureOptions) { _logger = loggerFactory.CreateLogger(); - - if (string.IsNullOrEmpty(Options.SignInScheme)) + if (string.IsNullOrEmpty(Options.SignInScheme) && !string.IsNullOrEmpty(externalOptions.Options.SignInScheme)) { Options.SignInScheme = externalOptions.Options.SignInScheme; } - if (string.IsNullOrWhiteSpace(Options.TokenValidationParameters.AuthenticationType)) - { - Options.TokenValidationParameters.AuthenticationType = Options.AuthenticationScheme; - } - if (Options.StateDataFormat == null) { var dataProtector = dataProtectionProvider.CreateProtector( @@ -152,7 +150,7 @@ private static HttpMessageHandler ResolveHttpMessageHandler(OpenIdConnectAuthent var webRequestHandler = handler as WebRequestHandler; if (webRequestHandler == null) { - throw new InvalidOperationException(Resources.Exception_ValidatorHandlerMismatch); + throw new InvalidOperationException(Resources.OIDCH_0102_ExceptionValidatorHandlerMismatch); } webRequestHandler.ServerCertificateValidationCallback = options.BackchannelCertificateValidator.Validate; } diff --git a/src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenIdConnectAuthenticationOptions.cs b/src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenIdConnectAuthenticationOptions.cs index f7bfde804..e5a3793d3 100644 --- a/src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenIdConnectAuthenticationOptions.cs +++ b/src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenIdConnectAuthenticationOptions.cs @@ -52,13 +52,12 @@ public OpenIdConnectAuthenticationOptions() [SuppressMessage("Microsoft.Globalization", "CA1303:Do not pass literals as localized parameters", MessageId = "Microsoft.Owin.Security.OpenIdConnect.OpenIdConnectAuthenticationOptions.set_Caption(System.String)", Justification = "Not a LOC field")] public OpenIdConnectAuthenticationOptions(string authenticationScheme) { - // REVIEW: why was this active by default?? - //AuthenticationMode = AuthenticationMode.Active; AuthenticationScheme = authenticationScheme; BackchannelTimeout = TimeSpan.FromMinutes(1); Caption = OpenIdConnectAuthenticationDefaults.Caption; ProtocolValidator = new OpenIdConnectProtocolValidator(); RefreshOnIssuerKeyNotFound = true; + ResponseMode = OpenIdConnectResponseModes.FormPost; ResponseType = OpenIdConnectResponseTypes.CodeIdToken; Scope = OpenIdConnectScopes.OpenIdProfile; TokenValidationParameters = new TokenValidationParameters(); @@ -66,17 +65,17 @@ public OpenIdConnectAuthenticationOptions(string authenticationScheme) } /// - /// Gets or sets the Authority to use when making OpenIdConnect calls. + /// Gets or sets the expected audience for any received JWT token. /// - public string Authority { get; set; } + /// + /// The expected audience for any received JWT token. + /// + public string Audience { get; set; } /// - /// An optional constrained path on which to process the authentication callback. - /// If not provided and RedirectUri is available, this value will be generated from RedirectUri. + /// Gets or sets the Authority to use when making OpenIdConnect calls. /// - /// If you set this value, then the will only listen for posts at this address. - /// If the IdentityProvider does not post to this address, you may end up in a 401 -> IdentityProvider -> Client -> 401 -> ... - public PathString CallbackPath { get; set; } + public string Authority { get; set; } #if DNX451 /// @@ -112,7 +111,7 @@ public TimeSpan BackchannelTimeout { if (value <= TimeSpan.Zero) { - throw new ArgumentOutOfRangeException("BackchannelTimeout", value, Resources.ArgsException_BackchallelLessThanZero); + throw new ArgumentOutOfRangeException("BackchannelTimeout", value, Resources.OIDCH_0101_BackChallnelLessThanZero); } _backchannelTimeout = value; @@ -128,6 +127,14 @@ public string Caption set { Description.Caption = value; } } + /// + /// An optional constrained path on which to process the authentication callback. + /// If not provided and RedirectUri is available, this value will be generated from RedirectUri. + /// + /// If you set this value, then the will only listen for posts at this address. + /// If the IdentityProvider does not post to this address, you may end up in a 401 -> IdentityProvider -> Client -> 401 -> ... + public PathString CallbackPath { get; set; } + /// /// Gets or sets the 'client_id'. /// @@ -145,36 +152,28 @@ public string Caption public OpenIdConnectConfiguration Configuration { get; set; } /// - /// The OpenIdConnect protocol http://openid.net/specs/openid-connect-core-1_0.html - /// recommends adding a nonce to a request as a mitigation against replay attacks when requesting id_tokens. - /// By default the runtime uses cookies with unique names generated from a hash of the nonce. - /// - public INonceCache NonceCache { get; set; } - - /// - /// Gets or sets the discovery endpoint for obtaining metadata + /// Responsible for retrieving, caching, and refreshing the configuration from metadata. + /// If not provided, then one will be created using the MetadataAddress and Backchannel properties. /// - public string MetadataAddress { get; set; } + public IConfigurationManager ConfigurationManager { get; set; } /// - /// Gets or sets the expected audience for any received JWT token. + /// Gets or sets a value controlling if the 'CurrentUri' should be used as the 'local redirect' post authentication + /// if AuthenticationProperties.RedirectUri is null or empty. /// - /// - /// The expected audience for any received JWT token. - /// - public string Audience { get; set; } + public bool DefaultToCurrentUriOnRedirect { get; set; } /// - /// Responsible for retrieving, caching, and refreshing the configuration from metadata. - /// If not provided, then one will be created using the MetadataAddress and Backchannel properties. + /// Gets or sets the discovery endpoint for obtaining metadata /// - public IConfigurationManager ConfigurationManager { get; set; } + public string MetadataAddress { get; set; } /// - /// Gets or sets if a metadata refresh should be attempted after a SecurityTokenSignatureKeyNotFoundException. This allows for automatic - /// recovery in the event of a signature key rollover. This is enabled by default. + /// The OpenIdConnect protocol http://openid.net/specs/openid-connect-core-1_0.html + /// recommends adding a nonce to a request as a mitigation against replay attacks when requesting id_tokens. + /// By default the runtime uses cookies with unique names generated from a hash of the nonce. /// - public bool RefreshOnIssuerKeyNotFound { get; set; } + public INonceCache NonceCache { get; set; } /// /// Gets or sets the to notify when processing OpenIdConnect messages. @@ -217,11 +216,22 @@ public OpenIdConnectProtocolValidator ProtocolValidator [SuppressMessage("Microsoft.Design", "CA1056:UriPropertiesShouldNotBeStrings", Justification = "By Design")] public string RedirectUri { get; set; } + /// + /// Gets or sets if a metadata refresh should be attempted after a SecurityTokenSignatureKeyNotFoundException. This allows for automatic + /// recovery in the event of a signature key rollover. This is enabled by default. + /// + public bool RefreshOnIssuerKeyNotFound { get; set; } + /// /// Gets or sets the 'resource'. /// public string Resource { get; set; } + /// + /// Gets or sets the 'response_mode'. + /// + public string ResponseMode { get; private set; } + /// /// Gets or sets the 'response_type'. /// @@ -233,10 +243,7 @@ public OpenIdConnectProtocolValidator ProtocolValidator public string Scope { get; set; } /// - /// Gets or sets the authentication scheme corresponding to the middleware - /// responsible of persisting user's identity after a successful authentication. - /// This value typically corresponds to a cookie middleware registered in the Startup class. - /// When omitted, is used as a fallback value. + /// Gets or sets the SignInScheme which will be used to set the . /// public string SignInScheme { get; set; } diff --git a/src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenIdConnectServiceCollectionExtensions.cs b/src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenIdConnectServiceCollectionExtensions.cs index 6f5544889..2e55b96fa 100644 --- a/src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenIdConnectServiceCollectionExtensions.cs +++ b/src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenIdConnectServiceCollectionExtensions.cs @@ -15,7 +15,7 @@ public static class OpenIdConnectServiceCollectionExtensions { public static IServiceCollection ConfigureOpenIdConnectAuthentication([NotNull] this IServiceCollection services, [NotNull] Action configure) { - return services.ConfigureOpenIdConnectAuthentication(configure, optionsName: ""); + return ConfigureOpenIdConnectAuthentication(services, configure, null); } public static IServiceCollection ConfigureOpenIdConnectAuthentication([NotNull] this IServiceCollection services, [NotNull] Action configure, string optionsName) @@ -25,7 +25,7 @@ public static IServiceCollection ConfigureOpenIdConnectAuthentication([NotNull] public static IServiceCollection ConfigureOpenIdConnectAuthentication([NotNull] this IServiceCollection services, [NotNull] IConfiguration config) { - return services.ConfigureOpenIdConnectAuthentication(config, optionsName: ""); + return ConfigureOpenIdConnectAuthentication(services, config, null); } public static IServiceCollection ConfigureOpenIdConnectAuthentication([NotNull] this IServiceCollection services, [NotNull] IConfiguration config, string optionsName) diff --git a/src/Microsoft.AspNet.Authentication.OpenIdConnect/Resources.Designer.cs b/src/Microsoft.AspNet.Authentication.OpenIdConnect/Resources.Designer.cs index ee19db011..b95de8318 100644 --- a/src/Microsoft.AspNet.Authentication.OpenIdConnect/Resources.Designer.cs +++ b/src/Microsoft.AspNet.Authentication.OpenIdConnect/Resources.Designer.cs @@ -1,18 +1,9 @@ -//------------------------------------------------------------------------------ -// -// This code was generated by a tool. -// Runtime Version:4.0.30319.34014 -// -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace Microsoft.AspNet.Authentication.OpenIdConnect { - using System; +// +namespace Microsoft.AspNet.Authentication.OpenIdConnect +{ + using System.Globalization; using System.Reflection; - - + using System.Resources; /// /// A strongly-typed resource class, for looking up localized strings, etc. @@ -24,78 +15,337 @@ namespace Microsoft.AspNet.Authentication.OpenIdConnect { [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - internal class Resources { - + internal class Resources + { private static global::System.Resources.ResourceManager resourceMan; - + private static global::System.Globalization.CultureInfo resourceCulture; - + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - internal Resources() { + internal Resources() + { } - + /// /// Returns the cached ResourceManager instance used by this class. /// [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Resources.ResourceManager ResourceManager { - get { - if (object.ReferenceEquals(resourceMan, null)) { - global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Microsoft.Owin.Security.OpenIdConnect.Resources", IntrospectionExtensions.GetTypeInfo(typeof(Resources)).Assembly); + internal static global::System.Resources.ResourceManager ResourceManager + { + get + { + if (object.ReferenceEquals(resourceMan, null)) + { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Microsoft.AspNet.Authentication.OpenIdConnect.Resources", System.Reflection.IntrospectionExtensions.GetTypeInfo(typeof(Resources)).Assembly); resourceMan = temp; } return resourceMan; } } - + /// /// Overrides the current thread's CurrentUICulture property for all /// resource lookups using this strongly typed resource class. /// [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Globalization.CultureInfo Culture { - get { + internal static global::System.Globalization.CultureInfo Culture + { + get + { return resourceCulture; } - set { + set + { resourceCulture = value; } } - + /// - /// Looks up a localized string similar to BackchannelTimeout cannot be less or equal to TimeSpan.Zero.. + /// OIDCH_0101: BackchannelTimeout cannot be less or equal to TimeSpan.Zero. /// - internal static string ArgsException_BackchallelLessThanZero { - get { - return ResourceManager.GetString("ArgsException_BackchallelLessThanZero", resourceCulture); - } + internal static string OIDCH_0101_BackChallnelLessThanZero + { + get { return ResourceManager.GetString("OIDCH_0101_BackChallnelLessThanZero"); } + } + + /// + /// OIDCH0102: An ICertificateValidator cannot be specified at the same time as an HttpMessageHandler unless it is a WebRequestHandler. + /// + internal static string OIDCH_0102_ExceptionValidatorHandlerMismatch + { + get { return ResourceManager.GetString("OIDCH_0102_Exception_ValidatorHandlerMismatch"); } } - + /// - /// Looks up a localized string similar to "OpenIdConnectMessage.Error was not null, indicating an error. Error: '{0}'. Error_Description (may be empty): '{1}'. Error_Uri (may be empty): '{2}'.". + /// OIDCH_0051: The query string for Logout is not a well formed URI. The runtime cannot redirect. Redirect uri: '{0}'. /// - internal static string Exception_OpenIdConnectMessageError { - get { - return ResourceManager.GetString("Exception_OpenIdConnectMessageError", resourceCulture); - } + internal static string OIDCH_0051_RedirectUriLogoutIsNotWellFormed + { + get { return ResourceManager.GetString("OIDCH_0051_RedirectUriLogoutIsNotWellFormed"); } } - + /// - /// Looks up a localized string similar to OIDC_20001: The query string for Logout is not a well formed URI. The runtime cannot redirect. Redirect uri: '{0}'.. + /// OIDCH_0026: Entering: '{0}' /// - internal static string Exception_RedirectUri_LogoutQueryString_IsNotWellFormed { - get { - return ResourceManager.GetString("Exception_RedirectUri_LogoutQueryString_IsNotWellFormed", resourceCulture); - } + internal static string OIDCH_0026_ApplyResponseChallengeAsync + { + get { return ResourceManager.GetString("OIDCH_0026_ApplyResponseChallengeAsync"); } } - + /// - /// Looks up a localized string similar to An ICertificateValidator cannot be specified at the same time as an HttpMessageHandler unless it is a An ICertificateValidator cannot be specified at the same time as an HttpMessageHandler unless it is a WebRequestHandler.. + /// OIDCH_0027: converted 401 to 403. /// - internal static string Exception_ValidatorHandlerMismatch { - get { - return ResourceManager.GetString("Exception_ValidatorHandlerMismatch", resourceCulture); - } + internal static string OIDCH_0027_401_ConvertedTo_403 + { + get { return ResourceManager.GetString("OIDCH_0027_401_ConvertedTo_403"); } + } + + /// + /// OIDCH_0028: Response.StatusCode != 401, StatusCode: '{0}'." + /// + internal static string OIDCH_0028_StatusCodeNot401 + { + get { return ResourceManager.GetString("OIDCH_0028_StatusCodeNot401"); } + } + + /// + /// OIDCH_0029: ChallengeContext == null AND !Options.AutomaticAuthentication + /// + internal static string OIDCH_0029_ChallengeContextEqualsNull + { + get { return ResourceManager.GetString("OIDCH_0029_ChallengeContextEqualsNull"); } + } + + /// + /// OIDCH_0030: using properties.RedirectUri for 'local redirect' post authentication: '{0}'. + /// + internal static string OIDCH_0030_Using_Properties_RedirectUri + { + get { return ResourceManager.GetString("OIDCH_0030_Using_Properties_RedirectUri"); } + } + + /// + /// OIDCH_0031: using Options.RedirectUri for 'redirect_uri': '{0}'. + /// + internal static string OIDCH_0031_Using_Options_RedirectUri + { + get { return ResourceManager.GetString("OIDCH_0031_Using_Options_RedirectUri"); } + } + + /// + /// OIDCH_0032: using the CurrentUri for 'local redirect' post authentication: '{0}'. + /// + internal static string OIDCH_0032_UsingCurrentUriRedirectUri + { + get { return ResourceManager.GetString("OIDCH_0032_UsingCurrentUriRedirectUri"); } + } + + /// + /// OIDCH_0033: ProtocolValidator.RequireNonce == true. Options.NonceCache.TryAddNonce returned false. This usually indicates the nonce is not unique or has been used. The nonce is: '{0}'. + /// + internal static string OIDCH_0033_TryAddNonceFailed + { + get { return ResourceManager.GetString("OIDCH_0033_TryAddNonceFailed"); } + } + + /// + /// OIDCH_0034: redirectToIdentityProviderNotification.HandledResponse + /// + internal static string OIDCH_0034_RedirectToIdentityProviderNotificationHandledResponse + { + get { return ResourceManager.GetString("OIDCH_0034_RedirectToIdentityProviderNotificationHandledResponse"); } + } + + /// + /// OIDCH_0035: redirectToIdentityProviderNotification.Skipped + /// + internal static string OIDCH_0035_RedirectToIdentityProviderNotificationSkipped + { + get { return ResourceManager.GetString("OIDCH_0035_RedirectToIdentityProviderNotificationSkipped"); } + } + + /// + /// OIDCH_0036: Uri.IsWellFormedUriString(redirectUri, UriKind.Absolute) returned 'false', redirectUri is: {0}", (redirectUri ?? "null")) + /// + internal static string OIDCH_0036_UriIsNotWellFormed + { + get { return ResourceManager.GetString("OIDCH_0036_UriIsNotWellFormed"); } + } + + /// + /// OIDCH_0000: Entering: '{0}'. + /// + internal static string OIDCH_0000_AuthenticateCoreAsync + { + get { return ResourceManager.GetString("OIDCH_0000_AuthenticateCoreAsync"); } + } + + /// + /// OIDCH_0001: MessageReceived: '{0}'. + /// + internal static string OIDCH_0001_MessageReceived + { + get { return ResourceManager.GetString("OIDCH_0001_MessageReceived"); } + } + + /// + /// OIDCH_0001: MessageReceived: '{0}'. + /// + internal static string FormatOIDCH_0001_MessageReceived(object p0) + { + return string.Format(CultureInfo.CurrentCulture, ResourceManager.GetString("OIDCH_0001_MessageReceived"), p0); + } + + /// + /// OIDCH_0002: messageReceivedNotification.HandledResponse + /// + internal static string OIDCH_0002_MessageReceivedNotificationHandledResponse + { + get { return ResourceManager.GetString("OIDCH_0002_MessageReceivedNotificationHandledResponse"); } + } + + /// + /// OIDCH_0003: messageReceivedNotification.Skipped + /// + internal static string OIDCH_0003_MessageReceivedNotificationSkipped + { + get { return ResourceManager.GetString("OIDCH_0003_MessageReceivedNotificationSkipped"); } + } + + /// + /// OIDCH_0004: OpenIdConnectAuthenticationHandler: message.State is null or whitespace. State is required to process the message. + /// + internal static string OIDCH_0004_MessageStateIsNullOrWhiteSpace + { + get { return ResourceManager.GetString("OIDCH_0004_MessageStateIsNullOrWhiteSpace"); } + } + + /// + /// OIDCH_0005: unable to unprotect the message.State + /// + internal static string OIDCH_0005_MessageStateIsInvalid + { + get { return ResourceManager.GetString("OIDCH_0005_MessageStateIsInvalid"); } + } + + /// + /// OIDCH_0006_MessageErrorNotNull: '{0}'. + /// + internal static string OIDCH_0006_MessageErrorNotNull + { + get { return ResourceManager.GetString("OIDCH_0006_MessageErrorNotNull"); } + } + + /// + /// OIDCH_0007: updating configuration + /// + internal static string OIDCH_0007_UpdatingConfiguration + { + get { return ResourceManager.GetString("OIDCH_0007_UpdatingConfiguration"); } + } + + /// + /// OIDCH_0008: securityTokenReceivedNotification.HandledResponse + /// + internal static string OIDCH_0008_SecurityTokenReceivedNotificationHandledResponse + { + get { return ResourceManager.GetString("OIDCH_0008_SecurityTokenReceivedNotificationHandledResponse"); } + } + + /// + /// OIDCH_0009: securityTokenReceivedNotification.Skipped + /// + internal static string OIDCH_0009_SecurityTokenReceivedNotificationSkipped + { + get { return ResourceManager.GetString("OIDCH_0009_SecurityTokenReceivedNotificationSkipped:"); } + } + + /// + /// OIDCH_0010: Validated Security Token must be a JwtSecurityToken was: '{0}'. + /// + internal static string OIDCH_0010_ValidatedSecurityTokenNotJwt + { + get { return ResourceManager.GetString("OIDCH_0010_ValidatedSecurityTokenNotJwt"); } + } + + /// + /// OIDCH_0011: Unable to validate the 'id_token', no suitable ISecurityTokenValidator was found for: {0}." + /// + internal static string OIDCH_0011_UnableToValidateToken + { + get { return ResourceManager.GetString("OIDCH_0011_UnableToValidateToken"); } + } + + /// + /// OIDCH_0012: securityTokenValidatedNotification.HandledResponse + /// + internal static string OIDCH_0012_SecurityTokenValidatedNotificationHandledResponse + { + get { return ResourceManager.GetString("OIDCH_0012_SecurityTokenValidatedNotificationHandledResponse"); } + } + + /// + /// OIDCH_0013: securityTokenValidatedNotification.Skipped + /// + internal static string OIDCH_0013_SecurityTokenValidatedNotificationSkipped + { + get { return ResourceManager.GetString("OIDCH_0013_SecurityTokenValidatedNotificationSkipped"); } + } + + /// + /// OIDCH_0014: 'code' received: '{0}' + /// + internal static string OIDCH_0014_CodeReceived + { + get { return ResourceManager.GetString("OIDCH_0014_CodeReceived"); } + } + + /// + /// OIDCH_0015: codeReceivedNotification.HandledResponse") + /// + internal static string OIDCH_0015_CodeReceivedNotificationHandledResponse + { + get { return ResourceManager.GetString("OIDCH_0015_CodeReceivedNotificationHandledResponse"); } + } + + /// + /// OIDCH_0016: codeReceivedNotification.Skipped + /// + internal static string OIDCH_0016_CodeReceivedNotificationSkipped + { + get { return ResourceManager.GetString("OIDCH_0016_CodeReceivedNotificationSkipped"); } + } + + /// + /// OIDCH_0017: Exception occurred while processing message + /// + internal static string OIDCH_0017_ExceptionOccurredWhileProcessingMessage + { + get { return ResourceManager.GetString("OIDCH_0017_ExceptionOccurredWhileProcessingMessage"); } + } + + /// + /// OIDCH_0018: authenticationFailedNotification.HandledResponse + /// + internal static string OIDCH_0018_AuthenticationFailedNotificationHandledResponse + { + get { return ResourceManager.GetString("OIDCH_0018_AuthenticationFailedNotificationHandledResponse"); } + } + + /// + /// OIDCH_0019: authenticationFailedNotification.Skipped + /// + internal static string OIDCH_0019_AuthenticationFailedNotificationSkipped + { + get { return ResourceManager.GetString("OIDCH_0019_AuthenticationFailedNotificationSkipped"); } + } + + /// + /// OIDCH_0020: 'id_token' received: '{0}' + /// + internal static string OIDCH_0020_IdTokenReceived + { + get { return ResourceManager.GetString("OIDCH_0020_IdTokenReceived"); } } } } diff --git a/src/Microsoft.AspNet.Authentication.OpenIdConnect/Resources.resx b/src/Microsoft.AspNet.Authentication.OpenIdConnect/Resources.resx index 7abad90eb..454dae209 100644 --- a/src/Microsoft.AspNet.Authentication.OpenIdConnect/Resources.resx +++ b/src/Microsoft.AspNet.Authentication.OpenIdConnect/Resources.resx @@ -117,16 +117,109 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - BackchannelTimeout cannot be less or equal to TimeSpan.Zero. + + OIDCH_0101: BackchannelTimeout cannot be less or equal to TimeSpan.Zero. - - "OpenIdConnectMessage.Error was not null, indicating an error. Error: '{0}'. Error_Description (may be empty): '{1}'. Error_Uri (may be empty): '{2}'." + + OIDCH_0102: An ICertificateValidator cannot be specified at the same time as an HttpMessageHandler unless it is a WebRequestHandler. - - OIDC_20001: The query string for Logout is not a well formed URI. The runtime cannot redirect. Redirect uri: '{0}'. + + OIDC_0051: The query string for Logout is not a well formed URI. The runtime cannot redirect. Redirect uri: '{0}'. - - An ICertificateValidator cannot be specified at the same time as an HttpMessageHandler unless it is a WebRequestHandler. + + OIDCH_0026: Entering: '{0}' - \ No newline at end of file + + OIDCH_0027: converted 401 to 403. + + + OIDCH_0028: Response.StatusCode != 401, StatusCode: '{0}'. + + + OIDCH_0029: ChallengeContext == null AND !Options.AutomaticAuthentication + + + OIDCH_0030: using properties.RedirectUri for 'local redirect' post authentication: '{0}'. + + + OIDCH_0031: using Options.RedirectUri for 'redirect_uri': '{0}'. + + + OIDCH_0032: using the CurrentUri for 'local redirect' post authentication: '{0}'. + + + OIDCH_0033: ProtocolValidator.RequireNonce == true. Options.NonceCache.TryAddNonce returned false. This usually indicates the nonce is not unique or has been used. The nonce is: '{0}'. + + + OIDCH_0034: redirectToIdentityProviderNotification.HandledResponse + + + OIDCH_0035: redirectToIdentityProviderNotification.Skipped + + + OIDCH_0036: Uri.IsWellFormedUriString(redirectUri, UriKind.Absolute) returned 'false', redirectUri is: {0}", (redirectUri ?? "null")) + + + OIDCH_0000: Entering: '{0}'. + + + OIDCH_0001: MessageReceived: '{0}'. + + + OIDCH_0002: messageReceivedNotification.HandledResponse + + + OIDCH_0003: messageReceivedNotification.Skipped + + + OIDCH_0004: OpenIdConnectAuthenticationHandler: message.State is null or whitespace. State is required to process the message. + + + OIDCH_0005: unable to unprotect the message.State + + + OIDCH_0006_MessageErrorNotNull: '{0}'. + + + OIDCH_0007: updating configuration + + + OIDCH_0008: securityTokenReceivedNotification.HandledResponse + + + OIDCH_0009: securityTokenReceivedNotification.Skipped + + + OIDCH_0010: Validated Security Token must be a JwtSecurityToken was: '{0}'. + + + OIDCH_0011: Unable to validate the 'id_token', no suitable ISecurityTokenValidator was found for: {0}." + + + OIDCH_0012: securityTokenValidatedNotification.HandledResponse + + + OIDCH_0013: securityTokenValidatedNotification.Skipped + + + OIDCH_0014: 'code' received: '{0}' + + + OIDCH_0015: codeReceivedNotification.HandledResponse + + + OIDCH_0016: codeReceivedNotification.Skipped + + + OIDCH_0017: Exception occurred while processing message + + + OIDCH_0018: authenticationFailedNotification.HandledResponse + + + OIDCH_0019: authenticationFailedNotification.Skipped + + + OIDCH_0020: 'id_token' received: '{0}' + + diff --git a/test/Microsoft.AspNet.Authentication.Test/OpenIdConnect/OpenIdConnectHandlerTests.cs b/test/Microsoft.AspNet.Authentication.Test/OpenIdConnect/OpenIdConnectHandlerTests.cs new file mode 100644 index 000000000..5817615f2 --- /dev/null +++ b/test/Microsoft.AspNet.Authentication.Test/OpenIdConnect/OpenIdConnectHandlerTests.cs @@ -0,0 +1,768 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +// this controls if the logs are written to the console. +// they can be reviewed for general content. +//#define _Verbose + +using System; +using System.Collections.Generic; +using System.Net.Http; +using System.Security.Claims; +using System.Threading.Tasks; +using Microsoft.AspNet.Authentication.Notifications; +using Microsoft.AspNet.Authentication.OpenIdConnect; +using Microsoft.AspNet.Builder; +using Microsoft.AspNet.DataProtection; +using Microsoft.AspNet.Http; +using Microsoft.AspNet.Http.Authentication; +using Microsoft.AspNet.TestHost; +using Microsoft.Framework.DependencyInjection; +using Microsoft.Framework.Logging; +using Microsoft.Framework.OptionsModel; +using Microsoft.IdentityModel.Protocols; +using Shouldly; +using Xunit; + +namespace Microsoft.AspNet.Authentication.Tests.OpenIdConnect +{ + /// + /// These tests are designed to test OpenIdConnectAuthenticationHandler. + /// + public class OpenIdConnectHandlerTests + { + static List CompleteLogEntries; + static Dictionary LogEntries; + + static OpenIdConnectHandlerTests() + { + LogEntries = + new Dictionary() + { + { "OIDCH_0000:", LogLevel.Debug }, + { "OIDCH_0001:", LogLevel.Debug }, + { "OIDCH_0002:", LogLevel.Information }, + { "OIDCH_0003:", LogLevel.Information }, + { "OIDCH_0004:", LogLevel.Error }, + { "OIDCH_0005:", LogLevel.Error }, + { "OIDCH_0006:", LogLevel.Error }, + { "OIDCH_0007:", LogLevel.Error }, + { "OIDCH_0008:", LogLevel.Debug }, + { "OIDCH_0009:", LogLevel.Debug }, + { "OIDCH_0010:", LogLevel.Error }, + { "OIDCH_0011:", LogLevel.Error }, + { "OIDCH_0012:", LogLevel.Debug }, + { "OIDCH_0013:", LogLevel.Debug }, + { "OIDCH_0014:", LogLevel.Debug }, + { "OIDCH_0015:", LogLevel.Debug }, + { "OIDCH_0016:", LogLevel.Debug }, + { "OIDCH_0017:", LogLevel.Error }, + { "OIDCH_0018:", LogLevel.Debug }, + { "OIDCH_0019:", LogLevel.Debug }, + { "OIDCH_0020:", LogLevel.Debug }, + { "OIDCH_0026:", LogLevel.Error }, + }; + + BuildLogEntryList(); + } + + /// + /// Builds the complete list of log entries that are available in the runtime. + /// + private static void BuildLogEntryList() + { + CompleteLogEntries = new List(); + foreach (var entry in LogEntries) + { + CompleteLogEntries.Add(new LogEntry { State = entry.Key, Level = entry.Value }); + } + } + + /// + /// Sanity check that logging is filtering, hi / low water marks are checked + /// + [Fact] + public void LoggingLevel() + { + var logger = new CustomLogger(LogLevel.Debug); + logger.IsEnabled(LogLevel.Critical).ShouldBe(true); + logger.IsEnabled(LogLevel.Debug).ShouldBe(true); + logger.IsEnabled(LogLevel.Error).ShouldBe(true); + logger.IsEnabled(LogLevel.Information).ShouldBe(true); + logger.IsEnabled(LogLevel.Verbose).ShouldBe(true); + logger.IsEnabled(LogLevel.Warning).ShouldBe(true); + + logger = new CustomLogger(LogLevel.Critical); + logger.IsEnabled(LogLevel.Critical).ShouldBe(true); + logger.IsEnabled(LogLevel.Debug).ShouldBe(false); + logger.IsEnabled(LogLevel.Error).ShouldBe(false); + logger.IsEnabled(LogLevel.Information).ShouldBe(false); + logger.IsEnabled(LogLevel.Verbose).ShouldBe(false); + logger.IsEnabled(LogLevel.Warning).ShouldBe(false); + } + + /// + /// Test produces expected logs. + /// Each call to 'RunVariation' is configured with an and . + /// The list of expected log entries is checked and any errors reported. + /// captures the logs so they can be prepared. + /// + /// + [Fact] + public async Task AuthenticateCore() + { + //System.Diagnostics.Debugger.Launch(); + + var propertiesFormatter = new AuthenticationPropertiesFormater(); + var protectedProperties = propertiesFormatter.Protect(new AuthenticationProperties()); + var state = OpenIdConnectAuthenticationDefaults.AuthenticationPropertiesKey + "=" + Uri.EscapeDataString(protectedProperties); + var code = Guid.NewGuid().ToString(); + var message = + new OpenIdConnectMessage + { + Code = code, + State = state, + }; + + var errors = new Dictionary>>(); + + var logsEntriesExpected = new int[] { 0, 1, 7, 14, 15 }; + await RunVariation(LogLevel.Debug, message, CodeReceivedHandledOptions, errors, logsEntriesExpected); + + logsEntriesExpected = new int[] { 0, 1, 7, 14, 16 }; + await RunVariation(LogLevel.Debug, message, CodeReceivedSkippedOptions, errors, logsEntriesExpected); + + logsEntriesExpected = new int[] { 0, 1, 7, 14 }; + await RunVariation(LogLevel.Debug, message, DefaultOptions, errors, logsEntriesExpected); + + // each message below should return before processing the idtoken + message.IdToken = "invalid_token"; + + logsEntriesExpected = new int[] { 0, 1, 2 }; + await RunVariation(LogLevel.Debug, message, MessageReceivedHandledOptions, errors, logsEntriesExpected); + + logsEntriesExpected = new int[]{ 2 }; + await RunVariation(LogLevel.Information, message, MessageReceivedHandledOptions, errors, logsEntriesExpected); + + logsEntriesExpected = new int[] { 0, 1, 3 }; + await RunVariation(LogLevel.Debug, message, MessageReceivedSkippedOptions, errors, logsEntriesExpected); + + logsEntriesExpected = new int[] { 3 }; + await RunVariation(LogLevel.Information, message, MessageReceivedSkippedOptions, errors, logsEntriesExpected); + + logsEntriesExpected = new int[] {0, 1, 7, 20, 8 }; + await RunVariation(LogLevel.Debug, message, SecurityTokenReceivedHandledOptions, errors, logsEntriesExpected); + + logsEntriesExpected = new int[] {0, 1, 7, 20, 9 }; + await RunVariation(LogLevel.Debug, message, SecurityTokenReceivedSkippedOptions, errors, logsEntriesExpected); + +#if _Verbose + Console.WriteLine("\n ===== \n"); + DisplayErrors(errors); +#endif + errors.Count.ShouldBe(0); + } + + /// + /// Tests that processes a messaage as expected. + /// The test runs two independant paths: Using and + /// + /// for this variation + /// the that has arrived + /// the delegate used for setting the options. + /// container for propogation of errors. + /// the expected log entries + /// a Task + private async Task RunVariation(LogLevel logLevel, OpenIdConnectMessage message, Action action, Dictionary>> errors, int[] logsEntriesExpected) + { + var expectedLogs = PopulateLogEntries(logsEntriesExpected); + string variation = action.Method.ToString().Substring(5, action.Method.ToString().IndexOf('(') - 5); +#if _Verbose + Console.WriteLine(Environment.NewLine + "=====" + Environment.NewLine + "Variation: " + variation + ", LogLevel: " + logLevel.ToString() + Environment.NewLine + Environment.NewLine + "Expected Logs: "); + DisplayLogs(expectedLogs); + Console.WriteLine(Environment.NewLine + "Logs using ConfigureOptions:"); +#endif + var form = new FormUrlEncodedContent(message.Parameters); + var loggerFactory = new CustomLoggerFactory(logLevel); + var server = CreateServer(new CustomConfigureOptions(action), loggerFactory); + await server.CreateClient().PostAsync("http://localhost", form); + CheckLogs(variation + ":ConfigOptions", loggerFactory.Logger.Logs, expectedLogs, errors); + +#if _Verbose + Console.WriteLine(Environment.NewLine + "Logs using IOptions:"); +#endif + form = new FormUrlEncodedContent(message.Parameters); + loggerFactory = new CustomLoggerFactory(logLevel); + server = CreateServer(new Options(action), loggerFactory); + await server.CreateClient().PostAsync("http://localhost", form); + CheckLogs(variation + ":IOptions", loggerFactory.Logger.Logs, expectedLogs, errors); + } + + /// + /// Populates a list of expected log entries for a test variation. + /// + /// the index for the in CompleteLogEntries of interest. + /// a that represents the expected entries for a test variation. + private List PopulateLogEntries(int[] items) + { + var entries = new List(); + foreach(var item in items) + { + entries.Add(CompleteLogEntries[item]); + } + + return entries; + } + + private void DisplayLogs(List logs) + { + foreach (var logentry in logs) + { + Console.WriteLine(logentry.ToString()); + } + } + + private void DisplayErrors(Dictionary>> errors) + { + if (errors.Count > 0) + { + foreach (var error in errors) + { + Console.WriteLine("Error in Variation: " + error.Key); + foreach (var logError in error.Value) + { + Console.WriteLine("*Captured*, *Expected* : *" + (logError.Item1?.ToString() ?? "null") + "*, *" + (logError.Item2?.ToString() ?? "null") + "*"); + } + Console.WriteLine(Environment.NewLine); + } + } + } + + /// + /// Adds to errors if a variation if any are found. + /// + /// if this has been seen before, errors will be appended, test results are easier to understand if this is unique. + /// these are the logs the runtime generated + /// these are the errors that were expected + /// the dictionary to record any errors + private void CheckLogs(string variation, List capturedLogs, List expectedLogs, Dictionary>> errors) + { + var localErrors = new List>(); + + if (capturedLogs.Count >= expectedLogs.Count) + { + for (int i = 0; i < capturedLogs.Count; i++) + { + if (i + 1 > expectedLogs.Count) + { + localErrors.Add(new Tuple(capturedLogs[i], null)); + } + else + { + if (!TestUtilities.AreEqual(capturedLogs[i], expectedLogs[i])) + { + localErrors.Add(new Tuple(capturedLogs[i], expectedLogs[i])); + } + } + } + } + else + { + for (int i = 0; i < expectedLogs.Count; i++) + { + if (i + 1 > capturedLogs.Count) + { + localErrors.Add(new Tuple(null, expectedLogs[i])); + } + else + { + if (!TestUtilities.AreEqual(expectedLogs[i], capturedLogs[i])) + { + localErrors.Add(new Tuple(capturedLogs[i], expectedLogs[i])); + } + } + } + } + + if (localErrors.Count != 0) + { + if (errors.ContainsKey(variation)) + { + foreach (var error in localErrors) + { + errors[variation].Add(error); + } + } + else + { + errors[variation] = localErrors; + } + } + } + + #region Configure Options + + private static void CodeReceivedHandledOptions(OpenIdConnectAuthenticationOptions options) + { + DefaultOptions(options); + options.Notifications = + new OpenIdConnectAuthenticationNotifications + { + AuthorizationCodeReceived = (notification) => + { + notification.HandleResponse(); + return Task.FromResult(null); + } + }; + } + + private static void CodeReceivedSkippedOptions(OpenIdConnectAuthenticationOptions options) + { + DefaultOptions(options); + options.Notifications = + new OpenIdConnectAuthenticationNotifications + { + AuthorizationCodeReceived = (notification) => + { + notification.SkipToNextMiddleware(); + return Task.FromResult(null); + } + }; + } + + private static void DefaultOptions(OpenIdConnectAuthenticationOptions options) + { + options.AuthenticationScheme = "OpenIdConnectHandlerTest"; + options.ConfigurationManager = ConfigurationManager.DefaultStaticConfigurationManager; + options.StateDataFormat = new AuthenticationPropertiesFormater(); + } + + private static void MessageReceivedHandledOptions(OpenIdConnectAuthenticationOptions options) + { + DefaultOptions(options); + options.Notifications = + new OpenIdConnectAuthenticationNotifications + { + MessageReceived = (notification) => + { + notification.HandleResponse(); + return Task.FromResult(null); + } + }; + } + + private static void MessageReceivedSkippedOptions(OpenIdConnectAuthenticationOptions options) + { + DefaultOptions(options); + options.Notifications = + new OpenIdConnectAuthenticationNotifications + { + MessageReceived = (notification) => + { + notification.SkipToNextMiddleware(); + return Task.FromResult(null); + } + }; + } + + private static void SecurityTokenReceivedHandledOptions(OpenIdConnectAuthenticationOptions options) + { + DefaultOptions(options); + options.Notifications = + new OpenIdConnectAuthenticationNotifications + { + SecurityTokenReceived = (notification) => + { + notification.HandleResponse(); + return Task.FromResult(null); + } + }; + } + + private static void SecurityTokenReceivedSkippedOptions(OpenIdConnectAuthenticationOptions options) + { + DefaultOptions(options); + options.Notifications = + new OpenIdConnectAuthenticationNotifications + { + SecurityTokenReceived = (notification) => + { + notification.SkipToNextMiddleware(); + return Task.FromResult(null); + } + }; + } + + private static void SecurityTokenValidatedHandledOptions(OpenIdConnectAuthenticationOptions options) + { + DefaultOptions(options); + options.Notifications = + new OpenIdConnectAuthenticationNotifications + { + SecurityTokenValidated = (notification) => + { + notification.HandleResponse(); + return Task.FromResult(null); + } + }; + } + + private static void SecurityTokenValidatedSkippedOptions(OpenIdConnectAuthenticationOptions options) + { + DefaultOptions(options); + options.Notifications = + new OpenIdConnectAuthenticationNotifications + { + SecurityTokenValidated = (notification) => + { + notification.SkipToNextMiddleware(); + return Task.FromResult(null); + } + }; + } + + #endregion + + private static TestServer CreateServer(IOptions options, ILoggerFactory loggerFactory) + { + return TestServer.Create( + app => + { + app.UseCustomOpenIdConnectAuthentication(options, loggerFactory); + app.Use(async (context, next) => + { + await next(); + }); + }, + services => + { + services.AddDataProtection(); + } + ); + } + + private static TestServer CreateServer(CustomConfigureOptions configureOptions, ILoggerFactory loggerFactory) + { + return TestServer.Create( + app => + { + app.UseCustomOpenIdConnectAuthentication(configureOptions, loggerFactory); + app.Use(async (context, next) => + { + await next(); + }); + }, + services => + { + services.AddDataProtection(); + } + ); + } + } + + /// + /// Extension specifies as the middleware. + /// + public static class OpenIdConnectAuthenticationExtensions + { + /// + /// Adds the into the ASP.NET runtime. + /// + /// The application builder + /// Options which control the processing of the OpenIdConnect protocol and token validation. + /// custom loggerFactory + /// The application builder + public static IApplicationBuilder UseCustomOpenIdConnectAuthentication(this IApplicationBuilder app, CustomConfigureOptions customConfigureOption, ILoggerFactory loggerFactory) + { + return app.UseMiddleware(customConfigureOption, loggerFactory); + } + + /// + /// Adds the into the ASP.NET runtime. + /// + /// The application builder + /// Options which control the processing of the OpenIdConnect protocol and token validation. + /// custom loggerFactory + /// The application builder + public static IApplicationBuilder UseCustomOpenIdConnectAuthentication(this IApplicationBuilder app, IOptions options, ILoggerFactory loggerFactory) + { + return app.UseMiddleware(options, loggerFactory); + } + } + + public class OpenIdConnectAuthenticationContext : IAuthenticateContext + { + public OpenIdConnectAuthenticationContext(string scheme = null) + { + AuthenticationScheme = scheme ?? OpenIdConnectAuthenticationDefaults.AuthenticationScheme; + } + + public string AuthenticationScheme + { + get; + set; + } + + public void Authenticated(ClaimsPrincipal principal, IDictionary properties, IDictionary description) + { + } + + public void NotAuthenticated() + { + } + } + + /// + /// Provides a Facade over IOptions + /// + public class Options : IOptions + { + OpenIdConnectAuthenticationOptions _options; + + public Options(Action action) + { + _options = new OpenIdConnectAuthenticationOptions(); + action(_options); + } + + OpenIdConnectAuthenticationOptions IOptions.Options + { + get + { + return _options; + } + } + + /// + /// For now returns _options + /// + /// configuration to return + /// + public OpenIdConnectAuthenticationOptions GetNamedOptions(string name) + { + return _options; + } + } + + public class CustomConfigureOptions : ConfigureOptions + { + public CustomConfigureOptions(Action action) + : base(action) + { + } + + public override void Configure(OpenIdConnectAuthenticationOptions options, string name = "") + { + base.Configure(options, name); + return; + } + } + + /// + /// Used to control which methods are handled + /// + public class CustomOpenIdConnectAuthenticationHandler : OpenIdConnectAuthenticationHandler + { + public CustomOpenIdConnectAuthenticationHandler(ILogger logger) + : base(logger) + { + } + + public async Task BaseInitializeAsyncPublic(AuthenticationOptions options, HttpContext context) + { + await base.BaseInitializeAsync(options, context); + } + + public override bool ShouldHandleScheme(string authenticationScheme) + { + return true; + } + + public override void Challenge(IChallengeContext context) + { + } + + protected override void ApplyResponseChallenge() + { + } + + protected override async Task ApplyResponseChallengeAsync() + { + var redirectToIdentityProviderNotification = new RedirectToIdentityProviderNotification(Context, Options) + { + }; + + await Options.Notifications.RedirectToIdentityProvider(redirectToIdentityProviderNotification); + } + } + + /// + /// Used to set as the AuthenticationHandler + /// which can be configured to handle certain messages. + /// + public class CustomOpenIdConnectAuthenticationMiddleware : OpenIdConnectAuthenticationMiddleware + { + public CustomOpenIdConnectAuthenticationMiddleware( + RequestDelegate next, + IDataProtectionProvider dataProtectionProvider, + ILoggerFactory loggerFactory, + IOptions externalOptions, + IOptions options, + ConfigureOptions configureOptions = null + ) + : base(next, dataProtectionProvider, loggerFactory, externalOptions, options, configureOptions) + { + Logger = (loggerFactory as CustomLoggerFactory).Logger; + } + + protected override AuthenticationHandler CreateHandler() + { + return new CustomOpenIdConnectAuthenticationHandler(Logger); + } + + public ILogger Logger + { + get; + set; + } + } + + public class LogEntry + { + public LogEntry() { } + + public int EventId { get; set; } + + public Exception Exception { get; set; } + + public Func Formatter { get; set; } + + public LogLevel Level { get; set; } + + public object State { get; set; } + + public override string ToString() + { + if (Formatter != null) + { + return Formatter(this.State, this.Exception); + } + else + { + string message = (Formatter != null ? Formatter(State, Exception) : (State?.ToString() ?? "null")); + message += ", LogLevel: " + Level.ToString(); + message += ", EventId: " + EventId.ToString(); + message += ", Exception: " + (Exception == null ? "null" : Exception.Message); + return message; + } + } + } + + public class CustomLogger : ILogger, IDisposable + { + LogLevel _logLevel = 0; + + public CustomLogger(LogLevel logLevel = LogLevel.Debug) + { + _logLevel = logLevel; + } + + List logEntries = new List(); + + public IDisposable BeginScopeImpl(object state) + { + return this; + } + + public void Dispose() + { + } + + public bool IsEnabled(LogLevel logLevel) + { + return (logLevel >= _logLevel); + } + + public void Log(LogLevel logLevel, int eventId, object state, Exception exception, Func formatter) + { + if (IsEnabled(logLevel)) + { + logEntries.Add( + new LogEntry + { + EventId = eventId, + Exception = exception, + Formatter = formatter, + Level = logLevel, + State = state, + }); + +#if _Verbose + Console.WriteLine(state?.ToString() ?? "state null"); +#endif + } + } + + public List Logs { get { return logEntries; } } + } + + public class CustomLoggerFactory : ILoggerFactory + { + CustomLogger _logger; + LogLevel _logLevel = LogLevel.Debug; + + public CustomLoggerFactory(LogLevel logLevel) + { + _logLevel = logLevel; + _logger = new CustomLogger(_logLevel); + } + + public LogLevel MinimumLevel + { + get { return _logLevel; } + set {_logLevel = value; } + } + + public void AddProvider(ILoggerProvider provider) + { + } + + public ILogger CreateLogger(string categoryName) + { + return _logger; + } + + public CustomLogger Logger { get { return _logger; } } + } + + /// + /// Processing a requires 'unprotecting' the state. + /// This class side-steps that process. + /// + public class AuthenticationPropertiesFormater : ISecureDataFormat + { + public string Protect(AuthenticationProperties data) + { + return "protectedData"; + } + + AuthenticationProperties ISecureDataFormat.Unprotect(string protectedText) + { + return new AuthenticationProperties(); + } + } + + /// + /// Used to set up different configurations of metadata for different tests + /// + public class ConfigurationManager + { + /// + /// Simple static empty manager. + /// + static public IConfigurationManager DefaultStaticConfigurationManager + { + get { return new StaticConfigurationManager(new OpenIdConnectConfiguration()); } + } + } +} diff --git a/test/Microsoft.AspNet.Authentication.Test/OpenIdConnect/TestUtilities.cs b/test/Microsoft.AspNet.Authentication.Test/OpenIdConnect/TestUtilities.cs new file mode 100644 index 000000000..abb5b8538 --- /dev/null +++ b/test/Microsoft.AspNet.Authentication.Test/OpenIdConnect/TestUtilities.cs @@ -0,0 +1,109 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using Microsoft.IdentityModel.Protocols; +using System; + +namespace Microsoft.AspNet.Authentication.Tests.OpenIdConnect +{ + /// + /// These utilities are designed to test openidconnect related flows + /// + public class TestUtilities + { + public static bool AreEqual(object obj1, object obj2, Func comparer = null) where T : class + { + if (obj1 == null && obj2 == null) + { + return true; + } + + if (obj1 == null || obj2 == null) + { + return false; + } + + if (obj1.GetType() != obj2.GetType()) + { + return false; + } + + if (obj1.GetType() != typeof(T)) + { + return false; + } + + if (comparer != null) + { + return comparer(obj1, obj2); + } + + if (typeof(T) == typeof(LogEntry)) + { + return AreEqual(obj1 as LogEntry, obj2 as LogEntry); + } + else if (typeof(T) == typeof(Exception)) + { + return AreEqual(obj1 as Exception, obj2 as Exception); + } + + throw new ArithmeticException("Unknown type, no comparer. Type: " + typeof(T).ToString()); + + } + + /// + /// Never call this method directly, call AreObjectsEqual, as it deals with nulls and types"/> + /// + /// + /// + /// + private static bool AreEqual(LogEntry logEntry1, LogEntry logEntry2) + { + if (logEntry1.EventId != logEntry2.EventId) + { + return false; + } + + if (!AreEqual(logEntry1.Exception, logEntry2.Exception)) + { + return false; + } + + if (logEntry1.State == null && logEntry2.State == null) + { + return true; + } + + if (logEntry1.State == null) + { + return false; + } + + if (logEntry2.State == null) + { + return false; + } + + string logValue1 = logEntry1.Formatter == null ? logEntry1.State.ToString() : logEntry1.Formatter(logEntry1.State, logEntry1.Exception); + string logValue2 = logEntry2.Formatter == null ? logEntry2.State.ToString() : logEntry2.Formatter(logEntry2.State, logEntry2.Exception); + + return (logValue1.StartsWith(logValue2) || (logValue2.StartsWith(logValue1))); + } + + /// + /// Never call this method directly, call AreObjectsEqual, as it deals with nulls and types"/> + /// + /// + /// + /// + private static bool AreEqual(Exception exception1, Exception exception2) + { + if (!string.Equals(exception1.Message, exception2.Message)) + { + return false; + } + + return AreEqual(exception1.InnerException, exception2.InnerException); + } + } +} From a3b2d2c3ebdfa3dff3baed88d4600b4e61fd6879 Mon Sep 17 00:00:00 2001 From: Chris Ross Date: Thu, 16 Apr 2015 15:58:45 -0700 Subject: [PATCH 189/216] Handle Http.Core rename. --- .../FacebookAuthenticationHandler.cs | 2 +- .../TwitterAuthenticationHandler.cs | 2 +- .../AuthenticationServiceCollectionExtensions.cs | 1 - .../ClaimsTransformationAuthenticationHandler.cs | 1 - src/Microsoft.AspNet.Authentication/HttpContextExtensions.cs | 1 - src/Microsoft.AspNet.Authentication/project.json | 2 +- .../AuthenticationHandlerFacts.cs | 2 +- .../Cookies/Infrastructure/CookieChunkingTests.cs | 1 - .../Microsoft.AspNet.Authentication.Test/SecurityHelperTests.cs | 1 - 9 files changed, 4 insertions(+), 9 deletions(-) diff --git a/src/Microsoft.AspNet.Authentication.Facebook/FacebookAuthenticationHandler.cs b/src/Microsoft.AspNet.Authentication.Facebook/FacebookAuthenticationHandler.cs index 5f2d5b886..d16c796ed 100644 --- a/src/Microsoft.AspNet.Authentication.Facebook/FacebookAuthenticationHandler.cs +++ b/src/Microsoft.AspNet.Authentication.Facebook/FacebookAuthenticationHandler.cs @@ -9,7 +9,7 @@ using System.Text; using System.Threading.Tasks; using Microsoft.AspNet.Http; -using Microsoft.AspNet.Http.Core.Collections; +using Microsoft.AspNet.Http.Collections; using Microsoft.AspNet.Http.Extensions; using Microsoft.AspNet.Http.Authentication; using Microsoft.AspNet.Authentication.OAuth; diff --git a/src/Microsoft.AspNet.Authentication.Twitter/TwitterAuthenticationHandler.cs b/src/Microsoft.AspNet.Authentication.Twitter/TwitterAuthenticationHandler.cs index 6f2aade30..dc0d7fc8d 100644 --- a/src/Microsoft.AspNet.Authentication.Twitter/TwitterAuthenticationHandler.cs +++ b/src/Microsoft.AspNet.Authentication.Twitter/TwitterAuthenticationHandler.cs @@ -10,7 +10,7 @@ using System.Text; using System.Threading.Tasks; using Microsoft.AspNet.Http; -using Microsoft.AspNet.Http.Core.Collections; +using Microsoft.AspNet.Http.Collections; using Microsoft.AspNet.Http.Authentication; using Microsoft.AspNet.Authentication; using Microsoft.AspNet.Authentication.Twitter.Messages; diff --git a/src/Microsoft.AspNet.Authentication/AuthenticationServiceCollectionExtensions.cs b/src/Microsoft.AspNet.Authentication/AuthenticationServiceCollectionExtensions.cs index 55b82acab..43c0a7426 100644 --- a/src/Microsoft.AspNet.Authentication/AuthenticationServiceCollectionExtensions.cs +++ b/src/Microsoft.AspNet.Authentication/AuthenticationServiceCollectionExtensions.cs @@ -5,7 +5,6 @@ using System.Security.Claims; using System.Threading.Tasks; using Microsoft.AspNet.Authentication; -using Microsoft.AspNet.Http.Core.Authentication; using Microsoft.Framework.Internal; namespace Microsoft.Framework.DependencyInjection diff --git a/src/Microsoft.AspNet.Authentication/ClaimsTransformationAuthenticationHandler.cs b/src/Microsoft.AspNet.Authentication/ClaimsTransformationAuthenticationHandler.cs index bee68e7d7..ae1599ee0 100644 --- a/src/Microsoft.AspNet.Authentication/ClaimsTransformationAuthenticationHandler.cs +++ b/src/Microsoft.AspNet.Authentication/ClaimsTransformationAuthenticationHandler.cs @@ -5,7 +5,6 @@ using System.Security.Claims; using System.Threading.Tasks; using Microsoft.AspNet.Http.Authentication; -using Microsoft.AspNet.Http.Core.Authentication; namespace Microsoft.AspNet.Authentication { diff --git a/src/Microsoft.AspNet.Authentication/HttpContextExtensions.cs b/src/Microsoft.AspNet.Authentication/HttpContextExtensions.cs index e378934cb..65f7bcc10 100644 --- a/src/Microsoft.AspNet.Authentication/HttpContextExtensions.cs +++ b/src/Microsoft.AspNet.Authentication/HttpContextExtensions.cs @@ -2,7 +2,6 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using Microsoft.AspNet.Http; -using Microsoft.AspNet.Http.Core.Authentication; using Microsoft.AspNet.Http.Authentication; namespace Microsoft.AspNet.Authentication diff --git a/src/Microsoft.AspNet.Authentication/project.json b/src/Microsoft.AspNet.Authentication/project.json index 83840f36c..8367af5f0 100644 --- a/src/Microsoft.AspNet.Authentication/project.json +++ b/src/Microsoft.AspNet.Authentication/project.json @@ -3,8 +3,8 @@ "description": "ASP.NET 5 common types used by the various authentication middleware.", "dependencies": { "Microsoft.AspNet.DataProtection": "1.0.0-*", + "Microsoft.AspNet.Http": "1.0.0-*", "Microsoft.AspNet.Http.Interfaces": "1.0.0-*", - "Microsoft.AspNet.Http.Core": "1.0.0-*", "Microsoft.AspNet.Http.Extensions": "1.0.0-*", "Microsoft.Framework.Logging.Interfaces": "1.0.0-*", "Microsoft.Framework.NotNullAttribute.Internal": { "type": "build", "version": "1.0.0-*" } diff --git a/test/Microsoft.AspNet.Authentication.Test/AuthenticationHandlerFacts.cs b/test/Microsoft.AspNet.Authentication.Test/AuthenticationHandlerFacts.cs index a8ec25fe0..ba23fea2b 100644 --- a/test/Microsoft.AspNet.Authentication.Test/AuthenticationHandlerFacts.cs +++ b/test/Microsoft.AspNet.Authentication.Test/AuthenticationHandlerFacts.cs @@ -2,7 +2,7 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; -using Microsoft.AspNet.Http.Core; +using Microsoft.AspNet.Http; using Xunit; namespace Microsoft.AspNet.Authentication diff --git a/test/Microsoft.AspNet.Authentication.Test/Cookies/Infrastructure/CookieChunkingTests.cs b/test/Microsoft.AspNet.Authentication.Test/Cookies/Infrastructure/CookieChunkingTests.cs index c4014ad77..20ee0a735 100644 --- a/test/Microsoft.AspNet.Authentication.Test/Cookies/Infrastructure/CookieChunkingTests.cs +++ b/test/Microsoft.AspNet.Authentication.Test/Cookies/Infrastructure/CookieChunkingTests.cs @@ -4,7 +4,6 @@ using System; using System.Collections.Generic; using Microsoft.AspNet.Http; -using Microsoft.AspNet.Http.Core; using Xunit; namespace Microsoft.AspNet.Authentication.Cookies.Infrastructure diff --git a/test/Microsoft.AspNet.Authentication.Test/SecurityHelperTests.cs b/test/Microsoft.AspNet.Authentication.Test/SecurityHelperTests.cs index 3d75bd0a1..1b47c81f8 100644 --- a/test/Microsoft.AspNet.Authentication.Test/SecurityHelperTests.cs +++ b/test/Microsoft.AspNet.Authentication.Test/SecurityHelperTests.cs @@ -6,7 +6,6 @@ using System.Security.Claims; using System.Security.Principal; using Microsoft.AspNet.Http; -using Microsoft.AspNet.Http.Core; using Microsoft.AspNet.Authentication; using Shouldly; using Xunit; From 99f3aa197f899102f5aef50368831748370643b1 Mon Sep 17 00:00:00 2001 From: Chris Ross Date: Mon, 13 Apr 2015 15:56:14 -0700 Subject: [PATCH 190/216] #118 - Use common cookie header formatters. --- samples/CookieSample/Startup.cs | 1 + samples/CookieSessionSample/Startup.cs | 1 + samples/OpenIdConnectSample/Startup.cs | 1 + samples/SocialSample/Startup.cs | 1 + .../CookieAuthenticationMiddleware.cs | 4 +- .../CookieServiceCollectionExtensions.cs | 2 + .../Infrastructure/ChunkingCookieManager.cs | 65 +++++++++---------- .../project.json | 1 + .../Cookies/CookieMiddlewareTests.cs | 1 + .../Infrastructure/CookieChunkingTests.cs | 32 ++++----- .../Facebook/FacebookMiddlewareTests.cs | 2 + .../Google/GoogleMiddlewareTests.cs | 1 + .../MicrosoftAccountMiddlewareTests.cs | 1 + .../OpenIdConnectHandlerTests.cs | 2 + .../OpenIdConnectMiddlewareTests.cs | 1 + .../Twitter/TwitterMiddlewareTests.cs | 1 + 16 files changed, 64 insertions(+), 53 deletions(-) diff --git a/samples/CookieSample/Startup.cs b/samples/CookieSample/Startup.cs index d7c3e3128..df88589fb 100644 --- a/samples/CookieSample/Startup.cs +++ b/samples/CookieSample/Startup.cs @@ -10,6 +10,7 @@ public class Startup { public void ConfigureServices(IServiceCollection services) { + services.AddWebEncoders(); services.AddDataProtection(); } diff --git a/samples/CookieSessionSample/Startup.cs b/samples/CookieSessionSample/Startup.cs index f93777758..decbd181a 100644 --- a/samples/CookieSessionSample/Startup.cs +++ b/samples/CookieSessionSample/Startup.cs @@ -11,6 +11,7 @@ public class Startup { public void ConfigureServices(IServiceCollection services) { + services.AddWebEncoders(); services.AddDataProtection(); } diff --git a/samples/OpenIdConnectSample/Startup.cs b/samples/OpenIdConnectSample/Startup.cs index cb748b5d6..c93eae671 100644 --- a/samples/OpenIdConnectSample/Startup.cs +++ b/samples/OpenIdConnectSample/Startup.cs @@ -12,6 +12,7 @@ public class Startup { public void ConfigureServices(IServiceCollection services) { + services.AddWebEncoders(); services.AddDataProtection(); services.Configure(options => { diff --git a/samples/SocialSample/Startup.cs b/samples/SocialSample/Startup.cs index ffc723126..45c775cd1 100644 --- a/samples/SocialSample/Startup.cs +++ b/samples/SocialSample/Startup.cs @@ -18,6 +18,7 @@ public class Startup { public void ConfigureServices(IServiceCollection services) { + services.AddWebEncoders(); services.AddDataProtection(); services.Configure(options => { diff --git a/src/Microsoft.AspNet.Authentication.Cookies/CookieAuthenticationMiddleware.cs b/src/Microsoft.AspNet.Authentication.Cookies/CookieAuthenticationMiddleware.cs index 0b4afe125..0d95f08e7 100644 --- a/src/Microsoft.AspNet.Authentication.Cookies/CookieAuthenticationMiddleware.cs +++ b/src/Microsoft.AspNet.Authentication.Cookies/CookieAuthenticationMiddleware.cs @@ -9,6 +9,7 @@ using Microsoft.Framework.Internal; using Microsoft.Framework.Logging; using Microsoft.Framework.OptionsModel; +using Microsoft.Framework.WebEncoders; namespace Microsoft.AspNet.Authentication.Cookies { @@ -20,6 +21,7 @@ public CookieAuthenticationMiddleware( [NotNull] RequestDelegate next, [NotNull] IDataProtectionProvider dataProtectionProvider, [NotNull] ILoggerFactory loggerFactory, + [NotNull] IUrlEncoder urlEncoder, [NotNull] IOptions options, ConfigureOptions configureOptions) : base(next, options, configureOptions) @@ -40,7 +42,7 @@ public CookieAuthenticationMiddleware( } if (Options.CookieManager == null) { - Options.CookieManager = new ChunkingCookieManager(); + Options.CookieManager = new ChunkingCookieManager(urlEncoder); } _logger = loggerFactory.CreateLogger(typeof(CookieAuthenticationMiddleware).FullName); diff --git a/src/Microsoft.AspNet.Authentication.Cookies/CookieServiceCollectionExtensions.cs b/src/Microsoft.AspNet.Authentication.Cookies/CookieServiceCollectionExtensions.cs index af6d4d377..c0e188eca 100644 --- a/src/Microsoft.AspNet.Authentication.Cookies/CookieServiceCollectionExtensions.cs +++ b/src/Microsoft.AspNet.Authentication.Cookies/CookieServiceCollectionExtensions.cs @@ -20,6 +20,7 @@ public static IServiceCollection ConfigureCookieAuthentication([NotNull] this IS public static IServiceCollection ConfigureCookieAuthentication([NotNull] this IServiceCollection services, [NotNull] Action configure, string optionsName) { + services.AddWebEncoders(); return services.Configure(configure, optionsName); } @@ -30,6 +31,7 @@ public static IServiceCollection ConfigureCookieAuthentication([NotNull] this IS public static IServiceCollection ConfigureCookieAuthentication([NotNull] this IServiceCollection services, [NotNull] IConfiguration config, string optionsName) { + services.AddWebEncoders(); return services.Configure(config, optionsName); } } diff --git a/src/Microsoft.AspNet.Authentication.Cookies/Infrastructure/ChunkingCookieManager.cs b/src/Microsoft.AspNet.Authentication.Cookies/Infrastructure/ChunkingCookieManager.cs index 40008e47b..30af0b43d 100644 --- a/src/Microsoft.AspNet.Authentication.Cookies/Infrastructure/ChunkingCookieManager.cs +++ b/src/Microsoft.AspNet.Authentication.Cookies/Infrastructure/ChunkingCookieManager.cs @@ -7,6 +7,8 @@ using System.Linq; using Microsoft.AspNet.Http; using Microsoft.Framework.Internal; +using Microsoft.Framework.WebEncoders; +using Microsoft.Net.Http.Headers; namespace Microsoft.AspNet.Authentication.Cookies.Infrastructure { @@ -16,12 +18,13 @@ namespace Microsoft.AspNet.Authentication.Cookies.Infrastructure /// public class ChunkingCookieManager : ICookieManager { - public ChunkingCookieManager() + public ChunkingCookieManager(IUrlEncoder urlEncoder) { // Lowest common denominator. Safari has the lowest known limit (4093), and we leave little extra just in case. // See http://browsercookielimits.x64.me/. ChunkSize = 4090; ThrowForPartialCookies = true; + Encoder = urlEncoder ?? UrlEncoder.Default; } /// @@ -38,6 +41,8 @@ public ChunkingCookieManager() /// public bool ThrowForPartialCookies { get; set; } + private IUrlEncoder Encoder { get; set; } + // Parse the "chunks:XX" to determine how many chunks there should be. private static int ParseChunksCount(string value) { @@ -119,22 +124,18 @@ public string GetRequestCookie([NotNull] HttpContext context, [NotNull] string k /// public void AppendResponseCookie([NotNull] HttpContext context, [NotNull] string key, string value, [NotNull] CookieOptions options) { - var domainHasValue = !string.IsNullOrEmpty(options.Domain); - var pathHasValue = !string.IsNullOrEmpty(options.Path); - var expiresHasValue = options.Expires.HasValue; + var escapedKey = Encoder.UrlEncode(key); - var escapedKey = Uri.EscapeDataString(key); - var prefix = escapedKey + "="; + var template = new SetCookieHeaderValue(escapedKey) + { + Domain = options.Domain, + Expires = options.Expires, + HttpOnly = options.HttpOnly, + Path = options.Path, + Secure = options.Secure, + }; - var suffix = string.Concat( - !domainHasValue ? null : "; domain=", - !domainHasValue ? null : options.Domain, - !pathHasValue ? null : "; path=", - !pathHasValue ? null : options.Path, - !expiresHasValue ? null : "; expires=", - !expiresHasValue ? null : options.Expires.Value.ToString("ddd, dd-MMM-yyyy HH:mm:ss ", CultureInfo.InvariantCulture) + "GMT", - !options.Secure ? null : "; secure", - !options.HttpOnly ? null : "; HttpOnly"); + var templateLength = template.ToString().Length; value = value ?? string.Empty; var quoted = false; @@ -143,19 +144,16 @@ public void AppendResponseCookie([NotNull] HttpContext context, [NotNull] string quoted = true; value = RemoveQuotes(value); } - var escapedValue = Uri.EscapeDataString(value); + var escapedValue = Encoder.UrlEncode(value); // Normal cookie var responseHeaders = context.Response.Headers; - if (!ChunkSize.HasValue || ChunkSize.Value > prefix.Length + escapedValue.Length + suffix.Length + (quoted ? 2 : 0)) + if (!ChunkSize.HasValue || ChunkSize.Value > templateLength + escapedValue.Length + (quoted ? 2 : 0)) { - var setCookieValue = string.Concat( - prefix, - quoted ? Quote(escapedValue) : escapedValue, - suffix); - responseHeaders.AppendValues(Constants.Headers.SetCookie, setCookieValue); + template.Value = quoted ? Quote(escapedValue) : escapedValue; + responseHeaders.AppendValues(Constants.Headers.SetCookie, template.ToString()); } - else if (ChunkSize.Value < prefix.Length + suffix.Length + (quoted ? 2 : 0) + 10) + else if (ChunkSize.Value < templateLength + (quoted ? 2 : 0) + 10) { // 10 is the minimum data we want to put in an individual cookie, including the cookie chunk identifier "CXX". // No room for data, we can't chunk the options and name @@ -169,10 +167,11 @@ public void AppendResponseCookie([NotNull] HttpContext context, [NotNull] string // Set-Cookie: CookieNameC1="Segment1"; path=/ // Set-Cookie: CookieNameC2="Segment2"; path=/ // Set-Cookie: CookieNameC3="Segment3"; path=/ - var dataSizePerCookie = ChunkSize.Value - prefix.Length - suffix.Length - (quoted ? 2 : 0) - 3; // Budget 3 chars for the chunkid. + var dataSizePerCookie = ChunkSize.Value - templateLength - (quoted ? 2 : 0) - 3; // Budget 3 chars for the chunkid. var cookieChunkCount = (int)Math.Ceiling(escapedValue.Length * 1.0 / dataSizePerCookie); - responseHeaders.AppendValues(Constants.Headers.SetCookie, prefix + "chunks:" + cookieChunkCount.ToString(CultureInfo.InvariantCulture) + suffix); + template.Value = "chunks:" + cookieChunkCount.ToString(CultureInfo.InvariantCulture); + responseHeaders.AppendValues(Constants.Headers.SetCookie, template.ToString()); var chunks = new string[cookieChunkCount]; var offset = 0; @@ -183,15 +182,9 @@ public void AppendResponseCookie([NotNull] HttpContext context, [NotNull] string var segment = escapedValue.Substring(offset, length); offset += length; - chunks[chunkId - 1] = string.Concat( - escapedKey, - "C", - chunkId.ToString(CultureInfo.InvariantCulture), - "=", - quoted ? "\"" : string.Empty, - segment, - quoted ? "\"" : string.Empty, - suffix); + template.Name = escapedKey + "C" + chunkId.ToString(CultureInfo.InvariantCulture); + template.Value = quoted ? Quote(segment) : segment; + chunks[chunkId - 1] = template.ToString(); } responseHeaders.AppendValues(Constants.Headers.SetCookie, chunks); } @@ -206,7 +199,7 @@ public void AppendResponseCookie([NotNull] HttpContext context, [NotNull] string /// public void DeleteCookie([NotNull] HttpContext context, [NotNull] string key, [NotNull] CookieOptions options) { - var escapedKey = Uri.EscapeDataString(key); + var escapedKey = Encoder.UrlEncode(key); var keys = new List(); keys.Add(escapedKey + "="); @@ -260,7 +253,7 @@ public void DeleteCookie([NotNull] HttpContext context, [NotNull] string key, [N for (int i = 1; i <= chunks; i++) { AppendResponseCookie( - context, + context, key + "C" + i.ToString(CultureInfo.InvariantCulture), string.Empty, new CookieOptions() diff --git a/src/Microsoft.AspNet.Authentication.Cookies/project.json b/src/Microsoft.AspNet.Authentication.Cookies/project.json index c2377a44f..7b42df350 100644 --- a/src/Microsoft.AspNet.Authentication.Cookies/project.json +++ b/src/Microsoft.AspNet.Authentication.Cookies/project.json @@ -4,6 +4,7 @@ "dependencies": { "Microsoft.AspNet.Authentication": "1.0.0-*", "Microsoft.Framework.NotNullAttribute.Internal": { "type": "build", "version": "1.0.0-*" }, + "Microsoft.Framework.WebEncoders": "1.0.0-*", "Newtonsoft.Json": "6.0.6" }, "frameworks": { diff --git a/test/Microsoft.AspNet.Authentication.Test/Cookies/CookieMiddlewareTests.cs b/test/Microsoft.AspNet.Authentication.Test/Cookies/CookieMiddlewareTests.cs index 0a0e5a8da..cd2483119 100644 --- a/test/Microsoft.AspNet.Authentication.Test/Cookies/CookieMiddlewareTests.cs +++ b/test/Microsoft.AspNet.Authentication.Test/Cookies/CookieMiddlewareTests.cs @@ -573,6 +573,7 @@ private static TestServer CreateServer(Action confi }, services => { + services.AddWebEncoders(); services.AddDataProtection(); if (claimsTransform != null) { diff --git a/test/Microsoft.AspNet.Authentication.Test/Cookies/Infrastructure/CookieChunkingTests.cs b/test/Microsoft.AspNet.Authentication.Test/Cookies/Infrastructure/CookieChunkingTests.cs index 20ee0a735..a8e437cd7 100644 --- a/test/Microsoft.AspNet.Authentication.Test/Cookies/Infrastructure/CookieChunkingTests.cs +++ b/test/Microsoft.AspNet.Authentication.Test/Cookies/Infrastructure/CookieChunkingTests.cs @@ -16,7 +16,7 @@ public void AppendLargeCookie_Appended() HttpContext context = new DefaultHttpContext(); string testString = "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; - new ChunkingCookieManager() { ChunkSize = null }.AppendResponseCookie(context, "TestCookie", testString, new CookieOptions()); + new ChunkingCookieManager(null) { ChunkSize = null }.AppendResponseCookie(context, "TestCookie", testString, new CookieOptions()); IList values = context.Response.Headers.GetValues("Set-Cookie"); Assert.Equal(1, values.Count); Assert.Equal("TestCookie=" + testString + "; path=/", values[0]); @@ -28,7 +28,7 @@ public void AppendLargeCookieWithLimit_Chunked() HttpContext context = new DefaultHttpContext(); string testString = "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; - new ChunkingCookieManager() { ChunkSize = 30 }.AppendResponseCookie(context, "TestCookie", testString, new CookieOptions()); + new ChunkingCookieManager(null) { ChunkSize = 30 }.AppendResponseCookie(context, "TestCookie", testString, new CookieOptions()); IList values = context.Response.Headers.GetValues("Set-Cookie"); Assert.Equal(9, values.Count); Assert.Equal(new[] @@ -51,7 +51,7 @@ public void AppendLargeQuotedCookieWithLimit_QuotedChunked() HttpContext context = new DefaultHttpContext(); string testString = "\"abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ\""; - new ChunkingCookieManager() { ChunkSize = 32 }.AppendResponseCookie(context, "TestCookie", testString, new CookieOptions()); + new ChunkingCookieManager(null) { ChunkSize = 32 }.AppendResponseCookie(context, "TestCookie", testString, new CookieOptions()); IList values = context.Response.Headers.GetValues("Set-Cookie"); Assert.Equal(9, values.Count); Assert.Equal(new[] @@ -82,7 +82,7 @@ public void GetLargeChunkedCookie_Reassembled() "TestCookieC6=JKLMNOPQR", "TestCookieC7=STUVWXYZ"); - string result = new ChunkingCookieManager().GetRequestCookie(context, "TestCookie"); + string result = new ChunkingCookieManager(null).GetRequestCookie(context, "TestCookie"); string testString = "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; Assert.Equal(testString, result); } @@ -101,7 +101,7 @@ public void GetLargeChunkedCookieWithQuotes_Reassembled() "TestCookieC6=\"JKLMNOPQR\"", "TestCookieC7=\"STUVWXYZ\""); - string result = new ChunkingCookieManager().GetRequestCookie(context, "TestCookie"); + string result = new ChunkingCookieManager(null).GetRequestCookie(context, "TestCookie"); string testString = "\"abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ\""; Assert.Equal(testString, result); } @@ -120,7 +120,7 @@ public void GetLargeChunkedCookieWithMissingChunk_ThrowingEnabled_Throws() "TestCookieC6=JKLMNOPQR", "TestCookieC7=STUVWXYZ"); - Assert.Throws(() => new ChunkingCookieManager().GetRequestCookie(context, "TestCookie")); + Assert.Throws(() => new ChunkingCookieManager(null).GetRequestCookie(context, "TestCookie")); } [Fact] @@ -137,7 +137,7 @@ public void GetLargeChunkedCookieWithMissingChunk_ThrowingDisabled_NotReassemble "TestCookieC6=JKLMNOPQR", "TestCookieC7=STUVWXYZ"); - string result = new ChunkingCookieManager() { ThrowForPartialCookies = false }.GetRequestCookie(context, "TestCookie"); + string result = new ChunkingCookieManager(null) { ThrowForPartialCookies = false }.GetRequestCookie(context, "TestCookie"); string testString = "chunks:7"; Assert.Equal(testString, result); } @@ -148,19 +148,19 @@ public void DeleteChunkedCookieWithOptions_AllDeleted() HttpContext context = new DefaultHttpContext(); context.Request.Headers.AppendValues("Cookie", "TestCookie=chunks:7"); - new ChunkingCookieManager().DeleteCookie(context, "TestCookie", new CookieOptions() { Domain = "foo.com" }); + new ChunkingCookieManager(null).DeleteCookie(context, "TestCookie", new CookieOptions() { Domain = "foo.com" }); var cookies = context.Response.Headers.GetValues("Set-Cookie"); Assert.Equal(8, cookies.Count); Assert.Equal(new[] { - "TestCookie=; domain=foo.com; path=/; expires=Thu, 01-Jan-1970 00:00:00 GMT", - "TestCookieC1=; domain=foo.com; path=/; expires=Thu, 01-Jan-1970 00:00:00 GMT", - "TestCookieC2=; domain=foo.com; path=/; expires=Thu, 01-Jan-1970 00:00:00 GMT", - "TestCookieC3=; domain=foo.com; path=/; expires=Thu, 01-Jan-1970 00:00:00 GMT", - "TestCookieC4=; domain=foo.com; path=/; expires=Thu, 01-Jan-1970 00:00:00 GMT", - "TestCookieC5=; domain=foo.com; path=/; expires=Thu, 01-Jan-1970 00:00:00 GMT", - "TestCookieC6=; domain=foo.com; path=/; expires=Thu, 01-Jan-1970 00:00:00 GMT", - "TestCookieC7=; domain=foo.com; path=/; expires=Thu, 01-Jan-1970 00:00:00 GMT", + "TestCookie=; expires=Thu, 01 Jan 1970 00:00:00 GMT; domain=foo.com; path=/", + "TestCookieC1=; expires=Thu, 01 Jan 1970 00:00:00 GMT; domain=foo.com; path=/", + "TestCookieC2=; expires=Thu, 01 Jan 1970 00:00:00 GMT; domain=foo.com; path=/", + "TestCookieC3=; expires=Thu, 01 Jan 1970 00:00:00 GMT; domain=foo.com; path=/", + "TestCookieC4=; expires=Thu, 01 Jan 1970 00:00:00 GMT; domain=foo.com; path=/", + "TestCookieC5=; expires=Thu, 01 Jan 1970 00:00:00 GMT; domain=foo.com; path=/", + "TestCookieC6=; expires=Thu, 01 Jan 1970 00:00:00 GMT; domain=foo.com; path=/", + "TestCookieC7=; expires=Thu, 01 Jan 1970 00:00:00 GMT; domain=foo.com; path=/", }, cookies); } } diff --git a/test/Microsoft.AspNet.Authentication.Test/Facebook/FacebookMiddlewareTests.cs b/test/Microsoft.AspNet.Authentication.Test/Facebook/FacebookMiddlewareTests.cs index fd349582f..ad3f6b74f 100644 --- a/test/Microsoft.AspNet.Authentication.Test/Facebook/FacebookMiddlewareTests.cs +++ b/test/Microsoft.AspNet.Authentication.Test/Facebook/FacebookMiddlewareTests.cs @@ -29,6 +29,7 @@ public async Task ChallengeWillTriggerApplyRedirectEvent() }, services => { + services.AddWebEncoders(); services.AddDataProtection(); services.ConfigureFacebookAuthentication(options => { @@ -74,6 +75,7 @@ public async Task ChallengeWillTriggerRedirection() }, services => { + services.AddWebEncoders(); services.AddDataProtection(); services.ConfigureFacebookAuthentication(options => { diff --git a/test/Microsoft.AspNet.Authentication.Test/Google/GoogleMiddlewareTests.cs b/test/Microsoft.AspNet.Authentication.Test/Google/GoogleMiddlewareTests.cs index 33612b7ef..a37dfe6d2 100644 --- a/test/Microsoft.AspNet.Authentication.Test/Google/GoogleMiddlewareTests.cs +++ b/test/Microsoft.AspNet.Authentication.Test/Google/GoogleMiddlewareTests.cs @@ -530,6 +530,7 @@ private static TestServer CreateServer(Action confi }, services => { + services.AddWebEncoders(); services.AddDataProtection(); services.Configure(options => { diff --git a/test/Microsoft.AspNet.Authentication.Test/MicrosoftAccount/MicrosoftAccountMiddlewareTests.cs b/test/Microsoft.AspNet.Authentication.Test/MicrosoftAccount/MicrosoftAccountMiddlewareTests.cs index 0f22e3ac7..7ea848207 100644 --- a/test/Microsoft.AspNet.Authentication.Test/MicrosoftAccount/MicrosoftAccountMiddlewareTests.cs +++ b/test/Microsoft.AspNet.Authentication.Test/MicrosoftAccount/MicrosoftAccountMiddlewareTests.cs @@ -177,6 +177,7 @@ private static TestServer CreateServer(Action { + services.AddWebEncoders(); services.AddDataProtection(); services.Configure(options => { diff --git a/test/Microsoft.AspNet.Authentication.Test/OpenIdConnect/OpenIdConnectHandlerTests.cs b/test/Microsoft.AspNet.Authentication.Test/OpenIdConnect/OpenIdConnectHandlerTests.cs index 5817615f2..c31cdc657 100644 --- a/test/Microsoft.AspNet.Authentication.Test/OpenIdConnect/OpenIdConnectHandlerTests.cs +++ b/test/Microsoft.AspNet.Authentication.Test/OpenIdConnect/OpenIdConnectHandlerTests.cs @@ -436,6 +436,7 @@ private static TestServer CreateServer(IOptions { + services.AddWebEncoders(); services.AddDataProtection(); } ); @@ -454,6 +455,7 @@ private static TestServer CreateServer(CustomConfigureOptions configureOptions, }, services => { + services.AddWebEncoders(); services.AddDataProtection(); } ); diff --git a/test/Microsoft.AspNet.Authentication.Test/OpenIdConnect/OpenIdConnectMiddlewareTests.cs b/test/Microsoft.AspNet.Authentication.Test/OpenIdConnect/OpenIdConnectMiddlewareTests.cs index bec9f1bf3..6abc8aa94 100644 --- a/test/Microsoft.AspNet.Authentication.Test/OpenIdConnect/OpenIdConnectMiddlewareTests.cs +++ b/test/Microsoft.AspNet.Authentication.Test/OpenIdConnect/OpenIdConnectMiddlewareTests.cs @@ -234,6 +234,7 @@ private static TestServer CreateServer(Action { + services.AddWebEncoders(); services.AddDataProtection(); services.Configure(options => { diff --git a/test/Microsoft.AspNet.Authentication.Test/Twitter/TwitterMiddlewareTests.cs b/test/Microsoft.AspNet.Authentication.Test/Twitter/TwitterMiddlewareTests.cs index 75220f921..d4f6fd24a 100644 --- a/test/Microsoft.AspNet.Authentication.Test/Twitter/TwitterMiddlewareTests.cs +++ b/test/Microsoft.AspNet.Authentication.Test/Twitter/TwitterMiddlewareTests.cs @@ -123,6 +123,7 @@ private static TestServer CreateServer(Action configure, Fu }, services => { + services.AddWebEncoders(); services.AddDataProtection(); services.Configure(options => { From 7bc6cab72e3bc3ec3cffe026257fa3d8d4b5f6ba Mon Sep 17 00:00:00 2001 From: Hao Kung Date: Mon, 20 Apr 2015 15:26:22 -0700 Subject: [PATCH 191/216] Fix samples --- samples/CookieSample/Startup.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/samples/CookieSample/Startup.cs b/samples/CookieSample/Startup.cs index df88589fb..e700f4b90 100644 --- a/samples/CookieSample/Startup.cs +++ b/samples/CookieSample/Startup.cs @@ -18,13 +18,14 @@ public void Configure(IApplicationBuilder app) { app.UseCookieAuthentication(options => { + options.AutomaticAuthentication = true; }); app.Run(async context => { - if (context.User == null || !context.User.Identity.IsAuthenticated) + if (string.IsNullOrEmpty(context.User.Identity.Name)) { - context.Response.SignIn(CookieAuthenticationDefaults.AuthenticationScheme, new ClaimsPrincipal(new ClaimsIdentity(new[] { new Claim("name", "bob") }))); + context.Response.SignIn(CookieAuthenticationDefaults.AuthenticationScheme, new ClaimsPrincipal(new ClaimsIdentity(new[] { new Claim(ClaimTypes.Name, "bob") }))); context.Response.ContentType = "text/plain"; await context.Response.WriteAsync("Hello First timer"); return; From 7d6349c81d6c9b49ea93bdef7ea6220f9e5ddeb6 Mon Sep 17 00:00:00 2001 From: Chris Ross Date: Mon, 20 Apr 2015 15:55:46 -0700 Subject: [PATCH 192/216] Fix samples. --- .../Properties/launchSettings.json | 21 +++++++++++++++++++ samples/CookieSample/Startup.cs | 10 ++++++--- samples/CookieSample/project.json | 1 + .../Properties/launchSettings.json | 21 +++++++++++++++++++ samples/CookieSessionSample/Startup.cs | 12 +++++++---- samples/CookieSessionSample/project.json | 5 +++-- .../Properties/launchSettings.json | 21 +++++++++++++++++++ samples/OpenIdConnectSample/Startup.cs | 7 +++++-- samples/OpenIdConnectSample/project.json | 9 ++++---- .../Properties/launchSettings.json | 21 +++++++++++++++++++ samples/SocialSample/SocialSample.xproj | 2 +- samples/SocialSample/Startup.cs | 14 ++++++++----- samples/SocialSample/project.json | 3 ++- 13 files changed, 125 insertions(+), 22 deletions(-) create mode 100644 samples/CookieSample/Properties/launchSettings.json create mode 100644 samples/CookieSessionSample/Properties/launchSettings.json create mode 100644 samples/OpenIdConnectSample/Properties/launchSettings.json create mode 100644 samples/SocialSample/Properties/launchSettings.json diff --git a/samples/CookieSample/Properties/launchSettings.json b/samples/CookieSample/Properties/launchSettings.json new file mode 100644 index 000000000..381ef9b50 --- /dev/null +++ b/samples/CookieSample/Properties/launchSettings.json @@ -0,0 +1,21 @@ +{ + "profiles": { + "IIS Express": { + "commandName": "IISExpress", + "launchBrowser": true, + "environmentVariables": { + "ASPNET_ENV": "Development" + } + }, + "web": { + "commandName": "web", + "launchBrowser": true, + "launchUrl": "http://localhost:12345" + }, + "kestrel": { + "commandName": "kestrel", + "launchBrowser": true, + "launchUrl": "http://localhost:5004" + } + } +} \ No newline at end of file diff --git a/samples/CookieSample/Startup.cs b/samples/CookieSample/Startup.cs index e700f4b90..cff155a78 100644 --- a/samples/CookieSample/Startup.cs +++ b/samples/CookieSample/Startup.cs @@ -1,8 +1,9 @@ using System.Security.Claims; +using Microsoft.AspNet.Authentication.Cookies; using Microsoft.AspNet.Builder; using Microsoft.AspNet.Http; -using Microsoft.AspNet.Authentication.Cookies; using Microsoft.Framework.DependencyInjection; +using Microsoft.Framework.Logging; namespace CookieSample { @@ -14,8 +15,10 @@ public void ConfigureServices(IServiceCollection services) services.AddDataProtection(); } - public void Configure(IApplicationBuilder app) + public void Configure(IApplicationBuilder app, ILoggerFactory loggerfactory) { + loggerfactory.AddConsole(LogLevel.Information); + app.UseCookieAuthentication(options => { options.AutomaticAuthentication = true; @@ -25,7 +28,8 @@ public void Configure(IApplicationBuilder app) { if (string.IsNullOrEmpty(context.User.Identity.Name)) { - context.Response.SignIn(CookieAuthenticationDefaults.AuthenticationScheme, new ClaimsPrincipal(new ClaimsIdentity(new[] { new Claim(ClaimTypes.Name, "bob") }))); + var user = new ClaimsPrincipal(new ClaimsIdentity(new[] { new Claim(ClaimTypes.Name, "bob") })); + context.Response.SignIn(CookieAuthenticationDefaults.AuthenticationScheme, user); context.Response.ContentType = "text/plain"; await context.Response.WriteAsync("Hello First timer"); return; diff --git a/samples/CookieSample/project.json b/samples/CookieSample/project.json index eea2a4c7e..1c559aeba 100644 --- a/samples/CookieSample/project.json +++ b/samples/CookieSample/project.json @@ -3,6 +3,7 @@ "Microsoft.AspNet.Authentication.Cookies": "1.0.0-*", "Microsoft.AspNet.Server.WebListener": "1.0.0-*", "Microsoft.AspNet.Server.IIS": "1.0.0-*", + "Microsoft.Framework.Logging.Console": "1.0.0-*", "Kestrel": "1.0.0-*" }, "commands": { diff --git a/samples/CookieSessionSample/Properties/launchSettings.json b/samples/CookieSessionSample/Properties/launchSettings.json new file mode 100644 index 000000000..381ef9b50 --- /dev/null +++ b/samples/CookieSessionSample/Properties/launchSettings.json @@ -0,0 +1,21 @@ +{ + "profiles": { + "IIS Express": { + "commandName": "IISExpress", + "launchBrowser": true, + "environmentVariables": { + "ASPNET_ENV": "Development" + } + }, + "web": { + "commandName": "web", + "launchBrowser": true, + "launchUrl": "http://localhost:12345" + }, + "kestrel": { + "commandName": "kestrel", + "launchBrowser": true, + "launchUrl": "http://localhost:5004" + } + } +} \ No newline at end of file diff --git a/samples/CookieSessionSample/Startup.cs b/samples/CookieSessionSample/Startup.cs index decbd181a..314ff3782 100644 --- a/samples/CookieSessionSample/Startup.cs +++ b/samples/CookieSessionSample/Startup.cs @@ -4,6 +4,7 @@ using Microsoft.AspNet.Http; using Microsoft.AspNet.Authentication.Cookies; using Microsoft.Framework.DependencyInjection; +using Microsoft.Framework.Logging; namespace CookieSessionSample { @@ -15,20 +16,23 @@ public void ConfigureServices(IServiceCollection services) services.AddDataProtection(); } - public void Configure(IApplicationBuilder app) + public void Configure(IApplicationBuilder app, ILoggerFactory loggerfactory) { - app.UseCookieAuthentication(options => + loggerfactory.AddConsole(LogLevel.Information); + + app.UseCookieAuthentication(options => { + options.AutomaticAuthentication = true; options.SessionStore = new MemoryCacheSessionStore(); }); app.Run(async context => { - if (context.User.Identity == null || !context.User.Identity.IsAuthenticated) + if (string.IsNullOrEmpty(context.User.Identity.Name)) { // Make a large identity var claims = new List(1001); - claims.Add(new Claim("name", "bob")); + claims.Add(new Claim(ClaimTypes.Name, "bob")); for (int i = 0; i < 1000; i++) { claims.Add(new Claim(ClaimTypes.Role, "SomeRandomGroup" + i, ClaimValueTypes.String, "IssuedByBob", "OriginalIssuerJoe")); diff --git a/samples/CookieSessionSample/project.json b/samples/CookieSessionSample/project.json index 253079ceb..0e8c9a350 100644 --- a/samples/CookieSessionSample/project.json +++ b/samples/CookieSessionSample/project.json @@ -1,10 +1,11 @@ { "dependencies": { "Microsoft.AspNet.Authentication.Cookies": "1.0.0-*", + "Microsoft.AspNet.Server.IIS": "1.0.0-*", "Microsoft.AspNet.Server.WebListener": "1.0.0-*", "Microsoft.Framework.Caching.Memory": "1.0.0-*", - "Kestrel": "1.0.0-*", - "Microsoft.AspNet.Server.IIS": "1.0.0-*" + "Microsoft.Framework.Logging.Console": "1.0.0-*", + "Kestrel": "1.0.0-*" }, "commands": { "web": "Microsoft.AspNet.Hosting server=Microsoft.AspNet.Server.WebListener server.urls=http://localhost:12345", diff --git a/samples/OpenIdConnectSample/Properties/launchSettings.json b/samples/OpenIdConnectSample/Properties/launchSettings.json new file mode 100644 index 000000000..d8622657c --- /dev/null +++ b/samples/OpenIdConnectSample/Properties/launchSettings.json @@ -0,0 +1,21 @@ +{ + "profiles": { + "IIS Express": { + "commandName": "IISExpress", + "launchBrowser": true, + "environmentVariables": { + "ASPNET_ENV": "Development" + } + }, + "kestrel": { + "commandName": "kestrel", + "launchBrowser": true, + "launchUrl": "http://localhost:5004" + }, + "web": { + "commandName": "web", + "launchBrowser": true, + "launchUrl": "http://localhost:12345" + } + } +} \ No newline at end of file diff --git a/samples/OpenIdConnectSample/Startup.cs b/samples/OpenIdConnectSample/Startup.cs index c93eae671..29b89c824 100644 --- a/samples/OpenIdConnectSample/Startup.cs +++ b/samples/OpenIdConnectSample/Startup.cs @@ -5,6 +5,7 @@ using Microsoft.AspNet.Authentication.Cookies; using Microsoft.AspNet.Authentication.OpenIdConnect; using Microsoft.Framework.DependencyInjection; +using Microsoft.Framework.Logging; namespace OpenIdConnectSample { @@ -20,8 +21,10 @@ public void ConfigureServices(IServiceCollection services) }); } - public void Configure(IApplicationBuilder app) + public void Configure(IApplicationBuilder app, ILoggerFactory loggerfactory) { + loggerfactory.AddConsole(LogLevel.Information); + app.UseCookieAuthentication(options => { options.AutomaticAuthentication = true; @@ -36,7 +39,7 @@ public void Configure(IApplicationBuilder app) app.Run(async context => { - if (context.User == null || !context.User.Identity.IsAuthenticated) + if (string.IsNullOrEmpty(context.User.Identity.Name)) { context.Response.Challenge(new AuthenticationProperties { RedirectUri = "/" }, OpenIdConnectAuthenticationDefaults.AuthenticationScheme); diff --git a/samples/OpenIdConnectSample/project.json b/samples/OpenIdConnectSample/project.json index e6e8d6a7b..13d492ed3 100644 --- a/samples/OpenIdConnectSample/project.json +++ b/samples/OpenIdConnectSample/project.json @@ -1,10 +1,11 @@ { "dependencies": { - "Kestrel": "1.0.0-*", "Microsoft.AspNet.Authentication.Cookies": "1.0.0-*", - "Microsoft.AspNet.Server.IIS": "1.0.0-*", "Microsoft.AspNet.Authentication.OpenIdConnect": "1.0.0-*", - "Microsoft.AspNet.Server.WebListener": "1.0.0-*" + "Microsoft.AspNet.Server.IIS": "1.0.0-*", + "Microsoft.AspNet.Server.WebListener": "1.0.0-*", + "Microsoft.Framework.Logging.Console": "1.0.0-*", + "Kestrel": "1.0.0-*" }, "frameworks": { "dnx451": { }, @@ -13,6 +14,6 @@ "commands": { "web": "Microsoft.AspNet.Hosting server=Microsoft.AspNet.Server.WebListener server.urls=http://localhost:12345", "kestrel": "Microsoft.AspNet.Hosting --server Kestrel --server.urls http://localhost:5004" - }, + }, "webroot": "wwwroot" } diff --git a/samples/SocialSample/Properties/launchSettings.json b/samples/SocialSample/Properties/launchSettings.json new file mode 100644 index 000000000..88e42ba2b --- /dev/null +++ b/samples/SocialSample/Properties/launchSettings.json @@ -0,0 +1,21 @@ +{ + "profiles": { + "IIS Express": { + "commandName": "IISExpress", + "launchBrowser": true, + "environmentVariables": { + "ASPNET_ENV": "Development" + } + }, + "kestrel": { + "commandName": "kestrel", + "launchBrowser": true, + "launchUrl": "http://localhost:54540/" + }, + "web": { + "commandName": "web", + "launchBrowser": true, + "launchUrl": "http://localhost:54540/" + } + } +} \ No newline at end of file diff --git a/samples/SocialSample/SocialSample.xproj b/samples/SocialSample/SocialSample.xproj index d12b8fcbf..3d2aa528d 100644 --- a/samples/SocialSample/SocialSample.xproj +++ b/samples/SocialSample/SocialSample.xproj @@ -12,7 +12,7 @@ 2.0 - 36504 + 54540 \ No newline at end of file diff --git a/samples/SocialSample/Startup.cs b/samples/SocialSample/Startup.cs index 45c775cd1..aea458e1a 100644 --- a/samples/SocialSample/Startup.cs +++ b/samples/SocialSample/Startup.cs @@ -10,6 +10,7 @@ using Microsoft.AspNet.Http; using Microsoft.AspNet.Http.Authentication; using Microsoft.Framework.DependencyInjection; +using Microsoft.Framework.Logging; using Newtonsoft.Json.Linq; namespace CookieSample @@ -33,14 +34,17 @@ public void ConfigureServices(IServiceCollection services) }); } - public void Configure(IApplicationBuilder app) + public void Configure(IApplicationBuilder app, ILoggerFactory loggerfactory) { + loggerfactory.AddConsole(LogLevel.Information); + app.UseErrorPage(); app.UseCookieAuthentication(options => - { - options.LoginPath = new PathString("/login"); - }); + { + options.AutomaticAuthentication = true; + options.LoginPath = new PathString("/login"); + }); // https://developers.facebook.com/apps/ app.UseFacebookAuthentication(options => @@ -217,7 +221,7 @@ dnx . web // Deny anonymous request beyond this point. app.Use(async (context, next) => { - if (!context.User.Identity.IsAuthenticated) + if (string.IsNullOrEmpty(context.User.Identity.Name)) { // The cookie middleware will intercept this 401 and redirect to /login context.Response.Challenge(); diff --git a/samples/SocialSample/project.json b/samples/SocialSample/project.json index 30905d0b3..7c52600f3 100644 --- a/samples/SocialSample/project.json +++ b/samples/SocialSample/project.json @@ -1,13 +1,14 @@ { "dependencies": { - "Microsoft.AspNet.Diagnostics": "1.0.0-*", "Microsoft.AspNet.Authentication.Cookies": "1.0.0-*", "Microsoft.AspNet.Authentication.Facebook": "1.0.0-*", "Microsoft.AspNet.Authentication.Google": "1.0.0-*", "Microsoft.AspNet.Authentication.MicrosoftAccount": "1.0.0-*", "Microsoft.AspNet.Authentication.Twitter": "1.0.0-*", + "Microsoft.AspNet.Diagnostics": "1.0.0-*", "Microsoft.AspNet.Server.IIS": "1.0.0-*", "Microsoft.AspNet.Server.WebListener": "1.0.0-*", + "Microsoft.Framework.Logging.Console": "1.0.0-*", "Kestrel": "1.0.0-*" }, "commands": { From 6072e3b1b80befa6472b0134399d5d21ae9d1178 Mon Sep 17 00:00:00 2001 From: Chris Ross Date: Tue, 21 Apr 2015 16:21:50 -0700 Subject: [PATCH 193/216] #221 Remove unneeded dependencies around DataProtection. --- samples/CookieSample/project.json | 1 + samples/CookieSessionSample/project.json | 1 + samples/OpenIdConnectSample/project.json | 1 + samples/SocialSample/project.json | 1 + .../project.json | 6 +++++- .../project.json | 1 - .../project.json | 3 ++- src/Microsoft.AspNet.Authentication/project.json | 12 ++++++++---- .../project.json | 1 + 9 files changed, 20 insertions(+), 7 deletions(-) diff --git a/samples/CookieSample/project.json b/samples/CookieSample/project.json index 1c559aeba..e69eed0e2 100644 --- a/samples/CookieSample/project.json +++ b/samples/CookieSample/project.json @@ -1,6 +1,7 @@ { "dependencies": { "Microsoft.AspNet.Authentication.Cookies": "1.0.0-*", + "Microsoft.AspNet.DataProtection": "1.0.0-*", "Microsoft.AspNet.Server.WebListener": "1.0.0-*", "Microsoft.AspNet.Server.IIS": "1.0.0-*", "Microsoft.Framework.Logging.Console": "1.0.0-*", diff --git a/samples/CookieSessionSample/project.json b/samples/CookieSessionSample/project.json index 0e8c9a350..0f481e611 100644 --- a/samples/CookieSessionSample/project.json +++ b/samples/CookieSessionSample/project.json @@ -1,6 +1,7 @@ { "dependencies": { "Microsoft.AspNet.Authentication.Cookies": "1.0.0-*", + "Microsoft.AspNet.DataProtection": "1.0.0-*", "Microsoft.AspNet.Server.IIS": "1.0.0-*", "Microsoft.AspNet.Server.WebListener": "1.0.0-*", "Microsoft.Framework.Caching.Memory": "1.0.0-*", diff --git a/samples/OpenIdConnectSample/project.json b/samples/OpenIdConnectSample/project.json index 13d492ed3..815ad8a33 100644 --- a/samples/OpenIdConnectSample/project.json +++ b/samples/OpenIdConnectSample/project.json @@ -2,6 +2,7 @@ "dependencies": { "Microsoft.AspNet.Authentication.Cookies": "1.0.0-*", "Microsoft.AspNet.Authentication.OpenIdConnect": "1.0.0-*", + "Microsoft.AspNet.DataProtection": "1.0.0-*", "Microsoft.AspNet.Server.IIS": "1.0.0-*", "Microsoft.AspNet.Server.WebListener": "1.0.0-*", "Microsoft.Framework.Logging.Console": "1.0.0-*", diff --git a/samples/SocialSample/project.json b/samples/SocialSample/project.json index 7c52600f3..ccaf0a439 100644 --- a/samples/SocialSample/project.json +++ b/samples/SocialSample/project.json @@ -5,6 +5,7 @@ "Microsoft.AspNet.Authentication.Google": "1.0.0-*", "Microsoft.AspNet.Authentication.MicrosoftAccount": "1.0.0-*", "Microsoft.AspNet.Authentication.Twitter": "1.0.0-*", + "Microsoft.AspNet.DataProtection": "1.0.0-*", "Microsoft.AspNet.Diagnostics": "1.0.0-*", "Microsoft.AspNet.Server.IIS": "1.0.0-*", "Microsoft.AspNet.Server.WebListener": "1.0.0-*", diff --git a/src/Microsoft.AspNet.Authentication.Facebook/project.json b/src/Microsoft.AspNet.Authentication.Facebook/project.json index 7bce6f458..a14ab52da 100644 --- a/src/Microsoft.AspNet.Authentication.Facebook/project.json +++ b/src/Microsoft.AspNet.Authentication.Facebook/project.json @@ -8,6 +8,10 @@ }, "frameworks": { "dnx451": { }, - "dnxcore50": { } + "dnxcore50": { + "dependencies": { + "System.Security.Cryptography.Hashing.Algorithms": "4.0.0-beta-*" + } + } } } diff --git a/src/Microsoft.AspNet.Authentication.OAuth/project.json b/src/Microsoft.AspNet.Authentication.OAuth/project.json index 215b5155d..a3409abf8 100644 --- a/src/Microsoft.AspNet.Authentication.OAuth/project.json +++ b/src/Microsoft.AspNet.Authentication.OAuth/project.json @@ -2,7 +2,6 @@ "version": "1.0.0-*", "description": "ASP.NET 5 middleware that enables an application to support any standard OAuth 2.0 authentication workflow.", "dependencies": { - "Microsoft.AspNet.DataProtection": "1.0.0-*", "Microsoft.AspNet.Authentication": "1.0.0-*", "Microsoft.Framework.NotNullAttribute.Internal": { "type": "build", "version": "1.0.0-*" }, "Newtonsoft.Json": "6.0.6" diff --git a/src/Microsoft.AspNet.Authentication.Twitter/project.json b/src/Microsoft.AspNet.Authentication.Twitter/project.json index 33d73fd1c..a9d804bc2 100644 --- a/src/Microsoft.AspNet.Authentication.Twitter/project.json +++ b/src/Microsoft.AspNet.Authentication.Twitter/project.json @@ -14,7 +14,8 @@ }, "dnxcore50": { "dependencies": { - "System.Net.Http.WinHttpHandler": "4.0.0-beta-*" + "System.Net.Http.WinHttpHandler": "4.0.0-beta-*", + "System.Security.Cryptography.Hashing.Algorithms": "4.0.0-beta-*" } } } diff --git a/src/Microsoft.AspNet.Authentication/project.json b/src/Microsoft.AspNet.Authentication/project.json index 8367af5f0..a28d27e07 100644 --- a/src/Microsoft.AspNet.Authentication/project.json +++ b/src/Microsoft.AspNet.Authentication/project.json @@ -2,15 +2,19 @@ "version": "1.0.0-*", "description": "ASP.NET 5 common types used by the various authentication middleware.", "dependencies": { - "Microsoft.AspNet.DataProtection": "1.0.0-*", + "Microsoft.AspNet.DataProtection.Interfaces": "1.0.0-*", "Microsoft.AspNet.Http": "1.0.0-*", - "Microsoft.AspNet.Http.Interfaces": "1.0.0-*", "Microsoft.AspNet.Http.Extensions": "1.0.0-*", "Microsoft.Framework.Logging.Interfaces": "1.0.0-*", - "Microsoft.Framework.NotNullAttribute.Internal": { "type": "build", "version": "1.0.0-*" } + "Microsoft.Framework.NotNullAttribute.Internal": { "type": "build", "version": "1.0.0-*" }, + "Microsoft.Framework.OptionsModel": "1.0.0-*" }, "frameworks": { "dnx451": { }, - "dnxcore50": { } + "dnxcore50": { + "dependencies": { + "System.Security.Cryptography.RandomNumberGenerator": "4.0.0-beta-*" + } + } } } diff --git a/test/Microsoft.AspNet.Authentication.Test/project.json b/test/Microsoft.AspNet.Authentication.Test/project.json index 2d88d7988..c7f594c4f 100644 --- a/test/Microsoft.AspNet.Authentication.Test/project.json +++ b/test/Microsoft.AspNet.Authentication.Test/project.json @@ -10,6 +10,7 @@ "Microsoft.AspNet.Authentication.OAuthBearer": "1.0.0-*", "Microsoft.AspNet.Authentication.OpenIdConnect": "1.0.0-*", "Microsoft.AspNet.Authentication.Twitter": "1.0.0-*", + "Microsoft.AspNet.DataProtection": "1.0.0-*", "Microsoft.AspNet.TestHost": "1.0.0-*", "Moq": "4.2.1312.1622", "xunit.runner.aspnet": "2.0.0-aspnet-*" From 30d350da26d5c40e9e160ccb2cd120303da5baf1 Mon Sep 17 00:00:00 2001 From: Hao Kung Date: Wed, 22 Apr 2015 12:23:54 -0700 Subject: [PATCH 194/216] Move logger to base handler and moar var --- .../CookieAuthenticationHandler.cs | 13 +- .../CookieAuthenticationMiddleware.cs | 10 +- .../FacebookAuthenticationHandler.cs | 18 +-- .../FacebookAuthenticationMiddleware.cs | 4 +- .../FacebookServiceCollectionExtensions.cs | 2 +- .../GoogleAuthenticationHandler.cs | 17 ++- .../GoogleAuthenticationMiddleware.cs | 4 +- .../GoogleAuthenticationOptions.cs | 2 +- .../MicrosoftAccountAuthenticationHandler.cs | 18 ++- ...icrosoftAccountAuthenticationMiddleware.cs | 3 +- .../OAuthAuthenticationHandler.cs | 7 +- .../OAuthAuthenticationMiddleware.cs | 10 +- .../OAuthBearerAuthenticationHandler.cs | 10 +- .../OAuthBearerAuthenticationMiddleware.cs | 5 +- .../OpenIdConnectAuthenticationHandler.cs | 111 ++++++++---------- .../OpenIdConnectAuthenticationMiddleware.cs | 11 +- .../OpenIdConnectAuthenticationOptions.cs | 1 - .../TwitterAuthenticationHandler.cs | 74 ++++++------ .../TwitterAuthenticationMiddleware.cs | 7 +- .../AuthenticationHandler.cs | 18 +-- .../AuthenticationHandler`1.cs | 6 +- .../AuthenticationMiddleware.cs | 10 +- .../AuthorizationPolicy.cs | 2 +- .../AuthenticationHandlerFacts.cs | 11 +- .../Google/GoogleMiddlewareTests.cs | 2 + .../OpenIdConnectHandlerTests.cs | 17 +-- .../Microsoft.AspNet.Authorization.Test.xproj | 3 + 27 files changed, 169 insertions(+), 227 deletions(-) diff --git a/src/Microsoft.AspNet.Authentication.Cookies/CookieAuthenticationHandler.cs b/src/Microsoft.AspNet.Authentication.Cookies/CookieAuthenticationHandler.cs index 8ccbb3653..27b0d2c4e 100644 --- a/src/Microsoft.AspNet.Authentication.Cookies/CookieAuthenticationHandler.cs +++ b/src/Microsoft.AspNet.Authentication.Cookies/CookieAuthenticationHandler.cs @@ -22,18 +22,11 @@ internal class CookieAuthenticationHandler : AuthenticationHandler AuthenticateCoreAsync() if (ticket == null) { - _logger.LogWarning(@"Unprotect ticket failed"); + Logger.LogWarning(@"Unprotect ticket failed"); return null; } @@ -63,14 +56,14 @@ protected override async Task AuthenticateCoreAsync() Claim claim = ticket.Principal.Claims.FirstOrDefault(c => c.Type.Equals(SessionIdClaim)); if (claim == null) { - _logger.LogWarning(@"SessionId missing"); + Logger.LogWarning(@"SessionId missing"); return null; } _sessionKey = claim.Value; ticket = await Options.SessionStore.RetrieveAsync(_sessionKey); if (ticket == null) { - _logger.LogWarning(@"Identity missing in session store"); + Logger.LogWarning(@"Identity missing in session store"); return null; } } diff --git a/src/Microsoft.AspNet.Authentication.Cookies/CookieAuthenticationMiddleware.cs b/src/Microsoft.AspNet.Authentication.Cookies/CookieAuthenticationMiddleware.cs index 0d95f08e7..0a5789f7c 100644 --- a/src/Microsoft.AspNet.Authentication.Cookies/CookieAuthenticationMiddleware.cs +++ b/src/Microsoft.AspNet.Authentication.Cookies/CookieAuthenticationMiddleware.cs @@ -15,8 +15,6 @@ namespace Microsoft.AspNet.Authentication.Cookies { public class CookieAuthenticationMiddleware : AuthenticationMiddleware { - private readonly ILogger _logger; - public CookieAuthenticationMiddleware( [NotNull] RequestDelegate next, [NotNull] IDataProtectionProvider dataProtectionProvider, @@ -24,7 +22,7 @@ public CookieAuthenticationMiddleware( [NotNull] IUrlEncoder urlEncoder, [NotNull] IOptions options, ConfigureOptions configureOptions) - : base(next, options, configureOptions) + : base(next, options, loggerFactory, configureOptions) { if (Options.Notifications == null) { @@ -36,7 +34,7 @@ public CookieAuthenticationMiddleware( } if (Options.TicketDataFormat == null) { - IDataProtector dataProtector = dataProtectionProvider.CreateProtector( + var dataProtector = dataProtectionProvider.CreateProtector( typeof(CookieAuthenticationMiddleware).FullName, Options.AuthenticationScheme, "v2"); Options.TicketDataFormat = new TicketDataFormat(dataProtector); } @@ -44,13 +42,11 @@ public CookieAuthenticationMiddleware( { Options.CookieManager = new ChunkingCookieManager(urlEncoder); } - - _logger = loggerFactory.CreateLogger(typeof(CookieAuthenticationMiddleware).FullName); } protected override AuthenticationHandler CreateHandler() { - return new CookieAuthenticationHandler(_logger); + return new CookieAuthenticationHandler(); } } } \ No newline at end of file diff --git a/src/Microsoft.AspNet.Authentication.Facebook/FacebookAuthenticationHandler.cs b/src/Microsoft.AspNet.Authentication.Facebook/FacebookAuthenticationHandler.cs index d16c796ed..246a5328e 100644 --- a/src/Microsoft.AspNet.Authentication.Facebook/FacebookAuthenticationHandler.cs +++ b/src/Microsoft.AspNet.Authentication.Facebook/FacebookAuthenticationHandler.cs @@ -21,8 +21,8 @@ namespace Microsoft.AspNet.Authentication.Facebook { internal class FacebookAuthenticationHandler : OAuthAuthenticationHandler { - public FacebookAuthenticationHandler(HttpClient httpClient, ILogger logger) - : base(httpClient, logger) + public FacebookAuthenticationHandler(HttpClient httpClient) + : base(httpClient) { } @@ -39,9 +39,9 @@ protected override async Task ExchangeCodeAsync(string code, stri var tokenResponse = await Backchannel.GetAsync(Options.TokenEndpoint + queryBuilder.ToString(), Context.RequestAborted); tokenResponse.EnsureSuccessStatusCode(); - string oauthTokenResponse = await tokenResponse.Content.ReadAsStringAsync(); + var oauthTokenResponse = await tokenResponse.Content.ReadAsStringAsync(); - IFormCollection form = new FormCollection(FormReader.ReadForm(oauthTokenResponse)); + var form = new FormCollection(FormReader.ReadForm(oauthTokenResponse)); var response = new JObject(); foreach (string key in form.Keys) { @@ -53,7 +53,7 @@ protected override async Task ExchangeCodeAsync(string code, stri protected override async Task GetUserInformationAsync(AuthenticationProperties properties, TokenResponse tokens) { - string graphAddress = Options.UserInformationEndpoint + "?access_token=" + Uri.EscapeDataString(tokens.AccessToken); + var graphAddress = Options.UserInformationEndpoint + "?access_token=" + Uri.EscapeDataString(tokens.AccessToken); if (Options.SendAppSecretProof) { graphAddress += "&appsecret_proof=" + GenerateAppSecretProof(tokens.AccessToken); @@ -61,8 +61,8 @@ protected override async Task GetUserInformationAsync(Auth var graphResponse = await Backchannel.GetAsync(graphAddress, Context.RequestAborted); graphResponse.EnsureSuccessStatusCode(); - string text = await graphResponse.Content.ReadAsStringAsync(); - JObject user = JObject.Parse(text); + var text = await graphResponse.Content.ReadAsStringAsync(); + var user = JObject.Parse(text); var context = new FacebookAuthenticatedContext(Context, Options, user, tokens); var identity = new ClaimsIdentity( @@ -107,8 +107,8 @@ private string GenerateAppSecretProof(string accessToken) { using (HMACSHA256 algorithm = new HMACSHA256(Encoding.ASCII.GetBytes(Options.AppSecret))) { - byte[] hash = algorithm.ComputeHash(Encoding.ASCII.GetBytes(accessToken)); - StringBuilder builder = new StringBuilder(); + var hash = algorithm.ComputeHash(Encoding.ASCII.GetBytes(accessToken)); + var builder = new StringBuilder(); for (int i = 0; i < hash.Length; i++) { builder.Append(hash[i].ToString("x2", CultureInfo.InvariantCulture)); diff --git a/src/Microsoft.AspNet.Authentication.Facebook/FacebookAuthenticationMiddleware.cs b/src/Microsoft.AspNet.Authentication.Facebook/FacebookAuthenticationMiddleware.cs index 7feacb1d1..39b0e87ea 100644 --- a/src/Microsoft.AspNet.Authentication.Facebook/FacebookAuthenticationMiddleware.cs +++ b/src/Microsoft.AspNet.Authentication.Facebook/FacebookAuthenticationMiddleware.cs @@ -54,7 +54,7 @@ public FacebookAuthenticationMiddleware( /// An configured with the supplied to the constructor. protected override AuthenticationHandler CreateHandler() { - return new FacebookAuthenticationHandler(Backchannel, Logger); + return new FacebookAuthenticationHandler(Backchannel); } } -} +} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Authentication.Facebook/FacebookServiceCollectionExtensions.cs b/src/Microsoft.AspNet.Authentication.Facebook/FacebookServiceCollectionExtensions.cs index 26ab1c063..1550a6cd8 100644 --- a/src/Microsoft.AspNet.Authentication.Facebook/FacebookServiceCollectionExtensions.cs +++ b/src/Microsoft.AspNet.Authentication.Facebook/FacebookServiceCollectionExtensions.cs @@ -33,4 +33,4 @@ public static IServiceCollection ConfigureFacebookAuthentication([NotNull] this return services.Configure(config, optionsName); } } -} +} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Authentication.Google/GoogleAuthenticationHandler.cs b/src/Microsoft.AspNet.Authentication.Google/GoogleAuthenticationHandler.cs index 71e51f06a..175c38c20 100644 --- a/src/Microsoft.AspNet.Authentication.Google/GoogleAuthenticationHandler.cs +++ b/src/Microsoft.AspNet.Authentication.Google/GoogleAuthenticationHandler.cs @@ -10,27 +10,26 @@ using Microsoft.AspNet.Http.Authentication; using Microsoft.AspNet.Authentication.OAuth; using Microsoft.AspNet.WebUtilities; -using Microsoft.Framework.Logging; using Newtonsoft.Json.Linq; namespace Microsoft.AspNet.Authentication.Google { internal class GoogleAuthenticationHandler : OAuthAuthenticationHandler { - public GoogleAuthenticationHandler(HttpClient httpClient, ILogger logger) - : base(httpClient, logger) + public GoogleAuthenticationHandler(HttpClient httpClient) + : base(httpClient) { } protected override async Task GetUserInformationAsync(AuthenticationProperties properties, TokenResponse tokens) { // Get the Google user - HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, Options.UserInformationEndpoint); + var request = new HttpRequestMessage(HttpMethod.Get, Options.UserInformationEndpoint); request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", tokens.AccessToken); - HttpResponseMessage graphResponse = await Backchannel.SendAsync(request, Context.RequestAborted); + var graphResponse = await Backchannel.SendAsync(request, Context.RequestAborted); graphResponse.EnsureSuccessStatusCode(); var text = await graphResponse.Content.ReadAsStringAsync(); - JObject user = JObject.Parse(text); + var user = JObject.Parse(text); var context = new GoogleAuthenticatedContext(Context, Options, user, tokens); var identity = new ClaimsIdentity( @@ -79,7 +78,7 @@ protected override async Task GetUserInformationAsync(Auth // TODO: Abstract this properties override pattern into the base class? protected override string BuildChallengeUrl(AuthenticationProperties properties, string redirectUri) { - string scope = FormatScope(); + var scope = FormatScope(); var queryStrings = new Dictionary(StringComparer.OrdinalIgnoreCase); queryStrings.Add("response_type", "code"); @@ -92,10 +91,10 @@ protected override string BuildChallengeUrl(AuthenticationProperties properties, AddQueryString(queryStrings, properties, "approval_prompt"); AddQueryString(queryStrings, properties, "login_hint"); - string state = Options.StateDataFormat.Protect(properties); + var state = Options.StateDataFormat.Protect(properties); queryStrings.Add("state", state); - string authorizationEndpoint = QueryHelpers.AddQueryString(Options.AuthorizationEndpoint, queryStrings); + var authorizationEndpoint = QueryHelpers.AddQueryString(Options.AuthorizationEndpoint, queryStrings); return authorizationEndpoint; } diff --git a/src/Microsoft.AspNet.Authentication.Google/GoogleAuthenticationMiddleware.cs b/src/Microsoft.AspNet.Authentication.Google/GoogleAuthenticationMiddleware.cs index 73e6b180b..f98d659d2 100644 --- a/src/Microsoft.AspNet.Authentication.Google/GoogleAuthenticationMiddleware.cs +++ b/src/Microsoft.AspNet.Authentication.Google/GoogleAuthenticationMiddleware.cs @@ -56,7 +56,7 @@ public GoogleAuthenticationMiddleware( /// An configured with the supplied to the constructor. protected override AuthenticationHandler CreateHandler() { - return new GoogleAuthenticationHandler(Backchannel, Logger); + return new GoogleAuthenticationHandler(Backchannel); } } -} +} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Authentication.Google/GoogleAuthenticationOptions.cs b/src/Microsoft.AspNet.Authentication.Google/GoogleAuthenticationOptions.cs index e562a8f2c..30446b3b5 100644 --- a/src/Microsoft.AspNet.Authentication.Google/GoogleAuthenticationOptions.cs +++ b/src/Microsoft.AspNet.Authentication.Google/GoogleAuthenticationOptions.cs @@ -33,4 +33,4 @@ public GoogleAuthenticationOptions() /// public string AccessType { get; set; } } -} +} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Authentication.MicrosoftAccount/MicrosoftAccountAuthenticationHandler.cs b/src/Microsoft.AspNet.Authentication.MicrosoftAccount/MicrosoftAccountAuthenticationHandler.cs index bb953cc13..5696ce16a 100644 --- a/src/Microsoft.AspNet.Authentication.MicrosoftAccount/MicrosoftAccountAuthenticationHandler.cs +++ b/src/Microsoft.AspNet.Authentication.MicrosoftAccount/MicrosoftAccountAuthenticationHandler.cs @@ -1,35 +1,31 @@ // Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -using System; -using System.Collections.Generic; using System.Net.Http; using System.Net.Http.Headers; using System.Security.Claims; using System.Threading.Tasks; -using Microsoft.AspNet.Http; -using Microsoft.AspNet.Http.Authentication; using Microsoft.AspNet.Authentication.OAuth; -using Microsoft.Framework.Logging; +using Microsoft.AspNet.Http.Authentication; using Newtonsoft.Json.Linq; namespace Microsoft.AspNet.Authentication.MicrosoftAccount { internal class MicrosoftAccountAuthenticationHandler : OAuthAuthenticationHandler { - public MicrosoftAccountAuthenticationHandler(HttpClient httpClient, ILogger logger) - : base(httpClient, logger) + public MicrosoftAccountAuthenticationHandler(HttpClient httpClient) + : base(httpClient) { } protected override async Task GetUserInformationAsync(AuthenticationProperties properties, TokenResponse tokens) { - HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, Options.UserInformationEndpoint); + var request = new HttpRequestMessage(HttpMethod.Get, Options.UserInformationEndpoint); request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", tokens.AccessToken); - HttpResponseMessage graphResponse = await Backchannel.SendAsync(request, Context.RequestAborted); + var graphResponse = await Backchannel.SendAsync(request, Context.RequestAborted); graphResponse.EnsureSuccessStatusCode(); - string accountString = await graphResponse.Content.ReadAsStringAsync(); - JObject accountInformation = JObject.Parse(accountString); + var accountString = await graphResponse.Content.ReadAsStringAsync(); + var accountInformation = JObject.Parse(accountString); var context = new MicrosoftAccountAuthenticatedContext(Context, Options, accountInformation, tokens); context.Properties = properties; diff --git a/src/Microsoft.AspNet.Authentication.MicrosoftAccount/MicrosoftAccountAuthenticationMiddleware.cs b/src/Microsoft.AspNet.Authentication.MicrosoftAccount/MicrosoftAccountAuthenticationMiddleware.cs index 7626c7061..8978c4d1d 100644 --- a/src/Microsoft.AspNet.Authentication.MicrosoftAccount/MicrosoftAccountAuthenticationMiddleware.cs +++ b/src/Microsoft.AspNet.Authentication.MicrosoftAccount/MicrosoftAccountAuthenticationMiddleware.cs @@ -1,7 +1,6 @@ // Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -using System; using Microsoft.AspNet.Authentication.OAuth; using Microsoft.AspNet.Builder; using Microsoft.AspNet.DataProtection; @@ -50,7 +49,7 @@ public MicrosoftAccountAuthenticationMiddleware( /// An configured with the supplied to the constructor. protected override AuthenticationHandler CreateHandler() { - return new MicrosoftAccountAuthenticationHandler(Backchannel, Logger); + return new MicrosoftAccountAuthenticationHandler(Backchannel); } } } diff --git a/src/Microsoft.AspNet.Authentication.OAuth/OAuthAuthenticationHandler.cs b/src/Microsoft.AspNet.Authentication.OAuth/OAuthAuthenticationHandler.cs index 6389b8c1d..5d3cb8c60 100644 --- a/src/Microsoft.AspNet.Authentication.OAuth/OAuthAuthenticationHandler.cs +++ b/src/Microsoft.AspNet.Authentication.OAuth/OAuthAuthenticationHandler.cs @@ -19,16 +19,13 @@ public class OAuthAuthenticationHandler : Authenticati where TOptions : OAuthAuthenticationOptions where TNotifications : IOAuthAuthenticationNotifications { - public OAuthAuthenticationHandler(HttpClient backchannel, ILogger logger) + public OAuthAuthenticationHandler(HttpClient backchannel) { Backchannel = backchannel; - Logger = logger; } protected HttpClient Backchannel { get; private set; } - protected ILogger Logger { get; private set; } - public override async Task InvokeAsync() { if (Options.CallbackPath.HasValue && Options.CallbackPath == Request.Path) @@ -107,7 +104,7 @@ protected override async Task AuthenticateCoreAsync() } // OAuth2 10.12 CSRF - if (!ValidateCorrelationId(properties, Logger)) + if (!ValidateCorrelationId(properties)) { return new AuthenticationTicket(properties, Options.AuthenticationScheme); } diff --git a/src/Microsoft.AspNet.Authentication.OAuth/OAuthAuthenticationMiddleware.cs b/src/Microsoft.AspNet.Authentication.OAuth/OAuthAuthenticationMiddleware.cs index 8b8e432b3..9a211ef24 100644 --- a/src/Microsoft.AspNet.Authentication.OAuth/OAuthAuthenticationMiddleware.cs +++ b/src/Microsoft.AspNet.Authentication.OAuth/OAuthAuthenticationMiddleware.cs @@ -36,7 +36,7 @@ public OAuthAuthenticationMiddleware( [NotNull] IOptions externalOptions, [NotNull] IOptions options, ConfigureOptions configureOptions = null) - : base(next, options, configureOptions) + : base(next, options, loggerFactory, configureOptions) { // todo: review error handling if (string.IsNullOrWhiteSpace(Options.AuthenticationScheme)) @@ -64,11 +64,9 @@ public OAuthAuthenticationMiddleware( throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, Resources.Exception_OptionMustBeProvided, "TokenEndpoint")); } - Logger = loggerFactory.CreateLogger(this.GetType().FullName); - if (Options.StateDataFormat == null) { - IDataProtector dataProtector = dataProtectionProvider.CreateProtector( + var dataProtector = dataProtectionProvider.CreateProtector( this.GetType().FullName, Options.AuthenticationScheme, "v1"); Options.StateDataFormat = new PropertiesDataFormat(dataProtector); } @@ -90,15 +88,13 @@ public OAuthAuthenticationMiddleware( protected HttpClient Backchannel { get; private set; } - protected ILogger Logger { get; private set; } - /// /// Provides the object for processing authentication-related requests. /// /// An configured with the supplied to the constructor. protected override AuthenticationHandler CreateHandler() { - return new OAuthAuthenticationHandler(Backchannel, Logger); + return new OAuthAuthenticationHandler(Backchannel); } [SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Justification = "Managed by caller")] diff --git a/src/Microsoft.AspNet.Authentication.OAuthBearer/OAuthBearerAuthenticationHandler.cs b/src/Microsoft.AspNet.Authentication.OAuthBearer/OAuthBearerAuthenticationHandler.cs index 1f2d20b76..745c36f0f 100644 --- a/src/Microsoft.AspNet.Authentication.OAuthBearer/OAuthBearerAuthenticationHandler.cs +++ b/src/Microsoft.AspNet.Authentication.OAuthBearer/OAuthBearerAuthenticationHandler.cs @@ -17,14 +17,8 @@ namespace Microsoft.AspNet.Authentication.OAuthBearer { public class OAuthBearerAuthenticationHandler : AuthenticationHandler { - private readonly ILogger _logger; private OpenIdConnectConfiguration _configuration; - public OAuthBearerAuthenticationHandler(ILogger logger) - { - _logger = logger; - } - protected override AuthenticationTicket AuthenticateCore() { return AuthenticateCoreAsync().GetAwaiter().GetResult(); @@ -63,7 +57,7 @@ protected override async Task AuthenticateCoreAsync() if (string.IsNullOrEmpty(token)) { - string authorization = Request.Headers.Get("Authorization"); + var authorization = Request.Headers.Get("Authorization"); // If no authorization header found, nothing to process further if (string.IsNullOrEmpty(authorization)) @@ -155,7 +149,7 @@ protected override async Task AuthenticateCoreAsync() } catch (Exception ex) { - _logger.LogError("Exception occurred while processing message", ex); + Logger.LogError("Exception occurred while processing message", ex); // Refresh the configuration for exceptions that may be caused by key rollovers. The user can also request a refresh in the notification. if (Options.RefreshOnIssuerKeyNotFound && ex.GetType().Equals(typeof(SecurityTokenSignatureKeyNotFoundException))) diff --git a/src/Microsoft.AspNet.Authentication.OAuthBearer/OAuthBearerAuthenticationMiddleware.cs b/src/Microsoft.AspNet.Authentication.OAuthBearer/OAuthBearerAuthenticationMiddleware.cs index 9ab829c5d..a18bbee93 100644 --- a/src/Microsoft.AspNet.Authentication.OAuthBearer/OAuthBearerAuthenticationMiddleware.cs +++ b/src/Microsoft.AspNet.Authentication.OAuthBearer/OAuthBearerAuthenticationMiddleware.cs @@ -34,9 +34,8 @@ public OAuthBearerAuthenticationMiddleware( [NotNull] ILoggerFactory loggerFactory, [NotNull] IOptions options, ConfigureOptions configureOptions) - : base(next, options, configureOptions) + : base(next, options, loggerFactory, configureOptions) { - _logger = loggerFactory.CreateLogger(); if (Options.Notifications == null) { Options.Notifications = new OAuthBearerAuthenticationNotifications(); @@ -86,7 +85,7 @@ public OAuthBearerAuthenticationMiddleware( /// A new instance of the request handler protected override AuthenticationHandler CreateHandler() { - return new OAuthBearerAuthenticationHandler(_logger); + return new OAuthBearerAuthenticationHandler(); } [SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Justification = "Managed by caller")] diff --git a/src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenIdConnectAuthenticationHandler.cs b/src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenIdConnectAuthenticationHandler.cs index c0efcd0f6..75914cc7b 100644 --- a/src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenIdConnectAuthenticationHandler.cs +++ b/src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenIdConnectAuthenticationHandler.cs @@ -23,18 +23,8 @@ public class OpenIdConnectAuthenticationHandler : AuthenticationHandler - /// Creates a new OpenIdConnectAuthenticationHandler - /// - /// - public OpenIdConnectAuthenticationHandler(ILogger logger) - { - _logger = logger; - } - private string CurrentUri { get @@ -67,7 +57,7 @@ protected override async Task ApplyResponseGrantAsync() _configuration = await Options.ConfigurationManager.GetConfigurationAsync(Context.RequestAborted); } - OpenIdConnectMessage openIdConnectMessage = new OpenIdConnectMessage() + var openIdConnectMessage = new OpenIdConnectMessage() { IssuerAddress = _configuration == null ? string.Empty : (_configuration.EndSessionEndpoint ?? string.Empty), RequestType = OpenIdConnectRequestType.LogoutRequest, @@ -95,10 +85,10 @@ protected override async Task ApplyResponseGrantAsync() if (!notification.HandledResponse) { - string redirectUri = notification.ProtocolMessage.CreateLogoutRequestUrl(); + var redirectUri = notification.ProtocolMessage.CreateLogoutRequestUrl(); if (!Uri.IsWellFormedUriString(redirectUri, UriKind.Absolute)) { - _logger.LogWarning(Resources.OIDCH_0051_RedirectUriLogoutIsNotWellFormed, redirectUri); + Logger.LogWarning(Resources.OIDCH_0051_RedirectUriLogoutIsNotWellFormed, redirectUri); } Response.Redirect(redirectUri); @@ -118,28 +108,25 @@ protected override void ApplyResponseChallenge() /// Uses log id's OIDCH-0026 - OIDCH-0050, next num: 37 protected override async Task ApplyResponseChallengeAsync() { - if (_logger.IsEnabled(LogLevel.Debug)) - { - _logger.LogDebug(Resources.OIDCH_0026_ApplyResponseChallengeAsync, this.GetType()); - } + Logger.LogDebug(Resources.OIDCH_0026_ApplyResponseChallengeAsync, this.GetType()); if (ShouldConvertChallengeToForbidden()) { - _logger.LogDebug(Resources.OIDCH_0027_401_ConvertedTo_403); + Logger.LogDebug(Resources.OIDCH_0027_401_ConvertedTo_403); Response.StatusCode = 403; return; } if (Response.StatusCode != 401) { - _logger.LogDebug(Resources.OIDCH_0028_StatusCodeNot401, Response.StatusCode); + Logger.LogDebug(Resources.OIDCH_0028_StatusCodeNot401, Response.StatusCode); return; } // When Automatic should redirect on 401 even if there wasn't an explicit challenge. if (ChallengeContext == null && !Options.AutomaticAuthentication) { - _logger.LogDebug(Resources.OIDCH_0029_ChallengeContextEqualsNull); + Logger.LogDebug(Resources.OIDCH_0029_ChallengeContextEqualsNull); return; } @@ -158,17 +145,17 @@ protected override async Task ApplyResponseChallengeAsync() if (!string.IsNullOrWhiteSpace(properties.RedirectUri)) { - _logger.LogDebug(Resources.OIDCH_0030_Using_Properties_RedirectUri, properties.RedirectUri); + Logger.LogDebug(Resources.OIDCH_0030_Using_Properties_RedirectUri, properties.RedirectUri); } else if (Options.DefaultToCurrentUriOnRedirect) { - _logger.LogDebug(Resources.OIDCH_0032_UsingCurrentUriRedirectUri, CurrentUri); + Logger.LogDebug(Resources.OIDCH_0032_UsingCurrentUriRedirectUri, CurrentUri); properties.RedirectUri = CurrentUri; } if (!string.IsNullOrWhiteSpace(Options.RedirectUri)) { - _logger.LogDebug(Resources.OIDCH_0031_Using_Options_RedirectUri, Options.RedirectUri); + Logger.LogDebug(Resources.OIDCH_0031_Using_Options_RedirectUri, Options.RedirectUri); } // When redeeming a 'code' for an AccessToken, this value is needed @@ -203,7 +190,7 @@ protected override async Task ApplyResponseChallengeAsync() { if (!Options.NonceCache.TryAddNonce(message.Nonce)) { - _logger.LogError(Resources.OIDCH_0033_TryAddNonceFailed, message.Nonce); + Logger.LogError(Resources.OIDCH_0033_TryAddNonceFailed, message.Nonce); throw new OpenIdConnectProtocolException(string.Format(CultureInfo.InvariantCulture, Resources.OIDCH_0033_TryAddNonceFailed, message.Nonce)); } } @@ -221,19 +208,19 @@ protected override async Task ApplyResponseChallengeAsync() await Options.Notifications.RedirectToIdentityProvider(redirectToIdentityProviderNotification); if (redirectToIdentityProviderNotification.HandledResponse) { - _logger.LogInformation(Resources.OIDCH_0034_RedirectToIdentityProviderNotificationHandledResponse); + Logger.LogInformation(Resources.OIDCH_0034_RedirectToIdentityProviderNotificationHandledResponse); return; } else if (redirectToIdentityProviderNotification.Skipped) { - _logger.LogInformation(Resources.OIDCH_0035_RedirectToIdentityProviderNotificationSkipped); + Logger.LogInformation(Resources.OIDCH_0035_RedirectToIdentityProviderNotificationSkipped); return; } - string redirectUri = redirectToIdentityProviderNotification.ProtocolMessage.CreateAuthenticationRequestUrl(); + var redirectUri = redirectToIdentityProviderNotification.ProtocolMessage.CreateAuthenticationRequestUrl(); if (!Uri.IsWellFormedUriString(redirectUri, UriKind.Absolute)) { - _logger.LogWarning(Resources.OIDCH_0036_UriIsNotWellFormed, redirectUri); + Logger.LogWarning(Resources.OIDCH_0036_UriIsNotWellFormed, redirectUri); } Response.Redirect(redirectUri); @@ -251,10 +238,7 @@ protected override AuthenticationTicket AuthenticateCore() /// Uses log id's OIDCH-0000 - OIDCH-0025 protected override async Task AuthenticateCoreAsync() { - if (_logger.IsEnabled(LogLevel.Debug)) - { - _logger.LogDebug(Resources.OIDCH_0000_AuthenticateCoreAsync, this.GetType()); - } + Logger.LogDebug(Resources.OIDCH_0000_AuthenticateCoreAsync, this.GetType()); // Allow login to be constrained to a specific path. Need to make this runtime configurable. if (Options.CallbackPath.HasValue && Options.CallbackPath != (Request.PathBase + Request.Path)) @@ -271,7 +255,7 @@ protected override async Task AuthenticateCoreAsync() && Request.ContentType.StartsWith("application/x-www-form-urlencoded", StringComparison.OrdinalIgnoreCase) && Request.Body.CanRead) { - IFormCollection form = await Request.ReadFormAsync(); + var form = await Request.ReadFormAsync(); Request.Body.Seek(0, SeekOrigin.Begin); message = new OpenIdConnectMessage(form); } @@ -283,9 +267,9 @@ protected override async Task AuthenticateCoreAsync() try { - if (_logger.IsEnabled(LogLevel.Debug)) + if (Logger.IsEnabled(LogLevel.Debug)) { - _logger.LogDebug(Resources.OIDCH_0001_MessageReceived, message.BuildRedirectUrl()); + Logger.LogDebug(Resources.OIDCH_0001_MessageReceived, message.BuildRedirectUrl()); } var messageReceivedNotification = @@ -297,34 +281,34 @@ protected override async Task AuthenticateCoreAsync() await Options.Notifications.MessageReceived(messageReceivedNotification); if (messageReceivedNotification.HandledResponse) { - _logger.LogInformation(Resources.OIDCH_0002_MessageReceivedNotificationHandledResponse); + Logger.LogInformation(Resources.OIDCH_0002_MessageReceivedNotificationHandledResponse); return messageReceivedNotification.AuthenticationTicket; } if (messageReceivedNotification.Skipped) { - _logger.LogInformation(Resources.OIDCH_0003_MessageReceivedNotificationSkipped); + Logger.LogInformation(Resources.OIDCH_0003_MessageReceivedNotificationSkipped); return null; } // runtime always adds state, if we don't find it OR we failed to 'unprotect' it this is not a message we should process. if (string.IsNullOrWhiteSpace(message.State)) { - _logger.LogError(Resources.OIDCH_0004_MessageStateIsNullOrWhiteSpace); + Logger.LogError(Resources.OIDCH_0004_MessageStateIsNullOrWhiteSpace); return null; } var properties = GetPropertiesFromState(message.State); if (properties == null) { - _logger.LogError(Resources.OIDCH_0005_MessageStateIsInvalid); + Logger.LogError(Resources.OIDCH_0005_MessageStateIsInvalid); return null; } // devs will need to hook AuthenticationFailedNotification to avoid having 'raw' runtime errors displayed to users. if (!string.IsNullOrWhiteSpace(message.Error)) { - _logger.LogError(Resources.OIDCH_0006_MessageErrorNotNull, message.Error); + Logger.LogError(Resources.OIDCH_0006_MessageErrorNotNull, message.Error); throw new OpenIdConnectProtocolException(string.Format(CultureInfo.InvariantCulture, Resources.OIDCH_0006_MessageErrorNotNull, message.Error)); } @@ -333,14 +317,14 @@ protected override async Task AuthenticateCoreAsync() if (_configuration == null && Options.ConfigurationManager != null) { - _logger.LogDebug(Resources.OIDCH_0007_UpdatingConfiguration); + Logger.LogDebug(Resources.OIDCH_0007_UpdatingConfiguration); _configuration = await Options.ConfigurationManager.GetConfigurationAsync(Context.RequestAborted); } // OpenIdConnect protocol allows a Code to be received without the id_token if (!string.IsNullOrWhiteSpace(message.IdToken)) { - _logger.LogDebug(Resources.OIDCH_0020_IdTokenReceived, message.IdToken); + Logger.LogDebug(Resources.OIDCH_0020_IdTokenReceived, message.IdToken); var securityTokenReceivedNotification = new SecurityTokenReceivedNotification(Context, Options) { @@ -350,18 +334,18 @@ protected override async Task AuthenticateCoreAsync() await Options.Notifications.SecurityTokenReceived(securityTokenReceivedNotification); if (securityTokenReceivedNotification.HandledResponse) { - _logger.LogInformation(Resources.OIDCH_0008_SecurityTokenReceivedNotificationHandledResponse); + Logger.LogInformation(Resources.OIDCH_0008_SecurityTokenReceivedNotificationHandledResponse); return securityTokenReceivedNotification.AuthenticationTicket; } if (securityTokenReceivedNotification.Skipped) { - _logger.LogInformation(Resources.OIDCH_0009_SecurityTokenReceivedNotificationSkipped); + Logger.LogInformation(Resources.OIDCH_0009_SecurityTokenReceivedNotificationSkipped); return null; } // Copy and augment to avoid cross request race conditions for updated configurations. - TokenValidationParameters validationParameters = Options.TokenValidationParameters.Clone(); + var validationParameters = Options.TokenValidationParameters.Clone(); if (_configuration != null) { if (string.IsNullOrWhiteSpace(validationParameters.ValidIssuer)) @@ -386,7 +370,7 @@ protected override async Task AuthenticateCoreAsync() jwt = validatedToken as JwtSecurityToken; if (jwt == null) { - _logger.LogError(Resources.OIDCH_0010_ValidatedSecurityTokenNotJwt, validatedToken?.GetType()); + Logger.LogError(Resources.OIDCH_0010_ValidatedSecurityTokenNotJwt, validatedToken?.GetType()); throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, Resources.OIDCH_0010_ValidatedSecurityTokenNotJwt, validatedToken?.GetType())); } } @@ -394,7 +378,7 @@ protected override async Task AuthenticateCoreAsync() if (validatedToken == null) { - _logger.LogError(Resources.OIDCH_0011_UnableToValidateToken, message.IdToken); + Logger.LogError(Resources.OIDCH_0011_UnableToValidateToken, message.IdToken); throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, Resources.OIDCH_0011_UnableToValidateToken, message.IdToken)); } @@ -412,13 +396,13 @@ protected override async Task AuthenticateCoreAsync() // Rename? if (Options.UseTokenLifetime) { - DateTime issued = validatedToken.ValidFrom; + var issued = validatedToken.ValidFrom; if (issued != DateTime.MinValue) { ticket.Properties.IssuedUtc = issued; } - DateTime expires = validatedToken.ValidTo; + var expires = validatedToken.ValidTo; if (expires != DateTime.MinValue) { ticket.Properties.ExpiresUtc = expires; @@ -435,13 +419,13 @@ protected override async Task AuthenticateCoreAsync() await Options.Notifications.SecurityTokenValidated(securityTokenValidatedNotification); if (securityTokenValidatedNotification.HandledResponse) { - _logger.LogInformation(Resources.OIDCH_0012_SecurityTokenValidatedNotificationHandledResponse); + Logger.LogInformation(Resources.OIDCH_0012_SecurityTokenValidatedNotificationHandledResponse); return securityTokenValidatedNotification.AuthenticationTicket; } if (securityTokenValidatedNotification.Skipped) { - _logger.LogInformation(Resources.OIDCH_0013_SecurityTokenValidatedNotificationSkipped); + Logger.LogInformation(Resources.OIDCH_0013_SecurityTokenValidatedNotificationSkipped); return null; } @@ -470,7 +454,7 @@ protected override async Task AuthenticateCoreAsync() if (message.Code != null) { - _logger.LogDebug(Resources.OIDCH_0014_CodeReceived, message.Code); + Logger.LogDebug(Resources.OIDCH_0014_CodeReceived, message.Code); if (ticket == null) { ticket = new AuthenticationTicket(properties, Options.AuthenticationScheme); @@ -489,13 +473,13 @@ protected override async Task AuthenticateCoreAsync() await Options.Notifications.AuthorizationCodeReceived(authorizationCodeReceivedNotification); if (authorizationCodeReceivedNotification.HandledResponse) { - _logger.LogInformation(Resources.OIDCH_0015_CodeReceivedNotificationHandledResponse); + Logger.LogInformation(Resources.OIDCH_0015_CodeReceivedNotificationHandledResponse); return authorizationCodeReceivedNotification.AuthenticationTicket; } if (authorizationCodeReceivedNotification.Skipped) { - _logger.LogInformation(Resources.OIDCH_0016_CodeReceivedNotificationSkipped); + Logger.LogInformation(Resources.OIDCH_0016_CodeReceivedNotificationSkipped); return null; } } @@ -504,7 +488,7 @@ protected override async Task AuthenticateCoreAsync() } catch (Exception exception) { - _logger.LogError(Resources.OIDCH_0017_ExceptionOccurredWhileProcessingMessage, exception); + Logger.LogError(Resources.OIDCH_0017_ExceptionOccurredWhileProcessingMessage, exception); // Refresh the configuration for exceptions that may be caused by key rollovers. The user can also request a refresh in the notification. if (Options.RefreshOnIssuerKeyNotFound && exception.GetType().Equals(typeof(SecurityTokenSignatureKeyNotFoundException))) @@ -522,13 +506,13 @@ protected override async Task AuthenticateCoreAsync() await Options.Notifications.AuthenticationFailed(authenticationFailedNotification); if (authenticationFailedNotification.HandledResponse) { - _logger.LogInformation(Resources.OIDCH_0018_AuthenticationFailedNotificationHandledResponse); + Logger.LogInformation(Resources.OIDCH_0018_AuthenticationFailedNotificationHandledResponse); return authenticationFailedNotification.AuthenticationTicket; } if (authenticationFailedNotification.Skipped) { - _logger.LogInformation(Resources.OIDCH_0019_AuthenticationFailedNotificationSkipped); + Logger.LogInformation(Resources.OIDCH_0019_AuthenticationFailedNotificationSkipped); return null; } @@ -579,7 +563,7 @@ private string ReadNonceCookie(string nonce) { try { - string nonceDecodedValue = Options.StringDataFormat.Unprotect(nonceKey.Substring(OpenIdConnectAuthenticationDefaults.CookieNoncePrefix.Length, nonceKey.Length - OpenIdConnectAuthenticationDefaults.CookieNoncePrefix.Length)); + var nonceDecodedValue = Options.StringDataFormat.Unprotect(nonceKey.Substring(OpenIdConnectAuthenticationDefaults.CookieNoncePrefix.Length, nonceKey.Length - OpenIdConnectAuthenticationDefaults.CookieNoncePrefix.Length)); if (nonceDecodedValue == nonce) { var cookieOptions = new CookieOptions @@ -594,7 +578,7 @@ private string ReadNonceCookie(string nonce) } catch (Exception ex) { - _logger.LogWarning("Failed to un-protect the nonce cookie.", ex); + Logger.LogWarning("Failed to un-protect the nonce cookie.", ex); } } } @@ -605,13 +589,13 @@ private string ReadNonceCookie(string nonce) private AuthenticationProperties GetPropertiesFromState(string state) { // assume a well formed query string: OpenIdConnectAuthenticationDefaults.AuthenticationPropertiesKey=kasjd;fljasldkjflksdj<&c=d> - int startIndex = 0; + var startIndex = 0; if (string.IsNullOrWhiteSpace(state) || (startIndex = state.IndexOf(OpenIdConnectAuthenticationDefaults.AuthenticationPropertiesKey, StringComparison.Ordinal)) == -1) { return null; } - int authenticationIndex = startIndex + OpenIdConnectAuthenticationDefaults.AuthenticationPropertiesKey.Length; + var authenticationIndex = startIndex + OpenIdConnectAuthenticationDefaults.AuthenticationPropertiesKey.Length; if (authenticationIndex == -1 || authenticationIndex == state.Length || state[authenticationIndex] != '=') { return null; @@ -619,7 +603,7 @@ private AuthenticationProperties GetPropertiesFromState(string state) // scan rest of string looking for '&' authenticationIndex++; - int endIndex = state.Substring(authenticationIndex, state.Length - authenticationIndex).IndexOf("&", StringComparison.Ordinal); + var endIndex = state.Substring(authenticationIndex, state.Length - authenticationIndex).IndexOf("&", StringComparison.Ordinal); // -1 => no other parameters are after the AuthenticationPropertiesKey if (endIndex == -1) @@ -643,8 +627,7 @@ public override Task InvokeAsync() private async Task InvokeReplyPathAsync() { - AuthenticationTicket ticket = await AuthenticateAsync(); - + var ticket = await AuthenticateAsync(); if (ticket != null) { if (ticket.Principal != null) diff --git a/src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenIdConnectAuthenticationMiddleware.cs b/src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenIdConnectAuthenticationMiddleware.cs index ee8eec0e5..46524c17c 100644 --- a/src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenIdConnectAuthenticationMiddleware.cs +++ b/src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenIdConnectAuthenticationMiddleware.cs @@ -25,8 +25,6 @@ namespace Microsoft.AspNet.Authentication.OpenIdConnect /// public class OpenIdConnectAuthenticationMiddleware : AuthenticationMiddleware { - private readonly ILogger _logger; - /// /// Initializes a /// @@ -45,9 +43,8 @@ public OpenIdConnectAuthenticationMiddleware( [NotNull] IOptions externalOptions, [NotNull] IOptions options, ConfigureOptions configureOptions = null) - : base(next, options, configureOptions) + : base(next, options, loggerFactory, configureOptions) { - _logger = loggerFactory.CreateLogger(); if (string.IsNullOrEmpty(Options.SignInScheme) && !string.IsNullOrEmpty(externalOptions.Options.SignInScheme)) { Options.SignInScheme = externalOptions.Options.SignInScheme; @@ -120,7 +117,7 @@ public OpenIdConnectAuthenticationMiddleware( Options.MetadataAddress += ".well-known/openid-configuration"; } - HttpClient httpClient = new HttpClient(ResolveHttpMessageHandler(Options)); + var httpClient = new HttpClient(ResolveHttpMessageHandler(Options)); httpClient.Timeout = Options.BackchannelTimeout; httpClient.MaxResponseContentBufferSize = 1024 * 1024 * 10; // 10 MB Options.ConfigurationManager = new ConfigurationManager(Options.MetadataAddress, httpClient); @@ -134,13 +131,13 @@ public OpenIdConnectAuthenticationMiddleware( /// An configured with the supplied to the constructor. protected override AuthenticationHandler CreateHandler() { - return new OpenIdConnectAuthenticationHandler(_logger); + return new OpenIdConnectAuthenticationHandler(); } [SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Justification = "Managed by caller")] private static HttpMessageHandler ResolveHttpMessageHandler(OpenIdConnectAuthenticationOptions options) { - HttpMessageHandler handler = options.BackchannelHttpHandler ?? + var handler = options.BackchannelHttpHandler ?? #if DNX451 new WebRequestHandler(); // If they provided a validator, apply it or fail. diff --git a/src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenIdConnectAuthenticationOptions.cs b/src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenIdConnectAuthenticationOptions.cs index e5a3793d3..4a306c731 100644 --- a/src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenIdConnectAuthenticationOptions.cs +++ b/src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenIdConnectAuthenticationOptions.cs @@ -38,7 +38,6 @@ public OpenIdConnectAuthenticationOptions() /// /// Defaults: /// AddNonceToRequest: true. - /// AuthenticationMode: . /// BackchannelTimeout: 1 minute. /// Caption: . /// ProtocolValidator: new . diff --git a/src/Microsoft.AspNet.Authentication.Twitter/TwitterAuthenticationHandler.cs b/src/Microsoft.AspNet.Authentication.Twitter/TwitterAuthenticationHandler.cs index dc0d7fc8d..cbc48910c 100644 --- a/src/Microsoft.AspNet.Authentication.Twitter/TwitterAuthenticationHandler.cs +++ b/src/Microsoft.AspNet.Authentication.Twitter/TwitterAuthenticationHandler.cs @@ -12,7 +12,6 @@ using Microsoft.AspNet.Http; using Microsoft.AspNet.Http.Collections; using Microsoft.AspNet.Http.Authentication; -using Microsoft.AspNet.Authentication; using Microsoft.AspNet.Authentication.Twitter.Messages; using Microsoft.AspNet.WebUtilities; using Microsoft.Framework.Logging; @@ -28,12 +27,10 @@ internal class TwitterAuthenticationHandler : AuthenticationHandler InvokeAsync() @@ -55,40 +52,40 @@ protected override async Task AuthenticateCoreAsync() AuthenticationProperties properties = null; try { - IReadableStringCollection query = Request.Query; - string protectedRequestToken = Request.Cookies[StateCookie]; + var query = Request.Query; + var protectedRequestToken = Request.Cookies[StateCookie]; - RequestToken requestToken = Options.StateDataFormat.Unprotect(protectedRequestToken); + var requestToken = Options.StateDataFormat.Unprotect(protectedRequestToken); if (requestToken == null) { - _logger.LogWarning("Invalid state"); + Logger.LogWarning("Invalid state"); return null; } properties = requestToken.Properties; - string returnedToken = query.Get("oauth_token"); + var returnedToken = query.Get("oauth_token"); if (string.IsNullOrWhiteSpace(returnedToken)) { - _logger.LogWarning("Missing oauth_token"); + Logger.LogWarning("Missing oauth_token"); return new AuthenticationTicket(properties, Options.AuthenticationScheme); } if (returnedToken != requestToken.Token) { - _logger.LogWarning("Unmatched token"); + Logger.LogWarning("Unmatched token"); return new AuthenticationTicket(properties, Options.AuthenticationScheme); } string oauthVerifier = query.Get("oauth_verifier"); if (string.IsNullOrWhiteSpace(oauthVerifier)) { - _logger.LogWarning("Missing or blank oauth_verifier"); + Logger.LogWarning("Missing or blank oauth_verifier"); return new AuthenticationTicket(properties, Options.AuthenticationScheme); } - AccessToken accessToken = await ObtainAccessTokenAsync(Options.ConsumerKey, Options.ConsumerSecret, requestToken, oauthVerifier); + var accessToken = await ObtainAccessTokenAsync(Options.ConsumerKey, Options.ConsumerSecret, requestToken, oauthVerifier); var context = new TwitterAuthenticatedContext(Context, accessToken.UserId, accessToken.ScreenName, accessToken.Token, accessToken.TokenSecret); @@ -120,7 +117,7 @@ protected override async Task AuthenticateCoreAsync() } catch (Exception ex) { - _logger.LogError("Authentication failed", ex); + Logger.LogError("Authentication failed", ex); return new AuthenticationTicket(properties, Options.AuthenticationScheme); } } @@ -148,8 +145,8 @@ protected override async Task ApplyResponseChallengeAsync() return; } - string requestPrefix = Request.Scheme + "://" + Request.Host; - string callBackUrl = requestPrefix + RequestPathBase + Options.CallbackPath; + var requestPrefix = Request.Scheme + "://" + Request.Host; + var callBackUrl = requestPrefix + RequestPathBase + Options.CallbackPath; AuthenticationProperties properties; if (ChallengeContext == null) @@ -165,11 +162,11 @@ protected override async Task ApplyResponseChallengeAsync() properties.RedirectUri = requestPrefix + Request.PathBase + Request.Path + Request.QueryString; } - RequestToken requestToken = await ObtainRequestTokenAsync(Options.ConsumerKey, Options.ConsumerSecret, callBackUrl, properties); + var requestToken = await ObtainRequestTokenAsync(Options.ConsumerKey, Options.ConsumerSecret, callBackUrl, properties); if (requestToken.CallbackConfirmed) { - string twitterAuthenticationEndpoint = AuthenticationEndpoint + requestToken.Token; + var twitterAuthenticationEndpoint = AuthenticationEndpoint + requestToken.Token; var cookieOptions = new CookieOptions { @@ -186,16 +183,16 @@ protected override async Task ApplyResponseChallengeAsync() } else { - _logger.LogError("requestToken CallbackConfirmed!=true"); + Logger.LogError("requestToken CallbackConfirmed!=true"); } } public async Task InvokeReturnPathAsync() { - AuthenticationTicket model = await AuthenticateAsync(); + var model = await AuthenticateAsync(); if (model == null) { - _logger.LogWarning("Invalid return state, unable to redirect."); + Logger.LogWarning("Invalid return state, unable to redirect."); Response.StatusCode = 500; return true; } @@ -230,9 +227,9 @@ public async Task InvokeReturnPathAsync() private async Task ObtainRequestTokenAsync(string consumerKey, string consumerSecret, string callBackUri, AuthenticationProperties properties) { - _logger.LogVerbose("ObtainRequestToken"); + Logger.LogVerbose("ObtainRequestToken"); - string nonce = Guid.NewGuid().ToString("N"); + var nonce = Guid.NewGuid().ToString("N"); var authorizationParts = new SortedDictionary { @@ -250,7 +247,7 @@ private async Task ObtainRequestTokenAsync(string consumerKey, str parameterBuilder.AppendFormat("{0}={1}&", Uri.EscapeDataString(authorizationKey.Key), Uri.EscapeDataString(authorizationKey.Value)); } parameterBuilder.Length--; - string parameterString = parameterBuilder.ToString(); + var parameterString = parameterBuilder.ToString(); var canonicalizedRequestBuilder = new StringBuilder(); canonicalizedRequestBuilder.Append(HttpMethod.Post.Method); @@ -259,7 +256,7 @@ private async Task ObtainRequestTokenAsync(string consumerKey, str canonicalizedRequestBuilder.Append("&"); canonicalizedRequestBuilder.Append(Uri.EscapeDataString(parameterString)); - string signature = ComputeSignature(consumerSecret, null, canonicalizedRequestBuilder.ToString()); + var signature = ComputeSignature(consumerSecret, null, canonicalizedRequestBuilder.ToString()); authorizationParts.Add("oauth_signature", signature); var authorizationHeaderBuilder = new StringBuilder(); @@ -274,11 +271,11 @@ private async Task ObtainRequestTokenAsync(string consumerKey, str var request = new HttpRequestMessage(HttpMethod.Post, RequestTokenEndpoint); request.Headers.Add("Authorization", authorizationHeaderBuilder.ToString()); - HttpResponseMessage response = await _httpClient.SendAsync(request, Context.RequestAborted); + var response = await _httpClient.SendAsync(request, Context.RequestAborted); response.EnsureSuccessStatusCode(); string responseText = await response.Content.ReadAsStringAsync(); - IFormCollection responseParameters = new FormCollection(FormReader.ReadForm(responseText)); + var responseParameters = new FormCollection(FormReader.ReadForm(responseText)); if (string.Equals(responseParameters["oauth_callback_confirmed"], "true", StringComparison.Ordinal)) { return new RequestToken { Token = Uri.UnescapeDataString(responseParameters["oauth_token"]), TokenSecret = Uri.UnescapeDataString(responseParameters["oauth_token_secret"]), CallbackConfirmed = true, Properties = properties }; @@ -291,9 +288,9 @@ private async Task ObtainAccessTokenAsync(string consumerKey, strin { // https://dev.twitter.com/docs/api/1/post/oauth/access_token - _logger.LogVerbose("ObtainAccessToken"); + Logger.LogVerbose("ObtainAccessToken"); - string nonce = Guid.NewGuid().ToString("N"); + var nonce = Guid.NewGuid().ToString("N"); var authorizationParts = new SortedDictionary { @@ -312,7 +309,7 @@ private async Task ObtainAccessTokenAsync(string consumerKey, strin parameterBuilder.AppendFormat("{0}={1}&", Uri.EscapeDataString(authorizationKey.Key), Uri.EscapeDataString(authorizationKey.Value)); } parameterBuilder.Length--; - string parameterString = parameterBuilder.ToString(); + var parameterString = parameterBuilder.ToString(); var canonicalizedRequestBuilder = new StringBuilder(); canonicalizedRequestBuilder.Append(HttpMethod.Post.Method); @@ -321,7 +318,7 @@ private async Task ObtainAccessTokenAsync(string consumerKey, strin canonicalizedRequestBuilder.Append("&"); canonicalizedRequestBuilder.Append(Uri.EscapeDataString(parameterString)); - string signature = ComputeSignature(consumerSecret, token.TokenSecret, canonicalizedRequestBuilder.ToString()); + var signature = ComputeSignature(consumerSecret, token.TokenSecret, canonicalizedRequestBuilder.ToString()); authorizationParts.Add("oauth_signature", signature); authorizationParts.Remove("oauth_verifier"); @@ -344,17 +341,16 @@ private async Task ObtainAccessTokenAsync(string consumerKey, strin request.Content = new FormUrlEncodedContent(formPairs); - HttpResponseMessage response = await _httpClient.SendAsync(request, Context.RequestAborted); + var response = await _httpClient.SendAsync(request, Context.RequestAborted); if (!response.IsSuccessStatusCode) { - _logger.LogError("AccessToken request failed with a status code of " + response.StatusCode); + Logger.LogError("AccessToken request failed with a status code of " + response.StatusCode); response.EnsureSuccessStatusCode(); // throw } - string responseText = await response.Content.ReadAsStringAsync(); - - IFormCollection responseParameters = new FormCollection(FormReader.ReadForm(responseText)); + var responseText = await response.Content.ReadAsStringAsync(); + var responseParameters = new FormCollection(FormReader.ReadForm(responseText)); return new AccessToken { @@ -367,7 +363,7 @@ private async Task ObtainAccessTokenAsync(string consumerKey, strin private static string GenerateTimeStamp() { - TimeSpan secondsSinceUnixEpocStart = DateTime.UtcNow - Epoch; + var secondsSinceUnixEpocStart = DateTime.UtcNow - Epoch; return Convert.ToInt64(secondsSinceUnixEpocStart.TotalSeconds).ToString(CultureInfo.InvariantCulture); } @@ -380,7 +376,7 @@ private static string ComputeSignature(string consumerSecret, string tokenSecret "{0}&{1}", Uri.EscapeDataString(consumerSecret), string.IsNullOrEmpty(tokenSecret) ? string.Empty : Uri.EscapeDataString(tokenSecret))); - byte[] hash = algorithm.ComputeHash(Encoding.ASCII.GetBytes(signatureData)); + var hash = algorithm.ComputeHash(Encoding.ASCII.GetBytes(signatureData)); return Convert.ToBase64String(hash); } } @@ -390,4 +386,4 @@ protected override void ApplyResponseGrant() // N/A - No SignIn or SignOut support. } } -} +} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Authentication.Twitter/TwitterAuthenticationMiddleware.cs b/src/Microsoft.AspNet.Authentication.Twitter/TwitterAuthenticationMiddleware.cs index 63534a85f..145cf4cad 100644 --- a/src/Microsoft.AspNet.Authentication.Twitter/TwitterAuthenticationMiddleware.cs +++ b/src/Microsoft.AspNet.Authentication.Twitter/TwitterAuthenticationMiddleware.cs @@ -22,7 +22,6 @@ namespace Microsoft.AspNet.Authentication.Twitter [SuppressMessage("Microsoft.Design", "CA1001:TypesThatOwnDisposableFieldsShouldBeDisposable", Justification = "Middleware are not disposable.")] public class TwitterAuthenticationMiddleware : AuthenticationMiddleware { - private readonly ILogger _logger; private readonly HttpClient _httpClient; /// @@ -40,7 +39,7 @@ public TwitterAuthenticationMiddleware( [NotNull] IOptions externalOptions, [NotNull] IOptions options, ConfigureOptions configureOptions = null) - : base(next, options, configureOptions) + : base(next, options, loggerFactory, configureOptions) { if (string.IsNullOrWhiteSpace(Options.ConsumerSecret)) { @@ -51,8 +50,6 @@ public TwitterAuthenticationMiddleware( throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, Resources.Exception_OptionMustBeProvided, "ConsumerKey")); } - _logger = loggerFactory.CreateLogger(typeof(TwitterAuthenticationMiddleware).FullName); - if (Options.Notifications == null) { Options.Notifications = new TwitterAuthenticationNotifications(); @@ -90,7 +87,7 @@ public TwitterAuthenticationMiddleware( /// An configured with the supplied to the constructor. protected override AuthenticationHandler CreateHandler() { - return new TwitterAuthenticationHandler(_httpClient, _logger); + return new TwitterAuthenticationHandler(_httpClient); } [SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Justification = "Managed by caller")] diff --git a/src/Microsoft.AspNet.Authentication/AuthenticationHandler.cs b/src/Microsoft.AspNet.Authentication/AuthenticationHandler.cs index 318d0ad73..7d412d28a 100644 --- a/src/Microsoft.AspNet.Authentication/AuthenticationHandler.cs +++ b/src/Microsoft.AspNet.Authentication/AuthenticationHandler.cs @@ -2,8 +2,6 @@ // 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.Linq; using System.Security.Cryptography; using System.Threading; using System.Threading.Tasks; @@ -50,6 +48,8 @@ protected HttpResponse Response protected PathString RequestPathBase { get; private set; } + protected ILogger Logger { get; private set; } + internal AuthenticationOptions BaseOptions { get { return _baseOptions; } @@ -61,11 +61,12 @@ internal AuthenticationOptions BaseOptions public bool Faulted { get; set; } - protected async Task BaseInitializeAsync(AuthenticationOptions options, HttpContext context) + protected async Task BaseInitializeAsync([NotNull] AuthenticationOptions options, [NotNull] HttpContext context, [NotNull] ILogger logger) { _baseOptions = options; Context = context; RequestPathBase = Request.PathBase; + Logger = logger; RegisterAuthenticationHandler(); @@ -414,13 +415,13 @@ protected void GenerateCorrelationId([NotNull] AuthenticationProperties properti Response.Cookies.Append(correlationKey, correlationId, cookieOptions); } - protected bool ValidateCorrelationId([NotNull] AuthenticationProperties properties, [NotNull] ILogger logger) + protected bool ValidateCorrelationId([NotNull] AuthenticationProperties properties) { var correlationKey = Constants.CorrelationPrefix + BaseOptions.AuthenticationScheme; var correlationCookie = Request.Cookies[correlationKey]; if (string.IsNullOrWhiteSpace(correlationCookie)) { - logger.LogWarning("{0} cookie not found.", correlationKey); + Logger.LogWarning("{0} cookie not found.", correlationKey); return false; } @@ -436,7 +437,7 @@ protected bool ValidateCorrelationId([NotNull] AuthenticationProperties properti correlationKey, out correlationExtra)) { - logger.LogWarning("{0} state property not found.", correlationKey); + Logger.LogWarning("{0} state property not found.", correlationKey); return false; } @@ -444,7 +445,7 @@ protected bool ValidateCorrelationId([NotNull] AuthenticationProperties properti if (!string.Equals(correlationCookie, correlationExtra, StringComparison.Ordinal)) { - logger.LogWarning("{0} correlation cookie and state property mismatch.", correlationKey); + Logger.LogWarning("{0} correlation cookie and state property mismatch.", correlationKey); return false; } @@ -464,5 +465,4 @@ private void UnregisterAuthenticationHandler() auth.Handler = PriorHandler; } } -} - +} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Authentication/AuthenticationHandler`1.cs b/src/Microsoft.AspNet.Authentication/AuthenticationHandler`1.cs index a70b11c60..973f9f00f 100644 --- a/src/Microsoft.AspNet.Authentication/AuthenticationHandler`1.cs +++ b/src/Microsoft.AspNet.Authentication/AuthenticationHandler`1.cs @@ -3,6 +3,7 @@ using System.Threading.Tasks; using Microsoft.AspNet.Http; +using Microsoft.Framework.Logging; namespace Microsoft.AspNet.Authentication { @@ -19,11 +20,12 @@ public abstract class AuthenticationHandler : AuthenticationHandler wh /// /// The original options passed by the application control behavior /// The utility object to observe the current request and response + /// The logging factory used to create loggers /// async completion - public Task Initialize(TOptions options, HttpContext context) + public Task Initialize(TOptions options, HttpContext context, ILogger logger) { Options = options; - return BaseInitializeAsync(options, context); + return BaseInitializeAsync(options, context, logger); } } } diff --git a/src/Microsoft.AspNet.Authentication/AuthenticationMiddleware.cs b/src/Microsoft.AspNet.Authentication/AuthenticationMiddleware.cs index b9eaa36f8..cdb6fbdf8 100644 --- a/src/Microsoft.AspNet.Authentication/AuthenticationMiddleware.cs +++ b/src/Microsoft.AspNet.Authentication/AuthenticationMiddleware.cs @@ -6,6 +6,7 @@ using Microsoft.AspNet.Builder; using Microsoft.AspNet.Http; using Microsoft.Framework.Internal; +using Microsoft.Framework.Logging; using Microsoft.Framework.OptionsModel; namespace Microsoft.AspNet.Authentication @@ -17,6 +18,7 @@ namespace Microsoft.AspNet.Authentication protected AuthenticationMiddleware( [NotNull] RequestDelegate next, [NotNull] IOptions options, + [NotNull] ILoggerFactory loggerFactory, ConfigureOptions configureOptions) { if (configureOptions != null) @@ -28,6 +30,8 @@ protected AuthenticationMiddleware( { Options = options.Options; } + Logger = loggerFactory.CreateLogger(this.GetType().FullName); + _next = next; } @@ -35,10 +39,12 @@ protected AuthenticationMiddleware( public TOptions Options { get; set; } + public ILogger Logger { get; set; } + public async Task Invoke(HttpContext context) { - AuthenticationHandler handler = CreateHandler(); - await handler.Initialize(Options, context); + var handler = CreateHandler(); + await handler.Initialize(Options, context, Logger); try { if (!await handler.InvokeAsync()) diff --git a/src/Microsoft.AspNet.Authorization/AuthorizationPolicy.cs b/src/Microsoft.AspNet.Authorization/AuthorizationPolicy.cs index 2ade0a15f..02769a8dd 100644 --- a/src/Microsoft.AspNet.Authorization/AuthorizationPolicy.cs +++ b/src/Microsoft.AspNet.Authorization/AuthorizationPolicy.cs @@ -75,4 +75,4 @@ public static AuthorizationPolicy Combine([NotNull] AuthorizationOptions options return any ? policyBuilder.Build() : null; } } -} +} \ No newline at end of file diff --git a/test/Microsoft.AspNet.Authentication.Test/AuthenticationHandlerFacts.cs b/test/Microsoft.AspNet.Authentication.Test/AuthenticationHandlerFacts.cs index ba23fea2b..cf628db54 100644 --- a/test/Microsoft.AspNet.Authentication.Test/AuthenticationHandlerFacts.cs +++ b/test/Microsoft.AspNet.Authentication.Test/AuthenticationHandlerFacts.cs @@ -3,6 +3,7 @@ using System; using Microsoft.AspNet.Http; +using Microsoft.Framework.Logging; using Xunit; namespace Microsoft.AspNet.Authentication @@ -13,12 +14,10 @@ public class AuthenticationHandlerFacts public void ShouldHandleSchemeAreDeterminedOnlyByMatchingAuthenticationScheme() { var handler = new TestHandler("Alpha"); - - bool passiveNoMatch = handler.ShouldHandleScheme("Beta"); + var passiveNoMatch = handler.ShouldHandleScheme("Beta"); handler = new TestHandler("Alpha"); - - bool passiveWithMatch = handler.ShouldHandleScheme("Alpha"); + var passiveWithMatch = handler.ShouldHandleScheme("Alpha"); Assert.False(passiveNoMatch); Assert.True(passiveWithMatch); @@ -56,7 +55,7 @@ private class TestHandler : AuthenticationHandler { public TestHandler(string scheme) { - Initialize(new TestOptions(), new DefaultHttpContext()); + Initialize(new TestOptions(), new DefaultHttpContext(), new LoggerFactory().CreateLogger("TestHandler")); Options.AuthenticationScheme = scheme; } @@ -90,7 +89,7 @@ private class TestAutoHandler : AuthenticationHandler { public TestAutoHandler(string scheme, bool auto) { - Initialize(new TestAutoOptions(), new DefaultHttpContext()); + Initialize(new TestAutoOptions(), new DefaultHttpContext(), new LoggerFactory().CreateLogger("TestHandler")); Options.AuthenticationScheme = scheme; Options.AutomaticAuthentication = auto; } diff --git a/test/Microsoft.AspNet.Authentication.Test/Google/GoogleMiddlewareTests.cs b/test/Microsoft.AspNet.Authentication.Test/Google/GoogleMiddlewareTests.cs index a37dfe6d2..76db1debb 100644 --- a/test/Microsoft.AspNet.Authentication.Test/Google/GoogleMiddlewareTests.cs +++ b/test/Microsoft.AspNet.Authentication.Test/Google/GoogleMiddlewareTests.cs @@ -226,6 +226,8 @@ public async Task ReplyPathWithoutStateQueryStringWillBeRejected() transaction.Response.StatusCode.ShouldBe(HttpStatusCode.InternalServerError); } + + [Fact] public async Task ReplyPathWillAuthenticateValidAuthorizeCodeAndState() { diff --git a/test/Microsoft.AspNet.Authentication.Test/OpenIdConnect/OpenIdConnectHandlerTests.cs b/test/Microsoft.AspNet.Authentication.Test/OpenIdConnect/OpenIdConnectHandlerTests.cs index c31cdc657..c3dbece13 100644 --- a/test/Microsoft.AspNet.Authentication.Test/OpenIdConnect/OpenIdConnectHandlerTests.cs +++ b/test/Microsoft.AspNet.Authentication.Test/OpenIdConnect/OpenIdConnectHandlerTests.cs @@ -565,14 +565,9 @@ public override void Configure(OpenIdConnectAuthenticationOptions options, strin /// public class CustomOpenIdConnectAuthenticationHandler : OpenIdConnectAuthenticationHandler { - public CustomOpenIdConnectAuthenticationHandler(ILogger logger) - : base(logger) + public async Task BaseInitializeAsyncPublic(AuthenticationOptions options, HttpContext context, ILogger logger) { - } - - public async Task BaseInitializeAsyncPublic(AuthenticationOptions options, HttpContext context) - { - await base.BaseInitializeAsync(options, context); + await base.BaseInitializeAsync(options, context, logger); } public override bool ShouldHandleScheme(string authenticationScheme) @@ -619,13 +614,7 @@ public CustomOpenIdConnectAuthenticationMiddleware( protected override AuthenticationHandler CreateHandler() { - return new CustomOpenIdConnectAuthenticationHandler(Logger); - } - - public ILogger Logger - { - get; - set; + return new CustomOpenIdConnectAuthenticationHandler(); } } diff --git a/test/Microsoft.AspNet.Authorization.Test/Microsoft.AspNet.Authorization.Test.xproj b/test/Microsoft.AspNet.Authorization.Test/Microsoft.AspNet.Authorization.Test.xproj index 0e8a98e2a..579dd0f44 100644 --- a/test/Microsoft.AspNet.Authorization.Test/Microsoft.AspNet.Authorization.Test.xproj +++ b/test/Microsoft.AspNet.Authorization.Test/Microsoft.AspNet.Authorization.Test.xproj @@ -13,5 +13,8 @@ 2.0 + + + \ No newline at end of file From 87c31c5526edee557997f03c7b13d46cb5d1d893 Mon Sep 17 00:00:00 2001 From: Hao Kung Date: Thu, 23 Apr 2015 22:49:47 -0700 Subject: [PATCH 195/216] Switch to IUrlEncoder, introduce AddAuthentication --- samples/CookieSample/Startup.cs | 3 +-- samples/CookieSessionSample/Startup.cs | 3 +-- samples/OpenIdConnectSample/Startup.cs | 3 +-- samples/SocialSample/Startup.cs | 11 ++++---- .../CookieAuthenticationMiddleware.cs | 2 +- .../CookieServiceCollectionExtensions.cs | 2 -- .../FacebookAuthenticationHandler.cs | 9 +++---- .../FacebookAuthenticationMiddleware.cs | 4 ++- .../GoogleAuthenticationMiddleware.cs | 4 ++- ...icrosoftAccountAuthenticationMiddleware.cs | 4 ++- .../OAuthAuthenticationMiddleware.cs | 4 ++- .../OAuthBearerAuthenticationMiddleware.cs | 4 ++- .../OpenIdConnectAuthenticationHandler.cs | 2 +- .../OpenIdConnectAuthenticationMiddleware.cs | 4 ++- .../TwitterAuthenticationHandler.cs | 22 ++++++++-------- .../TwitterAuthenticationMiddleware.cs | 4 ++- .../AuthenticationHandler.cs | 6 ++++- .../AuthenticationHandler`1.cs | 5 ++-- .../AuthenticationMiddleware.cs | 7 +++++- ...thenticationServiceCollectionExtensions.cs | 8 +++++- .../project.json | 5 ++-- .../AuthenticationHandlerFacts.cs | 4 +-- .../Cookies/CookieMiddlewareTests.cs | 3 +-- .../Google/GoogleMiddlewareTests.cs | 25 +++++++++---------- ...Microsoft.AspNet.Authentication.Test.xproj | 3 +++ .../MicrosoftAccountMiddlewareTests.cs | 6 ++--- .../OAuthBearer/OAuthBearerMiddlewareTests.cs | 2 +- .../OpenIdConnectHandlerTests.cs | 10 +++++--- .../OpenIdConnectMiddlewareTests.cs | 14 +++++------ .../Twitter/TwitterMiddlewareTests.cs | 3 +-- 30 files changed, 106 insertions(+), 80 deletions(-) diff --git a/samples/CookieSample/Startup.cs b/samples/CookieSample/Startup.cs index cff155a78..3f0919190 100644 --- a/samples/CookieSample/Startup.cs +++ b/samples/CookieSample/Startup.cs @@ -11,8 +11,7 @@ public class Startup { public void ConfigureServices(IServiceCollection services) { - services.AddWebEncoders(); - services.AddDataProtection(); + services.AddAuthentication(); } public void Configure(IApplicationBuilder app, ILoggerFactory loggerfactory) diff --git a/samples/CookieSessionSample/Startup.cs b/samples/CookieSessionSample/Startup.cs index 314ff3782..0f962caed 100644 --- a/samples/CookieSessionSample/Startup.cs +++ b/samples/CookieSessionSample/Startup.cs @@ -12,8 +12,7 @@ public class Startup { public void ConfigureServices(IServiceCollection services) { - services.AddWebEncoders(); - services.AddDataProtection(); + services.AddAuthentication(); } public void Configure(IApplicationBuilder app, ILoggerFactory loggerfactory) diff --git a/samples/OpenIdConnectSample/Startup.cs b/samples/OpenIdConnectSample/Startup.cs index 29b89c824..7c1969d3b 100644 --- a/samples/OpenIdConnectSample/Startup.cs +++ b/samples/OpenIdConnectSample/Startup.cs @@ -13,8 +13,7 @@ public class Startup { public void ConfigureServices(IServiceCollection services) { - services.AddWebEncoders(); - services.AddDataProtection(); + services.AddAuthentication(); services.Configure(options => { options.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme; diff --git a/samples/SocialSample/Startup.cs b/samples/SocialSample/Startup.cs index aea458e1a..4bfc7b659 100644 --- a/samples/SocialSample/Startup.cs +++ b/samples/SocialSample/Startup.cs @@ -19,8 +19,7 @@ public class Startup { public void ConfigureServices(IServiceCollection services) { - services.AddWebEncoders(); - services.AddDataProtection(); + services.AddAuthentication(); services.Configure(options => { options.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme; @@ -139,13 +138,13 @@ dnx . web OnGetUserInformationAsync = async (context) => { // Get the GitHub user - HttpRequestMessage userRequest = new HttpRequestMessage(HttpMethod.Get, context.Options.UserInformationEndpoint); + var userRequest = new HttpRequestMessage(HttpMethod.Get, context.Options.UserInformationEndpoint); userRequest.Headers.Authorization = new AuthenticationHeaderValue("Bearer", context.AccessToken); userRequest.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); - HttpResponseMessage userResponse = await context.Backchannel.SendAsync(userRequest, context.HttpContext.RequestAborted); + var userResponse = await context.Backchannel.SendAsync(userRequest, context.HttpContext.RequestAborted); userResponse.EnsureSuccessStatusCode(); var text = await userResponse.Content.ReadAsStringAsync(); - JObject user = JObject.Parse(text); + var user = JObject.Parse(text); var identity = new ClaimsIdentity( context.Options.AuthenticationScheme, @@ -184,7 +183,7 @@ dnx . web { signoutApp.Run(async context => { - string authType = context.Request.Query["authscheme"]; + var authType = context.Request.Query["authscheme"]; if (!string.IsNullOrEmpty(authType)) { // By default the client will be redirect back to the URL that issued the challenge (/login?authtype=foo), diff --git a/src/Microsoft.AspNet.Authentication.Cookies/CookieAuthenticationMiddleware.cs b/src/Microsoft.AspNet.Authentication.Cookies/CookieAuthenticationMiddleware.cs index 0a5789f7c..2c7743932 100644 --- a/src/Microsoft.AspNet.Authentication.Cookies/CookieAuthenticationMiddleware.cs +++ b/src/Microsoft.AspNet.Authentication.Cookies/CookieAuthenticationMiddleware.cs @@ -22,7 +22,7 @@ public CookieAuthenticationMiddleware( [NotNull] IUrlEncoder urlEncoder, [NotNull] IOptions options, ConfigureOptions configureOptions) - : base(next, options, loggerFactory, configureOptions) + : base(next, options, loggerFactory, urlEncoder, configureOptions) { if (Options.Notifications == null) { diff --git a/src/Microsoft.AspNet.Authentication.Cookies/CookieServiceCollectionExtensions.cs b/src/Microsoft.AspNet.Authentication.Cookies/CookieServiceCollectionExtensions.cs index c0e188eca..af6d4d377 100644 --- a/src/Microsoft.AspNet.Authentication.Cookies/CookieServiceCollectionExtensions.cs +++ b/src/Microsoft.AspNet.Authentication.Cookies/CookieServiceCollectionExtensions.cs @@ -20,7 +20,6 @@ public static IServiceCollection ConfigureCookieAuthentication([NotNull] this IS public static IServiceCollection ConfigureCookieAuthentication([NotNull] this IServiceCollection services, [NotNull] Action configure, string optionsName) { - services.AddWebEncoders(); return services.Configure(configure, optionsName); } @@ -31,7 +30,6 @@ public static IServiceCollection ConfigureCookieAuthentication([NotNull] this IS public static IServiceCollection ConfigureCookieAuthentication([NotNull] this IServiceCollection services, [NotNull] IConfiguration config, string optionsName) { - services.AddWebEncoders(); return services.Configure(config, optionsName); } } diff --git a/src/Microsoft.AspNet.Authentication.Facebook/FacebookAuthenticationHandler.cs b/src/Microsoft.AspNet.Authentication.Facebook/FacebookAuthenticationHandler.cs index 246a5328e..3f5766e50 100644 --- a/src/Microsoft.AspNet.Authentication.Facebook/FacebookAuthenticationHandler.cs +++ b/src/Microsoft.AspNet.Authentication.Facebook/FacebookAuthenticationHandler.cs @@ -8,13 +8,12 @@ using System.Security.Cryptography; using System.Text; using System.Threading.Tasks; -using Microsoft.AspNet.Http; +using Microsoft.AspNet.Authentication.OAuth; +using Microsoft.AspNet.Http.Authentication; using Microsoft.AspNet.Http.Collections; using Microsoft.AspNet.Http.Extensions; -using Microsoft.AspNet.Http.Authentication; -using Microsoft.AspNet.Authentication.OAuth; using Microsoft.AspNet.WebUtilities; -using Microsoft.Framework.Logging; +using Microsoft.Framework.WebEncoders; using Newtonsoft.Json.Linq; namespace Microsoft.AspNet.Authentication.Facebook @@ -53,7 +52,7 @@ protected override async Task ExchangeCodeAsync(string code, stri protected override async Task GetUserInformationAsync(AuthenticationProperties properties, TokenResponse tokens) { - var graphAddress = Options.UserInformationEndpoint + "?access_token=" + Uri.EscapeDataString(tokens.AccessToken); + var graphAddress = Options.UserInformationEndpoint + "?access_token=" + UrlEncoder.UrlEncode(tokens.AccessToken); if (Options.SendAppSecretProof) { graphAddress += "&appsecret_proof=" + GenerateAppSecretProof(tokens.AccessToken); diff --git a/src/Microsoft.AspNet.Authentication.Facebook/FacebookAuthenticationMiddleware.cs b/src/Microsoft.AspNet.Authentication.Facebook/FacebookAuthenticationMiddleware.cs index 39b0e87ea..4fa9224c9 100644 --- a/src/Microsoft.AspNet.Authentication.Facebook/FacebookAuthenticationMiddleware.cs +++ b/src/Microsoft.AspNet.Authentication.Facebook/FacebookAuthenticationMiddleware.cs @@ -9,6 +9,7 @@ using Microsoft.Framework.Internal; using Microsoft.Framework.Logging; using Microsoft.Framework.OptionsModel; +using Microsoft.Framework.WebEncoders; namespace Microsoft.AspNet.Authentication.Facebook { @@ -28,10 +29,11 @@ public FacebookAuthenticationMiddleware( [NotNull] RequestDelegate next, [NotNull] IDataProtectionProvider dataProtectionProvider, [NotNull] ILoggerFactory loggerFactory, + [NotNull] IUrlEncoder encoder, [NotNull] IOptions externalOptions, [NotNull] IOptions options, ConfigureOptions configureOptions = null) - : base(next, dataProtectionProvider, loggerFactory, externalOptions, options, configureOptions) + : base(next, dataProtectionProvider, loggerFactory, encoder, externalOptions, options, configureOptions) { if (string.IsNullOrWhiteSpace(Options.AppId)) { diff --git a/src/Microsoft.AspNet.Authentication.Google/GoogleAuthenticationMiddleware.cs b/src/Microsoft.AspNet.Authentication.Google/GoogleAuthenticationMiddleware.cs index f98d659d2..3f0bd745d 100644 --- a/src/Microsoft.AspNet.Authentication.Google/GoogleAuthenticationMiddleware.cs +++ b/src/Microsoft.AspNet.Authentication.Google/GoogleAuthenticationMiddleware.cs @@ -9,6 +9,7 @@ using Microsoft.Framework.Internal; using Microsoft.Framework.Logging; using Microsoft.Framework.OptionsModel; +using Microsoft.Framework.WebEncoders; namespace Microsoft.AspNet.Authentication.Google { @@ -29,10 +30,11 @@ public GoogleAuthenticationMiddleware( [NotNull] RequestDelegate next, [NotNull] IDataProtectionProvider dataProtectionProvider, [NotNull] ILoggerFactory loggerFactory, + [NotNull] IUrlEncoder encoder, [NotNull] IOptions externalOptions, [NotNull] IOptions options, ConfigureOptions configureOptions = null) - : base(next, dataProtectionProvider, loggerFactory, externalOptions, options, configureOptions) + : base(next, dataProtectionProvider, loggerFactory, encoder, externalOptions, options, configureOptions) { if (Options.Notifications == null) { diff --git a/src/Microsoft.AspNet.Authentication.MicrosoftAccount/MicrosoftAccountAuthenticationMiddleware.cs b/src/Microsoft.AspNet.Authentication.MicrosoftAccount/MicrosoftAccountAuthenticationMiddleware.cs index 8978c4d1d..06001f183 100644 --- a/src/Microsoft.AspNet.Authentication.MicrosoftAccount/MicrosoftAccountAuthenticationMiddleware.cs +++ b/src/Microsoft.AspNet.Authentication.MicrosoftAccount/MicrosoftAccountAuthenticationMiddleware.cs @@ -7,6 +7,7 @@ using Microsoft.Framework.Internal; using Microsoft.Framework.Logging; using Microsoft.Framework.OptionsModel; +using Microsoft.Framework.WebEncoders; namespace Microsoft.AspNet.Authentication.MicrosoftAccount { @@ -26,10 +27,11 @@ public MicrosoftAccountAuthenticationMiddleware( [NotNull] RequestDelegate next, [NotNull] IDataProtectionProvider dataProtectionProvider, [NotNull] ILoggerFactory loggerFactory, + [NotNull] IUrlEncoder encoder, [NotNull] IOptions externalOptions, [NotNull] IOptions options, ConfigureOptions configureOptions = null) - : base(next, dataProtectionProvider, loggerFactory, externalOptions, options, configureOptions) + : base(next, dataProtectionProvider, loggerFactory, encoder, externalOptions, options, configureOptions) { if (Options.Notifications == null) { diff --git a/src/Microsoft.AspNet.Authentication.OAuth/OAuthAuthenticationMiddleware.cs b/src/Microsoft.AspNet.Authentication.OAuth/OAuthAuthenticationMiddleware.cs index 9a211ef24..3188a1bd9 100644 --- a/src/Microsoft.AspNet.Authentication.OAuth/OAuthAuthenticationMiddleware.cs +++ b/src/Microsoft.AspNet.Authentication.OAuth/OAuthAuthenticationMiddleware.cs @@ -11,6 +11,7 @@ using Microsoft.Framework.Internal; using Microsoft.Framework.Logging; using Microsoft.Framework.OptionsModel; +using Microsoft.Framework.WebEncoders; namespace Microsoft.AspNet.Authentication.OAuth { @@ -33,10 +34,11 @@ public OAuthAuthenticationMiddleware( [NotNull] RequestDelegate next, [NotNull] IDataProtectionProvider dataProtectionProvider, [NotNull] ILoggerFactory loggerFactory, + [NotNull] IUrlEncoder encoder, [NotNull] IOptions externalOptions, [NotNull] IOptions options, ConfigureOptions configureOptions = null) - : base(next, options, loggerFactory, configureOptions) + : base(next, options, loggerFactory, encoder, configureOptions) { // todo: review error handling if (string.IsNullOrWhiteSpace(Options.AuthenticationScheme)) diff --git a/src/Microsoft.AspNet.Authentication.OAuthBearer/OAuthBearerAuthenticationMiddleware.cs b/src/Microsoft.AspNet.Authentication.OAuthBearer/OAuthBearerAuthenticationMiddleware.cs index a18bbee93..1bde86c83 100644 --- a/src/Microsoft.AspNet.Authentication.OAuthBearer/OAuthBearerAuthenticationMiddleware.cs +++ b/src/Microsoft.AspNet.Authentication.OAuthBearer/OAuthBearerAuthenticationMiddleware.cs @@ -11,6 +11,7 @@ using Microsoft.Framework.Internal; using Microsoft.Framework.Logging; using Microsoft.Framework.OptionsModel; +using Microsoft.Framework.WebEncoders; using Microsoft.IdentityModel.Protocols; namespace Microsoft.AspNet.Authentication.OAuthBearer @@ -32,9 +33,10 @@ public class OAuthBearerAuthenticationMiddleware : AuthenticationMiddleware options, ConfigureOptions configureOptions) - : base(next, options, loggerFactory, configureOptions) + : base(next, options, loggerFactory, encoder, configureOptions) { if (Options.Notifications == null) { diff --git a/src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenIdConnectAuthenticationHandler.cs b/src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenIdConnectAuthenticationHandler.cs index 75914cc7b..25af5a4a0 100644 --- a/src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenIdConnectAuthenticationHandler.cs +++ b/src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenIdConnectAuthenticationHandler.cs @@ -180,7 +180,7 @@ protected override async Task ApplyResponseChallengeAsync() ResponseMode = Options.ResponseMode, ResponseType = Options.ResponseType, Scope = Options.Scope, - State = OpenIdConnectAuthenticationDefaults.AuthenticationPropertiesKey + "=" + Uri.EscapeDataString(Options.StateDataFormat.Protect(properties)) + State = OpenIdConnectAuthenticationDefaults.AuthenticationPropertiesKey + "=" + UrlEncoder.UrlEncode(Options.StateDataFormat.Protect(properties)) }; if (Options.ProtocolValidator.RequireNonce) diff --git a/src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenIdConnectAuthenticationMiddleware.cs b/src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenIdConnectAuthenticationMiddleware.cs index 46524c17c..70e45d0c2 100644 --- a/src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenIdConnectAuthenticationMiddleware.cs +++ b/src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenIdConnectAuthenticationMiddleware.cs @@ -17,6 +17,7 @@ using Microsoft.Framework.OptionsModel; using Microsoft.IdentityModel.Protocols; using Microsoft.Framework.Internal; +using Microsoft.Framework.WebEncoders; namespace Microsoft.AspNet.Authentication.OpenIdConnect { @@ -40,10 +41,11 @@ public OpenIdConnectAuthenticationMiddleware( [NotNull] RequestDelegate next, [NotNull] IDataProtectionProvider dataProtectionProvider, [NotNull] ILoggerFactory loggerFactory, + [NotNull] IUrlEncoder encoder, [NotNull] IOptions externalOptions, [NotNull] IOptions options, ConfigureOptions configureOptions = null) - : base(next, options, loggerFactory, configureOptions) + : base(next, options, loggerFactory, encoder, configureOptions) { if (string.IsNullOrEmpty(Options.SignInScheme) && !string.IsNullOrEmpty(externalOptions.Options.SignInScheme)) { diff --git a/src/Microsoft.AspNet.Authentication.Twitter/TwitterAuthenticationHandler.cs b/src/Microsoft.AspNet.Authentication.Twitter/TwitterAuthenticationHandler.cs index cbc48910c..6df6fc1a8 100644 --- a/src/Microsoft.AspNet.Authentication.Twitter/TwitterAuthenticationHandler.cs +++ b/src/Microsoft.AspNet.Authentication.Twitter/TwitterAuthenticationHandler.cs @@ -244,7 +244,7 @@ private async Task ObtainRequestTokenAsync(string consumerKey, str var parameterBuilder = new StringBuilder(); foreach (var authorizationKey in authorizationParts) { - parameterBuilder.AppendFormat("{0}={1}&", Uri.EscapeDataString(authorizationKey.Key), Uri.EscapeDataString(authorizationKey.Value)); + parameterBuilder.AppendFormat("{0}={1}&", UrlEncoder.UrlEncode(authorizationKey.Key), UrlEncoder.UrlEncode(authorizationKey.Value)); } parameterBuilder.Length--; var parameterString = parameterBuilder.ToString(); @@ -252,9 +252,9 @@ private async Task ObtainRequestTokenAsync(string consumerKey, str var canonicalizedRequestBuilder = new StringBuilder(); canonicalizedRequestBuilder.Append(HttpMethod.Post.Method); canonicalizedRequestBuilder.Append("&"); - canonicalizedRequestBuilder.Append(Uri.EscapeDataString(RequestTokenEndpoint)); + canonicalizedRequestBuilder.Append(UrlEncoder.UrlEncode(RequestTokenEndpoint)); canonicalizedRequestBuilder.Append("&"); - canonicalizedRequestBuilder.Append(Uri.EscapeDataString(parameterString)); + canonicalizedRequestBuilder.Append(UrlEncoder.UrlEncode(parameterString)); var signature = ComputeSignature(consumerSecret, null, canonicalizedRequestBuilder.ToString()); authorizationParts.Add("oauth_signature", signature); @@ -264,7 +264,7 @@ private async Task ObtainRequestTokenAsync(string consumerKey, str foreach (var authorizationPart in authorizationParts) { authorizationHeaderBuilder.AppendFormat( - "{0}=\"{1}\", ", authorizationPart.Key, Uri.EscapeDataString(authorizationPart.Value)); + "{0}=\"{1}\", ", authorizationPart.Key, UrlEncoder.UrlEncode(authorizationPart.Value)); } authorizationHeaderBuilder.Length = authorizationHeaderBuilder.Length - 2; @@ -306,7 +306,7 @@ private async Task ObtainAccessTokenAsync(string consumerKey, strin var parameterBuilder = new StringBuilder(); foreach (var authorizationKey in authorizationParts) { - parameterBuilder.AppendFormat("{0}={1}&", Uri.EscapeDataString(authorizationKey.Key), Uri.EscapeDataString(authorizationKey.Value)); + parameterBuilder.AppendFormat("{0}={1}&", UrlEncoder.UrlEncode(authorizationKey.Key), UrlEncoder.UrlEncode(authorizationKey.Value)); } parameterBuilder.Length--; var parameterString = parameterBuilder.ToString(); @@ -314,9 +314,9 @@ private async Task ObtainAccessTokenAsync(string consumerKey, strin var canonicalizedRequestBuilder = new StringBuilder(); canonicalizedRequestBuilder.Append(HttpMethod.Post.Method); canonicalizedRequestBuilder.Append("&"); - canonicalizedRequestBuilder.Append(Uri.EscapeDataString(AccessTokenEndpoint)); + canonicalizedRequestBuilder.Append(UrlEncoder.UrlEncode(AccessTokenEndpoint)); canonicalizedRequestBuilder.Append("&"); - canonicalizedRequestBuilder.Append(Uri.EscapeDataString(parameterString)); + canonicalizedRequestBuilder.Append(UrlEncoder.UrlEncode(parameterString)); var signature = ComputeSignature(consumerSecret, token.TokenSecret, canonicalizedRequestBuilder.ToString()); authorizationParts.Add("oauth_signature", signature); @@ -327,7 +327,7 @@ private async Task ObtainAccessTokenAsync(string consumerKey, strin foreach (var authorizationPart in authorizationParts) { authorizationHeaderBuilder.AppendFormat( - "{0}=\"{1}\", ", authorizationPart.Key, Uri.EscapeDataString(authorizationPart.Value)); + "{0}=\"{1}\", ", authorizationPart.Key, UrlEncoder.UrlEncode(authorizationPart.Value)); } authorizationHeaderBuilder.Length = authorizationHeaderBuilder.Length - 2; @@ -367,15 +367,15 @@ private static string GenerateTimeStamp() return Convert.ToInt64(secondsSinceUnixEpocStart.TotalSeconds).ToString(CultureInfo.InvariantCulture); } - private static string ComputeSignature(string consumerSecret, string tokenSecret, string signatureData) + private string ComputeSignature(string consumerSecret, string tokenSecret, string signatureData) { using (var algorithm = new HMACSHA1()) { algorithm.Key = Encoding.ASCII.GetBytes( string.Format(CultureInfo.InvariantCulture, "{0}&{1}", - Uri.EscapeDataString(consumerSecret), - string.IsNullOrEmpty(tokenSecret) ? string.Empty : Uri.EscapeDataString(tokenSecret))); + UrlEncoder.UrlEncode(consumerSecret), + string.IsNullOrEmpty(tokenSecret) ? string.Empty : UrlEncoder.UrlEncode(tokenSecret))); var hash = algorithm.ComputeHash(Encoding.ASCII.GetBytes(signatureData)); return Convert.ToBase64String(hash); } diff --git a/src/Microsoft.AspNet.Authentication.Twitter/TwitterAuthenticationMiddleware.cs b/src/Microsoft.AspNet.Authentication.Twitter/TwitterAuthenticationMiddleware.cs index 145cf4cad..c1d266163 100644 --- a/src/Microsoft.AspNet.Authentication.Twitter/TwitterAuthenticationMiddleware.cs +++ b/src/Microsoft.AspNet.Authentication.Twitter/TwitterAuthenticationMiddleware.cs @@ -13,6 +13,7 @@ using Microsoft.Framework.Internal; using Microsoft.Framework.Logging; using Microsoft.Framework.OptionsModel; +using Microsoft.Framework.WebEncoders; namespace Microsoft.AspNet.Authentication.Twitter { @@ -36,10 +37,11 @@ public TwitterAuthenticationMiddleware( [NotNull] RequestDelegate next, [NotNull] IDataProtectionProvider dataProtectionProvider, [NotNull] ILoggerFactory loggerFactory, + [NotNull] IUrlEncoder encoder, [NotNull] IOptions externalOptions, [NotNull] IOptions options, ConfigureOptions configureOptions = null) - : base(next, options, loggerFactory, configureOptions) + : base(next, options, loggerFactory, encoder, configureOptions) { if (string.IsNullOrWhiteSpace(Options.ConsumerSecret)) { diff --git a/src/Microsoft.AspNet.Authentication/AuthenticationHandler.cs b/src/Microsoft.AspNet.Authentication/AuthenticationHandler.cs index 7d412d28a..fed477878 100644 --- a/src/Microsoft.AspNet.Authentication/AuthenticationHandler.cs +++ b/src/Microsoft.AspNet.Authentication/AuthenticationHandler.cs @@ -10,6 +10,7 @@ using Microsoft.AspNet.Http.Authentication; using Microsoft.Framework.Internal; using Microsoft.Framework.Logging; +using Microsoft.Framework.WebEncoders; namespace Microsoft.AspNet.Authentication { @@ -50,6 +51,8 @@ protected HttpResponse Response protected ILogger Logger { get; private set; } + protected IUrlEncoder UrlEncoder { get; private set; } + internal AuthenticationOptions BaseOptions { get { return _baseOptions; } @@ -61,12 +64,13 @@ internal AuthenticationOptions BaseOptions public bool Faulted { get; set; } - protected async Task BaseInitializeAsync([NotNull] AuthenticationOptions options, [NotNull] HttpContext context, [NotNull] ILogger logger) + protected async Task BaseInitializeAsync([NotNull] AuthenticationOptions options, [NotNull] HttpContext context, [NotNull] ILogger logger, [NotNull] IUrlEncoder encoder) { _baseOptions = options; Context = context; RequestPathBase = Request.PathBase; Logger = logger; + UrlEncoder = encoder; RegisterAuthenticationHandler(); diff --git a/src/Microsoft.AspNet.Authentication/AuthenticationHandler`1.cs b/src/Microsoft.AspNet.Authentication/AuthenticationHandler`1.cs index 973f9f00f..1c59b3573 100644 --- a/src/Microsoft.AspNet.Authentication/AuthenticationHandler`1.cs +++ b/src/Microsoft.AspNet.Authentication/AuthenticationHandler`1.cs @@ -4,6 +4,7 @@ using System.Threading.Tasks; using Microsoft.AspNet.Http; using Microsoft.Framework.Logging; +using Microsoft.Framework.WebEncoders; namespace Microsoft.AspNet.Authentication { @@ -22,10 +23,10 @@ public abstract class AuthenticationHandler : AuthenticationHandler wh /// The utility object to observe the current request and response /// The logging factory used to create loggers /// async completion - public Task Initialize(TOptions options, HttpContext context, ILogger logger) + public Task Initialize(TOptions options, HttpContext context, ILogger logger, IUrlEncoder encoder) { Options = options; - return BaseInitializeAsync(options, context, logger); + return BaseInitializeAsync(options, context, logger, encoder); } } } diff --git a/src/Microsoft.AspNet.Authentication/AuthenticationMiddleware.cs b/src/Microsoft.AspNet.Authentication/AuthenticationMiddleware.cs index cdb6fbdf8..a70927f50 100644 --- a/src/Microsoft.AspNet.Authentication/AuthenticationMiddleware.cs +++ b/src/Microsoft.AspNet.Authentication/AuthenticationMiddleware.cs @@ -8,6 +8,7 @@ using Microsoft.Framework.Internal; using Microsoft.Framework.Logging; using Microsoft.Framework.OptionsModel; +using Microsoft.Framework.WebEncoders; namespace Microsoft.AspNet.Authentication { @@ -19,6 +20,7 @@ protected AuthenticationMiddleware( [NotNull] RequestDelegate next, [NotNull] IOptions options, [NotNull] ILoggerFactory loggerFactory, + [NotNull] IUrlEncoder encoder, ConfigureOptions configureOptions) { if (configureOptions != null) @@ -31,6 +33,7 @@ protected AuthenticationMiddleware( Options = options.Options; } Logger = loggerFactory.CreateLogger(this.GetType().FullName); + UrlEncoder = encoder; _next = next; } @@ -41,10 +44,12 @@ protected AuthenticationMiddleware( public ILogger Logger { get; set; } + public IUrlEncoder UrlEncoder { get; set; } + public async Task Invoke(HttpContext context) { var handler = CreateHandler(); - await handler.Initialize(Options, context, Logger); + await handler.Initialize(Options, context, Logger, UrlEncoder); try { if (!await handler.InvokeAsync()) diff --git a/src/Microsoft.AspNet.Authentication/AuthenticationServiceCollectionExtensions.cs b/src/Microsoft.AspNet.Authentication/AuthenticationServiceCollectionExtensions.cs index 43c0a7426..705ae6227 100644 --- a/src/Microsoft.AspNet.Authentication/AuthenticationServiceCollectionExtensions.cs +++ b/src/Microsoft.AspNet.Authentication/AuthenticationServiceCollectionExtensions.cs @@ -3,7 +3,6 @@ using System; using System.Security.Claims; -using System.Threading.Tasks; using Microsoft.AspNet.Authentication; using Microsoft.Framework.Internal; @@ -11,6 +10,13 @@ namespace Microsoft.Framework.DependencyInjection { public static class AuthenticationServiceCollectionExtensions { + public static IServiceCollection AddAuthentication([NotNull] this IServiceCollection services) + { + services.AddWebEncoders(); + services.AddDataProtection(); + return services; + } + public static IServiceCollection ConfigureClaimsTransformation([NotNull] this IServiceCollection services, [NotNull] Action configure) { return services.Configure(configure); diff --git a/src/Microsoft.AspNet.Authentication/project.json b/src/Microsoft.AspNet.Authentication/project.json index a28d27e07..31f033861 100644 --- a/src/Microsoft.AspNet.Authentication/project.json +++ b/src/Microsoft.AspNet.Authentication/project.json @@ -2,12 +2,13 @@ "version": "1.0.0-*", "description": "ASP.NET 5 common types used by the various authentication middleware.", "dependencies": { - "Microsoft.AspNet.DataProtection.Interfaces": "1.0.0-*", + "Microsoft.AspNet.DataProtection": "1.0.0-*", "Microsoft.AspNet.Http": "1.0.0-*", "Microsoft.AspNet.Http.Extensions": "1.0.0-*", "Microsoft.Framework.Logging.Interfaces": "1.0.0-*", "Microsoft.Framework.NotNullAttribute.Internal": { "type": "build", "version": "1.0.0-*" }, - "Microsoft.Framework.OptionsModel": "1.0.0-*" + "Microsoft.Framework.OptionsModel": "1.0.0-*", + "Microsoft.Framework.WebEncoders": "1.0.0-*" }, "frameworks": { "dnx451": { }, diff --git a/test/Microsoft.AspNet.Authentication.Test/AuthenticationHandlerFacts.cs b/test/Microsoft.AspNet.Authentication.Test/AuthenticationHandlerFacts.cs index cf628db54..f5428f1a3 100644 --- a/test/Microsoft.AspNet.Authentication.Test/AuthenticationHandlerFacts.cs +++ b/test/Microsoft.AspNet.Authentication.Test/AuthenticationHandlerFacts.cs @@ -55,7 +55,7 @@ private class TestHandler : AuthenticationHandler { public TestHandler(string scheme) { - Initialize(new TestOptions(), new DefaultHttpContext(), new LoggerFactory().CreateLogger("TestHandler")); + Initialize(new TestOptions(), new DefaultHttpContext(), new LoggerFactory().CreateLogger("TestHandler"), Framework.WebEncoders.UrlEncoder.Default); Options.AuthenticationScheme = scheme; } @@ -89,7 +89,7 @@ private class TestAutoHandler : AuthenticationHandler { public TestAutoHandler(string scheme, bool auto) { - Initialize(new TestAutoOptions(), new DefaultHttpContext(), new LoggerFactory().CreateLogger("TestHandler")); + Initialize(new TestAutoOptions(), new DefaultHttpContext(), new LoggerFactory().CreateLogger("TestHandler"), Framework.WebEncoders.UrlEncoder.Default); Options.AuthenticationScheme = scheme; Options.AutomaticAuthentication = auto; } diff --git a/test/Microsoft.AspNet.Authentication.Test/Cookies/CookieMiddlewareTests.cs b/test/Microsoft.AspNet.Authentication.Test/Cookies/CookieMiddlewareTests.cs index cd2483119..9c1ac2fdd 100644 --- a/test/Microsoft.AspNet.Authentication.Test/Cookies/CookieMiddlewareTests.cs +++ b/test/Microsoft.AspNet.Authentication.Test/Cookies/CookieMiddlewareTests.cs @@ -573,8 +573,7 @@ private static TestServer CreateServer(Action confi }, services => { - services.AddWebEncoders(); - services.AddDataProtection(); + services.AddAuthentication(); if (claimsTransform != null) { services.ConfigureClaimsTransformation(claimsTransform); diff --git a/test/Microsoft.AspNet.Authentication.Test/Google/GoogleMiddlewareTests.cs b/test/Microsoft.AspNet.Authentication.Test/Google/GoogleMiddlewareTests.cs index 76db1debb..6ed8a1734 100644 --- a/test/Microsoft.AspNet.Authentication.Test/Google/GoogleMiddlewareTests.cs +++ b/test/Microsoft.AspNet.Authentication.Test/Google/GoogleMiddlewareTests.cs @@ -109,7 +109,7 @@ public async Task ChallengeWillSetDefaultScope() var transaction = await SendAsync(server, "https://example.com/challenge"); transaction.Response.StatusCode.ShouldBe(HttpStatusCode.Redirect); var query = transaction.Response.Headers.Location.Query; - query.ShouldContain("&scope=" + Uri.EscapeDataString("openid profile email")); + query.ShouldContain("&scope=" + UrlEncoder.Default.UrlEncode("openid profile email")); } [Fact] @@ -124,7 +124,7 @@ public async Task Challenge401WillSetDefaultScope() var transaction = await SendAsync(server, "https://example.com/401"); transaction.Response.StatusCode.ShouldBe(HttpStatusCode.Redirect); var query = transaction.Response.Headers.Location.Query; - query.ShouldContain("&scope=" + Uri.EscapeDataString("openid profile email")); + query.ShouldContain("&scope=" + UrlEncoder.Default.UrlEncode("openid profile email")); } [Fact] @@ -231,7 +231,7 @@ public async Task ReplyPathWithoutStateQueryStringWillBeRejected() [Fact] public async Task ReplyPathWillAuthenticateValidAuthorizeCodeAndState() { - ISecureDataFormat stateFormat = new PropertiesDataFormat(new EphemeralDataProtectionProvider().CreateProtector("GoogleTest")); + var stateFormat = new PropertiesDataFormat(new EphemeralDataProtectionProvider().CreateProtector("GoogleTest")); var server = CreateServer(options => { options.ClientId = "Test Id"; @@ -284,7 +284,7 @@ public async Task ReplyPathWillAuthenticateValidAuthorizeCodeAndState() properties.RedirectUri = "/me"; var state = stateFormat.Protect(properties); var transaction = await SendAsync(server, - "https://example.com/signin-google?code=TestCode&state=" + Uri.EscapeDataString(state), + "https://example.com/signin-google?code=TestCode&state=" + UrlEncoder.Default.UrlEncode(state), correlationKey + "=" + correlationValue); transaction.Response.StatusCode.ShouldBe(HttpStatusCode.Redirect); transaction.Response.Headers.Location.ToString().ShouldBe("/me"); @@ -308,7 +308,7 @@ public async Task ReplyPathWillAuthenticateValidAuthorizeCodeAndState() [Fact] public async Task ReplyPathWillRejectIfCodeIsInvalid() { - ISecureDataFormat stateFormat = new PropertiesDataFormat(new EphemeralDataProtectionProvider().CreateProtector("GoogleTest")); + var stateFormat = new PropertiesDataFormat(new EphemeralDataProtectionProvider().CreateProtector("GoogleTest")); var server = CreateServer(options => { options.ClientId = "Test Id"; @@ -329,7 +329,7 @@ public async Task ReplyPathWillRejectIfCodeIsInvalid() properties.RedirectUri = "/me"; var state = stateFormat.Protect(properties); var transaction = await SendAsync(server, - "https://example.com/signin-google?code=TestCode&state=" + Uri.EscapeDataString(state), + "https://example.com/signin-google?code=TestCode&state=" + UrlEncoder.Default.UrlEncode(state), correlationKey + "=" + correlationValue); transaction.Response.StatusCode.ShouldBe(HttpStatusCode.Redirect); transaction.Response.Headers.Location.ToString().ShouldContain("error=access_denied"); @@ -338,7 +338,7 @@ public async Task ReplyPathWillRejectIfCodeIsInvalid() [Fact] public async Task ReplyPathWillRejectIfAccessTokenIsMissing() { - ISecureDataFormat stateFormat = new PropertiesDataFormat(new EphemeralDataProtectionProvider().CreateProtector("GoogleTest")); + var stateFormat = new PropertiesDataFormat(new EphemeralDataProtectionProvider().CreateProtector("GoogleTest")); var server = CreateServer(options => { options.ClientId = "Test Id"; @@ -359,7 +359,7 @@ public async Task ReplyPathWillRejectIfAccessTokenIsMissing() properties.RedirectUri = "/me"; var state = stateFormat.Protect(properties); var transaction = await SendAsync(server, - "https://example.com/signin-google?code=TestCode&state=" + Uri.EscapeDataString(state), + "https://example.com/signin-google?code=TestCode&state=" + UrlEncoder.Default.UrlEncode(state), correlationKey + "=" + correlationValue); transaction.Response.StatusCode.ShouldBe(HttpStatusCode.Redirect); transaction.Response.Headers.Location.ToString().ShouldContain("error=access_denied"); @@ -368,7 +368,7 @@ public async Task ReplyPathWillRejectIfAccessTokenIsMissing() [Fact] public async Task AuthenticatedEventCanGetRefreshToken() { - ISecureDataFormat stateFormat = new PropertiesDataFormat(new EphemeralDataProtectionProvider().CreateProtector("GoogleTest")); + var stateFormat = new PropertiesDataFormat(new EphemeralDataProtectionProvider().CreateProtector("GoogleTest")); var server = CreateServer(options => { options.ClientId = "Test Id"; @@ -431,7 +431,7 @@ public async Task AuthenticatedEventCanGetRefreshToken() properties.RedirectUri = "/me"; var state = stateFormat.Protect(properties); var transaction = await SendAsync(server, - "https://example.com/signin-google?code=TestCode&state=" + Uri.EscapeDataString(state), + "https://example.com/signin-google?code=TestCode&state=" + UrlEncoder.Default.UrlEncode(state), correlationKey + "=" + correlationValue); transaction.Response.StatusCode.ShouldBe(HttpStatusCode.Redirect); transaction.Response.Headers.Location.ToString().ShouldBe("/me"); @@ -532,8 +532,7 @@ private static TestServer CreateServer(Action confi }, services => { - services.AddWebEncoders(); - services.AddDataProtection(); + services.AddAuthentication(); services.Configure(options => { options.SignInScheme = CookieAuthenticationScheme; @@ -614,7 +613,7 @@ public string AuthenticationCookieValue public string FindClaimValue(string claimType) { - XElement claim = ResponseElement.Elements("claim").SingleOrDefault(elt => elt.Attribute("type").Value == claimType); + var claim = ResponseElement.Elements("claim").SingleOrDefault(elt => elt.Attribute("type").Value == claimType); if (claim == null) { return null; diff --git a/test/Microsoft.AspNet.Authentication.Test/Microsoft.AspNet.Authentication.Test.xproj b/test/Microsoft.AspNet.Authentication.Test/Microsoft.AspNet.Authentication.Test.xproj index 3bcf72482..aaf23b99e 100644 --- a/test/Microsoft.AspNet.Authentication.Test/Microsoft.AspNet.Authentication.Test.xproj +++ b/test/Microsoft.AspNet.Authentication.Test/Microsoft.AspNet.Authentication.Test.xproj @@ -13,5 +13,8 @@ 2.0 + + + \ No newline at end of file diff --git a/test/Microsoft.AspNet.Authentication.Test/MicrosoftAccount/MicrosoftAccountMiddlewareTests.cs b/test/Microsoft.AspNet.Authentication.Test/MicrosoftAccount/MicrosoftAccountMiddlewareTests.cs index 7ea848207..28ca0ecc9 100644 --- a/test/Microsoft.AspNet.Authentication.Test/MicrosoftAccount/MicrosoftAccountMiddlewareTests.cs +++ b/test/Microsoft.AspNet.Authentication.Test/MicrosoftAccount/MicrosoftAccountMiddlewareTests.cs @@ -19,6 +19,7 @@ using Microsoft.AspNet.Http.Authentication; using Microsoft.AspNet.TestHost; using Microsoft.Framework.DependencyInjection; +using Microsoft.Framework.WebEncoders; using Newtonsoft.Json; using Shouldly; using Xunit; @@ -143,7 +144,7 @@ public async Task AuthenticatedEventCanGetRefreshToken() properties.RedirectUri = "/me"; var state = stateFormat.Protect(properties); var transaction = await SendAsync(server, - "https://example.com/signin-microsoft?code=TestCode&state=" + Uri.EscapeDataString(state), + "https://example.com/signin-microsoft?code=TestCode&state=" + UrlEncoder.Default.UrlEncode(state), correlationKey + "=" + correlationValue); transaction.Response.StatusCode.ShouldBe(HttpStatusCode.Redirect); transaction.Response.Headers.Location.ToString().ShouldBe("/me"); @@ -177,8 +178,7 @@ private static TestServer CreateServer(Action { - services.AddWebEncoders(); - services.AddDataProtection(); + services.AddAuthentication(); services.Configure(options => { options.SignInScheme = "External"; diff --git a/test/Microsoft.AspNet.Authentication.Test/OAuthBearer/OAuthBearerMiddlewareTests.cs b/test/Microsoft.AspNet.Authentication.Test/OAuthBearer/OAuthBearerMiddlewareTests.cs index e688497d9..2fd8bb422 100644 --- a/test/Microsoft.AspNet.Authentication.Test/OAuthBearer/OAuthBearerMiddlewareTests.cs +++ b/test/Microsoft.AspNet.Authentication.Test/OAuthBearer/OAuthBearerMiddlewareTests.cs @@ -336,7 +336,7 @@ private static TestServer CreateServer(Action } }); }, - services => services.AddDataProtection()); + services => services.AddAuthentication()); } private static async Task SendAsync(TestServer server, string uri, string authorizationHeader = null) diff --git a/test/Microsoft.AspNet.Authentication.Test/OpenIdConnect/OpenIdConnectHandlerTests.cs b/test/Microsoft.AspNet.Authentication.Test/OpenIdConnect/OpenIdConnectHandlerTests.cs index c3dbece13..197437347 100644 --- a/test/Microsoft.AspNet.Authentication.Test/OpenIdConnect/OpenIdConnectHandlerTests.cs +++ b/test/Microsoft.AspNet.Authentication.Test/OpenIdConnect/OpenIdConnectHandlerTests.cs @@ -20,6 +20,7 @@ using Microsoft.Framework.DependencyInjection; using Microsoft.Framework.Logging; using Microsoft.Framework.OptionsModel; +using Microsoft.Framework.WebEncoders; using Microsoft.IdentityModel.Protocols; using Shouldly; using Xunit; @@ -115,7 +116,7 @@ public async Task AuthenticateCore() var propertiesFormatter = new AuthenticationPropertiesFormater(); var protectedProperties = propertiesFormatter.Protect(new AuthenticationProperties()); - var state = OpenIdConnectAuthenticationDefaults.AuthenticationPropertiesKey + "=" + Uri.EscapeDataString(protectedProperties); + var state = OpenIdConnectAuthenticationDefaults.AuthenticationPropertiesKey + "=" + UrlEncoder.Default.UrlEncode(protectedProperties); var code = Guid.NewGuid().ToString(); var message = new OpenIdConnectMessage @@ -565,9 +566,9 @@ public override void Configure(OpenIdConnectAuthenticationOptions options, strin /// public class CustomOpenIdConnectAuthenticationHandler : OpenIdConnectAuthenticationHandler { - public async Task BaseInitializeAsyncPublic(AuthenticationOptions options, HttpContext context, ILogger logger) + public async Task BaseInitializeAsyncPublic(AuthenticationOptions options, HttpContext context, ILogger logger, IUrlEncoder encoder) { - await base.BaseInitializeAsync(options, context, logger); + await base.BaseInitializeAsync(options, context, logger, encoder); } public override bool ShouldHandleScheme(string authenticationScheme) @@ -603,11 +604,12 @@ public CustomOpenIdConnectAuthenticationMiddleware( RequestDelegate next, IDataProtectionProvider dataProtectionProvider, ILoggerFactory loggerFactory, + IUrlEncoder encoder, IOptions externalOptions, IOptions options, ConfigureOptions configureOptions = null ) - : base(next, dataProtectionProvider, loggerFactory, externalOptions, options, configureOptions) + : base(next, dataProtectionProvider, loggerFactory, encoder, externalOptions, options, configureOptions) { Logger = (loggerFactory as CustomLoggerFactory).Logger; } diff --git a/test/Microsoft.AspNet.Authentication.Test/OpenIdConnect/OpenIdConnectMiddlewareTests.cs b/test/Microsoft.AspNet.Authentication.Test/OpenIdConnect/OpenIdConnectMiddlewareTests.cs index 6abc8aa94..85e74e19a 100644 --- a/test/Microsoft.AspNet.Authentication.Test/OpenIdConnect/OpenIdConnectMiddlewareTests.cs +++ b/test/Microsoft.AspNet.Authentication.Test/OpenIdConnect/OpenIdConnectMiddlewareTests.cs @@ -22,6 +22,7 @@ using Microsoft.AspNet.Http.Authentication; using Microsoft.AspNet.TestHost; using Microsoft.Framework.DependencyInjection; +using Microsoft.Framework.WebEncoders; using Newtonsoft.Json; using Shouldly; using Xunit; @@ -75,7 +76,7 @@ public async Task ChallengeWillSetDefaultScope() }); var transaction = await SendAsync(server, "https://example.com/challenge"); transaction.Response.StatusCode.ShouldBe(HttpStatusCode.Redirect); - transaction.Response.Headers.Location.Query.ShouldContain("&scope=" + Uri.EscapeDataString("openid profile")); + transaction.Response.Headers.Location.Query.ShouldContain("&scope=" + UrlEncoder.Default.UrlEncode("openid profile")); } [Fact] @@ -92,8 +93,8 @@ public async Task ChallengeWillUseOptionsProperties() var transaction = await SendAsync(server, "https://example.com/challenge"); transaction.Response.StatusCode.ShouldBe(HttpStatusCode.Redirect); var query = transaction.Response.Headers.Location.Query; - query.ShouldContain("scope=" + Uri.EscapeDataString("https://www.googleapis.com/auth/plus.login")); - query.ShouldContain("response_type=" + Uri.EscapeDataString("id_token")); + query.ShouldContain("scope=" + UrlEncoder.Default.UrlEncode("https://www.googleapis.com/auth/plus.login")); + query.ShouldContain("response_type=" + UrlEncoder.Default.UrlEncode("id_token")); } [Fact] @@ -148,7 +149,7 @@ public async Task SignOutWithCustomRedirectUri() var transaction = await SendAsync(server, "https://example.com/signout"); transaction.Response.StatusCode.ShouldBe(HttpStatusCode.Redirect); - transaction.Response.Headers.Location.AbsoluteUri.ShouldContain(Uri.EscapeDataString("https://example.com/logout")); + transaction.Response.Headers.Location.AbsoluteUri.ShouldContain(UrlEncoder.Default.UrlEncode("https://example.com/logout")); } [Fact] @@ -163,7 +164,7 @@ public async Task SignOutWith_Specific_RedirectUri_From_Authentication_Properite var transaction = await SendAsync(server, "https://example.com/signout_with_specific_redirect_uri"); transaction.Response.StatusCode.ShouldBe(HttpStatusCode.Redirect); - transaction.Response.Headers.Location.AbsoluteUri.ShouldContain(Uri.EscapeDataString("http://www.example.com/specific_redirect_uri")); + transaction.Response.Headers.Location.AbsoluteUri.ShouldContain(UrlEncoder.Default.UrlEncode("http://www.example.com/specific_redirect_uri")); } [Fact] @@ -234,8 +235,7 @@ private static TestServer CreateServer(Action { - services.AddWebEncoders(); - services.AddDataProtection(); + services.AddAuthentication(); services.Configure(options => { options.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme; diff --git a/test/Microsoft.AspNet.Authentication.Test/Twitter/TwitterMiddlewareTests.cs b/test/Microsoft.AspNet.Authentication.Test/Twitter/TwitterMiddlewareTests.cs index d4f6fd24a..bca10fbf4 100644 --- a/test/Microsoft.AspNet.Authentication.Test/Twitter/TwitterMiddlewareTests.cs +++ b/test/Microsoft.AspNet.Authentication.Test/Twitter/TwitterMiddlewareTests.cs @@ -123,8 +123,7 @@ private static TestServer CreateServer(Action configure, Fu }, services => { - services.AddWebEncoders(); - services.AddDataProtection(); + services.AddAuthentication(); services.Configure(options => { options.SignInScheme = "External"; From 63fc18b945bb30b217de20d2aec7c042f70a68ae Mon Sep 17 00:00:00 2001 From: Chris Ross Date: Fri, 24 Apr 2015 09:39:17 -0700 Subject: [PATCH 196/216] React to auth feature API changes. --- samples/CookieSample/Startup.cs | 2 +- samples/CookieSessionSample/Startup.cs | 2 +- samples/OpenIdConnectSample/Startup.cs | 2 +- samples/SocialSample/Startup.cs | 8 ++--- .../CookieAuthenticationHandler.cs | 14 ++++---- .../GoogleAuthenticationHandler.cs | 4 +-- .../OAuthAuthenticationHandler.cs | 2 +- .../OpenIdConnectAuthenticationHandler.cs | 12 +++---- .../TwitterAuthenticationHandler.cs | 2 +- .../AuthenticationHandler.cs | 32 +++++++++---------- ...aimsTransformationAuthenticationHandler.cs | 22 ++++++------- .../Serializer/PropertiesSerializer.cs | 4 +-- .../SignInContext.cs | 20 ------------ .../Cookies/CookieMiddlewareTests.cs | 20 ++++++------ .../Facebook/FacebookMiddlewareTests.cs | 4 +-- .../Google/GoogleMiddlewareTests.cs | 22 ++++++------- .../MicrosoftAccountMiddlewareTests.cs | 6 ++-- .../OAuthBearer/OAuthBearerMiddlewareTests.cs | 4 +-- .../OpenIdConnectHandlerTests.cs | 24 +------------- .../OpenIdConnectMiddlewareTests.cs | 8 ++--- .../Twitter/TwitterMiddlewareTests.cs | 4 +-- 21 files changed, 88 insertions(+), 130 deletions(-) delete mode 100644 src/Microsoft.AspNet.Authentication/SignInContext.cs diff --git a/samples/CookieSample/Startup.cs b/samples/CookieSample/Startup.cs index 3f0919190..6547450e5 100644 --- a/samples/CookieSample/Startup.cs +++ b/samples/CookieSample/Startup.cs @@ -28,7 +28,7 @@ public void Configure(IApplicationBuilder app, ILoggerFactory loggerfactory) if (string.IsNullOrEmpty(context.User.Identity.Name)) { var user = new ClaimsPrincipal(new ClaimsIdentity(new[] { new Claim(ClaimTypes.Name, "bob") })); - context.Response.SignIn(CookieAuthenticationDefaults.AuthenticationScheme, user); + context.Authentication.SignIn(CookieAuthenticationDefaults.AuthenticationScheme, user); context.Response.ContentType = "text/plain"; await context.Response.WriteAsync("Hello First timer"); return; diff --git a/samples/CookieSessionSample/Startup.cs b/samples/CookieSessionSample/Startup.cs index 0f962caed..f0b1b5219 100644 --- a/samples/CookieSessionSample/Startup.cs +++ b/samples/CookieSessionSample/Startup.cs @@ -36,7 +36,7 @@ public void Configure(IApplicationBuilder app, ILoggerFactory loggerfactory) { claims.Add(new Claim(ClaimTypes.Role, "SomeRandomGroup" + i, ClaimValueTypes.String, "IssuedByBob", "OriginalIssuerJoe")); } - context.Response.SignIn(CookieAuthenticationDefaults.AuthenticationScheme, new ClaimsPrincipal(new ClaimsIdentity(claims))); + context.Authentication.SignIn(CookieAuthenticationDefaults.AuthenticationScheme, new ClaimsPrincipal(new ClaimsIdentity(claims))); context.Response.ContentType = "text/plain"; await context.Response.WriteAsync("Hello First timer"); return; diff --git a/samples/OpenIdConnectSample/Startup.cs b/samples/OpenIdConnectSample/Startup.cs index 7c1969d3b..2077d802b 100644 --- a/samples/OpenIdConnectSample/Startup.cs +++ b/samples/OpenIdConnectSample/Startup.cs @@ -40,7 +40,7 @@ public void Configure(IApplicationBuilder app, ILoggerFactory loggerfactory) { if (string.IsNullOrEmpty(context.User.Identity.Name)) { - context.Response.Challenge(new AuthenticationProperties { RedirectUri = "/" }, OpenIdConnectAuthenticationDefaults.AuthenticationScheme); + context.Authentication.Challenge(OpenIdConnectAuthenticationDefaults.AuthenticationScheme, new AuthenticationProperties { RedirectUri = "/" }); context.Response.ContentType = "text/plain"; await context.Response.WriteAsync("Hello First timer"); diff --git a/samples/SocialSample/Startup.cs b/samples/SocialSample/Startup.cs index 4bfc7b659..f552ceea3 100644 --- a/samples/SocialSample/Startup.cs +++ b/samples/SocialSample/Startup.cs @@ -188,14 +188,14 @@ dnx . web { // 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 (/). - context.Response.Challenge(new AuthenticationProperties() { RedirectUri = "/" }, authType); + context.Authentication.Challenge(authType, new AuthenticationProperties() { RedirectUri = "/" }); return; } context.Response.ContentType = "text/html"; await context.Response.WriteAsync(""); await context.Response.WriteAsync("Choose an authentication scheme:
"); - foreach (var type in context.GetAuthenticationSchemes()) + foreach (var type in context.Authentication.GetAuthenticationSchemes()) { await context.Response.WriteAsync("" + (type.Caption ?? "(suppressed)") + "
"); } @@ -208,7 +208,7 @@ dnx . web { signoutApp.Run(async context => { - context.Response.SignOut(CookieAuthenticationDefaults.AuthenticationScheme); + context.Authentication.SignOut(CookieAuthenticationDefaults.AuthenticationScheme); context.Response.ContentType = "text/html"; await context.Response.WriteAsync(""); await context.Response.WriteAsync("You have been logged out. Goodbye " + context.User.Identity.Name + "
"); @@ -223,7 +223,7 @@ dnx . web if (string.IsNullOrEmpty(context.User.Identity.Name)) { // The cookie middleware will intercept this 401 and redirect to /login - context.Response.Challenge(); + context.Authentication.Challenge(); return; } await next(); diff --git a/src/Microsoft.AspNet.Authentication.Cookies/CookieAuthenticationHandler.cs b/src/Microsoft.AspNet.Authentication.Cookies/CookieAuthenticationHandler.cs index 27b0d2c4e..5e1acbcb1 100644 --- a/src/Microsoft.AspNet.Authentication.Cookies/CookieAuthenticationHandler.cs +++ b/src/Microsoft.AspNet.Authentication.Cookies/CookieAuthenticationHandler.cs @@ -157,23 +157,23 @@ protected override async Task ApplyResponseGrantAsync() Options, Options.AuthenticationScheme, signin.Principal, - signin.Properties, + new AuthenticationProperties(signin.Properties), cookieOptions); DateTimeOffset issuedUtc; - if (signin.Properties.IssuedUtc.HasValue) + if (signInContext.Properties.IssuedUtc.HasValue) { - issuedUtc = signin.Properties.IssuedUtc.Value; + issuedUtc = signInContext.Properties.IssuedUtc.Value; } else { issuedUtc = Options.SystemClock.UtcNow; - signin.Properties.IssuedUtc = issuedUtc; + signInContext.Properties.IssuedUtc = issuedUtc; } - if (!signin.Properties.ExpiresUtc.HasValue) + if (!signInContext.Properties.ExpiresUtc.HasValue) { - signin.Properties.ExpiresUtc = issuedUtc.Add(Options.ExpireTimeSpan); + signInContext.Properties.ExpiresUtc = issuedUtc.Add(Options.ExpireTimeSpan); } Options.Notifications.ResponseSignIn(signInContext); @@ -226,7 +226,7 @@ protected override async Task ApplyResponseGrantAsync() Context, Options, cookieOptions); - + Options.Notifications.ResponseSignOut(context); Options.CookieManager.DeleteCookie( diff --git a/src/Microsoft.AspNet.Authentication.Google/GoogleAuthenticationHandler.cs b/src/Microsoft.AspNet.Authentication.Google/GoogleAuthenticationHandler.cs index 175c38c20..c30e70526 100644 --- a/src/Microsoft.AspNet.Authentication.Google/GoogleAuthenticationHandler.cs +++ b/src/Microsoft.AspNet.Authentication.Google/GoogleAuthenticationHandler.cs @@ -102,14 +102,14 @@ private static void AddQueryString(IDictionary queryStrings, Aut string name, string defaultValue = null) { string value; - if (!properties.Dictionary.TryGetValue(name, out value)) + if (!properties.Items.TryGetValue(name, out value)) { value = defaultValue; } else { // Remove the parameter from AuthenticationProperties so it won't be serialized to state parameter - properties.Dictionary.Remove(name); + properties.Items.Remove(name); } if (value == null) diff --git a/src/Microsoft.AspNet.Authentication.OAuth/OAuthAuthenticationHandler.cs b/src/Microsoft.AspNet.Authentication.OAuth/OAuthAuthenticationHandler.cs index 5d3cb8c60..21c684a68 100644 --- a/src/Microsoft.AspNet.Authentication.OAuth/OAuthAuthenticationHandler.cs +++ b/src/Microsoft.AspNet.Authentication.OAuth/OAuthAuthenticationHandler.cs @@ -56,7 +56,7 @@ public async Task InvokeReturnPathAsync() if (context.SignInScheme != null && context.Principal != null) { - Context.Response.SignIn(context.SignInScheme, context.Principal, context.Properties); + Context.Authentication.SignIn(context.SignInScheme, context.Principal, context.Properties); } if (!context.IsRequestCompleted && context.RedirectUri != null) diff --git a/src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenIdConnectAuthenticationHandler.cs b/src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenIdConnectAuthenticationHandler.cs index 25af5a4a0..3ea2a4578 100644 --- a/src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenIdConnectAuthenticationHandler.cs +++ b/src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenIdConnectAuthenticationHandler.cs @@ -161,7 +161,7 @@ protected override async Task ApplyResponseChallengeAsync() // When redeeming a 'code' for an AccessToken, this value is needed if (!string.IsNullOrWhiteSpace(Options.RedirectUri)) { - properties.Dictionary.Add(OpenIdConnectAuthenticationDefaults.RedirectUriUsedForCodeKey, Options.RedirectUri); + properties.Items.Add(OpenIdConnectAuthenticationDefaults.RedirectUriUsedForCodeKey, Options.RedirectUri); } if (_configuration == null && Options.ConfigurationManager != null) @@ -385,12 +385,12 @@ protected override async Task AuthenticateCoreAsync() ticket = new AuthenticationTicket(principal, properties, Options.AuthenticationScheme); if (!string.IsNullOrWhiteSpace(message.SessionState)) { - ticket.Properties.Dictionary[OpenIdConnectSessionProperties.SessionState] = message.SessionState; + ticket.Properties.Items[OpenIdConnectSessionProperties.SessionState] = message.SessionState; } if (_configuration != null && !string.IsNullOrWhiteSpace(_configuration.CheckSessionIframe)) { - ticket.Properties.Dictionary[OpenIdConnectSessionProperties.CheckSessionIFrame] = _configuration.CheckSessionIframe; + ticket.Properties.Items[OpenIdConnectSessionProperties.CheckSessionIFrame] = _configuration.CheckSessionIframe; } // Rename? @@ -466,8 +466,8 @@ protected override async Task AuthenticateCoreAsync() Code = message.Code, JwtSecurityToken = jwt, ProtocolMessage = message, - RedirectUri = ticket.Properties.Dictionary.ContainsKey(OpenIdConnectAuthenticationDefaults.RedirectUriUsedForCodeKey) ? - ticket.Properties.Dictionary[OpenIdConnectAuthenticationDefaults.RedirectUriUsedForCodeKey] : string.Empty, + RedirectUri = ticket.Properties.Items.ContainsKey(OpenIdConnectAuthenticationDefaults.RedirectUriUsedForCodeKey) ? + ticket.Properties.Items[OpenIdConnectAuthenticationDefaults.RedirectUriUsedForCodeKey] : string.Empty, }; await Options.Notifications.AuthorizationCodeReceived(authorizationCodeReceivedNotification); @@ -632,7 +632,7 @@ private async Task InvokeReplyPathAsync() { if (ticket.Principal != null) { - Request.HttpContext.Response.SignIn(Options.SignInScheme, ticket.Principal, ticket.Properties); + Request.HttpContext.Authentication.SignIn(Options.SignInScheme, ticket.Principal, ticket.Properties); } // Redirect back to the original secured resource, if any. diff --git a/src/Microsoft.AspNet.Authentication.Twitter/TwitterAuthenticationHandler.cs b/src/Microsoft.AspNet.Authentication.Twitter/TwitterAuthenticationHandler.cs index 6df6fc1a8..e487f7698 100644 --- a/src/Microsoft.AspNet.Authentication.Twitter/TwitterAuthenticationHandler.cs +++ b/src/Microsoft.AspNet.Authentication.Twitter/TwitterAuthenticationHandler.cs @@ -208,7 +208,7 @@ public async Task InvokeReturnPathAsync() if (context.SignInScheme != null && context.Principal != null) { - Context.Response.SignIn(context.SignInScheme, context.Principal, context.Properties); + Context.Authentication.SignIn(context.SignInScheme, context.Principal, context.Properties); } if (!context.IsRequestCompleted && context.RedirectUri != null) diff --git a/src/Microsoft.AspNet.Authentication/AuthenticationHandler.cs b/src/Microsoft.AspNet.Authentication/AuthenticationHandler.cs index fed477878..22bc9eb36 100644 --- a/src/Microsoft.AspNet.Authentication/AuthenticationHandler.cs +++ b/src/Microsoft.AspNet.Authentication/AuthenticationHandler.cs @@ -31,9 +31,9 @@ public abstract class AuthenticationHandler : IAuthenticationHandler private AuthenticationOptions _baseOptions; - protected IChallengeContext ChallengeContext { get; set; } + protected ChallengeContext ChallengeContext { get; set; } protected SignInContext SignInContext { get; set; } - protected ISignOutContext SignOutContext { get; set; } + protected SignOutContext SignOutContext { get; set; } protected HttpContext Context { get; private set; } @@ -145,9 +145,9 @@ public virtual Task InvokeAsync() return Task.FromResult(false); } - public virtual void GetDescriptions(IDescribeSchemesContext describeContext) + public virtual void GetDescriptions(DescribeSchemesContext describeContext) { - describeContext.Accept(BaseOptions.Description.Dictionary); + describeContext.Accept(BaseOptions.Description.Items); if (PriorHandler != null) { @@ -155,7 +155,7 @@ public virtual void GetDescriptions(IDescribeSchemesContext describeContext) } } - public virtual void Authenticate(IAuthenticateContext context) + public virtual void Authenticate(AuthenticateContext context) { if (ShouldHandleScheme(context.AuthenticationScheme)) { @@ -163,7 +163,7 @@ public virtual void Authenticate(IAuthenticateContext context) if (ticket?.Principal != null) { AuthenticateCalled = true; - context.Authenticated(ticket.Principal, ticket.Properties.Dictionary, BaseOptions.Description.Dictionary); + context.Authenticated(ticket.Principal, ticket.Properties.Items, BaseOptions.Description.Items); } else { @@ -177,7 +177,7 @@ public virtual void Authenticate(IAuthenticateContext context) } } - public virtual async Task AuthenticateAsync(IAuthenticateContext context) + public virtual async Task AuthenticateAsync(AuthenticateContext context) { if (ShouldHandleScheme(context.AuthenticationScheme)) { @@ -185,7 +185,7 @@ public virtual async Task AuthenticateAsync(IAuthenticateContext context) if (ticket?.Principal != null) { AuthenticateCalled = true; - context.Authenticated(ticket.Principal, ticket.Properties.Dictionary, BaseOptions.Description.Dictionary); + context.Authenticated(ticket.Principal, ticket.Properties.Items, BaseOptions.Description.Items); } else { @@ -326,13 +326,13 @@ protected virtual Task ApplyResponseGrantAsync() return Task.FromResult(0); } - public virtual void SignIn(ISignInContext context) + public virtual void SignIn(SignInContext context) { if (ShouldHandleScheme(context.AuthenticationScheme)) { - SignInContext = new SignInContext(context.Principal, new AuthenticationProperties(context.Properties)); + SignInContext = context; SignOutContext = null; - context.Accept(BaseOptions.Description.Dictionary); + context.Accept(); } if (PriorHandler != null) @@ -341,7 +341,7 @@ public virtual void SignIn(ISignInContext context) } } - public virtual void SignOut(ISignOutContext context) + public virtual void SignOut(SignOutContext context) { if (ShouldHandleScheme(context.AuthenticationScheme)) { @@ -356,7 +356,7 @@ public virtual void SignOut(ISignOutContext context) } } - public virtual void Challenge(IChallengeContext context) + public virtual void Challenge(ChallengeContext context) { if (ShouldHandleScheme(context.AuthenticationScheme)) { @@ -414,7 +414,7 @@ protected void GenerateCorrelationId([NotNull] AuthenticationProperties properti Secure = Request.IsHttps }; - properties.Dictionary[correlationKey] = correlationId; + properties.Items[correlationKey] = correlationId; Response.Cookies.Append(correlationKey, correlationId, cookieOptions); } @@ -437,7 +437,7 @@ protected bool ValidateCorrelationId([NotNull] AuthenticationProperties properti Response.Cookies.Delete(correlationKey, cookieOptions); string correlationExtra; - if (!properties.Dictionary.TryGetValue( + if (!properties.Items.TryGetValue( correlationKey, out correlationExtra)) { @@ -445,7 +445,7 @@ protected bool ValidateCorrelationId([NotNull] AuthenticationProperties properti return false; } - properties.Dictionary.Remove(correlationKey); + properties.Items.Remove(correlationKey); if (!string.Equals(correlationCookie, correlationExtra, StringComparison.Ordinal)) { diff --git a/src/Microsoft.AspNet.Authentication/ClaimsTransformationAuthenticationHandler.cs b/src/Microsoft.AspNet.Authentication/ClaimsTransformationAuthenticationHandler.cs index ae1599ee0..5839d4d4e 100644 --- a/src/Microsoft.AspNet.Authentication/ClaimsTransformationAuthenticationHandler.cs +++ b/src/Microsoft.AspNet.Authentication/ClaimsTransformationAuthenticationHandler.cs @@ -22,24 +22,24 @@ public ClaimsTransformationAuthenticationHandler(Func(null); @@ -87,7 +87,7 @@ private Task SignInAsAlice(HttpContext context) private Task SignInAsWrong(HttpContext context) { - context.Response.SignIn("Oops", + context.Authentication.SignIn("Oops", new ClaimsPrincipal(new ClaimsIdentity(new GenericIdentity("Alice", "Cookies"))), new AuthenticationProperties()); return Task.FromResult(null); @@ -95,7 +95,7 @@ private Task SignInAsWrong(HttpContext context) private Task SignOutAsWrong(HttpContext context) { - context.Response.SignOut("Oops"); + context.Authentication.SignOut("Oops"); return Task.FromResult(null); } @@ -305,7 +305,7 @@ public async Task CookieExpirationCanBeOverridenInSignin() }, context => { - context.Response.SignIn("Cookies", + context.Authentication.SignIn("Cookies", new ClaimsPrincipal(new ClaimsIdentity(new GenericIdentity("Alice", "Cookies"))), new AuthenticationProperties() { ExpiresUtc = clock.UtcNow.Add(TimeSpan.FromMinutes(5)) }); return Task.FromResult(null); @@ -435,7 +435,7 @@ public async Task CookieUsesPathBaseByDefault() context => { Assert.Equal(new PathString("/base"), context.Request.PathBase); - context.Response.SignIn("Cookies", + context.Authentication.SignIn("Cookies", new ClaimsPrincipal(new ClaimsIdentity(new GenericIdentity("Alice", "Cookies")))); return Task.FromResult(null); }, @@ -545,12 +545,12 @@ private static TestServer CreateServer(Action confi else if (req.Path == new PathString("/unauthorized")) { // Simulate Authorization failure - var result = await context.AuthenticateAsync(CookieAuthenticationDefaults.AuthenticationScheme); - res.Challenge(CookieAuthenticationDefaults.AuthenticationScheme); + var result = await context.Authentication.AuthenticateAsync(CookieAuthenticationDefaults.AuthenticationScheme); + context.Authentication.Challenge(CookieAuthenticationDefaults.AuthenticationScheme); } else if (req.Path == new PathString("/protected/CustomRedirect")) { - context.Response.Challenge(new AuthenticationProperties() { RedirectUri = "/CustomRedirect" }); + context.Authentication.Challenge(new AuthenticationProperties() { RedirectUri = "/CustomRedirect" }); } else if (req.Path == new PathString("/me")) { @@ -558,7 +558,7 @@ private static TestServer CreateServer(Action confi } else if (req.Path.StartsWithSegments(new PathString("/me"), out remainder)) { - var result = await context.AuthenticateAsync(remainder.Value.Substring(1)); + var result = await context.Authentication.AuthenticateAsync(remainder.Value.Substring(1)); Describe(res, result); } else if (req.Path == new PathString("/testpath") && testpath != null) @@ -594,7 +594,7 @@ private static void Describe(HttpResponse res, AuthenticationResult result) } if (result != null && result.Properties != null) { - xml.Add(result.Properties.Dictionary.Select(extra => new XElement("extra", new XAttribute("type", extra.Key), new XAttribute("value", extra.Value)))); + xml.Add(result.Properties.Items.Select(extra => new XElement("extra", new XAttribute("type", extra.Key), new XAttribute("value", extra.Value)))); } using (var memory = new MemoryStream()) { diff --git a/test/Microsoft.AspNet.Authentication.Test/Facebook/FacebookMiddlewareTests.cs b/test/Microsoft.AspNet.Authentication.Test/Facebook/FacebookMiddlewareTests.cs index ad3f6b74f..2cde6c767 100644 --- a/test/Microsoft.AspNet.Authentication.Test/Facebook/FacebookMiddlewareTests.cs +++ b/test/Microsoft.AspNet.Authentication.Test/Facebook/FacebookMiddlewareTests.cs @@ -55,7 +55,7 @@ public async Task ChallengeWillTriggerApplyRedirectEvent() }, context => { - context.Response.Challenge("Facebook"); + context.Authentication.Challenge("Facebook"); return true; }); var transaction = await SendAsync(server, "http://example.com/challenge"); @@ -93,7 +93,7 @@ public async Task ChallengeWillTriggerRedirection() }, context => { - context.Response.Challenge("Facebook"); + context.Authentication.Challenge("Facebook"); return true; }); var transaction = await SendAsync(server, "http://example.com/challenge"); diff --git a/test/Microsoft.AspNet.Authentication.Test/Google/GoogleMiddlewareTests.cs b/test/Microsoft.AspNet.Authentication.Test/Google/GoogleMiddlewareTests.cs index 6ed8a1734..08917a674 100644 --- a/test/Microsoft.AspNet.Authentication.Test/Google/GoogleMiddlewareTests.cs +++ b/test/Microsoft.AspNet.Authentication.Test/Google/GoogleMiddlewareTests.cs @@ -142,14 +142,14 @@ public async Task ChallengeWillUseAuthenticationPropertiesAsParameters() var res = context.Response; if (req.Path == new PathString("/challenge2")) { - res.Challenge(new AuthenticationProperties( + context.Authentication.Challenge("Google", new AuthenticationProperties( new Dictionary() { { "scope", "https://www.googleapis.com/auth/plus.login" }, { "access_type", "offline" }, { "approval_prompt", "force" }, { "login_hint", "test@example.com" } - }), "Google"); + })); res.StatusCode = 401; } @@ -280,7 +280,7 @@ public async Task ReplyPathWillAuthenticateValidAuthorizeCodeAndState() var properties = new AuthenticationProperties(); var correlationKey = ".AspNet.Correlation.Google"; var correlationValue = "TestCorrelationId"; - properties.Dictionary.Add(correlationKey, correlationValue); + properties.Items.Add(correlationKey, correlationValue); properties.RedirectUri = "/me"; var state = stateFormat.Protect(properties); var transaction = await SendAsync(server, @@ -325,7 +325,7 @@ public async Task ReplyPathWillRejectIfCodeIsInvalid() var properties = new AuthenticationProperties(); var correlationKey = ".AspNet.Correlation.Google"; var correlationValue = "TestCorrelationId"; - properties.Dictionary.Add(correlationKey, correlationValue); + properties.Items.Add(correlationKey, correlationValue); properties.RedirectUri = "/me"; var state = stateFormat.Protect(properties); var transaction = await SendAsync(server, @@ -355,7 +355,7 @@ public async Task ReplyPathWillRejectIfAccessTokenIsMissing() var properties = new AuthenticationProperties(); var correlationKey = ".AspNet.Correlation.Google"; var correlationValue = "TestCorrelationId"; - properties.Dictionary.Add(correlationKey, correlationValue); + properties.Items.Add(correlationKey, correlationValue); properties.RedirectUri = "/me"; var state = stateFormat.Protect(properties); var transaction = await SendAsync(server, @@ -427,7 +427,7 @@ public async Task AuthenticatedEventCanGetRefreshToken() var properties = new AuthenticationProperties(); var correlationKey = ".AspNet.Correlation.Google"; var correlationValue = "TestCorrelationId"; - properties.Dictionary.Add(correlationKey, correlationValue); + properties.Items.Add(correlationKey, correlationValue); properties.RedirectUri = "/me"; var state = stateFormat.Protect(properties); var transaction = await SendAsync(server, @@ -497,7 +497,7 @@ private static TestServer CreateServer(Action confi var res = context.Response; if (req.Path == new PathString("/challenge")) { - res.Challenge("Google"); + context.Authentication.Challenge("Google"); res.StatusCode = 401; } else if (req.Path == new PathString("/me")) @@ -507,14 +507,14 @@ private static TestServer CreateServer(Action confi else if (req.Path == new PathString("/unauthorized")) { // Simulate Authorization failure - var result = await context.AuthenticateAsync("Google"); - res.Challenge("Google"); + var result = await context.Authentication.AuthenticateAsync("Google"); + context.Authentication.Challenge("Google"); } else if (req.Path == new PathString("/unauthorizedAuto")) { - var result = await context.AuthenticateAsync("Google"); + var result = await context.Authentication.AuthenticateAsync("Google"); res.StatusCode = 401; - res.Challenge(); + context.Authentication.Challenge(); } else if (req.Path == new PathString("/401")) { diff --git a/test/Microsoft.AspNet.Authentication.Test/MicrosoftAccount/MicrosoftAccountMiddlewareTests.cs b/test/Microsoft.AspNet.Authentication.Test/MicrosoftAccount/MicrosoftAccountMiddlewareTests.cs index 28ca0ecc9..60230224b 100644 --- a/test/Microsoft.AspNet.Authentication.Test/MicrosoftAccount/MicrosoftAccountMiddlewareTests.cs +++ b/test/Microsoft.AspNet.Authentication.Test/MicrosoftAccount/MicrosoftAccountMiddlewareTests.cs @@ -46,7 +46,7 @@ public async Task ChallengeWillTriggerApplyRedirectEvent() }, context => { - context.Response.Challenge("Microsoft"); + context.Authentication.Challenge("Microsoft"); return true; }); var transaction = await SendAsync(server, "http://example.com/challenge"); @@ -66,7 +66,7 @@ public async Task ChallengeWillTriggerRedirection() }, context => { - context.Response.Challenge("Microsoft"); + context.Authentication.Challenge("Microsoft"); return true; }); var transaction = await SendAsync(server, "http://example.com/challenge"); @@ -140,7 +140,7 @@ public async Task AuthenticatedEventCanGetRefreshToken() var properties = new AuthenticationProperties(); var correlationKey = ".AspNet.Correlation.Microsoft"; var correlationValue = "TestCorrelationId"; - properties.Dictionary.Add(correlationKey, correlationValue); + properties.Items.Add(correlationKey, correlationValue); properties.RedirectUri = "/me"; var state = stateFormat.Protect(properties); var transaction = await SendAsync(server, diff --git a/test/Microsoft.AspNet.Authentication.Test/OAuthBearer/OAuthBearerMiddlewareTests.cs b/test/Microsoft.AspNet.Authentication.Test/OAuthBearer/OAuthBearerMiddlewareTests.cs index 2fd8bb422..4d589a43c 100644 --- a/test/Microsoft.AspNet.Authentication.Test/OAuthBearer/OAuthBearerMiddlewareTests.cs +++ b/test/Microsoft.AspNet.Authentication.Test/OAuthBearer/OAuthBearerMiddlewareTests.cs @@ -326,8 +326,8 @@ private static TestServer CreateServer(Action else if (context.Request.Path == new PathString("/unauthorized")) { // Simulate Authorization failure - var result = await context.AuthenticateAsync(OAuthBearerAuthenticationDefaults.AuthenticationScheme); - context.Response.Challenge(OAuthBearerAuthenticationDefaults.AuthenticationScheme); + var result = await context.Authentication.AuthenticateAsync(OAuthBearerAuthenticationDefaults.AuthenticationScheme); + context.Authentication.Challenge(OAuthBearerAuthenticationDefaults.AuthenticationScheme); } else diff --git a/test/Microsoft.AspNet.Authentication.Test/OpenIdConnect/OpenIdConnectHandlerTests.cs b/test/Microsoft.AspNet.Authentication.Test/OpenIdConnect/OpenIdConnectHandlerTests.cs index 197437347..1134c7300 100644 --- a/test/Microsoft.AspNet.Authentication.Test/OpenIdConnect/OpenIdConnectHandlerTests.cs +++ b/test/Microsoft.AspNet.Authentication.Test/OpenIdConnect/OpenIdConnectHandlerTests.cs @@ -493,28 +493,6 @@ public static IApplicationBuilder UseCustomOpenIdConnectAuthentication(this IApp } } - public class OpenIdConnectAuthenticationContext : IAuthenticateContext - { - public OpenIdConnectAuthenticationContext(string scheme = null) - { - AuthenticationScheme = scheme ?? OpenIdConnectAuthenticationDefaults.AuthenticationScheme; - } - - public string AuthenticationScheme - { - get; - set; - } - - public void Authenticated(ClaimsPrincipal principal, IDictionary properties, IDictionary description) - { - } - - public void NotAuthenticated() - { - } - } - /// /// Provides a Facade over IOptions /// @@ -576,7 +554,7 @@ public override bool ShouldHandleScheme(string authenticationScheme) return true; } - public override void Challenge(IChallengeContext context) + public override void Challenge(ChallengeContext context) { } diff --git a/test/Microsoft.AspNet.Authentication.Test/OpenIdConnect/OpenIdConnectMiddlewareTests.cs b/test/Microsoft.AspNet.Authentication.Test/OpenIdConnect/OpenIdConnectMiddlewareTests.cs index 85e74e19a..da290cca1 100644 --- a/test/Microsoft.AspNet.Authentication.Test/OpenIdConnect/OpenIdConnectMiddlewareTests.cs +++ b/test/Microsoft.AspNet.Authentication.Test/OpenIdConnect/OpenIdConnectMiddlewareTests.cs @@ -205,21 +205,21 @@ private static TestServer CreateServer(Action { - context.Response.Challenge("Twitter"); + context.Authentication.Challenge("Twitter"); return true; }); var transaction = await SendAsync(server, "http://example.com/challenge"); @@ -92,7 +92,7 @@ public async Task ChallengeWillTriggerRedirection() }), context => { - context.Response.Challenge("Twitter"); + context.Authentication.Challenge("Twitter"); return true; }); var transaction = await SendAsync(server, "http://example.com/challenge"); From 1283414499f8fb642d3dcd963225b9ab2874c629 Mon Sep 17 00:00:00 2001 From: Chris R Date: Wed, 29 Apr 2015 15:46:47 -0700 Subject: [PATCH 197/216] React to Http.Interfaces package rename. --- src/Microsoft.AspNet.Authorization/project.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Microsoft.AspNet.Authorization/project.json b/src/Microsoft.AspNet.Authorization/project.json index 6ebb367aa..5b1bf44e9 100644 --- a/src/Microsoft.AspNet.Authorization/project.json +++ b/src/Microsoft.AspNet.Authorization/project.json @@ -2,7 +2,7 @@ "version": "1.0.0-*", "description": "ASP.NET 5 authorization classes.", "dependencies": { - "Microsoft.AspNet.Http.Interfaces": "1.0.0-*", + "Microsoft.AspNet.Http.Features": "1.0.0-*", "Microsoft.Framework.Logging.Interfaces": "1.0.0-*", "Microsoft.Framework.NotNullAttribute.Internal": { "type": "build", "version": "1.0.0-*" }, "Microsoft.Framework.OptionsModel": "1.0.0-*" From 4a5e8e5dfef8b967eb7f956ce1e4d55d3965693c Mon Sep 17 00:00:00 2001 From: Brennan Date: Wed, 29 Apr 2015 19:09:52 -0700 Subject: [PATCH 198/216] Reacting to Logging Package rename --- src/Microsoft.AspNet.Authentication/project.json | 2 +- src/Microsoft.AspNet.Authorization/project.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Microsoft.AspNet.Authentication/project.json b/src/Microsoft.AspNet.Authentication/project.json index 31f033861..6bda0f7da 100644 --- a/src/Microsoft.AspNet.Authentication/project.json +++ b/src/Microsoft.AspNet.Authentication/project.json @@ -5,7 +5,7 @@ "Microsoft.AspNet.DataProtection": "1.0.0-*", "Microsoft.AspNet.Http": "1.0.0-*", "Microsoft.AspNet.Http.Extensions": "1.0.0-*", - "Microsoft.Framework.Logging.Interfaces": "1.0.0-*", + "Microsoft.Framework.Logging.Abstractions": "1.0.0-*", "Microsoft.Framework.NotNullAttribute.Internal": { "type": "build", "version": "1.0.0-*" }, "Microsoft.Framework.OptionsModel": "1.0.0-*", "Microsoft.Framework.WebEncoders": "1.0.0-*" diff --git a/src/Microsoft.AspNet.Authorization/project.json b/src/Microsoft.AspNet.Authorization/project.json index 5b1bf44e9..71c918fc5 100644 --- a/src/Microsoft.AspNet.Authorization/project.json +++ b/src/Microsoft.AspNet.Authorization/project.json @@ -3,7 +3,7 @@ "description": "ASP.NET 5 authorization classes.", "dependencies": { "Microsoft.AspNet.Http.Features": "1.0.0-*", - "Microsoft.Framework.Logging.Interfaces": "1.0.0-*", + "Microsoft.Framework.Logging.Abstractions": "1.0.0-*", "Microsoft.Framework.NotNullAttribute.Internal": { "type": "build", "version": "1.0.0-*" }, "Microsoft.Framework.OptionsModel": "1.0.0-*" }, From 5cf0564484cf5bb2a7a16e6485816d19287538e6 Mon Sep 17 00:00:00 2001 From: "N. Taylor Mullen" Date: Fri, 1 May 2015 14:00:05 -0700 Subject: [PATCH 199/216] Update LICENSE.txt and license header on files. --- LICENSE.txt | 2 +- .../CookieAppBuilderExtensions.cs | 2 +- .../CookieAuthenticationDefaults.cs | 2 +- .../CookieAuthenticationHandler.cs | 2 +- .../CookieAuthenticationMiddleware.cs | 2 +- .../CookieAuthenticationOptions.cs | 2 +- .../CookieSecureOption.cs | 2 +- .../CookieServiceCollectionExtensions.cs | 2 +- .../Infrastructure/ChunkingCookieManager.cs | 2 +- .../Infrastructure/Constants.cs | 2 +- .../Infrastructure/IAuthenticationSessionStore.cs | 2 +- .../Infrastructure/ICookieManager.cs | 2 +- .../Notifications/CookieApplyRedirectContext.cs | 2 +- .../Notifications/CookieAuthenticationNotifications.cs | 2 +- .../Notifications/CookieExceptionContext.cs | 2 +- .../Notifications/CookieResponseSignInContext.cs | 2 +- .../Notifications/CookieResponseSignOutContext.cs | 2 +- .../Notifications/CookieResponseSignedInContext.cs | 2 +- .../Notifications/CookieValidateIdentityContext.cs | 2 +- .../Notifications/DefaultBehavior.cs | 2 +- .../Notifications/ICookieAuthenticationNotifications.cs | 2 +- .../Properties/AssemblyInfo.cs | 2 +- .../FacebookAppBuilderExtensions.cs | 2 +- .../FacebookAuthenticationDefaults.cs | 2 +- .../FacebookAuthenticationHandler.cs | 2 +- .../FacebookAuthenticationMiddleware.cs | 2 +- .../FacebookAuthenticationOptions.cs | 2 +- .../FacebookServiceCollectionExtensions.cs | 2 +- .../Notifications/FacebookAuthenticatedContext.cs | 2 +- .../Notifications/FacebookAuthenticationNotifications.cs | 2 +- .../Notifications/IFacebookAuthenticationNotifications.cs | 2 +- .../Properties/AssemblyInfo.cs | 2 +- .../GoogleAppBuilderExtensions.cs | 2 +- .../GoogleAuthenticationDefaults.cs | 2 +- .../GoogleAuthenticationHandler.cs | 2 +- .../GoogleAuthenticationMiddleware.cs | 2 +- .../GoogleAuthenticationOptions.cs | 2 +- .../GoogleServiceCollectionExtensions.cs | 2 +- .../Notifications/GoogleAuthenticatedContext.cs | 2 +- .../Notifications/GoogleAuthenticationNotifications.cs | 2 +- .../Notifications/IGoogleAuthenticationNotifications.cs | 2 +- .../Properties/AssemblyInfo.cs | 2 +- .../MicrosoftAccountAppBuilderExtensions.cs | 2 +- .../MicrosoftAccountAuthenticationDefaults.cs | 2 +- .../MicrosoftAccountAuthenticationHandler.cs | 2 +- .../MicrosoftAccountAuthenticationMiddleware.cs | 2 +- .../MicrosoftAccountAuthenticationOptions.cs | 2 +- .../MicrosoftAccountServiceCollectionExtensions.cs | 2 +- .../IMicrosoftAccountAuthenticationNotifications.cs | 2 +- .../Notifications/MicrosoftAccountAuthenticatedContext.cs | 2 +- .../MicrosoftAccountAuthenticationNotifications.cs | 2 +- .../Properties/AssemblyInfo.cs | 2 +- .../Notifications/BaseValidatingContext.cs | 2 +- .../Notifications/BaseValidatingTicketContext.cs | 2 +- .../Notifications/IOAuthAuthenticationNotifications.cs | 2 +- .../Notifications/OAuthApplyRedirectContext.cs | 2 +- .../Notifications/OAuthAuthenticatedContext.cs | 2 +- .../Notifications/OAuthAuthenticationNotifications.cs | 2 +- .../Notifications/OAuthChallengeContext.cs | 2 +- .../Notifications/OAuthGetUserInformationContext.cs | 2 +- .../Notifications/OAuthRequestTokenContext.cs | 2 +- .../Notifications/OAuthReturnEndpointContext.cs | 2 +- .../OAuthAuthenticationDefaults.cs | 2 +- .../OAuthAuthenticationExtensions.cs | 2 +- .../OAuthAuthenticationHandler.cs | 2 +- .../OAuthAuthenticationMiddleware.cs | 2 +- .../OAuthAuthenticationOptions.cs | 2 +- .../OAuthAuthenticationOptions`1.cs | 2 +- .../Properties/AssemblyInfo.cs | 2 +- src/Microsoft.AspNet.Authentication.OAuth/TokenResponse.cs | 2 +- .../Notifications/AuthenticationChallengeNotification.cs | 2 +- .../Notifications/OAuthBearerAuthenticationNotifications.cs | 2 +- .../OAuthBearerAppBuilderExtensions.cs | 2 +- .../OAuthBearerAuthenticationDefaults.cs | 2 +- .../OAuthBearerAuthenticationHandler.cs | 2 +- .../OAuthBearerAuthenticationMiddleware.cs | 2 +- .../OAuthBearerAuthenticationOptions.cs | 2 +- .../OAuthBearerServiceCollectionExtensions.cs | 2 +- .../Properties/AssemblyInfo.cs | 2 +- .../INonceCache.cs | 2 +- .../Notifications/AuthorizationCodeReceivedNotification.cs | 2 +- .../OpenIdConnectAuthenticationDefaults.cs | 2 +- .../OpenIdConnectAuthenticationExtensions.cs | 2 +- .../OpenIdConnectAuthenticationHandler.cs | 2 +- .../OpenIdConnectAuthenticationMiddleware.cs | 2 +- .../OpenIdConnectAuthenticationNotifications.cs | 2 +- .../OpenIdConnectAuthenticationOptions.cs | 2 +- .../OpenIdConnectServiceCollectionExtensions.cs | 2 +- .../Properties/AssemblyInfo.cs | 2 +- .../Messages/AccessToken.cs | 2 +- .../Messages/RequestToken.cs | 2 +- .../Messages/RequestTokenSerializer.cs | 2 +- .../Messages/Serializers.cs | 2 +- .../Notifications/ITwitterAuthenticationNotifications.cs | 2 +- .../Notifications/TwitterApplyRedirectContext.cs | 2 +- .../Notifications/TwitterAuthenticatedContext.cs | 2 +- .../Notifications/TwitterAuthenticationNotifications.cs | 2 +- .../Notifications/TwitterReturnEndpointContext.cs | 2 +- .../Properties/AssemblyInfo.cs | 2 +- .../TwitterAppBuilderExtensions.cs | 2 +- .../TwitterAuthenticationDefaults.cs | 2 +- .../TwitterAuthenticationHandler.cs | 2 +- .../TwitterAuthenticationMiddleware.cs | 2 +- .../TwitterAuthenticationOptions.cs | 2 +- .../TwitterServiceCollectionExtensions.cs | 2 +- src/Microsoft.AspNet.Authentication/AuthenticationHandler.cs | 2 +- src/Microsoft.AspNet.Authentication/AuthenticationHandler`1.cs | 2 +- src/Microsoft.AspNet.Authentication/AuthenticationMiddleware.cs | 2 +- src/Microsoft.AspNet.Authentication/AuthenticationOptions.cs | 2 +- .../AuthenticationServiceCollectionExtensions.cs | 2 +- src/Microsoft.AspNet.Authentication/AuthenticationTicket.cs | 2 +- .../AuthenticationTokenCreateContext.cs | 2 +- .../AuthenticationTokenProvider.cs | 2 +- .../AuthenticationTokenReceiveContext.cs | 2 +- .../CertificateSubjectKeyIdentifierValidator.cs | 2 +- .../CertificateSubjectPublicKeyInfoValidator.cs | 2 +- .../CertificateThumbprintValidator.cs | 2 +- .../ClaimsTransformationAppBuilderExtensions.cs | 2 +- .../ClaimsTransformationAuthenticationHandler.cs | 2 +- .../ClaimsTransformationMiddleware.cs | 2 +- .../ClaimsTransformationOptions.cs | 2 +- src/Microsoft.AspNet.Authentication/Constants.cs | 2 +- .../DataHandler/Encoder/Base64TextEncoder.cs | 2 +- .../DataHandler/Encoder/Base64UrlTextEncoder.cs | 2 +- .../DataHandler/Encoder/ITextEncoder.cs | 2 +- .../DataHandler/Encoder/TextEncodings.cs | 2 +- .../DataHandler/ISecureDataFormat.cs | 2 +- .../DataHandler/PropertiesDataFormat.cs | 2 +- .../DataHandler/SecureDataFormat.cs | 2 +- .../DataHandler/Serializer/DataSerializers.cs | 2 +- .../DataHandler/Serializer/IDataSerializer.cs | 2 +- .../DataHandler/Serializer/PropertiesSerializer.cs | 2 +- .../DataHandler/Serializer/TicketSerializer.cs | 2 +- .../DataHandler/TicketDataFormat.cs | 2 +- .../ExternalAuthenticationOptions.cs | 2 +- src/Microsoft.AspNet.Authentication/HttpContextExtensions.cs | 2 +- .../IAuthenticationTokenProvider.cs | 2 +- src/Microsoft.AspNet.Authentication/ICertificateValidator.cs | 2 +- src/Microsoft.AspNet.Authentication/ISystemClock.cs | 2 +- .../Notifications/AuthenticationFailedNotification.cs | 2 +- .../Notifications/BaseContext.cs | 2 +- .../Notifications/BaseContext`1.cs | 2 +- .../Notifications/BaseNotification.cs | 2 +- .../Notifications/EndpointContext.cs | 2 +- .../Notifications/EndpointContext`1.cs | 2 +- .../Notifications/MessageReceivedNotification.cs | 2 +- .../Notifications/NotificationResultState.cs | 2 +- .../Notifications/RedirectFromIdentityProviderNotification.cs | 2 +- .../Notifications/RedirectToIdentityProviderNotification.cs | 2 +- .../Notifications/ReturnEndpointContext.cs | 2 +- .../Notifications/SecurityTokenReceivedNotification.cs | 2 +- .../Notifications/SecurityTokenValidatedNotification.cs | 2 +- src/Microsoft.AspNet.Authentication/Properties/AssemblyInfo.cs | 2 +- src/Microsoft.AspNet.Authentication/SecurityHelper.cs | 2 +- .../SubjectPublicKeyInfoAlgorithm.cs | 2 +- src/Microsoft.AspNet.Authentication/SystemClock.cs | 2 +- src/Microsoft.AspNet.Authentication/Win32.cs | 2 +- src/Microsoft.AspNet.Authorization/AuthorizationContext.cs | 2 +- src/Microsoft.AspNet.Authorization/AuthorizationHandler.cs | 2 +- src/Microsoft.AspNet.Authorization/AuthorizationOptions.cs | 2 +- src/Microsoft.AspNet.Authorization/AuthorizationPolicy.cs | 2 +- .../AuthorizationPolicyBuilder.cs | 2 +- .../AuthorizationServiceExtensions.cs | 2 +- src/Microsoft.AspNet.Authorization/AuthorizeAttribute.cs | 2 +- .../ClaimsAuthorizationHandler.cs | 2 +- .../ClaimsAuthorizationRequirement.cs | 2 +- .../DefaultAuthorizationService.cs | 2 +- .../DenyAnonymousAuthorizationHandler.cs | 2 +- .../DenyAnonymousAuthorizationRequirement.cs | 2 +- src/Microsoft.AspNet.Authorization/IAuthorizationHandler.cs | 2 +- src/Microsoft.AspNet.Authorization/IAuthorizationRequirement.cs | 2 +- src/Microsoft.AspNet.Authorization/IAuthorizationService.cs | 2 +- .../OperationAuthorizationRequirement.cs | 2 +- .../PassThroughAuthorizationHandler.cs | 2 +- src/Microsoft.AspNet.Authorization/Properties/AssemblyInfo.cs | 2 +- .../ServiceCollectionExtensions.cs | 2 +- .../AuthenticationHandlerFacts.cs | 2 +- .../CertificateSubjectKeyIdentifierValidatorTests.cs | 2 +- .../CertificateSubjectPublicKeyInfoValidatorTests.cs | 2 +- .../CertificateThumbprintValidatorTests.cs | 2 +- .../Cookies/CookieMiddlewareTests.cs | 2 +- .../Cookies/Infrastructure/CookieChunkingTests.cs | 2 +- .../DataHandler/Encoder/Base64UrlTextEncoderTests.cs | 2 +- .../Facebook/FacebookMiddlewareTests.cs | 2 +- .../Google/GoogleMiddlewareTests.cs | 2 +- .../MicrosoftAccount/MicrosoftAccountMiddlewareTests.cs | 2 +- .../OAuthBearer/OAuthBearerMiddlewareTests.cs | 2 +- .../OpenIdConnect/OpenIdConnectHandlerTests.cs | 2 +- .../OpenIdConnect/OpenIdConnectMiddlewareTests.cs | 2 +- .../OpenIdConnect/TestUtilities.cs | 2 +- .../Microsoft.AspNet.Authentication.Test/SecurityHelperTests.cs | 2 +- test/Microsoft.AspNet.Authentication.Test/TestClock.cs | 2 +- .../Twitter/TwitterMiddlewareTests.cs | 2 +- .../AuthorizationPolicyFacts.cs | 2 +- .../DefaultAuthorizationServiceTests.cs | 2 +- 195 files changed, 195 insertions(+), 195 deletions(-) diff --git a/LICENSE.txt b/LICENSE.txt index d85a1524a..0bdc1962b 100644 --- a/LICENSE.txt +++ b/LICENSE.txt @@ -1,4 +1,4 @@ -Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +Copyright (c) .NET Foundation. All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use these files except in compliance with the License. You may obtain a copy of the diff --git a/src/Microsoft.AspNet.Authentication.Cookies/CookieAppBuilderExtensions.cs b/src/Microsoft.AspNet.Authentication.Cookies/CookieAppBuilderExtensions.cs index 3af76b243..d865dc4ce 100644 --- a/src/Microsoft.AspNet.Authentication.Cookies/CookieAppBuilderExtensions.cs +++ b/src/Microsoft.AspNet.Authentication.Cookies/CookieAppBuilderExtensions.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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; diff --git a/src/Microsoft.AspNet.Authentication.Cookies/CookieAuthenticationDefaults.cs b/src/Microsoft.AspNet.Authentication.Cookies/CookieAuthenticationDefaults.cs index d02b337f3..95981a0f0 100644 --- a/src/Microsoft.AspNet.Authentication.Cookies/CookieAuthenticationDefaults.cs +++ b/src/Microsoft.AspNet.Authentication.Cookies/CookieAuthenticationDefaults.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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.Diagnostics.CodeAnalysis; diff --git a/src/Microsoft.AspNet.Authentication.Cookies/CookieAuthenticationHandler.cs b/src/Microsoft.AspNet.Authentication.Cookies/CookieAuthenticationHandler.cs index 5e1acbcb1..2e71d1c0e 100644 --- a/src/Microsoft.AspNet.Authentication.Cookies/CookieAuthenticationHandler.cs +++ b/src/Microsoft.AspNet.Authentication.Cookies/CookieAuthenticationHandler.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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. diff --git a/src/Microsoft.AspNet.Authentication.Cookies/CookieAuthenticationMiddleware.cs b/src/Microsoft.AspNet.Authentication.Cookies/CookieAuthenticationMiddleware.cs index 2c7743932..70cafe854 100644 --- a/src/Microsoft.AspNet.Authentication.Cookies/CookieAuthenticationMiddleware.cs +++ b/src/Microsoft.AspNet.Authentication.Cookies/CookieAuthenticationMiddleware.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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; diff --git a/src/Microsoft.AspNet.Authentication.Cookies/CookieAuthenticationOptions.cs b/src/Microsoft.AspNet.Authentication.Cookies/CookieAuthenticationOptions.cs index c2fc4c3a7..966858fa6 100644 --- a/src/Microsoft.AspNet.Authentication.Cookies/CookieAuthenticationOptions.cs +++ b/src/Microsoft.AspNet.Authentication.Cookies/CookieAuthenticationOptions.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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; diff --git a/src/Microsoft.AspNet.Authentication.Cookies/CookieSecureOption.cs b/src/Microsoft.AspNet.Authentication.Cookies/CookieSecureOption.cs index c8309612b..83d34d0ae 100644 --- a/src/Microsoft.AspNet.Authentication.Cookies/CookieSecureOption.cs +++ b/src/Microsoft.AspNet.Authentication.Cookies/CookieSecureOption.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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. diff --git a/src/Microsoft.AspNet.Authentication.Cookies/CookieServiceCollectionExtensions.cs b/src/Microsoft.AspNet.Authentication.Cookies/CookieServiceCollectionExtensions.cs index af6d4d377..256844abd 100644 --- a/src/Microsoft.AspNet.Authentication.Cookies/CookieServiceCollectionExtensions.cs +++ b/src/Microsoft.AspNet.Authentication.Cookies/CookieServiceCollectionExtensions.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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; diff --git a/src/Microsoft.AspNet.Authentication.Cookies/Infrastructure/ChunkingCookieManager.cs b/src/Microsoft.AspNet.Authentication.Cookies/Infrastructure/ChunkingCookieManager.cs index 30af0b43d..62ab42dd2 100644 --- a/src/Microsoft.AspNet.Authentication.Cookies/Infrastructure/ChunkingCookieManager.cs +++ b/src/Microsoft.AspNet.Authentication.Cookies/Infrastructure/ChunkingCookieManager.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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; diff --git a/src/Microsoft.AspNet.Authentication.Cookies/Infrastructure/Constants.cs b/src/Microsoft.AspNet.Authentication.Cookies/Infrastructure/Constants.cs index b3c3bb3a7..6865cea0f 100644 --- a/src/Microsoft.AspNet.Authentication.Cookies/Infrastructure/Constants.cs +++ b/src/Microsoft.AspNet.Authentication.Cookies/Infrastructure/Constants.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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. namespace Microsoft.AspNet.Authentication.Cookies.Infrastructure diff --git a/src/Microsoft.AspNet.Authentication.Cookies/Infrastructure/IAuthenticationSessionStore.cs b/src/Microsoft.AspNet.Authentication.Cookies/Infrastructure/IAuthenticationSessionStore.cs index 6a6fa574b..6b2886d0a 100644 --- a/src/Microsoft.AspNet.Authentication.Cookies/Infrastructure/IAuthenticationSessionStore.cs +++ b/src/Microsoft.AspNet.Authentication.Cookies/Infrastructure/IAuthenticationSessionStore.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. +// Copyright (c) .NET Foundation. All rights reserved. See License.txt in the project root for license information. using System.Threading.Tasks; diff --git a/src/Microsoft.AspNet.Authentication.Cookies/Infrastructure/ICookieManager.cs b/src/Microsoft.AspNet.Authentication.Cookies/Infrastructure/ICookieManager.cs index 966d3f935..cffde3869 100644 --- a/src/Microsoft.AspNet.Authentication.Cookies/Infrastructure/ICookieManager.cs +++ b/src/Microsoft.AspNet.Authentication.Cookies/Infrastructure/ICookieManager.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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 Microsoft.AspNet.Http; diff --git a/src/Microsoft.AspNet.Authentication.Cookies/Notifications/CookieApplyRedirectContext.cs b/src/Microsoft.AspNet.Authentication.Cookies/Notifications/CookieApplyRedirectContext.cs index 877e9c5ea..cc6364817 100644 --- a/src/Microsoft.AspNet.Authentication.Cookies/Notifications/CookieApplyRedirectContext.cs +++ b/src/Microsoft.AspNet.Authentication.Cookies/Notifications/CookieApplyRedirectContext.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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. diff --git a/src/Microsoft.AspNet.Authentication.Cookies/Notifications/CookieAuthenticationNotifications.cs b/src/Microsoft.AspNet.Authentication.Cookies/Notifications/CookieAuthenticationNotifications.cs index f4c29dca4..dc287484a 100644 --- a/src/Microsoft.AspNet.Authentication.Cookies/Notifications/CookieAuthenticationNotifications.cs +++ b/src/Microsoft.AspNet.Authentication.Cookies/Notifications/CookieAuthenticationNotifications.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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. diff --git a/src/Microsoft.AspNet.Authentication.Cookies/Notifications/CookieExceptionContext.cs b/src/Microsoft.AspNet.Authentication.Cookies/Notifications/CookieExceptionContext.cs index 852e90b68..0d51f95d4 100644 --- a/src/Microsoft.AspNet.Authentication.Cookies/Notifications/CookieExceptionContext.cs +++ b/src/Microsoft.AspNet.Authentication.Cookies/Notifications/CookieExceptionContext.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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; diff --git a/src/Microsoft.AspNet.Authentication.Cookies/Notifications/CookieResponseSignInContext.cs b/src/Microsoft.AspNet.Authentication.Cookies/Notifications/CookieResponseSignInContext.cs index bf448a8dd..e9d7b1059 100644 --- a/src/Microsoft.AspNet.Authentication.Cookies/Notifications/CookieResponseSignInContext.cs +++ b/src/Microsoft.AspNet.Authentication.Cookies/Notifications/CookieResponseSignInContext.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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. diff --git a/src/Microsoft.AspNet.Authentication.Cookies/Notifications/CookieResponseSignOutContext.cs b/src/Microsoft.AspNet.Authentication.Cookies/Notifications/CookieResponseSignOutContext.cs index 4ba06bad3..28dce3cdf 100644 --- a/src/Microsoft.AspNet.Authentication.Cookies/Notifications/CookieResponseSignOutContext.cs +++ b/src/Microsoft.AspNet.Authentication.Cookies/Notifications/CookieResponseSignOutContext.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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. diff --git a/src/Microsoft.AspNet.Authentication.Cookies/Notifications/CookieResponseSignedInContext.cs b/src/Microsoft.AspNet.Authentication.Cookies/Notifications/CookieResponseSignedInContext.cs index ec0c3b876..df88fef98 100644 --- a/src/Microsoft.AspNet.Authentication.Cookies/Notifications/CookieResponseSignedInContext.cs +++ b/src/Microsoft.AspNet.Authentication.Cookies/Notifications/CookieResponseSignedInContext.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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.Security.Claims; diff --git a/src/Microsoft.AspNet.Authentication.Cookies/Notifications/CookieValidateIdentityContext.cs b/src/Microsoft.AspNet.Authentication.Cookies/Notifications/CookieValidateIdentityContext.cs index f9574bf80..ec795c468 100644 --- a/src/Microsoft.AspNet.Authentication.Cookies/Notifications/CookieValidateIdentityContext.cs +++ b/src/Microsoft.AspNet.Authentication.Cookies/Notifications/CookieValidateIdentityContext.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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.Security.Claims; diff --git a/src/Microsoft.AspNet.Authentication.Cookies/Notifications/DefaultBehavior.cs b/src/Microsoft.AspNet.Authentication.Cookies/Notifications/DefaultBehavior.cs index 0e0ed537c..77d537710 100644 --- a/src/Microsoft.AspNet.Authentication.Cookies/Notifications/DefaultBehavior.cs +++ b/src/Microsoft.AspNet.Authentication.Cookies/Notifications/DefaultBehavior.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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. diff --git a/src/Microsoft.AspNet.Authentication.Cookies/Notifications/ICookieAuthenticationNotifications.cs b/src/Microsoft.AspNet.Authentication.Cookies/Notifications/ICookieAuthenticationNotifications.cs index 0ede97ce6..3364207af 100644 --- a/src/Microsoft.AspNet.Authentication.Cookies/Notifications/ICookieAuthenticationNotifications.cs +++ b/src/Microsoft.AspNet.Authentication.Cookies/Notifications/ICookieAuthenticationNotifications.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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. diff --git a/src/Microsoft.AspNet.Authentication.Cookies/Properties/AssemblyInfo.cs b/src/Microsoft.AspNet.Authentication.Cookies/Properties/AssemblyInfo.cs index f5c6f4a83..025a94598 100644 --- a/src/Microsoft.AspNet.Authentication.Cookies/Properties/AssemblyInfo.cs +++ b/src/Microsoft.AspNet.Authentication.Cookies/Properties/AssemblyInfo.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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.Reflection; diff --git a/src/Microsoft.AspNet.Authentication.Facebook/FacebookAppBuilderExtensions.cs b/src/Microsoft.AspNet.Authentication.Facebook/FacebookAppBuilderExtensions.cs index 0758d43ac..24e1e0726 100644 --- a/src/Microsoft.AspNet.Authentication.Facebook/FacebookAppBuilderExtensions.cs +++ b/src/Microsoft.AspNet.Authentication.Facebook/FacebookAppBuilderExtensions.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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; diff --git a/src/Microsoft.AspNet.Authentication.Facebook/FacebookAuthenticationDefaults.cs b/src/Microsoft.AspNet.Authentication.Facebook/FacebookAuthenticationDefaults.cs index 92b56413a..54d48cbc5 100644 --- a/src/Microsoft.AspNet.Authentication.Facebook/FacebookAuthenticationDefaults.cs +++ b/src/Microsoft.AspNet.Authentication.Facebook/FacebookAuthenticationDefaults.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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. namespace Microsoft.AspNet.Authentication.Facebook diff --git a/src/Microsoft.AspNet.Authentication.Facebook/FacebookAuthenticationHandler.cs b/src/Microsoft.AspNet.Authentication.Facebook/FacebookAuthenticationHandler.cs index 3f5766e50..aa306d683 100644 --- a/src/Microsoft.AspNet.Authentication.Facebook/FacebookAuthenticationHandler.cs +++ b/src/Microsoft.AspNet.Authentication.Facebook/FacebookAuthenticationHandler.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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; diff --git a/src/Microsoft.AspNet.Authentication.Facebook/FacebookAuthenticationMiddleware.cs b/src/Microsoft.AspNet.Authentication.Facebook/FacebookAuthenticationMiddleware.cs index 4fa9224c9..ad10432c5 100644 --- a/src/Microsoft.AspNet.Authentication.Facebook/FacebookAuthenticationMiddleware.cs +++ b/src/Microsoft.AspNet.Authentication.Facebook/FacebookAuthenticationMiddleware.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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; diff --git a/src/Microsoft.AspNet.Authentication.Facebook/FacebookAuthenticationOptions.cs b/src/Microsoft.AspNet.Authentication.Facebook/FacebookAuthenticationOptions.cs index 119bd25b8..c7ba48aab 100644 --- a/src/Microsoft.AspNet.Authentication.Facebook/FacebookAuthenticationOptions.cs +++ b/src/Microsoft.AspNet.Authentication.Facebook/FacebookAuthenticationOptions.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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 Microsoft.AspNet.Http; diff --git a/src/Microsoft.AspNet.Authentication.Facebook/FacebookServiceCollectionExtensions.cs b/src/Microsoft.AspNet.Authentication.Facebook/FacebookServiceCollectionExtensions.cs index 1550a6cd8..771197b50 100644 --- a/src/Microsoft.AspNet.Authentication.Facebook/FacebookServiceCollectionExtensions.cs +++ b/src/Microsoft.AspNet.Authentication.Facebook/FacebookServiceCollectionExtensions.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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; diff --git a/src/Microsoft.AspNet.Authentication.Facebook/Notifications/FacebookAuthenticatedContext.cs b/src/Microsoft.AspNet.Authentication.Facebook/Notifications/FacebookAuthenticatedContext.cs index 084b27347..321b78f8b 100644 --- a/src/Microsoft.AspNet.Authentication.Facebook/Notifications/FacebookAuthenticatedContext.cs +++ b/src/Microsoft.AspNet.Authentication.Facebook/Notifications/FacebookAuthenticatedContext.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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 Microsoft.AspNet.Http; diff --git a/src/Microsoft.AspNet.Authentication.Facebook/Notifications/FacebookAuthenticationNotifications.cs b/src/Microsoft.AspNet.Authentication.Facebook/Notifications/FacebookAuthenticationNotifications.cs index b89ad5c3b..acee5b54e 100644 --- a/src/Microsoft.AspNet.Authentication.Facebook/Notifications/FacebookAuthenticationNotifications.cs +++ b/src/Microsoft.AspNet.Authentication.Facebook/Notifications/FacebookAuthenticationNotifications.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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; diff --git a/src/Microsoft.AspNet.Authentication.Facebook/Notifications/IFacebookAuthenticationNotifications.cs b/src/Microsoft.AspNet.Authentication.Facebook/Notifications/IFacebookAuthenticationNotifications.cs index 247715f93..aff7de6ee 100644 --- a/src/Microsoft.AspNet.Authentication.Facebook/Notifications/IFacebookAuthenticationNotifications.cs +++ b/src/Microsoft.AspNet.Authentication.Facebook/Notifications/IFacebookAuthenticationNotifications.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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.Threading.Tasks; diff --git a/src/Microsoft.AspNet.Authentication.Facebook/Properties/AssemblyInfo.cs b/src/Microsoft.AspNet.Authentication.Facebook/Properties/AssemblyInfo.cs index f5c6f4a83..025a94598 100644 --- a/src/Microsoft.AspNet.Authentication.Facebook/Properties/AssemblyInfo.cs +++ b/src/Microsoft.AspNet.Authentication.Facebook/Properties/AssemblyInfo.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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.Reflection; diff --git a/src/Microsoft.AspNet.Authentication.Google/GoogleAppBuilderExtensions.cs b/src/Microsoft.AspNet.Authentication.Google/GoogleAppBuilderExtensions.cs index dc73a1666..e00dcffdd 100644 --- a/src/Microsoft.AspNet.Authentication.Google/GoogleAppBuilderExtensions.cs +++ b/src/Microsoft.AspNet.Authentication.Google/GoogleAppBuilderExtensions.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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; diff --git a/src/Microsoft.AspNet.Authentication.Google/GoogleAuthenticationDefaults.cs b/src/Microsoft.AspNet.Authentication.Google/GoogleAuthenticationDefaults.cs index 3c163c111..88aa4f1f1 100644 --- a/src/Microsoft.AspNet.Authentication.Google/GoogleAuthenticationDefaults.cs +++ b/src/Microsoft.AspNet.Authentication.Google/GoogleAuthenticationDefaults.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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. namespace Microsoft.AspNet.Authentication.Google diff --git a/src/Microsoft.AspNet.Authentication.Google/GoogleAuthenticationHandler.cs b/src/Microsoft.AspNet.Authentication.Google/GoogleAuthenticationHandler.cs index c30e70526..b54f657be 100644 --- a/src/Microsoft.AspNet.Authentication.Google/GoogleAuthenticationHandler.cs +++ b/src/Microsoft.AspNet.Authentication.Google/GoogleAuthenticationHandler.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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; diff --git a/src/Microsoft.AspNet.Authentication.Google/GoogleAuthenticationMiddleware.cs b/src/Microsoft.AspNet.Authentication.Google/GoogleAuthenticationMiddleware.cs index 3f0bd745d..2921b6b21 100644 --- a/src/Microsoft.AspNet.Authentication.Google/GoogleAuthenticationMiddleware.cs +++ b/src/Microsoft.AspNet.Authentication.Google/GoogleAuthenticationMiddleware.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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; diff --git a/src/Microsoft.AspNet.Authentication.Google/GoogleAuthenticationOptions.cs b/src/Microsoft.AspNet.Authentication.Google/GoogleAuthenticationOptions.cs index 30446b3b5..1dab084f0 100644 --- a/src/Microsoft.AspNet.Authentication.Google/GoogleAuthenticationOptions.cs +++ b/src/Microsoft.AspNet.Authentication.Google/GoogleAuthenticationOptions.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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; diff --git a/src/Microsoft.AspNet.Authentication.Google/GoogleServiceCollectionExtensions.cs b/src/Microsoft.AspNet.Authentication.Google/GoogleServiceCollectionExtensions.cs index 6928c48fc..bb7ce223c 100644 --- a/src/Microsoft.AspNet.Authentication.Google/GoogleServiceCollectionExtensions.cs +++ b/src/Microsoft.AspNet.Authentication.Google/GoogleServiceCollectionExtensions.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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; diff --git a/src/Microsoft.AspNet.Authentication.Google/Notifications/GoogleAuthenticatedContext.cs b/src/Microsoft.AspNet.Authentication.Google/Notifications/GoogleAuthenticatedContext.cs index a18ba2040..915b80436 100644 --- a/src/Microsoft.AspNet.Authentication.Google/Notifications/GoogleAuthenticatedContext.cs +++ b/src/Microsoft.AspNet.Authentication.Google/Notifications/GoogleAuthenticatedContext.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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; diff --git a/src/Microsoft.AspNet.Authentication.Google/Notifications/GoogleAuthenticationNotifications.cs b/src/Microsoft.AspNet.Authentication.Google/Notifications/GoogleAuthenticationNotifications.cs index 27d24e3cd..51269aeff 100644 --- a/src/Microsoft.AspNet.Authentication.Google/Notifications/GoogleAuthenticationNotifications.cs +++ b/src/Microsoft.AspNet.Authentication.Google/Notifications/GoogleAuthenticationNotifications.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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; diff --git a/src/Microsoft.AspNet.Authentication.Google/Notifications/IGoogleAuthenticationNotifications.cs b/src/Microsoft.AspNet.Authentication.Google/Notifications/IGoogleAuthenticationNotifications.cs index e9f7c492e..30ce69778 100644 --- a/src/Microsoft.AspNet.Authentication.Google/Notifications/IGoogleAuthenticationNotifications.cs +++ b/src/Microsoft.AspNet.Authentication.Google/Notifications/IGoogleAuthenticationNotifications.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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.Threading.Tasks; diff --git a/src/Microsoft.AspNet.Authentication.Google/Properties/AssemblyInfo.cs b/src/Microsoft.AspNet.Authentication.Google/Properties/AssemblyInfo.cs index f5c6f4a83..025a94598 100644 --- a/src/Microsoft.AspNet.Authentication.Google/Properties/AssemblyInfo.cs +++ b/src/Microsoft.AspNet.Authentication.Google/Properties/AssemblyInfo.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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.Reflection; diff --git a/src/Microsoft.AspNet.Authentication.MicrosoftAccount/MicrosoftAccountAppBuilderExtensions.cs b/src/Microsoft.AspNet.Authentication.MicrosoftAccount/MicrosoftAccountAppBuilderExtensions.cs index a404845c8..b7c1d0ca9 100644 --- a/src/Microsoft.AspNet.Authentication.MicrosoftAccount/MicrosoftAccountAppBuilderExtensions.cs +++ b/src/Microsoft.AspNet.Authentication.MicrosoftAccount/MicrosoftAccountAppBuilderExtensions.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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; diff --git a/src/Microsoft.AspNet.Authentication.MicrosoftAccount/MicrosoftAccountAuthenticationDefaults.cs b/src/Microsoft.AspNet.Authentication.MicrosoftAccount/MicrosoftAccountAuthenticationDefaults.cs index 22ca51751..d42368cdc 100644 --- a/src/Microsoft.AspNet.Authentication.MicrosoftAccount/MicrosoftAccountAuthenticationDefaults.cs +++ b/src/Microsoft.AspNet.Authentication.MicrosoftAccount/MicrosoftAccountAuthenticationDefaults.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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. namespace Microsoft.AspNet.Authentication.MicrosoftAccount diff --git a/src/Microsoft.AspNet.Authentication.MicrosoftAccount/MicrosoftAccountAuthenticationHandler.cs b/src/Microsoft.AspNet.Authentication.MicrosoftAccount/MicrosoftAccountAuthenticationHandler.cs index 5696ce16a..4ecaabab6 100644 --- a/src/Microsoft.AspNet.Authentication.MicrosoftAccount/MicrosoftAccountAuthenticationHandler.cs +++ b/src/Microsoft.AspNet.Authentication.MicrosoftAccount/MicrosoftAccountAuthenticationHandler.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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.Net.Http; diff --git a/src/Microsoft.AspNet.Authentication.MicrosoftAccount/MicrosoftAccountAuthenticationMiddleware.cs b/src/Microsoft.AspNet.Authentication.MicrosoftAccount/MicrosoftAccountAuthenticationMiddleware.cs index 06001f183..362664629 100644 --- a/src/Microsoft.AspNet.Authentication.MicrosoftAccount/MicrosoftAccountAuthenticationMiddleware.cs +++ b/src/Microsoft.AspNet.Authentication.MicrosoftAccount/MicrosoftAccountAuthenticationMiddleware.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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 Microsoft.AspNet.Authentication.OAuth; diff --git a/src/Microsoft.AspNet.Authentication.MicrosoftAccount/MicrosoftAccountAuthenticationOptions.cs b/src/Microsoft.AspNet.Authentication.MicrosoftAccount/MicrosoftAccountAuthenticationOptions.cs index f97f84b94..0212b6e7d 100644 --- a/src/Microsoft.AspNet.Authentication.MicrosoftAccount/MicrosoftAccountAuthenticationOptions.cs +++ b/src/Microsoft.AspNet.Authentication.MicrosoftAccount/MicrosoftAccountAuthenticationOptions.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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 Microsoft.AspNet.Http; diff --git a/src/Microsoft.AspNet.Authentication.MicrosoftAccount/MicrosoftAccountServiceCollectionExtensions.cs b/src/Microsoft.AspNet.Authentication.MicrosoftAccount/MicrosoftAccountServiceCollectionExtensions.cs index 8f0de0755..556b1fb87 100644 --- a/src/Microsoft.AspNet.Authentication.MicrosoftAccount/MicrosoftAccountServiceCollectionExtensions.cs +++ b/src/Microsoft.AspNet.Authentication.MicrosoftAccount/MicrosoftAccountServiceCollectionExtensions.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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; diff --git a/src/Microsoft.AspNet.Authentication.MicrosoftAccount/Notifications/IMicrosoftAccountAuthenticationNotifications.cs b/src/Microsoft.AspNet.Authentication.MicrosoftAccount/Notifications/IMicrosoftAccountAuthenticationNotifications.cs index f96040925..d9647e4cd 100644 --- a/src/Microsoft.AspNet.Authentication.MicrosoftAccount/Notifications/IMicrosoftAccountAuthenticationNotifications.cs +++ b/src/Microsoft.AspNet.Authentication.MicrosoftAccount/Notifications/IMicrosoftAccountAuthenticationNotifications.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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.Threading.Tasks; diff --git a/src/Microsoft.AspNet.Authentication.MicrosoftAccount/Notifications/MicrosoftAccountAuthenticatedContext.cs b/src/Microsoft.AspNet.Authentication.MicrosoftAccount/Notifications/MicrosoftAccountAuthenticatedContext.cs index ed55b4de3..7d6a31cd2 100644 --- a/src/Microsoft.AspNet.Authentication.MicrosoftAccount/Notifications/MicrosoftAccountAuthenticatedContext.cs +++ b/src/Microsoft.AspNet.Authentication.MicrosoftAccount/Notifications/MicrosoftAccountAuthenticatedContext.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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; diff --git a/src/Microsoft.AspNet.Authentication.MicrosoftAccount/Notifications/MicrosoftAccountAuthenticationNotifications.cs b/src/Microsoft.AspNet.Authentication.MicrosoftAccount/Notifications/MicrosoftAccountAuthenticationNotifications.cs index 70dc8faa5..16491a4ed 100644 --- a/src/Microsoft.AspNet.Authentication.MicrosoftAccount/Notifications/MicrosoftAccountAuthenticationNotifications.cs +++ b/src/Microsoft.AspNet.Authentication.MicrosoftAccount/Notifications/MicrosoftAccountAuthenticationNotifications.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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; diff --git a/src/Microsoft.AspNet.Authentication.MicrosoftAccount/Properties/AssemblyInfo.cs b/src/Microsoft.AspNet.Authentication.MicrosoftAccount/Properties/AssemblyInfo.cs index f5c6f4a83..025a94598 100644 --- a/src/Microsoft.AspNet.Authentication.MicrosoftAccount/Properties/AssemblyInfo.cs +++ b/src/Microsoft.AspNet.Authentication.MicrosoftAccount/Properties/AssemblyInfo.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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.Reflection; diff --git a/src/Microsoft.AspNet.Authentication.OAuth/Notifications/BaseValidatingContext.cs b/src/Microsoft.AspNet.Authentication.OAuth/Notifications/BaseValidatingContext.cs index 84e8c0df4..1dec37860 100644 --- a/src/Microsoft.AspNet.Authentication.OAuth/Notifications/BaseValidatingContext.cs +++ b/src/Microsoft.AspNet.Authentication.OAuth/Notifications/BaseValidatingContext.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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 Microsoft.AspNet.Http; diff --git a/src/Microsoft.AspNet.Authentication.OAuth/Notifications/BaseValidatingTicketContext.cs b/src/Microsoft.AspNet.Authentication.OAuth/Notifications/BaseValidatingTicketContext.cs index f44af9328..6d088c853 100644 --- a/src/Microsoft.AspNet.Authentication.OAuth/Notifications/BaseValidatingTicketContext.cs +++ b/src/Microsoft.AspNet.Authentication.OAuth/Notifications/BaseValidatingTicketContext.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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.Security.Claims; diff --git a/src/Microsoft.AspNet.Authentication.OAuth/Notifications/IOAuthAuthenticationNotifications.cs b/src/Microsoft.AspNet.Authentication.OAuth/Notifications/IOAuthAuthenticationNotifications.cs index 2161d70fd..6d386d089 100644 --- a/src/Microsoft.AspNet.Authentication.OAuth/Notifications/IOAuthAuthenticationNotifications.cs +++ b/src/Microsoft.AspNet.Authentication.OAuth/Notifications/IOAuthAuthenticationNotifications.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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.Threading.Tasks; diff --git a/src/Microsoft.AspNet.Authentication.OAuth/Notifications/OAuthApplyRedirectContext.cs b/src/Microsoft.AspNet.Authentication.OAuth/Notifications/OAuthApplyRedirectContext.cs index 070e1994e..71c61f261 100644 --- a/src/Microsoft.AspNet.Authentication.OAuth/Notifications/OAuthApplyRedirectContext.cs +++ b/src/Microsoft.AspNet.Authentication.OAuth/Notifications/OAuthApplyRedirectContext.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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 Microsoft.AspNet.Http; diff --git a/src/Microsoft.AspNet.Authentication.OAuth/Notifications/OAuthAuthenticatedContext.cs b/src/Microsoft.AspNet.Authentication.OAuth/Notifications/OAuthAuthenticatedContext.cs index 7283a80c6..d03411747 100644 --- a/src/Microsoft.AspNet.Authentication.OAuth/Notifications/OAuthAuthenticatedContext.cs +++ b/src/Microsoft.AspNet.Authentication.OAuth/Notifications/OAuthAuthenticatedContext.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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; diff --git a/src/Microsoft.AspNet.Authentication.OAuth/Notifications/OAuthAuthenticationNotifications.cs b/src/Microsoft.AspNet.Authentication.OAuth/Notifications/OAuthAuthenticationNotifications.cs index a20821889..aa6d7a811 100644 --- a/src/Microsoft.AspNet.Authentication.OAuth/Notifications/OAuthAuthenticationNotifications.cs +++ b/src/Microsoft.AspNet.Authentication.OAuth/Notifications/OAuthAuthenticationNotifications.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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; diff --git a/src/Microsoft.AspNet.Authentication.OAuth/Notifications/OAuthChallengeContext.cs b/src/Microsoft.AspNet.Authentication.OAuth/Notifications/OAuthChallengeContext.cs index 55dd72008..00560432d 100644 --- a/src/Microsoft.AspNet.Authentication.OAuth/Notifications/OAuthChallengeContext.cs +++ b/src/Microsoft.AspNet.Authentication.OAuth/Notifications/OAuthChallengeContext.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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 Microsoft.AspNet.Http; diff --git a/src/Microsoft.AspNet.Authentication.OAuth/Notifications/OAuthGetUserInformationContext.cs b/src/Microsoft.AspNet.Authentication.OAuth/Notifications/OAuthGetUserInformationContext.cs index 8d2405ebf..74d02cd58 100644 --- a/src/Microsoft.AspNet.Authentication.OAuth/Notifications/OAuthGetUserInformationContext.cs +++ b/src/Microsoft.AspNet.Authentication.OAuth/Notifications/OAuthGetUserInformationContext.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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; diff --git a/src/Microsoft.AspNet.Authentication.OAuth/Notifications/OAuthRequestTokenContext.cs b/src/Microsoft.AspNet.Authentication.OAuth/Notifications/OAuthRequestTokenContext.cs index cd9294a42..8af4bf6c6 100644 --- a/src/Microsoft.AspNet.Authentication.OAuth/Notifications/OAuthRequestTokenContext.cs +++ b/src/Microsoft.AspNet.Authentication.OAuth/Notifications/OAuthRequestTokenContext.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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 Microsoft.AspNet.Http; diff --git a/src/Microsoft.AspNet.Authentication.OAuth/Notifications/OAuthReturnEndpointContext.cs b/src/Microsoft.AspNet.Authentication.OAuth/Notifications/OAuthReturnEndpointContext.cs index ce9ffd4ea..222420797 100644 --- a/src/Microsoft.AspNet.Authentication.OAuth/Notifications/OAuthReturnEndpointContext.cs +++ b/src/Microsoft.AspNet.Authentication.OAuth/Notifications/OAuthReturnEndpointContext.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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 Microsoft.AspNet.Http; diff --git a/src/Microsoft.AspNet.Authentication.OAuth/OAuthAuthenticationDefaults.cs b/src/Microsoft.AspNet.Authentication.OAuth/OAuthAuthenticationDefaults.cs index 90dc2b616..a9b93d43a 100644 --- a/src/Microsoft.AspNet.Authentication.OAuth/OAuthAuthenticationDefaults.cs +++ b/src/Microsoft.AspNet.Authentication.OAuth/OAuthAuthenticationDefaults.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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; diff --git a/src/Microsoft.AspNet.Authentication.OAuth/OAuthAuthenticationExtensions.cs b/src/Microsoft.AspNet.Authentication.OAuth/OAuthAuthenticationExtensions.cs index 79e669d21..3c6b3db9a 100644 --- a/src/Microsoft.AspNet.Authentication.OAuth/OAuthAuthenticationExtensions.cs +++ b/src/Microsoft.AspNet.Authentication.OAuth/OAuthAuthenticationExtensions.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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; diff --git a/src/Microsoft.AspNet.Authentication.OAuth/OAuthAuthenticationHandler.cs b/src/Microsoft.AspNet.Authentication.OAuth/OAuthAuthenticationHandler.cs index 21c684a68..d9c218344 100644 --- a/src/Microsoft.AspNet.Authentication.OAuth/OAuthAuthenticationHandler.cs +++ b/src/Microsoft.AspNet.Authentication.OAuth/OAuthAuthenticationHandler.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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; diff --git a/src/Microsoft.AspNet.Authentication.OAuth/OAuthAuthenticationMiddleware.cs b/src/Microsoft.AspNet.Authentication.OAuth/OAuthAuthenticationMiddleware.cs index 3188a1bd9..e4357a68a 100644 --- a/src/Microsoft.AspNet.Authentication.OAuth/OAuthAuthenticationMiddleware.cs +++ b/src/Microsoft.AspNet.Authentication.OAuth/OAuthAuthenticationMiddleware.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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; diff --git a/src/Microsoft.AspNet.Authentication.OAuth/OAuthAuthenticationOptions.cs b/src/Microsoft.AspNet.Authentication.OAuth/OAuthAuthenticationOptions.cs index bd9ab43b0..bfbea1e29 100644 --- a/src/Microsoft.AspNet.Authentication.OAuth/OAuthAuthenticationOptions.cs +++ b/src/Microsoft.AspNet.Authentication.OAuth/OAuthAuthenticationOptions.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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; diff --git a/src/Microsoft.AspNet.Authentication.OAuth/OAuthAuthenticationOptions`1.cs b/src/Microsoft.AspNet.Authentication.OAuth/OAuthAuthenticationOptions`1.cs index 2a37062d3..aa989dfe5 100644 --- a/src/Microsoft.AspNet.Authentication.OAuth/OAuthAuthenticationOptions`1.cs +++ b/src/Microsoft.AspNet.Authentication.OAuth/OAuthAuthenticationOptions`1.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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. namespace Microsoft.AspNet.Authentication.OAuth diff --git a/src/Microsoft.AspNet.Authentication.OAuth/Properties/AssemblyInfo.cs b/src/Microsoft.AspNet.Authentication.OAuth/Properties/AssemblyInfo.cs index f5c6f4a83..025a94598 100644 --- a/src/Microsoft.AspNet.Authentication.OAuth/Properties/AssemblyInfo.cs +++ b/src/Microsoft.AspNet.Authentication.OAuth/Properties/AssemblyInfo.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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.Reflection; diff --git a/src/Microsoft.AspNet.Authentication.OAuth/TokenResponse.cs b/src/Microsoft.AspNet.Authentication.OAuth/TokenResponse.cs index 4acc2d6e0..5bcb80ad8 100644 --- a/src/Microsoft.AspNet.Authentication.OAuth/TokenResponse.cs +++ b/src/Microsoft.AspNet.Authentication.OAuth/TokenResponse.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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 Newtonsoft.Json.Linq; diff --git a/src/Microsoft.AspNet.Authentication.OAuthBearer/Notifications/AuthenticationChallengeNotification.cs b/src/Microsoft.AspNet.Authentication.OAuthBearer/Notifications/AuthenticationChallengeNotification.cs index 53e02673c..a3bc8af03 100644 --- a/src/Microsoft.AspNet.Authentication.OAuthBearer/Notifications/AuthenticationChallengeNotification.cs +++ b/src/Microsoft.AspNet.Authentication.OAuthBearer/Notifications/AuthenticationChallengeNotification.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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 Microsoft.AspNet.Http; diff --git a/src/Microsoft.AspNet.Authentication.OAuthBearer/Notifications/OAuthBearerAuthenticationNotifications.cs b/src/Microsoft.AspNet.Authentication.OAuthBearer/Notifications/OAuthBearerAuthenticationNotifications.cs index 3c87d520a..648ff036d 100644 --- a/src/Microsoft.AspNet.Authentication.OAuthBearer/Notifications/OAuthBearerAuthenticationNotifications.cs +++ b/src/Microsoft.AspNet.Authentication.OAuthBearer/Notifications/OAuthBearerAuthenticationNotifications.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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; diff --git a/src/Microsoft.AspNet.Authentication.OAuthBearer/OAuthBearerAppBuilderExtensions.cs b/src/Microsoft.AspNet.Authentication.OAuthBearer/OAuthBearerAppBuilderExtensions.cs index 06be46390..f50b2a401 100644 --- a/src/Microsoft.AspNet.Authentication.OAuthBearer/OAuthBearerAppBuilderExtensions.cs +++ b/src/Microsoft.AspNet.Authentication.OAuthBearer/OAuthBearerAppBuilderExtensions.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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; diff --git a/src/Microsoft.AspNet.Authentication.OAuthBearer/OAuthBearerAuthenticationDefaults.cs b/src/Microsoft.AspNet.Authentication.OAuthBearer/OAuthBearerAuthenticationDefaults.cs index e16483ef0..2dc1797e9 100644 --- a/src/Microsoft.AspNet.Authentication.OAuthBearer/OAuthBearerAuthenticationDefaults.cs +++ b/src/Microsoft.AspNet.Authentication.OAuthBearer/OAuthBearerAuthenticationDefaults.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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. namespace Microsoft.AspNet.Authentication.OAuthBearer diff --git a/src/Microsoft.AspNet.Authentication.OAuthBearer/OAuthBearerAuthenticationHandler.cs b/src/Microsoft.AspNet.Authentication.OAuthBearer/OAuthBearerAuthenticationHandler.cs index 745c36f0f..c88d45604 100644 --- a/src/Microsoft.AspNet.Authentication.OAuthBearer/OAuthBearerAuthenticationHandler.cs +++ b/src/Microsoft.AspNet.Authentication.OAuthBearer/OAuthBearerAuthenticationHandler.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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; diff --git a/src/Microsoft.AspNet.Authentication.OAuthBearer/OAuthBearerAuthenticationMiddleware.cs b/src/Microsoft.AspNet.Authentication.OAuthBearer/OAuthBearerAuthenticationMiddleware.cs index 1bde86c83..ed1242b95 100644 --- a/src/Microsoft.AspNet.Authentication.OAuthBearer/OAuthBearerAuthenticationMiddleware.cs +++ b/src/Microsoft.AspNet.Authentication.OAuthBearer/OAuthBearerAuthenticationMiddleware.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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; diff --git a/src/Microsoft.AspNet.Authentication.OAuthBearer/OAuthBearerAuthenticationOptions.cs b/src/Microsoft.AspNet.Authentication.OAuthBearer/OAuthBearerAuthenticationOptions.cs index 9bbc6300c..00cc96c7a 100644 --- a/src/Microsoft.AspNet.Authentication.OAuthBearer/OAuthBearerAuthenticationOptions.cs +++ b/src/Microsoft.AspNet.Authentication.OAuthBearer/OAuthBearerAuthenticationOptions.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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; diff --git a/src/Microsoft.AspNet.Authentication.OAuthBearer/OAuthBearerServiceCollectionExtensions.cs b/src/Microsoft.AspNet.Authentication.OAuthBearer/OAuthBearerServiceCollectionExtensions.cs index 1b1bce814..51080737b 100644 --- a/src/Microsoft.AspNet.Authentication.OAuthBearer/OAuthBearerServiceCollectionExtensions.cs +++ b/src/Microsoft.AspNet.Authentication.OAuthBearer/OAuthBearerServiceCollectionExtensions.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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; diff --git a/src/Microsoft.AspNet.Authentication.OAuthBearer/Properties/AssemblyInfo.cs b/src/Microsoft.AspNet.Authentication.OAuthBearer/Properties/AssemblyInfo.cs index f5c6f4a83..025a94598 100644 --- a/src/Microsoft.AspNet.Authentication.OAuthBearer/Properties/AssemblyInfo.cs +++ b/src/Microsoft.AspNet.Authentication.OAuthBearer/Properties/AssemblyInfo.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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.Reflection; diff --git a/src/Microsoft.AspNet.Authentication.OpenIdConnect/INonceCache.cs b/src/Microsoft.AspNet.Authentication.OpenIdConnect/INonceCache.cs index a56117560..8dc39aa9d 100644 --- a/src/Microsoft.AspNet.Authentication.OpenIdConnect/INonceCache.cs +++ b/src/Microsoft.AspNet.Authentication.OpenIdConnect/INonceCache.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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. namespace Microsoft.AspNet.Authentication.OpenIdConnect diff --git a/src/Microsoft.AspNet.Authentication.OpenIdConnect/Notifications/AuthorizationCodeReceivedNotification.cs b/src/Microsoft.AspNet.Authentication.OpenIdConnect/Notifications/AuthorizationCodeReceivedNotification.cs index 167f7f8dd..740a0e63c 100644 --- a/src/Microsoft.AspNet.Authentication.OpenIdConnect/Notifications/AuthorizationCodeReceivedNotification.cs +++ b/src/Microsoft.AspNet.Authentication.OpenIdConnect/Notifications/AuthorizationCodeReceivedNotification.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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 Microsoft.AspNet.Http; diff --git a/src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenIdConnectAuthenticationDefaults.cs b/src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenIdConnectAuthenticationDefaults.cs index cecc57a74..763ef11d3 100644 --- a/src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenIdConnectAuthenticationDefaults.cs +++ b/src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenIdConnectAuthenticationDefaults.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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. namespace Microsoft.AspNet.Authentication.OpenIdConnect diff --git a/src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenIdConnectAuthenticationExtensions.cs b/src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenIdConnectAuthenticationExtensions.cs index 4ced947e2..c4a1961f1 100644 --- a/src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenIdConnectAuthenticationExtensions.cs +++ b/src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenIdConnectAuthenticationExtensions.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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; diff --git a/src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenIdConnectAuthenticationHandler.cs b/src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenIdConnectAuthenticationHandler.cs index 3ea2a4578..cc132e9bb 100644 --- a/src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenIdConnectAuthenticationHandler.cs +++ b/src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenIdConnectAuthenticationHandler.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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; diff --git a/src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenIdConnectAuthenticationMiddleware.cs b/src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenIdConnectAuthenticationMiddleware.cs index 70e45d0c2..9353f385c 100644 --- a/src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenIdConnectAuthenticationMiddleware.cs +++ b/src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenIdConnectAuthenticationMiddleware.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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; diff --git a/src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenIdConnectAuthenticationNotifications.cs b/src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenIdConnectAuthenticationNotifications.cs index a4f15d6e9..11c8c9ccc 100644 --- a/src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenIdConnectAuthenticationNotifications.cs +++ b/src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenIdConnectAuthenticationNotifications.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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; diff --git a/src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenIdConnectAuthenticationOptions.cs b/src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenIdConnectAuthenticationOptions.cs index 4a306c731..b89699b14 100644 --- a/src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenIdConnectAuthenticationOptions.cs +++ b/src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenIdConnectAuthenticationOptions.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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; diff --git a/src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenIdConnectServiceCollectionExtensions.cs b/src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenIdConnectServiceCollectionExtensions.cs index 2e55b96fa..8d2e9e355 100644 --- a/src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenIdConnectServiceCollectionExtensions.cs +++ b/src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenIdConnectServiceCollectionExtensions.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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; diff --git a/src/Microsoft.AspNet.Authentication.OpenIdConnect/Properties/AssemblyInfo.cs b/src/Microsoft.AspNet.Authentication.OpenIdConnect/Properties/AssemblyInfo.cs index f5c6f4a83..025a94598 100644 --- a/src/Microsoft.AspNet.Authentication.OpenIdConnect/Properties/AssemblyInfo.cs +++ b/src/Microsoft.AspNet.Authentication.OpenIdConnect/Properties/AssemblyInfo.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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.Reflection; diff --git a/src/Microsoft.AspNet.Authentication.Twitter/Messages/AccessToken.cs b/src/Microsoft.AspNet.Authentication.Twitter/Messages/AccessToken.cs index 2c3351453..f723da742 100644 --- a/src/Microsoft.AspNet.Authentication.Twitter/Messages/AccessToken.cs +++ b/src/Microsoft.AspNet.Authentication.Twitter/Messages/AccessToken.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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. namespace Microsoft.AspNet.Authentication.Twitter.Messages diff --git a/src/Microsoft.AspNet.Authentication.Twitter/Messages/RequestToken.cs b/src/Microsoft.AspNet.Authentication.Twitter/Messages/RequestToken.cs index 51c5c08e4..963ad1d7d 100644 --- a/src/Microsoft.AspNet.Authentication.Twitter/Messages/RequestToken.cs +++ b/src/Microsoft.AspNet.Authentication.Twitter/Messages/RequestToken.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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 Microsoft.AspNet.Http.Authentication; diff --git a/src/Microsoft.AspNet.Authentication.Twitter/Messages/RequestTokenSerializer.cs b/src/Microsoft.AspNet.Authentication.Twitter/Messages/RequestTokenSerializer.cs index 6305f52bd..21ef478a8 100644 --- a/src/Microsoft.AspNet.Authentication.Twitter/Messages/RequestTokenSerializer.cs +++ b/src/Microsoft.AspNet.Authentication.Twitter/Messages/RequestTokenSerializer.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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.Diagnostics.CodeAnalysis; diff --git a/src/Microsoft.AspNet.Authentication.Twitter/Messages/Serializers.cs b/src/Microsoft.AspNet.Authentication.Twitter/Messages/Serializers.cs index 749abaa3f..b40ac22c1 100644 --- a/src/Microsoft.AspNet.Authentication.Twitter/Messages/Serializers.cs +++ b/src/Microsoft.AspNet.Authentication.Twitter/Messages/Serializers.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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 Microsoft.AspNet.Authentication.DataHandler.Serializer; diff --git a/src/Microsoft.AspNet.Authentication.Twitter/Notifications/ITwitterAuthenticationNotifications.cs b/src/Microsoft.AspNet.Authentication.Twitter/Notifications/ITwitterAuthenticationNotifications.cs index 3bf685ec3..19fe1b1cc 100644 --- a/src/Microsoft.AspNet.Authentication.Twitter/Notifications/ITwitterAuthenticationNotifications.cs +++ b/src/Microsoft.AspNet.Authentication.Twitter/Notifications/ITwitterAuthenticationNotifications.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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.Threading.Tasks; diff --git a/src/Microsoft.AspNet.Authentication.Twitter/Notifications/TwitterApplyRedirectContext.cs b/src/Microsoft.AspNet.Authentication.Twitter/Notifications/TwitterApplyRedirectContext.cs index ffac97680..2186644ed 100644 --- a/src/Microsoft.AspNet.Authentication.Twitter/Notifications/TwitterApplyRedirectContext.cs +++ b/src/Microsoft.AspNet.Authentication.Twitter/Notifications/TwitterApplyRedirectContext.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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 Microsoft.AspNet.Http; diff --git a/src/Microsoft.AspNet.Authentication.Twitter/Notifications/TwitterAuthenticatedContext.cs b/src/Microsoft.AspNet.Authentication.Twitter/Notifications/TwitterAuthenticatedContext.cs index 9055c809d..9cf3b085c 100644 --- a/src/Microsoft.AspNet.Authentication.Twitter/Notifications/TwitterAuthenticatedContext.cs +++ b/src/Microsoft.AspNet.Authentication.Twitter/Notifications/TwitterAuthenticatedContext.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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.Security.Claims; diff --git a/src/Microsoft.AspNet.Authentication.Twitter/Notifications/TwitterAuthenticationNotifications.cs b/src/Microsoft.AspNet.Authentication.Twitter/Notifications/TwitterAuthenticationNotifications.cs index 492dbb7f6..5b7f7948d 100644 --- a/src/Microsoft.AspNet.Authentication.Twitter/Notifications/TwitterAuthenticationNotifications.cs +++ b/src/Microsoft.AspNet.Authentication.Twitter/Notifications/TwitterAuthenticationNotifications.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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; diff --git a/src/Microsoft.AspNet.Authentication.Twitter/Notifications/TwitterReturnEndpointContext.cs b/src/Microsoft.AspNet.Authentication.Twitter/Notifications/TwitterReturnEndpointContext.cs index a4eb87eed..6d71bc95f 100644 --- a/src/Microsoft.AspNet.Authentication.Twitter/Notifications/TwitterReturnEndpointContext.cs +++ b/src/Microsoft.AspNet.Authentication.Twitter/Notifications/TwitterReturnEndpointContext.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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 Microsoft.AspNet.Http; diff --git a/src/Microsoft.AspNet.Authentication.Twitter/Properties/AssemblyInfo.cs b/src/Microsoft.AspNet.Authentication.Twitter/Properties/AssemblyInfo.cs index f5c6f4a83..025a94598 100644 --- a/src/Microsoft.AspNet.Authentication.Twitter/Properties/AssemblyInfo.cs +++ b/src/Microsoft.AspNet.Authentication.Twitter/Properties/AssemblyInfo.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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.Reflection; diff --git a/src/Microsoft.AspNet.Authentication.Twitter/TwitterAppBuilderExtensions.cs b/src/Microsoft.AspNet.Authentication.Twitter/TwitterAppBuilderExtensions.cs index e0d0e0cf7..04e36058f 100644 --- a/src/Microsoft.AspNet.Authentication.Twitter/TwitterAppBuilderExtensions.cs +++ b/src/Microsoft.AspNet.Authentication.Twitter/TwitterAppBuilderExtensions.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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; diff --git a/src/Microsoft.AspNet.Authentication.Twitter/TwitterAuthenticationDefaults.cs b/src/Microsoft.AspNet.Authentication.Twitter/TwitterAuthenticationDefaults.cs index aa1faa20f..9b7d8c0fa 100644 --- a/src/Microsoft.AspNet.Authentication.Twitter/TwitterAuthenticationDefaults.cs +++ b/src/Microsoft.AspNet.Authentication.Twitter/TwitterAuthenticationDefaults.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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. namespace Microsoft.AspNet.Authentication.Twitter diff --git a/src/Microsoft.AspNet.Authentication.Twitter/TwitterAuthenticationHandler.cs b/src/Microsoft.AspNet.Authentication.Twitter/TwitterAuthenticationHandler.cs index e487f7698..cd09a1416 100644 --- a/src/Microsoft.AspNet.Authentication.Twitter/TwitterAuthenticationHandler.cs +++ b/src/Microsoft.AspNet.Authentication.Twitter/TwitterAuthenticationHandler.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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; diff --git a/src/Microsoft.AspNet.Authentication.Twitter/TwitterAuthenticationMiddleware.cs b/src/Microsoft.AspNet.Authentication.Twitter/TwitterAuthenticationMiddleware.cs index c1d266163..bcf3c4d87 100644 --- a/src/Microsoft.AspNet.Authentication.Twitter/TwitterAuthenticationMiddleware.cs +++ b/src/Microsoft.AspNet.Authentication.Twitter/TwitterAuthenticationMiddleware.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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; diff --git a/src/Microsoft.AspNet.Authentication.Twitter/TwitterAuthenticationOptions.cs b/src/Microsoft.AspNet.Authentication.Twitter/TwitterAuthenticationOptions.cs index a3179c386..4768f59b5 100644 --- a/src/Microsoft.AspNet.Authentication.Twitter/TwitterAuthenticationOptions.cs +++ b/src/Microsoft.AspNet.Authentication.Twitter/TwitterAuthenticationOptions.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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; diff --git a/src/Microsoft.AspNet.Authentication.Twitter/TwitterServiceCollectionExtensions.cs b/src/Microsoft.AspNet.Authentication.Twitter/TwitterServiceCollectionExtensions.cs index f34d22945..090b237dc 100644 --- a/src/Microsoft.AspNet.Authentication.Twitter/TwitterServiceCollectionExtensions.cs +++ b/src/Microsoft.AspNet.Authentication.Twitter/TwitterServiceCollectionExtensions.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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; diff --git a/src/Microsoft.AspNet.Authentication/AuthenticationHandler.cs b/src/Microsoft.AspNet.Authentication/AuthenticationHandler.cs index 22bc9eb36..674fec16a 100644 --- a/src/Microsoft.AspNet.Authentication/AuthenticationHandler.cs +++ b/src/Microsoft.AspNet.Authentication/AuthenticationHandler.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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; diff --git a/src/Microsoft.AspNet.Authentication/AuthenticationHandler`1.cs b/src/Microsoft.AspNet.Authentication/AuthenticationHandler`1.cs index 1c59b3573..edc127e26 100644 --- a/src/Microsoft.AspNet.Authentication/AuthenticationHandler`1.cs +++ b/src/Microsoft.AspNet.Authentication/AuthenticationHandler`1.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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.Threading.Tasks; diff --git a/src/Microsoft.AspNet.Authentication/AuthenticationMiddleware.cs b/src/Microsoft.AspNet.Authentication/AuthenticationMiddleware.cs index a70927f50..7cfd6138f 100644 --- a/src/Microsoft.AspNet.Authentication/AuthenticationMiddleware.cs +++ b/src/Microsoft.AspNet.Authentication/AuthenticationMiddleware.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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; diff --git a/src/Microsoft.AspNet.Authentication/AuthenticationOptions.cs b/src/Microsoft.AspNet.Authentication/AuthenticationOptions.cs index c91a5bddf..b1c2bc263 100644 --- a/src/Microsoft.AspNet.Authentication/AuthenticationOptions.cs +++ b/src/Microsoft.AspNet.Authentication/AuthenticationOptions.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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 Microsoft.AspNet.Http.Authentication; diff --git a/src/Microsoft.AspNet.Authentication/AuthenticationServiceCollectionExtensions.cs b/src/Microsoft.AspNet.Authentication/AuthenticationServiceCollectionExtensions.cs index 705ae6227..0b6cfdb9f 100644 --- a/src/Microsoft.AspNet.Authentication/AuthenticationServiceCollectionExtensions.cs +++ b/src/Microsoft.AspNet.Authentication/AuthenticationServiceCollectionExtensions.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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; diff --git a/src/Microsoft.AspNet.Authentication/AuthenticationTicket.cs b/src/Microsoft.AspNet.Authentication/AuthenticationTicket.cs index c7fb43f9a..e72385d87 100644 --- a/src/Microsoft.AspNet.Authentication/AuthenticationTicket.cs +++ b/src/Microsoft.AspNet.Authentication/AuthenticationTicket.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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.Security.Claims; diff --git a/src/Microsoft.AspNet.Authentication/AuthenticationTokenCreateContext.cs b/src/Microsoft.AspNet.Authentication/AuthenticationTokenCreateContext.cs index 1045d477f..ae0548f76 100644 --- a/src/Microsoft.AspNet.Authentication/AuthenticationTokenCreateContext.cs +++ b/src/Microsoft.AspNet.Authentication/AuthenticationTokenCreateContext.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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. diff --git a/src/Microsoft.AspNet.Authentication/AuthenticationTokenProvider.cs b/src/Microsoft.AspNet.Authentication/AuthenticationTokenProvider.cs index 7d090346f..9483538c6 100644 --- a/src/Microsoft.AspNet.Authentication/AuthenticationTokenProvider.cs +++ b/src/Microsoft.AspNet.Authentication/AuthenticationTokenProvider.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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. diff --git a/src/Microsoft.AspNet.Authentication/AuthenticationTokenReceiveContext.cs b/src/Microsoft.AspNet.Authentication/AuthenticationTokenReceiveContext.cs index df309ca06..ec0c38b20 100644 --- a/src/Microsoft.AspNet.Authentication/AuthenticationTokenReceiveContext.cs +++ b/src/Microsoft.AspNet.Authentication/AuthenticationTokenReceiveContext.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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 Microsoft.AspNet.Http; diff --git a/src/Microsoft.AspNet.Authentication/CertificateSubjectKeyIdentifierValidator.cs b/src/Microsoft.AspNet.Authentication/CertificateSubjectKeyIdentifierValidator.cs index 5dd663ec7..3e19a3e68 100644 --- a/src/Microsoft.AspNet.Authentication/CertificateSubjectKeyIdentifierValidator.cs +++ b/src/Microsoft.AspNet.Authentication/CertificateSubjectKeyIdentifierValidator.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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. #if DNX451 diff --git a/src/Microsoft.AspNet.Authentication/CertificateSubjectPublicKeyInfoValidator.cs b/src/Microsoft.AspNet.Authentication/CertificateSubjectPublicKeyInfoValidator.cs index 3c04ca9d8..0ea177d64 100644 --- a/src/Microsoft.AspNet.Authentication/CertificateSubjectPublicKeyInfoValidator.cs +++ b/src/Microsoft.AspNet.Authentication/CertificateSubjectPublicKeyInfoValidator.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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. #if DNX451 diff --git a/src/Microsoft.AspNet.Authentication/CertificateThumbprintValidator.cs b/src/Microsoft.AspNet.Authentication/CertificateThumbprintValidator.cs index 4392108f2..6befa1ea4 100644 --- a/src/Microsoft.AspNet.Authentication/CertificateThumbprintValidator.cs +++ b/src/Microsoft.AspNet.Authentication/CertificateThumbprintValidator.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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. #if DNX451 diff --git a/src/Microsoft.AspNet.Authentication/ClaimsTransformationAppBuilderExtensions.cs b/src/Microsoft.AspNet.Authentication/ClaimsTransformationAppBuilderExtensions.cs index 79ecb3888..ae1e4d97a 100644 --- a/src/Microsoft.AspNet.Authentication/ClaimsTransformationAppBuilderExtensions.cs +++ b/src/Microsoft.AspNet.Authentication/ClaimsTransformationAppBuilderExtensions.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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; diff --git a/src/Microsoft.AspNet.Authentication/ClaimsTransformationAuthenticationHandler.cs b/src/Microsoft.AspNet.Authentication/ClaimsTransformationAuthenticationHandler.cs index 5839d4d4e..69563a8de 100644 --- a/src/Microsoft.AspNet.Authentication/ClaimsTransformationAuthenticationHandler.cs +++ b/src/Microsoft.AspNet.Authentication/ClaimsTransformationAuthenticationHandler.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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; diff --git a/src/Microsoft.AspNet.Authentication/ClaimsTransformationMiddleware.cs b/src/Microsoft.AspNet.Authentication/ClaimsTransformationMiddleware.cs index cf3a58b79..a8022d576 100644 --- a/src/Microsoft.AspNet.Authentication/ClaimsTransformationMiddleware.cs +++ b/src/Microsoft.AspNet.Authentication/ClaimsTransformationMiddleware.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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.Threading.Tasks; diff --git a/src/Microsoft.AspNet.Authentication/ClaimsTransformationOptions.cs b/src/Microsoft.AspNet.Authentication/ClaimsTransformationOptions.cs index f8c4a3ed3..1eb76c82a 100644 --- a/src/Microsoft.AspNet.Authentication/ClaimsTransformationOptions.cs +++ b/src/Microsoft.AspNet.Authentication/ClaimsTransformationOptions.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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; diff --git a/src/Microsoft.AspNet.Authentication/Constants.cs b/src/Microsoft.AspNet.Authentication/Constants.cs index da3a23daa..e6b0d7b43 100644 --- a/src/Microsoft.AspNet.Authentication/Constants.cs +++ b/src/Microsoft.AspNet.Authentication/Constants.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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. diff --git a/src/Microsoft.AspNet.Authentication/DataHandler/Encoder/Base64TextEncoder.cs b/src/Microsoft.AspNet.Authentication/DataHandler/Encoder/Base64TextEncoder.cs index 0a4056450..073795f26 100644 --- a/src/Microsoft.AspNet.Authentication/DataHandler/Encoder/Base64TextEncoder.cs +++ b/src/Microsoft.AspNet.Authentication/DataHandler/Encoder/Base64TextEncoder.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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. diff --git a/src/Microsoft.AspNet.Authentication/DataHandler/Encoder/Base64UrlTextEncoder.cs b/src/Microsoft.AspNet.Authentication/DataHandler/Encoder/Base64UrlTextEncoder.cs index 41cb10abd..723736973 100644 --- a/src/Microsoft.AspNet.Authentication/DataHandler/Encoder/Base64UrlTextEncoder.cs +++ b/src/Microsoft.AspNet.Authentication/DataHandler/Encoder/Base64UrlTextEncoder.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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. diff --git a/src/Microsoft.AspNet.Authentication/DataHandler/Encoder/ITextEncoder.cs b/src/Microsoft.AspNet.Authentication/DataHandler/Encoder/ITextEncoder.cs index aeb577ec0..953fb6232 100644 --- a/src/Microsoft.AspNet.Authentication/DataHandler/Encoder/ITextEncoder.cs +++ b/src/Microsoft.AspNet.Authentication/DataHandler/Encoder/ITextEncoder.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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. diff --git a/src/Microsoft.AspNet.Authentication/DataHandler/Encoder/TextEncodings.cs b/src/Microsoft.AspNet.Authentication/DataHandler/Encoder/TextEncodings.cs index 1b59cec5c..5e6bbde93 100644 --- a/src/Microsoft.AspNet.Authentication/DataHandler/Encoder/TextEncodings.cs +++ b/src/Microsoft.AspNet.Authentication/DataHandler/Encoder/TextEncodings.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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. diff --git a/src/Microsoft.AspNet.Authentication/DataHandler/ISecureDataFormat.cs b/src/Microsoft.AspNet.Authentication/DataHandler/ISecureDataFormat.cs index 2e3f24e84..e9587de00 100644 --- a/src/Microsoft.AspNet.Authentication/DataHandler/ISecureDataFormat.cs +++ b/src/Microsoft.AspNet.Authentication/DataHandler/ISecureDataFormat.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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. diff --git a/src/Microsoft.AspNet.Authentication/DataHandler/PropertiesDataFormat.cs b/src/Microsoft.AspNet.Authentication/DataHandler/PropertiesDataFormat.cs index 1472dd427..127554ad8 100644 --- a/src/Microsoft.AspNet.Authentication/DataHandler/PropertiesDataFormat.cs +++ b/src/Microsoft.AspNet.Authentication/DataHandler/PropertiesDataFormat.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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 Microsoft.AspNet.DataProtection; diff --git a/src/Microsoft.AspNet.Authentication/DataHandler/SecureDataFormat.cs b/src/Microsoft.AspNet.Authentication/DataHandler/SecureDataFormat.cs index b7e240768..6221e498a 100644 --- a/src/Microsoft.AspNet.Authentication/DataHandler/SecureDataFormat.cs +++ b/src/Microsoft.AspNet.Authentication/DataHandler/SecureDataFormat.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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. diff --git a/src/Microsoft.AspNet.Authentication/DataHandler/Serializer/DataSerializers.cs b/src/Microsoft.AspNet.Authentication/DataHandler/Serializer/DataSerializers.cs index fd8e45fc8..0c185a9b2 100644 --- a/src/Microsoft.AspNet.Authentication/DataHandler/Serializer/DataSerializers.cs +++ b/src/Microsoft.AspNet.Authentication/DataHandler/Serializer/DataSerializers.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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. diff --git a/src/Microsoft.AspNet.Authentication/DataHandler/Serializer/IDataSerializer.cs b/src/Microsoft.AspNet.Authentication/DataHandler/Serializer/IDataSerializer.cs index dc78d8c46..d6cfd18b2 100644 --- a/src/Microsoft.AspNet.Authentication/DataHandler/Serializer/IDataSerializer.cs +++ b/src/Microsoft.AspNet.Authentication/DataHandler/Serializer/IDataSerializer.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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. diff --git a/src/Microsoft.AspNet.Authentication/DataHandler/Serializer/PropertiesSerializer.cs b/src/Microsoft.AspNet.Authentication/DataHandler/Serializer/PropertiesSerializer.cs index ccfba6456..5120219ff 100644 --- a/src/Microsoft.AspNet.Authentication/DataHandler/Serializer/PropertiesSerializer.cs +++ b/src/Microsoft.AspNet.Authentication/DataHandler/Serializer/PropertiesSerializer.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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. diff --git a/src/Microsoft.AspNet.Authentication/DataHandler/Serializer/TicketSerializer.cs b/src/Microsoft.AspNet.Authentication/DataHandler/Serializer/TicketSerializer.cs index 40d80c28d..71c8b5856 100644 --- a/src/Microsoft.AspNet.Authentication/DataHandler/Serializer/TicketSerializer.cs +++ b/src/Microsoft.AspNet.Authentication/DataHandler/Serializer/TicketSerializer.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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; diff --git a/src/Microsoft.AspNet.Authentication/DataHandler/TicketDataFormat.cs b/src/Microsoft.AspNet.Authentication/DataHandler/TicketDataFormat.cs index 922f5c8c0..6dd719aec 100644 --- a/src/Microsoft.AspNet.Authentication/DataHandler/TicketDataFormat.cs +++ b/src/Microsoft.AspNet.Authentication/DataHandler/TicketDataFormat.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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 Microsoft.AspNet.DataProtection; diff --git a/src/Microsoft.AspNet.Authentication/ExternalAuthenticationOptions.cs b/src/Microsoft.AspNet.Authentication/ExternalAuthenticationOptions.cs index a80b80b83..19bd05fa9 100644 --- a/src/Microsoft.AspNet.Authentication/ExternalAuthenticationOptions.cs +++ b/src/Microsoft.AspNet.Authentication/ExternalAuthenticationOptions.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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. diff --git a/src/Microsoft.AspNet.Authentication/HttpContextExtensions.cs b/src/Microsoft.AspNet.Authentication/HttpContextExtensions.cs index 65f7bcc10..eaa53c1b3 100644 --- a/src/Microsoft.AspNet.Authentication/HttpContextExtensions.cs +++ b/src/Microsoft.AspNet.Authentication/HttpContextExtensions.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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 Microsoft.AspNet.Http; diff --git a/src/Microsoft.AspNet.Authentication/IAuthenticationTokenProvider.cs b/src/Microsoft.AspNet.Authentication/IAuthenticationTokenProvider.cs index d0c2bf34c..3315fa21f 100644 --- a/src/Microsoft.AspNet.Authentication/IAuthenticationTokenProvider.cs +++ b/src/Microsoft.AspNet.Authentication/IAuthenticationTokenProvider.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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. diff --git a/src/Microsoft.AspNet.Authentication/ICertificateValidator.cs b/src/Microsoft.AspNet.Authentication/ICertificateValidator.cs index 6cb2c4d6d..4e8c2d41e 100644 --- a/src/Microsoft.AspNet.Authentication/ICertificateValidator.cs +++ b/src/Microsoft.AspNet.Authentication/ICertificateValidator.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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. #if DNX451 diff --git a/src/Microsoft.AspNet.Authentication/ISystemClock.cs b/src/Microsoft.AspNet.Authentication/ISystemClock.cs index 4748fb63e..dedb6d36a 100644 --- a/src/Microsoft.AspNet.Authentication/ISystemClock.cs +++ b/src/Microsoft.AspNet.Authentication/ISystemClock.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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. diff --git a/src/Microsoft.AspNet.Authentication/Notifications/AuthenticationFailedNotification.cs b/src/Microsoft.AspNet.Authentication/Notifications/AuthenticationFailedNotification.cs index 16aa15751..4f912dc1c 100644 --- a/src/Microsoft.AspNet.Authentication/Notifications/AuthenticationFailedNotification.cs +++ b/src/Microsoft.AspNet.Authentication/Notifications/AuthenticationFailedNotification.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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; diff --git a/src/Microsoft.AspNet.Authentication/Notifications/BaseContext.cs b/src/Microsoft.AspNet.Authentication/Notifications/BaseContext.cs index 11f65199c..4215020dc 100644 --- a/src/Microsoft.AspNet.Authentication/Notifications/BaseContext.cs +++ b/src/Microsoft.AspNet.Authentication/Notifications/BaseContext.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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. diff --git a/src/Microsoft.AspNet.Authentication/Notifications/BaseContext`1.cs b/src/Microsoft.AspNet.Authentication/Notifications/BaseContext`1.cs index 184adfb3b..b124fa717 100644 --- a/src/Microsoft.AspNet.Authentication/Notifications/BaseContext`1.cs +++ b/src/Microsoft.AspNet.Authentication/Notifications/BaseContext`1.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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. diff --git a/src/Microsoft.AspNet.Authentication/Notifications/BaseNotification.cs b/src/Microsoft.AspNet.Authentication/Notifications/BaseNotification.cs index 1563dbb07..50b626d1a 100644 --- a/src/Microsoft.AspNet.Authentication/Notifications/BaseNotification.cs +++ b/src/Microsoft.AspNet.Authentication/Notifications/BaseNotification.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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. diff --git a/src/Microsoft.AspNet.Authentication/Notifications/EndpointContext.cs b/src/Microsoft.AspNet.Authentication/Notifications/EndpointContext.cs index 1671316d1..096de20ee 100644 --- a/src/Microsoft.AspNet.Authentication/Notifications/EndpointContext.cs +++ b/src/Microsoft.AspNet.Authentication/Notifications/EndpointContext.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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. diff --git a/src/Microsoft.AspNet.Authentication/Notifications/EndpointContext`1.cs b/src/Microsoft.AspNet.Authentication/Notifications/EndpointContext`1.cs index dde3a4fbb..f7a9a1e97 100644 --- a/src/Microsoft.AspNet.Authentication/Notifications/EndpointContext`1.cs +++ b/src/Microsoft.AspNet.Authentication/Notifications/EndpointContext`1.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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. diff --git a/src/Microsoft.AspNet.Authentication/Notifications/MessageReceivedNotification.cs b/src/Microsoft.AspNet.Authentication/Notifications/MessageReceivedNotification.cs index 08f6521c0..32df87bab 100644 --- a/src/Microsoft.AspNet.Authentication/Notifications/MessageReceivedNotification.cs +++ b/src/Microsoft.AspNet.Authentication/Notifications/MessageReceivedNotification.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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 Microsoft.AspNet.Http; diff --git a/src/Microsoft.AspNet.Authentication/Notifications/NotificationResultState.cs b/src/Microsoft.AspNet.Authentication/Notifications/NotificationResultState.cs index 993aa7618..7434ebd82 100644 --- a/src/Microsoft.AspNet.Authentication/Notifications/NotificationResultState.cs +++ b/src/Microsoft.AspNet.Authentication/Notifications/NotificationResultState.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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. diff --git a/src/Microsoft.AspNet.Authentication/Notifications/RedirectFromIdentityProviderNotification.cs b/src/Microsoft.AspNet.Authentication/Notifications/RedirectFromIdentityProviderNotification.cs index f883baf7d..970d9d718 100644 --- a/src/Microsoft.AspNet.Authentication/Notifications/RedirectFromIdentityProviderNotification.cs +++ b/src/Microsoft.AspNet.Authentication/Notifications/RedirectFromIdentityProviderNotification.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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 Microsoft.AspNet.Http; diff --git a/src/Microsoft.AspNet.Authentication/Notifications/RedirectToIdentityProviderNotification.cs b/src/Microsoft.AspNet.Authentication/Notifications/RedirectToIdentityProviderNotification.cs index 1c069b4e2..a4b2d979e 100644 --- a/src/Microsoft.AspNet.Authentication/Notifications/RedirectToIdentityProviderNotification.cs +++ b/src/Microsoft.AspNet.Authentication/Notifications/RedirectToIdentityProviderNotification.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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 Microsoft.AspNet.Http; diff --git a/src/Microsoft.AspNet.Authentication/Notifications/ReturnEndpointContext.cs b/src/Microsoft.AspNet.Authentication/Notifications/ReturnEndpointContext.cs index 344c56ccc..ac4fa7b3c 100644 --- a/src/Microsoft.AspNet.Authentication/Notifications/ReturnEndpointContext.cs +++ b/src/Microsoft.AspNet.Authentication/Notifications/ReturnEndpointContext.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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. diff --git a/src/Microsoft.AspNet.Authentication/Notifications/SecurityTokenReceivedNotification.cs b/src/Microsoft.AspNet.Authentication/Notifications/SecurityTokenReceivedNotification.cs index f7a042444..a0208b8b3 100644 --- a/src/Microsoft.AspNet.Authentication/Notifications/SecurityTokenReceivedNotification.cs +++ b/src/Microsoft.AspNet.Authentication/Notifications/SecurityTokenReceivedNotification.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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 Microsoft.AspNet.Http; diff --git a/src/Microsoft.AspNet.Authentication/Notifications/SecurityTokenValidatedNotification.cs b/src/Microsoft.AspNet.Authentication/Notifications/SecurityTokenValidatedNotification.cs index aad6d7e3a..82c641ca1 100644 --- a/src/Microsoft.AspNet.Authentication/Notifications/SecurityTokenValidatedNotification.cs +++ b/src/Microsoft.AspNet.Authentication/Notifications/SecurityTokenValidatedNotification.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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 Microsoft.AspNet.Http; diff --git a/src/Microsoft.AspNet.Authentication/Properties/AssemblyInfo.cs b/src/Microsoft.AspNet.Authentication/Properties/AssemblyInfo.cs index f5c6f4a83..025a94598 100644 --- a/src/Microsoft.AspNet.Authentication/Properties/AssemblyInfo.cs +++ b/src/Microsoft.AspNet.Authentication/Properties/AssemblyInfo.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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.Reflection; diff --git a/src/Microsoft.AspNet.Authentication/SecurityHelper.cs b/src/Microsoft.AspNet.Authentication/SecurityHelper.cs index cb1b1fe1c..ea7234b20 100644 --- a/src/Microsoft.AspNet.Authentication/SecurityHelper.cs +++ b/src/Microsoft.AspNet.Authentication/SecurityHelper.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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; diff --git a/src/Microsoft.AspNet.Authentication/SubjectPublicKeyInfoAlgorithm.cs b/src/Microsoft.AspNet.Authentication/SubjectPublicKeyInfoAlgorithm.cs index 921abb953..fa5704f34 100644 --- a/src/Microsoft.AspNet.Authentication/SubjectPublicKeyInfoAlgorithm.cs +++ b/src/Microsoft.AspNet.Authentication/SubjectPublicKeyInfoAlgorithm.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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. diff --git a/src/Microsoft.AspNet.Authentication/SystemClock.cs b/src/Microsoft.AspNet.Authentication/SystemClock.cs index 11c30564f..405b8afa2 100644 --- a/src/Microsoft.AspNet.Authentication/SystemClock.cs +++ b/src/Microsoft.AspNet.Authentication/SystemClock.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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. diff --git a/src/Microsoft.AspNet.Authentication/Win32.cs b/src/Microsoft.AspNet.Authentication/Win32.cs index fe817e92d..0e757e42a 100644 --- a/src/Microsoft.AspNet.Authentication/Win32.cs +++ b/src/Microsoft.AspNet.Authentication/Win32.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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. diff --git a/src/Microsoft.AspNet.Authorization/AuthorizationContext.cs b/src/Microsoft.AspNet.Authorization/AuthorizationContext.cs index 8b051fcdc..b117f8851 100644 --- a/src/Microsoft.AspNet.Authorization/AuthorizationContext.cs +++ b/src/Microsoft.AspNet.Authorization/AuthorizationContext.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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.Collections.Generic; diff --git a/src/Microsoft.AspNet.Authorization/AuthorizationHandler.cs b/src/Microsoft.AspNet.Authorization/AuthorizationHandler.cs index c05b55b9c..b682e43ff 100644 --- a/src/Microsoft.AspNet.Authorization/AuthorizationHandler.cs +++ b/src/Microsoft.AspNet.Authorization/AuthorizationHandler.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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.Linq; diff --git a/src/Microsoft.AspNet.Authorization/AuthorizationOptions.cs b/src/Microsoft.AspNet.Authorization/AuthorizationOptions.cs index d23a0effe..17d879329 100644 --- a/src/Microsoft.AspNet.Authorization/AuthorizationOptions.cs +++ b/src/Microsoft.AspNet.Authorization/AuthorizationOptions.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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; diff --git a/src/Microsoft.AspNet.Authorization/AuthorizationPolicy.cs b/src/Microsoft.AspNet.Authorization/AuthorizationPolicy.cs index 02769a8dd..3cc52abe5 100644 --- a/src/Microsoft.AspNet.Authorization/AuthorizationPolicy.cs +++ b/src/Microsoft.AspNet.Authorization/AuthorizationPolicy.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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; diff --git a/src/Microsoft.AspNet.Authorization/AuthorizationPolicyBuilder.cs b/src/Microsoft.AspNet.Authorization/AuthorizationPolicyBuilder.cs index 976d997cc..128545032 100644 --- a/src/Microsoft.AspNet.Authorization/AuthorizationPolicyBuilder.cs +++ b/src/Microsoft.AspNet.Authorization/AuthorizationPolicyBuilder.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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.Collections.Generic; diff --git a/src/Microsoft.AspNet.Authorization/AuthorizationServiceExtensions.cs b/src/Microsoft.AspNet.Authorization/AuthorizationServiceExtensions.cs index 03f112b73..298a2f081 100644 --- a/src/Microsoft.AspNet.Authorization/AuthorizationServiceExtensions.cs +++ b/src/Microsoft.AspNet.Authorization/AuthorizationServiceExtensions.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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.Linq; diff --git a/src/Microsoft.AspNet.Authorization/AuthorizeAttribute.cs b/src/Microsoft.AspNet.Authorization/AuthorizeAttribute.cs index 15db20dbf..42d757d8e 100644 --- a/src/Microsoft.AspNet.Authorization/AuthorizeAttribute.cs +++ b/src/Microsoft.AspNet.Authorization/AuthorizeAttribute.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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; diff --git a/src/Microsoft.AspNet.Authorization/ClaimsAuthorizationHandler.cs b/src/Microsoft.AspNet.Authorization/ClaimsAuthorizationHandler.cs index 608b14936..fed436ad4 100644 --- a/src/Microsoft.AspNet.Authorization/ClaimsAuthorizationHandler.cs +++ b/src/Microsoft.AspNet.Authorization/ClaimsAuthorizationHandler.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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; diff --git a/src/Microsoft.AspNet.Authorization/ClaimsAuthorizationRequirement.cs b/src/Microsoft.AspNet.Authorization/ClaimsAuthorizationRequirement.cs index d13c9ecc9..b8994b8b7 100644 --- a/src/Microsoft.AspNet.Authorization/ClaimsAuthorizationRequirement.cs +++ b/src/Microsoft.AspNet.Authorization/ClaimsAuthorizationRequirement.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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.Collections.Generic; diff --git a/src/Microsoft.AspNet.Authorization/DefaultAuthorizationService.cs b/src/Microsoft.AspNet.Authorization/DefaultAuthorizationService.cs index c6e57eb54..abc866276 100644 --- a/src/Microsoft.AspNet.Authorization/DefaultAuthorizationService.cs +++ b/src/Microsoft.AspNet.Authorization/DefaultAuthorizationService.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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.Collections.Generic; diff --git a/src/Microsoft.AspNet.Authorization/DenyAnonymousAuthorizationHandler.cs b/src/Microsoft.AspNet.Authorization/DenyAnonymousAuthorizationHandler.cs index 0f6cb3def..3c1c872b3 100644 --- a/src/Microsoft.AspNet.Authorization/DenyAnonymousAuthorizationHandler.cs +++ b/src/Microsoft.AspNet.Authorization/DenyAnonymousAuthorizationHandler.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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.Linq; diff --git a/src/Microsoft.AspNet.Authorization/DenyAnonymousAuthorizationRequirement.cs b/src/Microsoft.AspNet.Authorization/DenyAnonymousAuthorizationRequirement.cs index ecbee9b90..fce23a3dc 100644 --- a/src/Microsoft.AspNet.Authorization/DenyAnonymousAuthorizationRequirement.cs +++ b/src/Microsoft.AspNet.Authorization/DenyAnonymousAuthorizationRequirement.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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 Microsoft.AspNet.Authorization; diff --git a/src/Microsoft.AspNet.Authorization/IAuthorizationHandler.cs b/src/Microsoft.AspNet.Authorization/IAuthorizationHandler.cs index bcd0cdc2b..b4366a6f5 100644 --- a/src/Microsoft.AspNet.Authorization/IAuthorizationHandler.cs +++ b/src/Microsoft.AspNet.Authorization/IAuthorizationHandler.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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.Threading.Tasks; diff --git a/src/Microsoft.AspNet.Authorization/IAuthorizationRequirement.cs b/src/Microsoft.AspNet.Authorization/IAuthorizationRequirement.cs index 5aeef262e..19857b618 100644 --- a/src/Microsoft.AspNet.Authorization/IAuthorizationRequirement.cs +++ b/src/Microsoft.AspNet.Authorization/IAuthorizationRequirement.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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. namespace Microsoft.AspNet.Authorization diff --git a/src/Microsoft.AspNet.Authorization/IAuthorizationService.cs b/src/Microsoft.AspNet.Authorization/IAuthorizationService.cs index 89215c7aa..dedfcc37c 100644 --- a/src/Microsoft.AspNet.Authorization/IAuthorizationService.cs +++ b/src/Microsoft.AspNet.Authorization/IAuthorizationService.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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.Security.Claims; diff --git a/src/Microsoft.AspNet.Authorization/OperationAuthorizationRequirement.cs b/src/Microsoft.AspNet.Authorization/OperationAuthorizationRequirement.cs index 64cd198eb..13732d019 100644 --- a/src/Microsoft.AspNet.Authorization/OperationAuthorizationRequirement.cs +++ b/src/Microsoft.AspNet.Authorization/OperationAuthorizationRequirement.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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. namespace Microsoft.AspNet.Authorization diff --git a/src/Microsoft.AspNet.Authorization/PassThroughAuthorizationHandler.cs b/src/Microsoft.AspNet.Authorization/PassThroughAuthorizationHandler.cs index 3ae506b2d..93107cc6b 100644 --- a/src/Microsoft.AspNet.Authorization/PassThroughAuthorizationHandler.cs +++ b/src/Microsoft.AspNet.Authorization/PassThroughAuthorizationHandler.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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.Linq; diff --git a/src/Microsoft.AspNet.Authorization/Properties/AssemblyInfo.cs b/src/Microsoft.AspNet.Authorization/Properties/AssemblyInfo.cs index f5c6f4a83..025a94598 100644 --- a/src/Microsoft.AspNet.Authorization/Properties/AssemblyInfo.cs +++ b/src/Microsoft.AspNet.Authorization/Properties/AssemblyInfo.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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.Reflection; diff --git a/src/Microsoft.AspNet.Authorization/ServiceCollectionExtensions.cs b/src/Microsoft.AspNet.Authorization/ServiceCollectionExtensions.cs index 467b36aff..4deced289 100644 --- a/src/Microsoft.AspNet.Authorization/ServiceCollectionExtensions.cs +++ b/src/Microsoft.AspNet.Authorization/ServiceCollectionExtensions.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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; diff --git a/test/Microsoft.AspNet.Authentication.Test/AuthenticationHandlerFacts.cs b/test/Microsoft.AspNet.Authentication.Test/AuthenticationHandlerFacts.cs index f5428f1a3..c858dee28 100644 --- a/test/Microsoft.AspNet.Authentication.Test/AuthenticationHandlerFacts.cs +++ b/test/Microsoft.AspNet.Authentication.Test/AuthenticationHandlerFacts.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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; diff --git a/test/Microsoft.AspNet.Authentication.Test/CertificateSubjectKeyIdentifierValidatorTests.cs b/test/Microsoft.AspNet.Authentication.Test/CertificateSubjectKeyIdentifierValidatorTests.cs index f52e6f4ae..a0df4a419 100644 --- a/test/Microsoft.AspNet.Authentication.Test/CertificateSubjectKeyIdentifierValidatorTests.cs +++ b/test/Microsoft.AspNet.Authentication.Test/CertificateSubjectKeyIdentifierValidatorTests.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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; diff --git a/test/Microsoft.AspNet.Authentication.Test/CertificateSubjectPublicKeyInfoValidatorTests.cs b/test/Microsoft.AspNet.Authentication.Test/CertificateSubjectPublicKeyInfoValidatorTests.cs index 13b9a900a..366e2f3b5 100644 --- a/test/Microsoft.AspNet.Authentication.Test/CertificateSubjectPublicKeyInfoValidatorTests.cs +++ b/test/Microsoft.AspNet.Authentication.Test/CertificateSubjectPublicKeyInfoValidatorTests.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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; diff --git a/test/Microsoft.AspNet.Authentication.Test/CertificateThumbprintValidatorTests.cs b/test/Microsoft.AspNet.Authentication.Test/CertificateThumbprintValidatorTests.cs index 145e883dc..30537c51d 100644 --- a/test/Microsoft.AspNet.Authentication.Test/CertificateThumbprintValidatorTests.cs +++ b/test/Microsoft.AspNet.Authentication.Test/CertificateThumbprintValidatorTests.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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; diff --git a/test/Microsoft.AspNet.Authentication.Test/Cookies/CookieMiddlewareTests.cs b/test/Microsoft.AspNet.Authentication.Test/Cookies/CookieMiddlewareTests.cs index aa1304397..d35978aee 100644 --- a/test/Microsoft.AspNet.Authentication.Test/Cookies/CookieMiddlewareTests.cs +++ b/test/Microsoft.AspNet.Authentication.Test/Cookies/CookieMiddlewareTests.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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; diff --git a/test/Microsoft.AspNet.Authentication.Test/Cookies/Infrastructure/CookieChunkingTests.cs b/test/Microsoft.AspNet.Authentication.Test/Cookies/Infrastructure/CookieChunkingTests.cs index a8e437cd7..7c94ecadf 100644 --- a/test/Microsoft.AspNet.Authentication.Test/Cookies/Infrastructure/CookieChunkingTests.cs +++ b/test/Microsoft.AspNet.Authentication.Test/Cookies/Infrastructure/CookieChunkingTests.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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; diff --git a/test/Microsoft.AspNet.Authentication.Test/DataHandler/Encoder/Base64UrlTextEncoderTests.cs b/test/Microsoft.AspNet.Authentication.Test/DataHandler/Encoder/Base64UrlTextEncoderTests.cs index 8183f3879..a345241d2 100644 --- a/test/Microsoft.AspNet.Authentication.Test/DataHandler/Encoder/Base64UrlTextEncoderTests.cs +++ b/test/Microsoft.AspNet.Authentication.Test/DataHandler/Encoder/Base64UrlTextEncoderTests.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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 Shouldly; diff --git a/test/Microsoft.AspNet.Authentication.Test/Facebook/FacebookMiddlewareTests.cs b/test/Microsoft.AspNet.Authentication.Test/Facebook/FacebookMiddlewareTests.cs index 2cde6c767..4977a9923 100644 --- a/test/Microsoft.AspNet.Authentication.Test/Facebook/FacebookMiddlewareTests.cs +++ b/test/Microsoft.AspNet.Authentication.Test/Facebook/FacebookMiddlewareTests.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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; diff --git a/test/Microsoft.AspNet.Authentication.Test/Google/GoogleMiddlewareTests.cs b/test/Microsoft.AspNet.Authentication.Test/Google/GoogleMiddlewareTests.cs index 08917a674..f44d4d3e7 100644 --- a/test/Microsoft.AspNet.Authentication.Test/Google/GoogleMiddlewareTests.cs +++ b/test/Microsoft.AspNet.Authentication.Test/Google/GoogleMiddlewareTests.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. +// Copyright (c) .NET Foundation. All rights reserved. See License.txt in the project root for license information. using System; using System.Collections.Generic; diff --git a/test/Microsoft.AspNet.Authentication.Test/MicrosoftAccount/MicrosoftAccountMiddlewareTests.cs b/test/Microsoft.AspNet.Authentication.Test/MicrosoftAccount/MicrosoftAccountMiddlewareTests.cs index 60230224b..1382fc640 100644 --- a/test/Microsoft.AspNet.Authentication.Test/MicrosoftAccount/MicrosoftAccountMiddlewareTests.cs +++ b/test/Microsoft.AspNet.Authentication.Test/MicrosoftAccount/MicrosoftAccountMiddlewareTests.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. +// Copyright (c) .NET Foundation. All rights reserved. See License.txt in the project root for license information. using System; using System.Collections.Generic; diff --git a/test/Microsoft.AspNet.Authentication.Test/OAuthBearer/OAuthBearerMiddlewareTests.cs b/test/Microsoft.AspNet.Authentication.Test/OAuthBearer/OAuthBearerMiddlewareTests.cs index 4d589a43c..7ae0db82b 100644 --- a/test/Microsoft.AspNet.Authentication.Test/OAuthBearer/OAuthBearerMiddlewareTests.cs +++ b/test/Microsoft.AspNet.Authentication.Test/OAuthBearer/OAuthBearerMiddlewareTests.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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; diff --git a/test/Microsoft.AspNet.Authentication.Test/OpenIdConnect/OpenIdConnectHandlerTests.cs b/test/Microsoft.AspNet.Authentication.Test/OpenIdConnect/OpenIdConnectHandlerTests.cs index 1134c7300..73350e619 100644 --- a/test/Microsoft.AspNet.Authentication.Test/OpenIdConnect/OpenIdConnectHandlerTests.cs +++ b/test/Microsoft.AspNet.Authentication.Test/OpenIdConnect/OpenIdConnectHandlerTests.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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. // this controls if the logs are written to the console. diff --git a/test/Microsoft.AspNet.Authentication.Test/OpenIdConnect/OpenIdConnectMiddlewareTests.cs b/test/Microsoft.AspNet.Authentication.Test/OpenIdConnect/OpenIdConnectMiddlewareTests.cs index da290cca1..32aa028f0 100644 --- a/test/Microsoft.AspNet.Authentication.Test/OpenIdConnect/OpenIdConnectMiddlewareTests.cs +++ b/test/Microsoft.AspNet.Authentication.Test/OpenIdConnect/OpenIdConnectMiddlewareTests.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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; diff --git a/test/Microsoft.AspNet.Authentication.Test/OpenIdConnect/TestUtilities.cs b/test/Microsoft.AspNet.Authentication.Test/OpenIdConnect/TestUtilities.cs index abb5b8538..3f18ee6b9 100644 --- a/test/Microsoft.AspNet.Authentication.Test/OpenIdConnect/TestUtilities.cs +++ b/test/Microsoft.AspNet.Authentication.Test/OpenIdConnect/TestUtilities.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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 Microsoft.IdentityModel.Protocols; diff --git a/test/Microsoft.AspNet.Authentication.Test/SecurityHelperTests.cs b/test/Microsoft.AspNet.Authentication.Test/SecurityHelperTests.cs index 1b47c81f8..01315805d 100644 --- a/test/Microsoft.AspNet.Authentication.Test/SecurityHelperTests.cs +++ b/test/Microsoft.AspNet.Authentication.Test/SecurityHelperTests.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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.Collections.Generic; diff --git a/test/Microsoft.AspNet.Authentication.Test/TestClock.cs b/test/Microsoft.AspNet.Authentication.Test/TestClock.cs index 1b7dd1be8..20495125d 100644 --- a/test/Microsoft.AspNet.Authentication.Test/TestClock.cs +++ b/test/Microsoft.AspNet.Authentication.Test/TestClock.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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; diff --git a/test/Microsoft.AspNet.Authentication.Test/Twitter/TwitterMiddlewareTests.cs b/test/Microsoft.AspNet.Authentication.Test/Twitter/TwitterMiddlewareTests.cs index d0b9494d1..0ad84b7f1 100644 --- a/test/Microsoft.AspNet.Authentication.Test/Twitter/TwitterMiddlewareTests.cs +++ b/test/Microsoft.AspNet.Authentication.Test/Twitter/TwitterMiddlewareTests.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. +// Copyright (c) .NET Foundation. All rights reserved. See License.txt in the project root for license information. using System; using System.Collections.Generic; diff --git a/test/Microsoft.AspNet.Authorization.Test/AuthorizationPolicyFacts.cs b/test/Microsoft.AspNet.Authorization.Test/AuthorizationPolicyFacts.cs index eae8502ae..535e8d527 100644 --- a/test/Microsoft.AspNet.Authorization.Test/AuthorizationPolicyFacts.cs +++ b/test/Microsoft.AspNet.Authorization.Test/AuthorizationPolicyFacts.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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.Linq; diff --git a/test/Microsoft.AspNet.Authorization.Test/DefaultAuthorizationServiceTests.cs b/test/Microsoft.AspNet.Authorization.Test/DefaultAuthorizationServiceTests.cs index 752d2383b..4c26f10b3 100644 --- a/test/Microsoft.AspNet.Authorization.Test/DefaultAuthorizationServiceTests.cs +++ b/test/Microsoft.AspNet.Authorization.Test/DefaultAuthorizationServiceTests.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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; From 6e7ec9b2fb6e7c1c991056f8ed6eb77627c3fa0a Mon Sep 17 00:00:00 2001 From: Hao Kung Date: Fri, 1 May 2015 17:00:06 -0700 Subject: [PATCH 200/216] Cleanup cookies (moar var) --- .../CookieAuthenticationHandler.cs | 49 +++++++++---------- .../CookieApplyRedirectContext.cs | 1 - .../CookieAuthenticationNotifications.cs | 3 +- .../CookieResponseSignInContext.cs | 1 - .../CookieResponseSignOutContext.cs | 1 - .../Notifications/DefaultBehavior.cs | 6 +-- 6 files changed, 28 insertions(+), 33 deletions(-) diff --git a/src/Microsoft.AspNet.Authentication.Cookies/CookieAuthenticationHandler.cs b/src/Microsoft.AspNet.Authentication.Cookies/CookieAuthenticationHandler.cs index 2e71d1c0e..cc1dc9168 100644 --- a/src/Microsoft.AspNet.Authentication.Cookies/CookieAuthenticationHandler.cs +++ b/src/Microsoft.AspNet.Authentication.Cookies/CookieAuthenticationHandler.cs @@ -8,7 +8,6 @@ using System.Threading.Tasks; using Microsoft.AspNet.Http; using Microsoft.AspNet.Http.Authentication; -using Microsoft.Framework.Internal; using Microsoft.Framework.Logging; namespace Microsoft.AspNet.Authentication.Cookies @@ -37,7 +36,7 @@ protected override async Task AuthenticateCoreAsync() AuthenticationTicket ticket = null; try { - string cookie = Options.CookieManager.GetRequestCookie(Context, Options.CookieName); + var cookie = Options.CookieManager.GetRequestCookie(Context, Options.CookieName); if (string.IsNullOrWhiteSpace(cookie)) { return null; @@ -53,7 +52,7 @@ protected override async Task AuthenticateCoreAsync() if (Options.SessionStore != null) { - Claim claim = ticket.Principal.Claims.FirstOrDefault(c => c.Type.Equals(SessionIdClaim)); + var claim = ticket.Principal.Claims.FirstOrDefault(c => c.Type.Equals(SessionIdClaim)); if (claim == null) { Logger.LogWarning(@"SessionId missing"); @@ -68,9 +67,9 @@ protected override async Task AuthenticateCoreAsync() } } - DateTimeOffset currentUtc = Options.SystemClock.UtcNow; - DateTimeOffset? issuedUtc = ticket.Properties.IssuedUtc; - DateTimeOffset? expiresUtc = ticket.Properties.ExpiresUtc; + var currentUtc = Options.SystemClock.UtcNow; + var issuedUtc = ticket.Properties.IssuedUtc; + var expiresUtc = ticket.Properties.ExpiresUtc; if (expiresUtc != null && expiresUtc.Value < currentUtc) { @@ -81,17 +80,17 @@ protected override async Task AuthenticateCoreAsync() return null; } - bool allowRefresh = ticket.Properties.AllowRefresh ?? true; + var allowRefresh = ticket.Properties.AllowRefresh ?? true; if (issuedUtc != null && expiresUtc != null && Options.SlidingExpiration && allowRefresh) { - TimeSpan timeElapsed = currentUtc.Subtract(issuedUtc.Value); - TimeSpan timeRemaining = expiresUtc.Value.Subtract(currentUtc); + var timeElapsed = currentUtc.Subtract(issuedUtc.Value); + var timeRemaining = expiresUtc.Value.Subtract(currentUtc); if (timeRemaining < timeElapsed) { _shouldRenew = true; _renewIssuedUtc = currentUtc; - TimeSpan timeSpan = expiresUtc.Value.Subtract(issuedUtc.Value); + var timeSpan = expiresUtc.Value.Subtract(issuedUtc.Value); _renewExpiresUtc = currentUtc.Add(timeSpan); } } @@ -104,7 +103,7 @@ protected override async Task AuthenticateCoreAsync() } catch (Exception exception) { - CookieExceptionContext exceptionContext = new CookieExceptionContext(Context, Options, + var exceptionContext = new CookieExceptionContext(Context, Options, CookieExceptionContext.ExceptionLocation.Authenticate, exception, ticket); Options.Notifications.Exception(exceptionContext); if (exceptionContext.Rethrow) @@ -123,16 +122,16 @@ protected override void ApplyResponseGrant() protected override async Task ApplyResponseGrantAsync() { var signin = SignInContext; - bool shouldSignin = signin != null; + var shouldSignin = signin != null; var signout = SignOutContext; - bool shouldSignout = signout != null; + var shouldSignout = signout != null; if (!(shouldSignin || shouldSignout || _shouldRenew)) { return; } - AuthenticationTicket model = await AuthenticateAsync(); + var model = await AuthenticateAsync(); try { var cookieOptions = new CookieOptions @@ -180,7 +179,7 @@ protected override async Task ApplyResponseGrantAsync() if (signInContext.Properties.IsPersistent) { - DateTimeOffset expiresUtc = signInContext.Properties.ExpiresUtc ?? issuedUtc.Add(Options.ExpireTimeSpan); + var expiresUtc = signInContext.Properties.ExpiresUtc ?? issuedUtc.Add(Options.ExpireTimeSpan); signInContext.CookieOptions.Expires = expiresUtc.ToUniversalTime().DateTime; } @@ -198,7 +197,7 @@ protected override async Task ApplyResponseGrantAsync() Options.AuthenticationScheme)); model = new AuthenticationTicket(principal, null, Options.AuthenticationScheme); } - string cookieValue = Options.TicketDataFormat.Protect(model); + var cookieValue = Options.TicketDataFormat.Protect(model); Options.CookieManager.AppendResponseCookie( Context, @@ -249,7 +248,7 @@ protected override async Task ApplyResponseGrantAsync() model = new AuthenticationTicket(principal, null, Options.AuthenticationScheme); } - string cookieValue = Options.TicketDataFormat.Protect(model); + var cookieValue = Options.TicketDataFormat.Protect(model); if (model.Properties.IsPersistent) { @@ -275,13 +274,13 @@ protected override async Task ApplyResponseGrantAsync() HeaderNameExpires, HeaderValueMinusOne); - bool shouldLoginRedirect = shouldSignin && Options.LoginPath.HasValue && Request.Path == Options.LoginPath; - bool shouldLogoutRedirect = shouldSignout && Options.LogoutPath.HasValue && Request.Path == Options.LogoutPath; + var shouldLoginRedirect = shouldSignin && Options.LoginPath.HasValue && Request.Path == Options.LoginPath; + var shouldLogoutRedirect = shouldSignout && Options.LogoutPath.HasValue && Request.Path == Options.LogoutPath; if ((shouldLoginRedirect || shouldLogoutRedirect) && Response.StatusCode == 200) { - IReadableStringCollection query = Request.Query; - string redirectUri = query.Get(Options.ReturnUrlParameter); + var query = Request.Query; + var redirectUri = query.Get(Options.ReturnUrlParameter); if (!string.IsNullOrWhiteSpace(redirectUri) && IsHostRelative(redirectUri)) { @@ -292,7 +291,7 @@ protected override async Task ApplyResponseGrantAsync() } catch (Exception exception) { - CookieExceptionContext exceptionContext = new CookieExceptionContext(Context, Options, + var exceptionContext = new CookieExceptionContext(Context, Options, CookieExceptionContext.ExceptionLocation.ApplyResponseGrant, exception, model); Options.Notifications.Exception(exceptionContext); if (exceptionContext.Rethrow) @@ -363,7 +362,7 @@ protected override void ApplyResponseChallenge() return; } - string loginUri = string.Empty; + var loginUri = string.Empty; if (ChallengeContext != null) { loginUri = new AuthenticationProperties(ChallengeContext.Properties).RedirectUri; @@ -373,7 +372,7 @@ protected override void ApplyResponseChallenge() { if (string.IsNullOrWhiteSpace(loginUri)) { - string currentUri = + var currentUri = Request.PathBase + Request.Path + Request.QueryString; @@ -392,7 +391,7 @@ protected override void ApplyResponseChallenge() } catch (Exception exception) { - CookieExceptionContext exceptionContext = new CookieExceptionContext(Context, Options, + var exceptionContext = new CookieExceptionContext(Context, Options, CookieExceptionContext.ExceptionLocation.ApplyResponseChallenge, exception, ticket: null); Options.Notifications.Exception(exceptionContext); if (exceptionContext.Rethrow) diff --git a/src/Microsoft.AspNet.Authentication.Cookies/Notifications/CookieApplyRedirectContext.cs b/src/Microsoft.AspNet.Authentication.Cookies/Notifications/CookieApplyRedirectContext.cs index cc6364817..9083ed817 100644 --- a/src/Microsoft.AspNet.Authentication.Cookies/Notifications/CookieApplyRedirectContext.cs +++ b/src/Microsoft.AspNet.Authentication.Cookies/Notifications/CookieApplyRedirectContext.cs @@ -1,7 +1,6 @@ // Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - using System.Diagnostics.CodeAnalysis; using Microsoft.AspNet.Http; using Microsoft.AspNet.Authentication.Notifications; diff --git a/src/Microsoft.AspNet.Authentication.Cookies/Notifications/CookieAuthenticationNotifications.cs b/src/Microsoft.AspNet.Authentication.Cookies/Notifications/CookieAuthenticationNotifications.cs index dc287484a..0c875b208 100644 --- a/src/Microsoft.AspNet.Authentication.Cookies/Notifications/CookieAuthenticationNotifications.cs +++ b/src/Microsoft.AspNet.Authentication.Cookies/Notifications/CookieAuthenticationNotifications.cs @@ -1,7 +1,6 @@ // Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - using System; using System.Threading.Tasks; @@ -112,4 +111,4 @@ public virtual void Exception(CookieExceptionContext context) OnException.Invoke(context); } } -} +} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Authentication.Cookies/Notifications/CookieResponseSignInContext.cs b/src/Microsoft.AspNet.Authentication.Cookies/Notifications/CookieResponseSignInContext.cs index e9d7b1059..f894231ae 100644 --- a/src/Microsoft.AspNet.Authentication.Cookies/Notifications/CookieResponseSignInContext.cs +++ b/src/Microsoft.AspNet.Authentication.Cookies/Notifications/CookieResponseSignInContext.cs @@ -1,7 +1,6 @@ // Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - using System.Security.Claims; using Microsoft.AspNet.Http; using Microsoft.AspNet.Http.Authentication; diff --git a/src/Microsoft.AspNet.Authentication.Cookies/Notifications/CookieResponseSignOutContext.cs b/src/Microsoft.AspNet.Authentication.Cookies/Notifications/CookieResponseSignOutContext.cs index 28dce3cdf..260a31ad9 100644 --- a/src/Microsoft.AspNet.Authentication.Cookies/Notifications/CookieResponseSignOutContext.cs +++ b/src/Microsoft.AspNet.Authentication.Cookies/Notifications/CookieResponseSignOutContext.cs @@ -1,7 +1,6 @@ // Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - using Microsoft.AspNet.Http; using Microsoft.AspNet.Authentication.Notifications; diff --git a/src/Microsoft.AspNet.Authentication.Cookies/Notifications/DefaultBehavior.cs b/src/Microsoft.AspNet.Authentication.Cookies/Notifications/DefaultBehavior.cs index 77d537710..9807bbdf4 100644 --- a/src/Microsoft.AspNet.Authentication.Cookies/Notifications/DefaultBehavior.cs +++ b/src/Microsoft.AspNet.Authentication.Cookies/Notifications/DefaultBehavior.cs @@ -14,7 +14,7 @@ internal static class DefaultBehavior { if (IsAjaxRequest(context.Request)) { - string jsonResponse = JsonConvert.SerializeObject(new + var jsonResponse = JsonConvert.SerializeObject(new { status = context.Response.StatusCode, headers = new @@ -34,7 +34,7 @@ internal static class DefaultBehavior private static bool IsAjaxRequest(HttpRequest request) { - IReadableStringCollection query = request.Query; + var query = request.Query; if (query != null) { if (query["X-Requested-With"] == "XMLHttpRequest") @@ -43,7 +43,7 @@ private static bool IsAjaxRequest(HttpRequest request) } } - IHeaderDictionary headers = request.Headers; + var headers = request.Headers; if (headers != null) { if (headers["X-Requested-With"] == "XMLHttpRequest") From f864244124560ff90d3f138add02456f72d5925e Mon Sep 17 00:00:00 2001 From: Chris R Date: Tue, 5 May 2015 09:52:15 -0700 Subject: [PATCH 201/216] #242 Remove diagnostics sample dependency. --- samples/SocialSample/Startup.cs | 2 -- samples/SocialSample/project.json | 1 - 2 files changed, 3 deletions(-) diff --git a/samples/SocialSample/Startup.cs b/samples/SocialSample/Startup.cs index f552ceea3..22c0e44a0 100644 --- a/samples/SocialSample/Startup.cs +++ b/samples/SocialSample/Startup.cs @@ -37,8 +37,6 @@ public void Configure(IApplicationBuilder app, ILoggerFactory loggerfactory) { loggerfactory.AddConsole(LogLevel.Information); - app.UseErrorPage(); - app.UseCookieAuthentication(options => { options.AutomaticAuthentication = true; diff --git a/samples/SocialSample/project.json b/samples/SocialSample/project.json index ccaf0a439..020f08b1b 100644 --- a/samples/SocialSample/project.json +++ b/samples/SocialSample/project.json @@ -6,7 +6,6 @@ "Microsoft.AspNet.Authentication.MicrosoftAccount": "1.0.0-*", "Microsoft.AspNet.Authentication.Twitter": "1.0.0-*", "Microsoft.AspNet.DataProtection": "1.0.0-*", - "Microsoft.AspNet.Diagnostics": "1.0.0-*", "Microsoft.AspNet.Server.IIS": "1.0.0-*", "Microsoft.AspNet.Server.WebListener": "1.0.0-*", "Microsoft.Framework.Logging.Console": "1.0.0-*", From ce48c1fc7dabe0315b18eda378586ec169542b9c Mon Sep 17 00:00:00 2001 From: Hao Kung Date: Tue, 5 May 2015 14:50:59 -0700 Subject: [PATCH 202/216] Move ClaimsIssuer to base AuthenticationOptions Also step 1 of refactoring tests --- .../CookieAuthenticationHandler.cs | 6 +- .../FacebookAuthenticationHandler.cs | 19 +- .../GoogleAuthenticationHandler.cs | 16 +- .../GoogleAuthenticationMiddleware.cs | 1 - .../GoogleAuthenticationOptions.cs | 6 +- .../MicrosoftAccountAuthenticationHandler.cs | 12 +- .../OAuthAuthenticationMiddleware.cs | 2 +- .../OAuthAuthenticationOptions.cs | 6 - .../OAuthBearerAuthenticationHandler.cs | 8 +- .../OAuthBearerAuthenticationMiddleware.cs | 4 +- .../OAuthBearerAuthenticationOptions.cs | 1 - .../TwitterAuthenticationHandler.cs | 12 +- .../AuthenticationMiddleware.cs | 6 + .../AuthenticationOptions.cs | 5 + .../Encoder/Base64UrlTextEncoder.cs | 1 - .../SecurityHelper.cs | 5 +- .../Cookies/CookieMiddlewareTests.cs | 129 +++++++------- .../Facebook/FacebookMiddlewareTests.cs | 42 +---- .../Google/GoogleMiddlewareTests.cs | 167 ++++-------------- .../MicrosoftAccountMiddlewareTests.cs | 154 +++------------- .../OAuthBearer/OAuthBearerMiddlewareTests.cs | 13 +- .../OpenIdConnect/TestUtilities.cs | 1 - .../SecurityHelperTests.cs | 6 +- .../TestExtensions.cs | 73 ++++++++ .../TestHttpMessageHandler.cs | 24 +++ .../Transaction.cs | 50 ++++++ .../Twitter/TwitterMiddlewareTests.cs | 50 +----- 27 files changed, 327 insertions(+), 492 deletions(-) create mode 100644 test/Microsoft.AspNet.Authentication.Test/TestExtensions.cs create mode 100644 test/Microsoft.AspNet.Authentication.Test/TestHttpMessageHandler.cs create mode 100644 test/Microsoft.AspNet.Authentication.Test/Transaction.cs diff --git a/src/Microsoft.AspNet.Authentication.Cookies/CookieAuthenticationHandler.cs b/src/Microsoft.AspNet.Authentication.Cookies/CookieAuthenticationHandler.cs index cc1dc9168..b002fc2d6 100644 --- a/src/Microsoft.AspNet.Authentication.Cookies/CookieAuthenticationHandler.cs +++ b/src/Microsoft.AspNet.Authentication.Cookies/CookieAuthenticationHandler.cs @@ -193,8 +193,8 @@ protected override async Task ApplyResponseGrantAsync() _sessionKey = await Options.SessionStore.StoreAsync(model); var principal = new ClaimsPrincipal( new ClaimsIdentity( - new[] { new Claim(SessionIdClaim, _sessionKey) }, - Options.AuthenticationScheme)); + new[] { new Claim(SessionIdClaim, _sessionKey, ClaimValueTypes.String, Options.ClaimsIssuer) }, + Options.ClaimsIssuer)); model = new AuthenticationTicket(principal, null, Options.AuthenticationScheme); } var cookieValue = Options.TicketDataFormat.Protect(model); @@ -243,7 +243,7 @@ protected override async Task ApplyResponseGrantAsync() await Options.SessionStore.RenewAsync(_sessionKey, model); var principal = new ClaimsPrincipal( new ClaimsIdentity( - new[] { new Claim(SessionIdClaim, _sessionKey) }, + new[] { new Claim(SessionIdClaim, _sessionKey, ClaimValueTypes.String, Options.ClaimsIssuer) }, Options.AuthenticationScheme)); model = new AuthenticationTicket(principal, null, Options.AuthenticationScheme); } diff --git a/src/Microsoft.AspNet.Authentication.Facebook/FacebookAuthenticationHandler.cs b/src/Microsoft.AspNet.Authentication.Facebook/FacebookAuthenticationHandler.cs index aa306d683..3549eec2d 100644 --- a/src/Microsoft.AspNet.Authentication.Facebook/FacebookAuthenticationHandler.cs +++ b/src/Microsoft.AspNet.Authentication.Facebook/FacebookAuthenticationHandler.cs @@ -13,7 +13,6 @@ using Microsoft.AspNet.Http.Collections; using Microsoft.AspNet.Http.Extensions; using Microsoft.AspNet.WebUtilities; -using Microsoft.Framework.WebEncoders; using Newtonsoft.Json.Linq; namespace Microsoft.AspNet.Authentication.Facebook @@ -65,34 +64,34 @@ protected override async Task GetUserInformationAsync(Auth var context = new FacebookAuthenticatedContext(Context, Options, user, tokens); var identity = new ClaimsIdentity( - Options.AuthenticationScheme, + Options.ClaimsIssuer, ClaimsIdentity.DefaultNameClaimType, ClaimsIdentity.DefaultRoleClaimType); if (!string.IsNullOrEmpty(context.Id)) { - identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, context.Id, ClaimValueTypes.String, Options.AuthenticationScheme)); + identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, context.Id, ClaimValueTypes.String, Options.ClaimsIssuer)); } if (!string.IsNullOrEmpty(context.UserName)) { - identity.AddClaim(new Claim(ClaimsIdentity.DefaultNameClaimType, context.UserName, ClaimValueTypes.String, Options.AuthenticationScheme)); + identity.AddClaim(new Claim(ClaimsIdentity.DefaultNameClaimType, context.UserName, ClaimValueTypes.String, Options.ClaimsIssuer)); } if (!string.IsNullOrEmpty(context.Email)) { - identity.AddClaim(new Claim(ClaimTypes.Email, context.Email, ClaimValueTypes.String, Options.AuthenticationScheme)); + identity.AddClaim(new Claim(ClaimTypes.Email, context.Email, ClaimValueTypes.String, Options.ClaimsIssuer)); } if (!string.IsNullOrEmpty(context.Name)) { - identity.AddClaim(new Claim("urn:facebook:name", context.Name, ClaimValueTypes.String, Options.AuthenticationScheme)); + identity.AddClaim(new Claim("urn:facebook:name", context.Name, ClaimValueTypes.String, Options.ClaimsIssuer)); // Many Facebook accounts do not set the UserName field. Fall back to the Name field instead. if (string.IsNullOrEmpty(context.UserName)) { - identity.AddClaim(new Claim(ClaimsIdentity.DefaultNameClaimType, context.Name, ClaimValueTypes.String, Options.AuthenticationScheme)); + identity.AddClaim(new Claim(ClaimsIdentity.DefaultNameClaimType, context.Name, ClaimValueTypes.String, Options.ClaimsIssuer)); } } if (!string.IsNullOrEmpty(context.Link)) { - identity.AddClaim(new Claim("urn:facebook:link", context.Link, ClaimValueTypes.String, Options.AuthenticationScheme)); + identity.AddClaim(new Claim("urn:facebook:link", context.Link, ClaimValueTypes.String, Options.ClaimsIssuer)); } context.Properties = properties; context.Principal = new ClaimsPrincipal(identity); @@ -104,7 +103,7 @@ protected override async Task GetUserInformationAsync(Auth private string GenerateAppSecretProof(string accessToken) { - using (HMACSHA256 algorithm = new HMACSHA256(Encoding.ASCII.GetBytes(Options.AppSecret))) + using (var algorithm = new HMACSHA256(Encoding.ASCII.GetBytes(Options.AppSecret))) { var hash = algorithm.ComputeHash(Encoding.ASCII.GetBytes(accessToken)); var builder = new StringBuilder(); @@ -124,4 +123,4 @@ protected override string FormatScope() return string.Join(",", Options.Scope); } } -} +} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Authentication.Google/GoogleAuthenticationHandler.cs b/src/Microsoft.AspNet.Authentication.Google/GoogleAuthenticationHandler.cs index b54f657be..621e77d83 100644 --- a/src/Microsoft.AspNet.Authentication.Google/GoogleAuthenticationHandler.cs +++ b/src/Microsoft.AspNet.Authentication.Google/GoogleAuthenticationHandler.cs @@ -33,39 +33,39 @@ protected override async Task GetUserInformationAsync(Auth var context = new GoogleAuthenticatedContext(Context, Options, user, tokens); var identity = new ClaimsIdentity( - Options.AuthenticationScheme, + Options.ClaimsIssuer, ClaimsIdentity.DefaultNameClaimType, ClaimsIdentity.DefaultRoleClaimType); if (!string.IsNullOrEmpty(context.Id)) { identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, context.Id, - ClaimValueTypes.String, Options.AuthenticationScheme)); + ClaimValueTypes.String, Options.ClaimsIssuer)); } if (!string.IsNullOrEmpty(context.GivenName)) { identity.AddClaim(new Claim(ClaimTypes.GivenName, context.GivenName, - ClaimValueTypes.String, Options.AuthenticationScheme)); + ClaimValueTypes.String, Options.ClaimsIssuer)); } if (!string.IsNullOrEmpty(context.FamilyName)) { identity.AddClaim(new Claim(ClaimTypes.Surname, context.FamilyName, - ClaimValueTypes.String, Options.AuthenticationScheme)); + ClaimValueTypes.String, Options.ClaimsIssuer)); } if (!string.IsNullOrEmpty(context.Name)) { identity.AddClaim(new Claim(ClaimTypes.Name, context.Name, ClaimValueTypes.String, - Options.AuthenticationScheme)); + Options.ClaimsIssuer)); } if (!string.IsNullOrEmpty(context.Email)) { identity.AddClaim(new Claim(ClaimTypes.Email, context.Email, ClaimValueTypes.String, - Options.AuthenticationScheme)); + Options.ClaimsIssuer)); } if (!string.IsNullOrEmpty(context.Profile)) { identity.AddClaim(new Claim("urn:google:profile", context.Profile, ClaimValueTypes.String, - Options.AuthenticationScheme)); + Options.ClaimsIssuer)); } context.Properties = properties; context.Principal = new ClaimsPrincipal(identity); @@ -120,4 +120,4 @@ private static void AddQueryString(IDictionary queryStrings, Aut queryStrings[name] = value; } } -} +} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Authentication.Google/GoogleAuthenticationMiddleware.cs b/src/Microsoft.AspNet.Authentication.Google/GoogleAuthenticationMiddleware.cs index 2921b6b21..db7a3c988 100644 --- a/src/Microsoft.AspNet.Authentication.Google/GoogleAuthenticationMiddleware.cs +++ b/src/Microsoft.AspNet.Authentication.Google/GoogleAuthenticationMiddleware.cs @@ -1,7 +1,6 @@ // Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -using System; using System.Diagnostics.CodeAnalysis; using Microsoft.AspNet.Authentication.OAuth; using Microsoft.AspNet.Builder; diff --git a/src/Microsoft.AspNet.Authentication.Google/GoogleAuthenticationOptions.cs b/src/Microsoft.AspNet.Authentication.Google/GoogleAuthenticationOptions.cs index 1dab084f0..e65b800ed 100644 --- a/src/Microsoft.AspNet.Authentication.Google/GoogleAuthenticationOptions.cs +++ b/src/Microsoft.AspNet.Authentication.Google/GoogleAuthenticationOptions.cs @@ -1,12 +1,8 @@ // Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -using System; -using System.Collections.Generic; -using System.Net.Http; -using Microsoft.AspNet.Http; -using Microsoft.AspNet.Http.Authentication; using Microsoft.AspNet.Authentication.OAuth; +using Microsoft.AspNet.Http; namespace Microsoft.AspNet.Authentication.Google { diff --git a/src/Microsoft.AspNet.Authentication.MicrosoftAccount/MicrosoftAccountAuthenticationHandler.cs b/src/Microsoft.AspNet.Authentication.MicrosoftAccount/MicrosoftAccountAuthenticationHandler.cs index 4ecaabab6..31484f998 100644 --- a/src/Microsoft.AspNet.Authentication.MicrosoftAccount/MicrosoftAccountAuthenticationHandler.cs +++ b/src/Microsoft.AspNet.Authentication.MicrosoftAccount/MicrosoftAccountAuthenticationHandler.cs @@ -32,18 +32,18 @@ protected override async Task GetUserInformationAsync(Auth var identity = new ClaimsIdentity( new[] { - new Claim(ClaimTypes.NameIdentifier, context.Id, ClaimValueTypes.String, Options.AuthenticationScheme), - new Claim(ClaimTypes.Name, context.Name, ClaimValueTypes.String, Options.AuthenticationScheme), - new Claim("urn:microsoftaccount:id", context.Id, ClaimValueTypes.String, Options.AuthenticationScheme), - new Claim("urn:microsoftaccount:name", context.Name, ClaimValueTypes.String, Options.AuthenticationScheme) + new Claim(ClaimTypes.NameIdentifier, context.Id, ClaimValueTypes.String, Options.ClaimsIssuer), + new Claim(ClaimTypes.Name, context.Name, ClaimValueTypes.String, Options.ClaimsIssuer), + new Claim("urn:microsoftaccount:id", context.Id, ClaimValueTypes.String, Options.ClaimsIssuer), + new Claim("urn:microsoftaccount:name", context.Name, ClaimValueTypes.String, Options.ClaimsIssuer) }, - Options.AuthenticationScheme, + Options.ClaimsIssuer, ClaimsIdentity.DefaultNameClaimType, ClaimsIdentity.DefaultRoleClaimType); if (!string.IsNullOrWhiteSpace(context.Email)) { - identity.AddClaim(new Claim(ClaimTypes.Email, context.Email, ClaimValueTypes.String, Options.AuthenticationScheme)); + identity.AddClaim(new Claim(ClaimTypes.Email, context.Email, ClaimValueTypes.String, Options.ClaimsIssuer)); } context.Principal = new ClaimsPrincipal(identity); diff --git a/src/Microsoft.AspNet.Authentication.OAuth/OAuthAuthenticationMiddleware.cs b/src/Microsoft.AspNet.Authentication.OAuth/OAuthAuthenticationMiddleware.cs index e4357a68a..70d4544a2 100644 --- a/src/Microsoft.AspNet.Authentication.OAuth/OAuthAuthenticationMiddleware.cs +++ b/src/Microsoft.AspNet.Authentication.OAuth/OAuthAuthenticationMiddleware.cs @@ -69,7 +69,7 @@ public OAuthAuthenticationMiddleware( if (Options.StateDataFormat == null) { var dataProtector = dataProtectionProvider.CreateProtector( - this.GetType().FullName, Options.AuthenticationScheme, "v1"); + GetType().FullName, Options.AuthenticationScheme, "v1"); Options.StateDataFormat = new PropertiesDataFormat(dataProtector); } diff --git a/src/Microsoft.AspNet.Authentication.OAuth/OAuthAuthenticationOptions.cs b/src/Microsoft.AspNet.Authentication.OAuth/OAuthAuthenticationOptions.cs index bfbea1e29..62296c4a9 100644 --- a/src/Microsoft.AspNet.Authentication.OAuth/OAuthAuthenticationOptions.cs +++ b/src/Microsoft.AspNet.Authentication.OAuth/OAuthAuthenticationOptions.cs @@ -4,7 +4,6 @@ using System; using System.Collections.Generic; using System.Net.Http; -using System.Threading.Tasks; using Microsoft.AspNet.Http; using Microsoft.AspNet.Http.Authentication; @@ -106,11 +105,6 @@ public string Caption /// public string SignInScheme { get; set; } - /// - /// Gets or sets the issuer that should be used for any claims that are created - /// - public string ClaimsIssuer { get; set; } - /// /// Gets or sets the type used to secure data handled by the middleware. /// diff --git a/src/Microsoft.AspNet.Authentication.OAuthBearer/OAuthBearerAuthenticationHandler.cs b/src/Microsoft.AspNet.Authentication.OAuthBearer/OAuthBearerAuthenticationHandler.cs index c88d45604..b08851950 100644 --- a/src/Microsoft.AspNet.Authentication.OAuthBearer/OAuthBearerAuthenticationHandler.cs +++ b/src/Microsoft.AspNet.Authentication.OAuthBearer/OAuthBearerAuthenticationHandler.cs @@ -79,7 +79,7 @@ protected override async Task AuthenticateCoreAsync() // notify user token was received var securityTokenReceivedNotification = - new SecurityTokenReceivedNotification(Context, Options) + new SecurityTokenReceivedNotification(Context, Options) { ProtocolMessage = Context, SecurityToken = token, @@ -110,7 +110,7 @@ protected override async Task AuthenticateCoreAsync() } else { - IEnumerable issuers = new[] { _configuration.Issuer }; + var issuers = new[] { _configuration.Issuer }; validationParameters.ValidIssuers = (validationParameters.ValidIssuers == null ? issuers : validationParameters.ValidIssuers.Concat(issuers)); } @@ -122,8 +122,8 @@ protected override async Task AuthenticateCoreAsync() { if (validator.CanReadToken(token)) { - ClaimsPrincipal principal = validator.ValidateToken(token, validationParameters, out validatedToken); - AuthenticationTicket ticket = new AuthenticationTicket(principal, new AuthenticationProperties(), Options.AuthenticationScheme); + var principal = validator.ValidateToken(token, validationParameters, out validatedToken); + var ticket = new AuthenticationTicket(principal, new AuthenticationProperties(), Options.AuthenticationScheme); var securityTokenValidatedNotification = new SecurityTokenValidatedNotification(Context, Options) { ProtocolMessage = Context, diff --git a/src/Microsoft.AspNet.Authentication.OAuthBearer/OAuthBearerAuthenticationMiddleware.cs b/src/Microsoft.AspNet.Authentication.OAuthBearer/OAuthBearerAuthenticationMiddleware.cs index ed1242b95..c76071b6a 100644 --- a/src/Microsoft.AspNet.Authentication.OAuthBearer/OAuthBearerAuthenticationMiddleware.cs +++ b/src/Microsoft.AspNet.Authentication.OAuthBearer/OAuthBearerAuthenticationMiddleware.cs @@ -23,8 +23,6 @@ namespace Microsoft.AspNet.Authentication.OAuthBearer /// public class OAuthBearerAuthenticationMiddleware : AuthenticationMiddleware { - private readonly ILogger _logger; - /// /// 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 UseOAuthBearerAuthentication @@ -72,7 +70,7 @@ public OAuthBearerAuthenticationMiddleware( Options.MetadataAddress += ".well-known/openid-configuration"; } - HttpClient httpClient = new HttpClient(ResolveHttpMessageHandler(Options)); + var httpClient = new HttpClient(ResolveHttpMessageHandler(Options)); httpClient.Timeout = Options.BackchannelTimeout; httpClient.MaxResponseContentBufferSize = 1024 * 1024 * 10; // 10 MB diff --git a/src/Microsoft.AspNet.Authentication.OAuthBearer/OAuthBearerAuthenticationOptions.cs b/src/Microsoft.AspNet.Authentication.OAuthBearer/OAuthBearerAuthenticationOptions.cs index 00cc96c7a..e52040687 100644 --- a/src/Microsoft.AspNet.Authentication.OAuthBearer/OAuthBearerAuthenticationOptions.cs +++ b/src/Microsoft.AspNet.Authentication.OAuthBearer/OAuthBearerAuthenticationOptions.cs @@ -5,7 +5,6 @@ using System.Collections.Generic; using System.IdentityModel.Tokens; using System.Net.Http; -using Microsoft.AspNet.Authentication; using Microsoft.IdentityModel.Protocols; namespace Microsoft.AspNet.Authentication.OAuthBearer diff --git a/src/Microsoft.AspNet.Authentication.Twitter/TwitterAuthenticationHandler.cs b/src/Microsoft.AspNet.Authentication.Twitter/TwitterAuthenticationHandler.cs index cd09a1416..61ff95e2f 100644 --- a/src/Microsoft.AspNet.Authentication.Twitter/TwitterAuthenticationHandler.cs +++ b/src/Microsoft.AspNet.Authentication.Twitter/TwitterAuthenticationHandler.cs @@ -78,7 +78,7 @@ protected override async Task AuthenticateCoreAsync() return new AuthenticationTicket(properties, Options.AuthenticationScheme); } - string oauthVerifier = query.Get("oauth_verifier"); + var oauthVerifier = query.Get("oauth_verifier"); if (string.IsNullOrWhiteSpace(oauthVerifier)) { Logger.LogWarning("Missing or blank oauth_verifier"); @@ -93,12 +93,12 @@ protected override async Task AuthenticateCoreAsync() new ClaimsIdentity( new[] { - new Claim(ClaimTypes.NameIdentifier, accessToken.UserId, "http://www.w3.org/2001/XMLSchema#string", Options.AuthenticationScheme), - new Claim(ClaimTypes.Name, accessToken.ScreenName, "http://www.w3.org/2001/XMLSchema#string", Options.AuthenticationScheme), - new Claim("urn:twitter:userid", accessToken.UserId, "http://www.w3.org/2001/XMLSchema#string", Options.AuthenticationScheme), - new Claim("urn:twitter:screenname", accessToken.ScreenName, "http://www.w3.org/2001/XMLSchema#string", Options.AuthenticationScheme) + new Claim(ClaimTypes.NameIdentifier, accessToken.UserId, "http://www.w3.org/2001/XMLSchema#string", Options.ClaimsIssuer), + new Claim(ClaimTypes.Name, accessToken.ScreenName, "http://www.w3.org/2001/XMLSchema#string", Options.ClaimsIssuer), + new Claim("urn:twitter:userid", accessToken.UserId, "http://www.w3.org/2001/XMLSchema#string", Options.ClaimsIssuer), + new Claim("urn:twitter:screenname", accessToken.ScreenName, "http://www.w3.org/2001/XMLSchema#string", Options.ClaimsIssuer) }, - Options.AuthenticationScheme, + Options.ClaimsIssuer, ClaimsIdentity.DefaultNameClaimType, ClaimsIdentity.DefaultRoleClaimType)); context.Properties = requestToken.Properties; diff --git a/src/Microsoft.AspNet.Authentication/AuthenticationMiddleware.cs b/src/Microsoft.AspNet.Authentication/AuthenticationMiddleware.cs index 7cfd6138f..188f903c4 100644 --- a/src/Microsoft.AspNet.Authentication/AuthenticationMiddleware.cs +++ b/src/Microsoft.AspNet.Authentication/AuthenticationMiddleware.cs @@ -35,6 +35,12 @@ protected AuthenticationMiddleware( Logger = loggerFactory.CreateLogger(this.GetType().FullName); UrlEncoder = encoder; + if (string.IsNullOrEmpty(Options.ClaimsIssuer)) + { + // Default to something reasonable + Options.ClaimsIssuer = Options.AuthenticationScheme; + } + _next = next; } diff --git a/src/Microsoft.AspNet.Authentication/AuthenticationOptions.cs b/src/Microsoft.AspNet.Authentication/AuthenticationOptions.cs index b1c2bc263..54f8a7a35 100644 --- a/src/Microsoft.AspNet.Authentication/AuthenticationOptions.cs +++ b/src/Microsoft.AspNet.Authentication/AuthenticationOptions.cs @@ -33,6 +33,11 @@ public string AuthenticationScheme /// public bool AutomaticAuthentication { get; set; } + /// + /// Gets or sets the issuer that should be used for any claims that are created + /// + public string ClaimsIssuer { get; set; } + /// /// Additional information about the authentication type which is made available to the application. /// diff --git a/src/Microsoft.AspNet.Authentication/DataHandler/Encoder/Base64UrlTextEncoder.cs b/src/Microsoft.AspNet.Authentication/DataHandler/Encoder/Base64UrlTextEncoder.cs index 723736973..28d74196f 100644 --- a/src/Microsoft.AspNet.Authentication/DataHandler/Encoder/Base64UrlTextEncoder.cs +++ b/src/Microsoft.AspNet.Authentication/DataHandler/Encoder/Base64UrlTextEncoder.cs @@ -1,7 +1,6 @@ // Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - using System; using Microsoft.Framework.Internal; diff --git a/src/Microsoft.AspNet.Authentication/SecurityHelper.cs b/src/Microsoft.AspNet.Authentication/SecurityHelper.cs index ea7234b20..617fe14a1 100644 --- a/src/Microsoft.AspNet.Authentication/SecurityHelper.cs +++ b/src/Microsoft.AspNet.Authentication/SecurityHelper.cs @@ -1,9 +1,6 @@ // Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -using System; -using System.Collections.Generic; -using System.Linq; using System.Security.Claims; using Microsoft.AspNet.Http; using Microsoft.Framework.Internal; @@ -21,7 +18,7 @@ public static class SecurityHelper /// public static void AddUserPrincipal([NotNull] HttpContext context, [NotNull] ClaimsPrincipal principal) { - ClaimsPrincipal existingPrincipal = context.User; + var existingPrincipal = context.User; if (existingPrincipal != null) { foreach (var existingClaimsIdentity in existingPrincipal.Identities) diff --git a/test/Microsoft.AspNet.Authentication.Test/Cookies/CookieMiddlewareTests.cs b/test/Microsoft.AspNet.Authentication.Test/Cookies/CookieMiddlewareTests.cs index d35978aee..c36836532 100644 --- a/test/Microsoft.AspNet.Authentication.Test/Cookies/CookieMiddlewareTests.cs +++ b/test/Microsoft.AspNet.Authentication.Test/Cookies/CookieMiddlewareTests.cs @@ -27,10 +27,10 @@ public class CookieMiddlewareTests [Fact] public async Task NormalRequestPassesThrough() { - TestServer server = CreateServer(options => + var server = CreateServer(options => { }); - HttpResponseMessage response = await server.CreateClient().GetAsync("http://example.com/normal"); + var response = await server.CreateClient().GetAsync("http://example.com/normal"); response.StatusCode.ShouldBe(HttpStatusCode.OK); } @@ -39,13 +39,13 @@ public async Task NormalRequestPassesThrough() [InlineData(false)] public async Task ProtectedRequestShouldRedirectToLoginOnlyWhenAutomatic(bool auto) { - TestServer server = CreateServer(options => + var server = CreateServer(options => { options.LoginPath = new PathString("/login"); options.AutomaticAuthentication = auto; }); - Transaction transaction = await SendAsync(server, "http://example.com/protected"); + var transaction = await SendAsync(server, "http://example.com/protected"); transaction.Response.StatusCode.ShouldBe(auto ? HttpStatusCode.Redirect : HttpStatusCode.Unauthorized); if (auto) @@ -61,13 +61,13 @@ public async Task ProtectedRequestShouldRedirectToLoginOnlyWhenAutomatic(bool au [InlineData(false)] public async Task ProtectedCustomRequestShouldRedirectToCustomLogin(bool auto) { - TestServer server = CreateServer(options => + var server = CreateServer(options => { options.LoginPath = new PathString("/login"); options.AutomaticAuthentication = auto; }); - Transaction transaction = await SendAsync(server, "http://example.com/protected/CustomRedirect"); + var transaction = await SendAsync(server, "http://example.com/protected/CustomRedirect"); transaction.Response.StatusCode.ShouldBe(auto ? HttpStatusCode.Redirect : HttpStatusCode.Unauthorized); if (auto) @@ -102,15 +102,15 @@ private Task SignOutAsWrong(HttpContext context) [Fact] public async Task SignInCausesDefaultCookieToBeCreated() { - TestServer server = CreateServer(options => + var server = CreateServer(options => { options.LoginPath = new PathString("/login"); options.CookieName = "TestCookie"; }, SignInAsAlice); - Transaction transaction = await SendAsync(server, "http://example.com/testpath"); + var transaction = await SendAsync(server, "http://example.com/testpath"); - string setCookie = transaction.SetCookie; + var setCookie = transaction.SetCookie; setCookie.ShouldStartWith("TestCookie="); setCookie.ShouldContain("; path=/"); setCookie.ShouldContain("; HttpOnly"); @@ -122,7 +122,7 @@ public async Task SignInCausesDefaultCookieToBeCreated() [Fact] public async Task SignInWrongAuthTypeThrows() { - TestServer server = CreateServer(options => + var server = CreateServer(options => { options.LoginPath = new PathString("/login"); options.CookieName = "TestCookie"; @@ -134,7 +134,7 @@ public async Task SignInWrongAuthTypeThrows() [Fact] public async Task SignOutWrongAuthTypeThrows() { - TestServer server = CreateServer(options => + var server = CreateServer(options => { options.LoginPath = new PathString("/login"); options.CookieName = "TestCookie"; @@ -155,15 +155,15 @@ public async Task SecureSignInCausesSecureOnlyCookieByDefault( string requestUri, bool shouldBeSecureOnly) { - TestServer server = CreateServer(options => + var server = CreateServer(options => { options.LoginPath = new PathString("/login"); options.CookieName = "TestCookie"; options.CookieSecure = cookieSecureOption; }, SignInAsAlice); - Transaction transaction = await SendAsync(server, requestUri); - string setCookie = transaction.SetCookie; + var transaction = await SendAsync(server, requestUri); + var setCookie = transaction.SetCookie; if (shouldBeSecureOnly) { @@ -187,9 +187,9 @@ public async Task CookieOptionsAlterSetCookieHeader() options.CookieHttpOnly = true; }, SignInAsAlice, new Uri("http://example.com/base")); - Transaction transaction1 = await SendAsync(server1, "http://example.com/base/testpath"); + var transaction1 = await SendAsync(server1, "http://example.com/base/testpath"); - string setCookie1 = transaction1.SetCookie; + var setCookie1 = transaction1.SetCookie; setCookie1.ShouldContain("TestCookie="); setCookie1.ShouldContain(" path=/foo"); @@ -197,16 +197,16 @@ public async Task CookieOptionsAlterSetCookieHeader() setCookie1.ShouldContain(" secure"); setCookie1.ShouldContain(" HttpOnly"); - TestServer server2 = CreateServer(options => + var server2 = CreateServer(options => { options.CookieName = "SecondCookie"; options.CookieSecure = CookieSecureOption.Never; options.CookieHttpOnly = false; }, SignInAsAlice, new Uri("http://example.com/base")); - Transaction transaction2 = await SendAsync(server2, "http://example.com/base/testpath"); + var transaction2 = await SendAsync(server2, "http://example.com/base/testpath"); - string setCookie2 = transaction2.SetCookie; + var setCookie2 = transaction2.SetCookie; setCookie2.ShouldContain("SecondCookie="); setCookie2.ShouldContain(" path=/base"); @@ -219,14 +219,14 @@ public async Task CookieOptionsAlterSetCookieHeader() public async Task CookieContainsIdentity() { var clock = new TestClock(); - TestServer server = CreateServer(options => + var server = CreateServer(options => { options.SystemClock = clock; }, SignInAsAlice); - Transaction transaction1 = await SendAsync(server, "http://example.com/testpath"); + var transaction1 = await SendAsync(server, "http://example.com/testpath"); - Transaction transaction2 = await SendAsync(server, "http://example.com/me/Cookies", transaction1.CookieNameValue); + var transaction2 = await SendAsync(server, "http://example.com/me/Cookies", transaction1.CookieNameValue); FindClaimValue(transaction2, ClaimTypes.Name).ShouldBe("Alice"); } @@ -235,7 +235,7 @@ public async Task CookieContainsIdentity() public async Task CookieAppliesClaimsTransform() { var clock = new TestClock(); - TestServer server = CreateServer(options => + var server = CreateServer(options => { options.SystemClock = clock; }, @@ -253,9 +253,9 @@ public async Task CookieAppliesClaimsTransform() return p; })); - Transaction transaction1 = await SendAsync(server, "http://example.com/testpath"); + var transaction1 = await SendAsync(server, "http://example.com/testpath"); - Transaction transaction2 = await SendAsync(server, "http://example.com/me/Cookies", transaction1.CookieNameValue); + var transaction2 = await SendAsync(server, "http://example.com/me/Cookies", transaction1.CookieNameValue); FindClaimValue(transaction2, ClaimTypes.Name).ShouldBe("Alice"); FindClaimValue(transaction2, "xform").ShouldBe("yup"); @@ -266,24 +266,24 @@ public async Task CookieAppliesClaimsTransform() public async Task CookieStopsWorkingAfterExpiration() { var clock = new TestClock(); - TestServer server = CreateServer(options => + var server = CreateServer(options => { options.SystemClock = clock; options.ExpireTimeSpan = TimeSpan.FromMinutes(10); options.SlidingExpiration = false; }, SignInAsAlice); - Transaction transaction1 = await SendAsync(server, "http://example.com/testpath"); + var transaction1 = await SendAsync(server, "http://example.com/testpath"); - Transaction transaction2 = await SendAsync(server, "http://example.com/me/Cookies", transaction1.CookieNameValue); + var transaction2 = await SendAsync(server, "http://example.com/me/Cookies", transaction1.CookieNameValue); clock.Add(TimeSpan.FromMinutes(7)); - Transaction transaction3 = await SendAsync(server, "http://example.com/me/Cookies", transaction1.CookieNameValue); + var transaction3 = await SendAsync(server, "http://example.com/me/Cookies", transaction1.CookieNameValue); clock.Add(TimeSpan.FromMinutes(7)); - Transaction transaction4 = await SendAsync(server, "http://example.com/me/Cookies", transaction1.CookieNameValue); + var transaction4 = await SendAsync(server, "http://example.com/me/Cookies", transaction1.CookieNameValue); transaction2.SetCookie.ShouldBe(null); FindClaimValue(transaction2, ClaimTypes.Name).ShouldBe("Alice"); @@ -297,7 +297,7 @@ public async Task CookieStopsWorkingAfterExpiration() public async Task CookieExpirationCanBeOverridenInSignin() { var clock = new TestClock(); - TestServer server = CreateServer(options => + var server = CreateServer(options => { options.SystemClock = clock; options.ExpireTimeSpan = TimeSpan.FromMinutes(10); @@ -311,17 +311,17 @@ public async Task CookieExpirationCanBeOverridenInSignin() return Task.FromResult(null); }); - Transaction transaction1 = await SendAsync(server, "http://example.com/testpath"); + var transaction1 = await SendAsync(server, "http://example.com/testpath"); - Transaction transaction2 = await SendAsync(server, "http://example.com/me/Cookies", transaction1.CookieNameValue); + var transaction2 = await SendAsync(server, "http://example.com/me/Cookies", transaction1.CookieNameValue); clock.Add(TimeSpan.FromMinutes(3)); - Transaction transaction3 = await SendAsync(server, "http://example.com/me/Cookies", transaction1.CookieNameValue); + var transaction3 = await SendAsync(server, "http://example.com/me/Cookies", transaction1.CookieNameValue); clock.Add(TimeSpan.FromMinutes(3)); - Transaction transaction4 = await SendAsync(server, "http://example.com/me/Cookies", transaction1.CookieNameValue); + var transaction4 = await SendAsync(server, "http://example.com/me/Cookies", transaction1.CookieNameValue); transaction2.SetCookie.ShouldBe(null); FindClaimValue(transaction2, ClaimTypes.Name).ShouldBe("Alice"); @@ -335,7 +335,7 @@ public async Task CookieExpirationCanBeOverridenInSignin() public async Task CookieExpirationCanBeOverridenInEvent() { var clock = new TestClock(); - TestServer server = CreateServer(options => + var server = CreateServer(options => { options.SystemClock = clock; options.ExpireTimeSpan = TimeSpan.FromMinutes(10); @@ -349,17 +349,17 @@ public async Task CookieExpirationCanBeOverridenInEvent() }; }, SignInAsAlice); - Transaction transaction1 = await SendAsync(server, "http://example.com/testpath"); + var transaction1 = await SendAsync(server, "http://example.com/testpath"); - Transaction transaction2 = await SendAsync(server, "http://example.com/me/Cookies", transaction1.CookieNameValue); + var transaction2 = await SendAsync(server, "http://example.com/me/Cookies", transaction1.CookieNameValue); clock.Add(TimeSpan.FromMinutes(3)); - Transaction transaction3 = await SendAsync(server, "http://example.com/me/Cookies", transaction1.CookieNameValue); + var transaction3 = await SendAsync(server, "http://example.com/me/Cookies", transaction1.CookieNameValue); clock.Add(TimeSpan.FromMinutes(3)); - Transaction transaction4 = await SendAsync(server, "http://example.com/me/Cookies", transaction1.CookieNameValue); + var transaction4 = await SendAsync(server, "http://example.com/me/Cookies", transaction1.CookieNameValue); transaction2.SetCookie.ShouldBe(null); FindClaimValue(transaction2, ClaimTypes.Name).ShouldBe("Alice"); @@ -373,25 +373,25 @@ public async Task CookieExpirationCanBeOverridenInEvent() public async Task CookieIsRenewedWithSlidingExpiration() { var clock = new TestClock(); - TestServer server = CreateServer(options => + var server = CreateServer(options => { options.SystemClock = clock; options.ExpireTimeSpan = TimeSpan.FromMinutes(10); options.SlidingExpiration = true; }, SignInAsAlice); - Transaction transaction1 = await SendAsync(server, "http://example.com/testpath"); + var transaction1 = await SendAsync(server, "http://example.com/testpath"); - Transaction transaction2 = await SendAsync(server, "http://example.com/me/Cookies", transaction1.CookieNameValue); + var transaction2 = await SendAsync(server, "http://example.com/me/Cookies", transaction1.CookieNameValue); clock.Add(TimeSpan.FromMinutes(4)); - Transaction transaction3 = await SendAsync(server, "http://example.com/me/Cookies", transaction1.CookieNameValue); + var transaction3 = await SendAsync(server, "http://example.com/me/Cookies", transaction1.CookieNameValue); clock.Add(TimeSpan.FromMinutes(4)); // transaction4 should arrive with a new SetCookie value - Transaction transaction4 = await SendAsync(server, "http://example.com/me/Cookies", transaction1.CookieNameValue); + var transaction4 = await SendAsync(server, "http://example.com/me/Cookies", transaction1.CookieNameValue); clock.Add(TimeSpan.FromMinutes(4)); @@ -410,13 +410,13 @@ public async Task CookieIsRenewedWithSlidingExpiration() [Fact] public async Task AjaxRedirectsAsExtraHeaderOnTwoHundred() { - TestServer server = CreateServer(options => + var server = CreateServer(options => { options.LoginPath = new PathString("/login"); options.AutomaticAuthentication = true; }); - Transaction transaction = await SendAsync(server, "http://example.com/protected", ajaxRequest: true); + var transaction = await SendAsync(server, "http://example.com/protected", ajaxRequest: true); transaction.Response.StatusCode.ShouldBe(HttpStatusCode.OK); var responded = transaction.Response.Headers.GetValues("X-Responded-JSON"); @@ -429,9 +429,7 @@ public async Task AjaxRedirectsAsExtraHeaderOnTwoHundred() public async Task CookieUsesPathBaseByDefault() { var clock = new TestClock(); - TestServer server = CreateServer(options => - { - }, + var server = CreateServer(options => { }, context => { Assert.Equal(new PathString("/base"), context.Request.PathBase); @@ -441,7 +439,7 @@ public async Task CookieUsesPathBaseByDefault() }, new Uri("http://example.com/base")); - Transaction transaction1 = await SendAsync(server, "http://example.com/base/testpath"); + var transaction1 = await SendAsync(server, "http://example.com/base/testpath"); Assert.True(transaction1.SetCookie.Contains("path=/base")); } @@ -449,15 +447,15 @@ public async Task CookieUsesPathBaseByDefault() public async Task CookieTurns401To403IfAuthenticated() { var clock = new TestClock(); - TestServer server = CreateServer(options => + var server = CreateServer(options => { options.SystemClock = clock; }, SignInAsAlice); - Transaction transaction1 = await SendAsync(server, "http://example.com/testpath"); + var transaction1 = await SendAsync(server, "http://example.com/testpath"); - Transaction transaction2 = await SendAsync(server, "http://example.com/unauthorized", transaction1.CookieNameValue); + var transaction2 = await SendAsync(server, "http://example.com/unauthorized", transaction1.CookieNameValue); transaction2.Response.StatusCode.ShouldBe(HttpStatusCode.Forbidden); } @@ -466,20 +464,20 @@ public async Task CookieTurns401To403IfAuthenticated() public async Task CookieTurns401ToAccessDeniedWhenSetAndIfAuthenticated() { var clock = new TestClock(); - TestServer server = CreateServer(options => + var server = CreateServer(options => { options.SystemClock = clock; options.AccessDeniedPath = new PathString("/accessdenied"); }, SignInAsAlice); - Transaction transaction1 = await SendAsync(server, "http://example.com/testpath"); + var transaction1 = await SendAsync(server, "http://example.com/testpath"); - Transaction transaction2 = await SendAsync(server, "http://example.com/unauthorized", transaction1.CookieNameValue); + var transaction2 = await SendAsync(server, "http://example.com/unauthorized", transaction1.CookieNameValue); transaction2.Response.StatusCode.ShouldBe(HttpStatusCode.Redirect); - Uri location = transaction2.Response.Headers.Location; + var location = transaction2.Response.Headers.Location; location.LocalPath.ShouldBe("/accessdenied"); } @@ -487,21 +485,21 @@ public async Task CookieTurns401ToAccessDeniedWhenSetAndIfAuthenticated() public async Task CookieDoesNothingTo401IfNotAuthenticated() { var clock = new TestClock(); - TestServer server = CreateServer(options => + var server = CreateServer(options => { options.SystemClock = clock; }); - Transaction transaction1 = await SendAsync(server, "http://example.com/testpath"); + var transaction1 = await SendAsync(server, "http://example.com/testpath"); - Transaction transaction2 = await SendAsync(server, "http://example.com/unauthorized", transaction1.CookieNameValue); + var transaction2 = await SendAsync(server, "http://example.com/unauthorized", transaction1.CookieNameValue); transaction2.Response.StatusCode.ShouldBe(HttpStatusCode.Unauthorized); } private static string FindClaimValue(Transaction transaction, string claimType) { - XElement claim = transaction.ResponseElement.Elements("claim").SingleOrDefault(elt => elt.Attribute("type").Value == claimType); + var claim = transaction.ResponseElement.Elements("claim").SingleOrDefault(elt => elt.Attribute("type").Value == claimType); if (claim == null) { return null; @@ -514,9 +512,9 @@ private static async Task GetAuthData(TestServer server, string url, s var request = new HttpRequestMessage(HttpMethod.Get, url); request.Headers.Add("Cookie", cookie); - HttpResponseMessage response2 = await server.CreateClient().SendAsync(request); - string text = await response2.Content.ReadAsStringAsync(); - XElement me = XElement.Parse(text); + var response2 = await server.CreateClient().SendAsync(request); + var text = await response2.Content.ReadAsStringAsync(); + var me = XElement.Parse(text); return me; } @@ -525,6 +523,7 @@ private static TestServer CreateServer(Action confi var server = TestServer.Create(app => { app.UseCookieAuthentication(configureOptions); + if (claimsTransform != null) { app.UseClaimsTransformation(); diff --git a/test/Microsoft.AspNet.Authentication.Test/Facebook/FacebookMiddlewareTests.cs b/test/Microsoft.AspNet.Authentication.Test/Facebook/FacebookMiddlewareTests.cs index 4977a9923..6279c0a8e 100644 --- a/test/Microsoft.AspNet.Authentication.Test/Facebook/FacebookMiddlewareTests.cs +++ b/test/Microsoft.AspNet.Authentication.Test/Facebook/FacebookMiddlewareTests.cs @@ -2,10 +2,7 @@ // 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.Linq; using System.Net; -using System.Net.Http; using System.Threading.Tasks; using Microsoft.AspNet.Builder; using Microsoft.AspNet.Http; @@ -29,8 +26,7 @@ public async Task ChallengeWillTriggerApplyRedirectEvent() }, services => { - services.AddWebEncoders(); - services.AddDataProtection(); + services.AddAuthentication(); services.ConfigureFacebookAuthentication(options => { options.AppId = "Test App Id"; @@ -58,7 +54,7 @@ public async Task ChallengeWillTriggerApplyRedirectEvent() context.Authentication.Challenge("Facebook"); return true; }); - var transaction = await SendAsync(server, "http://example.com/challenge"); + var transaction = await server.SendAsync("http://example.com/challenge"); transaction.Response.StatusCode.ShouldBe(HttpStatusCode.Redirect); var query = transaction.Response.Headers.Location.Query; query.ShouldContain("custom=test"); @@ -75,8 +71,7 @@ public async Task ChallengeWillTriggerRedirection() }, services => { - services.AddWebEncoders(); - services.AddDataProtection(); + services.AddAuthentication(); services.ConfigureFacebookAuthentication(options => { options.AppId = "Test App Id"; @@ -96,7 +91,7 @@ public async Task ChallengeWillTriggerRedirection() context.Authentication.Challenge("Facebook"); return true; }); - var transaction = await SendAsync(server, "http://example.com/challenge"); + var transaction = await server.SendAsync("http://example.com/challenge"); transaction.Response.StatusCode.ShouldBe(HttpStatusCode.Redirect); var location = transaction.Response.Headers.Location.AbsoluteUri; location.ShouldContain("https://www.facebook.com/v2.2/dialog/oauth"); @@ -125,34 +120,5 @@ private static TestServer CreateServer(Action configure, Ac }, configureServices); } - - private static async Task SendAsync(TestServer server, string uri, string cookieHeader = null) - { - var request = new HttpRequestMessage(HttpMethod.Get, uri); - if (!string.IsNullOrEmpty(cookieHeader)) - { - request.Headers.Add("Cookie", cookieHeader); - } - var transaction = new Transaction - { - Request = request, - Response = await server.CreateClient().SendAsync(request), - }; - if (transaction.Response.Headers.Contains("Set-Cookie")) - { - transaction.SetCookie = transaction.Response.Headers.GetValues("Set-Cookie").ToList(); - } - transaction.ResponseText = await transaction.Response.Content.ReadAsStringAsync(); - - return transaction; - } - - private class Transaction - { - public HttpRequestMessage Request { get; set; } - public HttpResponseMessage Response { get; set; } - public IList SetCookie { get; set; } - public string ResponseText { get; set; } - } } } diff --git a/test/Microsoft.AspNet.Authentication.Test/Google/GoogleMiddlewareTests.cs b/test/Microsoft.AspNet.Authentication.Test/Google/GoogleMiddlewareTests.cs index f44d4d3e7..7e1dc417b 100644 --- a/test/Microsoft.AspNet.Authentication.Test/Google/GoogleMiddlewareTests.cs +++ b/test/Microsoft.AspNet.Authentication.Test/Google/GoogleMiddlewareTests.cs @@ -2,16 +2,12 @@ using System; using System.Collections.Generic; -using System.Diagnostics; -using System.IO; using System.Linq; using System.Net; using System.Net.Http; using System.Security.Claims; using System.Text; using System.Threading.Tasks; -using System.Xml; -using System.Xml.Linq; using Microsoft.AspNet.Authentication.DataHandler; using Microsoft.AspNet.Builder; using Microsoft.AspNet.DataProtection; @@ -28,8 +24,6 @@ namespace Microsoft.AspNet.Authentication.Google { public class GoogleMiddlewareTests { - private const string CookieAuthenticationScheme = "Cookie"; - [Fact] public async Task ChallengeWillTriggerRedirection() { @@ -38,7 +32,7 @@ public async Task ChallengeWillTriggerRedirection() options.ClientId = "Test Id"; options.ClientSecret = "Test Secret"; }); - var transaction = await SendAsync(server, "https://example.com/challenge"); + var transaction = await server.SendAsync("https://example.com/challenge"); transaction.Response.StatusCode.ShouldBe(HttpStatusCode.Redirect); var location = transaction.Response.Headers.Location.ToString(); location.ShouldContain("https://accounts.google.com/o/oauth2/auth?response_type=code"); @@ -61,7 +55,7 @@ public async Task Challenge401WillTriggerRedirection() options.ClientSecret = "Test Secret"; options.AutomaticAuthentication = true; }); - var transaction = await SendAsync(server, "https://example.com/401"); + var transaction = await server.SendAsync("https://example.com/401"); transaction.Response.StatusCode.ShouldBe(HttpStatusCode.Redirect); var location = transaction.Response.Headers.Location.ToString(); location.ShouldContain("https://accounts.google.com/o/oauth2/auth?response_type=code"); @@ -79,7 +73,7 @@ public async Task ChallengeWillSetCorrelationCookie() options.ClientId = "Test Id"; options.ClientSecret = "Test Secret"; }); - var transaction = await SendAsync(server, "https://example.com/challenge"); + var transaction = await server.SendAsync("https://example.com/challenge"); Console.WriteLine(transaction.SetCookie); transaction.SetCookie.Single().ShouldContain(".AspNet.Correlation.Google="); } @@ -93,7 +87,7 @@ public async Task Challenge401WillSetCorrelationCookie() options.ClientSecret = "Test Secret"; options.AutomaticAuthentication = true; }); - var transaction = await SendAsync(server, "https://example.com/401"); + var transaction = await server.SendAsync("https://example.com/401"); Console.WriteLine(transaction.SetCookie); transaction.SetCookie.Single().ShouldContain(".AspNet.Correlation.Google="); } @@ -106,7 +100,7 @@ public async Task ChallengeWillSetDefaultScope() options.ClientId = "Test Id"; options.ClientSecret = "Test Secret"; }); - var transaction = await SendAsync(server, "https://example.com/challenge"); + var transaction = await server.SendAsync("https://example.com/challenge"); transaction.Response.StatusCode.ShouldBe(HttpStatusCode.Redirect); var query = transaction.Response.Headers.Location.Query; query.ShouldContain("&scope=" + UrlEncoder.Default.UrlEncode("openid profile email")); @@ -121,7 +115,7 @@ public async Task Challenge401WillSetDefaultScope() options.ClientSecret = "Test Secret"; options.AutomaticAuthentication = true; }); - var transaction = await SendAsync(server, "https://example.com/401"); + var transaction = await server.SendAsync("https://example.com/401"); transaction.Response.StatusCode.ShouldBe(HttpStatusCode.Redirect); var query = transaction.Response.Headers.Location.Query; query.ShouldContain("&scope=" + UrlEncoder.Default.UrlEncode("openid profile email")); @@ -155,7 +149,7 @@ public async Task ChallengeWillUseAuthenticationPropertiesAsParameters() return Task.FromResult(null); }); - var transaction = await SendAsync(server, "https://example.com/challenge2"); + var transaction = await server.SendAsync("https://example.com/challenge2"); transaction.Response.StatusCode.ShouldBe(HttpStatusCode.Redirect); var query = transaction.Response.Headers.Location.Query; query.ShouldContain("scope=" + UrlEncoder.Default.UrlEncode("https://www.googleapis.com/auth/plus.login")); @@ -179,7 +173,7 @@ public async Task ChallengeWillTriggerApplyRedirectEvent() } }; }); - var transaction = await SendAsync(server, "https://example.com/challenge"); + var transaction = await server.SendAsync("https://example.com/challenge"); transaction.Response.StatusCode.ShouldBe(HttpStatusCode.Redirect); var query = transaction.Response.Headers.Location.Query; query.ShouldContain("custom=test"); @@ -222,14 +216,16 @@ public async Task ReplyPathWithoutStateQueryStringWillBeRejected() options.ClientId = "Test Id"; options.ClientSecret = "Test Secret"; }); - var transaction = await SendAsync(server, "https://example.com/signin-google?code=TestCode"); + var transaction = await server.SendAsync("https://example.com/signin-google?code=TestCode"); transaction.Response.StatusCode.ShouldBe(HttpStatusCode.InternalServerError); } - [Fact] - public async Task ReplyPathWillAuthenticateValidAuthorizeCodeAndState() + [Theory] + [InlineData(null)] + [InlineData("CustomIssuer")] + public async Task ReplyPathWillAuthenticateValidAuthorizeCodeAndState(string claimsIssuer) { var stateFormat = new PropertiesDataFormat(new EphemeralDataProtectionProvider().CreateProtector("GoogleTest")); var server = CreateServer(options => @@ -237,6 +233,7 @@ public async Task ReplyPathWillAuthenticateValidAuthorizeCodeAndState() options.ClientId = "Test Id"; options.ClientSecret = "Test Secret"; options.StateDataFormat = stateFormat; + options.ClaimsIssuer = claimsIssuer; options.BackchannelHttpHandler = new TestHttpMessageHandler { Sender = req => @@ -283,23 +280,24 @@ public async Task ReplyPathWillAuthenticateValidAuthorizeCodeAndState() properties.Items.Add(correlationKey, correlationValue); properties.RedirectUri = "/me"; var state = stateFormat.Protect(properties); - var transaction = await SendAsync(server, + var transaction = await server.SendAsync( "https://example.com/signin-google?code=TestCode&state=" + UrlEncoder.Default.UrlEncode(state), correlationKey + "=" + correlationValue); transaction.Response.StatusCode.ShouldBe(HttpStatusCode.Redirect); transaction.Response.Headers.Location.ToString().ShouldBe("/me"); transaction.SetCookie.Count.ShouldBe(2); transaction.SetCookie[0].ShouldContain(correlationKey); - transaction.SetCookie[1].ShouldContain(".AspNet.Cookie"); + transaction.SetCookie[1].ShouldContain(".AspNet." + TestExtensions.CookieAuthenticationScheme); var authCookie = transaction.AuthenticationCookieValue; - transaction = await SendAsync(server, "https://example.com/me", authCookie); + transaction = await server.SendAsync("https://example.com/me", authCookie); transaction.Response.StatusCode.ShouldBe(HttpStatusCode.OK); - transaction.FindClaimValue(ClaimTypes.Name).ShouldBe("Test Name"); - transaction.FindClaimValue(ClaimTypes.NameIdentifier).ShouldBe("Test User ID"); - transaction.FindClaimValue(ClaimTypes.GivenName).ShouldBe("Test Given Name"); - transaction.FindClaimValue(ClaimTypes.Surname).ShouldBe("Test Family Name"); - transaction.FindClaimValue(ClaimTypes.Email).ShouldBe("Test email"); + var expectedIssuer = claimsIssuer ?? GoogleAuthenticationDefaults.AuthenticationScheme; + transaction.FindClaimValue(ClaimTypes.Name, expectedIssuer).ShouldBe("Test Name"); + transaction.FindClaimValue(ClaimTypes.NameIdentifier, expectedIssuer).ShouldBe("Test User ID"); + transaction.FindClaimValue(ClaimTypes.GivenName, expectedIssuer).ShouldBe("Test Given Name"); + transaction.FindClaimValue(ClaimTypes.Surname, expectedIssuer).ShouldBe("Test Family Name"); + transaction.FindClaimValue(ClaimTypes.Email, expectedIssuer).ShouldBe("Test email"); // Ensure claims transformation transaction.FindClaimValue("xform").ShouldBe("yup"); @@ -328,7 +326,7 @@ public async Task ReplyPathWillRejectIfCodeIsInvalid() properties.Items.Add(correlationKey, correlationValue); properties.RedirectUri = "/me"; var state = stateFormat.Protect(properties); - var transaction = await SendAsync(server, + var transaction = await server.SendAsync( "https://example.com/signin-google?code=TestCode&state=" + UrlEncoder.Default.UrlEncode(state), correlationKey + "=" + correlationValue); transaction.Response.StatusCode.ShouldBe(HttpStatusCode.Redirect); @@ -358,7 +356,7 @@ public async Task ReplyPathWillRejectIfAccessTokenIsMissing() properties.Items.Add(correlationKey, correlationValue); properties.RedirectUri = "/me"; var state = stateFormat.Protect(properties); - var transaction = await SendAsync(server, + var transaction = await server.SendAsync( "https://example.com/signin-google?code=TestCode&state=" + UrlEncoder.Default.UrlEncode(state), correlationKey + "=" + correlationValue); transaction.Response.StatusCode.ShouldBe(HttpStatusCode.Redirect); @@ -419,7 +417,7 @@ public async Task AuthenticatedEventCanGetRefreshToken() OnAuthenticated = context => { var refreshToken = context.RefreshToken; - context.Principal.AddIdentity(new ClaimsIdentity(new Claim[] { new Claim("RefreshToken", refreshToken) }, "Google")); + context.Principal.AddIdentity(new ClaimsIdentity(new Claim[] { new Claim("RefreshToken", refreshToken, ClaimValueTypes.String, "Google") }, "Google")); return Task.FromResult(null); } }; @@ -430,17 +428,17 @@ public async Task AuthenticatedEventCanGetRefreshToken() properties.Items.Add(correlationKey, correlationValue); properties.RedirectUri = "/me"; var state = stateFormat.Protect(properties); - var transaction = await SendAsync(server, + var transaction = await server.SendAsync( "https://example.com/signin-google?code=TestCode&state=" + UrlEncoder.Default.UrlEncode(state), correlationKey + "=" + correlationValue); transaction.Response.StatusCode.ShouldBe(HttpStatusCode.Redirect); transaction.Response.Headers.Location.ToString().ShouldBe("/me"); transaction.SetCookie.Count.ShouldBe(2); transaction.SetCookie[0].ShouldContain(correlationKey); - transaction.SetCookie[1].ShouldContain(".AspNet.Cookie"); + transaction.SetCookie[1].ShouldContain(".AspNet." + TestExtensions.CookieAuthenticationScheme); var authCookie = transaction.AuthenticationCookieValue; - transaction = await SendAsync(server, "https://example.com/me", authCookie); + transaction = await server.SendAsync("https://example.com/me", authCookie); transaction.Response.StatusCode.ShouldBe(HttpStatusCode.OK); transaction.FindClaimValue("RefreshToken").ShouldBe("Test Refresh Token"); } @@ -453,40 +451,13 @@ private static HttpResponseMessage ReturnJsonResponse(object content) return res; } - private static async Task SendAsync(TestServer server, string uri, string cookieHeader = null) - { - var request = new HttpRequestMessage(HttpMethod.Get, uri); - if (!string.IsNullOrEmpty(cookieHeader)) - { - request.Headers.Add("Cookie", cookieHeader); - } - var transaction = new Transaction - { - Request = request, - Response = await server.CreateClient().SendAsync(request), - }; - if (transaction.Response.Headers.Contains("Set-Cookie")) - { - transaction.SetCookie = transaction.Response.Headers.GetValues("Set-Cookie").ToList(); - } - transaction.ResponseText = await transaction.Response.Content.ReadAsStringAsync(); - - if (transaction.Response.Content != null && - transaction.Response.Content.Headers.ContentType != null && - transaction.Response.Content.Headers.ContentType.MediaType == "text/xml") - { - transaction.ResponseElement = XElement.Parse(transaction.ResponseText); - } - return transaction; - } - private static TestServer CreateServer(Action configureOptions, Func testpath = null) { return TestServer.Create(app => { app.UseCookieAuthentication(options => { - options.AuthenticationScheme = CookieAuthenticationScheme; + options.AuthenticationScheme = TestExtensions.CookieAuthenticationScheme; options.AutomaticAuthentication = true; }); app.UseGoogleAuthentication(configureOptions); @@ -502,7 +473,7 @@ private static TestServer CreateServer(Action confi } else if (req.Path == new PathString("/me")) { - Describe(res, context.User); + res.Describe(context.User); } else if (req.Path == new PathString("/unauthorized")) { @@ -535,7 +506,7 @@ private static TestServer CreateServer(Action confi services.AddAuthentication(); services.Configure(options => { - options.SignInScheme = CookieAuthenticationScheme; + options.SignInScheme = TestExtensions.CookieAuthenticationScheme; }); services.ConfigureClaimsTransformation(p => { @@ -547,79 +518,5 @@ private static TestServer CreateServer(Action confi }); } - private static void Describe(HttpResponse res, ClaimsPrincipal user) - { - res.StatusCode = 200; - res.ContentType = "text/xml"; - var xml = new XElement("xml"); - if (user != null) - { - foreach (var identity in user.Identities) - { - xml.Add(identity.Claims.Select(claim => new XElement("claim", new XAttribute("type", claim.Type), new XAttribute("value", claim.Value)))); - } - } - using (var memory = new MemoryStream()) - { - using (var writer = new XmlTextWriter(memory, Encoding.UTF8)) - { - xml.WriteTo(writer); - } - res.Body.Write(memory.ToArray(), 0, memory.ToArray().Length); - } - } - - private class TestHttpMessageHandler : HttpMessageHandler - { - public Func Sender { get; set; } - - protected override Task SendAsync(HttpRequestMessage request, System.Threading.CancellationToken cancellationToken) - { - if (Sender != null) - { - return Task.FromResult(Sender(request)); - } - - return Task.FromResult(null); - } - } - - private class Transaction - { - public HttpRequestMessage Request { get; set; } - public HttpResponseMessage Response { get; set; } - - public IList SetCookie { get; set; } - - public string ResponseText { get; set; } - public XElement ResponseElement { get; set; } - - public string AuthenticationCookieValue - { - get - { - if (SetCookie != null && SetCookie.Count > 0) - { - var authCookie = SetCookie.SingleOrDefault(c => c.Contains(".AspNet.Cookie=")); - if (authCookie != null) - { - return authCookie.Substring(0, authCookie.IndexOf(';')); - } - } - - return null; - } - } - - public string FindClaimValue(string claimType) - { - var claim = ResponseElement.Elements("claim").SingleOrDefault(elt => elt.Attribute("type").Value == claimType); - if (claim == null) - { - return null; - } - return claim.Attribute("value").Value; - } - } } } diff --git a/test/Microsoft.AspNet.Authentication.Test/MicrosoftAccount/MicrosoftAccountMiddlewareTests.cs b/test/Microsoft.AspNet.Authentication.Test/MicrosoftAccount/MicrosoftAccountMiddlewareTests.cs index 1382fc640..2d6baba35 100644 --- a/test/Microsoft.AspNet.Authentication.Test/MicrosoftAccount/MicrosoftAccountMiddlewareTests.cs +++ b/test/Microsoft.AspNet.Authentication.Test/MicrosoftAccount/MicrosoftAccountMiddlewareTests.cs @@ -1,16 +1,11 @@ // Copyright (c) .NET Foundation. All rights reserved. See License.txt in the project root for license information. using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; using System.Net; using System.Net.Http; using System.Security.Claims; using System.Text; using System.Threading.Tasks; -using System.Xml; -using System.Xml.Linq; using Microsoft.AspNet.Authentication.DataHandler; using Microsoft.AspNet.Authentication.MicrosoftAccount; using Microsoft.AspNet.Builder; @@ -43,13 +38,8 @@ public async Task ChallengeWillTriggerApplyRedirectEvent() context.Response.Redirect(context.RedirectUri + "&custom=test"); } }; - }, - context => - { - context.Authentication.Challenge("Microsoft"); - return true; }); - var transaction = await SendAsync(server, "http://example.com/challenge"); + var transaction = await server.SendAsync("http://example.com/challenge"); transaction.Response.StatusCode.ShouldBe(HttpStatusCode.Redirect); var query = transaction.Response.Headers.Location.Query; query.ShouldContain("custom=test"); @@ -63,13 +53,8 @@ public async Task ChallengeWillTriggerRedirection() { options.ClientId = "Test Client Id"; options.ClientSecret = "Test Client Secret"; - }, - context => - { - context.Authentication.Challenge("Microsoft"); - return true; }); - var transaction = await SendAsync(server, "http://example.com/challenge"); + var transaction = await server.SendAsync("http://example.com/challenge"); transaction.Response.StatusCode.ShouldBe(HttpStatusCode.Redirect); var location = transaction.Response.Headers.Location.AbsoluteUri; location.ShouldContain("https://login.live.com/oauth20_authorize.srf"); @@ -83,7 +68,7 @@ public async Task ChallengeWillTriggerRedirection() [Fact] public async Task AuthenticatedEventCanGetRefreshToken() { - ISecureDataFormat stateFormat = new PropertiesDataFormat(new EphemeralDataProtectionProvider().CreateProtector("MsftTest")); + var stateFormat = new PropertiesDataFormat(new EphemeralDataProtectionProvider().CreateProtector("MsftTest")); var server = CreateServer( options => { @@ -127,15 +112,10 @@ public async Task AuthenticatedEventCanGetRefreshToken() OnAuthenticated = context => { var refreshToken = context.RefreshToken; - context.Principal.AddIdentity(new ClaimsIdentity(new Claim[] { new Claim("RefreshToken", refreshToken) })); + context.Principal.AddIdentity(new ClaimsIdentity(new Claim[] { new Claim("RefreshToken", refreshToken, ClaimValueTypes.String, "Microsoft") }, "Microsoft")); return Task.FromResult(null); } }; - }, - context => - { - Describe(context.Response, context.User); - return true; }); var properties = new AuthenticationProperties(); var correlationKey = ".AspNet.Correlation.Microsoft"; @@ -143,34 +123,46 @@ public async Task AuthenticatedEventCanGetRefreshToken() properties.Items.Add(correlationKey, correlationValue); properties.RedirectUri = "/me"; var state = stateFormat.Protect(properties); - var transaction = await SendAsync(server, + var transaction = await server.SendAsync( "https://example.com/signin-microsoft?code=TestCode&state=" + UrlEncoder.Default.UrlEncode(state), correlationKey + "=" + correlationValue); transaction.Response.StatusCode.ShouldBe(HttpStatusCode.Redirect); transaction.Response.Headers.Location.ToString().ShouldBe("/me"); transaction.SetCookie.Count.ShouldBe(2); transaction.SetCookie[0].ShouldContain(correlationKey); - transaction.SetCookie[1].ShouldContain(".AspNet.External"); + transaction.SetCookie[1].ShouldContain(".AspNet." + TestExtensions.CookieAuthenticationScheme); var authCookie = transaction.AuthenticationCookieValue; - transaction = await SendAsync(server, "https://example.com/me", authCookie); + transaction = await server.SendAsync("https://example.com/me", authCookie); transaction.Response.StatusCode.ShouldBe(HttpStatusCode.OK); transaction.FindClaimValue("RefreshToken").ShouldBe("Test Refresh Token"); } - private static TestServer CreateServer(Action configureOptions, Func handler) + private static TestServer CreateServer(Action configureOptions) { return TestServer.Create(app => { app.UseCookieAuthentication(options => { - options.AuthenticationScheme = "External"; + options.AuthenticationScheme = TestExtensions.CookieAuthenticationScheme; options.AutomaticAuthentication = true; }); app.UseMicrosoftAccountAuthentication(configureOptions); + app.Use(async (context, next) => { - if (handler == null || !handler(context)) + var req = context.Request; + var res = context.Response; + if (req.Path == new PathString("/challenge")) + { + context.Authentication.Challenge("Microsoft"); + res.StatusCode = 401; + } + else if (req.Path == new PathString("/me")) + { + res.Describe(context.User); + } + else { await next(); } @@ -181,38 +173,11 @@ private static TestServer CreateServer(Action(options => { - options.SignInScheme = "External"; + options.SignInScheme = TestExtensions.CookieAuthenticationScheme; }); }); } - private static async Task SendAsync(TestServer server, string uri, string cookieHeader = null) - { - var request = new HttpRequestMessage(HttpMethod.Get, uri); - if (!string.IsNullOrEmpty(cookieHeader)) - { - request.Headers.Add("Cookie", cookieHeader); - } - var transaction = new Transaction - { - Request = request, - Response = await server.CreateClient().SendAsync(request), - }; - if (transaction.Response.Headers.Contains("Set-Cookie")) - { - transaction.SetCookie = transaction.Response.Headers.GetValues("Set-Cookie").ToList(); - } - transaction.ResponseText = await transaction.Response.Content.ReadAsStringAsync(); - - if (transaction.Response.Content != null && - transaction.Response.Content.Headers.ContentType != null && - transaction.Response.Content.Headers.ContentType.MediaType == "text/xml") - { - transaction.ResponseElement = XElement.Parse(transaction.ResponseText); - } - return transaction; - } - private static HttpResponseMessage ReturnJsonResponse(object content) { var res = new HttpResponseMessage(HttpStatusCode.OK); @@ -220,78 +185,5 @@ private static HttpResponseMessage ReturnJsonResponse(object content) res.Content = new StringContent(text, Encoding.UTF8, "application/json"); return res; } - - private static void Describe(HttpResponse res, ClaimsPrincipal principal) - { - res.StatusCode = 200; - res.ContentType = "text/xml"; - var xml = new XElement("xml"); - if (principal != null) - { - foreach (var identity in principal.Identities) - { - xml.Add(identity.Claims.Select(claim => new XElement("claim", new XAttribute("type", claim.Type), new XAttribute("value", claim.Value)))); - } - } - using (var memory = new MemoryStream()) - { - using (var writer = new XmlTextWriter(memory, Encoding.UTF8)) - { - xml.WriteTo(writer); - } - res.Body.Write(memory.ToArray(), 0, memory.ToArray().Length); - } - } - - private class TestHttpMessageHandler : HttpMessageHandler - { - public Func Sender { get; set; } - - protected override Task SendAsync(HttpRequestMessage request, System.Threading.CancellationToken cancellationToken) - { - if (Sender != null) - { - return Task.FromResult(Sender(request)); - } - - return Task.FromResult(null); - } - } - - private class Transaction - { - public HttpRequestMessage Request { get; set; } - public HttpResponseMessage Response { get; set; } - public IList SetCookie { get; set; } - public string ResponseText { get; set; } - public XElement ResponseElement { get; set; } - - public string AuthenticationCookieValue - { - get - { - if (SetCookie != null && SetCookie.Count > 0) - { - var authCookie = SetCookie.SingleOrDefault(c => c.Contains(".AspNet.External=")); - if (authCookie != null) - { - return authCookie.Substring(0, authCookie.IndexOf(';')); - } - } - - return null; - } - } - - public string FindClaimValue(string claimType) - { - XElement claim = ResponseElement.Elements("claim").SingleOrDefault(elt => elt.Attribute("type").Value == claimType); - if (claim == null) - { - return null; - } - return claim.Attribute("value").Value; - } - } } } diff --git a/test/Microsoft.AspNet.Authentication.Test/OAuthBearer/OAuthBearerMiddlewareTests.cs b/test/Microsoft.AspNet.Authentication.Test/OAuthBearer/OAuthBearerMiddlewareTests.cs index 7ae0db82b..f21b00f79 100644 --- a/test/Microsoft.AspNet.Authentication.Test/OAuthBearer/OAuthBearerMiddlewareTests.cs +++ b/test/Microsoft.AspNet.Authentication.Test/OAuthBearer/OAuthBearerMiddlewareTests.cs @@ -2,7 +2,6 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; -using System.Collections.Generic; using System.IdentityModel.Tokens; using System.Net; using System.Net.Http; @@ -36,7 +35,7 @@ public async Task BearerTokenValidation() }; }); - string newBearerToken = "Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6ImtyaU1QZG1Cdng2OHNrVDgtbVBBQjNCc2VlQSJ9.eyJhdWQiOiJodHRwczovL1R1c2hhclRlc3Qub25taWNyb3NvZnQuY29tL1RvZG9MaXN0U2VydmljZS1NYW51YWxKd3QiLCJpc3MiOiJodHRwczovL3N0cy53aW5kb3dzLm5ldC9hZmJlY2UwMy1hZWFhLTRmM2YtODVlNy1jZTA4ZGQyMGNlNTAvIiwiaWF0IjoxNDE4MzMwNjE0LCJuYmYiOjE0MTgzMzA2MTQsImV4cCI6MTQxODMzNDUxNCwidmVyIjoiMS4wIiwidGlkIjoiYWZiZWNlMDMtYWVhYS00ZjNmLTg1ZTctY2UwOGRkMjBjZTUwIiwiYW1yIjpbInB3ZCJdLCJvaWQiOiI1Mzk3OTdjMi00MDE5LTQ2NTktOWRiNS03MmM0Yzc3NzhhMzMiLCJ1cG4iOiJWaWN0b3JAVHVzaGFyVGVzdC5vbm1pY3Jvc29mdC5jb20iLCJ1bmlxdWVfbmFtZSI6IlZpY3RvckBUdXNoYXJUZXN0Lm9ubWljcm9zb2Z0LmNvbSIsInN1YiI6IkQyMm9aMW9VTzEzTUFiQXZrdnFyd2REVE80WXZJdjlzMV9GNWlVOVUwYnciLCJmYW1pbHlfbmFtZSI6Ikd1cHRhIiwiZ2l2ZW5fbmFtZSI6IlZpY3RvciIsImFwcGlkIjoiNjEzYjVhZjgtZjJjMy00MWI2LWExZGMtNDE2Yzk3ODAzMGI3IiwiYXBwaWRhY3IiOiIwIiwic2NwIjoidXNlcl9pbXBlcnNvbmF0aW9uIiwiYWNyIjoiMSJ9.N_Kw1EhoVGrHbE6hOcm7ERdZ7paBQiNdObvp2c6T6n5CE8p0fZqmUd-ya_EqwElcD6SiKSiP7gj0gpNUnOJcBl_H2X8GseaeeMxBrZdsnDL8qecc6_ygHruwlPltnLTdka67s1Ow4fDSHaqhVTEk6lzGmNEcbNAyb0CxQxU6o7Fh0yHRiWoLsT8yqYk8nKzsHXfZBNby4aRo3_hXaa4i0SZLYfDGGYPdttG4vT_u54QGGd4Wzbonv2gjDlllOVGOwoJS6kfl1h8mk0qxdiIaT_ChbDWgkWvTB7bTvBE-EgHgV0XmAo0WtJeSxgjsG3KhhEPsONmqrSjhIUV4IVnF2w"; + var newBearerToken = "Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6ImtyaU1QZG1Cdng2OHNrVDgtbVBBQjNCc2VlQSJ9.eyJhdWQiOiJodHRwczovL1R1c2hhclRlc3Qub25taWNyb3NvZnQuY29tL1RvZG9MaXN0U2VydmljZS1NYW51YWxKd3QiLCJpc3MiOiJodHRwczovL3N0cy53aW5kb3dzLm5ldC9hZmJlY2UwMy1hZWFhLTRmM2YtODVlNy1jZTA4ZGQyMGNlNTAvIiwiaWF0IjoxNDE4MzMwNjE0LCJuYmYiOjE0MTgzMzA2MTQsImV4cCI6MTQxODMzNDUxNCwidmVyIjoiMS4wIiwidGlkIjoiYWZiZWNlMDMtYWVhYS00ZjNmLTg1ZTctY2UwOGRkMjBjZTUwIiwiYW1yIjpbInB3ZCJdLCJvaWQiOiI1Mzk3OTdjMi00MDE5LTQ2NTktOWRiNS03MmM0Yzc3NzhhMzMiLCJ1cG4iOiJWaWN0b3JAVHVzaGFyVGVzdC5vbm1pY3Jvc29mdC5jb20iLCJ1bmlxdWVfbmFtZSI6IlZpY3RvckBUdXNoYXJUZXN0Lm9ubWljcm9zb2Z0LmNvbSIsInN1YiI6IkQyMm9aMW9VTzEzTUFiQXZrdnFyd2REVE80WXZJdjlzMV9GNWlVOVUwYnciLCJmYW1pbHlfbmFtZSI6Ikd1cHRhIiwiZ2l2ZW5fbmFtZSI6IlZpY3RvciIsImFwcGlkIjoiNjEzYjVhZjgtZjJjMy00MWI2LWExZGMtNDE2Yzk3ODAzMGI3IiwiYXBwaWRhY3IiOiIwIiwic2NwIjoidXNlcl9pbXBlcnNvbmF0aW9uIiwiYWNyIjoiMSJ9.N_Kw1EhoVGrHbE6hOcm7ERdZ7paBQiNdObvp2c6T6n5CE8p0fZqmUd-ya_EqwElcD6SiKSiP7gj0gpNUnOJcBl_H2X8GseaeeMxBrZdsnDL8qecc6_ygHruwlPltnLTdka67s1Ow4fDSHaqhVTEk6lzGmNEcbNAyb0CxQxU6o7Fh0yHRiWoLsT8yqYk8nKzsHXfZBNby4aRo3_hXaa4i0SZLYfDGGYPdttG4vT_u54QGGd4Wzbonv2gjDlllOVGOwoJS6kfl1h8mk0qxdiIaT_ChbDWgkWvTB7bTvBE-EgHgV0XmAo0WtJeSxgjsG3KhhEPsONmqrSjhIUV4IVnF2w"; var response = await SendAsync(server, "http://example.com/oauth", newBearerToken); response.Response.StatusCode.ShouldBe(HttpStatusCode.OK); } @@ -339,6 +338,7 @@ private static TestServer CreateServer(Action services => services.AddAuthentication()); } + // TODO: see if we can share the TestExtensions SendAsync method (only diff is auth header) private static async Task SendAsync(TestServer server, string uri, string authorizationHeader = null) { var request = new HttpRequestMessage(HttpMethod.Get, uri); @@ -364,14 +364,5 @@ private static async Task SendAsync(TestServer server, string uri, return transaction; } - - private class Transaction - { - public HttpRequestMessage Request { get; set; } - public HttpResponseMessage Response { get; set; } - public IList SetCookie { get; set; } - public string ResponseText { get; set; } - public XElement ResponseElement { get; set; } - } } } diff --git a/test/Microsoft.AspNet.Authentication.Test/OpenIdConnect/TestUtilities.cs b/test/Microsoft.AspNet.Authentication.Test/OpenIdConnect/TestUtilities.cs index 3f18ee6b9..1e6bea793 100644 --- a/test/Microsoft.AspNet.Authentication.Test/OpenIdConnect/TestUtilities.cs +++ b/test/Microsoft.AspNet.Authentication.Test/OpenIdConnect/TestUtilities.cs @@ -1,7 +1,6 @@ // Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -using Microsoft.IdentityModel.Protocols; using System; namespace Microsoft.AspNet.Authentication.Tests.OpenIdConnect diff --git a/test/Microsoft.AspNet.Authentication.Test/SecurityHelperTests.cs b/test/Microsoft.AspNet.Authentication.Test/SecurityHelperTests.cs index 01315805d..aa9e91e55 100644 --- a/test/Microsoft.AspNet.Authentication.Test/SecurityHelperTests.cs +++ b/test/Microsoft.AspNet.Authentication.Test/SecurityHelperTests.cs @@ -1,12 +1,10 @@ // Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -using System.Collections.Generic; using System.Linq; using System.Security.Claims; using System.Security.Principal; using Microsoft.AspNet.Http; -using Microsoft.AspNet.Authentication; using Shouldly; using Xunit; @@ -17,7 +15,7 @@ public class SecurityHelperTests [Fact] public void AddingToAnonymousIdentityDoesNotKeepAnonymousIdentity() { - HttpContext context = new DefaultHttpContext(); + var context = new DefaultHttpContext(); context.User.ShouldNotBe(null); context.User.Identity.IsAuthenticated.ShouldBe(false); @@ -36,7 +34,7 @@ public void AddingToAnonymousIdentityDoesNotKeepAnonymousIdentity() [Fact] public void AddingExistingIdentityChangesDefaultButPreservesPrior() { - HttpContext context = new DefaultHttpContext(); + var context = new DefaultHttpContext(); context.User = new GenericPrincipal(new GenericIdentity("Test1", "Alpha"), null); context.User.Identity.AuthenticationType.ShouldBe("Alpha"); diff --git a/test/Microsoft.AspNet.Authentication.Test/TestExtensions.cs b/test/Microsoft.AspNet.Authentication.Test/TestExtensions.cs new file mode 100644 index 000000000..b406f5813 --- /dev/null +++ b/test/Microsoft.AspNet.Authentication.Test/TestExtensions.cs @@ -0,0 +1,73 @@ +// 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.IO; +using System.Linq; +using System.Net.Http; +using System.Security.Claims; +using System.Text; +using System.Threading.Tasks; +using System.Xml; +using System.Xml.Linq; +using Microsoft.AspNet.Http; +using Microsoft.AspNet.TestHost; + +namespace Microsoft.AspNet.Authentication +{ + public static class TestExtensions + { + public const string CookieAuthenticationScheme = "External"; + + public static async Task SendAsync(this TestServer server, string uri, string cookieHeader = null) + { + var request = new HttpRequestMessage(HttpMethod.Get, uri); + if (!string.IsNullOrEmpty(cookieHeader)) + { + request.Headers.Add("Cookie", cookieHeader); + } + var transaction = new Transaction + { + Request = request, + Response = await server.CreateClient().SendAsync(request), + }; + if (transaction.Response.Headers.Contains("Set-Cookie")) + { + transaction.SetCookie = transaction.Response.Headers.GetValues("Set-Cookie").ToList(); + } + transaction.ResponseText = await transaction.Response.Content.ReadAsStringAsync(); + + if (transaction.Response.Content != null && + transaction.Response.Content.Headers.ContentType != null && + transaction.Response.Content.Headers.ContentType.MediaType == "text/xml") + { + transaction.ResponseElement = XElement.Parse(transaction.ResponseText); + } + return transaction; + } + + public static void Describe(this HttpResponse res, ClaimsPrincipal principal) + { + res.StatusCode = 200; + res.ContentType = "text/xml"; + var xml = new XElement("xml"); + if (principal != null) + { + foreach (var identity in principal.Identities) + { + xml.Add(identity.Claims.Select(claim => + new XElement("claim", new XAttribute("type", claim.Type), + new XAttribute("value", claim.Value), + new XAttribute("issuer", claim.Issuer)))); + } + } + using (var memory = new MemoryStream()) + { + using (var writer = new XmlTextWriter(memory, Encoding.UTF8)) + { + xml.WriteTo(writer); + } + res.Body.Write(memory.ToArray(), 0, memory.ToArray().Length); + } + } + } +} diff --git a/test/Microsoft.AspNet.Authentication.Test/TestHttpMessageHandler.cs b/test/Microsoft.AspNet.Authentication.Test/TestHttpMessageHandler.cs new file mode 100644 index 000000000..1a93b16df --- /dev/null +++ b/test/Microsoft.AspNet.Authentication.Test/TestHttpMessageHandler.cs @@ -0,0 +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.Threading.Tasks; + +namespace Microsoft.AspNet.Authentication +{ + public class TestHttpMessageHandler : HttpMessageHandler + { + public Func Sender { get; set; } + + protected override Task SendAsync(HttpRequestMessage request, System.Threading.CancellationToken cancellationToken) + { + if (Sender != null) + { + return Task.FromResult(Sender(request)); + } + + return Task.FromResult(null); + } + } +} diff --git a/test/Microsoft.AspNet.Authentication.Test/Transaction.cs b/test/Microsoft.AspNet.Authentication.Test/Transaction.cs new file mode 100644 index 000000000..e32c3b926 --- /dev/null +++ b/test/Microsoft.AspNet.Authentication.Test/Transaction.cs @@ -0,0 +1,50 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System.Collections.Generic; +using System.Linq; +using System.Net.Http; +using System.Xml.Linq; + +namespace Microsoft.AspNet.Authentication +{ + public class Transaction + { + public HttpRequestMessage Request { get; set; } + public HttpResponseMessage Response { get; set; } + + public IList SetCookie { get; set; } + + public string ResponseText { get; set; } + public XElement ResponseElement { get; set; } + + public string AuthenticationCookieValue + { + get + { + if (SetCookie != null && SetCookie.Count > 0) + { + var authCookie = SetCookie.SingleOrDefault(c => c.Contains(".AspNet." + TestExtensions.CookieAuthenticationScheme + "=")); + if (authCookie != null) + { + return authCookie.Substring(0, authCookie.IndexOf(';')); + } + } + + return null; + } + } + + public string FindClaimValue(string claimType, string issuer = null) + { + var claim = ResponseElement.Elements("claim") + .SingleOrDefault(elt => elt.Attribute("type").Value == claimType && + (issuer == null || elt.Attribute("issuer").Value == issuer)); + if (claim == null) + { + return null; + } + return claim.Attribute("value").Value; + } + } +} diff --git a/test/Microsoft.AspNet.Authentication.Test/Twitter/TwitterMiddlewareTests.cs b/test/Microsoft.AspNet.Authentication.Test/Twitter/TwitterMiddlewareTests.cs index 0ad84b7f1..abbe3d37f 100644 --- a/test/Microsoft.AspNet.Authentication.Test/Twitter/TwitterMiddlewareTests.cs +++ b/test/Microsoft.AspNet.Authentication.Test/Twitter/TwitterMiddlewareTests.cs @@ -1,8 +1,6 @@ // Copyright (c) .NET Foundation. All rights reserved. See License.txt in the project root for license information. using System; -using System.Collections.Generic; -using System.Linq; using System.Net; using System.Net.Http; using System.Text; @@ -57,7 +55,7 @@ public async Task ChallengeWillTriggerApplyRedirectEvent() context.Authentication.Challenge("Twitter"); return true; }); - var transaction = await SendAsync(server, "http://example.com/challenge"); + var transaction = await server.SendAsync("http://example.com/challenge"); transaction.Response.StatusCode.ShouldBe(HttpStatusCode.Redirect); var query = transaction.Response.Headers.Location.Query; query.ShouldContain("custom=test"); @@ -95,7 +93,7 @@ public async Task ChallengeWillTriggerRedirection() context.Authentication.Challenge("Twitter"); return true; }); - var transaction = await SendAsync(server, "http://example.com/challenge"); + var transaction = await server.SendAsync("http://example.com/challenge"); transaction.Response.StatusCode.ShouldBe(HttpStatusCode.Redirect); var location = transaction.Response.Headers.Location.AbsoluteUri; location.ShouldContain("https://twitter.com/oauth/authenticate?oauth_token="); @@ -130,49 +128,5 @@ private static TestServer CreateServer(Action configure, Fu }); }); } - - private static async Task SendAsync(TestServer server, string uri, string cookieHeader = null) - { - var request = new HttpRequestMessage(HttpMethod.Get, uri); - if (!string.IsNullOrEmpty(cookieHeader)) - { - request.Headers.Add("Cookie", cookieHeader); - } - var transaction = new Transaction - { - Request = request, - Response = await server.CreateClient().SendAsync(request), - }; - if (transaction.Response.Headers.Contains("Set-Cookie")) - { - transaction.SetCookie = transaction.Response.Headers.GetValues("Set-Cookie").ToList(); - } - transaction.ResponseText = await transaction.Response.Content.ReadAsStringAsync(); - - return transaction; - } - - private class TestHttpMessageHandler : HttpMessageHandler - { - public Func Sender { get; set; } - - protected override Task SendAsync(HttpRequestMessage request, System.Threading.CancellationToken cancellationToken) - { - if (Sender != null) - { - return Task.FromResult(Sender(request)); - } - - return Task.FromResult(null); - } - } - - private class Transaction - { - public HttpRequestMessage Request { get; set; } - public HttpResponseMessage Response { get; set; } - public IList SetCookie { get; set; } - public string ResponseText { get; set; } - } } } From 434d158c7620fd75492ea5d03b6885246745b26c Mon Sep 17 00:00:00 2001 From: Hao Kung Date: Wed, 6 May 2015 14:24:20 -0700 Subject: [PATCH 203/216] Support custom name and role claims --- .../AuthorizationPolicy.cs | 4 +- .../AuthorizationPolicyBuilder.cs | 16 ++---- .../AuthorizationServiceExtensions.cs | 12 ---- .../ClaimsAuthorizationRequirement.cs | 36 +++++++++++- .../DenyAnonymousAuthorizationRequirement.cs | 17 +++++- .../NameAuthorizationRequirement.cs | 35 ++++++++++++ .../Properties/Resources.Designer.cs | 56 ++++--------------- .../Resources.resx | 12 +--- .../RolesAuthorizationRequirement.cs | 47 ++++++++++++++++ .../ServiceCollectionExtensions.cs | 2 - .../AuthorizationPolicyFacts.cs | 10 +++- .../DefaultAuthorizationServiceTests.cs | 45 +++++++++++++++ 12 files changed, 205 insertions(+), 87 deletions(-) create mode 100644 src/Microsoft.AspNet.Authorization/NameAuthorizationRequirement.cs create mode 100644 src/Microsoft.AspNet.Authorization/RolesAuthorizationRequirement.cs diff --git a/src/Microsoft.AspNet.Authorization/AuthorizationPolicy.cs b/src/Microsoft.AspNet.Authorization/AuthorizationPolicy.cs index 3cc52abe5..ef16f968c 100644 --- a/src/Microsoft.AspNet.Authorization/AuthorizationPolicy.cs +++ b/src/Microsoft.AspNet.Authorization/AuthorizationPolicy.cs @@ -38,7 +38,7 @@ public static AuthorizationPolicy Combine([NotNull] IEnumerable attributes) { var policyBuilder = new AuthorizationPolicyBuilder(); - bool any = false; + var any = false; foreach (var authorizeAttribute in attributes.OfType()) { any = true; @@ -59,7 +59,7 @@ public static AuthorizationPolicy Combine([NotNull] AuthorizationOptions options policyBuilder.RequireRole(rolesSplit); requireAnyAuthenticated = false; } - string[] authTypesSplit = authorizeAttribute.ActiveAuthenticationSchemes?.Split(','); + var authTypesSplit = authorizeAttribute.ActiveAuthenticationSchemes?.Split(','); if (authTypesSplit != null && authTypesSplit.Any()) { foreach (var authType in authTypesSplit) diff --git a/src/Microsoft.AspNet.Authorization/AuthorizationPolicyBuilder.cs b/src/Microsoft.AspNet.Authorization/AuthorizationPolicyBuilder.cs index 128545032..f41fe7369 100644 --- a/src/Microsoft.AspNet.Authorization/AuthorizationPolicyBuilder.cs +++ b/src/Microsoft.AspNet.Authorization/AuthorizationPolicyBuilder.cs @@ -55,21 +55,13 @@ public AuthorizationPolicyBuilder RequireClaim([NotNull] string claimType, param public AuthorizationPolicyBuilder RequireClaim([NotNull] string claimType, IEnumerable requiredValues) { - Requirements.Add(new ClaimsAuthorizationRequirement - { - ClaimType = claimType, - AllowedValues = requiredValues - }); + Requirements.Add(new ClaimsAuthorizationRequirement(claimType, requiredValues)); return this; } public AuthorizationPolicyBuilder RequireClaim([NotNull] string claimType) { - Requirements.Add(new ClaimsAuthorizationRequirement - { - ClaimType = claimType, - AllowedValues = null - }); + Requirements.Add(new ClaimsAuthorizationRequirement(claimType, allowedValues: null)); return this; } @@ -80,13 +72,13 @@ public AuthorizationPolicyBuilder RequireRole([NotNull] params string[] roles) public AuthorizationPolicyBuilder RequireRole([NotNull] IEnumerable roles) { - RequireClaim(ClaimTypes.Role, roles); + Requirements.Add(new RolesAuthorizationRequirement(roles)); return this; } public AuthorizationPolicyBuilder RequireUserName([NotNull] string userName) { - RequireClaim(ClaimTypes.Name, userName); + Requirements.Add(new NameAuthorizationRequirement(userName)); return this; } diff --git a/src/Microsoft.AspNet.Authorization/AuthorizationServiceExtensions.cs b/src/Microsoft.AspNet.Authorization/AuthorizationServiceExtensions.cs index 298a2f081..07619f37c 100644 --- a/src/Microsoft.AspNet.Authorization/AuthorizationServiceExtensions.cs +++ b/src/Microsoft.AspNet.Authorization/AuthorizationServiceExtensions.cs @@ -20,12 +20,6 @@ public static class AuthorizationServiceExtensions /// true when the user fulfills the policy, false otherwise. public static Task AuthorizeAsync([NotNull] this IAuthorizationService service, ClaimsPrincipal user, object resource, [NotNull] AuthorizationPolicy policy) { - // TODO RENABLE - //if (policy.ActiveAuthenticationSchemes != null && policy.ActiveAuthenticationSchemes.Any() && user != null) - //{ - // // Filter the user to only contain the active authentication types - // user = new ClaimsPrincipal(user.Identities.Where(i => policy.ActiveAuthenticationSchemes.Contains(i.AuthenticationScheme))); - //} return service.AuthorizeAsync(user, resource, policy.Requirements.ToArray()); } @@ -39,12 +33,6 @@ public static Task AuthorizeAsync([NotNull] this IAuthorizationService ser /// true when the user fulfills the policy, false otherwise. public static bool Authorize([NotNull] this IAuthorizationService service, ClaimsPrincipal user, object resource, [NotNull] AuthorizationPolicy policy) { - // TODO: REeanble - //if (policy.ActiveAuthenticationSchemes != null && policy.ActiveAuthenticationSchemes.Any() && user != null) - //{ - // // Filter the user to only contain the active authentication types - // user = new ClaimsPrincipal(user.Identities.Where(i => policy.ActiveAuthenticationSchemes.Contains(i.AuthenticationScheme))); - //} return service.Authorize(user, resource, policy.Requirements.ToArray()); } diff --git a/src/Microsoft.AspNet.Authorization/ClaimsAuthorizationRequirement.cs b/src/Microsoft.AspNet.Authorization/ClaimsAuthorizationRequirement.cs index b8994b8b7..c5af9449b 100644 --- a/src/Microsoft.AspNet.Authorization/ClaimsAuthorizationRequirement.cs +++ b/src/Microsoft.AspNet.Authorization/ClaimsAuthorizationRequirement.cs @@ -1,15 +1,45 @@ // 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.Linq; +using Microsoft.Framework.Internal; namespace Microsoft.AspNet.Authorization { // Must contain a claim with the specified name, and at least one of the required values // If AllowedValues is null or empty, that means any claim is valid - public class ClaimsAuthorizationRequirement : IAuthorizationRequirement + public class ClaimsAuthorizationRequirement : AuthorizationHandler, IAuthorizationRequirement { - public string ClaimType { get; set; } - public IEnumerable AllowedValues { get; set; } + public ClaimsAuthorizationRequirement([NotNull] string claimType, IEnumerable allowedValues) + { + ClaimType = claimType; + AllowedValues = allowedValues; + } + + public string ClaimType { get; } + public IEnumerable AllowedValues { get; } + + public override void Handle(AuthorizationContext context, ClaimsAuthorizationRequirement requirement) + { + if (context.User != null) + { + var found = false; + if (requirement.AllowedValues == null || !requirement.AllowedValues.Any()) + { + found = context.User.Claims.Any(c => string.Equals(c.Type, requirement.ClaimType, StringComparison.OrdinalIgnoreCase)); + } + else + { + found = context.User.Claims.Any(c => string.Equals(c.Type, requirement.ClaimType, StringComparison.OrdinalIgnoreCase) + && requirement.AllowedValues.Contains(c.Value, StringComparer.Ordinal)); + } + if (found) + { + context.Succeed(requirement); + } + } + } } } diff --git a/src/Microsoft.AspNet.Authorization/DenyAnonymousAuthorizationRequirement.cs b/src/Microsoft.AspNet.Authorization/DenyAnonymousAuthorizationRequirement.cs index fce23a3dc..92f48c1fe 100644 --- a/src/Microsoft.AspNet.Authorization/DenyAnonymousAuthorizationRequirement.cs +++ b/src/Microsoft.AspNet.Authorization/DenyAnonymousAuthorizationRequirement.cs @@ -1,9 +1,22 @@ // 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.AspNet.Authorization; +using System.Linq; namespace Microsoft.AspNet.Authorization { - public class DenyAnonymousAuthorizationRequirement : IAuthorizationRequirement { } + public class DenyAnonymousAuthorizationRequirement : AuthorizationHandler, IAuthorizationRequirement + { + public override void Handle(AuthorizationContext context, DenyAnonymousAuthorizationRequirement requirement) + { + var user = context.User; + var userIsAnonymous = + user?.Identity == null || + !user.Identities.Any(i => i.IsAuthenticated); + if (!userIsAnonymous) + { + context.Succeed(requirement); + } + } + } } diff --git a/src/Microsoft.AspNet.Authorization/NameAuthorizationRequirement.cs b/src/Microsoft.AspNet.Authorization/NameAuthorizationRequirement.cs new file mode 100644 index 000000000..7d64f1b71 --- /dev/null +++ b/src/Microsoft.AspNet.Authorization/NameAuthorizationRequirement.cs @@ -0,0 +1,35 @@ +// 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.Linq; +using Microsoft.Framework.Internal; + +namespace Microsoft.AspNet.Authorization +{ + /// + /// Requirement that ensures a specific Name + /// + public class NameAuthorizationRequirement : AuthorizationHandler, IAuthorizationRequirement + { + public NameAuthorizationRequirement([NotNull] string requiredName) + { + RequiredName = requiredName; + } + + public string RequiredName { get; } + + public override void Handle(AuthorizationContext context, NameAuthorizationRequirement requirement) + { + if (context.User != null) + { + // REVIEW: Do we need to do normalization? casing/loc? + if (context.User.Identities.Any(i => string.Equals(i.Name, requirement.RequiredName))) + { + context.Succeed(requirement); + } + } + } + } +} diff --git a/src/Microsoft.AspNet.Authorization/Properties/Resources.Designer.cs b/src/Microsoft.AspNet.Authorization/Properties/Resources.Designer.cs index b8ab20596..b62711827 100644 --- a/src/Microsoft.AspNet.Authorization/Properties/Resources.Designer.cs +++ b/src/Microsoft.AspNet.Authorization/Properties/Resources.Designer.cs @@ -11,67 +11,35 @@ private static readonly ResourceManager _resourceManager = new ResourceManager("Microsoft.AspNet.Authorization.Resources", typeof(Resources).GetTypeInfo().Assembly); /// - /// The default data protection provider may only be used when the IApplicationBuilder.Properties contains an appropriate 'host.AppName' key. - /// - internal static string Exception_DefaultDpapiRequiresAppNameKey - { - get { return GetString("Exception_DefaultDpapiRequiresAppNameKey"); } - } - - /// - /// The default data protection provider may only be used when the IApplicationBuilder.Properties contains an appropriate 'host.AppName' key. - /// - internal static string FormatException_DefaultDpapiRequiresAppNameKey() - { - return GetString("Exception_DefaultDpapiRequiresAppNameKey"); - } - - /// - /// The state passed to UnhookAuthentication may only be the return value from HookAuthentication. - /// - internal static string Exception_UnhookAuthenticationStateType - { - get { return GetString("Exception_UnhookAuthenticationStateType"); } - } - - /// - /// The state passed to UnhookAuthentication may only be the return value from HookAuthentication. - /// - internal static string FormatException_UnhookAuthenticationStateType() - { - return GetString("Exception_UnhookAuthenticationStateType"); - } - - /// - /// The AuthenticationTokenProvider's required synchronous events have not been registered. + /// The AuthorizationPolicy named: '{0}' was not found. /// - internal static string Exception_AuthenticationTokenDoesNotProvideSyncMethods + internal static string Exception_AuthorizationPolicyNotFound { - get { return GetString("Exception_AuthenticationTokenDoesNotProvideSyncMethods"); } + get { return GetString("Exception_AuthorizationPolicyNotFound"); } } /// - /// The AuthenticationTokenProvider's required synchronous events have not been registered. + /// The AuthorizationPolicy named: '{0}' was not found. /// - internal static string FormatException_AuthenticationTokenDoesNotProvideSyncMethods() + internal static string FormatException_AuthorizationPolicyNotFound(object p0) { - return GetString("Exception_AuthenticationTokenDoesNotProvideSyncMethods"); + return string.Format(CultureInfo.CurrentCulture, GetString("Exception_AuthorizationPolicyNotFound"), p0); } /// - /// The AuthorizationPolicy named: '{0}' was not found. + /// At least one role must be specified. /// - internal static string Exception_AuthorizationPolicyNotFound + internal static string Exception_RoleRequirementEmpty { - get { return GetString("Exception_AuthorizationPolicyNotFound"); } + get { return GetString("Exception_RoleRequirementEmpty"); } } /// - /// The AuthorizationPolicy named: '{0}' was not found. + /// At least one role must be specified. /// - internal static string FormatException_AuthorizationPolicyNotFound(object p0) + internal static string FormatException_RoleRequirementEmpty() { - return string.Format(CultureInfo.CurrentCulture, GetString("Exception_AuthorizationPolicyNotFound"), p0); + return GetString("Exception_RoleRequirementEmpty"); } private static string GetString(string name, params string[] formatterNames) diff --git a/src/Microsoft.AspNet.Authorization/Resources.resx b/src/Microsoft.AspNet.Authorization/Resources.resx index 3e72c4a2c..ee3f8cd88 100644 --- a/src/Microsoft.AspNet.Authorization/Resources.resx +++ b/src/Microsoft.AspNet.Authorization/Resources.resx @@ -117,16 +117,10 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - The default data protection provider may only be used when the IApplicationBuilder.Properties contains an appropriate 'host.AppName' key. - - - The state passed to UnhookAuthentication may only be the return value from HookAuthentication. - - - The AuthenticationTokenProvider's required synchronous events have not been registered. - The AuthorizationPolicy named: '{0}' was not found. + + At least one role must be specified. + \ No newline at end of file diff --git a/src/Microsoft.AspNet.Authorization/RolesAuthorizationRequirement.cs b/src/Microsoft.AspNet.Authorization/RolesAuthorizationRequirement.cs new file mode 100644 index 000000000..f3336237e --- /dev/null +++ b/src/Microsoft.AspNet.Authorization/RolesAuthorizationRequirement.cs @@ -0,0 +1,47 @@ +// 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.Linq; +using Microsoft.Framework.Internal; + +namespace Microsoft.AspNet.Authorization +{ + // Must belong to with one of specified roles + // If AllowedRoles is null or empty, that means any role is valid + public class RolesAuthorizationRequirement : AuthorizationHandler, IAuthorizationRequirement + { + public RolesAuthorizationRequirement([NotNull] IEnumerable allowedRoles) + { + if (allowedRoles.Count() == 0) + { + throw new InvalidOperationException(Resources.Exception_RoleRequirementEmpty); + } + AllowedRoles = allowedRoles; + } + + public IEnumerable AllowedRoles { get; } + + public override void Handle(AuthorizationContext context, RolesAuthorizationRequirement requirement) + { + if (context.User != null) + { + bool found = false; + if (requirement.AllowedRoles == null || !requirement.AllowedRoles.Any()) + { + // Review: What do we want to do here? No roles requested is auto success? + } + else + { + found = requirement.AllowedRoles.Any(r => context.User.IsInRole(r)); + } + if (found) + { + context.Succeed(requirement); + } + } + } + + } +} diff --git a/src/Microsoft.AspNet.Authorization/ServiceCollectionExtensions.cs b/src/Microsoft.AspNet.Authorization/ServiceCollectionExtensions.cs index 4deced289..d77512a64 100644 --- a/src/Microsoft.AspNet.Authorization/ServiceCollectionExtensions.cs +++ b/src/Microsoft.AspNet.Authorization/ServiceCollectionExtensions.cs @@ -23,8 +23,6 @@ public static IServiceCollection AddAuthorization([NotNull] this IServiceCollect { services.AddOptions(); services.TryAdd(ServiceDescriptor.Transient()); - services.AddTransient(); - services.AddTransient(); services.AddTransient(); return services; } diff --git a/test/Microsoft.AspNet.Authorization.Test/AuthorizationPolicyFacts.cs b/test/Microsoft.AspNet.Authorization.Test/AuthorizationPolicyFacts.cs index 535e8d527..208c53b1c 100644 --- a/test/Microsoft.AspNet.Authorization.Test/AuthorizationPolicyFacts.cs +++ b/test/Microsoft.AspNet.Authorization.Test/AuthorizationPolicyFacts.cs @@ -1,6 +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 System; using System.Linq; using Microsoft.AspNet.Authorization; using Xunit; @@ -9,6 +10,12 @@ namespace Microsoft.AspNet.Authroization.Test { public class AuthorizationPolicyFacts { + [Fact] + public void RequireRoleThrowsIfEmpty() + { + Assert.Throws(() => new AuthorizationPolicyBuilder().RequireRole()); + } + [Fact] public void CanCombineAuthorizeAttributes() { @@ -32,7 +39,8 @@ public void CanCombineAuthorizeAttributes() Assert.True(combined.ActiveAuthenticationSchemes.Contains("roles")); Assert.Equal(4, combined.Requirements.Count()); Assert.True(combined.Requirements.Any(r => r is DenyAnonymousAuthorizationRequirement)); - Assert.Equal(3, combined.Requirements.OfType().Count()); + Assert.Equal(2, combined.Requirements.OfType().Count()); + Assert.Equal(1, combined.Requirements.OfType().Count()); } } } \ No newline at end of file diff --git a/test/Microsoft.AspNet.Authorization.Test/DefaultAuthorizationServiceTests.cs b/test/Microsoft.AspNet.Authorization.Test/DefaultAuthorizationServiceTests.cs index 4c26f10b3..2683eddce 100644 --- a/test/Microsoft.AspNet.Authorization.Test/DefaultAuthorizationServiceTests.cs +++ b/test/Microsoft.AspNet.Authorization.Test/DefaultAuthorizationServiceTests.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using System.Linq; using System.Security.Claims; using System.Threading.Tasks; @@ -504,6 +505,50 @@ public async Task CanRequireUserName() Assert.True(allowed); } + [Fact] + public async Task CanRequireUserNameWithDiffClaimType() + { + // Arrange + var authorizationService = BuildAuthorizationService(services => + { + services.ConfigureAuthorization(options => + { + options.AddPolicy("Hao", policy => policy.RequireUserName("Hao")); + }); + }); + var identity = new ClaimsIdentity("AuthType", "Name", "Role"); + identity.AddClaim(new Claim("Name", "Hao")); + var user = new ClaimsPrincipal(identity); + + // Act + var allowed = await authorizationService.AuthorizeAsync(user, null, "Hao"); + + // Assert + Assert.True(allowed); + } + + [Fact] + public async Task CanRequireRoleWithDiffClaimType() + { + // Arrange + var authorizationService = BuildAuthorizationService(services => + { + services.ConfigureAuthorization(options => + { + options.AddPolicy("Hao", policy => policy.RequireRole("Hao")); + }); + }); + var identity = new ClaimsIdentity("AuthType", "Name", "Role"); + identity.AddClaim(new Claim("Role", "Hao")); + var user = new ClaimsPrincipal(identity); + + // Act + var allowed = await authorizationService.AuthorizeAsync(user, null, "Hao"); + + // Assert + Assert.True(allowed); + } + [Fact] public async Task CanApproveAnyAuthenticatedUser() { From dbdabeb9d2d01846967e98f5fc07530770b6c639 Mon Sep 17 00:00:00 2001 From: Hao Kung Date: Wed, 6 May 2015 14:24:58 -0700 Subject: [PATCH 204/216] Delete old handlers --- .../ClaimsAuthorizationHandler.cs | 32 ------------------- .../DenyAnonymousAuthorizationHandler.cs | 22 ------------- 2 files changed, 54 deletions(-) delete mode 100644 src/Microsoft.AspNet.Authorization/ClaimsAuthorizationHandler.cs delete mode 100644 src/Microsoft.AspNet.Authorization/DenyAnonymousAuthorizationHandler.cs diff --git a/src/Microsoft.AspNet.Authorization/ClaimsAuthorizationHandler.cs b/src/Microsoft.AspNet.Authorization/ClaimsAuthorizationHandler.cs deleted file mode 100644 index fed436ad4..000000000 --- a/src/Microsoft.AspNet.Authorization/ClaimsAuthorizationHandler.cs +++ /dev/null @@ -1,32 +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.Linq; - -namespace Microsoft.AspNet.Authorization -{ - public class ClaimsAuthorizationHandler : AuthorizationHandler - { - public override void Handle(AuthorizationContext context, ClaimsAuthorizationRequirement requirement) - { - if (context.User != null) - { - bool found = false; - if (requirement.AllowedValues == null || !requirement.AllowedValues.Any()) - { - found = context.User.Claims.Any(c => string.Equals(c.Type, requirement.ClaimType, StringComparison.OrdinalIgnoreCase)); - } - else - { - found = context.User.Claims.Any(c => string.Equals(c.Type, requirement.ClaimType, StringComparison.OrdinalIgnoreCase) - && requirement.AllowedValues.Contains(c.Value, StringComparer.Ordinal)); - } - if (found) - { - context.Succeed(requirement); - } - } - } - } -} diff --git a/src/Microsoft.AspNet.Authorization/DenyAnonymousAuthorizationHandler.cs b/src/Microsoft.AspNet.Authorization/DenyAnonymousAuthorizationHandler.cs deleted file mode 100644 index 3c1c872b3..000000000 --- a/src/Microsoft.AspNet.Authorization/DenyAnonymousAuthorizationHandler.cs +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System.Linq; - -namespace Microsoft.AspNet.Authorization -{ - public class DenyAnonymousAuthorizationHandler : AuthorizationHandler - { - public override void Handle(AuthorizationContext context, DenyAnonymousAuthorizationRequirement requirement) - { - var user = context.User; - var userIsAnonymous = - user?.Identity == null || - !user.Identities.Any(i => i.IsAuthenticated); - if (!userIsAnonymous) - { - context.Succeed(requirement); - } - } - } -} From 3cc6739c3d71fa6c4088336c95b97cbc66e78e58 Mon Sep 17 00:00:00 2001 From: Chris R Date: Wed, 6 May 2015 16:17:34 -0700 Subject: [PATCH 205/216] React to QueryString API change. --- .../CookieAuthenticationHandler.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Microsoft.AspNet.Authentication.Cookies/CookieAuthenticationHandler.cs b/src/Microsoft.AspNet.Authentication.Cookies/CookieAuthenticationHandler.cs index b002fc2d6..04852e390 100644 --- a/src/Microsoft.AspNet.Authentication.Cookies/CookieAuthenticationHandler.cs +++ b/src/Microsoft.AspNet.Authentication.Cookies/CookieAuthenticationHandler.cs @@ -383,7 +383,7 @@ protected override void ApplyResponseChallenge() Request.Host + Request.PathBase + Options.LoginPath + - new QueryString(Options.ReturnUrlParameter, currentUri); + QueryString.Create(Options.ReturnUrlParameter, currentUri); } var redirectContext = new CookieApplyRedirectContext(Context, Options, loginUri); From e57440f92c152e653ecdf7692dddb8eeafc16d4e Mon Sep 17 00:00:00 2001 From: Troy Dai Date: Thu, 7 May 2015 09:41:05 -0700 Subject: [PATCH 206/216] React to common package name change --- src/Microsoft.AspNet.Authentication.Cookies/project.json | 2 +- src/Microsoft.AspNet.Authentication.Facebook/project.json | 2 +- src/Microsoft.AspNet.Authentication.Google/project.json | 2 +- .../project.json | 2 +- src/Microsoft.AspNet.Authentication.OAuth/project.json | 2 +- src/Microsoft.AspNet.Authentication.OAuthBearer/project.json | 2 +- src/Microsoft.AspNet.Authentication.OpenIdConnect/project.json | 2 +- src/Microsoft.AspNet.Authentication.Twitter/project.json | 2 +- src/Microsoft.AspNet.Authentication/project.json | 2 +- src/Microsoft.AspNet.Authorization/project.json | 2 +- 10 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/Microsoft.AspNet.Authentication.Cookies/project.json b/src/Microsoft.AspNet.Authentication.Cookies/project.json index 7b42df350..28127904d 100644 --- a/src/Microsoft.AspNet.Authentication.Cookies/project.json +++ b/src/Microsoft.AspNet.Authentication.Cookies/project.json @@ -3,7 +3,7 @@ "description": "ASP.NET middleware that enables an application to use cookie based authentication, similar to ASP.NET's forms authentication.", "dependencies": { "Microsoft.AspNet.Authentication": "1.0.0-*", - "Microsoft.Framework.NotNullAttribute.Internal": { "type": "build", "version": "1.0.0-*" }, + "Microsoft.Framework.NotNullAttribute.Sources": { "type": "build", "version": "1.0.0-*" }, "Microsoft.Framework.WebEncoders": "1.0.0-*", "Newtonsoft.Json": "6.0.6" }, diff --git a/src/Microsoft.AspNet.Authentication.Facebook/project.json b/src/Microsoft.AspNet.Authentication.Facebook/project.json index a14ab52da..332385ca7 100644 --- a/src/Microsoft.AspNet.Authentication.Facebook/project.json +++ b/src/Microsoft.AspNet.Authentication.Facebook/project.json @@ -3,7 +3,7 @@ "description": "ASP.NET 5 middleware that enables an application to support Facebook's OAuth 2.0 authentication workflow.", "dependencies": { "Microsoft.AspNet.Authentication.OAuth": "1.0.0-*", - "Microsoft.Framework.NotNullAttribute.Internal": { "type": "build", "version": "1.0.0-*" }, + "Microsoft.Framework.NotNullAttribute.Sources": { "type": "build", "version": "1.0.0-*" }, "Newtonsoft.Json": "6.0.6" }, "frameworks": { diff --git a/src/Microsoft.AspNet.Authentication.Google/project.json b/src/Microsoft.AspNet.Authentication.Google/project.json index 72beb690a..b7ffdd0bc 100644 --- a/src/Microsoft.AspNet.Authentication.Google/project.json +++ b/src/Microsoft.AspNet.Authentication.Google/project.json @@ -3,7 +3,7 @@ "description": "ASP.NET 5 contains middlewares to support Google's OpenId and OAuth 2.0 authentication workflows.", "dependencies": { "Microsoft.AspNet.Authentication.OAuth": "1.0.0-*", - "Microsoft.Framework.NotNullAttribute.Internal": { "type": "build", "version": "1.0.0-*" } + "Microsoft.Framework.NotNullAttribute.Sources": { "type": "build", "version": "1.0.0-*" } }, "frameworks": { "dnx451": { }, diff --git a/src/Microsoft.AspNet.Authentication.MicrosoftAccount/project.json b/src/Microsoft.AspNet.Authentication.MicrosoftAccount/project.json index 6bd7bb375..41ef74556 100644 --- a/src/Microsoft.AspNet.Authentication.MicrosoftAccount/project.json +++ b/src/Microsoft.AspNet.Authentication.MicrosoftAccount/project.json @@ -3,7 +3,7 @@ "description": "ASP.NET 5 middleware that enables an application to support the Microsoft Account authentication workflow.", "dependencies": { "Microsoft.AspNet.Authentication.OAuth": "1.0.0-*", - "Microsoft.Framework.NotNullAttribute.Internal": { "type": "build", "version": "1.0.0-*" } + "Microsoft.Framework.NotNullAttribute.Sources": { "type": "build", "version": "1.0.0-*" } }, "frameworks": { "dnx451": { }, diff --git a/src/Microsoft.AspNet.Authentication.OAuth/project.json b/src/Microsoft.AspNet.Authentication.OAuth/project.json index a3409abf8..ba2cc53dc 100644 --- a/src/Microsoft.AspNet.Authentication.OAuth/project.json +++ b/src/Microsoft.AspNet.Authentication.OAuth/project.json @@ -3,7 +3,7 @@ "description": "ASP.NET 5 middleware that enables an application to support any standard OAuth 2.0 authentication workflow.", "dependencies": { "Microsoft.AspNet.Authentication": "1.0.0-*", - "Microsoft.Framework.NotNullAttribute.Internal": { "type": "build", "version": "1.0.0-*" }, + "Microsoft.Framework.NotNullAttribute.Sources": { "type": "build", "version": "1.0.0-*" }, "Newtonsoft.Json": "6.0.6" }, "frameworks": { diff --git a/src/Microsoft.AspNet.Authentication.OAuthBearer/project.json b/src/Microsoft.AspNet.Authentication.OAuthBearer/project.json index 570eb8346..e81bd3499 100644 --- a/src/Microsoft.AspNet.Authentication.OAuthBearer/project.json +++ b/src/Microsoft.AspNet.Authentication.OAuthBearer/project.json @@ -3,7 +3,7 @@ "description": "ASP.NET 5 middleware that enables an application to receive a OAuth bearer token.", "dependencies": { "Microsoft.AspNet.Authentication": "1.0.0-*", - "Microsoft.Framework.NotNullAttribute.Internal": { "type": "build", "version": "1.0.0-*" }, + "Microsoft.Framework.NotNullAttribute.Sources": { "type": "build", "version": "1.0.0-*" }, "Microsoft.IdentityModel.Protocol.Extensions": "2.0.0-beta4-*" }, "frameworks": { diff --git a/src/Microsoft.AspNet.Authentication.OpenIdConnect/project.json b/src/Microsoft.AspNet.Authentication.OpenIdConnect/project.json index 5f8e6d67a..b61834b53 100644 --- a/src/Microsoft.AspNet.Authentication.OpenIdConnect/project.json +++ b/src/Microsoft.AspNet.Authentication.OpenIdConnect/project.json @@ -3,7 +3,7 @@ "description": "ASP.NET 5 middleware that enables an application to support OpenIdConnect authentication workflow.", "dependencies": { "Microsoft.AspNet.Authentication": "1.0.0-*", - "Microsoft.Framework.NotNullAttribute.Internal": { "type": "build", "version": "1.0.0-*" }, + "Microsoft.Framework.NotNullAttribute.Sources": { "type": "build", "version": "1.0.0-*" }, "Microsoft.IdentityModel.Protocol.Extensions": "2.0.0-beta4-*" }, "frameworks": { diff --git a/src/Microsoft.AspNet.Authentication.Twitter/project.json b/src/Microsoft.AspNet.Authentication.Twitter/project.json index a9d804bc2..6b2ddf521 100644 --- a/src/Microsoft.AspNet.Authentication.Twitter/project.json +++ b/src/Microsoft.AspNet.Authentication.Twitter/project.json @@ -3,7 +3,7 @@ "description": "ASP.NET 5 middleware that enables an application to support Twitter's OAuth 2.0 authentication workflow.", "dependencies": { "Microsoft.AspNet.Authentication": "1.0.0-*", - "Microsoft.Framework.NotNullAttribute.Internal": { "type": "build", "version": "1.0.0-*" } + "Microsoft.Framework.NotNullAttribute.Sources": { "type": "build", "version": "1.0.0-*" } }, "frameworks": { "dnx451": { diff --git a/src/Microsoft.AspNet.Authentication/project.json b/src/Microsoft.AspNet.Authentication/project.json index 6bda0f7da..bdf51537f 100644 --- a/src/Microsoft.AspNet.Authentication/project.json +++ b/src/Microsoft.AspNet.Authentication/project.json @@ -6,7 +6,7 @@ "Microsoft.AspNet.Http": "1.0.0-*", "Microsoft.AspNet.Http.Extensions": "1.0.0-*", "Microsoft.Framework.Logging.Abstractions": "1.0.0-*", - "Microsoft.Framework.NotNullAttribute.Internal": { "type": "build", "version": "1.0.0-*" }, + "Microsoft.Framework.NotNullAttribute.Sources": { "type": "build", "version": "1.0.0-*" }, "Microsoft.Framework.OptionsModel": "1.0.0-*", "Microsoft.Framework.WebEncoders": "1.0.0-*" }, diff --git a/src/Microsoft.AspNet.Authorization/project.json b/src/Microsoft.AspNet.Authorization/project.json index 71c918fc5..a0b9beb5d 100644 --- a/src/Microsoft.AspNet.Authorization/project.json +++ b/src/Microsoft.AspNet.Authorization/project.json @@ -4,7 +4,7 @@ "dependencies": { "Microsoft.AspNet.Http.Features": "1.0.0-*", "Microsoft.Framework.Logging.Abstractions": "1.0.0-*", - "Microsoft.Framework.NotNullAttribute.Internal": { "type": "build", "version": "1.0.0-*" }, + "Microsoft.Framework.NotNullAttribute.Sources": { "type": "build", "version": "1.0.0-*" }, "Microsoft.Framework.OptionsModel": "1.0.0-*" }, "frameworks": { From 582f562bbb20fc76f37023086e2b2d861eb4d43d Mon Sep 17 00:00:00 2001 From: Hisham Abdullah Bin Ateya Date: Tue, 5 May 2015 19:23:54 +0300 Subject: [PATCH 207/216] Using [NotNull] and 'nameof' operator --- .../CookieAuthenticationOptions.cs | 6 ++---- .../FacebookAuthenticationMiddleware.cs | 4 ++-- .../MicrosoftAccountAuthenticatedContext.cs | 2 +- .../OAuthAuthenticationMiddleware.cs | 6 +++--- .../OAuthBearerAuthenticationOptions.cs | 7 ++----- .../OpenIdConnectAuthenticationOptions.cs | 9 +++------ .../TwitterAuthenticationMiddleware.cs | 4 ++-- .../CertificateSubjectPublicKeyInfoValidator.cs | 4 ++-- .../CertificateThumbprintValidator.cs | 2 +- 9 files changed, 18 insertions(+), 26 deletions(-) diff --git a/src/Microsoft.AspNet.Authentication.Cookies/CookieAuthenticationOptions.cs b/src/Microsoft.AspNet.Authentication.Cookies/CookieAuthenticationOptions.cs index 966858fa6..52660955c 100644 --- a/src/Microsoft.AspNet.Authentication.Cookies/CookieAuthenticationOptions.cs +++ b/src/Microsoft.AspNet.Authentication.Cookies/CookieAuthenticationOptions.cs @@ -5,6 +5,7 @@ using System.Diagnostics.CodeAnalysis; using Microsoft.AspNet.Http; using Microsoft.AspNet.Authentication.Cookies.Infrastructure; +using Microsoft.Framework.Internal; namespace Microsoft.AspNet.Authentication.Cookies { @@ -38,12 +39,9 @@ public CookieAuthenticationOptions() public string CookieName { get { return _cookieName; } + [param: NotNull] set { - if (value == null) - { - throw new ArgumentNullException("value"); - } _cookieName = value; } } diff --git a/src/Microsoft.AspNet.Authentication.Facebook/FacebookAuthenticationMiddleware.cs b/src/Microsoft.AspNet.Authentication.Facebook/FacebookAuthenticationMiddleware.cs index ad10432c5..4eab19ddb 100644 --- a/src/Microsoft.AspNet.Authentication.Facebook/FacebookAuthenticationMiddleware.cs +++ b/src/Microsoft.AspNet.Authentication.Facebook/FacebookAuthenticationMiddleware.cs @@ -37,11 +37,11 @@ public FacebookAuthenticationMiddleware( { if (string.IsNullOrWhiteSpace(Options.AppId)) { - throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, Resources.Exception_OptionMustBeProvided, "AppId")); + throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, Resources.Exception_OptionMustBeProvided, nameof(Options.AppId))); } if (string.IsNullOrWhiteSpace(Options.AppSecret)) { - throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, Resources.Exception_OptionMustBeProvided, "AppSecret")); + throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, Resources.Exception_OptionMustBeProvided, nameof(Options.AppSecret))); } if (Options.Notifications == null) diff --git a/src/Microsoft.AspNet.Authentication.MicrosoftAccount/Notifications/MicrosoftAccountAuthenticatedContext.cs b/src/Microsoft.AspNet.Authentication.MicrosoftAccount/Notifications/MicrosoftAccountAuthenticatedContext.cs index 7d6a31cd2..c5bfa3f9b 100644 --- a/src/Microsoft.AspNet.Authentication.MicrosoftAccount/Notifications/MicrosoftAccountAuthenticatedContext.cs +++ b/src/Microsoft.AspNet.Authentication.MicrosoftAccount/Notifications/MicrosoftAccountAuthenticatedContext.cs @@ -30,7 +30,7 @@ public MicrosoftAccountAuthenticatedContext(HttpContext context, OAuthAuthentica JToken userId = User["id"]; if (userId == null) { - throw new ArgumentException(Resources.Exception_MissingId, "user"); + throw new ArgumentException(Resources.Exception_MissingId, nameof(user)); } Id = userId.ToString(); diff --git a/src/Microsoft.AspNet.Authentication.OAuth/OAuthAuthenticationMiddleware.cs b/src/Microsoft.AspNet.Authentication.OAuth/OAuthAuthenticationMiddleware.cs index e4357a68a..f0be294c5 100644 --- a/src/Microsoft.AspNet.Authentication.OAuth/OAuthAuthenticationMiddleware.cs +++ b/src/Microsoft.AspNet.Authentication.OAuth/OAuthAuthenticationMiddleware.cs @@ -43,17 +43,17 @@ public OAuthAuthenticationMiddleware( // todo: review error handling if (string.IsNullOrWhiteSpace(Options.AuthenticationScheme)) { - throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, Resources.Exception_OptionMustBeProvided, "AuthenticationScheme")); + throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, Resources.Exception_OptionMustBeProvided, nameof(Options.AuthenticationScheme))); } if (string.IsNullOrWhiteSpace(Options.ClientId)) { - throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, Resources.Exception_OptionMustBeProvided, "ClientId")); + throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, Resources.Exception_OptionMustBeProvided, nameof(Options.ClientId))); } if (string.IsNullOrWhiteSpace(Options.ClientSecret)) { - throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, Resources.Exception_OptionMustBeProvided, "ClientSecret")); + throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, Resources.Exception_OptionMustBeProvided, nameof(Options.ClientSecret))); } if (string.IsNullOrWhiteSpace(Options.AuthorizationEndpoint)) diff --git a/src/Microsoft.AspNet.Authentication.OAuthBearer/OAuthBearerAuthenticationOptions.cs b/src/Microsoft.AspNet.Authentication.OAuthBearer/OAuthBearerAuthenticationOptions.cs index 00cc96c7a..ebae57b9f 100644 --- a/src/Microsoft.AspNet.Authentication.OAuthBearer/OAuthBearerAuthenticationOptions.cs +++ b/src/Microsoft.AspNet.Authentication.OAuthBearer/OAuthBearerAuthenticationOptions.cs @@ -7,6 +7,7 @@ using System.Net.Http; using Microsoft.AspNet.Authentication; using Microsoft.IdentityModel.Protocols; +using Microsoft.Framework.Internal; namespace Microsoft.AspNet.Authentication.OAuthBearer { @@ -122,13 +123,9 @@ public ICollection SecurityTokenValidators return _securityTokenValidators; } + [param: NotNull] set { - if (value == null) - { - throw new ArgumentNullException("SecurityTokenValidators"); - } - _securityTokenValidators = value; } } diff --git a/src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenIdConnectAuthenticationOptions.cs b/src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenIdConnectAuthenticationOptions.cs index b89699b14..9e4bfa55d 100644 --- a/src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenIdConnectAuthenticationOptions.cs +++ b/src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenIdConnectAuthenticationOptions.cs @@ -9,6 +9,7 @@ using Microsoft.AspNet.Http; using Microsoft.AspNet.Http.Authentication; using Microsoft.IdentityModel.Protocols; +using Microsoft.Framework.Internal; namespace Microsoft.AspNet.Authentication.OpenIdConnect { @@ -110,7 +111,7 @@ public TimeSpan BackchannelTimeout { if (value <= TimeSpan.Zero) { - throw new ArgumentOutOfRangeException("BackchannelTimeout", value, Resources.OIDCH_0101_BackChallnelLessThanZero); + throw new ArgumentOutOfRangeException(nameof(BackchannelTimeout), value, Resources.OIDCH_0101_BackChallnelLessThanZero); } _backchannelTimeout = value; @@ -190,13 +191,9 @@ public OpenIdConnectProtocolValidator ProtocolValidator { return _protocolValidator; } + [param: NotNull] set { - if (value == null) - { - throw new ArgumentNullException("value"); - } - _protocolValidator = value; } } diff --git a/src/Microsoft.AspNet.Authentication.Twitter/TwitterAuthenticationMiddleware.cs b/src/Microsoft.AspNet.Authentication.Twitter/TwitterAuthenticationMiddleware.cs index bcf3c4d87..1536bd807 100644 --- a/src/Microsoft.AspNet.Authentication.Twitter/TwitterAuthenticationMiddleware.cs +++ b/src/Microsoft.AspNet.Authentication.Twitter/TwitterAuthenticationMiddleware.cs @@ -45,11 +45,11 @@ public TwitterAuthenticationMiddleware( { if (string.IsNullOrWhiteSpace(Options.ConsumerSecret)) { - throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, Resources.Exception_OptionMustBeProvided, "ConsumerSecret")); + throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, Resources.Exception_OptionMustBeProvided, nameof(Options.ConsumerSecret))); } if (string.IsNullOrWhiteSpace(Options.ConsumerKey)) { - throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, Resources.Exception_OptionMustBeProvided, "ConsumerKey")); + throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, Resources.Exception_OptionMustBeProvided, nameof(Options.ConsumerKey))); } if (Options.Notifications == null) diff --git a/src/Microsoft.AspNet.Authentication/CertificateSubjectPublicKeyInfoValidator.cs b/src/Microsoft.AspNet.Authentication/CertificateSubjectPublicKeyInfoValidator.cs index 0ea177d64..11e827ae7 100644 --- a/src/Microsoft.AspNet.Authentication/CertificateSubjectPublicKeyInfoValidator.cs +++ b/src/Microsoft.AspNet.Authentication/CertificateSubjectPublicKeyInfoValidator.cs @@ -36,12 +36,12 @@ public CertificateSubjectPublicKeyInfoValidator([NotNull] IEnumerable va if (_validBase64EncodedSubjectPublicKeyInfoHashes.Count == 0) { - throw new ArgumentOutOfRangeException("validBase64EncodedSubjectPublicKeyInfoHashes"); + throw new ArgumentOutOfRangeException(nameof(validBase64EncodedSubjectPublicKeyInfoHashes)); } if (_algorithm != SubjectPublicKeyInfoAlgorithm.Sha1 && _algorithm != SubjectPublicKeyInfoAlgorithm.Sha256) { - throw new ArgumentOutOfRangeException("algorithm"); + throw new ArgumentOutOfRangeException(nameof(algorithm)); } _algorithm = algorithm; diff --git a/src/Microsoft.AspNet.Authentication/CertificateThumbprintValidator.cs b/src/Microsoft.AspNet.Authentication/CertificateThumbprintValidator.cs index 6befa1ea4..6188375a1 100644 --- a/src/Microsoft.AspNet.Authentication/CertificateThumbprintValidator.cs +++ b/src/Microsoft.AspNet.Authentication/CertificateThumbprintValidator.cs @@ -27,7 +27,7 @@ public CertificateThumbprintValidator([NotNull] IEnumerable validThumbpr if (_validCertificateThumbprints.Count == 0) { - throw new ArgumentOutOfRangeException("validThumbprints"); + throw new ArgumentOutOfRangeException(nameof(validThumbprints)); } } From 071de85e042de3715edeb0b541f2b62b9e423622 Mon Sep 17 00:00:00 2001 From: Chris R Date: Thu, 7 May 2015 14:10:59 -0700 Subject: [PATCH 208/216] React to Http namespace changes. --- .../FacebookAuthenticationHandler.cs | 2 +- .../TwitterAuthenticationHandler.cs | 4 ++-- src/Microsoft.AspNet.Authentication/AuthenticationHandler.cs | 1 + .../ClaimsTransformationAuthenticationHandler.cs | 2 +- src/Microsoft.AspNet.Authentication/HttpContextExtensions.cs | 3 ++- .../AuthenticationHandlerFacts.cs | 2 +- .../Cookies/Infrastructure/CookieChunkingTests.cs | 1 + .../OpenIdConnect/OpenIdConnectHandlerTests.cs | 2 +- .../SecurityHelperTests.cs | 2 +- 9 files changed, 11 insertions(+), 8 deletions(-) diff --git a/src/Microsoft.AspNet.Authentication.Facebook/FacebookAuthenticationHandler.cs b/src/Microsoft.AspNet.Authentication.Facebook/FacebookAuthenticationHandler.cs index 3549eec2d..291956409 100644 --- a/src/Microsoft.AspNet.Authentication.Facebook/FacebookAuthenticationHandler.cs +++ b/src/Microsoft.AspNet.Authentication.Facebook/FacebookAuthenticationHandler.cs @@ -10,8 +10,8 @@ using System.Threading.Tasks; using Microsoft.AspNet.Authentication.OAuth; using Microsoft.AspNet.Http.Authentication; -using Microsoft.AspNet.Http.Collections; using Microsoft.AspNet.Http.Extensions; +using Microsoft.AspNet.Http.Internal; using Microsoft.AspNet.WebUtilities; using Newtonsoft.Json.Linq; diff --git a/src/Microsoft.AspNet.Authentication.Twitter/TwitterAuthenticationHandler.cs b/src/Microsoft.AspNet.Authentication.Twitter/TwitterAuthenticationHandler.cs index 61ff95e2f..eecc1a043 100644 --- a/src/Microsoft.AspNet.Authentication.Twitter/TwitterAuthenticationHandler.cs +++ b/src/Microsoft.AspNet.Authentication.Twitter/TwitterAuthenticationHandler.cs @@ -9,10 +9,10 @@ using System.Security.Cryptography; using System.Text; using System.Threading.Tasks; +using Microsoft.AspNet.Authentication.Twitter.Messages; using Microsoft.AspNet.Http; -using Microsoft.AspNet.Http.Collections; using Microsoft.AspNet.Http.Authentication; -using Microsoft.AspNet.Authentication.Twitter.Messages; +using Microsoft.AspNet.Http.Internal; using Microsoft.AspNet.WebUtilities; using Microsoft.Framework.Logging; diff --git a/src/Microsoft.AspNet.Authentication/AuthenticationHandler.cs b/src/Microsoft.AspNet.Authentication/AuthenticationHandler.cs index 674fec16a..1d1d8e193 100644 --- a/src/Microsoft.AspNet.Authentication/AuthenticationHandler.cs +++ b/src/Microsoft.AspNet.Authentication/AuthenticationHandler.cs @@ -8,6 +8,7 @@ using Microsoft.AspNet.Authentication.DataHandler.Encoder; using Microsoft.AspNet.Http; using Microsoft.AspNet.Http.Authentication; +using Microsoft.AspNet.Http.Features.Authentication; using Microsoft.Framework.Internal; using Microsoft.Framework.Logging; using Microsoft.Framework.WebEncoders; diff --git a/src/Microsoft.AspNet.Authentication/ClaimsTransformationAuthenticationHandler.cs b/src/Microsoft.AspNet.Authentication/ClaimsTransformationAuthenticationHandler.cs index 69563a8de..4d896e152 100644 --- a/src/Microsoft.AspNet.Authentication/ClaimsTransformationAuthenticationHandler.cs +++ b/src/Microsoft.AspNet.Authentication/ClaimsTransformationAuthenticationHandler.cs @@ -4,7 +4,7 @@ using System; using System.Security.Claims; using System.Threading.Tasks; -using Microsoft.AspNet.Http.Authentication; +using Microsoft.AspNet.Http.Features.Authentication; namespace Microsoft.AspNet.Authentication { diff --git a/src/Microsoft.AspNet.Authentication/HttpContextExtensions.cs b/src/Microsoft.AspNet.Authentication/HttpContextExtensions.cs index eaa53c1b3..4617b02f4 100644 --- a/src/Microsoft.AspNet.Authentication/HttpContextExtensions.cs +++ b/src/Microsoft.AspNet.Authentication/HttpContextExtensions.cs @@ -2,7 +2,8 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using Microsoft.AspNet.Http; -using Microsoft.AspNet.Http.Authentication; +using Microsoft.AspNet.Http.Features.Authentication; +using Microsoft.AspNet.Http.Features.Authentication.Internal; namespace Microsoft.AspNet.Authentication { diff --git a/test/Microsoft.AspNet.Authentication.Test/AuthenticationHandlerFacts.cs b/test/Microsoft.AspNet.Authentication.Test/AuthenticationHandlerFacts.cs index c858dee28..c531c17ca 100644 --- a/test/Microsoft.AspNet.Authentication.Test/AuthenticationHandlerFacts.cs +++ b/test/Microsoft.AspNet.Authentication.Test/AuthenticationHandlerFacts.cs @@ -2,7 +2,7 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; -using Microsoft.AspNet.Http; +using Microsoft.AspNet.Http.Internal; using Microsoft.Framework.Logging; using Xunit; diff --git a/test/Microsoft.AspNet.Authentication.Test/Cookies/Infrastructure/CookieChunkingTests.cs b/test/Microsoft.AspNet.Authentication.Test/Cookies/Infrastructure/CookieChunkingTests.cs index 7c94ecadf..425fa1742 100644 --- a/test/Microsoft.AspNet.Authentication.Test/Cookies/Infrastructure/CookieChunkingTests.cs +++ b/test/Microsoft.AspNet.Authentication.Test/Cookies/Infrastructure/CookieChunkingTests.cs @@ -4,6 +4,7 @@ using System; using System.Collections.Generic; using Microsoft.AspNet.Http; +using Microsoft.AspNet.Http.Internal; using Xunit; namespace Microsoft.AspNet.Authentication.Cookies.Infrastructure diff --git a/test/Microsoft.AspNet.Authentication.Test/OpenIdConnect/OpenIdConnectHandlerTests.cs b/test/Microsoft.AspNet.Authentication.Test/OpenIdConnect/OpenIdConnectHandlerTests.cs index 73350e619..183ae6018 100644 --- a/test/Microsoft.AspNet.Authentication.Test/OpenIdConnect/OpenIdConnectHandlerTests.cs +++ b/test/Microsoft.AspNet.Authentication.Test/OpenIdConnect/OpenIdConnectHandlerTests.cs @@ -8,7 +8,6 @@ using System; using System.Collections.Generic; using System.Net.Http; -using System.Security.Claims; using System.Threading.Tasks; using Microsoft.AspNet.Authentication.Notifications; using Microsoft.AspNet.Authentication.OpenIdConnect; @@ -16,6 +15,7 @@ using Microsoft.AspNet.DataProtection; using Microsoft.AspNet.Http; using Microsoft.AspNet.Http.Authentication; +using Microsoft.AspNet.Http.Features.Authentication; using Microsoft.AspNet.TestHost; using Microsoft.Framework.DependencyInjection; using Microsoft.Framework.Logging; diff --git a/test/Microsoft.AspNet.Authentication.Test/SecurityHelperTests.cs b/test/Microsoft.AspNet.Authentication.Test/SecurityHelperTests.cs index aa9e91e55..1de266682 100644 --- a/test/Microsoft.AspNet.Authentication.Test/SecurityHelperTests.cs +++ b/test/Microsoft.AspNet.Authentication.Test/SecurityHelperTests.cs @@ -4,7 +4,7 @@ using System.Linq; using System.Security.Claims; using System.Security.Principal; -using Microsoft.AspNet.Http; +using Microsoft.AspNet.Http.Internal; using Shouldly; using Xunit; From 75474fe9facfc80672120fa5c7a6dc011edf4c40 Mon Sep 17 00:00:00 2001 From: Eilon Lipton Date: Tue, 12 May 2015 11:48:43 -0700 Subject: [PATCH 209/216] Update Home master -> Home dev --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index eac4268e4..64ff041d5 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,4 +1,4 @@ Contributing ====== -Information on contributing to this repo is in the [Contributing Guide](https://github.com/aspnet/Home/blob/master/CONTRIBUTING.md) in the Home repo. +Information on contributing to this repo is in the [Contributing Guide](https://github.com/aspnet/Home/blob/dev/CONTRIBUTING.md) in the Home repo. From bb2e12a8e611e0f7a2f54ee2fab15373c02d6fca Mon Sep 17 00:00:00 2001 From: Hao Kung Date: Tue, 12 May 2015 13:52:32 -0700 Subject: [PATCH 210/216] Add sugar for UseClaimsTransformation --- ...laimsTransformationAppBuilderExtensions.cs | 28 +++++++++++++++++-- .../ClaimsTransformationMiddleware.cs | 14 ++++++++-- .../Google/GoogleMiddlewareTests.cs | 18 ++++++------ 3 files changed, 47 insertions(+), 13 deletions(-) diff --git a/src/Microsoft.AspNet.Authentication/ClaimsTransformationAppBuilderExtensions.cs b/src/Microsoft.AspNet.Authentication/ClaimsTransformationAppBuilderExtensions.cs index ae1e4d97a..c18317f83 100644 --- a/src/Microsoft.AspNet.Authentication/ClaimsTransformationAppBuilderExtensions.cs +++ b/src/Microsoft.AspNet.Authentication/ClaimsTransformationAppBuilderExtensions.cs @@ -3,6 +3,8 @@ using System; using Microsoft.AspNet.Authentication; +using Microsoft.Framework.Internal; +using Microsoft.Framework.OptionsModel; namespace Microsoft.AspNet.Builder { @@ -11,6 +13,27 @@ namespace Microsoft.AspNet.Builder /// public static class ClaimsTransformationAppBuilderExtensions { + /// + /// Adds a claims transformation middleware to your web application pipeline. + /// + /// The IApplicationBuilder passed to your configuration method + /// The original app parameter + public static IApplicationBuilder UseClaimsTransformation(this IApplicationBuilder app) + { + return app.UseClaimsTransformation(configureOptions: o => { }, optionsName: string.Empty); + } + + /// + /// Adds a claims transformation middleware to your web application pipeline. + /// + /// The IApplicationBuilder passed to your configuration method + /// Used to configure the options for the middleware + /// The original app parameter + public static IApplicationBuilder UseClaimsTransformation(this IApplicationBuilder app, [NotNull] Action configureOptions) + { + return app.UseClaimsTransformation(configureOptions: configureOptions, optionsName: string.Empty); + } + /// /// Adds a claims transformation middleware to your web application pipeline. /// @@ -18,9 +41,10 @@ public static class ClaimsTransformationAppBuilderExtensions /// Used to configure the options for the middleware /// The name of the options class that controls the middleware behavior, null will use the default options /// The original app parameter - public static IApplicationBuilder UseClaimsTransformation(this IApplicationBuilder app) + public static IApplicationBuilder UseClaimsTransformation(this IApplicationBuilder app, [NotNull] Action configureOptions, [NotNull] string optionsName) { - return app.UseMiddleware(); + return app.UseMiddleware( + new ConfigureOptions(configureOptions) { Name = optionsName }); } } } \ No newline at end of file diff --git a/src/Microsoft.AspNet.Authentication/ClaimsTransformationMiddleware.cs b/src/Microsoft.AspNet.Authentication/ClaimsTransformationMiddleware.cs index a8022d576..0f785161c 100644 --- a/src/Microsoft.AspNet.Authentication/ClaimsTransformationMiddleware.cs +++ b/src/Microsoft.AspNet.Authentication/ClaimsTransformationMiddleware.cs @@ -15,10 +15,18 @@ public class ClaimsTransformationMiddleware public ClaimsTransformationMiddleware( [NotNull] RequestDelegate next, - [NotNull] IOptions options) + [NotNull] IOptions options, + ConfigureOptions configureOptions) { - // REVIEW: do we need to take ConfigureOptions?? - Options = options.Options; + if (configureOptions != null) + { + Options = options.GetNamedOptions(configureOptions.Name); + configureOptions.Configure(Options, configureOptions.Name); + } + else + { + Options = options.Options; + } _next = next; } diff --git a/test/Microsoft.AspNet.Authentication.Test/Google/GoogleMiddlewareTests.cs b/test/Microsoft.AspNet.Authentication.Test/Google/GoogleMiddlewareTests.cs index 7e1dc417b..0b02b78e9 100644 --- a/test/Microsoft.AspNet.Authentication.Test/Google/GoogleMiddlewareTests.cs +++ b/test/Microsoft.AspNet.Authentication.Test/Google/GoogleMiddlewareTests.cs @@ -461,7 +461,16 @@ private static TestServer CreateServer(Action confi options.AutomaticAuthentication = true; }); app.UseGoogleAuthentication(configureOptions); - app.UseClaimsTransformation(); + app.UseClaimsTransformation(o => + { + o.Transformation = p => + { + var id = new ClaimsIdentity("xform"); + id.AddClaim(new Claim("xform", "yup")); + p.AddIdentity(id); + return p; + }; + }); app.Use(async (context, next) => { var req = context.Request; @@ -508,13 +517,6 @@ private static TestServer CreateServer(Action confi { options.SignInScheme = TestExtensions.CookieAuthenticationScheme; }); - services.ConfigureClaimsTransformation(p => - { - var id = new ClaimsIdentity("xform"); - id.AddClaim(new Claim("xform", "yup")); - p.AddIdentity(id); - return p; - }); }); } From 17deab142da56b656bb2cd84dce294ca15135397 Mon Sep 17 00:00:00 2001 From: Hao Kung Date: Tue, 12 May 2015 13:57:23 -0700 Subject: [PATCH 211/216] AuthZ: Sugar to make resource parameter optional --- .../AuthorizationPolicy.cs | 6 +- .../AuthorizationServiceExtensions.cs | 72 +++++++++++++++++++ .../DefaultAuthorizationService.cs | 5 +- .../IAuthorizationService.cs | 10 +-- .../Properties/Resources.Designer.cs | 16 +++++ .../Resources.resx | 3 + .../DefaultAuthorizationServiceTests.cs | 61 ++++++---------- 7 files changed, 128 insertions(+), 45 deletions(-) diff --git a/src/Microsoft.AspNet.Authorization/AuthorizationPolicy.cs b/src/Microsoft.AspNet.Authorization/AuthorizationPolicy.cs index ef16f968c..379926450 100644 --- a/src/Microsoft.AspNet.Authorization/AuthorizationPolicy.cs +++ b/src/Microsoft.AspNet.Authorization/AuthorizationPolicy.cs @@ -10,8 +10,12 @@ namespace Microsoft.AspNet.Authorization { public class AuthorizationPolicy { - public AuthorizationPolicy(IEnumerable requirements, IEnumerable activeAuthenticationSchemes) + public AuthorizationPolicy([NotNull] IEnumerable requirements, [NotNull] IEnumerable activeAuthenticationSchemes) { + if (requirements.Count() == 0) + { + throw new InvalidOperationException(Resources.Exception_AuthorizationPolicyEmpty); + } Requirements = new List(requirements).AsReadOnly(); ActiveAuthenticationSchemes = new List(activeAuthenticationSchemes).AsReadOnly(); } diff --git a/src/Microsoft.AspNet.Authorization/AuthorizationServiceExtensions.cs b/src/Microsoft.AspNet.Authorization/AuthorizationServiceExtensions.cs index 07619f37c..14951fa07 100644 --- a/src/Microsoft.AspNet.Authorization/AuthorizationServiceExtensions.cs +++ b/src/Microsoft.AspNet.Authorization/AuthorizationServiceExtensions.cs @@ -10,6 +10,18 @@ namespace Microsoft.AspNet.Authorization { public static class AuthorizationServiceExtensions { + /// + /// Checks if a user meets a specific requirement for the specified resource + /// + /// + /// + /// + /// + public static Task AuthorizeAsync([NotNull] this IAuthorizationService service, ClaimsPrincipal user, object resource, [NotNull] IAuthorizationRequirement requirement) + { + return service.AuthorizeAsync(user, resource, new IAuthorizationRequirement[] { requirement }); + } + /// /// Checks if a user meets a specific authorization policy /// @@ -23,6 +35,42 @@ public static Task AuthorizeAsync([NotNull] this IAuthorizationService ser return service.AuthorizeAsync(user, resource, policy.Requirements.ToArray()); } + /// + /// Checks if a user meets a specific authorization policy + /// + /// The authorization service. + /// The user to check the policy against. + /// The policy to check against a specific context. + /// true when the user fulfills the policy, false otherwise. + public static Task AuthorizeAsync([NotNull] this IAuthorizationService service, ClaimsPrincipal user, [NotNull] AuthorizationPolicy policy) + { + return service.AuthorizeAsync(user, resource: null, policy: policy); + } + + /// + /// Checks if a user meets a specific authorization policy + /// + /// The authorization service. + /// The user to check the policy against. + /// The name of the policy to check against a specific context. + /// true when the user fulfills the policy, false otherwise. + public static Task AuthorizeAsync([NotNull] this IAuthorizationService service, ClaimsPrincipal user, [NotNull] string policyName) + { + return service.AuthorizeAsync(user, resource: null, policyName: policyName); + } + + /// + /// Checks if a user meets a specific requirement for the specified resource + /// + /// + /// + /// + /// + public static bool Authorize([NotNull] this IAuthorizationService service, ClaimsPrincipal user, object resource, [NotNull] IAuthorizationRequirement requirement) + { + return service.Authorize(user, resource, new IAuthorizationRequirement[] { requirement }); + } + /// /// Checks if a user meets a specific authorization policy /// @@ -36,5 +84,29 @@ public static bool Authorize([NotNull] this IAuthorizationService service, Claim return service.Authorize(user, resource, policy.Requirements.ToArray()); } + /// + /// Checks if a user meets a specific authorization policy + /// + /// The authorization service. + /// The user to check the policy against. + /// The policy to check against a specific context. + /// true when the user fulfills the policy, false otherwise. + public static bool Authorize([NotNull] this IAuthorizationService service, ClaimsPrincipal user, [NotNull] AuthorizationPolicy policy) + { + return service.Authorize(user, resource: null, requirements: policy.Requirements.ToArray()); + } + + /// + /// Checks if a user meets a specific authorization policy + /// + /// The authorization service. + /// The user to check the policy against. + /// The name of the policy to check against a specific context. + /// true when the user fulfills the policy, false otherwise. + public static bool Authorize([NotNull] this IAuthorizationService service, ClaimsPrincipal user, [NotNull] string policyName) + { + return service.Authorize(user, resource: null, policyName: policyName); + } + } } \ No newline at end of file diff --git a/src/Microsoft.AspNet.Authorization/DefaultAuthorizationService.cs b/src/Microsoft.AspNet.Authorization/DefaultAuthorizationService.cs index abc866276..e66721a5c 100644 --- a/src/Microsoft.AspNet.Authorization/DefaultAuthorizationService.cs +++ b/src/Microsoft.AspNet.Authorization/DefaultAuthorizationService.cs @@ -5,6 +5,7 @@ using System.Linq; using System.Security.Claims; using System.Threading.Tasks; +using Microsoft.Framework.Internal; using Microsoft.Framework.OptionsModel; namespace Microsoft.AspNet.Authorization @@ -28,7 +29,7 @@ public bool Authorize(ClaimsPrincipal user, object resource, string policyName) : this.Authorize(user, resource, policy); } - public bool Authorize(ClaimsPrincipal user, object resource, params IAuthorizationRequirement[] requirements) + public bool Authorize(ClaimsPrincipal user, object resource, [NotNull] IEnumerable requirements) { var authContext = new AuthorizationContext(requirements, user, resource); foreach (var handler in _handlers) @@ -38,7 +39,7 @@ public bool Authorize(ClaimsPrincipal user, object resource, params IAuthorizati return authContext.HasSucceeded; } - public async Task AuthorizeAsync(ClaimsPrincipal user, object resource, params IAuthorizationRequirement[] requirements) + public async Task AuthorizeAsync(ClaimsPrincipal user, object resource, [NotNull] IEnumerable requirements) { var authContext = new AuthorizationContext(requirements, user, resource); foreach (var handler in _handlers) diff --git a/src/Microsoft.AspNet.Authorization/IAuthorizationService.cs b/src/Microsoft.AspNet.Authorization/IAuthorizationService.cs index dedfcc37c..876fd7601 100644 --- a/src/Microsoft.AspNet.Authorization/IAuthorizationService.cs +++ b/src/Microsoft.AspNet.Authorization/IAuthorizationService.cs @@ -1,8 +1,10 @@ // Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. +using System.Collections.Generic; using System.Security.Claims; using System.Threading.Tasks; +using Microsoft.Framework.Internal; namespace Microsoft.AspNet.Authorization { @@ -18,7 +20,7 @@ public interface IAuthorizationService /// /// /// - Task AuthorizeAsync(ClaimsPrincipal user, object resource, params IAuthorizationRequirement[] requirements); + Task AuthorizeAsync(ClaimsPrincipal user, object resource, [NotNull] IEnumerable requirements); /// /// Checks if a user meets a specific set of requirements for the specified resource @@ -27,7 +29,7 @@ public interface IAuthorizationService /// /// /// - bool Authorize(ClaimsPrincipal user, object resource, params IAuthorizationRequirement[] requirements); + bool Authorize(ClaimsPrincipal user, object resource, [NotNull] IEnumerable requirements); /// /// Checks if a user meets a specific authorization policy @@ -36,7 +38,7 @@ public interface IAuthorizationService /// The resource the policy should be checked with. /// The name of the policy to check against a specific context. /// true when the user fulfills the policy, false otherwise. - Task AuthorizeAsync(ClaimsPrincipal user, object resource, string policyName); + Task AuthorizeAsync(ClaimsPrincipal user, object resource, [NotNull] string policyName); /// /// Checks if a user meets a specific authorization policy @@ -45,6 +47,6 @@ public interface IAuthorizationService /// The resource the policy should be checked with. /// The name of the policy to check against a specific context. /// true when the user fulfills the policy, false otherwise. - bool Authorize(ClaimsPrincipal user, object resource, string policyName); + bool Authorize(ClaimsPrincipal user, object resource, [NotNull] string policyName); } } \ No newline at end of file diff --git a/src/Microsoft.AspNet.Authorization/Properties/Resources.Designer.cs b/src/Microsoft.AspNet.Authorization/Properties/Resources.Designer.cs index b62711827..29d82385f 100644 --- a/src/Microsoft.AspNet.Authorization/Properties/Resources.Designer.cs +++ b/src/Microsoft.AspNet.Authorization/Properties/Resources.Designer.cs @@ -26,6 +26,22 @@ internal static string FormatException_AuthorizationPolicyNotFound(object p0) return string.Format(CultureInfo.CurrentCulture, GetString("Exception_AuthorizationPolicyNotFound"), p0); } + /// + /// AuthorizationPolicy must have at least one requirement. + /// + internal static string Exception_AuthorizationPolicyEmpty + { + get { return GetString("Exception_AuthorizationPolicyEmpty"); } + } + + /// + /// AuthorizationPolicy must have at least one requirement. + /// + internal static string FormatException_AuthorizationPolicyEmpty(object p0) + { + return string.Format(CultureInfo.CurrentCulture, GetString("Exception_AuthorizationPolicyEmpty"), p0); + } + /// /// At least one role must be specified. /// diff --git a/src/Microsoft.AspNet.Authorization/Resources.resx b/src/Microsoft.AspNet.Authorization/Resources.resx index ee3f8cd88..a36e55d6b 100644 --- a/src/Microsoft.AspNet.Authorization/Resources.resx +++ b/src/Microsoft.AspNet.Authorization/Resources.resx @@ -117,6 +117,9 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + AuthorizationPolicy must have at least one requirement. + The AuthorizationPolicy named: '{0}' was not found. diff --git a/test/Microsoft.AspNet.Authorization.Test/DefaultAuthorizationServiceTests.cs b/test/Microsoft.AspNet.Authorization.Test/DefaultAuthorizationServiceTests.cs index 2683eddce..d5491164d 100644 --- a/test/Microsoft.AspNet.Authorization.Test/DefaultAuthorizationServiceTests.cs +++ b/test/Microsoft.AspNet.Authorization.Test/DefaultAuthorizationServiceTests.cs @@ -3,7 +3,6 @@ using System; using System.Collections.Generic; -using System.Diagnostics; using System.Linq; using System.Security.Claims; using System.Threading.Tasks; @@ -47,7 +46,7 @@ public async Task Authorize_ShouldAllowIfClaimIsPresent() var user = new ClaimsPrincipal(new ClaimsIdentity(new Claim[] { new Claim("Permission", "CanViewPage") }, "Basic")); // Act - var allowed = await authorizationService.AuthorizeAsync(user, null, "Basic"); + var allowed = await authorizationService.AuthorizeAsync(user, "Basic"); // Assert Assert.True(allowed); @@ -67,7 +66,7 @@ public async Task Authorize_ShouldAllowIfClaimIsPresentWithSpecifiedAuthType() var user = new ClaimsPrincipal(new ClaimsIdentity(new Claim[] { new Claim("Permission", "CanViewPage") }, "Basic")); // Act - var allowed = await authorizationService.AuthorizeAsync(user, null, "Basic"); + var allowed = await authorizationService.AuthorizeAsync(user, "Basic"); // Assert Assert.True(allowed); @@ -94,7 +93,7 @@ public async Task Authorize_ShouldAllowIfClaimIsAmongValues() ); // Act - var allowed = await authorizationService.AuthorizeAsync(user, null, "Basic"); + var allowed = await authorizationService.AuthorizeAsync(user, "Basic"); // Assert Assert.True(allowed); @@ -120,7 +119,7 @@ public async Task Authorize_ShouldFailWhenAllRequirementsNotHandled() ); // Act - var allowed = await authorizationService.AuthorizeAsync(user, null, "Basic"); + var allowed = await authorizationService.AuthorizeAsync(user, "Basic"); // Assert Assert.False(allowed); @@ -146,7 +145,7 @@ public async Task Authorize_ShouldNotAllowIfClaimTypeIsNotPresent() ); // Act - var allowed = await authorizationService.AuthorizeAsync(user, null, "Basic"); + var allowed = await authorizationService.AuthorizeAsync(user, "Basic"); // Assert Assert.False(allowed); @@ -172,7 +171,7 @@ public async Task Authorize_ShouldNotAllowIfClaimValueIsNotPresent() ); // Act - var allowed = await authorizationService.AuthorizeAsync(user, null, "Basic"); + var allowed = await authorizationService.AuthorizeAsync(user, "Basic"); // Assert Assert.False(allowed); @@ -196,7 +195,7 @@ public async Task Authorize_ShouldNotAllowIfNoClaims() ); // Act - var allowed = await authorizationService.AuthorizeAsync(user, null, "Basic"); + var allowed = await authorizationService.AuthorizeAsync(user, "Basic"); // Assert Assert.False(allowed); @@ -235,7 +234,7 @@ public async Task Authorize_ShouldNotAllowIfNotCorrectAuthType() var user = new ClaimsPrincipal(new ClaimsIdentity()); // Act - var allowed = await authorizationService.AuthorizeAsync(user, null, "Basic"); + var allowed = await authorizationService.AuthorizeAsync(user, "Basic"); // Assert Assert.False(allowed); @@ -261,7 +260,7 @@ public async Task Authorize_ShouldAllowWithNoAuthType() ); // Act - var allowed = await authorizationService.AuthorizeAsync(user, null, "Basic"); + var allowed = await authorizationService.AuthorizeAsync(user, "Basic"); // Assert Assert.True(allowed); @@ -281,7 +280,7 @@ public async Task Authorize_ShouldNotAllowIfUnknownPolicy() ); // Act - var allowed = await authorizationService.AuthorizeAsync(user, null, "Basic"); + var allowed = await authorizationService.AuthorizeAsync(user, "Basic"); // Assert Assert.False(allowed); @@ -304,7 +303,7 @@ public async Task Authorize_CustomRolePolicy() ); // Act - var allowed = await authorizationService.AuthorizeAsync(user, null, policy.Build()); + var allowed = await authorizationService.AuthorizeAsync(user, policy.Build()); // Assert Assert.True(allowed); @@ -325,7 +324,7 @@ public async Task Authorize_HasAnyClaimOfTypePolicy() ); // Act - var allowed = await authorizationService.AuthorizeAsync(user, null, policy.Build()); + var allowed = await authorizationService.AuthorizeAsync(user, policy.Build()); // Assert Assert.True(allowed); @@ -342,7 +341,7 @@ public async Task Authorize_PolicyCanAuthenticationSchemeWithNameClaim() ); // Act - var allowed = await authorizationService.AuthorizeAsync(user, null, policy.Build()); + var allowed = await authorizationService.AuthorizeAsync(user, policy.Build()); // Assert Assert.True(allowed); @@ -375,7 +374,7 @@ public async Task RolePolicyCanRequireOneOfManyRoles() new ClaimsIdentity(new Claim[] { new Claim(ClaimTypes.Role, "Users") }, "AuthType")); // Act - var allowed = await authorizationService.AuthorizeAsync(user, null, policy.Build()); + var allowed = await authorizationService.AuthorizeAsync(user, policy.Build()); // Assert Assert.True(allowed); @@ -396,7 +395,7 @@ public async Task RolePolicyCanBlockWrongRole() ); // Act - var allowed = await authorizationService.AuthorizeAsync(user, null, policy.Build()); + var allowed = await authorizationService.AuthorizeAsync(user, policy.Build()); // Assert Assert.False(allowed); @@ -421,36 +420,22 @@ public async Task RolePolicyCanBlockNoRole() ); // Act - var allowed = await authorizationService.AuthorizeAsync(user, null, "Basic"); + var allowed = await authorizationService.AuthorizeAsync(user, "Basic"); // Assert Assert.False(allowed); } [Fact] - public async Task PolicyFailsWithNoRequirements() + public void PolicyThrowsWithNoRequirements() { - // Arrange - var authorizationService = BuildAuthorizationService(services => + Assert.Throws(() => BuildAuthorizationService(services => { services.ConfigureAuthorization(options => { options.AddPolicy("Basic", policy => { }); }); - }); - var user = new ClaimsPrincipal( - new ClaimsIdentity( - new Claim[] { - new Claim(ClaimTypes.Name, "Name"), - }, - "AuthType") - ); - - // Act - var allowed = await authorizationService.AuthorizeAsync(user, null, "Basic"); - - // Assert - Assert.False(allowed); + })); } [Fact] @@ -473,7 +458,7 @@ public async Task RequireUserNameFailsForWrongUserName() ); // Act - var allowed = await authorizationService.AuthorizeAsync(user, null, "Any"); + var allowed = await authorizationService.AuthorizeAsync(user, "Any"); // Assert Assert.False(allowed); @@ -499,7 +484,7 @@ public async Task CanRequireUserName() ); // Act - var allowed = await authorizationService.AuthorizeAsync(user, null, "Hao"); + var allowed = await authorizationService.AuthorizeAsync(user, "Hao"); // Assert Assert.True(allowed); @@ -521,7 +506,7 @@ public async Task CanRequireUserNameWithDiffClaimType() var user = new ClaimsPrincipal(identity); // Act - var allowed = await authorizationService.AuthorizeAsync(user, null, "Hao"); + var allowed = await authorizationService.AuthorizeAsync(user, "Hao"); // Assert Assert.True(allowed); @@ -543,7 +528,7 @@ public async Task CanRequireRoleWithDiffClaimType() var user = new ClaimsPrincipal(identity); // Act - var allowed = await authorizationService.AuthorizeAsync(user, null, "Hao"); + var allowed = await authorizationService.AuthorizeAsync(user, "Hao"); // Assert Assert.True(allowed); From 538e1d6a8baca53f63f91a5b8f3debdfc70ba608 Mon Sep 17 00:00:00 2001 From: Troy Dai Date: Tue, 12 May 2015 11:30:25 -0700 Subject: [PATCH 212/216] Remove comments from project.json --- samples/SocialSample/project.json | 1 - 1 file changed, 1 deletion(-) diff --git a/samples/SocialSample/project.json b/samples/SocialSample/project.json index 020f08b1b..024014140 100644 --- a/samples/SocialSample/project.json +++ b/samples/SocialSample/project.json @@ -12,7 +12,6 @@ "Kestrel": "1.0.0-*" }, "commands": { - /* Note all servers must use the same address and port because these are pre-registered with the various providers. */ "web": "Microsoft.AspNet.Hosting server=Microsoft.AspNet.Server.WebListener server.urls=http://localhost:54540", "kestrel": "Microsoft.AspNet.Hosting --server Kestrel --server.urls http://localhost:54540" }, From 468852550cfc467f5cb80bcf86e394cd48fe4e7c Mon Sep 17 00:00:00 2001 From: Hao Kung Date: Tue, 12 May 2015 15:49:49 -0700 Subject: [PATCH 213/216] Tweak SecurityHelper.AddUserPrincipal logic --- .../SecurityHelper.cs | 20 ++++---- .../SecurityHelperTests.cs | 47 +++++++++++++++++++ 2 files changed, 57 insertions(+), 10 deletions(-) diff --git a/src/Microsoft.AspNet.Authentication/SecurityHelper.cs b/src/Microsoft.AspNet.Authentication/SecurityHelper.cs index 617fe14a1..5f5c765b3 100644 --- a/src/Microsoft.AspNet.Authentication/SecurityHelper.cs +++ b/src/Microsoft.AspNet.Authentication/SecurityHelper.cs @@ -1,6 +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 System.Linq; using System.Security.Claims; using Microsoft.AspNet.Http; using Microsoft.Framework.Internal; @@ -14,24 +15,23 @@ public static class SecurityHelper { /// /// Add all ClaimsIdenities from an additional ClaimPrincipal to the ClaimsPrincipal + /// Merges a new claims principal, placing all new identities first, and eliminating + /// any empty unauthenticated identities from context.User /// /// public static void AddUserPrincipal([NotNull] HttpContext context, [NotNull] ClaimsPrincipal principal) { + var newPrincipal = new ClaimsPrincipal(); + // New principal identities go first + newPrincipal.AddIdentities(principal.Identities); + + // Then add any existing non empty or authenticated identities var existingPrincipal = context.User; if (existingPrincipal != null) { - foreach (var existingClaimsIdentity in existingPrincipal.Identities) - { - // REVIEW: No longer use auth type for anything, so we could remove this check, except for the default one HttpContext.user creates - // REVIEW: Need to ignore any identities that did not come from an authentication scheme? - if (existingClaimsIdentity.IsAuthenticated) - { - principal.AddIdentity(existingClaimsIdentity); - } - } + newPrincipal.AddIdentities(existingPrincipal.Identities.Where(i => i.IsAuthenticated || i.Claims.Count() > 0)); } - context.User = principal; + context.User = newPrincipal; } } } diff --git a/test/Microsoft.AspNet.Authentication.Test/SecurityHelperTests.cs b/test/Microsoft.AspNet.Authentication.Test/SecurityHelperTests.cs index 1de266682..a02283ab7 100644 --- a/test/Microsoft.AspNet.Authentication.Test/SecurityHelperTests.cs +++ b/test/Microsoft.AspNet.Authentication.Test/SecurityHelperTests.cs @@ -56,5 +56,52 @@ public void AddingExistingIdentityChangesDefaultButPreservesPrior() principal.Identities.Skip(1).First().Name.ShouldBe("Test2"); principal.Identities.Skip(2).First().Name.ShouldBe("Test1"); } + + [Fact] + public void AddingPreservesNewIdentitiesAndDropsEmpty() + { + var context = new DefaultHttpContext(); + var existingPrincipal = new ClaimsPrincipal(new ClaimsIdentity()); + var identityNoAuthTypeWithClaim = new ClaimsIdentity(); + identityNoAuthTypeWithClaim.AddClaim(new Claim("identityNoAuthTypeWithClaim", "yes")); + existingPrincipal.AddIdentity(identityNoAuthTypeWithClaim); + var identityEmptyWithAuthType = new ClaimsIdentity("empty"); + existingPrincipal.AddIdentity(identityEmptyWithAuthType); + context.User = existingPrincipal; + + context.User.Identity.IsAuthenticated.ShouldBe(false); + + var newPrincipal = new ClaimsPrincipal(); + var newEmptyIdentity = new ClaimsIdentity(); + var identityTwo = new ClaimsIdentity("yep"); + newPrincipal.AddIdentity(newEmptyIdentity); + newPrincipal.AddIdentity(identityTwo); + + SecurityHelper.AddUserPrincipal(context, newPrincipal); + + // Preserve newPrincipal order + context.User.Identity.IsAuthenticated.ShouldBe(false); + context.User.Identity.Name.ShouldBe(null); + + var principal = context.User; + principal.Identities.Count().ShouldBe(4); + principal.Identities.Skip(0).First().ShouldBe(newEmptyIdentity); + principal.Identities.Skip(1).First().ShouldBe(identityTwo); + principal.Identities.Skip(2).First().ShouldBe(identityNoAuthTypeWithClaim); + principal.Identities.Skip(3).First().ShouldBe(identityEmptyWithAuthType); + + // This merge should drop newEmptyIdentity since its empty + SecurityHelper.AddUserPrincipal(context, new GenericPrincipal(new GenericIdentity("Test3", "Gamma"), new string[0])); + + context.User.Identity.AuthenticationType.ShouldBe("Gamma"); + context.User.Identity.Name.ShouldBe("Test3"); + + principal = context.User; + principal.Identities.Count().ShouldBe(4); + principal.Identities.Skip(0).First().Name.ShouldBe("Test3"); + principal.Identities.Skip(1).First().ShouldBe(identityTwo); + principal.Identities.Skip(2).First().ShouldBe(identityNoAuthTypeWithClaim); + principal.Identities.Skip(3).First().ShouldBe(identityEmptyWithAuthType); + } } } From 4ec81538b9d9fff842acf560ec8bc803dcb2bb64 Mon Sep 17 00:00:00 2001 From: Henk Mollema Date: Wed, 13 May 2015 16:43:15 +0200 Subject: [PATCH 214/216] Reference to ASP.NET 5 instead of vNext in README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 06a74de41..a676d4a87 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ ASP.NET Security ======== -ASP.NET Security contains the security and authorization middlewares for ASP.NET vNext. +ASP.NET Security contains the security and authorization middlewares for ASP.NET 5. This project is part of ASP.NET 5. You can find samples, documentation and getting started instructions for ASP.NET 5 at the [Home](https://github.com/aspnet/home) repo. From d89f5d0f47df47d6a9993c6945195d334cd16c7a Mon Sep 17 00:00:00 2001 From: Troy Dai Date: Tue, 12 May 2015 21:45:29 -0700 Subject: [PATCH 215/216] Move comment into Startup.cs --- samples/SocialSample/Startup.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/samples/SocialSample/Startup.cs b/samples/SocialSample/Startup.cs index 22c0e44a0..eb6c74563 100644 --- a/samples/SocialSample/Startup.cs +++ b/samples/SocialSample/Startup.cs @@ -15,6 +15,7 @@ namespace CookieSample { + /* Note all servers must use the same address and port because these are pre-registered with the various providers. */ public class Startup { public void ConfigureServices(IServiceCollection services) @@ -242,4 +243,4 @@ dnx . web }); } } -} \ No newline at end of file +} From af2c524352159a5e5765a5bec0d1451314bb8ae3 Mon Sep 17 00:00:00 2001 From: Kirthi Krishnamraju Date: Wed, 20 May 2015 18:20:35 -0700 Subject: [PATCH 216/216] React to aspnet/Configuration #195,#198 --- .../CookieServiceCollectionExtensions.cs | 2 +- .../FacebookServiceCollectionExtensions.cs | 2 +- .../GoogleServiceCollectionExtensions.cs | 2 +- .../MicrosoftAccountServiceCollectionExtensions.cs | 2 +- .../OAuthBearerServiceCollectionExtensions.cs | 2 +- .../OpenIdConnectServiceCollectionExtensions.cs | 2 +- .../TwitterServiceCollectionExtensions.cs | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/Microsoft.AspNet.Authentication.Cookies/CookieServiceCollectionExtensions.cs b/src/Microsoft.AspNet.Authentication.Cookies/CookieServiceCollectionExtensions.cs index 256844abd..c55cb9d5f 100644 --- a/src/Microsoft.AspNet.Authentication.Cookies/CookieServiceCollectionExtensions.cs +++ b/src/Microsoft.AspNet.Authentication.Cookies/CookieServiceCollectionExtensions.cs @@ -3,7 +3,7 @@ using System; using Microsoft.AspNet.Authentication.Cookies; -using Microsoft.Framework.ConfigurationModel; +using Microsoft.Framework.Configuration; using Microsoft.Framework.Internal; namespace Microsoft.Framework.DependencyInjection diff --git a/src/Microsoft.AspNet.Authentication.Facebook/FacebookServiceCollectionExtensions.cs b/src/Microsoft.AspNet.Authentication.Facebook/FacebookServiceCollectionExtensions.cs index 771197b50..911dd18b8 100644 --- a/src/Microsoft.AspNet.Authentication.Facebook/FacebookServiceCollectionExtensions.cs +++ b/src/Microsoft.AspNet.Authentication.Facebook/FacebookServiceCollectionExtensions.cs @@ -3,7 +3,7 @@ using System; using Microsoft.AspNet.Authentication.Facebook; -using Microsoft.Framework.ConfigurationModel; +using Microsoft.Framework.Configuration; using Microsoft.Framework.Internal; namespace Microsoft.Framework.DependencyInjection diff --git a/src/Microsoft.AspNet.Authentication.Google/GoogleServiceCollectionExtensions.cs b/src/Microsoft.AspNet.Authentication.Google/GoogleServiceCollectionExtensions.cs index bb7ce223c..c5f7041e4 100644 --- a/src/Microsoft.AspNet.Authentication.Google/GoogleServiceCollectionExtensions.cs +++ b/src/Microsoft.AspNet.Authentication.Google/GoogleServiceCollectionExtensions.cs @@ -3,7 +3,7 @@ using System; using Microsoft.AspNet.Authentication.Google; -using Microsoft.Framework.ConfigurationModel; +using Microsoft.Framework.Configuration; using Microsoft.Framework.Internal; namespace Microsoft.Framework.DependencyInjection diff --git a/src/Microsoft.AspNet.Authentication.MicrosoftAccount/MicrosoftAccountServiceCollectionExtensions.cs b/src/Microsoft.AspNet.Authentication.MicrosoftAccount/MicrosoftAccountServiceCollectionExtensions.cs index 556b1fb87..86b68230d 100644 --- a/src/Microsoft.AspNet.Authentication.MicrosoftAccount/MicrosoftAccountServiceCollectionExtensions.cs +++ b/src/Microsoft.AspNet.Authentication.MicrosoftAccount/MicrosoftAccountServiceCollectionExtensions.cs @@ -3,7 +3,7 @@ using System; using Microsoft.AspNet.Authentication.MicrosoftAccount; -using Microsoft.Framework.ConfigurationModel; +using Microsoft.Framework.Configuration; using Microsoft.Framework.Internal; namespace Microsoft.Framework.DependencyInjection diff --git a/src/Microsoft.AspNet.Authentication.OAuthBearer/OAuthBearerServiceCollectionExtensions.cs b/src/Microsoft.AspNet.Authentication.OAuthBearer/OAuthBearerServiceCollectionExtensions.cs index 51080737b..76fb362d3 100644 --- a/src/Microsoft.AspNet.Authentication.OAuthBearer/OAuthBearerServiceCollectionExtensions.cs +++ b/src/Microsoft.AspNet.Authentication.OAuthBearer/OAuthBearerServiceCollectionExtensions.cs @@ -3,7 +3,7 @@ using System; using Microsoft.AspNet.Authentication.OAuthBearer; -using Microsoft.Framework.ConfigurationModel; +using Microsoft.Framework.Configuration; using Microsoft.Framework.Internal; namespace Microsoft.Framework.DependencyInjection diff --git a/src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenIdConnectServiceCollectionExtensions.cs b/src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenIdConnectServiceCollectionExtensions.cs index 8d2e9e355..394ebe3f3 100644 --- a/src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenIdConnectServiceCollectionExtensions.cs +++ b/src/Microsoft.AspNet.Authentication.OpenIdConnect/OpenIdConnectServiceCollectionExtensions.cs @@ -3,7 +3,7 @@ using System; using Microsoft.AspNet.Authentication.OpenIdConnect; -using Microsoft.Framework.ConfigurationModel; +using Microsoft.Framework.Configuration; using Microsoft.Framework.Internal; namespace Microsoft.Framework.DependencyInjection diff --git a/src/Microsoft.AspNet.Authentication.Twitter/TwitterServiceCollectionExtensions.cs b/src/Microsoft.AspNet.Authentication.Twitter/TwitterServiceCollectionExtensions.cs index 090b237dc..553bd1ba8 100644 --- a/src/Microsoft.AspNet.Authentication.Twitter/TwitterServiceCollectionExtensions.cs +++ b/src/Microsoft.AspNet.Authentication.Twitter/TwitterServiceCollectionExtensions.cs @@ -3,7 +3,7 @@ using System; using Microsoft.AspNet.Authentication.Twitter; -using Microsoft.Framework.ConfigurationModel; +using Microsoft.Framework.Configuration; using Microsoft.Framework.Internal; namespace Microsoft.Framework.DependencyInjection