Welcome to the Axosoft Community, Sign in | Register | Help
in Search

Logging on to customer portal with Windows Authentication

Last post 05-30-2008, 7:39 AM by Mark. 8 replies.
Sort Posts: Previous Next
  •  02-19-2008, 11:45 AM 15079

    Logging on to customer portal with Windows Authentication
    I am trying to have my users log onto the customer portal with their accounts set to Windows ID in User Setup. But it won't let them. The account has to be on OnTime Built-in Authentication. Is there anyway to resolve this?
  •  02-20-2008, 1:00 PM 15099 in reply to 15079

    Re: Logging on to customer portal with Windows Authentication

    I don't believe there is any built in way to do this...you could probably get something working using the external authentication settings of Customer Portal. But customer portal customers don't have any built-in way of support windows-based authentication.

    Jonas 


    Axosoft Development Team
    Blog
  •  02-22-2008, 10:01 AM 15122 in reply to 15099

    • Mark is not online. Last active: 07-24-2008, 12:56 PM Mark
    • Top 500 Contributor
      Male
    • Joined on 11-02-2007
    • Raleigh, NC
    • Posts 7
    • Points 161
    Re: Logging on to customer portal with Windows Authentication

    You can indeed use the External Authentication settings to authenticate against active directory.  It took us a bit of effort to get things working.

    This seems like a popular feature request.  Hopefully Axosoft will make this a supported feature in the near future.

    Following is the code we got working.   

    See the administrators guide for information on the settings that must be changed to make external authentication work. (You must make sure the GUID matches what is in the following code)

    You will have to put in your domain settings in the 'ActiveDirectoryAuthentication' method.  This sits in a single aspx page in the root folder of the customer portal.

     Smile  Cheers

     

    <%@ Page Language="C#" Debug="true"  %>
    <%@ Import Namespace="System.Web" %>
    <%@ Assembly Name="System.DirectoryServices, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" %>
    <%@ Import Namespace="System.DirectoryServices" %>
    <%@ Import Namespace="System.Runtime.InteropServices" %>
    <%@ Import Namespace="Axosoft.CustomerPortal.Security" %>

    <script runat="server">
       
        class UserInfo
        {
            public string Company;
            public string FirstName;
            public string LastName;
            public string Email;
            public string ErrorMessage;
            public int ErrorCode;
            public bool Authenticated;

            public UserInfo()
            {
                Company = string.Empty;
                FirstName = string.Empty;
                LastName = string.Empty;
                Email = string.Empty;
                ErrorMessage = string.Empty;
                Authenticated = false;
            }
        }

        private void Page_Load(object sender, System.EventArgs e)
        {
            if (Request.QueryString["Register"] == "1" || Request.QueryString["ForgotPassword"] == "1")
            {
                return;
            }
           
            string UserID = Request.Form["PortalEmail"];
            string Password = Request.Form["PortalPassword"];
            string returnUrl = Request.QueryString["ReturnURL"];

            if (string.IsNullOrEmpty(returnUrl))
            {
                returnUrl = "Default.aspx";
            }
           
            if (Request.QueryString["Logout"] == "1")
            {
                ExpireOntimeCookie();
                Response.Redirect(returnUrl);
                return;
            }


            //we aren't logging out so we log them in.
            if (string.IsNullOrEmpty(UserID) || string.IsNullOrEmpty(Password))
            {
                if (returnUrl.Contains("?"))
                {
                    returnUrl += "&InvalidLogin=1";
                }
                else
                {
                    returnUrl += "?InvalidLogin=1";
                }
                Response.Redirect(returnUrl);
            }

            bool success = Authenticate(UserID, Password);

            if (!success)
            {
                if (returnUrl.Contains("?"))
                {
                    returnUrl += "&InvalidLogin=1";
                }
                else
                {
                    returnUrl += "?InvalidLogin=1";
                }
            }
            Response.Redirect(returnUrl);
        }

        private void ExpireOntimeCookie()
        {
            HttpCookie portalCookie = Request.Cookies["PortalUser"];
            if (portalCookie != null)
            {
                //update the expiration on the portal cookie so that customer portal will correctly detect a logged out user
                Axosoft.CustomerPortal.Security.SecurityProvider customerPortalSecurity = new SecurityProvider();
                portalCookie.Expires = DateTime.Now.AddMinutes(-10);
                portalCookie["Expires"] = HttpUtility.UrlEncode(customerPortalSecurity.EncryptString(portalCookie.Expires.ToString("s")));
                Response.Cookies.Set(portalCookie);
                //Response.Write("Cookie Set<br />");
                //Response.Write(portalCookie.Expires.ToString());
            }
        }

        private bool Authenticate(string UserId, string Password)
        {
            bool success = false;
            UserInfo userData = ActiveDirectoryAuthentication(UserId, Password);

            if (userData.Authenticated)
            {
                CreateOntimeCookie(userData);
                success = true;
            }
            return success;
        }

        private void CreateOntimeCookie(UserInfo user)
        {
            HttpCookie portalCookie = new HttpCookie("PortalUser");
            SecurityProvider customerPortalSecurity = new SecurityProvider();

            portalCookie["PortalEmail"] = HttpUtility.UrlEncode(customerPortalSecurity.EncryptString(user.Email));
            portalCookie["PortalFirstName"] = HttpUtility.UrlEncode(customerPortalSecurity.EncryptString(user.FirstName));
            portalCookie["PortalLastName"] = HttpUtility.UrlEncode(customerPortalSecurity.EncryptString(user.LastName));
            portalCookie["PortalCompany"] = HttpUtility.UrlEncode(customerPortalSecurity.EncryptString(user.Company));

            portalCookie["guid"] = HttpUtility.UrlEncode(customerPortalSecurity.EncryptString("C0DF8003-CC61-4c51-9A0F-EA21631C7199"));
            portalCookie.Expires = DateTime.Now.AddMinutes(this.Session.Timeout);
            portalCookie["Expires"] = HttpUtility.UrlEncode(customerPortalSecurity.EncryptString(portalCookie.Expires.ToString("s")));
            portalCookie.Domain = "ontime.office.abanes.org";
            portalCookie.Path = "/";

            Response.Cookies.Set(portalCookie);
            Response.Write("logged in");
        }

        private UserInfo ActiveDirectoryAuthentication(string UserId, string Password)
        {
            string Domain = "YOURDOMAINHERE";
            string Account = Domain + "\\" + UserId;
            DirectoryEntry searchRoot = new DirectoryEntry("LDAP://DC=host,DC=name,DC=com", Account, Password, AuthenticationTypes.ReadonlyServer);

            UserInfo userInfo = new UserInfo();
            userInfo.Company = Domain;

            //find the users information in Active Directory       
            DirectorySearcher searcher = null;
            try
            {
                string filter = "(&(objectClass=user)(sAMAccountName=" + UserId + "))";
                string[] propertiesToLoad = new string[] { "givenName", "sn", "mail" };
                searcher = new DirectorySearcher(searchRoot, filter, propertiesToLoad);

                SearchResult result = searcher.FindOne();  //because of late binding this is where the real AD authentication happens
                if (result != null)
                {
                    ResultPropertyCollection properties = result.Properties;
                    userInfo.FirstName = properties["givenName"][0].ToString();
                    userInfo.LastName = properties["sn"][0].ToString();
                    userInfo.Email = properties["mail"][0].ToString();
                    userInfo.Authenticated = true;
                }
            }
            catch (COMException exp)
            {
                userInfo.ErrorMessage = exp.Message;
                userInfo.ErrorCode = exp.ErrorCode;
            }
            finally
            {
                if (searcher != null)
                {
                    searcher.Dispose();
                }
                if (searchRoot != null)
                {
                    searchRoot.Dispose();
                }
            }
            return userInfo;
        }
    </script>

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
            "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head><title>Ontime for The ABA</title></head>
    <body>
    <div>
        This site is configured to authenticate against the domain. So there is not need to register<br />
        <br />
        Do not use your email address to log in.  Instead use your domain user id and password.  The same id and password you use to log in to your computer.
        <br />
        <br />
        <form method="get" action="Default.aspx">
        <input type="submit" id="home" name="home" value="home&gt;&gt;" />
        </form>
    </div>
    </body>
    </html>

     

    Filed under: , ,
  •  03-21-2008, 12:03 PM 15398 in reply to 15122

    • Jesse is not online. Last active: 03-26-2008, 3:16 PM Jesse
    • Not Ranked
      Male
    • Joined on 03-20-2008
    • Santa Barbara, CA
    • Posts 2
    • Points 47
    Re: Logging on to customer portal with Windows Authentication

    Nice work. I got the authentication to work, but it doesn't seem like a cookie is getting created. We're running on a intranet and customer portal is http://helpdesk/ so should the domain be "helpdesk"? I used firefox to look at the cookies and there is only a ASP.NET_SessionId Cookie. There is supposed to be another one called PortalUser right? Any ideas?

     
    Thanks, Jesse 

  •  03-24-2008, 1:37 PM 15414 in reply to 15398

    Re: Logging on to customer portal with Windows Authentication
    Hrm, for an intranet I'm not 100% sure...I know when testing locally, I was able to use "mymachinename.mydomainname.local" as the cookie domain, and it worked. Does that work for you, if you ping "helpdesk.mydomain.local" does that work?

    Axosoft Development Team
    Blog
  •  03-26-2008, 2:00 PM 15438 in reply to 15398

    • Mark is not online. Last active: 07-24-2008, 12:56 PM Mark
    • Top 500 Contributor
      Male
    • Joined on 11-02-2007
    • Raleigh, NC
    • Posts 7
    • Points 161
    Re: Logging on to customer portal with Windows Authentication

    Jesse,

     By "domain" I assume you mean cookie domain.  Yes there should be a cookie called PortalUser.  In FireFox it should show up in the same "site" folder along with a cookie named ASP.NET_SessionID and usually a cookie named RadEditorGlobalSerializeCookie.

    You will have to change that setting in the code.  You could try setting the cookie domain to "helpdesk" but I think you will have to use a fully qualified domain like "helpdesk.yourdomain.com".  That may depend on how you have configured OnTime.  For us if a user starts at "ontime" (our host name) they get redirected to ontime.ourdomain.org.

    HTH,
    Mark
     

  •  03-26-2008, 3:16 PM 15439 in reply to 15438

    • Jesse is not online. Last active: 03-26-2008, 3:16 PM Jesse
    • Not Ranked
      Male
    • Joined on 03-20-2008
    • Santa Barbara, CA
    • Posts 2
    • Points 47
    Re: Logging on to customer portal with Windows Authentication

    Thanks Mark and Jonas for your suggestions. Unfortunately I have not figured out what the correct cookie domain is. "helpdesk" is a dns alias for one of our app servers so that could be the problem. I tried the full domain name of the app server and the alias but nothing worked.

    I did find a workaround though. By not setting the cookie domain (both in code and OnTime settings), it worked fine. I realize this is not a perfect solution but the cookie is encrypted so I am not too worried. The cookie is no longer called PortalUser either.

     

    Thanks again,

    Jesse
     

  •  05-29-2008, 10:25 AM 15858 in reply to 15122

    Re: Logging on to customer portal with Windows Authentication

    Thanks for sharing this with us, it must have taken sometime to get working!

    Is there a way to change the label for the email field on the login page, our users will always forget that they should enter their network login instead of their email otherwise.

  •  05-30-2008, 7:39 AM 15865 in reply to 15858

    • Mark is not online. Last active: 07-24-2008, 12:56 PM Mark
    • Top 500 Contributor
      Male
    • Joined on 11-02-2007
    • Raleigh, NC
    • Posts 7
    • Points 161
    Re: Logging on to customer portal with Windows Authentication

    Unfortunately there is not a way to change the labels and fields on the login page.  Those are complied into an Axosoft assembly. 

    The other approach that you could take is to use email instead of userid in the authentication process.  This would require all users to have an email address in Active Directory, but that is usually the case.   To do this you would have to change the code in the ActiveDirectoryAuthentication method and instead of filtering your directory search on user id (sAMAccountName is the attribute AD stores the userid in) you would filter on email.  Like so:

    instead of

    string filter = "(&(objectClass=user)(sAMAccountName=" + UserId + "))";

    do this 

    string filter = "(&(objectClass=user)(mail=" + UserId + "))";

    Give it a try.

    Mark

     PS.  There is a bug in firefox that prevents users from logging off of the customer portal.  I did some troubleshooting, and the Customer portal does what it is supposed to and sets the cookie expiration date correctly, but Firefox doesn't save the updates to the cookie.   I didn't have the same problem with IE.

    Just thought I should make you and anyone who read this aware. 

View as RSS news feed in XML

© 2002 - 2007, Axosoft, LLC. All Rights Reserved. | Privacy
Bug Tracking | Defect Tracking Videos | Help Desk Software