Skip to content
This repository was archived by the owner on Nov 20, 2018. It is now read-only.

Commit df5c673

Browse files
authored
Add new default schemes + tests (#870)
1 parent b059bcc commit df5c673

File tree

4 files changed

+189
-0
lines changed

4 files changed

+189
-0
lines changed

src/Microsoft.AspNetCore.Authentication.Abstractions/AuthenticationOptions.cs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,19 @@ public void AddScheme(string name, Action<AuthenticationSchemeBuilder> configure
4747
SchemeMap[name] = builder;
4848
}
4949

50+
/// <summary>
51+
/// Adds an <see cref="AuthenticationScheme"/>.
52+
/// </summary>
53+
/// <typeparam name="THandler">The <see cref="IAuthenticationHandler"/> responsible for the scheme.</typeparam>
54+
/// <param name="name">The name of the scheme being added.</param>
55+
/// <param name="displayName">The display name for the scheme.</param>
56+
public void AddScheme<THandler>(string name, string displayName) where THandler : IAuthenticationHandler
57+
=> AddScheme(name, b =>
58+
{
59+
b.DisplayName = displayName;
60+
b.HandlerType = typeof(THandler);
61+
});
62+
5063
/// <summary>
5164
/// Used by as the default scheme by <see cref="IAuthenticationService.AuthenticateAsync(HttpContext, string)"/>.
5265
/// </summary>
@@ -57,9 +70,19 @@ public void AddScheme(string name, Action<AuthenticationSchemeBuilder> configure
5770
/// </summary>
5871
public string DefaultSignInScheme { get; set; }
5972

73+
/// <summary>
74+
/// Used by as the default scheme by <see cref="IAuthenticationService.SignOutAsync(HttpContext, string, AuthenticationProperties)"/>.
75+
/// </summary>
76+
public string DefaultSignOutScheme { get; set; }
77+
6078
/// <summary>
6179
/// Used by as the default scheme by <see cref="IAuthenticationService.ChallengeAsync(HttpContext, string, AuthenticationProperties)"/>.
6280
/// </summary>
6381
public string DefaultChallengeScheme { get; set; }
82+
83+
/// <summary>
84+
/// Used by as the default scheme by <see cref="IAuthenticationService.ForbidAsync(HttpContext, string, AuthenticationProperties)"/>.
85+
/// </summary>
86+
public string DefaultForbidScheme { get; set; }
6487
}
6588
}

src/Microsoft.AspNetCore.Authentication.Abstractions/IAuthenticationSchemeProvider.cs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,14 @@ public interface IAuthenticationSchemeProvider
4141
/// <returns>The scheme that will be used by default for <see cref="IAuthenticationService.ChallengeAsync(HttpContext, string, AuthenticationProperties)"/>.</returns>
4242
Task<AuthenticationScheme> GetDefaultChallengeSchemeAsync();
4343

44+
/// <summary>
45+
/// Returns the scheme that will be used by default for <see cref="IAuthenticationService.ForbidAsync(HttpContext, string, AuthenticationProperties)"/>.
46+
/// This is typically specified via <see cref="AuthenticationOptions.DefaultForbidScheme"/>.
47+
/// Otherwise, this will fallback to <see cref="GetDefaultChallengeSchemeAsync"/> .
48+
/// </summary>
49+
/// <returns>The scheme that will be used by default for <see cref="IAuthenticationService.ForbidAsync(HttpContext, string, AuthenticationProperties)"/>.</returns>
50+
Task<AuthenticationScheme> GetDefaultForbidSchemeAsync();
51+
4452
/// <summary>
4553
/// Returns the scheme that will be used by default for <see cref="IAuthenticationService.SignInAsync(HttpContext, string, System.Security.Claims.ClaimsPrincipal, AuthenticationProperties)"/>.
4654
/// This is typically specified via <see cref="AuthenticationOptions.DefaultSignInScheme"/>.
@@ -49,6 +57,14 @@ public interface IAuthenticationSchemeProvider
4957
/// <returns>The scheme that will be used by default for <see cref="IAuthenticationService.SignInAsync(HttpContext, string, System.Security.Claims.ClaimsPrincipal, AuthenticationProperties)"/>.</returns>
5058
Task<AuthenticationScheme> GetDefaultSignInSchemeAsync();
5159

