Feed Icon  

Contact

  • Bryant Likes
  • Send mail to the author(s) E-mail
  • twitter
  • View Bryant Likes's profile on LinkedIn
  • del.icio.us
Get Microsoft Silverlight
by clicking "Install Microsoft Silverlight" you accept the
Silverlight license agreement

Hosting By

Hot Topics

Tags

Open Source Projects

Archives

Ads

Idle Timeouts in RIA Services Authentication

Posted in RiaServices | Silverlight at Wednesday, October 28, 2009 10:02 AM Pacific Standard Time

A question came up in the Silverlight Forums about how to timeout a user when using .NET RIA Services. Since I have implemented this before I thought I would share an approach I used. There might be a better way that is more integrated with the ASP.Net security, but for now this works.

To start with, you’ll need the Sample Application that Brad Abram has been building and blogging about and you might want to read through this post on Authentication in RIA Services before going any further. Once you have that and can build/run it on your machine you can continue on.

The security in Brad’s example uses a simple membership provider that is using RIA Services FormsAuthentication since it takes a username and password to log in. For our example we will extend the FormsAuthentication and add a timeout to it. Below is my implementation of the FormsWithTimeoutAuthentication class:

namespace MyApp
{
    public class FormsWithTimeoutAuthentication : FormsAuthentication
    {
        private DispatcherTimer idleTimer;
        private int minutesIdle;
        private bool idle;
        private bool attached = false;

        public FormsWithTimeoutAuthentication()
            : this(20)
        { }

        public FormsWithTimeoutAuthentication(int idleMinutes)
        {
            IdleMinutesBeforeTimeout = idleMinutes;
            idleTimer = new DispatcherTimer();
            idleTimer.Interval = TimeSpan.FromMinutes(1);
            idleTimer.Tick += new EventHandler(idleTimer_Tick);
        }

        public int IdleMinutesBeforeTimeout
        {
            get;
            set;
        }

        protected override LoginResult EndLogin(IAsyncResult asyncResult)
        {
            var result = base.EndLogin(asyncResult);

            if (result.LoginSuccess == true)
            {
                if (!attached) AttachEvents();
                minutesIdle = 0;
                idleTimer.Start();
            }

            return result;
        }

        protected override LogoutResult EndLogout(IAsyncResult asyncResult)
        {
            idleTimer.Stop();

            return base.EndLogout(asyncResult);
        }

        private void AttachEvents()
        {
            attached = true;
            Application.Current.RootVisual.MouseMove += new MouseEventHandler(RootVisual_MouseMove);
            Application.Current.RootVisual.KeyDown += new KeyEventHandler(RootVisual_KeyDown);
        }

        private void RootVisual_KeyDown(object sender, KeyEventArgs e)
        {
            idle = false;
        }

        private void RootVisual_MouseMove(object sender, MouseEventArgs e)
        {
            idle = false;
        }

        private void idleTimer_Tick(object sender, EventArgs e)
        {
            if (idle == true)
            {
                minutesIdle += idleTimer.Interval.Minutes;
                if (minutesIdle >= IdleMinutesBeforeTimeout)
                {
                    Logout();
                }
            }
            else
            {
                minutesIdle = 0;
            }
            idle = true;
        }
    }
}

All this class does is add a timer that fires once a minute. If the user has either moved the mouse or hit a key in that minute then they stay logged in. If the user hasn’t, then a minute of idle time is added to the idle minute count until the timeout limit is reached. Once that happens the user gets logged out.

Note that the events are attached to the root visual and don’t get attached until the user logs in. This is because the Authentication is created prior to the RootVisual being set.

Simply add this code to the sample project (linked above) and then change the authentication service in the App.xaml as follows:

<Application   
  x:Class="MyApp.App"
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  xmlns:app="clr-namespace:MyApp"
  xmlns:appsvc="clr-namespace:System.Windows.Ria.ApplicationServices;assembly=System.Windows.Ria"  
    >

    <Application.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="Assets/Styles.xaml"/>
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Application.Resources>


    <Application.ApplicationLifetimeObjects>
        <app:RiaContext>
            <app:RiaContext.Authentication>
                <app:FormsWithTimeoutAuthentication IdleMinutesBeforeTimeout="2"/>
                <!--<appsvc:WindowsAuthentication/>-->
            </app:RiaContext.Authentication>
        </app:RiaContext>
    </Application.ApplicationLifetimeObjects>

</Application>

Here I’ve set the IdleMinutesBeforeTimeout to 2 minutes so that it is easy to test.

Once you’ve modified the application, when you run it you will get logged out after the number of minutes you specify in the timeout. There are lots of enhancements that could be made to this simple approach, but this works for most situations.

Friday, November 06, 2009 1:19:24 PM (Pacific Standard Time, UTC-08:00)

Very good stuff.
Simple and nice idea.
But I still think that it should be configured somehow on RIA .NET auth service level. Unfortunately in the current version RIA .NET service does not have even the access to the Session object.
AlexY
Thursday, November 12, 2009 5:46:27 AM (Pacific Standard Time, UTC-08:00)
Hi Bryant,

How did you get this to work? I tried to implement, but FormsAuthentication is a SEALED class.

Thanks,

Stephane
Stephane Touya
Thursday, November 12, 2009 11:21:01 AM (Pacific Standard Time, UTC-08:00)
@Stephane The FormsAuthentication class here is on the Silverlight side of things, not on the ASP.Net side.
Thursday, December 03, 2009 10:34:20 PM (Pacific Standard Time, UTC-08:00)
Great post Bryant ! It has worked fine at my side. Is there any provision to send user back to their current xaml page from where user was idle for 2 minitues? Say user is idle on A.xaml page for 2 mins and user was logout from Application(A.xaml page). After successfull Login to application back, can I redirect user to A.xaml page instead of 'Home.xaml' or some default xaml page ??
Chakris
Comments are closed.