Click here to Skip to main content
15,895,142 members
Articles / Desktop Programming / XAML

A Silverlight application with the WCF RIA Services Class Library

Rate me:
Please Sign up or sign in to vote.
4.72/5 (11 votes)
3 Mar 2010CPOL8 min read 62.8K   1.8K   39  
A Silverlight application using the WCF RIA Services Class Library. Demonstrates how to implement a custom Authorization Service, utilize localized resources, and add unit tests for DAL.
using System;
using System.Linq;
using System.Web.DomainServices.Providers;
using System.Web.Ria;
using System.Web.Ria.ApplicationServices;
using Microsoft.Practices.Unity;
using BizApp.Services.Server.Models;

namespace BizApp.Services.Server.DomainServices
{
    /// <summary>
    /// Authentication Domain Service.
    /// </summary>
    /// <remarks>
    /// LinqToSqlMetadataProviderAttribute enables this domain service 
    /// to reference the Linq To SQL generated entities.
    /// </remarks>
    [LinqToSqlMetadataProvider(typeof(AppDatabaseDataContext))]
    [EnableClientAccess]
    public class AuthenticationService : DomainServiceBase, IAuthentication<User>
    {
        /// <summary>
        /// Gets or sets a repository for the UserAccount entities.
        /// </summary>
        /// <remarks>It is resolved in the DomainServiceFactory. 
        /// IRepository is mapped to the LinqToSqlRepository class in the unity.config.
        /// </remarks>
        [Dependency]
        public IRepository<UserAccount> UserAccountRepository { get; set; }

        /// <summary>
        /// Gets or sets a repository for the UserRole entities.
        /// </summary>
        /// <remarks>It is resolved in the DomainServiceFactory. 
        /// IRepository is mapped to the LinqToSqlRepository class in the unity.config.
        /// </remarks>
        [Dependency]
        public IRepository<UserRole> UserRoleRepository { get; set; }

        /// <summary>
        /// Gets or sets AuthenticationServiceHelper.
        /// </summary>
        /// <remarks>The main purpose of the helper is to overcome problems with authentication cookies during
        /// unit testing. IAuthenticationServiceHelper is mapped to the AuthenticationServiceHelper class in the unity.config.
        /// </remarks>
        [Dependency]
        public IAuthenticationServiceHelper AuthenticationServiceHelper { get; set; }

        /// <summary>
        /// An empty user.
        /// </summary>
        private static User DefaultUser = new User()
        {
            Name = string.Empty,
        };

        #region IAuthentication<User> Members

        /// <summary>
        /// Returns current user or a default (non-authorized) one.
        /// </summary>
        /// <returns>Current user.</returns>
        public User GetUser()
        {
            User user = null;

            if ((this.ServiceContext != null) &&
                (this.ServiceContext.User != null) &&
                this.ServiceContext.User.Identity.IsAuthenticated)
            {
                user = this.GetUser(this.ServiceContext.User.Identity.Name);
            }

            return user ?? AuthenticationService.DefaultUser;
        }

        /// <summary>
        /// Validate user name and password and create user session.
        /// </summary>
        /// <param name="userName">User name.</param>
        /// <param name="password">Password.</param>
        /// <param name="isPersistent">N/A.</param>
        /// <param name="customData">N/A.</param>
        /// <returns>User if exists or null.</returns>
        public User Login(string userName, string password, bool isPersistent, string customData)
        {
            if (this.ValidateUser(userName, password))
            {
                AuthenticationServiceHelper.SetAuthCookie(userName, isPersistent);

                User user = this.GetUser(userName);
                if (user != null)
                {
                    // We don't want to expose real user ID
                    user.ID = 0;
                    return user;
                }
            }

            return null;
        }

        /// <summary>
        /// Returns a non-authorized user.
        /// </summary>
        /// <returns>Non-authorized user.</returns>
        public User Logout()
        {
            return AuthenticationService.DefaultUser;
        }

        /// <summary>
        /// Update the specified user.
        /// </summary>
        /// <param name="user">User.</param>
        public void UpdateUser(User user)
        {
            throw new NotImplementedException();
        }

        #endregion

        /// <summary>
        /// Returns <b>true</b> if a user with this user name and password exists.
        /// </summary>
        /// <param name="userName">User name.</param>
        /// <param name="password">Password.</param>
        /// <returns><b>true</b> if user exists.</returns>
        private bool ValidateUser(string userName, string password)
        {
            if (string.IsNullOrEmpty(userName) || string.IsNullOrEmpty(password))
                return false;

            var userAccounts = from u in UserAccountRepository.Query()
                               where u.UserName == userName && u.Password == password
                               select u;

            return userAccounts.Count() > 0;
        }

        /// <summary>
        /// Get a User by its user name.
        /// </summary>
        /// <param name="userName">User name.</param>
        /// <returns>User if exists; otherwise null.</returns>
        private User GetUser(string userName)
        {
            if (string.IsNullOrEmpty(userName))
                return null;

            User user = null;
            var userAccounts = from u in UserAccountRepository.Query()
                               where u.UserName == userName
                               select u;

            if (userAccounts.Count() > 0)
            {
                UserAccount userAccount = userAccounts.Single();
                user = new User
                {
                    ID = userAccount.ID,
                    Name = userAccount.UserName,
                    FullName = userAccount.FullName
                };

                // Display user name if full name is empty
                if (string.IsNullOrEmpty(userAccount.FullName))
                    user.FullName = user.Name;

                var roles = from r in UserRoleRepository.Query()
                            where r.ID == userAccount.RoleID
                            select r.RoleName;

                user.Roles = roles.ToList();
            }

            return user;
        }
    }
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Latvia Latvia
Jevgenij lives in Riga, Latvia. He started his programmer's career in 1983 developing software for radio equipment CAD systems. Created computer graphics for TV. Developed Internet credit card processing systems for banks.
Now he is System Analyst in Accenture.

Comments and Discussions