diff --git a/src/Microsoft.AspNetCore.Authentication.Abstractions/AuthenticationOptions.cs b/src/Microsoft.AspNetCore.Authentication.Abstractions/AuthenticationOptions.cs
index 9e1df2b455..4322dbebe1 100644
--- a/src/Microsoft.AspNetCore.Authentication.Abstractions/AuthenticationOptions.cs
+++ b/src/Microsoft.AspNetCore.Authentication.Abstractions/AuthenticationOptions.cs
@@ -60,6 +60,11 @@ namespace Microsoft.AspNetCore.Authentication
b.HandlerType = typeof(THandler);
});
+ ///
+ /// Used by as the fallback default scheme for all the other defaults."/>.
+ ///
+ public string DefaultScheme { get; set; }
+
///
/// Used by as the default scheme by .
///
diff --git a/src/Microsoft.AspNetCore.Authentication.Abstractions/IAuthenticationSchemeProvider.cs b/src/Microsoft.AspNetCore.Authentication.Abstractions/IAuthenticationSchemeProvider.cs
index 675cf52cf9..3d2584fca8 100644
--- a/src/Microsoft.AspNetCore.Authentication.Abstractions/IAuthenticationSchemeProvider.cs
+++ b/src/Microsoft.AspNetCore.Authentication.Abstractions/IAuthenticationSchemeProvider.cs
@@ -28,7 +28,7 @@ namespace Microsoft.AspNetCore.Authentication
///
/// Returns the scheme that will be used by default for .
/// This is typically specified via .
- /// Otherwise, if only a single scheme exists, that will be used, if more than one exists, null will be returned.
+ /// Otherwise, this will fallback to .
///
/// The scheme that will be used by default for .
Task GetDefaultAuthenticateSchemeAsync();
@@ -36,7 +36,7 @@ namespace Microsoft.AspNetCore.Authentication
///
/// Returns the scheme that will be used by default for .
/// This is typically specified via .
- /// Otherwise, if only a single scheme exists, that will be used, if more than one exists, null will be returned.
+ /// Otherwise, this will fallback to .
///
/// The scheme that will be used by default for .
Task GetDefaultChallengeSchemeAsync();
@@ -52,7 +52,7 @@ namespace Microsoft.AspNetCore.Authentication
///
/// Returns the scheme that will be used by default for .
/// This is typically specified via .
- /// Otherwise, if only a single scheme exists, that will be used, if more than one exists, null will be returned.
+ /// Otherwise, this will fallback to .
///
/// The scheme that will be used by default for .
Task GetDefaultSignInSchemeAsync();
diff --git a/src/Microsoft.AspNetCore.Authentication.Core/AuthenticationSchemeProvider.cs b/src/Microsoft.AspNetCore.Authentication.Core/AuthenticationSchemeProvider.cs
index be02a5c396..f5ec8e1598 100644
--- a/src/Microsoft.AspNetCore.Authentication.Core/AuthenticationSchemeProvider.cs
+++ b/src/Microsoft.AspNetCore.Authentication.Core/AuthenticationSchemeProvider.cs
@@ -3,7 +3,6 @@
using System;
using System.Collections.Generic;
-using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Options;
@@ -35,42 +34,33 @@ namespace Microsoft.AspNetCore.Authentication
private IDictionary _map = new Dictionary(StringComparer.Ordinal);
private List _requestHandlers = new List();
- private List _signOutHandlers = new List();
- private List _signInHandlers = new List();
+
+ private Task GetDefaultSchemeAsync()
+ => _options.DefaultScheme != null
+ ? GetSchemeAsync(_options.DefaultScheme)
+ : Task.FromResult(null);
///
/// Returns the scheme that will be used by default for .
/// This is typically specified via .
- /// Otherwise, if only a single scheme exists, that will be used, if more than one exists, null will be returned.
+ /// Otherwise, this will fallback to .
///
/// The scheme that will be used by default for .
public virtual Task GetDefaultAuthenticateSchemeAsync()
- {
- if (_options.DefaultAuthenticateScheme != null)
- {
- return GetSchemeAsync(_options.DefaultAuthenticateScheme);
- }
- if (_map.Count == 1)
- {
- return Task.FromResult(_map.Values.First());
- }
- return Task.FromResult(null);
- }
+ => _options.DefaultAuthenticateScheme != null
+ ? GetSchemeAsync(_options.DefaultAuthenticateScheme)
+ : GetDefaultSchemeAsync();
///
/// Returns the scheme that will be used by default for .
/// This is typically specified via .
- /// Otherwise, this will fallback to .
+ /// Otherwise, this will fallback to .
///
/// The scheme that will be used by default for .
public virtual Task GetDefaultChallengeSchemeAsync()
- {
- if (_options.DefaultChallengeScheme != null)
- {
- return GetSchemeAsync(_options.DefaultChallengeScheme);
- }
- return GetDefaultAuthenticateSchemeAsync();
- }
+ => _options.DefaultChallengeScheme != null
+ ? GetSchemeAsync(_options.DefaultChallengeScheme)
+ : GetDefaultSchemeAsync();
///
/// Returns the scheme that will be used by default for .
@@ -79,53 +69,31 @@ namespace Microsoft.AspNetCore.Authentication
///
/// The scheme that will be used by default for .
public virtual Task GetDefaultForbidSchemeAsync()
- {
- if (_options.DefaultForbidScheme != null)
- {
- return GetSchemeAsync(_options.DefaultForbidScheme);
- }
- return GetDefaultChallengeSchemeAsync();
- }
+ => _options.DefaultForbidScheme != null
+ ? GetSchemeAsync(_options.DefaultForbidScheme)
+ : GetDefaultChallengeSchemeAsync();
///
/// Returns the scheme that will be used by default for .
/// This is typically specified via .
- /// If only a single sign in handler scheme exists, that will be used, if more than one exists,
- /// this will fallback to .
+ /// Otherwise, this will fallback to .
///
/// The scheme that will be used by default for .
public virtual Task GetDefaultSignInSchemeAsync()
- {
- if (_options.DefaultSignInScheme != null)
- {
- return GetSchemeAsync(_options.DefaultSignInScheme);
- }
- if (_signInHandlers.Count == 1)
- {
- return Task.FromResult(_signInHandlers[0]);
- }
- return GetDefaultAuthenticateSchemeAsync();
- }
+ => _options.DefaultSignInScheme != null
+ ? GetSchemeAsync(_options.DefaultSignInScheme)
+ : GetDefaultSchemeAsync();
///
/// Returns the scheme that will be used by default for .
/// This is typically specified via .
- /// If only a single sign out handler scheme exists, that will be used, if more than one exists,
- /// this will fallback to if that supoorts sign out.
+ /// Otherwise this will fallback to if that supoorts sign out.
///
/// The scheme that will be used by default for .
public virtual Task GetDefaultSignOutSchemeAsync()
- {
- if (_options.DefaultSignOutScheme != null)
- {
- return GetSchemeAsync(_options.DefaultSignOutScheme);
- }
- if (_signOutHandlers.Count == 1)
- {
- return Task.FromResult(_signOutHandlers[0]);
- }
- return GetDefaultSignInSchemeAsync();
- }
+ => _options.DefaultSignOutScheme != null
+ ? GetSchemeAsync(_options.DefaultSignOutScheme)
+ : GetDefaultSignInSchemeAsync();
///
/// Returns the matching the name, or null.
@@ -133,22 +101,14 @@ namespace Microsoft.AspNetCore.Authentication
/// The name of the authenticationScheme.
/// The scheme or null if not found.
public virtual Task GetSchemeAsync(string name)
- {
- if (_map.ContainsKey(name))
- {
- return Task.FromResult(_map[name]);
- }
- return Task.FromResult(null);
- }
+ => Task.FromResult(_map.ContainsKey(name) ? _map[name] : null);
///
/// Returns the schemes in priority order for request handling.
///
/// The schemes in priority order for request handling
public virtual Task> GetRequestHandlerSchemesAsync()
- {
- return Task.FromResult>(_requestHandlers);
- }
+ => Task.FromResult>(_requestHandlers);
///
/// Registers a scheme for use by .
@@ -170,14 +130,6 @@ namespace Microsoft.AspNetCore.Authentication
{
_requestHandlers.Add(scheme);
}
- if (typeof(IAuthenticationSignInHandler).IsAssignableFrom(scheme.HandlerType))
- {
- _signInHandlers.Add(scheme);
- }
- if (typeof(IAuthenticationSignOutHandler).IsAssignableFrom(scheme.HandlerType))
- {
- _signOutHandlers.Add(scheme);
- }
_map[scheme.Name] = scheme;
}
}
@@ -198,8 +150,6 @@ namespace Microsoft.AspNetCore.Authentication
{
var scheme = _map[name];
_requestHandlers.Remove(scheme);
- _signInHandlers.Remove(scheme);
- _signOutHandlers.Remove(scheme);
_map.Remove(name);
}
}
diff --git a/test/Microsoft.AspNetCore.Authentication.Core.Test/AuthenticationSchemeProviderTests.cs b/test/Microsoft.AspNetCore.Authentication.Core.Test/AuthenticationSchemeProviderTests.cs
index fc647138d5..4fa0ea8782 100644
--- a/test/Microsoft.AspNetCore.Authentication.Core.Test/AuthenticationSchemeProviderTests.cs
+++ b/test/Microsoft.AspNetCore.Authentication.Core.Test/AuthenticationSchemeProviderTests.cs
@@ -13,6 +13,40 @@ namespace Microsoft.AspNetCore.Authentication
{
public class AuthenticationSchemeProviderTests
{
+ [Fact]
+ public async Task NoDefaultsByDefault()
+ {
+ var services = new ServiceCollection().AddOptions().AddAuthenticationCore(o =>
+ {
+ o.AddScheme("B", "whatever");
+ }).BuildServiceProvider();
+
+ var provider = services.GetRequiredService();
+ Assert.Null(await provider.GetDefaultForbidSchemeAsync());
+ Assert.Null(await provider.GetDefaultAuthenticateSchemeAsync());
+ Assert.Null(await provider.GetDefaultChallengeSchemeAsync());
+ Assert.Null(await provider.GetDefaultSignInSchemeAsync());
+ Assert.Null(await provider.GetDefaultSignOutSchemeAsync());
+ }
+
+ [Fact]
+ public async Task DefaultSchemesFallbackToDefaultScheme()
+ {
+ var services = new ServiceCollection().AddOptions().AddAuthenticationCore(o =>
+ {
+ o.DefaultScheme = "B";
+ o.AddScheme("B", "whatever");
+ }).BuildServiceProvider();
+
+ var provider = services.GetRequiredService();
+ Assert.Equal("B", (await provider.GetDefaultForbidSchemeAsync()).Name);
+ Assert.Equal("B", (await provider.GetDefaultAuthenticateSchemeAsync()).Name);
+ Assert.Equal("B", (await provider.GetDefaultChallengeSchemeAsync()).Name);
+ Assert.Equal("B", (await provider.GetDefaultSignInSchemeAsync()).Name);
+ Assert.Equal("B", (await provider.GetDefaultSignOutSchemeAsync()).Name);
+ }
+
+
[Fact]
public async Task DefaultSignOutFallsbackToSignIn()
{
@@ -45,40 +79,6 @@ namespace Microsoft.AspNetCore.Authentication
Assert.Equal("challenge", scheme.Name);
}
- [Fact]
- public async Task DefaultSchemesFallbackToOnlyScheme()
- {
- var services = new ServiceCollection().AddOptions().AddAuthenticationCore(o =>
- {
- o.AddScheme("single", "whatever");
- }).BuildServiceProvider();
-
- var provider = services.GetRequiredService();
- Assert.Equal("single", (await provider.GetDefaultForbidSchemeAsync()).Name);
- Assert.Equal("single", (await provider.GetDefaultAuthenticateSchemeAsync()).Name);
- Assert.Equal("single", (await provider.GetDefaultChallengeSchemeAsync()).Name);
- Assert.Equal("single", (await provider.GetDefaultSignInSchemeAsync()).Name);
- Assert.Equal("single", (await provider.GetDefaultSignOutSchemeAsync()).Name);
- }
-
- [Fact]
- public async Task DefaultSchemesFallbackToAuthenticateScheme()
- {
- var services = new ServiceCollection().AddOptions().AddAuthenticationCore(o =>
- {
- o.DefaultAuthenticateScheme = "B";
- o.AddScheme("A", "whatever");
- o.AddScheme("B", "whatever");
- }).BuildServiceProvider();
-
- var provider = services.GetRequiredService();
- Assert.Equal("B", (await provider.GetDefaultForbidSchemeAsync()).Name);
- Assert.Equal("B", (await provider.GetDefaultAuthenticateSchemeAsync()).Name);
- Assert.Equal("B", (await provider.GetDefaultChallengeSchemeAsync()).Name);
- Assert.Equal("B", (await provider.GetDefaultSignInSchemeAsync()).Name);
- Assert.Equal("B", (await provider.GetDefaultSignOutSchemeAsync()).Name);
- }
-
[Fact]
public async Task DefaultSchemesAreSet()
{
@@ -87,6 +87,8 @@ namespace Microsoft.AspNetCore.Authentication
o.AddScheme("A", "whatever");
o.AddScheme("B", "whatever");
o.AddScheme("C", "whatever");
+ o.AddScheme("Def", "whatever");
+ o.DefaultScheme = "Def";
o.DefaultChallengeScheme = "A";
o.DefaultForbidScheme = "B";
o.DefaultSignInScheme = "C";
@@ -102,25 +104,6 @@ namespace Microsoft.AspNetCore.Authentication
Assert.Equal("A", (await provider.GetDefaultSignOutSchemeAsync()).Name);
}
- [Fact]
- public async Task SignInSignOutDefaultsToOnlyOne()
- {
- var services = new ServiceCollection().AddOptions().AddAuthenticationCore(o =>
- {
- o.AddScheme("basic", "whatever");
- o.AddScheme("signout", "whatever");
- o.AddScheme("signin", "whatever");
- o.DefaultAuthenticateScheme = "basic";
- }).BuildServiceProvider();
-
- var provider = services.GetRequiredService();
- Assert.Equal("basic", (await provider.GetDefaultForbidSchemeAsync()).Name);
- Assert.Equal("basic", (await provider.GetDefaultAuthenticateSchemeAsync()).Name);
- Assert.Equal("basic", (await provider.GetDefaultChallengeSchemeAsync()).Name);
- Assert.Equal("signin", (await provider.GetDefaultSignInSchemeAsync()).Name);
- Assert.Equal("signin", (await provider.GetDefaultSignOutSchemeAsync()).Name); // Defaults to single sign in scheme
- }
-
[Fact]
public async Task SignOutWillDefaultsToSignInThatDoesNotSignOut()
{
diff --git a/test/Microsoft.AspNetCore.Authentication.Core.Test/AuthenticationServiceTests.cs b/test/Microsoft.AspNetCore.Authentication.Core.Test/AuthenticationServiceTests.cs
index 471053e6b0..c9fe57d970 100644
--- a/test/Microsoft.AspNetCore.Authentication.Core.Test/AuthenticationServiceTests.cs
+++ b/test/Microsoft.AspNetCore.Authentication.Core.Test/AuthenticationServiceTests.cs
@@ -56,6 +56,7 @@ namespace Microsoft.AspNetCore.Authentication
var services = new ServiceCollection().AddOptions().AddAuthenticationCore(o =>
{
o.AddScheme("base", "whatever");
+ o.DefaultScheme = "base";
}).BuildServiceProvider();
var context = new DefaultHttpContext();
context.RequestServices = services;
@@ -73,6 +74,7 @@ namespace Microsoft.AspNetCore.Authentication
var services = new ServiceCollection().AddOptions().AddAuthenticationCore(o =>
{
o.AddScheme("base", "whatever");
+ o.DefaultScheme = "base";
}).BuildServiceProvider();
var context = new DefaultHttpContext();
context.RequestServices = services;
@@ -90,6 +92,7 @@ namespace Microsoft.AspNetCore.Authentication
var services = new ServiceCollection().AddOptions().AddAuthenticationCore(o =>
{
o.AddScheme("base", "whatever");
+ o.DefaultScheme = "base";
}).BuildServiceProvider();
var context = new DefaultHttpContext();
context.RequestServices = services;
@@ -107,6 +110,7 @@ namespace Microsoft.AspNetCore.Authentication
var services = new ServiceCollection().AddOptions().AddAuthenticationCore(o =>
{
o.AddScheme("base", "whatever");
+ o.DefaultScheme = "base";
}).BuildServiceProvider();
var context = new DefaultHttpContext();
context.RequestServices = services;
diff --git a/test/Microsoft.AspNetCore.Authentication.Core.Test/TokenExtensionTests.cs b/test/Microsoft.AspNetCore.Authentication.Core.Test/TokenExtensionTests.cs
index d8f25f9509..21b78e5276 100644
--- a/test/Microsoft.AspNetCore.Authentication.Core.Test/TokenExtensionTests.cs
+++ b/test/Microsoft.AspNetCore.Authentication.Core.Test/TokenExtensionTests.cs
@@ -129,7 +129,11 @@ namespace Microsoft.AspNetCore.Authentication
{
var context = new DefaultHttpContext();
var services = new ServiceCollection().AddOptions()
- .AddAuthenticationCore(o => o.AddScheme("simple", s => s.HandlerType = typeof(SimpleAuth)));
+ .AddAuthenticationCore(o =>
+ {
+ o.DefaultScheme = "simple";
+ o.AddScheme("simple", s => s.HandlerType = typeof(SimpleAuth));
+ });
context.RequestServices = services.BuildServiceProvider();
Assert.Equal("1", await context.GetTokenAsync("One"));