Using Windows Authentication

Post suggestions and request features for ScrewTurn Wiki.

Using Windows Authentication

Postby samward » Thu Oct 19, 2006 9:56 am

Hi all,

I apologise if this has been asked already, but I could not find an exact answer in any previous posts.

I have been looking for a wiki to use in a corporate environment, and Screwturn seems like a fantastic wiki for all my needs. The one thing I would like to get clarified is whether the use of integrated windows authentication will be added. The topis has cropped up a couple of times in previous posts, but I can’t find any specifics as to whether and when it will be added.

And information would be appreciated.


Cheers
Sam
samward
 
Posts: 37
Joined: Wed Oct 18, 2006 4:02 pm

Postby Dario Solera » Thu Oct 19, 2006 10:14 am

The official answer is "No, it won't be implemented".

With the new Plugin Framework, though, it will be possible to implement features like that. I don't know whether we'll be able to do that, because our resources are not unlimted.
User avatar
Dario Solera
Site Admin
Site Admin
 
Posts: 3699
Joined: Mon Oct 09, 2006 3:11 pm
Location: Milano, Italy

Windows Authentication Plugin Framework Contributors

Postby Ben » Thu Oct 19, 2006 11:30 am

Hi samward,

I'm in the same situation like you are. After the plugin-framewrok is finished I will have a try to implement this feature. Maybe you have some kind of programming skills or something else that you could contribute. I think if the community of screwturn grows, we (individuals out of the community) surely can add more features like the one with the authentication. Maybe it is a good idea to start a poll or something like this to get an idea how many people are looking for a specific feature and maybe there is a way to support a programmer to implement the requested features.

Just drop me a line if you want to help me or to ask further questions. Private message welcome.

Greets Ben
Ben
 
Posts: 6
Joined: Wed Oct 11, 2006 10:24 am

We're in the same boat

Postby NickA » Tue Nov 07, 2006 3:43 pm

Ditto with our organisation. The current implementation around forcing users to register is great for a public/internet Wiki but not for one that's part of a corporate intranet. Everyone's already logged in via standard Windows and having to register again is a pain in the backside (we've currently set the Wiki for public access).

When the plug-in framework appears for ScrewTurn we'll definately be interested in Windows Integrated Authentication. Here's hoping it arrives soon!

Dario - any thoughts about what Ben mentioned around a single list of user requested features?
NickA
 
Posts: 18
Joined: Mon Oct 30, 2006 1:39 pm

Postby Dario Solera » Tue Nov 07, 2006 8:17 pm

I don't know, we could add a page in our wiki for that purpose. That way, though, it wouldn't be possible to comment the messages.
User avatar
Dario Solera
Site Admin
Site Admin
 
Posts: 3699
Joined: Mon Oct 09, 2006 3:11 pm
Location: Milano, Italy

Dirty Windows Auth Implementation

Postby CGambino » Fri Dec 08, 2006 8:01 pm

I hacked the 2.0 version of the wiki for my own purposes and created a sort of 'dirty' implementation of windows auth.

This was my 20 minute hack, probably not good enough for a 'distributable' production approach.

1) In my company, all users are on the same domain. So therefore, their account name is equal to their login name (ie cgambino@company.com) my username is cgambino.

2) All users have the same password (i put this in the web.config)

3) I hacked the heck out of login.cs. Basically it tries to log you in on page load, if not, it says that you haven't been set up. No other buttons etc exist on this page.

4) Currently, the user.cs file saves passwords in a hash, however the password value is all the same, so what I did was create a csv file of users that I wanted to have access and just manually appended the lines into the user.cs file (this was faster than using the admin page). I also made sure that a few users had the ADMIN privilege.

5) I removed the "delete account" and "change password" on the user profile page. (for completeness)

Note that using this way, there is no longer means for someone to type in a username/password. Which is fine in my case.

This was a quick hack that worked for me and was the least intrusive so that I can continue to install the nightly builds, all I do is just avoid copying down the Login & Profile pages.
CGambino
 
Posts: 19
Joined: Fri Dec 08, 2006 7:20 pm

Another Quick approach to Windows Authentication

Postby Ron » Sun Dec 10, 2006 5:55 am

