diff --git a/src/Umbraco.Web.BackOffice/Controllers/AuthenticationController.cs b/src/Umbraco.Web.BackOffice/Controllers/AuthenticationController.cs
index ae7776dfaf..cf7a7dd729 100644
--- a/src/Umbraco.Web.BackOffice/Controllers/AuthenticationController.cs
+++ b/src/Umbraco.Web.BackOffice/Controllers/AuthenticationController.cs
@@ -181,14 +181,14 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
}
else
{
- var opt = _externalAuthenticationOptions.Get(authType.Name);
+ BackOfficeExternaLoginProviderScheme opt = await _externalAuthenticationOptions.GetAsync(authType.Name);
if (opt == null)
{
return BadRequest($"Could not find external authentication options registered for provider {unlinkLoginModel.LoginProvider}");
}
else
{
- if (!opt.Options.AutoLinkOptions.AllowManualLinking)
+ if (!opt.ExternalLoginProvider.Options.AutoLinkOptions.AllowManualLinking)
{
// If AllowManualLinking is disabled for this provider we cannot unlink
return BadRequest();
diff --git a/src/Umbraco.Web.BackOffice/Controllers/BackOfficeServerVariables.cs b/src/Umbraco.Web.BackOffice/Controllers/BackOfficeServerVariables.cs
index c3fb203ec1..61c1660dd0 100644
--- a/src/Umbraco.Web.BackOffice/Controllers/BackOfficeServerVariables.cs
+++ b/src/Umbraco.Web.BackOffice/Controllers/BackOfficeServerVariables.cs
@@ -144,7 +144,7 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
/// Returns the server variables for authenticated users
///
///
- internal Task> GetServerVariablesAsync()
+ internal async Task> GetServerVariablesAsync()
{
var globalSettings = _globalSettings;
var backOfficeControllerName = ControllerExtensions.GetControllerName();
@@ -432,12 +432,12 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
{
// TODO: It would be nicer to not have to manually translate these properties
// but then needs to be changed in quite a few places in angular
- "providers", _externalLogins.GetBackOfficeProviders()
+ "providers", (await _externalLogins.GetBackOfficeProvidersAsync())
.Select(p => new
{
- authType = p.AuthenticationType,
- caption = p.Name,
- properties = p.Options
+ authType = p.ExternalLoginProvider.AuthenticationType,
+ caption = p.AuthenticationScheme.DisplayName,
+ properties = p.ExternalLoginProvider.Options
})
.ToArray()
}
@@ -456,7 +456,8 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
}
}
};
- return Task.FromResult(defaultVals);
+
+ return defaultVals;
}
[DataContract]
diff --git a/src/Umbraco.Web.BackOffice/Extensions/HtmlHelperBackOfficeExtensions.cs b/src/Umbraco.Web.BackOffice/Extensions/HtmlHelperBackOfficeExtensions.cs
index 3340988714..fee75f6eae 100644
--- a/src/Umbraco.Web.BackOffice/Extensions/HtmlHelperBackOfficeExtensions.cs
+++ b/src/Umbraco.Web.BackOffice/Extensions/HtmlHelperBackOfficeExtensions.cs
@@ -1,4 +1,4 @@
-using System.Collections.Generic;
+using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
@@ -54,18 +54,18 @@ namespace Umbraco.Extensions
///
///
///
- public static Task AngularValueExternalLoginInfoScriptAsync(this IHtmlHelper html,
+ public static async Task AngularValueExternalLoginInfoScriptAsync(this IHtmlHelper html,
IBackOfficeExternalLoginProviders externalLogins,
BackOfficeExternalLoginProviderErrors externalLoginErrors)
{
- var providers = externalLogins.GetBackOfficeProviders();
+ var providers = await externalLogins.GetBackOfficeProvidersAsync();
var loginProviders = providers
.Select(p => new
{
- authType = p.AuthenticationType,
- caption = p.Name,
- properties = p.Options
+ authType = p.ExternalLoginProvider.AuthenticationType,
+ caption = p.AuthenticationScheme.DisplayName,
+ properties = p.ExternalLoginProvider.Options
})
.ToArray();
@@ -89,7 +89,7 @@ namespace Umbraco.Extensions
sb.AppendLine(JsonConvert.SerializeObject(loginProviders));
sb.AppendLine(@"});");
- return Task.FromResult(html.Raw(sb.ToString()));
+ return html.Raw(sb.ToString());
}
///
diff --git a/src/Umbraco.Web.BackOffice/Security/BackOfficeAuthenticationBuilder.cs b/src/Umbraco.Web.BackOffice/Security/BackOfficeAuthenticationBuilder.cs
index ac19a5f195..bc9f64129f 100644
--- a/src/Umbraco.Web.BackOffice/Security/BackOfficeAuthenticationBuilder.cs
+++ b/src/Umbraco.Web.BackOffice/Security/BackOfficeAuthenticationBuilder.cs
@@ -1,4 +1,5 @@
using System;
+using System.Diagnostics;
using Microsoft.AspNetCore.Authentication;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
@@ -45,7 +46,6 @@ namespace Umbraco.Cms.Web.BackOffice.Security
base.Services.AddSingleton(services =>
{
return new BackOfficeExternalLoginProvider(
- displayName,
authenticationScheme,
services.GetRequiredService>());
});
diff --git a/src/Umbraco.Web.BackOffice/Security/BackOfficeExternaLoginProviderScheme.cs b/src/Umbraco.Web.BackOffice/Security/BackOfficeExternaLoginProviderScheme.cs
new file mode 100644
index 0000000000..2732338426
--- /dev/null
+++ b/src/Umbraco.Web.BackOffice/Security/BackOfficeExternaLoginProviderScheme.cs
@@ -0,0 +1,20 @@
+using System;
+using Microsoft.AspNetCore.Authentication;
+
+namespace Umbraco.Cms.Web.BackOffice.Security
+{
+ public class BackOfficeExternaLoginProviderScheme
+ {
+ public BackOfficeExternaLoginProviderScheme(
+ BackOfficeExternalLoginProvider externalLoginProvider,
+ AuthenticationScheme authenticationScheme)
+ {
+ ExternalLoginProvider = externalLoginProvider ?? throw new ArgumentNullException(nameof(externalLoginProvider));
+ AuthenticationScheme = authenticationScheme ?? throw new ArgumentNullException(nameof(authenticationScheme));
+ }
+
+ public BackOfficeExternalLoginProvider ExternalLoginProvider { get; }
+ public AuthenticationScheme AuthenticationScheme { get; }
+ }
+
+}
diff --git a/src/Umbraco.Web.BackOffice/Security/BackOfficeExternalLoginProvider.cs b/src/Umbraco.Web.BackOffice/Security/BackOfficeExternalLoginProvider.cs
index fa942bddaa..9e78917087 100644
--- a/src/Umbraco.Web.BackOffice/Security/BackOfficeExternalLoginProvider.cs
+++ b/src/Umbraco.Web.BackOffice/Security/BackOfficeExternalLoginProvider.cs
@@ -9,7 +9,6 @@ namespace Umbraco.Cms.Web.BackOffice.Security
public class BackOfficeExternalLoginProvider : IEquatable
{
public BackOfficeExternalLoginProvider(
- string name,
string authenticationType,
IOptionsMonitor properties)
{
@@ -18,31 +17,20 @@ namespace Umbraco.Cms.Web.BackOffice.Security
throw new ArgumentNullException(nameof(properties));
}
- Name = name ?? throw new ArgumentNullException(nameof(name));
AuthenticationType = authenticationType ?? throw new ArgumentNullException(nameof(authenticationType));
Options = properties.Get(authenticationType);
}
- public string Name { get; }
+ ///
+ /// The authentication "Scheme"
+ ///
public string AuthenticationType { get; }
+
public BackOfficeExternalLoginProviderOptions Options { get; }
- public override bool Equals(object obj)
- {
- return Equals(obj as BackOfficeExternalLoginProvider);
- }
-
- public bool Equals(BackOfficeExternalLoginProvider other)
- {
- return other != null &&
- Name == other.Name &&
- AuthenticationType == other.AuthenticationType;
- }
-
- public override int GetHashCode()
- {
- return HashCode.Combine(Name, AuthenticationType);
- }
+ public override bool Equals(object obj) => Equals(obj as BackOfficeExternalLoginProvider);
+ public bool Equals(BackOfficeExternalLoginProvider other) => other != null && AuthenticationType == other.AuthenticationType;
+ public override int GetHashCode() => HashCode.Combine(AuthenticationType);
}
}
diff --git a/src/Umbraco.Web.BackOffice/Security/BackOfficeExternalLoginProviders.cs b/src/Umbraco.Web.BackOffice/Security/BackOfficeExternalLoginProviders.cs
index 7ecb4e2829..4c9799b9a4 100644
--- a/src/Umbraco.Web.BackOffice/Security/BackOfficeExternalLoginProviders.cs
+++ b/src/Umbraco.Web.BackOffice/Security/BackOfficeExternalLoginProviders.cs
@@ -1,41 +1,71 @@
-using System.Collections.Generic;
+using System;
+using System.Collections.Generic;
using System.Linq;
+using System.Threading.Tasks;
+using Microsoft.AspNetCore.Authentication;
namespace Umbraco.Cms.Web.BackOffice.Security
{
+
///
public class BackOfficeExternalLoginProviders : IBackOfficeExternalLoginProviders
{
- public BackOfficeExternalLoginProviders(IEnumerable externalLogins)
+ private readonly Dictionary _externalLogins;
+ private readonly IAuthenticationSchemeProvider _authenticationSchemeProvider;
+
+ public BackOfficeExternalLoginProviders(
+ IEnumerable externalLogins,
+ IAuthenticationSchemeProvider authenticationSchemeProvider)
{
- _externalLogins = externalLogins;
+ _externalLogins = externalLogins.ToDictionary(x => x.AuthenticationType);
+ _authenticationSchemeProvider = authenticationSchemeProvider;
}
- private readonly IEnumerable _externalLogins;
-
///
- public BackOfficeExternalLoginProvider Get(string authenticationType)
+ public async Task GetAsync(string authenticationType)
{
- return _externalLogins.FirstOrDefault(x => x.AuthenticationType == authenticationType);
+ if (!_externalLogins.TryGetValue(authenticationType, out BackOfficeExternalLoginProvider provider))
+ {
+ return null;
+ }
+
+ // get the associated scheme
+ AuthenticationScheme associatedScheme = await _authenticationSchemeProvider.GetSchemeAsync(provider.AuthenticationType);
+
+ if (associatedScheme == null)
+ {
+ throw new InvalidOperationException("No authentication scheme registered for " + provider.AuthenticationType);
+ }
+
+ return new BackOfficeExternaLoginProviderScheme(provider, associatedScheme);
}
///
public string GetAutoLoginProvider()
{
- var found = _externalLogins.Where(x => x.Options.AutoRedirectLoginToExternalProvider).ToList();
+ var found = _externalLogins.Values.Where(x => x.Options.AutoRedirectLoginToExternalProvider).ToList();
return found.Count > 0 ? found[0].AuthenticationType : null;
}
///
- public IEnumerable GetBackOfficeProviders()
+ public async Task> GetBackOfficeProvidersAsync()
{
- return _externalLogins;
+ var providersWithSchemes = new List();
+ foreach (BackOfficeExternalLoginProvider login in _externalLogins.Values)
+ {
+ // get the associated scheme
+ AuthenticationScheme associatedScheme = await _authenticationSchemeProvider.GetSchemeAsync(login.AuthenticationType);
+
+ providersWithSchemes.Add(new BackOfficeExternaLoginProviderScheme(login, associatedScheme));
+ }
+
+ return providersWithSchemes;
}
///
public bool HasDenyLocalLogin()
{
- var found = _externalLogins.Where(x => x.Options.DenyLocalLogin).ToList();
+ var found = _externalLogins.Values.Where(x => x.Options.DenyLocalLogin).ToList();
return found.Count > 0;
}
}
diff --git a/src/Umbraco.Web.BackOffice/Security/BackOfficeSignInManager.cs b/src/Umbraco.Web.BackOffice/Security/BackOfficeSignInManager.cs
index 3e921ba0f9..4b970e4b72 100644
--- a/src/Umbraco.Web.BackOffice/Security/BackOfficeSignInManager.cs
+++ b/src/Umbraco.Web.BackOffice/Security/BackOfficeSignInManager.cs
@@ -64,7 +64,7 @@ namespace Umbraco.Cms.Web.BackOffice.Security
// borrowed from https://github.com/dotnet/aspnetcore/blob/master/src/Identity/Core/src/SignInManager.cs
// to be able to deal with auto-linking and reduce duplicate lookups
- var autoLinkOptions = _externalLogins.Get(loginInfo.LoginProvider)?.Options?.AutoLinkOptions;
+ var autoLinkOptions = (await _externalLogins.GetAsync(loginInfo.LoginProvider))?.ExternalLoginProvider?.Options?.AutoLinkOptions;
var user = await UserManager.FindByLoginAsync(loginInfo.LoginProvider, loginInfo.ProviderKey);
if (user == null)
{
diff --git a/src/Umbraco.Web.BackOffice/Security/IBackOfficeExternalLoginProviders.cs b/src/Umbraco.Web.BackOffice/Security/IBackOfficeExternalLoginProviders.cs
index d47873f3cd..2426cfcf4d 100644
--- a/src/Umbraco.Web.BackOffice/Security/IBackOfficeExternalLoginProviders.cs
+++ b/src/Umbraco.Web.BackOffice/Security/IBackOfficeExternalLoginProviders.cs
@@ -1,4 +1,5 @@
-using System.Collections.Generic;
+using System.Collections.Generic;
+using System.Threading.Tasks;
namespace Umbraco.Cms.Web.BackOffice.Security
{
@@ -13,13 +14,13 @@ namespace Umbraco.Cms.Web.BackOffice.Security
///
///
///
- BackOfficeExternalLoginProvider Get(string authenticationType);
+ Task GetAsync(string authenticationType);
///
/// Get all registered
///
///
- IEnumerable GetBackOfficeProviders();
+ Task> GetBackOfficeProvidersAsync();
///
/// Returns the authentication type for the last registered external login (oauth) provider that specifies an auto-login redirect option