Override username with AuthenticationProvider
Pass back the Username directive returned by an AuthenticationProvider to the calling code, so we may override the user-provided Username value if the authentication provider passes this back. Useful for instance in an LDAP scenario where what the user types may not necessarily be the "username" that is mapped in the system, e.g. the user providing 'mail' while 'uid' is the "username" value. Could also then be extensible to other authentication providers as well, should they wish to do a similar thing.
This commit is contained in:
parent
2d19bfa7fb
commit
1af9c047fb
|
@ -277,24 +277,35 @@ namespace Emby.Server.Implementations.Library
|
|||
.FirstOrDefault(i => string.Equals(username, i.Name, StringComparison.OrdinalIgnoreCase));
|
||||
|
||||
var success = false;
|
||||
string updatedUsername = null;
|
||||
IAuthenticationProvider authenticationProvider = null;
|
||||
|
||||
if (user != null)
|
||||
{
|
||||
var authResult = await AuthenticateLocalUser(username, password, hashedPassword, user, remoteEndPoint).ConfigureAwait(false);
|
||||
authenticationProvider = authResult.Item1;
|
||||
success = authResult.Item2;
|
||||
updatedUsername = authResult.Item2;
|
||||
success = authResult.Item3;
|
||||
}
|
||||
else
|
||||
{
|
||||
// user is null
|
||||
var authResult = await AuthenticateLocalUser(username, password, hashedPassword, null, remoteEndPoint).ConfigureAwait(false);
|
||||
authenticationProvider = authResult.Item1;
|
||||
success = authResult.Item2;
|
||||
updatedUsername = authResult.Item2;
|
||||
success = authResult.Item3;
|
||||
|
||||
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;
|
||||
if (hasNewUserPolicy != null)
|
||||
|
@ -414,32 +425,40 @@ namespace Emby.Server.Implementations.Library
|
|||
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
|
||||
{
|
||||
var requiresResolvedUser = provider as IRequiresResolvedUser;
|
||||
ProviderAuthenticationResult authenticationResult = null;
|
||||
if (requiresResolvedUser != null)
|
||||
{
|
||||
await requiresResolvedUser.Authenticate(username, password, resolvedUser).ConfigureAwait(false);
|
||||
authenticationResult = await requiresResolvedUser.Authenticate(username, password, resolvedUser).ConfigureAwait(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
await provider.Authenticate(username, password).ConfigureAwait(false);
|
||||
authenticationResult = await provider.Authenticate(username, password).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
return true;
|
||||
if(authenticationResult.Username != username)
|
||||
{
|
||||
_logger.LogDebug("Authentication provider provided updated username {1}", authenticationResult.Username);
|
||||
username = authenticationResult.Username;
|
||||
}
|
||||
|
||||
return new Tuple<string, bool>(username, true);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_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;
|
||||
IAuthenticationProvider authenticationProvider = null;
|
||||
|
||||
|
@ -458,11 +477,14 @@ namespace Emby.Server.Implementations.Library
|
|||
{
|
||||
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)
|
||||
{
|
||||
authenticationProvider = provider;
|
||||
username = updatedUsername;
|
||||
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)
|
||||
|
|
Loading…
Reference in New Issue
Block a user