Silverlight pages that require login, part 2

This page is part 2 in a series of pages about “Silverlight pages that require login”. The parts are part 1, part 2 and part 3.

I’m evaluating using Silverlight and RIA services to create a web based application. Right now I’d like to set something like this up;

  1. Some links – secured links – cannot be clicked unless you’re logged in – part 1
  2. If the user logs in, the secured links should automatically be enabled – part 1
  3. If the user logs out, the secured links should automatically be disabled – part 1
  4. If the user logs out while accessing a page that requires authentication, the user should be booted off the page – part 2
  5. If anyone directly accesses a page that requires authentication, the user shouldn’t see any information on the page – all information on the page is to be considered sensitive. part 2
  6. If the user is logged off while on the on the page, then the user should be booted off the page – part 2
  7. If the user isn’t logged in, the user should be asked to log in and if that fails, he should be booted to the main page. This is similar to 5 but 5 is about prohibiting access, this is about allowing login then access and the prohibition is a fallback – part 3

At this point, I have a link that’s disabled if I’m logged out and enabled if I’m logged in. But with Silverlight 3.0/RIA Services, I can copy a link (an HTML link, as it were) and paste that into a browser, and I’ll access the page directly. Thus, it doesn’t matter if the link is enabled or not!

The link to my demo page looks like this (you’ll notice I’m on the rather famous localhost server!);
http://localhost:56897/Myapp.ApplicationTestPage.aspx#/DemoPage

First off, I add an exception to my demo page, so that it’s impossible to view the page even if you somehow are able to stumble on to it;

    public partial class DemoPage : Page
    {
        public DemoPage()
        {
            // Fail as early as possible!
            if (WebContext.Current.User.IsAuthenticated == false)
            {
                throw new InvalidOperationException("You must be logged on to view this page!");
            }
            InitializeComponent();
        }

        // Executes when the user navigates to this page.
        protected override void OnNavigatedTo(NavigationEventArgs e)
        {
        }
    }

If I try to access the page directly, I get a huge exception! Clearly not a good way of restricting access, but if someone somehow got through our secured perimeter, that’s better than the alternative.

If I log on before I directly access the page, then the page shows as expected. So far so good. But if I log off, I’m still left on the page! Time to boot the user when he logs out.

What we’ll want to do is to again hook up an event to the WebContext.Current.Authentication object to navigate away from the page when the user is logged off;

        // Executes when the user navigates to this page.
        protected override void OnNavigatedTo(NavigationEventArgs e)
        {
            WebContext.Current.Authentication.LoggedOut += Authentication_LoggedOut;
        }

        protected override void OnNavigatedFrom(NavigationEventArgs e)
        {
            // Must unregister the event
            WebContext.Current.Authentication.LoggedOut -= Authentication_LoggedOut;
        }

        private void Authentication_LoggedOut(object sender, System.Windows.Ria.ApplicationServices.AuthenticationEventArgs e)
        {
            // Navigate to the home page! But how?
        }

As you can see from the comment in Authentication_LoggedOut we need a method for navigating to the main page – canceling any pending changes and hiding any currently visible information. But how?

After a bit of googling, it would seem that the MainPage is the holder of the Frame that in turn is showing the current page - the page that we want to navigate away from. And in my demo project, it's called ContentFrame - here's the xaml;

        <Border x:Name="ContentBorder" Style="{StaticResource ContentBorderStyle}">
            <navigation:Frame
                x:Name="ContentFrame"
                Style="{StaticResource ContentFrameStyle}"
                Source="/Home"
                Navigated="ContentFrame_Navigated"
                NavigationFailed="ContentFrame_NavigationFailed">
                <navigation:Frame.UriMapper>
                    <uriMapper:UriMapper>
                        <uriMapper:UriMapping Uri="" MappedUri="/Views/Home.xaml"/>
                        <uriMapper:UriMapping Uri="/{pageName}" MappedUri="/Views/{pageName}.xaml"/>
                    </uriMapper:UriMapper>
                </navigation:Frame.UriMapper>
            </navigation:Frame>
        </Border>

At this page about Silverlight 3 Navigation Framework (and this webcast) we’re told that from the page, we can use the Page.NavigationService to find the Frame that navigated to this page. And that frame has a Navigate method, so we’ll try that;

        private void Authentication_LoggedOut(object sender, System.Windows.Ria.ApplicationServices.AuthenticationEventArgs e)
        {
            NavigationService.Navigate(new Uri("/Home", UriKind.Relative));
        }

And that worked a charm! If the user logs out – he’s redirected to the main page. Without any message specifying what has happened – which would probably be nice.

Now, I’d like the user to be asked to log in, instead of simply being refused access to the page. I’ve added that to part 3.

About mfagerlund
Writes code in my sleep - and sometimes it even compiles!

2 Responses to Silverlight pages that require login, part 2

  1. Pingback: Silverlight pages that Require login, part 1 « Mattias Fagerlund's Coding Blog

  2. Pingback: Silverlight pages that require login, part 3 « Mattias Fagerlund's Coding Blog

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: