Page 1 of 1

LDAP authentication plus

PostPosted: Tue May 16, 2017 2:58 pm
by VarPippo
I followed the instructions available here https://www.aspnetboilerplate.com/Pages ... entication to configure the LDAP authentication and it's working as expected when invoked via:

Code: Select all private async Task<AbpLoginResult<Tenant, User>> GetLoginResultAsync(string usernameOrEmailAddress, string password, string tenancyName)
        {
            var loginResult = await _logInManager.LoginAsync(usernameOrEmailAddress, password, tenancyName);

            switch (loginResult.Result)
            {
                case AbpLoginResultType.Success:
                    return loginResult;
                default:
                    throw CreateExceptionForFailedLoginAttempt(loginResult.Result, usernameOrEmailAddress, tenancyName);
            }
        }


TryAuthenticateAsync is invoked as expected and it works smoothly, but I'd need to use 2 distinct authentication methods:

    * LdapAuthenticationSource --> TryAuthenticateAsync if userNameOrEmailAddress is an e-mail address OR if it's in the format domain\username
    * The local data (e.g. accounts available in dbo.AbpUsers) otherwise

Is there any way to combine the default authentication mechanism (=without LDAP/External source) with LDAP, based on some conditions?

I mean, is there any way to "chain" different authentication approaches as fallbacks ?
As an alternative, is it possible to invoke the "local" authentication from inside TryAuthenticateAsync in case usernameOrEmailAddress is not a valid username/e-mail?

Re: LDAP authentication plus

PostPosted: Thu May 18, 2017 6:41 am
by ismcagdas
Hi,

This is not possible by default but you have two options.

1. Define your own loginManager whic is derived from AbpLoginManager and ovverride LoginAsync method to do this.
2. Define an external auto source for example MixedExternalAuthSource (you can find a better name :)), and call Ldap and Local auth sources conditionally in it.
https://aspnetboilerplate.com/Pages/Doc ... entication

Thanks.

Re: LDAP authentication plus

PostPosted: Thu May 18, 2017 10:21 am
by VarPippo
Hi!

Thank you for your feedback :idea:

I managed to implement it as follows:

1) In the Web project GetLoginResultAsync invokes:
Code: Select allvar loginResult = await _logInManager.LoginAsync(usernameOrEmailAddress, password, tenancyName, false);


2) TryAuthenticateAsync takes this actions:
    * It tries to understand if userNameOrEmailAddress is a valid&known e-mail or domain\username
    * Invokes ValidateCredentials only if userNameOrEmailAddress exists in AD
    * In all other cases it returns false

3) var loggedInFromExternalSource = await TryLoginFromExternalAuthenticationSources(userNameOrEmailAddress, plainPassword, tenant);

can be either true (the authentication through LDAP went fine) or false (userNameOrEmailAddress is invalid / not existing). If it's false the default LoginAsyncInternal method is smart enough to attempt an "internal" authentication:

Code: Select all return await CreateLoginResultAsync(user, tenant);


I hope that helps someone ;)

PS. I implemented CreateUserAsync to store in dbo.AbpUsers information like Username/Mail/First name/Last name obtained from AD and it works perfectly, but I'm not sure if it makes sense to have a UpdateUserAsync like this in the class derived from LdapAuthenticationSource:

Code: Select all public async override Task UpdateUserAsync(User user, Tenant tenant)
        {
            await Task.Run(() => { }); // Nothing to do for the time being. LastLoginTime and other fields are updated automatically?
        }


We don't want to update users created with AuthenticationSource = LDAP

Re: LDAP authentication plus

PostPosted: Thu May 18, 2017 10:33 am
by VarPippo
Using the approach described above we allow the users to login using one of the following options:

LDAP:
- Valid AD e-mail address and AD password
- Valid AD domain\username and AD password
- Valid AD username and AD password

if the authentication fails, a last attempt is made:

LOCAL DATABASE:
- Valid combination of username / password ( Configuration.MultiTenancy.IsEnabled is commented out, so hopefully we disabled multi-tenancy :) )

We really appreciate the design behind ASP.NET Boilerplate! 8-)

Re: LDAP authentication plus

PostPosted: Fri May 19, 2017 6:35 am
by ismcagdas
Hi @VarPippo,

Thank you very much for sharing your solution and detailed explanation :).
The reason for UpdateUserAsync is, information of user on Ldap might change.

User can move to another group, can get married and have a different surname :) etc..., but you don't have to use it.

Thanks again.

Re: LDAP authentication plus

PostPosted: Fri May 19, 2017 12:20 pm
by VarPippo
Thank you!

We're storing some basic details in AbpUsers with CreateUserAsync , but essentially we need only a standardized format of the username: regardless to what is used for the first login (username, domain\username, e-mail), we convert the username to the AD username. Some additional details like first name and last name are retrieved and stored, but we're not using them in any way.

So, as long as, having an "empty" UpdateUserAsync method does not create any issues to ASP.NET Boilerplate inner mechanisms, I'm fine with that!
:D