Add new default schemes + tests (#870)

This commit is contained in:
Hao Kung 2017-06-14 12:57:45 -07:00 committed by GitHub
parent b059bcc426
commit df5c6730f7
4 changed files with 189 additions and 0 deletions

View File

@ -47,6 +47,19 @@ namespace Microsoft.AspNetCore.Authentication
SchemeMap[name] = builder;
}
/// <summary>
/// Adds an <see cref="AuthenticationScheme"/>.
/// </summary>
/// <typeparam name="THandler">The <see cref="IAuthenticationHandler"/> responsible for the scheme.</typeparam>
/// <param name="name">The name of the scheme being added.</param>
/// <param name="displayName">The display name for the scheme.</param>
public void AddScheme<THandler>(string name, string displayName) where THandler : IAuthenticationHandler
=> AddScheme(name, b =>
{
b.DisplayName = displayName;
b.HandlerType = typeof(THandler);
});
/// <summary>
/// Used by as the default scheme by <see cref="IAuthenticationService.AuthenticateAsync(HttpContext, string)"/>.
/// </summary>
@ -57,9 +70,19 @@ namespace Microsoft.AspNetCore.Authentication
/// </summary>
public string DefaultSignInScheme { get; set; }
/// <summary>
/// Used by as the default scheme by <see cref="IAuthenticationService.SignOutAsync(HttpContext, string, AuthenticationProperties)"/>.
/// </summary>
public string DefaultSignOutScheme { get; set; }
/// <summary>
/// Used by as the default scheme by <see cref="IAuthenticationService.ChallengeAsync(HttpContext, string, AuthenticationProperties)"/>.
/// </summary>
public string DefaultChallengeScheme { get; set; }
/// <summary>
/// Used by as the default scheme by <see cref="IAuthenticationService.ForbidAsync(HttpContext, string, AuthenticationProperties)"/>.
/// </summary>
public string DefaultForbidScheme { get; set; }
}
}

View File

@ -41,6 +41,14 @@ namespace Microsoft.AspNetCore.Authentication
/// <returns>The scheme that will be used by default for <see cref="IAuthenticationService.ChallengeAsync(HttpContext, string, AuthenticationProperties)"/>.</returns>
Task<AuthenticationScheme> GetDefaultChallengeSchemeAsync();
/// <summary>
/// Returns the scheme that will be used by default for <see cref="IAuthenticationService.ForbidAsync(HttpContext, string, AuthenticationProperties)"/>.
/// This is typically specified via <see cref="AuthenticationOptions.DefaultForbidScheme"/>.
/// Otherwise, this will fallback to <see cref="GetDefaultChallengeSchemeAsync"/> .
/// </summary>
/// <returns>The scheme that will be used by default for <see cref="IAuthenticationService.ForbidAsync(HttpContext, string, AuthenticationProperties)"/>.</returns>
Task<AuthenticationScheme> GetDefaultForbidSchemeAsync();
/// <summary>
/// Returns the scheme that will be used by default for <see cref="IAuthenticationService.SignInAsync(HttpContext, string, System.Security.Claims.ClaimsPrincipal, AuthenticationProperties)"/>.
/// This is typically specified via <see cref="AuthenticationOptions.DefaultSignInScheme"/>.
@ -49,6 +57,14 @@ namespace Microsoft.AspNetCore.Authentication
/// <returns>The scheme that will be used by default for <see cref="IAuthenticationService.SignInAsync(HttpContext, string, System.Security.Claims.ClaimsPrincipal, AuthenticationProperties)"/>.</returns>
Task<AuthenticationScheme> GetDefaultSignInSchemeAsync();
/// <summary>
/// Returns the scheme that will be used by default for <see cref="IAuthenticationService.SignOutAsync(HttpContext, string, AuthenticationProperties)"/>.
/// This is typically specified via <see cref="AuthenticationOptions.DefaultSignOutScheme"/>.
/// Otherwise, this will fallback to <see cref="GetDefaultSignInSchemeAsync"/> .
/// </summary>
/// <returns>The scheme that will be used by default for <see cref="IAuthenticationService.SignOutAsync(HttpContext, string, AuthenticationProperties)"/>.</returns>
Task<AuthenticationScheme> GetDefaultSignOutSchemeAsync();
/// <summary>
/// Registers a scheme for use by <see cref="IAuthenticationService"/>.
/// </summary>

View File

