Using E-mail for Sign In w/ LDAP Fallback Authentication

This forum is only for questions or discussions about working with the mojoPortal source code in Visual Studio, obtaining the source code from the repository, developing custom features, etc. If your question is not along these lines this is not the right forum. Please try to post your question in the appropriate forum.

Please do not post questions about design, CSS, or skinning here. Use the Help With Skins Forum for those questions.

This forum is for discussing mojoPortal development

This forum is only for questions or discussions about working with the mojoPortal source code in Visual Studio, obtaining the source code from the repository, developing custom features, etc. If your question is not along these lines this is not the right forum. Please try to post your question in the appropriate forum.

You can monitor commits to the repository from this page. We also recommend developers to subscribe to email notifications in the developer forum as occasionally important things are announced.

Before posting questions here you might want to review the developer documentation.

Do not post questions about design, CSS, or skinning here. Use the Help With Skins Forum for those questions.
This thread is closed to new posts. You must sign in to post in the forums.
3/30/2012 2:50:58 PM
Gravatar
Total Posts 18439

Re: Using E-mail for Sign In w/ LDAP Fallback Authentication

Another workaround you "could" use is to modify your copy of the stored procedure mp_Users_SelectByLoginName so that it also checks against the email address and returns the user row if it matches. It isn't an ideal thing to modify included procedures but that one has not changed in years and is not likely to change frequently if ever. That would be essentially making that SiteUser contsructor work no matter whether login name or email is passed in but only in your copy which is preferable to me than baking it in for everyone.

3/30/2012 4:12:47 PM
Gravatar
Total Posts 18439

Re: Using E-mail for Sign In w/ LDAP Fallback Authentication

What I am suggesting is to always use user Id for everything internally, including passing it to the SiteUser constructor. This way when user enters an e-mail for the username, we simply look up the user Id for that e-mail in Login.LogginIn event handler, re-assign UserName to the user Id and the proceed to pass it to SiteUser constructor.

SiteUser can always expect a user Id to be passed in to it, nothing else.

No, I don't like that idea. For LDAP users the cookie is going to have the loginname, and for the ones using email it would have the email address. you're suggesting sniffing the value of Context.User.Identity.Name to see if it looks like an email address then lookup ther username then lookup the user. Lots of extra weird logic and also additional hits to the database every time we lookup a user and big changes to code all to support this edge case of wanting to use email/database authentication in addition to ldap but also don't want to put the email address in the loginname field because we are using it to relate to some other custom data.

For this scenario, given the extra requirement that you don't want to put the email address in the LoginName field, I think the best solution is just modify the procedure like this:

ALTER PROCEDURE [dbo].[mp_Users_SelectByLoginName]


@SiteID int,
@LoginName nvarchar(50)

AS

SELECT *

FROM
mp_Users

WHERE
SiteID = @SiteID
AND (LoginName = @LoginName
OR Email =  @LoginName)


GO

Simple and effective and not really likely that this procedure will ever be modified by future upgrades. Not saying it could never happen but I don't expect it to, and it hasn't changed in many years so it hasn't been touched by an upgrade script in many years.

This would immediately meet your goal and seems like a reasonable solution to me for this particular scenario.

3/30/2012 4:46:08 PM
Gravatar
Total Posts 18439

Re: Using E-mail for Sign In w/ LDAP Fallback Authentication

Ok, I just got a good idea for how to do this without any changes that seem onerous to me.

  1. we promote the config setting for UseLDAPFallbackAuthentication to a site setting 
  2. we add another site setting for Allow Email Authentication with LDAP
  3. we add a bit parameter to the stored procedure mp_Users_SelectByLoginName to indicate whether to check also againts the email
  4. we set that parameter according to the site settings
So the procedure would change like this:
 
ALTER PROCEDURE [dbo].[mp_Users_SelectByLoginName]

@SiteID int,
@LoginName nvarchar(50),
@AllowEmail bit

AS

SELECT *

FROM
mp_Users

WHERE
SiteID = @SiteID
AND (LoginName = @LoginName
OR (@AllowEmail = 1 AND Email = @LoginName))

How does that sound to you?

 

3/30/2012 9:57:42 PM
Gravatar
Total Posts 156

Re: Using E-mail for Sign In w/ LDAP Fallback Authentication

