Gets oauth working (with google) now need to test others and debug why the styles aren't working
This commit is contained in:
@@ -180,7 +180,7 @@ namespace Umbraco.Web.BackOffice.Controllers
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!opt.AutoLinkOptions.AllowManualLinking)
|
||||
if (!opt.Options.AutoLinkOptions.AllowManualLinking)
|
||||
{
|
||||
// If AllowManualLinking is disabled for this provider we cannot unlink
|
||||
return BadRequest();
|
||||
|
||||
@@ -414,7 +414,7 @@ namespace Umbraco.Web.BackOffice.Controllers
|
||||
}
|
||||
else
|
||||
{
|
||||
autoLinkOptions = _externalLogins.Get(authType.Name)?.AutoLinkOptions;
|
||||
autoLinkOptions = _externalLogins.Get(authType.Name)?.Options?.AutoLinkOptions;
|
||||
}
|
||||
|
||||
// Sign in the user with this external login provider if the user already has a login
|
||||
@@ -445,7 +445,7 @@ namespace Umbraco.Web.BackOffice.Controllers
|
||||
ViewData.SetExternalSignInProviderErrors(
|
||||
new BackOfficeExternalLoginProviderErrors(
|
||||
loginInfo.LoginProvider,
|
||||
new[] { "The requested provider (" + loginInfo.LoginProvider + ") has not been linked to an account" }));
|
||||
new[] { "The requested provider (" + loginInfo.LoginProvider + ") has not been linked to an account, the provider must be linked from the back office." }));
|
||||
}
|
||||
|
||||
//Remove the cookie otherwise this message will keep appearing
|
||||
@@ -462,7 +462,7 @@ namespace Umbraco.Web.BackOffice.Controllers
|
||||
|
||||
if (autoLinkOptions.AutoLinkExternalAccount == false)
|
||||
{
|
||||
return true; // TODO: This seems weird to return true, but it was like that before so must be a reason?
|
||||
return false;
|
||||
}
|
||||
|
||||
var email = loginInfo.Principal.FindFirstValue(ClaimTypes.Email);
|
||||
|
||||
@@ -135,7 +135,7 @@ namespace Umbraco.Web.BackOffice.Controllers
|
||||
/// Returns the server variables for authenticated users
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
internal async Task<Dictionary<string, object>> GetServerVariablesAsync()
|
||||
internal Task<Dictionary<string, object>> GetServerVariablesAsync()
|
||||
{
|
||||
var globalSettings = _globalSettings;
|
||||
var backOfficeControllerName = ControllerExtensions.GetControllerName<BackOfficeController>();
|
||||
@@ -149,8 +149,8 @@ namespace Umbraco.Web.BackOffice.Controllers
|
||||
// having each url defined here explicitly - we can do that in v8! for now
|
||||
// for umbraco services we'll stick to explicitly defining the endpoints.
|
||||
|
||||
// {"externalLoginsUrl", _linkGenerator.GetPathByAction(nameof(BackOfficeController.ExternalLogin), backOfficeControllerName, new { area = Constants.Web.Mvc.BackOfficeArea })},
|
||||
// {"externalLinkLoginsUrl", _linkGenerator.GetPathByAction(nameof(BackOfficeController.LinkLogin), backOfficeControllerName, new { area = Constants.Web.Mvc.BackOfficeArea })},
|
||||
{"externalLoginsUrl", _linkGenerator.GetPathByAction(nameof(BackOfficeController.ExternalLogin), backOfficeControllerName, new { area = Constants.Web.Mvc.BackOfficeArea })},
|
||||
{"externalLinkLoginsUrl", _linkGenerator.GetPathByAction(nameof(BackOfficeController.LinkLogin), backOfficeControllerName, new { area = Constants.Web.Mvc.BackOfficeArea })},
|
||||
{"gridConfig", _linkGenerator.GetPathByAction(nameof(BackOfficeController.GetGridConfig), backOfficeControllerName, new { area = Constants.Web.Mvc.BackOfficeArea })},
|
||||
// TODO: This is ultra confusing! this same key is used for different things, when returning the full app when authenticated it is this URL but when not auth'd it's actually the ServerVariables address
|
||||
{"serverVarsJs", _linkGenerator.GetPathByAction(nameof(BackOfficeController.Application), backOfficeControllerName, new { area = Constants.Web.Mvc.BackOfficeArea })},
|
||||
@@ -418,10 +418,13 @@ namespace Umbraco.Web.BackOffice.Controllers
|
||||
"externalLogins", new Dictionary<string, object>
|
||||
{
|
||||
{
|
||||
// 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()
|
||||
.Select(p => new
|
||||
{
|
||||
authType = p.AuthenticationType, caption = p.Name,
|
||||
authType = p.AuthenticationType,
|
||||
caption = p.Name,
|
||||
properties = p.Options
|
||||
})
|
||||
.ToArray()
|
||||
@@ -441,7 +444,7 @@ namespace Umbraco.Web.BackOffice.Controllers
|
||||
}
|
||||
}
|
||||
};
|
||||
return defaultVals;
|
||||
return Task.FromResult(defaultVals);
|
||||
}
|
||||
|
||||
[DataContract]
|
||||
|
||||
@@ -4,7 +4,6 @@ using System.Runtime.Serialization;
|
||||
namespace Umbraco.Web.BackOffice.Security
|
||||
{
|
||||
|
||||
// TODO: This is only for the back office, does it need to be in common?
|
||||
|
||||
/// <summary>
|
||||
/// Options used to configure back office external login providers
|
||||
@@ -12,13 +11,13 @@ namespace Umbraco.Web.BackOffice.Security
|
||||
public class BackOfficeExternalLoginProviderOptions
|
||||
{
|
||||
public BackOfficeExternalLoginProviderOptions(
|
||||
string style, string icon, string callbackPath,
|
||||
string buttonStyle, string icon, string callbackPath,
|
||||
ExternalSignInAutoLinkOptions autoLinkOptions = null,
|
||||
bool denyLocalLogin = false,
|
||||
bool autoRedirectLoginToExternalProvider = false,
|
||||
string customBackOfficeView = null)
|
||||
{
|
||||
Style = style;
|
||||
ButtonStyle = buttonStyle;
|
||||
Icon = icon;
|
||||
CallbackPath = callbackPath;
|
||||
AutoLinkOptions = autoLinkOptions ?? new ExternalSignInAutoLinkOptions();
|
||||
@@ -27,11 +26,10 @@ namespace Umbraco.Web.BackOffice.Security
|
||||
CustomBackOfficeView = customBackOfficeView;
|
||||
}
|
||||
|
||||
public string Style { get; }
|
||||
public string ButtonStyle { get; }
|
||||
public string Icon { get; }
|
||||
public string CallbackPath { get; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Options used to control how users can be auto-linked/created/updated based on the external login provider
|
||||
/// </summary>
|
||||
|
||||
@@ -14,7 +14,6 @@ using Umbraco.Extensions;
|
||||
|
||||
namespace Umbraco.Web.Common.Security
|
||||
{
|
||||
// TODO: This is only for the back office, does it need to be in common?
|
||||
|
||||
using Constants = Umbraco.Core.Constants;
|
||||
|
||||
|
||||
@@ -7,8 +7,6 @@ using SecurityConstants = Umbraco.Core.Constants.Security;
|
||||
|
||||
namespace Umbraco.Web.BackOffice.Security
|
||||
{
|
||||
// TODO: This is only for the back office, does it need to be in common?
|
||||
|
||||
/// <summary>
|
||||
/// Options used to configure auto-linking external OAuth providers
|
||||
/// </summary>
|
||||
|
||||
@@ -1,27 +1,109 @@
|
||||
using Microsoft.AspNetCore.Authentication.OAuth;
|
||||
using Microsoft.AspNetCore.Authentication;
|
||||
using Microsoft.AspNetCore.Authentication.OAuth;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.DependencyInjection.Extensions;
|
||||
using Microsoft.Extensions.Options;
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Builder;
|
||||
|
||||
namespace Umbraco.Web.BackOffice.Security
|
||||
{
|
||||
// TODO: This is only for the back office, does it need to be in common?
|
||||
/// <summary>
|
||||
/// Custom <see cref="AuthenticationBuilder"/> used to associate external logins with umbraco external login options
|
||||
/// </summary>
|
||||
public class BackOfficeAuthenticationBuilder : AuthenticationBuilder
|
||||
{
|
||||
private readonly BackOfficeExternalLoginProviderOptions _loginProviderOptions;
|
||||
|
||||
public BackOfficeAuthenticationBuilder(IServiceCollection services, BackOfficeExternalLoginProviderOptions loginProviderOptions)
|
||||
: base(services)
|
||||
{
|
||||
_loginProviderOptions = loginProviderOptions;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Overridden to track the final authenticationScheme being registered for the external login
|
||||
/// </summary>
|
||||
/// <typeparam name="TOptions"></typeparam>
|
||||
/// <typeparam name="THandler"></typeparam>
|
||||
/// <param name="authenticationScheme"></param>
|
||||
/// <param name="displayName"></param>
|
||||
/// <param name="configureOptions"></param>
|
||||
/// <returns></returns>
|
||||
public override AuthenticationBuilder AddRemoteScheme<TOptions, THandler>(string authenticationScheme, string displayName, Action<TOptions> configureOptions)
|
||||
{
|
||||
//Ensure the prefix is set
|
||||
if (!authenticationScheme.StartsWith(Constants.Security.BackOfficeExternalAuthenticationTypePrefix))
|
||||
{
|
||||
authenticationScheme = Constants.Security.BackOfficeExternalAuthenticationTypePrefix + authenticationScheme;
|
||||
}
|
||||
|
||||
// add our login provider to the container along with a custom options configuration
|
||||
Services.AddSingleton(x => new BackOfficeExternalLoginProvider(displayName, authenticationScheme, _loginProviderOptions));
|
||||
Services.TryAddEnumerable(ServiceDescriptor.Singleton<IPostConfigureOptions<TOptions>, EnsureBackOfficeScheme<TOptions>>());
|
||||
|
||||
return base.AddRemoteScheme<TOptions, THandler>(authenticationScheme, displayName, configureOptions);
|
||||
}
|
||||
|
||||
// TODO: We could override and throw NotImplementedException for other methods?
|
||||
|
||||
// Ensures that the sign in scheme is always the Umbraco back office external type
|
||||
private class EnsureBackOfficeScheme<TOptions> : IPostConfigureOptions<TOptions> where TOptions : RemoteAuthenticationOptions
|
||||
{
|
||||
public void PostConfigure(string name, TOptions options)
|
||||
{
|
||||
options.SignInScheme = Constants.Security.BackOfficeExternalAuthenticationType;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Used to add back office login providers
|
||||
/// </summary>
|
||||
public class BackOfficeExternalLoginsBuilder
|
||||
{
|
||||
public BackOfficeExternalLoginsBuilder(IServiceCollection services)
|
||||
{
|
||||
_services = services;
|
||||
}
|
||||
|
||||
private readonly IServiceCollection _services;
|
||||
|
||||
/// <summary>
|
||||
/// Add a back office login provider with options
|
||||
/// </summary>
|
||||
/// <param name="loginProviderOptions"></param>
|
||||
/// <param name="build"></param>
|
||||
/// <returns></returns>
|
||||
public BackOfficeExternalLoginsBuilder AddBackOfficeLogin(
|
||||
BackOfficeExternalLoginProviderOptions loginProviderOptions,
|
||||
Action<BackOfficeAuthenticationBuilder> build)
|
||||
{
|
||||
build(new BackOfficeAuthenticationBuilder(_services, loginProviderOptions));
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
public static class AuthenticationBuilderExtensions
|
||||
{
|
||||
public static IUmbracoBuilder AddBackOfficeExternalLogins(this IUmbracoBuilder umbracoBuilder, Action<BackOfficeExternalLoginsBuilder> builder)
|
||||
{
|
||||
builder(new BackOfficeExternalLoginsBuilder(umbracoBuilder.Services));
|
||||
return umbracoBuilder;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: We need to implement this and extend it to support the back office external login options
|
||||
// basically migrate things from AuthenticationManagerExtensions & AuthenticationOptionsExtensions
|
||||
// and use this to get the back office external login infos
|
||||
public interface IBackOfficeExternalLoginProviders
|
||||
{
|
||||
/// <summary>
|
||||
/// Register a login provider for the back office
|
||||
/// </summary>
|
||||
/// <param name="provider"></param>
|
||||
void Register(BackOfficeExternalLoginProvider provider);
|
||||
|
||||
BackOfficeExternalLoginProviderOptions Get(string authenticationType);
|
||||
BackOfficeExternalLoginProvider Get(string authenticationType);
|
||||
|
||||
IEnumerable<BackOfficeExternalLoginProvider> GetBackOfficeProviders();
|
||||
|
||||
@@ -32,42 +114,41 @@ namespace Umbraco.Web.BackOffice.Security
|
||||
/// <returns></returns>
|
||||
string GetAutoLoginProvider();
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if there is any external provider that has the Deny Local Login option configured
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
bool HasDenyLocalLogin();
|
||||
}
|
||||
|
||||
// TODO: This class is just a placeholder for later
|
||||
public class BackOfficeExternalLoginProviders : IBackOfficeExternalLoginProviders
|
||||
{
|
||||
private ConcurrentDictionary<string, BackOfficeExternalLoginProvider> _providers = new ConcurrentDictionary<string, BackOfficeExternalLoginProvider>();
|
||||
|
||||
public void Register(BackOfficeExternalLoginProvider provider)
|
||||
public BackOfficeExternalLoginProviders(IEnumerable<BackOfficeExternalLoginProvider> externalLogins)
|
||||
{
|
||||
_providers.TryAdd(provider.AuthenticationType, provider);
|
||||
|
||||
// TODO: we need to be able to set things like we were doing in ForUmbracoBackOffice.
|
||||
// Ok, most is done but we'll also need to take into account the callback path to ignore when we
|
||||
// do front-end routing
|
||||
_externalLogins = externalLogins;
|
||||
}
|
||||
|
||||
public BackOfficeExternalLoginProviderOptions Get(string authenticationType)
|
||||
private readonly IEnumerable<BackOfficeExternalLoginProvider> _externalLogins;
|
||||
|
||||
public BackOfficeExternalLoginProvider Get(string authenticationType)
|
||||
{
|
||||
return _providers.TryGetValue(authenticationType, out var opt) ? opt.Options : null;
|
||||
return _externalLogins.FirstOrDefault(x => x.AuthenticationType == authenticationType);
|
||||
}
|
||||
|
||||
public string GetAutoLoginProvider()
|
||||
{
|
||||
var found = _providers.Where(x => x.Value.Options.AutoRedirectLoginToExternalProvider).ToList();
|
||||
return found.Count > 0 ? found[0].Key : null;
|
||||
var found = _externalLogins.Where(x => x.Options.AutoRedirectLoginToExternalProvider).ToList();
|
||||
return found.Count > 0 ? found[0].AuthenticationType : null;
|
||||
}
|
||||
|
||||
public IEnumerable<BackOfficeExternalLoginProvider> GetBackOfficeProviders()
|
||||
{
|
||||
return _providers.Values;
|
||||
return _externalLogins;
|
||||
}
|
||||
|
||||
public bool HasDenyLocalLogin()
|
||||
{
|
||||
var found = _providers.Where(x => x.Value.Options.DenyLocalLogin).ToList();
|
||||
var found = _externalLogins.Where(x => x.Options.DenyLocalLogin).ToList();
|
||||
return found.Count > 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,7 +50,7 @@ function externalLoginInfoService(externalLoginInfo, umbRequestHelper) {
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
return x.properties.ExternalSignInAutoLinkOptions.AllowManualLinking;
|
||||
return x.properties.AutoLinkOptions.AllowManualLinking;
|
||||
}
|
||||
});
|
||||
return providers;
|
||||
|
||||
@@ -52,11 +52,11 @@
|
||||
|
||||
<div ng-if="login.customView" ng-include="login.customView"></div>
|
||||
|
||||
<div ng-if="!login.customView && login.properties.ExternalSignInAutoLinkOptions.AllowManualLinking">
|
||||
<div ng-if="!login.customView && login.properties.AutoLinkOptions.AllowManualLinking">
|
||||
<form ng-submit="linkProvider($event)" ng-if="login.linkedProviderKey == undefined" method="POST" action="{{externalLinkLoginFormAction}}" name="oauthloginform" id="oauthloginform-{{login.authType}}">
|
||||
<input type="hidden" name="provider" value="{{login.authType}}" />
|
||||
<button class="btn btn-block btn-social"
|
||||
ng-class="login.properties.SocialStyle"
|
||||
ng-class="login.properties.ButtonStyle"
|
||||
id="{{login.authType}}">
|
||||
|
||||
<i class="fa" ng-class="login.properties.SocialIcon"></i>
|
||||
@@ -67,7 +67,7 @@
|
||||
<button ng-if="login.linkedProviderKey != undefined"
|
||||
ng-click="unlink($event, login.authType, login.linkedProviderKey)"
|
||||
class="btn btn-block btn-social"
|
||||
ng-class="login.properties.SocialStyle"
|
||||
ng-class="login.properties.ButtonStyle"
|
||||
id="{{login.authType}}"
|
||||
name="provider"
|
||||
value="{{login.authType}}">
|
||||
|
||||
@@ -126,7 +126,7 @@
|
||||
<form method="POST" action="{{vm.externalLoginFormAction}}">
|
||||
<button type="submit"
|
||||
class="btn btn-block btn-social"
|
||||
ng-class="login.properties.SocialStyle"
|
||||
ng-class="login.properties.ButtonStyle"
|
||||
id="{{login.authType}}" name="provider" value="{{login.authType}}"
|
||||
title="Log in using your {{login.caption}} account">
|
||||
<i class="fa" ng-class="login.properties.SocialIcon"></i>
|
||||
|
||||
Reference in New Issue
Block a user