|
@@ -277,24 +277,35 @@ namespace Emby.Server.Implementations.Library
|
|
.FirstOrDefault(i => string.Equals(username, i.Name, StringComparison.OrdinalIgnoreCase));
|
|
.FirstOrDefault(i => string.Equals(username, i.Name, StringComparison.OrdinalIgnoreCase));
|
|
|
|
|
|
var success = false;
|
|
var success = false;
|
|
|
|
+ string updatedUsername = null;
|
|
IAuthenticationProvider authenticationProvider = null;
|
|
IAuthenticationProvider authenticationProvider = null;
|
|
|
|
|
|
if (user != null)
|
|
if (user != null)
|
|
{
|
|
{
|
|
var authResult = await AuthenticateLocalUser(username, password, hashedPassword, user, remoteEndPoint).ConfigureAwait(false);
|
|
var authResult = await AuthenticateLocalUser(username, password, hashedPassword, user, remoteEndPoint).ConfigureAwait(false);
|
|
authenticationProvider = authResult.Item1;
|
|
authenticationProvider = authResult.Item1;
|
|
- success = authResult.Item2;
|
|
|
|
|
|
+ updatedUsername = authResult.Item2;
|
|
|
|
+ success = authResult.Item3;
|
|
}
|
|
}
|
|
else
|
|
else
|
|
{
|
|
{
|
|
// user is null
|
|
// user is null
|
|
var authResult = await AuthenticateLocalUser(username, password, hashedPassword, null, remoteEndPoint).ConfigureAwait(false);
|
|
var authResult = await AuthenticateLocalUser(username, password, hashedPassword, null, remoteEndPoint).ConfigureAwait(false);
|
|
authenticationProvider = authResult.Item1;
|
|
authenticationProvider = authResult.Item1;
|
|
- success = authResult.Item2;
|
|
|
|
|
|
+ updatedUsername = authResult.Item2;
|
|
|
|
+ success = authResult.Item3;
|
|
|
|
|
|
if (success && authenticationProvider != null && !(authenticationProvider is DefaultAuthenticationProvider))
|
|
if (success && authenticationProvider != null && !(authenticationProvider is DefaultAuthenticationProvider))
|
|
{
|
|
{
|
|
- user = await CreateUser(username).ConfigureAwait(false);
|
|
|
|
|
|
+ // We should trust the user that the authprovider says, not what was typed
|
|
|
|
+ if (updatedUsername != username)
|
|
|
|
+ {
|
|
|
|
+ username = updatedUsername;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // Search the database for the user again; the authprovider might have created it
|
|
|
|
+ user = Users
|
|
|
|
+ .FirstOrDefault(i => string.Equals(username, i.Name, StringComparison.OrdinalIgnoreCase));
|
|
|
|
|
|
var hasNewUserPolicy = authenticationProvider as IHasNewUserPolicy;
|
|
var hasNewUserPolicy = authenticationProvider as IHasNewUserPolicy;
|
|
if (hasNewUserPolicy != null)
|
|
if (hasNewUserPolicy != null)
|
|
@@ -414,32 +425,40 @@ namespace Emby.Server.Implementations.Library
|
|
return providers;
|
|
return providers;
|
|
}
|
|
}
|
|
|
|
|
|
- private async Task<bool> AuthenticateWithProvider(IAuthenticationProvider provider, string username, string password, User resolvedUser)
|
|
|
|
|
|
+ private async Task<Tuple<string, bool>> AuthenticateWithProvider(IAuthenticationProvider provider, string username, string password, User resolvedUser)
|
|
{
|
|
{
|
|
try
|
|
try
|
|
{
|
|
{
|
|
var requiresResolvedUser = provider as IRequiresResolvedUser;
|
|
var requiresResolvedUser = provider as IRequiresResolvedUser;
|
|
|
|
+ ProviderAuthenticationResult authenticationResult = null;
|
|
if (requiresResolvedUser != null)
|
|
if (requiresResolvedUser != null)
|
|
{
|
|
{
|
|
- await requiresResolvedUser.Authenticate(username, password, resolvedUser).ConfigureAwait(false);
|
|
|
|
|
|
+ authenticationResult = await requiresResolvedUser.Authenticate(username, password, resolvedUser).ConfigureAwait(false);
|
|
}
|
|
}
|
|
else
|
|
else
|
|
{
|
|
{
|
|
- await provider.Authenticate(username, password).ConfigureAwait(false);
|
|
|
|
|
|
+ authenticationResult = await provider.Authenticate(username, password).ConfigureAwait(false);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if(authenticationResult.Username != username)
|
|
|
|
+ {
|
|
|
|
+ _logger.LogDebug("Authentication provider provided updated username {1}", authenticationResult.Username);
|
|
|
|
+ username = authenticationResult.Username;
|
|
}
|
|
}
|
|
|
|
|
|
- return true;
|
|
|
|
|
|
+ return new Tuple<string, bool>(username, true);
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
catch (Exception ex)
|
|
{
|
|
{
|
|
_logger.LogError(ex, "Error authenticating with provider {provider}", provider.Name);
|
|
_logger.LogError(ex, "Error authenticating with provider {provider}", provider.Name);
|
|
|
|
|
|
- return false;
|
|
|
|
|
|
+ return new Tuple<string, bool>(username, false);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
- private async Task<Tuple<IAuthenticationProvider, bool>> AuthenticateLocalUser(string username, string password, string hashedPassword, User user, string remoteEndPoint)
|
|
|
|
|
|
+ private async Task<Tuple<IAuthenticationProvider, string, bool>> AuthenticateLocalUser(string username, string password, string hashedPassword, User user, string remoteEndPoint)
|
|
{
|
|
{
|
|
|
|
+ string updatedUsername = null;
|
|
bool success = false;
|
|
bool success = false;
|
|
IAuthenticationProvider authenticationProvider = null;
|
|
IAuthenticationProvider authenticationProvider = null;
|
|
|
|
|
|
@@ -458,11 +477,14 @@ namespace Emby.Server.Implementations.Library
|
|
{
|
|
{
|
|
foreach (var provider in GetAuthenticationProviders(user))
|
|
foreach (var provider in GetAuthenticationProviders(user))
|
|
{
|
|
{
|
|
- success = await AuthenticateWithProvider(provider, username, password, user).ConfigureAwait(false);
|
|
|
|
|
|
+ var providerAuthResult = await AuthenticateWithProvider(provider, username, password, user).ConfigureAwait(false);
|
|
|
|
+ updatedUsername = providerAuthResult.Item1;
|
|
|
|
+ success = providerAuthResult.Item2;
|
|
|
|
|
|
if (success)
|
|
if (success)
|
|
{
|
|
{
|
|
authenticationProvider = provider;
|
|
authenticationProvider = provider;
|
|
|
|
+ username = updatedUsername;
|
|
break;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -484,7 +506,7 @@ namespace Emby.Server.Implementations.Library
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
- return new Tuple<IAuthenticationProvider, bool>(authenticationProvider, success);
|
|
|
|
|
|
+ return new Tuple<IAuthenticationProvider, string, bool>(authenticationProvider, username, success);
|
|
}
|
|
}
|
|
|
|
|
|
private void UpdateInvalidLoginAttemptCount(User user, int newValue)
|
|
private void UpdateInvalidLoginAttemptCount(User user, int newValue)
|