Instead of creating a user list, this approach let's all authenticated users have access by creating the Session["LoginKey"] using the current method. Another static method can be added to get the user email from Active Directory or check their role to determine access level. Some of the registration options were removed from the sidebar.

1) Created WindowsLogin.cs
Code: Select all
 
namespace ScrewTurn.Wiki
{
    public static class WindowsLogin
    {     
public static string getWindowsUser()
        {
            //private string m_userName;
            //private string m_email;
            //private bool m_isAuthenticated;

            string userName = HttpContext.Current.User.Identity.Name;

            //Session["LoginKey"] = Tools.ComputeSecuredUsernameHash(userName);
            //Session["Username"] = userName;
            //Session["Admin"] = false;
            //Log.LogEntry("Windows User " + (string)Session["Username"] + " logged in", EntryType.General, "SYSTEM");
            return userName;
        }
   }
}

2) Modify SessionStart in Global.asx
Code: Select all
   
void Session_Start(object sender, EventArgs e) {
        // Code that runs when a new session is started
        ScrewTurn.Wiki.Users.OnlineUsers++;
        string userName = ScrewTurn.Wiki.WindowsLogin.getWindowsUser();
        string email = ScrewTurn.Wiki.WindowsLogin.getWindowsEmail(userName);  //need to get from AD not coded yet
        Session["LoginKey"] = ScrewTurn.Wiki.Tools.ComputeSecuredUsernameHash(userName);
        Session["Username"] = userName;
        Session["Email"] = email;
        Session["Admin"] = false;
        ScrewTurn.Wiki.Log.LogEntry("Windows User " + (string)Session["Username"] + " logged in", ScrewTurn.Wiki.EntryType.General, "SYSTEM");
    }


3. Removed these entries from sidebar.cs or in StartupTools.cs
Code: Select all
//* [RandPage.aspx|Random Page]
//* [Login.aspx|Login/Logout]
//* [Language.aspx|Language Selection]
//* [Profile.aspx|Your Profile]
//* [Register.aspx|Create Account]
Ron
 
Posts: 3
Joined: Fri Oct 27, 2006 3:13 am

only using windows user for log purposes? what do you think?

Postby sanchon » Thu Jan 25, 2007 9:09 pm