@ -75,6 +75,21 @@ namespace Microsoft.AspNetCore.Authentication
return Task.FromResult<AuthenticationScheme>(null);
}
/// <summary>
/// Returns the scheme that will be used by default for <see cref="IAuthenticationService.ForbidAsync(HttpContext, string, AuthenticationProperties)"/>.
/// This is typically specified via <see cref="AuthenticationOptions.DefaultForbidScheme"/>.
/// Otherwise, this will fallback to <see cref="GetDefaultChallengeSchemeAsync"/> .
/// </summary>
/// <returns>The scheme that will be used by default for <see cref="IAuthenticationService.ForbidAsync(HttpContext, string, AuthenticationProperties)"/>.</returns>
public Task<AuthenticationScheme> GetDefaultForbidSchemeAsync()
{
if (_options.DefaultForbidScheme != null)
{
return GetSchemeAsync(_options.DefaultForbidScheme);
}
return GetDefaultChallengeSchemeAsync();
}
/// <summary>
/// Returns the scheme that will be used by default for <see cref="IAuthenticationService.SignInAsync(HttpContext, string, System.Security.Claims.ClaimsPrincipal, AuthenticationProperties)"/>.
/// This is typically specified via <see cref="AuthenticationOptions.DefaultSignInScheme"/>.
@ -94,6 +109,21 @@ namespace Microsoft.AspNetCore.Authentication
return Task.FromResult<AuthenticationScheme>(null);
}
/// <summary>
/// Returns the scheme that will be used by default for <see cref="IAuthenticationService.SignOutAsync(HttpContext, string, AuthenticationProperties)"/>.
/// This is typically specified via <see cref="AuthenticationOptions.DefaultSignOutScheme"/>.
/// Otherwise, this will fallback to <see cref="GetDefaultSignInSchemeAsync"/> .
/// </summary>
/// <returns>The scheme that will be used by default for <see cref="IAuthenticationService.SignOutAsync(HttpContext, string, AuthenticationProperties)"/>.</returns>
public Task<AuthenticationScheme> GetDefaultSignOutSchemeAsync()
{
if (_options.DefaultSignOutScheme != null)
{
return GetSchemeAsync(_options.DefaultSignOutScheme);
}
return GetDefaultSignInSchemeAsync();
}
/// <summary>
/// Returns the <see cref="AuthenticationScheme"/> matching the name, or null.
/// </summary>

View File

@ -0,0 +1,120 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Security.Claims;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
using Xunit;
namespace Microsoft.AspNetCore.Authentication
{
public class AuthenticationSchemeProviderTests
{
[Fact]
public async Task DefaultSignOutFallsbackToSignIn()
{
var services = new ServiceCollection().AddOptions().AddAuthenticationCore(o =>
{
o.AddScheme<Handler>("signin", "whatever");
o.AddScheme<Handler>("foobly", "whatever");
o.DefaultSignInScheme = "signin";
}).BuildServiceProvider();
var provider = services.GetRequiredService<IAuthenticationSchemeProvider>();
var scheme = await provider.GetDefaultSignOutSchemeAsync();
Assert.NotNull(scheme);
Assert.Equal("signin", scheme.Name);
}
[Fact]
public async Task DefaultForbidFallsbackToChallenge()
{
var services = new ServiceCollection().AddOptions().AddAuthenticationCore(o =>
{
o.AddScheme<Handler>("challenge", "whatever");
o.AddScheme<Handler>("foobly", "whatever");
o.DefaultChallengeScheme = "challenge";
}).BuildServiceProvider();
var provider = services.GetRequiredService<IAuthenticationSchemeProvider>();
var scheme = await provider.GetDefaultForbidSchemeAsync();
Assert.NotNull(scheme);
Assert.Equal("challenge", scheme.Name);
}
[Fact]
public async Task DefaultSchemesFallbackToOnlyScheme()
{
var services = new ServiceCollection().AddOptions().AddAuthenticationCore(o =>
{
o.AddScheme<Handler>("single", "whatever");
}).BuildServiceProvider();
var provider = services.GetRequiredService<IAuthenticationSchemeProvider>();
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 DefaultSchemesAreSet()
{
var services = new ServiceCollection().AddOptions().AddAuthenticationCore(o =>
{
o.AddScheme<Handler>("A", "whatever");
o.AddScheme<Handler>("B", "whatever");
o.AddScheme<Handler>("C", "whatever");
o.DefaultChallengeScheme = "A";
o.DefaultForbidScheme = "B";
o.DefaultSignInScheme = "C";
o.DefaultSignOutScheme = "A";
o.DefaultAuthenticateScheme = "C";
}).BuildServiceProvider();
var provider = services.GetRequiredService<IAuthenticationSchemeProvider>();
Assert.Equal("B", (await provider.GetDefaultForbidSchemeAsync()).Name);
Assert.Equal("C", (await provider.GetDefaultAuthenticateSchemeAsync()).Name);
Assert.Equal("A", (await provider.GetDefaultChallengeSchemeAsync()).Name);
Assert.Equal("C", (await provider.GetDefaultSignInSchemeAsync()).Name);
Assert.Equal("A", (await provider.GetDefaultSignOutSchemeAsync()).Name);
}
private class Handler : IAuthenticationHandler
{
public Task<AuthenticateResult> AuthenticateAsync()
{
throw new NotImplementedException();
}
public Task ChallengeAsync(AuthenticationProperties properties)
{
throw new NotImplementedException();
}
public Task ForbidAsync(AuthenticationProperties properties)
{
throw new NotImplementedException();
}
public Task InitializeAsync(AuthenticationScheme scheme, HttpContext context)
{
throw new NotImplementedException();
}
public Task SignInAsync(ClaimsPrincipal user, AuthenticationProperties properties)
{
throw new NotImplementedException();
}
public Task SignOutAsync(AuthenticationProperties properties)
{
throw new NotImplementedException();
}
}
}
}