From 05ddbd7b2158846dbf5aa2c0b08db2c2c23c2668 Mon Sep 17 00:00:00 2001 From: Hao Kung Date: Thu, 13 Apr 2017 17:10:08 -0700 Subject: [PATCH 1/3] AddXyz() overloads that use config --- .../FacebookConfigureOptions.cs | 17 +++++++++++ .../FacebookExtensions.cs | 13 +++++++++ ....AspNetCore.Authentication.Facebook.csproj | 1 + .../JwtBearerConfigureOptions.cs | 17 +++++++++++ .../JwtBearerExtensions.cs | 13 +++++++++ ...AspNetCore.Authentication.JwtBearer.csproj | 1 + ...ore.Authentication.MicrosoftAccount.csproj | 1 + .../MicrosoftAccountConfigureOptions.cs | 17 +++++++++++ .../MicrosoftAccountExtensions.cs | 14 +++++++++- ...etCore.Authentication.OpenIdConnect.csproj | 1 + .../OpenIdConnectConfigureOptions.cs | 17 +++++++++++ .../OpenIdConnectExtensions.cs | 13 +++++++++ ...t.AspNetCore.Authentication.Twitter.csproj | 1 + .../TwitterConfigureOptions.cs | 17 +++++++++++ .../TwitterExtensions.cs | 13 +++++++++ .../FacebookTests.cs | 22 +++++++++++++++ .../GoogleTests.cs | 2 +- .../JwtBearerTests.cs | 22 +++++++++++++++ .../MicrosoftAccountTests.cs | 22 +++++++++++++++ ...ddlewareTests.cs => OpenIdConnectTests.cs} | 28 ++++++++++++++++++- ...tterMiddlewareTests.cs => TwitterTests.cs} | 24 +++++++++++++++- 21 files changed, 272 insertions(+), 4 deletions(-) create mode 100644 src/Microsoft.AspNetCore.Authentication.Facebook/FacebookConfigureOptions.cs create mode 100644 src/Microsoft.AspNetCore.Authentication.JwtBearer/JwtBearerConfigureOptions.cs create mode 100644 src/Microsoft.AspNetCore.Authentication.MicrosoftAccount/MicrosoftAccountConfigureOptions.cs create mode 100644 src/Microsoft.AspNetCore.Authentication.OpenIdConnect/OpenIdConnectConfigureOptions.cs create mode 100644 src/Microsoft.AspNetCore.Authentication.Twitter/TwitterConfigureOptions.cs rename test/Microsoft.AspNetCore.Authentication.Test/OpenIdConnect/{OpenIdConnectMiddlewareTests.cs => OpenIdConnectTests.cs} (89%) rename test/Microsoft.AspNetCore.Authentication.Test/{TwitterMiddlewareTests.cs => TwitterTests.cs} (88%) diff --git a/src/Microsoft.AspNetCore.Authentication.Facebook/FacebookConfigureOptions.cs b/src/Microsoft.AspNetCore.Authentication.Facebook/FacebookConfigureOptions.cs new file mode 100644 index 000000000..a8cbe1dfe --- /dev/null +++ b/src/Microsoft.AspNetCore.Authentication.Facebook/FacebookConfigureOptions.cs @@ -0,0 +1,17 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.Options; + +namespace Microsoft.AspNetCore.Authentication.Facebook +{ + internal class FacebookConfigureOptions : ConfigureNamedOptions + { + // Bind to "Google" section by default + public FacebookConfigureOptions(IConfiguration config) : + base(FacebookDefaults.AuthenticationScheme, + options => config.GetSection(FacebookDefaults.AuthenticationScheme).Bind(options)) + { } + } +} diff --git a/src/Microsoft.AspNetCore.Authentication.Facebook/FacebookExtensions.cs b/src/Microsoft.AspNetCore.Authentication.Facebook/FacebookExtensions.cs index e0cbf7efb..4450a980f 100644 --- a/src/Microsoft.AspNetCore.Authentication.Facebook/FacebookExtensions.cs +++ b/src/Microsoft.AspNetCore.Authentication.Facebook/FacebookExtensions.cs @@ -3,11 +3,24 @@ using System; using Microsoft.AspNetCore.Authentication.Facebook; +using Microsoft.Extensions.Options; namespace Microsoft.Extensions.DependencyInjection { public static class FacebookAuthenticationOptionsExtensions { + /// + /// Adds facebook authentication with options bound against the "Facebook" section + /// from the IConfiguration in the service container. + /// + /// + /// + public static IServiceCollection AddFacebookAuthentication(this IServiceCollection services) + { + services.AddSingleton, FacebookConfigureOptions>(); + return services.AddFacebookAuthentication(o => { }); + } + public static IServiceCollection AddFacebookAuthentication(this IServiceCollection services, Action configureOptions) => services.AddFacebookAuthentication(FacebookDefaults.AuthenticationScheme, configureOptions); diff --git a/src/Microsoft.AspNetCore.Authentication.Facebook/Microsoft.AspNetCore.Authentication.Facebook.csproj b/src/Microsoft.AspNetCore.Authentication.Facebook/Microsoft.AspNetCore.Authentication.Facebook.csproj index 0cef42b39..8f46ff169 100644 --- a/src/Microsoft.AspNetCore.Authentication.Facebook/Microsoft.AspNetCore.Authentication.Facebook.csproj +++ b/src/Microsoft.AspNetCore.Authentication.Facebook/Microsoft.AspNetCore.Authentication.Facebook.csproj @@ -13,6 +13,7 @@ + diff --git a/src/Microsoft.AspNetCore.Authentication.JwtBearer/JwtBearerConfigureOptions.cs b/src/Microsoft.AspNetCore.Authentication.JwtBearer/JwtBearerConfigureOptions.cs new file mode 100644 index 000000000..f3571a49c --- /dev/null +++ b/src/Microsoft.AspNetCore.Authentication.JwtBearer/JwtBearerConfigureOptions.cs @@ -0,0 +1,17 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.Options; + +namespace Microsoft.AspNetCore.Authentication.JwtBearer +{ + internal class JwtBearerConfigureOptions : ConfigureNamedOptions + { + // Bind to "Bearer" section by default + public JwtBearerConfigureOptions(IConfiguration config) : + base(JwtBearerDefaults.AuthenticationScheme, + options => config.GetSection(JwtBearerDefaults.AuthenticationScheme).Bind(options)) + { } + } +} diff --git a/src/Microsoft.AspNetCore.Authentication.JwtBearer/JwtBearerExtensions.cs b/src/Microsoft.AspNetCore.Authentication.JwtBearer/JwtBearerExtensions.cs index 575054b40..e7f643bfe 100644 --- a/src/Microsoft.AspNetCore.Authentication.JwtBearer/JwtBearerExtensions.cs +++ b/src/Microsoft.AspNetCore.Authentication.JwtBearer/JwtBearerExtensions.cs @@ -3,11 +3,24 @@ using System; using Microsoft.AspNetCore.Authentication.JwtBearer; +using Microsoft.Extensions.Options; namespace Microsoft.Extensions.DependencyInjection { public static class JwtBearerExtensions { + /// + /// Adds JwtBearer authentication with options bound against the "Bearer" section + /// from the IConfiguration in the service container. + /// + /// + /// + public static IServiceCollection AddJwtBearerAuthentication(this IServiceCollection services) + { + services.AddSingleton, JwtBearerConfigureOptions>(); + return services.AddJwtBearerAuthentication(o => { }); + } + public static IServiceCollection AddJwtBearerAuthentication(this IServiceCollection services, Action configureOptions) => services.AddJwtBearerAuthentication(JwtBearerDefaults.AuthenticationScheme, configureOptions); diff --git a/src/Microsoft.AspNetCore.Authentication.JwtBearer/Microsoft.AspNetCore.Authentication.JwtBearer.csproj b/src/Microsoft.AspNetCore.Authentication.JwtBearer/Microsoft.AspNetCore.Authentication.JwtBearer.csproj index df9f4af83..89e7ef9c3 100644 --- a/src/Microsoft.AspNetCore.Authentication.JwtBearer/Microsoft.AspNetCore.Authentication.JwtBearer.csproj +++ b/src/Microsoft.AspNetCore.Authentication.JwtBearer/Microsoft.AspNetCore.Authentication.JwtBearer.csproj @@ -11,6 +11,7 @@ + diff --git a/src/Microsoft.AspNetCore.Authentication.MicrosoftAccount/Microsoft.AspNetCore.Authentication.MicrosoftAccount.csproj b/src/Microsoft.AspNetCore.Authentication.MicrosoftAccount/Microsoft.AspNetCore.Authentication.MicrosoftAccount.csproj index eecfeb926..5b8263c9c 100644 --- a/src/Microsoft.AspNetCore.Authentication.MicrosoftAccount/Microsoft.AspNetCore.Authentication.MicrosoftAccount.csproj +++ b/src/Microsoft.AspNetCore.Authentication.MicrosoftAccount/Microsoft.AspNetCore.Authentication.MicrosoftAccount.csproj @@ -13,6 +13,7 @@ + diff --git a/src/Microsoft.AspNetCore.Authentication.MicrosoftAccount/MicrosoftAccountConfigureOptions.cs b/src/Microsoft.AspNetCore.Authentication.MicrosoftAccount/MicrosoftAccountConfigureOptions.cs new file mode 100644 index 000000000..520c3758d --- /dev/null +++ b/src/Microsoft.AspNetCore.Authentication.MicrosoftAccount/MicrosoftAccountConfigureOptions.cs @@ -0,0 +1,17 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.Options; + +namespace Microsoft.AspNetCore.Authentication.MicrosoftAccount +{ + internal class MicrosoftAccountConfigureOptions : ConfigureNamedOptions + { + // Bind to "Microsoft" section by default + public MicrosoftAccountConfigureOptions(IConfiguration config) : + base(MicrosoftAccountDefaults.AuthenticationScheme, + options => config.GetSection(MicrosoftAccountDefaults.AuthenticationScheme).Bind(options)) + { } + } +} diff --git a/src/Microsoft.AspNetCore.Authentication.MicrosoftAccount/MicrosoftAccountExtensions.cs b/src/Microsoft.AspNetCore.Authentication.MicrosoftAccount/MicrosoftAccountExtensions.cs index c5336db0b..0a4eb15f5 100644 --- a/src/Microsoft.AspNetCore.Authentication.MicrosoftAccount/MicrosoftAccountExtensions.cs +++ b/src/Microsoft.AspNetCore.Authentication.MicrosoftAccount/MicrosoftAccountExtensions.cs @@ -3,12 +3,24 @@ using System; using Microsoft.AspNetCore.Authentication.MicrosoftAccount; -using Microsoft.AspNetCore.Http; +using Microsoft.Extensions.Options; namespace Microsoft.Extensions.DependencyInjection { public static class MicrosoftAccountExtensions { + /// + /// Adds MicrosoftAccount authentication with options bound against the "Microsoft" section + /// from the IConfiguration in the service container. + /// + /// + /// + public static IServiceCollection AddMicrosoftAccountAuthentication(this IServiceCollection services) + { + services.AddSingleton, MicrosoftAccountConfigureOptions>(); + return services.AddMicrosoftAccountAuthentication(o => { }); + } + public static IServiceCollection AddMicrosoftAccountAuthentication(this IServiceCollection services, Action configureOptions) => services.AddMicrosoftAccountAuthentication(MicrosoftAccountDefaults.AuthenticationScheme, configureOptions); diff --git a/src/Microsoft.AspNetCore.Authentication.OpenIdConnect/Microsoft.AspNetCore.Authentication.OpenIdConnect.csproj b/src/Microsoft.AspNetCore.Authentication.OpenIdConnect/Microsoft.AspNetCore.Authentication.OpenIdConnect.csproj index 351cb284c..a5e4c8b0c 100644 --- a/src/Microsoft.AspNetCore.Authentication.OpenIdConnect/Microsoft.AspNetCore.Authentication.OpenIdConnect.csproj +++ b/src/Microsoft.AspNetCore.Authentication.OpenIdConnect/Microsoft.AspNetCore.Authentication.OpenIdConnect.csproj @@ -11,6 +11,7 @@ + diff --git a/src/Microsoft.AspNetCore.Authentication.OpenIdConnect/OpenIdConnectConfigureOptions.cs b/src/Microsoft.AspNetCore.Authentication.OpenIdConnect/OpenIdConnectConfigureOptions.cs new file mode 100644 index 000000000..9afae436d --- /dev/null +++ b/src/Microsoft.AspNetCore.Authentication.OpenIdConnect/OpenIdConnectConfigureOptions.cs @@ -0,0 +1,17 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.Options; + +namespace Microsoft.AspNetCore.Authentication.OpenIdConnect +{ + internal class OpenIdConnectConfigureOptions : ConfigureNamedOptions + { + // Bind to "OpenIdConnect" section by default + public OpenIdConnectConfigureOptions(IConfiguration config) : + base(OpenIdConnectDefaults.AuthenticationScheme, + options => config.GetSection(OpenIdConnectDefaults.AuthenticationScheme).Bind(options)) + { } + } +} diff --git a/src/Microsoft.AspNetCore.Authentication.OpenIdConnect/OpenIdConnectExtensions.cs b/src/Microsoft.AspNetCore.Authentication.OpenIdConnect/OpenIdConnectExtensions.cs index 5c84307b1..18d61982a 100644 --- a/src/Microsoft.AspNetCore.Authentication.OpenIdConnect/OpenIdConnectExtensions.cs +++ b/src/Microsoft.AspNetCore.Authentication.OpenIdConnect/OpenIdConnectExtensions.cs @@ -3,11 +3,24 @@ using System; using Microsoft.AspNetCore.Authentication.OpenIdConnect; +using Microsoft.Extensions.Options; namespace Microsoft.Extensions.DependencyInjection { public static class OpenIdConnectExtensions { + /// + /// Adds OpenIdConnect authentication with options bound against the "OpenIdConnect" section + /// from the IConfiguration in the service container. + /// + /// + /// + public static IServiceCollection AddOpenIdConnectAuthentication(this IServiceCollection services) + { + services.AddSingleton, OpenIdConnectConfigureOptions>(); + return services.AddOpenIdConnectAuthentication(o => { }); + } + public static IServiceCollection AddOpenIdConnectAuthentication(this IServiceCollection services, Action configureOptions) => services.AddOpenIdConnectAuthentication(OpenIdConnectDefaults.AuthenticationScheme, configureOptions); diff --git a/src/Microsoft.AspNetCore.Authentication.Twitter/Microsoft.AspNetCore.Authentication.Twitter.csproj b/src/Microsoft.AspNetCore.Authentication.Twitter/Microsoft.AspNetCore.Authentication.Twitter.csproj index dc4bbf80a..c0b773345 100644 --- a/src/Microsoft.AspNetCore.Authentication.Twitter/Microsoft.AspNetCore.Authentication.Twitter.csproj +++ b/src/Microsoft.AspNetCore.Authentication.Twitter/Microsoft.AspNetCore.Authentication.Twitter.csproj @@ -12,6 +12,7 @@ + diff --git a/src/Microsoft.AspNetCore.Authentication.Twitter/TwitterConfigureOptions.cs b/src/Microsoft.AspNetCore.Authentication.Twitter/TwitterConfigureOptions.cs new file mode 100644 index 000000000..b10435f18 --- /dev/null +++ b/src/Microsoft.AspNetCore.Authentication.Twitter/TwitterConfigureOptions.cs @@ -0,0 +1,17 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.Options; + +namespace Microsoft.AspNetCore.Authentication.Twitter +{ + internal class TwitterConfigureOptions : ConfigureNamedOptions + { + // Bind to "Twitter" section by default + public TwitterConfigureOptions(IConfiguration config) : + base(TwitterDefaults.AuthenticationScheme, + options => config.GetSection(TwitterDefaults.AuthenticationScheme).Bind(options)) + { } + } +} diff --git a/src/Microsoft.AspNetCore.Authentication.Twitter/TwitterExtensions.cs b/src/Microsoft.AspNetCore.Authentication.Twitter/TwitterExtensions.cs index e10ae4b17..837f4632e 100644 --- a/src/Microsoft.AspNetCore.Authentication.Twitter/TwitterExtensions.cs +++ b/src/Microsoft.AspNetCore.Authentication.Twitter/TwitterExtensions.cs @@ -3,11 +3,24 @@ using System; using Microsoft.AspNetCore.Authentication.Twitter; +using Microsoft.Extensions.Options; namespace Microsoft.Extensions.DependencyInjection { public static class TwitterExtensions { + /// + /// Adds Twitter authentication with options bound against the "Twitter" section + /// from the IConfiguration in the service container. + /// + /// + /// + public static IServiceCollection AddTwitterAuthentication(this IServiceCollection services) + { + services.AddSingleton, TwitterConfigureOptions>(); + return services.AddTwitterAuthentication(o => { }); + } + public static IServiceCollection AddTwitterAuthentication(this IServiceCollection services, Action configureOptions) => services.AddTwitterAuthentication(TwitterDefaults.AuthenticationScheme, configureOptions); diff --git a/test/Microsoft.AspNetCore.Authentication.Test/FacebookTests.cs b/test/Microsoft.AspNetCore.Authentication.Test/FacebookTests.cs index 92d6ac723..89189ad2b 100644 --- a/test/Microsoft.AspNetCore.Authentication.Test/FacebookTests.cs +++ b/test/Microsoft.AspNetCore.Authentication.Test/FacebookTests.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; +using System.Collections.Generic; using System.Linq; using System.Net; using System.Net.Http; @@ -15,8 +16,10 @@ using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.TestHost; +using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging.Abstractions; +using Microsoft.Extensions.Options; using Newtonsoft.Json; using Xunit; @@ -24,6 +27,25 @@ namespace Microsoft.AspNetCore.Authentication.Facebook { public class FacebookTests { + [Fact] + public void AddCanBindAgainstDefaultConfig() + { + var dic = new Dictionary + { + {"Facebook:AppId", ""}, + {"Facebook:AppSecret", ""} + }; + var configurationBuilder = new ConfigurationBuilder(); + configurationBuilder.AddInMemoryCollection(dic); + var config = configurationBuilder.Build(); + var services = new ServiceCollection().AddFacebookAuthentication().AddSingleton(config); + var sp = services.BuildServiceProvider(); + + var options = sp.GetRequiredService>().Get(FacebookDefaults.AuthenticationScheme); + Assert.Equal("", options.AppId); + Assert.Equal("", options.AppSecret); + } + [Fact] public async Task ThrowsIfAppIdMissing() { diff --git a/test/Microsoft.AspNetCore.Authentication.Test/GoogleTests.cs b/test/Microsoft.AspNetCore.Authentication.Test/GoogleTests.cs index d2a9e3d28..295e8e38f 100644 --- a/test/Microsoft.AspNetCore.Authentication.Test/GoogleTests.cs +++ b/test/Microsoft.AspNetCore.Authentication.Test/GoogleTests.cs @@ -40,7 +40,7 @@ public void AddGoogleCanBindAgainstDefaultConfig() var services = new ServiceCollection().AddGoogleAuthentication().AddSingleton(config); var sp = services.BuildServiceProvider(); - var options = sp.GetRequiredService>().Get("Google"); + var options = sp.GetRequiredService>().Get(GoogleDefaults.AuthenticationScheme); Assert.Equal("", options.ClientId); Assert.Equal("", options.ClientSecret); } diff --git a/test/Microsoft.AspNetCore.Authentication.Test/JwtBearerTests.cs b/test/Microsoft.AspNetCore.Authentication.Test/JwtBearerTests.cs index 3db2bad71..ce746cb42 100644 --- a/test/Microsoft.AspNetCore.Authentication.Test/JwtBearerTests.cs +++ b/test/Microsoft.AspNetCore.Authentication.Test/JwtBearerTests.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; +using System.Collections.Generic; using System.Linq; using System.Net; using System.Net.Http; @@ -15,7 +16,9 @@ using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.TestHost; using Microsoft.AspNetCore.Testing.xunit; +using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Options; using Microsoft.IdentityModel.Tokens; using Xunit; @@ -23,6 +26,25 @@ namespace Microsoft.AspNetCore.Authentication.JwtBearer { public class JwtBearerTests { + [Fact] + public void AddCanBindAgainstDefaultConfig() + { + var dic = new Dictionary + { + {"Bearer:Audience", ""}, + {"Bearer:Authority", ""} + }; + var configurationBuilder = new ConfigurationBuilder(); + configurationBuilder.AddInMemoryCollection(dic); + var config = configurationBuilder.Build(); + var services = new ServiceCollection().AddJwtBearerAuthentication().AddSingleton(config); + var sp = services.BuildServiceProvider(); + + var options = sp.GetRequiredService>().Get(JwtBearerDefaults.AuthenticationScheme); + Assert.Equal("", options.Audience); + Assert.Equal("", options.Authority); + } + [ConditionalFact(Skip = "Need to remove dependency on AAD since the generated tokens will expire")] [FrameworkSkipCondition(RuntimeFrameworks.Mono)] // https://github.com/AzureAD/azure-activedirectory-identitymodel-extensions-for-dotnet/issues/179 diff --git a/test/Microsoft.AspNetCore.Authentication.Test/MicrosoftAccountTests.cs b/test/Microsoft.AspNetCore.Authentication.Test/MicrosoftAccountTests.cs index 030ea52e7..72e6a89d5 100644 --- a/test/Microsoft.AspNetCore.Authentication.Test/MicrosoftAccountTests.cs +++ b/test/Microsoft.AspNetCore.Authentication.Test/MicrosoftAccountTests.cs @@ -1,6 +1,7 @@ // 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; @@ -15,8 +16,10 @@ using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.TestHost; +using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging.Abstractions; +using Microsoft.Extensions.Options; using Newtonsoft.Json; using Xunit; @@ -24,6 +27,25 @@ namespace Microsoft.AspNetCore.Authentication.Tests.MicrosoftAccount { public class MicrosoftAccountTests { + [Fact] + public void AddCanBindAgainstDefaultConfig() + { + var dic = new Dictionary + { + {"Microsoft:ClientId", ""}, + {"Microsoft:ClientSecret", ""} + }; + var configurationBuilder = new ConfigurationBuilder(); + configurationBuilder.AddInMemoryCollection(dic); + var config = configurationBuilder.Build(); + var services = new ServiceCollection().AddMicrosoftAccountAuthentication().AddSingleton(config); + var sp = services.BuildServiceProvider(); + + var options = sp.GetRequiredService>().Get("Microsoft"); + Assert.Equal("", options.ClientId); + Assert.Equal("", options.ClientSecret); + } + [Fact] public async Task ChallengeWillTriggerApplyRedirectEvent() { diff --git a/test/Microsoft.AspNetCore.Authentication.Test/OpenIdConnect/OpenIdConnectMiddlewareTests.cs b/test/Microsoft.AspNetCore.Authentication.Test/OpenIdConnect/OpenIdConnectTests.cs similarity index 89% rename from test/Microsoft.AspNetCore.Authentication.Test/OpenIdConnect/OpenIdConnectMiddlewareTests.cs rename to test/Microsoft.AspNetCore.Authentication.Test/OpenIdConnect/OpenIdConnectTests.cs index 3614e1bcf..a3d7f5130 100644 --- a/test/Microsoft.AspNetCore.Authentication.Test/OpenIdConnect/OpenIdConnectMiddlewareTests.cs +++ b/test/Microsoft.AspNetCore.Authentication.Test/OpenIdConnect/OpenIdConnectTests.cs @@ -2,20 +2,25 @@ // 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.Net; using System.Text.Encodings.Web; using System.Threading.Tasks; using Microsoft.AspNetCore.Authentication.Cookies; +using Microsoft.AspNetCore.Authentication.OpenIdConnect; using Microsoft.AspNetCore.DataProtection; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging.Abstractions; +using Microsoft.Extensions.Options; using Microsoft.IdentityModel.Protocols.OpenIdConnect; using Xunit; namespace Microsoft.AspNetCore.Authentication.Test.OpenIdConnect { - public class OpenIdConnectMiddlewareTests + public class OpenIdConnectTests { static string noncePrefix = "OpenIdConnect." + "Nonce."; static string nonceDelimiter = "."; @@ -24,6 +29,27 @@ public class OpenIdConnectMiddlewareTests const string Signin = "/signin"; const string Signout = "/signout"; + [Fact] + public void AddCanBindAgainstDefaultConfig() + { + var dic = new Dictionary + { + {"OpenIdConnect:ClientId", ""}, + {"OpenIdConnect:ClientSecret", ""}, + {"OpenIdConnect:Authority", ""} + }; + var configurationBuilder = new ConfigurationBuilder(); + configurationBuilder.AddInMemoryCollection(dic); + var config = configurationBuilder.Build(); + var services = new ServiceCollection().AddOpenIdConnectAuthentication().AddSingleton(config); + var sp = services.BuildServiceProvider(); + + var options = sp.GetRequiredService>().Get(OpenIdConnectDefaults.AuthenticationScheme); + Assert.Equal("", options.ClientId); + Assert.Equal("", options.ClientSecret); + Assert.Equal("", options.Authority); + } + /// /// Tests RedirectForSignOutContext replaces the OpenIdConnectMesssage correctly. diff --git a/test/Microsoft.AspNetCore.Authentication.Test/TwitterMiddlewareTests.cs b/test/Microsoft.AspNetCore.Authentication.Test/TwitterTests.cs similarity index 88% rename from test/Microsoft.AspNetCore.Authentication.Test/TwitterMiddlewareTests.cs rename to test/Microsoft.AspNetCore.Authentication.Test/TwitterTests.cs index 00c96d610..58b64c060 100644 --- a/test/Microsoft.AspNetCore.Authentication.Test/TwitterMiddlewareTests.cs +++ b/test/Microsoft.AspNetCore.Authentication.Test/TwitterTests.cs @@ -1,6 +1,7 @@ // 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.Net; using System.Net.Http; using System.Security.Claims; @@ -10,13 +11,34 @@ using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.TestHost; +using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Options; using Xunit; namespace Microsoft.AspNetCore.Authentication.Twitter { - public class TwitterMiddlewareTests + public class TwitterTests { + [Fact] + public void AddCanBindAgainstDefaultConfig() + { + var dic = new Dictionary + { + {"Twitter:ConsumerKey", ""}, + {"Twitter:ConsumerSecret", ""} + }; + var configurationBuilder = new ConfigurationBuilder(); + configurationBuilder.AddInMemoryCollection(dic); + var config = configurationBuilder.Build(); + var services = new ServiceCollection().AddTwitterAuthentication().AddSingleton(config); + var sp = services.BuildServiceProvider(); + + var options = sp.GetRequiredService>().Get(TwitterDefaults.AuthenticationScheme); + Assert.Equal("", options.ConsumerKey); + Assert.Equal("", options.ConsumerSecret); + } + [Fact] public async Task ChallengeWillTriggerApplyRedirectEvent() { From e0dfd596a8e94f4e07db36bb42aa0c8f4e515f84 Mon Sep 17 00:00:00 2001 From: Hao Kung Date: Thu, 13 Apr 2017 17:14:10 -0700 Subject: [PATCH 2/3] Cleanup --- .../FacebookConfigureOptions.cs | 1 - .../GoogleConfigureOptions.cs | 1 - 2 files changed, 2 deletions(-) diff --git a/src/Microsoft.AspNetCore.Authentication.Facebook/FacebookConfigureOptions.cs b/src/Microsoft.AspNetCore.Authentication.Facebook/FacebookConfigureOptions.cs index a8cbe1dfe..9305623da 100644 --- a/src/Microsoft.AspNetCore.Authentication.Facebook/FacebookConfigureOptions.cs +++ b/src/Microsoft.AspNetCore.Authentication.Facebook/FacebookConfigureOptions.cs @@ -8,7 +8,6 @@ namespace Microsoft.AspNetCore.Authentication.Facebook { internal class FacebookConfigureOptions : ConfigureNamedOptions { - // Bind to "Google" section by default public FacebookConfigureOptions(IConfiguration config) : base(FacebookDefaults.AuthenticationScheme, options => config.GetSection(FacebookDefaults.AuthenticationScheme).Bind(options)) diff --git a/src/Microsoft.AspNetCore.Authentication.Google/GoogleConfigureOptions.cs b/src/Microsoft.AspNetCore.Authentication.Google/GoogleConfigureOptions.cs index 2c4f8f103..e19c1fdb1 100644 --- a/src/Microsoft.AspNetCore.Authentication.Google/GoogleConfigureOptions.cs +++ b/src/Microsoft.AspNetCore.Authentication.Google/GoogleConfigureOptions.cs @@ -8,7 +8,6 @@ namespace Microsoft.AspNetCore.Authentication.Google { internal class GoogleConfigureOptions : ConfigureNamedOptions { - // Bind to "Google" section by default public GoogleConfigureOptions(IConfiguration config) : base(GoogleDefaults.AuthenticationScheme, options => config.GetSection(GoogleDefaults.AuthenticationScheme).Bind(options)) From 719d8a96c0a856787b2cc23dabdb31d4d3f4e306 Mon Sep 17 00:00:00 2001 From: Hao Kung Date: Mon, 17 Apr 2017 12:30:26 -0700 Subject: [PATCH 3/3] Add tests --- .../OpenIdConnect.AzureAdSample/Startup.cs | 2 +- samples/OpenIdConnectSample/Startup.cs | 2 +- samples/SocialSample/Startup.cs | 2 +- .../FacebookExtensions.cs | 12 +-- .../GoogleExtensions.cs | 14 ++-- .../JwtBearerExtensions.cs | 14 ++-- .../MicrosoftAccountExtensions.cs | 12 +-- .../OpenIdConnectExtensions.cs | 14 ++-- .../TwitterExtensions.cs | 14 ++-- .../FacebookTests.cs | 73 ++++++++++++++++++- .../GoogleTests.cs | 67 ++++++++++++++++- .../JwtBearerTests.cs | 63 +++++++++++++++- .../MicrosoftAccountTests.cs | 69 +++++++++++++++++- .../OpenIdConnect/TestServerBuilder.cs | 2 +- .../TwitterTests.cs | 51 ++++++++++++- 15 files changed, 350 insertions(+), 61 deletions(-) diff --git a/samples/OpenIdConnect.AzureAdSample/Startup.cs b/samples/OpenIdConnect.AzureAdSample/Startup.cs index 07ed0f2b3..912fcb47f 100644 --- a/samples/OpenIdConnect.AzureAdSample/Startup.cs +++ b/samples/OpenIdConnect.AzureAdSample/Startup.cs @@ -72,7 +72,7 @@ public void ConfigureServices(IServiceCollection services) }); services.AddAuthentication(sharedOptions => - sharedOptions.DefaultAuthenticationScheme = CookieAuthenticationDefaults.AuthenticationScheme); + sharedOptions.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme); } public void Configure(IApplicationBuilder app, ILoggerFactory loggerfactory) diff --git a/samples/OpenIdConnectSample/Startup.cs b/samples/OpenIdConnectSample/Startup.cs index 27c6099b0..36133db74 100644 --- a/samples/OpenIdConnectSample/Startup.cs +++ b/samples/OpenIdConnectSample/Startup.cs @@ -71,7 +71,7 @@ public void ConfigureServices(IServiceCollection services) services.AddAuthentication(sharedOptions => { - sharedOptions.DefaultAuthenticationScheme = CookieAuthenticationDefaults.AuthenticationScheme; + sharedOptions.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme; sharedOptions.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme; }); } diff --git a/samples/SocialSample/Startup.cs b/samples/SocialSample/Startup.cs index ee6b986d3..80bde190a 100644 --- a/samples/SocialSample/Startup.cs +++ b/samples/SocialSample/Startup.cs @@ -201,7 +201,7 @@ public void ConfigureServices(IServiceCollection services) }; }); - services.AddAuthentication(options => options.DefaultAuthenticationScheme = CookieAuthenticationDefaults.AuthenticationScheme); + services.AddAuthentication(options => options.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme); } public void Configure(IApplicationBuilder app, ILoggerFactory loggerfactory) diff --git a/src/Microsoft.AspNetCore.Authentication.Facebook/FacebookExtensions.cs b/src/Microsoft.AspNetCore.Authentication.Facebook/FacebookExtensions.cs index 4450a980f..9e22e683c 100644 --- a/src/Microsoft.AspNetCore.Authentication.Facebook/FacebookExtensions.cs +++ b/src/Microsoft.AspNetCore.Authentication.Facebook/FacebookExtensions.cs @@ -16,15 +16,15 @@ public static class FacebookAuthenticationOptionsExtensions /// /// public static IServiceCollection AddFacebookAuthentication(this IServiceCollection services) - { - services.AddSingleton, FacebookConfigureOptions>(); - return services.AddFacebookAuthentication(o => { }); - } + => services.AddFacebookAuthentication(FacebookDefaults.AuthenticationScheme, _ => { }); public static IServiceCollection AddFacebookAuthentication(this IServiceCollection services, Action configureOptions) => services.AddFacebookAuthentication(FacebookDefaults.AuthenticationScheme, configureOptions); - public static IServiceCollection AddFacebookAuthentication(this IServiceCollection services, string authenticationScheme, Action configureOptions) - => services.AddScheme(authenticationScheme, configureOptions); + public static IServiceCollection AddFacebookAuthentication(this IServiceCollection services, string authenticationScheme, Action configureOptions) + { + services.AddSingleton, FacebookConfigureOptions>(); + return services.AddScheme(authenticationScheme, configureOptions); + } } } diff --git a/src/Microsoft.AspNetCore.Authentication.Google/GoogleExtensions.cs b/src/Microsoft.AspNetCore.Authentication.Google/GoogleExtensions.cs index e6c98fe3f..23fcbcec2 100644 --- a/src/Microsoft.AspNetCore.Authentication.Google/GoogleExtensions.cs +++ b/src/Microsoft.AspNetCore.Authentication.Google/GoogleExtensions.cs @@ -16,15 +16,15 @@ public static class GoogleExtensions /// /// public static IServiceCollection AddGoogleAuthentication(this IServiceCollection services) + => services.AddGoogleAuthentication(GoogleDefaults.AuthenticationScheme, _ => { }); + + public static IServiceCollection AddGoogleAuthentication(this IServiceCollection services, Action configureOptions) + => services.AddGoogleAuthentication(GoogleDefaults.AuthenticationScheme, configureOptions); + + public static IServiceCollection AddGoogleAuthentication(this IServiceCollection services, string authenticationScheme, Action configureOptions) { services.AddSingleton, GoogleConfigureOptions>(); - return services.AddGoogleAuthentication(o => { }); + return services.AddScheme(authenticationScheme, configureOptions); } - - public static IServiceCollection AddGoogleAuthentication(this IServiceCollection services, Action configureOptions) => - services.AddGoogleAuthentication(GoogleDefaults.AuthenticationScheme, configureOptions); - - public static IServiceCollection AddGoogleAuthentication(this IServiceCollection services, string authenticationScheme, Action configureOptions) => - services.AddScheme(authenticationScheme, configureOptions); } } diff --git a/src/Microsoft.AspNetCore.Authentication.JwtBearer/JwtBearerExtensions.cs b/src/Microsoft.AspNetCore.Authentication.JwtBearer/JwtBearerExtensions.cs index e7f643bfe..a1ae6e723 100644 --- a/src/Microsoft.AspNetCore.Authentication.JwtBearer/JwtBearerExtensions.cs +++ b/src/Microsoft.AspNetCore.Authentication.JwtBearer/JwtBearerExtensions.cs @@ -16,15 +16,15 @@ public static class JwtBearerExtensions /// /// public static IServiceCollection AddJwtBearerAuthentication(this IServiceCollection services) + => services.AddJwtBearerAuthentication(JwtBearerDefaults.AuthenticationScheme, _ => { }); + + public static IServiceCollection AddJwtBearerAuthentication(this IServiceCollection services, Action configureOptions) + => services.AddJwtBearerAuthentication(JwtBearerDefaults.AuthenticationScheme, configureOptions); + + public static IServiceCollection AddJwtBearerAuthentication(this IServiceCollection services, string authenticationScheme, Action configureOptions) { services.AddSingleton, JwtBearerConfigureOptions>(); - return services.AddJwtBearerAuthentication(o => { }); + return services.AddScheme(authenticationScheme, configureOptions); } - - public static IServiceCollection AddJwtBearerAuthentication(this IServiceCollection services, Action configureOptions) => - services.AddJwtBearerAuthentication(JwtBearerDefaults.AuthenticationScheme, configureOptions); - - public static IServiceCollection AddJwtBearerAuthentication(this IServiceCollection services, string authenticationScheme, Action configureOptions) => - services.AddScheme(authenticationScheme, configureOptions); } } diff --git a/src/Microsoft.AspNetCore.Authentication.MicrosoftAccount/MicrosoftAccountExtensions.cs b/src/Microsoft.AspNetCore.Authentication.MicrosoftAccount/MicrosoftAccountExtensions.cs index 0a4eb15f5..574f9372a 100644 --- a/src/Microsoft.AspNetCore.Authentication.MicrosoftAccount/MicrosoftAccountExtensions.cs +++ b/src/Microsoft.AspNetCore.Authentication.MicrosoftAccount/MicrosoftAccountExtensions.cs @@ -16,15 +16,15 @@ public static class MicrosoftAccountExtensions /// /// public static IServiceCollection AddMicrosoftAccountAuthentication(this IServiceCollection services) - { - services.AddSingleton, MicrosoftAccountConfigureOptions>(); - return services.AddMicrosoftAccountAuthentication(o => { }); - } + => services.AddMicrosoftAccountAuthentication(MicrosoftAccountDefaults.AuthenticationScheme, o => { }); public static IServiceCollection AddMicrosoftAccountAuthentication(this IServiceCollection services, Action configureOptions) => services.AddMicrosoftAccountAuthentication(MicrosoftAccountDefaults.AuthenticationScheme, configureOptions); - public static IServiceCollection AddMicrosoftAccountAuthentication(this IServiceCollection services, string authenticationScheme, Action configureOptions) => - services.AddScheme(authenticationScheme, configureOptions); + public static IServiceCollection AddMicrosoftAccountAuthentication(this IServiceCollection services, string authenticationScheme, Action configureOptions) + { + services.AddSingleton, MicrosoftAccountConfigureOptions>(); + return services.AddScheme(authenticationScheme, configureOptions); + } } } \ No newline at end of file diff --git a/src/Microsoft.AspNetCore.Authentication.OpenIdConnect/OpenIdConnectExtensions.cs b/src/Microsoft.AspNetCore.Authentication.OpenIdConnect/OpenIdConnectExtensions.cs index 18d61982a..fe6f3d218 100644 --- a/src/Microsoft.AspNetCore.Authentication.OpenIdConnect/OpenIdConnectExtensions.cs +++ b/src/Microsoft.AspNetCore.Authentication.OpenIdConnect/OpenIdConnectExtensions.cs @@ -16,19 +16,15 @@ public static class OpenIdConnectExtensions /// /// public static IServiceCollection AddOpenIdConnectAuthentication(this IServiceCollection services) - { - services.AddSingleton, OpenIdConnectConfigureOptions>(); - return services.AddOpenIdConnectAuthentication(o => { }); - } + => services.AddOpenIdConnectAuthentication(OpenIdConnectDefaults.AuthenticationScheme, _ => { }); - public static IServiceCollection AddOpenIdConnectAuthentication(this IServiceCollection services, Action configureOptions) => - services.AddOpenIdConnectAuthentication(OpenIdConnectDefaults.AuthenticationScheme, configureOptions); + public static IServiceCollection AddOpenIdConnectAuthentication(this IServiceCollection services, Action configureOptions) + => services.AddOpenIdConnectAuthentication(OpenIdConnectDefaults.AuthenticationScheme, configureOptions); public static IServiceCollection AddOpenIdConnectAuthentication(this IServiceCollection services, string authenticationScheme, Action configureOptions) { - //services.AddRemoteScheme(authenticationScheme, configureOptions, o => new PathString[] { o.CallbackPath, o.SignedOutCallbackPath, o.RemoteSignOutPath }); - services.AddScheme(authenticationScheme, configureOptions); - return services; + services.AddSingleton, OpenIdConnectConfigureOptions>(); + return services.AddScheme(authenticationScheme, configureOptions); } } } diff --git a/src/Microsoft.AspNetCore.Authentication.Twitter/TwitterExtensions.cs b/src/Microsoft.AspNetCore.Authentication.Twitter/TwitterExtensions.cs index 837f4632e..8cf0dcb4d 100644 --- a/src/Microsoft.AspNetCore.Authentication.Twitter/TwitterExtensions.cs +++ b/src/Microsoft.AspNetCore.Authentication.Twitter/TwitterExtensions.cs @@ -16,15 +16,15 @@ public static class TwitterExtensions /// /// public static IServiceCollection AddTwitterAuthentication(this IServiceCollection services) + => services.AddTwitterAuthentication(TwitterDefaults.AuthenticationScheme, _ => { }); + + public static IServiceCollection AddTwitterAuthentication(this IServiceCollection services, Action configureOptions) + => services.AddTwitterAuthentication(TwitterDefaults.AuthenticationScheme, configureOptions); + + public static IServiceCollection AddTwitterAuthentication(this IServiceCollection services, string authenticationScheme, Action configureOptions) { services.AddSingleton, TwitterConfigureOptions>(); - return services.AddTwitterAuthentication(o => { }); + return services.AddScheme(authenticationScheme, configureOptions); } - - public static IServiceCollection AddTwitterAuthentication(this IServiceCollection services, Action configureOptions) => - services.AddTwitterAuthentication(TwitterDefaults.AuthenticationScheme, configureOptions); - - public static IServiceCollection AddTwitterAuthentication(this IServiceCollection services, string authenticationScheme, Action configureOptions) => - services.AddScheme(authenticationScheme, configureOptions); } } diff --git a/test/Microsoft.AspNetCore.Authentication.Test/FacebookTests.cs b/test/Microsoft.AspNetCore.Authentication.Test/FacebookTests.cs index 89189ad2b..6c6453e27 100644 --- a/test/Microsoft.AspNetCore.Authentication.Test/FacebookTests.cs +++ b/test/Microsoft.AspNetCore.Authentication.Test/FacebookTests.cs @@ -33,7 +33,18 @@ public void AddCanBindAgainstDefaultConfig() var dic = new Dictionary { {"Facebook:AppId", ""}, - {"Facebook:AppSecret", ""} + {"Facebook:AppSecret", ""}, + {"Facebook:AuthorizationEndpoint", ""}, + {"Facebook:BackchannelTimeout", "0.0:0:30"}, + //{"Facebook:CallbackPath", "/callbackpath"}, // PathString doesn't convert + {"Facebook:ClaimsIssuer", ""}, + {"Facebook:DisplayName", ""}, + {"Facebook:RemoteAuthenticationTimeout", "0.0:0:30"}, + {"Facebook:SaveTokens", "true"}, + {"Facebook:SendAppSecretProof", "true"}, + {"Facebook:SignInScheme", ""}, + {"Facebook:TokenEndpoint", ""}, + {"Facebook:UserInformationEndpoint", ""}, }; var configurationBuilder = new ConfigurationBuilder(); configurationBuilder.AddInMemoryCollection(dic); @@ -44,6 +55,62 @@ public void AddCanBindAgainstDefaultConfig() var options = sp.GetRequiredService>().Get(FacebookDefaults.AuthenticationScheme); Assert.Equal("", options.AppId); Assert.Equal("", options.AppSecret); + Assert.Equal("", options.AuthorizationEndpoint); + Assert.Equal(new TimeSpan(0, 0, 0, 30), options.BackchannelTimeout); + //Assert.Equal("/callbackpath", options.CallbackPath); // NOTE: PathString doesn't convert + Assert.Equal("", options.ClaimsIssuer); + Assert.Equal("", options.ClientId); + Assert.Equal("", options.ClientSecret); + Assert.Equal("", options.DisplayName); + Assert.Equal(new TimeSpan(0, 0, 0, 30), options.RemoteAuthenticationTimeout); + Assert.True(options.SaveTokens); + Assert.True(options.SendAppSecretProof); + Assert.Equal("", options.SignInScheme); + Assert.Equal("", options.TokenEndpoint); + Assert.Equal("", options.UserInformationEndpoint); + } + + [Fact] + public void AddCanBindAgainstDefaultConfigAndOverride() + { + var dic = new Dictionary + { + {"Facebook:AppId", ""}, + {"Facebook:AppSecret", ""}, + {"Facebook:AuthorizationEndpoint", ""}, + {"Facebook:BackchannelTimeout", "0.0:0:30"}, + //{"Facebook:CallbackPath", "/callbackpath"}, // PathString doesn't convert + {"Facebook:ClaimsIssuer", ""}, + {"Facebook:DisplayName", ""}, + {"Facebook:RemoteAuthenticationTimeout", "0.0:0:30"}, + {"Facebook:SaveTokens", "true"}, + {"Facebook:SendAppSecretProof", "true"}, + {"Facebook:SignInScheme", ""}, + {"Facebook:TokenEndpoint", ""}, + {"Facebook:UserInformationEndpoint", ""}, + }; + var configurationBuilder = new ConfigurationBuilder(); + configurationBuilder.AddInMemoryCollection(dic); + var config = configurationBuilder.Build(); + var services = new ServiceCollection().AddFacebookAuthentication(o => o.SaveTokens = false).AddSingleton(config); + var sp = services.BuildServiceProvider(); + + var options = sp.GetRequiredService>().Get(FacebookDefaults.AuthenticationScheme); + Assert.Equal("", options.AppId); + Assert.Equal("", options.AppSecret); + Assert.Equal("", options.AuthorizationEndpoint); + Assert.Equal(new TimeSpan(0, 0, 0, 30), options.BackchannelTimeout); + //Assert.Equal("/callbackpath", options.CallbackPath); // NOTE: PathString doesn't convert + Assert.Equal("", options.ClaimsIssuer); + Assert.Equal("", options.ClientId); + Assert.Equal("", options.ClientSecret); + Assert.Equal("", options.DisplayName); + Assert.Equal(new TimeSpan(0, 0, 0, 30), options.RemoteAuthenticationTimeout); + Assert.False(options.SaveTokens); + Assert.True(options.SendAppSecretProof); + Assert.Equal("", options.SignInScheme); + Assert.Equal("", options.TokenEndpoint); + Assert.Equal("", options.UserInformationEndpoint); } [Fact] @@ -91,7 +158,7 @@ public async Task ChallengeWillTriggerApplyRedirectEvent() services.AddAuthentication(options => { options.DefaultSignInScheme = "External"; - options.DefaultAuthenticationScheme = "External"; + options.DefaultAuthenticateScheme = "External"; }); services.AddCookieAuthentication("External", o => { }); services.AddFacebookAuthentication(o => @@ -233,7 +300,7 @@ public async Task CustomUserInfoEndpointHasValidGraphQuery() services.AddAuthentication(options => { options.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme; - options.DefaultAuthenticationScheme = CookieAuthenticationDefaults.AuthenticationScheme; + options.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme; }); services.AddCookieAuthentication(); services.AddFacebookAuthentication(o => diff --git a/test/Microsoft.AspNetCore.Authentication.Test/GoogleTests.cs b/test/Microsoft.AspNetCore.Authentication.Test/GoogleTests.cs index 295e8e38f..a3de06f73 100644 --- a/test/Microsoft.AspNetCore.Authentication.Test/GoogleTests.cs +++ b/test/Microsoft.AspNetCore.Authentication.Test/GoogleTests.cs @@ -27,12 +27,23 @@ namespace Microsoft.AspNetCore.Authentication.Google public class GoogleTests { [Fact] - public void AddGoogleCanBindAgainstDefaultConfig() + public void AddCanBindAgainstDefaultConfig() { var dic = new Dictionary { {"Google:ClientId", ""}, - {"Google:ClientSecret", ""} + {"Google:ClientSecret", ""}, + {"Google:AuthorizationEndpoint", ""}, + {"Google:BackchannelTimeout", "0.0:0:30"}, + //{"Google:CallbackPath", "/callbackpath"}, // PathString doesn't convert + {"Google:ClaimsIssuer", ""}, + {"Google:DisplayName", ""}, + {"Google:RemoteAuthenticationTimeout", "0.0:0:30"}, + {"Google:SaveTokens", "true"}, + {"Google:SendAppSecretProof", "true"}, + {"Google:SignInScheme", ""}, + {"Google:TokenEndpoint", ""}, + {"Google:UserInformationEndpoint", ""}, }; var configurationBuilder = new ConfigurationBuilder(); configurationBuilder.AddInMemoryCollection(dic); @@ -41,8 +52,58 @@ public void AddGoogleCanBindAgainstDefaultConfig() var sp = services.BuildServiceProvider(); var options = sp.GetRequiredService>().Get(GoogleDefaults.AuthenticationScheme); + Assert.Equal("", options.AuthorizationEndpoint); + Assert.Equal(new TimeSpan(0, 0, 0, 30), options.BackchannelTimeout); + //Assert.Equal("/callbackpath", options.CallbackPath); // NOTE: PathString doesn't convert + Assert.Equal("", options.ClaimsIssuer); Assert.Equal("", options.ClientId); Assert.Equal("", options.ClientSecret); + Assert.Equal("", options.DisplayName); + Assert.Equal(new TimeSpan(0, 0, 0, 30), options.RemoteAuthenticationTimeout); + Assert.True(options.SaveTokens); + Assert.Equal("", options.SignInScheme); + Assert.Equal("", options.TokenEndpoint); + Assert.Equal("", options.UserInformationEndpoint); + } + + [Fact] + public void AddCanBindAgainstDefaultConfigAndOverride() + { + var dic = new Dictionary + { + {"Google:ClientId", ""}, + {"Google:ClientSecret", ""}, + {"Google:AuthorizationEndpoint", ""}, + {"Google:BackchannelTimeout", "0.0:0:30"}, + //{"Google:CallbackPath", "/callbackpath"}, // PathString doesn't convert + {"Google:ClaimsIssuer", ""}, + {"Google:DisplayName", ""}, + {"Google:RemoteAuthenticationTimeout", "0.0:0:30"}, + {"Google:SaveTokens", "true"}, + {"Google:SendAppSecretProof", "true"}, + {"Google:SignInScheme", ""}, + {"Google:TokenEndpoint", ""}, + {"Google:UserInformationEndpoint", ""}, + }; + var configurationBuilder = new ConfigurationBuilder(); + configurationBuilder.AddInMemoryCollection(dic); + var config = configurationBuilder.Build(); + var services = new ServiceCollection().AddGoogleAuthentication(o => o.SaveTokens = false).AddSingleton(config); + var sp = services.BuildServiceProvider(); + + var options = sp.GetRequiredService>().Get(GoogleDefaults.AuthenticationScheme); + Assert.Equal("", options.AuthorizationEndpoint); + Assert.Equal(new TimeSpan(0, 0, 0, 30), options.BackchannelTimeout); + //Assert.Equal("/callbackpath", options.CallbackPath); // NOTE: PathString doesn't convert + Assert.Equal("", options.ClaimsIssuer); + Assert.Equal("", options.ClientId); + Assert.Equal("", options.ClientSecret); + Assert.Equal("", options.DisplayName); + Assert.Equal(new TimeSpan(0, 0, 0, 30), options.RemoteAuthenticationTimeout); + Assert.False(options.SaveTokens); + Assert.Equal("", options.SignInScheme); + Assert.Equal("", options.TokenEndpoint); + Assert.Equal("", options.UserInformationEndpoint); } [Fact] @@ -1092,7 +1153,7 @@ private static TestServer CreateServer(Action configureOptions, F services.AddTransient(); services.AddAuthentication(o => { - o.DefaultAuthenticationScheme = TestExtensions.CookieAuthenticationScheme; + o.DefaultAuthenticateScheme = TestExtensions.CookieAuthenticationScheme; o.DefaultSignInScheme = TestExtensions.CookieAuthenticationScheme; o.DefaultChallengeScheme = GoogleDefaults.AuthenticationScheme; }); diff --git a/test/Microsoft.AspNetCore.Authentication.Test/JwtBearerTests.cs b/test/Microsoft.AspNetCore.Authentication.Test/JwtBearerTests.cs index ce746cb42..553fba038 100644 --- a/test/Microsoft.AspNetCore.Authentication.Test/JwtBearerTests.cs +++ b/test/Microsoft.AspNetCore.Authentication.Test/JwtBearerTests.cs @@ -31,8 +31,17 @@ public void AddCanBindAgainstDefaultConfig() { var dic = new Dictionary { - {"Bearer:Audience", ""}, - {"Bearer:Authority", ""} + {"Bearer:Audience", ""}, + {"Bearer:Authority", ""}, + {"Bearer:BackchannelTimeout", "0.0:0:30"}, + {"Bearer:Challenge", ""}, + {"Bearer:ClaimsIssuer", ""}, + {"Bearer:DisplayName", ""}, + {"Bearer:IncludeErrorDetails", "true"}, + {"Bearer:MetadataAddress", ""}, + {"Bearer:RefreshOnIssuerKeyNotFound", "true"}, + {"Bearer:RequireHttpsMetadata", "true"}, + {"Bearer:SaveToken", "true"}, }; var configurationBuilder = new ConfigurationBuilder(); configurationBuilder.AddInMemoryCollection(dic); @@ -41,8 +50,54 @@ public void AddCanBindAgainstDefaultConfig() var sp = services.BuildServiceProvider(); var options = sp.GetRequiredService>().Get(JwtBearerDefaults.AuthenticationScheme); - Assert.Equal("", options.Audience); - Assert.Equal("", options.Authority); + Assert.Equal(new TimeSpan(0, 0, 0, 30), options.BackchannelTimeout); + Assert.Equal("", options.Audience); + Assert.Equal("", options.Authority); + Assert.Equal("", options.Challenge); + Assert.Equal("", options.ClaimsIssuer); + Assert.Equal("", options.DisplayName); + Assert.True(options.IncludeErrorDetails); + Assert.Equal("", options.MetadataAddress); + Assert.True(options.RefreshOnIssuerKeyNotFound); + Assert.True(options.RequireHttpsMetadata); + Assert.True(options.SaveToken); + } + + [Fact] + public void AddCanBindAgainstDefaultConfigAndOverride() + { + var dic = new Dictionary + { + {"Bearer:Audience", ""}, + {"Bearer:Authority", ""}, + {"Bearer:BackchannelTimeout", "0.0:0:30"}, + {"Bearer:Challenge", ""}, + {"Bearer:ClaimsIssuer", ""}, + {"Bearer:DisplayName", ""}, + {"Bearer:IncludeErrorDetails", "true"}, + {"Bearer:MetadataAddress", ""}, + {"Bearer:RefreshOnIssuerKeyNotFound", "true"}, + {"Bearer:RequireHttpsMetadata", "true"}, + {"Bearer:SaveToken", "true"}, + }; + var configurationBuilder = new ConfigurationBuilder(); + configurationBuilder.AddInMemoryCollection(dic); + var config = configurationBuilder.Build(); + var services = new ServiceCollection().AddJwtBearerAuthentication(o => o.IncludeErrorDetails = false).AddSingleton(config); + var sp = services.BuildServiceProvider(); + + var options = sp.GetRequiredService>().Get(JwtBearerDefaults.AuthenticationScheme); + Assert.Equal(new TimeSpan(0, 0, 0, 30), options.BackchannelTimeout); + Assert.Equal("", options.Audience); + Assert.Equal("", options.Authority); + Assert.Equal("", options.Challenge); + Assert.Equal("", options.ClaimsIssuer); + Assert.Equal("", options.DisplayName); + Assert.False(options.IncludeErrorDetails); + Assert.Equal("", options.MetadataAddress); + Assert.True(options.RefreshOnIssuerKeyNotFound); + Assert.True(options.RequireHttpsMetadata); + Assert.True(options.SaveToken); } [ConditionalFact(Skip = "Need to remove dependency on AAD since the generated tokens will expire")] diff --git a/test/Microsoft.AspNetCore.Authentication.Test/MicrosoftAccountTests.cs b/test/Microsoft.AspNetCore.Authentication.Test/MicrosoftAccountTests.cs index 72e6a89d5..af0736b5b 100644 --- a/test/Microsoft.AspNetCore.Authentication.Test/MicrosoftAccountTests.cs +++ b/test/Microsoft.AspNetCore.Authentication.Test/MicrosoftAccountTests.cs @@ -33,7 +33,18 @@ public void AddCanBindAgainstDefaultConfig() var dic = new Dictionary { {"Microsoft:ClientId", ""}, - {"Microsoft:ClientSecret", ""} + {"Microsoft:ClientSecret", ""}, + {"Microsoft:AuthorizationEndpoint", ""}, + {"Microsoft:BackchannelTimeout", "0.0:0:30"}, + //{"Microsoft:CallbackPath", "/callbackpath"}, // PathString doesn't convert + {"Microsoft:ClaimsIssuer", ""}, + {"Microsoft:DisplayName", ""}, + {"Microsoft:RemoteAuthenticationTimeout", "0.0:0:30"}, + {"Microsoft:SaveTokens", "true"}, + {"Microsoft:SendAppSecretProof", "true"}, + {"Microsoft:SignInScheme", ""}, + {"Microsoft:TokenEndpoint", ""}, + {"Microsoft:UserInformationEndpoint", ""}, }; var configurationBuilder = new ConfigurationBuilder(); configurationBuilder.AddInMemoryCollection(dic); @@ -41,11 +52,61 @@ public void AddCanBindAgainstDefaultConfig() var services = new ServiceCollection().AddMicrosoftAccountAuthentication().AddSingleton(config); var sp = services.BuildServiceProvider(); - var options = sp.GetRequiredService>().Get("Microsoft"); + var options = sp.GetRequiredService>().Get(MicrosoftAccountDefaults.AuthenticationScheme); + Assert.Equal("", options.AuthorizationEndpoint); + Assert.Equal(new TimeSpan(0, 0, 0, 30), options.BackchannelTimeout); + //Assert.Equal("/callbackpath", options.CallbackPath); // NOTE: PathString doesn't convert + Assert.Equal("", options.ClaimsIssuer); Assert.Equal("", options.ClientId); Assert.Equal("", options.ClientSecret); + Assert.Equal("", options.DisplayName); + Assert.Equal(new TimeSpan(0, 0, 0, 30), options.RemoteAuthenticationTimeout); + Assert.True(options.SaveTokens); + Assert.Equal("", options.SignInScheme); + Assert.Equal("", options.TokenEndpoint); + Assert.Equal("", options.UserInformationEndpoint); } - + + [Fact] + public void AddCanBindAgainstDefaultConfigAndOverride() + { + var dic = new Dictionary + { + {"Microsoft:ClientId", ""}, + {"Microsoft:ClientSecret", ""}, + {"Microsoft:AuthorizationEndpoint", ""}, + {"Microsoft:BackchannelTimeout", "0.0:0:30"}, + //{"Microsoft:CallbackPath", "/callbackpath"}, // PathString doesn't convert + {"Microsoft:ClaimsIssuer", ""}, + {"Microsoft:DisplayName", ""}, + {"Microsoft:RemoteAuthenticationTimeout", "0.0:0:30"}, + {"Microsoft:SaveTokens", "true"}, + {"Microsoft:SendAppSecretProof", "true"}, + {"Microsoft:SignInScheme", ""}, + {"Microsoft:TokenEndpoint", ""}, + {"Microsoft:UserInformationEndpoint", ""}, + }; + var configurationBuilder = new ConfigurationBuilder(); + configurationBuilder.AddInMemoryCollection(dic); + var config = configurationBuilder.Build(); + var services = new ServiceCollection().AddMicrosoftAccountAuthentication(o => o.SaveTokens = false).AddSingleton(config); + var sp = services.BuildServiceProvider(); + + var options = sp.GetRequiredService>().Get(MicrosoftAccountDefaults.AuthenticationScheme); + Assert.Equal("", options.AuthorizationEndpoint); + Assert.Equal(new TimeSpan(0, 0, 0, 30), options.BackchannelTimeout); + //Assert.Equal("/callbackpath", options.CallbackPath); // NOTE: PathString doesn't convert + Assert.Equal("", options.ClaimsIssuer); + Assert.Equal("", options.ClientId); + Assert.Equal("", options.ClientSecret); + Assert.Equal("", options.DisplayName); + Assert.Equal(new TimeSpan(0, 0, 0, 30), options.RemoteAuthenticationTimeout); + Assert.False(options.SaveTokens); + Assert.Equal("", options.SignInScheme); + Assert.Equal("", options.TokenEndpoint); + Assert.Equal("", options.UserInformationEndpoint); + } + [Fact] public async Task ChallengeWillTriggerApplyRedirectEvent() { @@ -232,7 +293,7 @@ private static TestServer CreateServer(Action configure { services.AddAuthentication(o => { - o.DefaultAuthenticationScheme = TestExtensions.CookieAuthenticationScheme; + o.DefaultAuthenticateScheme = TestExtensions.CookieAuthenticationScheme; o.DefaultSignInScheme = TestExtensions.CookieAuthenticationScheme; }); services.AddCookieAuthentication(TestExtensions.CookieAuthenticationScheme, o => { }); diff --git a/test/Microsoft.AspNetCore.Authentication.Test/OpenIdConnect/TestServerBuilder.cs b/test/Microsoft.AspNetCore.Authentication.Test/OpenIdConnect/TestServerBuilder.cs index 66bd5a6d1..aa7f6179b 100644 --- a/test/Microsoft.AspNetCore.Authentication.Test/OpenIdConnect/TestServerBuilder.cs +++ b/test/Microsoft.AspNetCore.Authentication.Test/OpenIdConnect/TestServerBuilder.cs @@ -111,7 +111,7 @@ await context.SignOutAsync( { services.AddAuthentication(o => { - o.DefaultAuthenticationScheme = CookieAuthenticationDefaults.AuthenticationScheme; + o.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme; o.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme; }); services.AddCookieAuthentication(); diff --git a/test/Microsoft.AspNetCore.Authentication.Test/TwitterTests.cs b/test/Microsoft.AspNetCore.Authentication.Test/TwitterTests.cs index 58b64c060..c1c5a6357 100644 --- a/test/Microsoft.AspNetCore.Authentication.Test/TwitterTests.cs +++ b/test/Microsoft.AspNetCore.Authentication.Test/TwitterTests.cs @@ -26,7 +26,15 @@ public void AddCanBindAgainstDefaultConfig() var dic = new Dictionary { {"Twitter:ConsumerKey", ""}, - {"Twitter:ConsumerSecret", ""} + {"Twitter:ConsumerSecret", ""}, + {"Twitter:BackchannelTimeout", "0.0:0:30"}, + //{"Twitter:CallbackPath", "/callbackpath"}, // PathString doesn't convert + {"Twitter:ClaimsIssuer", ""}, + {"Twitter:DisplayName", ""}, + {"Twitter:RemoteAuthenticationTimeout", "0.0:0:30"}, + {"Twitter:SaveTokens", "true"}, + {"Twitter:SendAppSecretProof", "true"}, + {"Twitter:SignInScheme", ""}, }; var configurationBuilder = new ConfigurationBuilder(); configurationBuilder.AddInMemoryCollection(dic); @@ -35,8 +43,49 @@ public void AddCanBindAgainstDefaultConfig() var sp = services.BuildServiceProvider(); var options = sp.GetRequiredService>().Get(TwitterDefaults.AuthenticationScheme); + Assert.Equal(new TimeSpan(0, 0, 0, 30), options.BackchannelTimeout); + //Assert.Equal("/callbackpath", options.CallbackPath); // NOTE: PathString doesn't convert + Assert.Equal("", options.ClaimsIssuer); Assert.Equal("", options.ConsumerKey); Assert.Equal("", options.ConsumerSecret); + Assert.Equal("", options.DisplayName); + Assert.Equal(new TimeSpan(0, 0, 0, 30), options.RemoteAuthenticationTimeout); + Assert.True(options.SaveTokens); + Assert.Equal("", options.SignInScheme); + } + + [Fact] + public void AddCanBindAgainstDefaultConfigAndOverride() + { + var dic = new Dictionary + { + {"Twitter:ConsumerKey", ""}, + {"Twitter:ConsumerSecret", ""}, + {"Twitter:BackchannelTimeout", "0.0:0:30"}, + //{"Twitter:CallbackPath", "/callbackpath"}, // PathString doesn't convert + {"Twitter:ClaimsIssuer", ""}, + {"Twitter:DisplayName", ""}, + {"Twitter:RemoteAuthenticationTimeout", "0.0:0:30"}, + {"Twitter:SaveTokens", "true"}, + {"Twitter:SendAppSecretProof", "true"}, + {"Twitter:SignInScheme", ""}, + }; + var configurationBuilder = new ConfigurationBuilder(); + configurationBuilder.AddInMemoryCollection(dic); + var config = configurationBuilder.Build(); + var services = new ServiceCollection().AddTwitterAuthentication(o => o.SaveTokens = false).AddSingleton(config); + var sp = services.BuildServiceProvider(); + + var options = sp.GetRequiredService>().Get(TwitterDefaults.AuthenticationScheme); + Assert.Equal(new TimeSpan(0, 0, 0, 30), options.BackchannelTimeout); + //Assert.Equal("/callbackpath", options.CallbackPath); // NOTE: PathString doesn't convert + Assert.Equal("", options.ClaimsIssuer); + Assert.Equal("", options.ConsumerKey); + Assert.Equal("", options.ConsumerSecret); + Assert.Equal("", options.DisplayName); + Assert.Equal(new TimeSpan(0, 0, 0, 30), options.RemoteAuthenticationTimeout); + Assert.False(options.SaveTokens); + Assert.Equal("", options.SignInScheme); } [Fact]