No, I don't like that idea. For LDAP users the cookie is going to have the loginname, and for the ones using email it would have the email address. you're suggesting sniffing the value of Context.User.Identity.Name to see if it looks like an email address then lookup ther username then lookup the user. Lots of extra weird logic and also additional hits to the database every time we lookup a user and big changes to code all to support this edge case of wanting to use email/database authentication in addition to ldap but also don't want to put the email address in the loginname field because we are using it to relate to some other custom data.

I never suggested anything of this sort. I probably shouldn't have used the word "convert" earlier in this thread as that might have been a bit misleading.

So, looking at the authentication workflow, here's what I see in your code:

  1. ~/Secure/Login.aspx  includes <mp:Login>   which is LoginControl.ascx
  2. Inside LoginControl.ascx, everything is wrapped by <portal:SiteLogin> which is defined in SiteLogin.cs
  3. SiteLogin.cs inherits from System.Web.UI.WebControls.Login and this is where you plug into .Net security framework.
  4. After the user hits "Sign In,"  Login.LoggingIn event is raised which is handled by SiteLogin_LoggingIn where SiteUser is initialized using SiteUser(SiteSettings settings, string login) constructor
  5. Inside SiteUser constructor mentioned in #4, GetUser(string logInfo) is called, keeping in mind that logInfo could be either user Id or an e-mail at this point.
  6. Inside GetUser mentioned in #5, you have the following logic: 