I think that in my company we can keep our internal wiki in public access mode without problems; it's not necessary to be really logged in but I also think that it would be a good idea to log, when somebody edits a page, not only the user's ip address, but also his windows username (if it's available).

If users are not using windows authentication then it could work exactly as it's working now...

Wouldn't that be nice? What do you think?
sanchon
 
Posts: 2
Joined: Thu Jan 25, 2007 8:54 pm

Postby samward » Thu Feb 01, 2007 8:55 am

Dario, rather than having to 'hack' the core code, would it be possible to add a function to the IUsersStorageProvider interface that the logon.aspx page could call. That way the provider could authenticate the user based on current credentials (or some other variable) before the logon page is displayed, and just pass the user through to the page they were trying to get to.

If the authentication failed, then the normal logon screen could be displayed. Perhaps also add a check for a session variable to see how the user was authenticated. That way, if the authentication was transparent, the log-out button could be hidden (to reduce confusion).

(I realise it is pretty late in the development to be modifying things, but the idea just occured to me, so I thought I would ask).
samward
 
Posts: 37
Joined: Wed Oct 18, 2006 4:02 pm

Postby Dario Solera » Thu Feb 01, 2007 4:26 pm

Well, this will be surely taken in consideration for version 2.1.
Thanks.
User avatar
Dario Solera
Site Admin
Site Admin
 
Posts: 3699
Joined: Mon Oct 09, 2006 3:11 pm
Location: Milano, Italy

Postby jerome.deville » Thu Mar 08, 2007 6:42 pm

Yes, that's what i'm looking for.
An option in the configuration menu to choose the type of authentification.
for example :

Internal -> the ScrewTurnWiki implementation
Ldap
Windows authentification
jerome.deville
 
Posts: 10
Joined: Thu Mar 08, 2007 6:21 pm
Location: Saint-Héand, France

Postby kscott » Sat Mar 24, 2007 8:17 am

If you're going to handle windows/LDAP authentication - you should allow for the ability to control the Admin group based on Active Directory groups.

this is my current rendition if anyone is interested:

modify global.asax as follows:
Code: Select all
    void Session_Start(object sender, EventArgs e) {
        // Code that runs when a new session is started
        ScrewTurn.Wiki.Users.OnlineUsers++;
        ScrewTurn.Wiki.SessionFacade.Breadcrumbs = new ScrewTurn.Wiki.BreadcrumbsManager();
        // new code from here down:
        if (ConfigurationManager.AppSettings["LDAP"] == "true")
        {
            ScrewTurn.Wiki.LDAP_Login ldap = new ScrewTurn.Wiki.LDAP_Login();
            ScrewTurn.Wiki.SessionFacade.LoginKey = ScrewTurn.Wiki.Tools.ComputeSecuredUsernameHash(ldap.Name);
            ScrewTurn.Wiki.SessionFacade.Username = ldap.Name;
            ScrewTurn.Wiki.SessionFacade.Admin = ldap.Admin;

            ScrewTurn.Wiki.PluginFramework.UserInfo result =
                    new ScrewTurn.Wiki.LocalUserInfo(ldap.Name, ldap.Email, true, DateTime.Now, ldap.Admin, new ScrewTurn.Wiki.UsersStorageProvider(), "");

            ScrewTurn.Wiki.Users.Instance = new ScrewTurn.Wiki.Users();
            ScrewTurn.Wiki.Users u = ScrewTurn.Wiki.Users.Instance;
            u.AllUsers.Add(result);
        }
    }



and I created a new class in the App_Code folder called LDAP_Login.cs with the following code:
Code: Select all
using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.DirectoryServices;

namespace ScrewTurn.Wiki
{
    /// <summary>
    /// Summary description for LDAP_Login
    /// </summary>
    public class LDAP_Login
    {
        private string strEmail = "";
        private string strName = "";
        private bool blnAdmin = false;

        public string Email
        {
            get
            {
                return strEmail;
            }
            set
            {
                strEmail = value;
            }
        }

        public string Name
        {
            get
            {
                return strName;
            }
            set
            {
                strName = value;
            }
        }
        public bool Admin
        {
            get
            {
                return blnAdmin;
            }
            set
            {
                blnAdmin = value;
            }
        }

        public LDAP_Login()
        {
            try
            {
                // get user name (excluding domain)
                string signon = HttpContext.Current.User.Identity.Name;
                string[] signon_array = signon.Split('\\');

                DirectorySearcher mySearcher = new DirectorySearcher("LDAP://...your ldap string here..");

                mySearcher.Filter = "(&(objectClass=user)(objectCategory=person)(samAccountName=" + signon_array[1] + "))";

                // add the mail property to the list of props to retrieve
                // you can add any others you might be interested in, too!
                mySearcher.PropertiesToLoad.Add("mail");
                mySearcher.PropertiesToLoad.Add("name");

                SearchResult mySearchResult = mySearcher.FindOne();

                // get email address and full name
                if (mySearchResult != null)
                {
                    ResultPropertyCollection myResultPropColl = mySearchResult.Properties;
                    foreach (string myKey in myResultPropColl.PropertyNames)
                    {
                        foreach (Object myCollection in myResultPropColl[myKey])
                        {
                            switch (myKey)
                            {
                                case "mail":
                                    Email = myCollection.ToString();
                                    break;
                                case "name":
                                    Name = myCollection.ToString();
                                    break;
                            }
                        }
                    }
                }

                // determine if user is admin
                string[] strAdminGroups = ConfigurationManager.AppSettings["Admin_Groups"].Split(',');
                foreach (string group in strAdminGroups)
                {
                    if (HttpContext.Current.User.IsInRole(group))
                    {
                        Admin = true;
                    }
                }
            }
            catch (Exception ex)
            {
                Admin = false;
                Email = "";
                Name = "";
                ScrewTurn.Wiki.Log.LogEntry("LDAP_Login Error: " + ex.Message, ScrewTurn.Wiki.EntryType.General, "SYSTEM");
            }
        }
    }
}


and I added two app settings lines to the web.config:
Code: Select all
    <add key="LDAP" value="true"/>
    <add key="Admin_Groups" value="admingroup1,admingroup2,etc"/>


The LDAP key is just a true/false flag to turn LDAP lookup on/off.
The Admin_Groups is just that - a list of comma-separated group names that if the user is a member of - they'll get Admin access.

And I removed the login, profile, lang, and create acct links from the sidebar.

And I really dont know what good it does to add the user to the AllUsers collection - other than allowing access to the email address... but since it's really just temporary - i dont know if you're really buying anything. But at least the user will be in the collection if you do hit a page that needs it.. like you could technically go to the Profile page without it crashing, etc.. just dont do anything while you're there.

oh yeah, one last tip.. i had to set Impersonation=true in the web.config to get the LDAP lookup to work. I'm assuming that's due to security restrictions in my environment - but thought i'd mention it-

anyway, I'd love to see a proper implementation of AD authentication.

Thanks-
kscott
 
Posts: 63
Joined: Tue Mar 20, 2007 11:01 pm

Postby Richard » Wed Mar 28, 2007 12:59 am

Here's another relatively simple implementation, which we are using at my work. It creates a Wiki account for the user if none is found (similar to Community Server's Windows Authentication implementation). The admin flag must be set manually.