60+
/// <summary>
61+
/// Returns the scheme that will be used by default for <see cref="IAuthenticationService.SignOutAsync(HttpContext, string, AuthenticationProperties)"/>.
62+
/// This is typically specified via <see cref="AuthenticationOptions.DefaultSignOutScheme"/>.
63+
/// Otherwise, this will fallback to <see cref="GetDefaultSignInSchemeAsync"/> .
64+
/// </summary>
65+
/// <returns>The scheme that will be used by default for <see cref="IAuthenticationService.SignOutAsync(HttpContext, string, AuthenticationProperties)"/>.</returns>
66+
Task<AuthenticationScheme> GetDefaultSignOutSchemeAsync();
67+
5268
/// <summary>
5369
/// Registers a scheme for use by <see cref="IAuthenticationService"/>.
5470
/// </summary>

src/Microsoft.AspNetCore.Authentication.Core/AuthenticationSchemeProvider.cs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,21 @@ public Task<AuthenticationScheme> GetDefaultChallengeSchemeAsync()
7575
return Task.FromResult<AuthenticationScheme>(null);
7676
}
7777

78+
/// <summary>
79+
/// Returns the scheme that will be used by default for <see cref="IAuthenticationService.ForbidAsync(HttpContext, string, AuthenticationProperties)"/>.
80+
/// This is typically specified via <see cref="AuthenticationOptions.DefaultForbidScheme"/>.
81+
/// Otherwise, this will fallback to <see cref="GetDefaultChallengeSchemeAsync"/> .
82+
/// </summary>
83+
/// <returns>The scheme that will be used by default for <see cref="IAuthenticationService.ForbidAsync(HttpContext, string, AuthenticationProperties)"/>.</returns>
84+
public Task<AuthenticationScheme> GetDefaultForbidSchemeAsync()
85+
{
86+
if (_options.DefaultForbidScheme != null)
87+
{
88+
return GetSchemeAsync(_options.DefaultForbidScheme);
89+
}
90+
return GetDefaultChallengeSchemeAsync();
91+
}
92+
7893
/// <summary>
7994
/// Returns the scheme that will be used by default for <see cref="IAuthenticationService.SignInAsync(HttpContext, string, System.Security.Claims.ClaimsPrincipal, AuthenticationProperties)"/>.
8095
/// This is typically specified via <see cref="AuthenticationOptions.DefaultSignInScheme"/>.
@@ -94,6 +109,21 @@ public Task<AuthenticationScheme> GetDefaultSignInSchemeAsync()
94109
return Task.FromResult<AuthenticationScheme>(null);
95110
}
96111

