Skip to content

Commit cabc303

Browse files
authored
Merge pull request #11592 from rickbutterfield/feature/temp-11591
v9: Fix for OAuth ExternalLogin
2 parents c59d799 + fe396ba commit cabc303

File tree

3 files changed

+45
-3
lines changed

3 files changed

+45
-3
lines changed

src/Umbraco.Web.BackOffice/Controllers/BackOfficeController.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -517,6 +517,11 @@ private async Task<IActionResult> ExternalSignInAsync(ExternalLoginInfo loginInf
517517
// Failed only occurs when the user does not exist
518518
errors.Add("The requested provider (" + loginInfo.LoginProvider + ") has not been linked to an account, the provider must be linked from the back office.");
519519
}
520+
else if (result == ExternalLoginSignInResult.NotAllowed)
521+
{
522+
// This occurs when the external provider has approved the login but custom logic in OnExternalLogin has denined it.
523+
errors.Add($"The user {loginInfo.Principal.Identity.Name} for the external provider {loginInfo.ProviderDisplayName} has not been accepted and cannot sign in.");
524+
}
520525
else if (result == AutoLinkSignInResult.FailedNotLinked)
521526
{
522527
errors.Add("The requested provider (" + loginInfo.LoginProvider + ") has not been linked to an account, the provider must be linked from the back office.");

src/Umbraco.Web.BackOffice/Security/BackOfficeSignInManager.cs

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,8 @@ public async Task<SignInResult> ExternalLoginSignInAsync(ExternalLoginInfo login
7777
var shouldSignIn = autoLinkOptions.OnExternalLogin(user, loginInfo);
7878
if (shouldSignIn == false)
7979
{
80-
Logger.LogWarning("The AutoLinkOptions of the external authentication provider '{LoginProvider}' have refused the login based on the OnExternalLogin method. Affected user id: '{UserId}'", loginInfo.LoginProvider, user.Id);
80+
LogFailedExternalLogin(loginInfo, user);
81+
return ExternalLoginSignInResult.NotAllowed;
8182
}
8283
}
8384

@@ -192,7 +193,16 @@ private async Task<SignInResult> AutoLinkAndSignInExternalAccount(ExternalLoginI
192193
return AutoLinkSignInResult.FailedException(ex.Message);
193194
}
194195

195-
return await LinkUser(autoLinkUser, loginInfo);
196+
var shouldLinkUser = autoLinkOptions.OnExternalLogin == null || autoLinkOptions.OnExternalLogin(autoLinkUser, loginInfo);
197+
if (shouldLinkUser)
198+
{
199+
return await LinkUser(autoLinkUser, loginInfo);
200+
}
201+
else
202+
{
203+
LogFailedExternalLogin(loginInfo, autoLinkUser);
204+
return ExternalLoginSignInResult.NotAllowed;
205+
}
196206
}
197207
else
198208
{
@@ -225,7 +235,16 @@ private async Task<SignInResult> AutoLinkAndSignInExternalAccount(ExternalLoginI
225235
}
226236
else
227237
{
228-
return await LinkUser(autoLinkUser, loginInfo);
238+
var shouldLinkUser = autoLinkOptions.OnExternalLogin == null || autoLinkOptions.OnExternalLogin(autoLinkUser, loginInfo);
239+
if (shouldLinkUser)
240+
{
241+
return await LinkUser(autoLinkUser, loginInfo);
242+
}
243+
else
244+
{
245+
LogFailedExternalLogin(loginInfo, autoLinkUser);
246+
return ExternalLoginSignInResult.NotAllowed;
247+
}
229248
}
230249
}
231250
}
@@ -264,5 +283,8 @@ private async Task<SignInResult> LinkUser(BackOfficeIdentityUser autoLinkUser, E
264283
return AutoLinkSignInResult.FailedLinkingUser(errors);
265284
}
266285
}
286+
287+
private void LogFailedExternalLogin(ExternalLoginInfo loginInfo, BackOfficeIdentityUser user) =>
288+
Logger.LogWarning("The AutoLinkOptions of the external authentication provider '{LoginProvider}' have refused the login based on the OnExternalLogin method. Affected user id: '{UserId}'", loginInfo.LoginProvider, user.Id);
267289
}
268290
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
using Microsoft.AspNetCore.Identity;
2+
3+
namespace Umbraco.Cms.Web.BackOffice.Security
4+
{
5+
/// <summary>
6+
/// Result returned from signing in when external logins are used.
7+
/// </summary>
8+
public class ExternalLoginSignInResult : SignInResult
9+
{
10+
public static ExternalLoginSignInResult NotAllowed { get; } = new ExternalLoginSignInResult()
11+
{
12+
Succeeded = false
13+
};
14+
}
15+
}

0 commit comments

Comments
 (0)