Edit Session_Start in Global.asax to match the following:

Code: Select all
void Session_Start(object sender, EventArgs e) {
    // Code that runs when a new session is started
    ScrewTurn.Wiki.Users.OnlineUsers++;
    ScrewTurn.Wiki.SessionFacade.Breadcrumbs = new ScrewTurn.Wiki.BreadcrumbsManager();
   
    // Get identity name from web server.
    string identityName = System.Web.HttpContext.Current.User.Identity.Name;
    if (identityName == null || identityName.Length < 1)
        throw new System.ApplicationException("Could not get current Windows user name. Ensure Integrated Windows Authentication is enabled.");
   
    string username;
   
    // Strip domain prefix (e.g. "\\COMPANY.NET\DoeJ").
    int domainDelimOffset = identityName.IndexOf("\\");
    if (domainDelimOffset > 0)
        username = identityName.Substring(domainDelimOffset + 1);
    else
        username = identityName;
   
    if (username.Length < 1)
        throw new System.ApplicationException("Username " + identityName + " is empty after domain stripped.");
   
    // Locate user.
    ScrewTurn.Wiki.PluginFramework.UserInfo user = ScrewTurn.Wiki.Users.Instance.Find(username);

    if (user == null)
    {
        // User not found, add a new one.
        if (!ScrewTurn.Wiki.Users.Instance.AddUser(username, string.Empty, string.Empty, true, false, null))
            throw new System.ApplicationException("Could not add user \"" + username + "\".");

            // Get freshly-added user.
            user = ScrewTurn.Wiki.Users.Instance.Find(username);
            if (user == null)
                throw new System.ApplicationException("Could not find user \"" + username + "\".");
    }
   
    // Set up session.
    ScrewTurn.Wiki.SessionFacade.LoginKey = ScrewTurn.Wiki.Tools.ComputeSecuredUsernameHash(user.Username);
    ScrewTurn.Wiki.SessionFacade.Username = user.Username;
    ScrewTurn.Wiki.SessionFacade.Admin = user.Admin;
   
    // Log event.
    ScrewTurn.Wiki.Log.LogEntry("User " + ScrewTurn.Wiki.SessionFacade.Username + " logged in through Windows Integrated Authentication", ScrewTurn.Wiki.EntryType.General, "SYSTEM");
}


You can optionally remove the Login/Logout menu link (Register is never visible to logged-in users). The Profile/language options behave as normal.
Richard
 
Posts: 8
Joined: Sun Jan 14, 2007 10:07 pm
Location: New Zealand

Postby mmestemaker » Mon Apr 02, 2007 9:40 pm

Richard wrote:// Get identity name from web server.
string identityName = System.Web.HttpContext.Current.User.Identity.Name;


I tried adding just this line plus a line to log the returned value. It comes back blank every time. I did add the <authentication mode="Windows"/> tag into web.config. This is just my local copy of IIS7 running on my desktop and not a server (Vista business edition). I wanted to verify this functionality before trying anything on my production server, but this seems to be a stopping point.

My network is not a domain based network; it's a workgroup if that makes any difference.

Any suggestions on what I need to configure differently? Or is this not possible in a workgroup environment?
- Mike Mestemaker
ISI Telemanagement Services, Inc.
mmestemaker
 