112+
/// <summary>
113+
/// Returns the scheme that will be used by default for <see cref="IAuthenticationService.SignOutAsync(HttpContext, string, AuthenticationProperties)"/>.
114+
/// This is typically specified via <see cref="AuthenticationOptions.DefaultSignOutScheme"/>.
115+
/// Otherwise, this will fallback to <see cref="GetDefaultSignInSchemeAsync"/> .
116+
/// </summary>
117+
/// <returns>The scheme that will be used by default for <see cref="IAuthenticationService.SignOutAsync(HttpContext, string, AuthenticationProperties)"/>.</returns>
118+
public Task<AuthenticationScheme> GetDefaultSignOutSchemeAsync()
119+
{
120+
if (_options.DefaultSignOutScheme != null)
121+
{
122+
return GetSchemeAsync(_options.DefaultSignOutScheme);
123+
}
124+
return GetDefaultSignInSchemeAsync();
125+
}
126+
97127
/// <summary>
98128
/// Returns the <see cref="AuthenticationScheme"/> matching the name, or null.
99129
/// </summary>
Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
// Copyright (c) .NET Foundation. All rights reserved.
2+
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3+
4+
using System;
5+
using System.Security.Claims;
6+
using System.Threading.Tasks;
7+
using Microsoft.AspNetCore.Http;
8+
using Microsoft.Extensions.DependencyInjection;
9+
using Xunit;
10+
11+
namespace Microsoft.AspNetCore.Authentication
12+
{
13+
public class AuthenticationSchemeProviderTests
14+
{
15+
[Fact]
16+
public async Task DefaultSignOutFallsbackToSignIn()
17+
{
18+
var services = new ServiceCollection().AddOptions().AddAuthenticationCore(o =>
19+
{
20+
o.AddScheme<Handler>("signin", "whatever");
21+
o.AddScheme<Handler>("foobly", "whatever");
22+
o.DefaultSignInScheme = "signin";
23+
}).BuildServiceProvider();
24+
25+
var provider = services.GetRequiredService<IAuthenticationSchemeProvider>();
26+
var scheme = await provider.GetDefaultSignOutSchemeAsync();
27+
Assert.NotNull(scheme);
28+
Assert.Equal("signin", scheme.Name);
29+
}
30+
31+
[Fact]
32+
public async Task DefaultForbidFallsbackToChallenge()
33+
{
34+
var services = new ServiceCollection().AddOptions().AddAuthenticationCore(o =>
35+
{
36+
o.AddScheme<Handler>("challenge", "whatever");
37+
o.AddScheme<Handler>("foobly", "whatever");
38+
o.DefaultChallengeScheme = "challenge";
39+
}).BuildServiceProvider();
40+
41+
var provider = services.GetRequiredService<IAuthenticationSchemeProvider>();
42+
var scheme = await provider.GetDefaultForbidSchemeAsync();
43+
Assert.NotNull(scheme);
44+
Assert.Equal("challenge", scheme.Name);
45+
}
46+
47+
[Fact]
48+
public async Task DefaultSchemesFallbackToOnlyScheme()
49+
{
50+
var services = new ServiceCollection().AddOptions().AddAuthenticationCore(o =>
51+
{
52+
o.AddScheme<Handler>("single", "whatever");
53+
}).BuildServiceProvider();
54+
55+
var provider = services.GetRequiredService<IAuthenticationSchemeProvider>();
56+
Assert.Equal("single", (await provider.GetDefaultForbidSchemeAsync()).Name);
57+
Assert.Equal("single", (await provider.GetDefaultAuthenticateSchemeAsync()).Name);
58+
Assert.Equal("single", (await provider.GetDefaultChallengeSchemeAsync()).Name);
59+
Assert.Equal("single", (await provider.GetDefaultSignInSchemeAsync()).Name);
60+
Assert.Equal("single", (await provider.GetDefaultSignOutSchemeAsync()).Name);
61+
}
62+
63+
[Fact]
64+
public async Task DefaultSchemesAreSet()
65+
{
66+
var services = new ServiceCollection().AddOptions().AddAuthenticationCore(o =>
67+
{
68+
o.AddScheme<Handler>("A", "whatever");
69+
o.AddScheme<Handler>("B", "whatever");
70+
o.AddScheme<Handler>("C", "whatever");
71+
o.DefaultChallengeScheme = "A";
72+
o.DefaultForbidScheme = "B";
73+
o.DefaultSignInScheme = "C";
74+
o.DefaultSignOutScheme = "A";
75+
o.DefaultAuthenticateScheme = "C";
76+
}).BuildServiceProvider();
77+
78+
var provider = services.GetRequiredService<IAuthenticationSchemeProvider>();
79+
Assert.Equal("B", (await provider.GetDefaultForbidSchemeAsync()).Name);
80+
Assert.Equal("C", (await provider.GetDefaultAuthenticateSchemeAsync()).Name);
81+
Assert.Equal("A", (await provider.GetDefaultChallengeSchemeAsync()).Name);
82+
Assert.Equal("C", (await provider.GetDefaultSignInSchemeAsync()).Name);
83+
Assert.Equal("A", (await provider.GetDefaultSignOutSchemeAsync()).Name);
84+
}
85+
86+
private class Handler : IAuthenticationHandler
87+
{
88+
public Task<AuthenticateResult> AuthenticateAsync()
89+
{
90+
throw new NotImplementedException();
91+
}
92+
93+
public Task ChallengeAsync(AuthenticationProperties properties)
94+
{
95+
throw new NotImplementedException();
96+
}
97+
98+
public Task ForbidAsync(AuthenticationProperties properties)
99+
{
100+
throw new NotImplementedException();
101+
}
102+
103+
public Task InitializeAsync(AuthenticationScheme scheme, HttpContext context)
104+
{
105+
throw new NotImplementedException();
106+
}
107+
108+
public Task SignInAsync(ClaimsPrincipal user, AuthenticationProperties properties)
109+
{
110+
throw new NotImplementedException();
111+
}
112+
113+
public Task SignOutAsync(AuthenticationProperties properties)
114+
{
115+
throw new NotImplementedException();
116+
}
117+
}
118+
119+
}
120+
}

0 commit comments

Comments
 (0)