if((siteSettings.UseEmailForLogin) && (!siteSettings.UseLdapAuth) &&(loginInfo.Contains("@")))
{
  using (reader = DBSiteUser.GetSingleUser(siteID, loginInfo))
  {
    GetUser(reader);
  }
}
else
{
  using (reader = DBSiteUser.GetSingleUserByLoginName(siteID, loginInfo))
  {
    GetUser(reader);
  }
 
This would have been the first place where you would make changes to the conditional statement to see if the newly introduced siteSettings.AllowEmailAuthenticationWithLDAP is set to true and use DBSiteUser.GetSingleUser(int siteId, string email) function which utilizes Email in mp_Users table.

Once this has been handled, then the Authenticate  event will be raised behind the scenes and .Net will start calling on your mojoMemebershipProvider where ValidateUser() and other functions and files would be the places where you would have to modify your conditionals to use either DBSiteUser.LoginByEmail() or DBSiteUser.Login().

 

This would involve more C# changes, but let you keep your stored procedures intact.  This is what I was suggesting from the very beginning.

I like your latest suggestion because I think it's an elegant and quick solution.  The only down side I see is that the existent user retrieval and validation code inside SiteUser.cs and mojoMembershipProvider.cs will not contain any logic for the change we are discussing as these changes would affect *.config files,  ~/Admin/SiteSettings.aspx(.cs) and mp_Users_SelectByLoginName stored procedure.  While it's an easier route to go, I don't think it's the most appropriate place for the logic.

In my humble opinion, if I were looking at your code for the first time to see how you authenticate users based on site settings, I would expect the new siteSettings.AllowEmailAuthenticationWithLDAP to be right there along with siteSettings.UseEmailForLogin and siteSettings.UseLdapAuth inside your conditionals.

It is your call though.  
 
I really appreciate your willingness to make this change.  Thank you so much for agreeing to accommodate this corner case of ours.
 
 
Respectfully,
Alex 

 

 

3/31/2012 6:49:48 AM
Gravatar
Total Posts 18439

Re: Using E-mail for Sign In w/ LDAP Fallback Authentication

Hi Alex,

The only down side I see is that the existent user retrieval and validation code inside SiteUser.cs and mojoMembershipProvider.cs will not contain any logic for the change we are discussing

That isn't the way I see it, this would be used at the point we lookup the user in mojoMembershipProvider ValidateUser method and it would use rules based on sitesettings passed into the constructor of siteUser. Looking up the user in onloggingin is like looking up the user before we lookup the user, its redundant and creates extra hits to the db and puts the logic more in the UI code.

Also its not just initial login where this matters. The auth cookie which is reflected in Context.User.Identity.Name is going to be LoginName for ladp users and EmailAddress for non ldap users in this scenario because the login control is going to set this cookie using whatever was passed in the textbox and validated by membership provider. Once the cookie is set membership provider is not involved on subsequent requests where the user is looked up by SiteUtils.GetCurrentSiteUser and again its going to pass sitesettings into the constructor and use the rules established on site settings to set the bit parameter for the stored procedure to true for AllowEmailFallback if and only if UseLDAP is true, AllowDbFallBackForLDAP is true and AllowEmailWithDBFallback is true. So it will be consistently enforced by the business objects both inside mojoMembershipProvider and outside it without any need for extra lookups and logic coded into the LoginControl. This also makes it more consistent when using other things like the AuthenticationService without having to code in extra rules into more places. mojoMembershipProvider is just an API wrapped around the business objects and the stored procedure is just doing what the business objects tell it to. The conditional logic you referenced is exactly where you will see the additional parameter passed into DBSiteUser.GetSingleUserByLoginName(siteId, loginInfo, allowEmailFallback) 

This is a clean and correct solution in my opinion. I'll implement it next week.

Best,

Joe

4/2/2012 11:35:14 AM
Gravatar
Total Posts 18439

Re: Using E-mail for Sign In w/ LDAP Fallback Authentication

This is now implemented in the source code repository, see the 2 new settings under the LDAP Settings tab in site settings.

Note that the previous web.config setting for UseLDAPFallbackAuthentication is no longer used as it has been replaced by a site setting. 

I would appreciate if you and Jamie could test this since I'm not currently setup to test with LDAP.

Thanks,

Joe

4/2/2012 1:27:49 PM
Gravatar
Total Posts 1203
Proud member of the mojoPortal team

Help support mojoPortal!
Add-on modules

Re: Using E-mail for Sign In w/ LDAP Fallback Authentication

Hi Joe, I'll try to test this soon and report back.

Jamie

4/3/2012 1:37:10 PM
Gravatar
Total Posts 1203
Proud member of the mojoPortal team

Help support mojoPortal!
Add-on modules

Re: Using E-mail for Sign In w/ LDAP Fallback Authentication

Hi Joe, here are the scenarios I tested, and all work:

  • LDAP fallback off: LDAP login works, database login fails
  • LDAP fallback on: LDAP and database login work
  • Allow sign-in with email: LDAP login by user ID works, LDAP login by email fails, database login by userid or email work

So it looks like everything is working as intended.

As an aside, one thing I noticed is that when LDAP fallback authentication is enabled with fallback off, the password field is hidden in the member list manage user interface. I think for consistency it should also probably hide the "User Must Change Password" checkbox in that case, since that really doesn't make sense in an LDAP-only environment.

Also, do you think the sign in ID textbox label needs to change? But maybe not, since I'm not sure if showing "User ID or Email" would be good, since LDAP still can't log in by email address.

Jamie

4/3/2012 1:47:30 PM
Gravatar
Total Posts 18439

Re: Using E-mail for Sign In w/ LDAP Fallback Authentication

Hi Jamie,

Thanks a lot for testing this. Good point on hiding the user must change password when its ldap only, I'll do that.

I don't think we need to worry about the label, I've seen sites where they label it user id but the email address is the user id, and there isn't a clear way to label it that makes sense for both ldap users and user who sign in by email other than for the email users to just know that the user id is their email address. I don't think we would want to give away any info cluing people in that it also uses ldap.

Thanks,

Joe

4/3/2012 1:54:40 PM
Gravatar
Total Posts 18439

Re: Using E-mail for Sign In w/ LDAP Fallback Authentication

I would like to point out that technically ldap users could login with their email address since a database user is created for every ldap user and we must populate the pwd field with something so we generate a random password. An LDAP user could find out this random password by password recovery and then login using their email address and the mojoportal password instead of the ldap password. But this is also true when not allowing email, but still allowing database fallback, the user could login using either their ldap credentials or their username and mojoPortal password. So in any case where database authentication is allowed it is possible to login using the database credentials.

Best,

Joe

4/3/2012 3:01:08 PM
Gravatar
Total Posts 1203
Proud member of the mojoPortal team

Help support mojoPortal!
Add-on modules

Re: Using E-mail for Sign In w/ LDAP Fallback Authentication

True, that's a good point, Joe. When we went live with our Intranet site I hadn't turned off password reset, so a couple of people had forgotten they were supposed to use their Windows passwords and tried to reset their passwords. Luckily they called the help desk and we were able to educate them. I turned off the recovery option for that site to avoid any confusion. It'll be nice to be able to set LDAP database fallback per site, because now for the Intranet site I'll be able to disable fallback authentication altogether. Laughing

Jamie

You must sign in to post in the forums. This thread is closed to new posts.