Posts: 162
Joined: Tue Jan 16, 2007 4:55 pm
Location: Chicago

Postby kscott » Mon Apr 02, 2007 10:52 pm

try turning off Anonymous users access in IIS under Directory Security.

(you'll have to use Basic or Integrated access)
kscott
 
Posts: 63
Joined: Tue Mar 20, 2007 11:01 pm

Postby mmestemaker » Mon Apr 02, 2007 11:42 pm

kscott wrote:try turning off Anonymous users access in IIS under Directory Security.

(you'll have to use Basic or Integrated access)


That works. Sorta. The browser is prompting me for login and password before letting get to the wiki. At that point, the code is picking up my ID and I could implement the rest of the code, but it's not really the pass-thru effect I was hoping for. Anyone know if this is the nature of using a workgroup network instead of a domain server? That's my current guess.
- Mike Mestemaker
ISI Telemanagement Services, Inc.
mmestemaker
 
Posts: 162
Joined: Tue Jan 16, 2007 4:55 pm
Location: Chicago

Postby Richard » Mon Apr 09, 2007 1:21 am

mmestemaker wrote:
kscott wrote:try turning off Anonymous users access in IIS under Directory Security.

(you'll have to use Basic or Integrated access)


That works. Sorta. The browser is prompting me for login and password before letting get to the wiki. At that point, the code is picking up my ID and I could implement the rest of the code, but it's not really the pass-thru effect I was hoping for. Anyone know if this is the nature of using a workgroup network instead of a domain server? That's my current guess.
You need anonymous users disabled and Windows Integrated Authentication enabled in IIS. If you are not using a domain, you may need to create accounts for each user on the web server.

As for the browser login prompt, it depends which browser you are using. Internet Explorer passes through your credentials automatically, but other browsers (e.g. Firefox), especially on other platforms, will require you to enter them manually.

Check out this post to see how to enable automatic authentication for Mozilla-based browsers under Windows.
Richard
 
Posts: 8
Joined: Sun Jan 14, 2007 10:07 pm
Location: New Zealand

Postby eric.stephani » Mon Apr 30, 2007 8:02 pm

I am thinking the method that Richard posted will have the smallest impact. But I also like what kscott has done. It seems a little more robust with allowing admin control though a domain group. The implementation that Ron posted seems like a simplified version of what kscott had done.

In another thread it looks like samward created a custom plugin.

http://www.screwturn.eu/forum/viewtopic.php?t=508

Samward, could you post your code so the community could evaluate it and maybe we could come up with a recommeded method?

I would like to avoid making any manual changes to avoid any problems when upgrading from version to version.
eric.stephani
 
Posts: 59
Joined: Mon Apr 30, 2007 7:49 pm

Postby samward » Tue May 01, 2007 1:30 am

eric.stephani wrote:In another thread it looks like samward created a custom plugin.

http://www.screwturn.eu/forum/viewtopic.php?t=508

Samward, could you post your code so the community could evaluate it and maybe we could come up with a recommeded method?

I would like to avoid making any manual changes to avoid any problems when upgrading from version to version.


I am happy to post my plugin as soon as I get it into a state I am comfortable will not have too many bugs :-)

At this point (due to the desing of the Screwturn plugin framework) the users still need to log in with a wiki account that an administrator has set up, but the username is in a 'domain\user' syntax and the password is the users AD password (i.e. not maintained seperatly in the wiki).

Hopfully I will be able to share the plugin shortly.


Cheers
Sam
samward
 
Posts: 37
Joined: Wed Oct 18, 2006 4:02 pm

Postby eric.stephani » Tue May 01, 2007 6:13 pm

Awesome.

For me I would personally like to see the pass-through functionality that others have talked about where users are never even prompted to login. The site just assumes that whoever is logged into the local machine is that person on the wiki.

I have implemented the method that Richard posted and it works pretty well. The only issue I had was that after I made the change I was no longer an admin, so I had to manually update the SQL table to make my account an admin.

Of course this will be a problem when I want to upgrade the wiki to a new version I will have to re-impement my change.
eric.stephani
 
Posts: 59
Joined: Mon Apr 30, 2007 7:49 pm

Next

Return to Suggestions and Feature Requests

Who is online

Users browsing this forum: No registered users and 0 guests