How to force timeouts in a Sharepoint intranet site when using Windows Authentication

By slightlybehindthecurve

How to force timeouts in a Sharepoint intranet site when using Windows Authentication
Background:
Security for my sharepoint web site depends on windows authentication. Our workstations are members of the authenticating domain; our users log in to the domain when they access their workstation. The sharepoint web server is also a member of the same domain.
One reason I’m blogging this is because I hope to get any misunderstandings I have cleared up by good comments.
I was not able to find any setting – either in iis, web.config, any sharepoint site setting, etc that would force a timeout when you use windows authentication. I found posts recommending that people use forms authentication if they really wanted to enforce timeouts.

So, why would anybody want timeouts if they are already secured by windows authentication? I think it’s something like the distinction between security and security theater.
We had had a problem where our users put up a number of Microsoft office documents, and then each time they attempted to open a doc, they got a windows authentication challenge. Then after they eliminated those by putting the sharepoint site into their IE “local intranet sites” group, they never had to log in again. That made them feel uneasy – like the site was wide open to the world. (and they had also themselves specifically permitted a huge group of 10,000 users to access the site without realizing what they had done.) So I wanted to make the site “feel” more secure by issuing some challenges after a timeout period.
Here’s how I did it, in C# script in my masterpage:
1) Modify Web.config on the server to allow server side scripting in your master page
Got to – C:InetpubwwwrootwssVirtualDirectories80web.config
Change the path to your master page to match your own site:
      <PageParserPaths>
      <PageParserPath VirtualPath=”/sites/OIT/_catalogs/masterpage/*” IncludeSubFolders=”true” CompilationMode=”Always” AllowServerSideScript=”true” />
      <PageParserPath VirtualPath=”/sites/Banner/_catalogs/masterpage/*” IncludeSubFolders=”true” CompilationMode=”Always” AllowServerSideScript=”true” />
      </PageParserPaths>

2) Copy the following c# code to maintain a session variable with the time of the last sign in. Basically, what it does is create a session variable to hold the last time you used  the web site, since the master page is executed for each page that you access. You set the timeout in the script. If your user leaves her desk for 33 minutes, for example, and then comes back and clicks on something, the master page will refresh, and the timeout code will see that the session should expire, and I send the user over to a page which forces her to login again.
<script language=”C#” runat=”server”>

    // ********************************************************************************
    // CONFIGS – not using web.config, using these lines
    // ********************************************************************************
    Boolean bDebugOn = false;  // control Response.Write
    Boolean bExecuteAspLoginScript = true;  // in my vstudio test project, I don’t have the page
    int TimeOutSeconds = 1800; //  30 minutes

    protected void Page_Load(object sender, EventArgs e)
    {
        Handle_CheckSessionForTimeout();
    }

    // ********************************************************************************
    // purpose – check the last time
    protected void Handle_CheckSessionForTimeout()
    {
        String strSession = System.Web.HttpContext.Current.Session["SignIn"] + “”;
        if (bDebugOn) Response.Write(“Session Value of SignIn Time:” + strSession);
        if (bDebugOn) Response.Write(“<br>Current Time:” + DateTime.Now.ToLongTimeString());

        if (strSession == “”)
        {
            System.Web.HttpContext.Current.Session["SignIn"] = DateTime.Now.ToLongTimeString();
            Force_A_New_SignIn(); // force login for new session
            return;
        }

        // check the time, if it’s too long, force a sign in
        try
        {
            DateTime tmSessionPlusTimeout = DateTime.Parse(strSession);
            tmSessionPlusTimeout = tmSessionPlusTimeout.AddSeconds(TimeOutSeconds);
            if (bDebugOn) Response.Write(“<br>Session plus TimeOutSeconds:” + tmSessionPlusTimeout.ToLongTimeString());
            DateTime tmNow = DateTime.Now;

            if (tmNow.CompareTo(tmSessionPlusTimeout) > 0)
            {
                if (bDebugOn) Response.Write(“<br>timeout expired ********************”);

                // set session variable so after a successful login they are permitted
                System.Web.HttpContext.Current.Session["SignIn"] = DateTime.Now.ToLongTimeString();
                Force_A_New_SignIn();
            }
            else
            {
                if (bDebugOn) Response.Write(“<br>timeout did not expire:” + tmSessionPlusTimeout.ToLongTimeString());
            }
        }
        catch (Exception ex)
        {
            if (bDebugOn) Response.Write(ex.Message);
            System.Web.HttpContext.Current.Session["SignIn"] = DateTime.Now.ToLongTimeString();
            Force_A_New_SignIn();
        }
    }
    // ********************************************************************************
    protected void Force_A_New_SignIn()
    {
        // THIS WORKED
        if (bDebugOn) Response.Write(“<br>Force_A_New_SignIn ************************************”);
        // set it so next time they get to come in
        System.Web.HttpContext.Current.Session["SignIn"] = DateTime.Now.ToLongTimeString();
        if (bExecuteAspLoginScript)
        {
                 Response.Redirect(“_layouts/AccessDenied.aspx?loginasanotheruser=false”);      
 }
        else
        {
            if (bDebugOn) Response.Write(“<br>TEST MODE – DON’T EXECUTE THE ASPX PAGE “);
        }
    }

</script>

I’ve just put this up, and it’s not getting used heavily. We’ll see how the process matures over the next weeks.

Points:

* I noticed that when I’ve evidently timed out, if I click on a link, such as “Document Library”, that after the login process is complete, I do not continue on to my desired page, but instead return to the default.aspx page. I’m not 100% sure what to do about that.
 

Tags:

5 Responses to “How to force timeouts in a Sharepoint intranet site when using Windows Authentication”

  1. Tim Says:

    Hi – thanks for the email.

    I still had not got a chance to figure this out…..but it looks as though you have got it working. Good job.

    Thanks for the great information.

  2. Adam Says:

    Have you ever gotten an “Object reference not set to an instance of an object.” error from your code? I copied it into a test solution I have here, and didn’t get it.

    Any ideas?

  3. » Session Timeouts, Windows Authentication, and SharePoint mylifeinaminute.com: You can learn a lot in a minute Says:

    [...] Visual Studio 2008, Windows SharePoint Services Over at (slightly) Behind the Curve, there is a posting on modifying your master page to allow for Session based timeouts for an integrated Windows [...]

  4. RP Says:

    I am unable to get this to work. As indicated I made changes to the web.config file and added the code to the master page of the referenced site. I added it before the tag

    First I get that runat attribute must be “Server”, so I change the case of “s” in server and then I get a Unexpected error occurred and the sharepoint log does not show any errors. Also the error continues even when I take away the code from the master page until I restore back to the original format.

    Any help is appreciated

  5. Anoop Says:

    We can also check for IsNewSession property of the sesson and check for cookie to see if the timeout occured and redirect to the login page

Leave a Reply