Here is a preparation for Very Very Verrrrry simple Login System for Silverlight.
I. Server Side ( XXXXX.Web project )
1. Membership Provider class
namespace XXXXX.Web.Providers
{
public class CustomMembershipProvider : MembershipProvider
{
public override string ApplicationName { set; get; }
public override MembershipUser GetUser(string username, bool userIsOnline)
{
return new MembershipUser("CustomMembershipProvider",
username,
null,
null,
null,
null,
false,
false,
new DateTime(),
new DateTime(),
new DateTime(),
new DateTime(),
new DateTime());
}
public override bool ValidateUser(string username, string password)
{
if(username == "admin")
return password == "password";
if(username == "user")
return password == "password";
return false;
}
public override bool EnablePasswordReset { get { throw new NotImplementedException(); } }
public override bool EnablePasswordRetrieval { get { throw new NotImplementedException(); } }
public override bool RequiresQuestionAndAnswer { get { throw new NotImplementedException(); } }
public override int MaxInvalidPasswordAttempts { get { throw new NotImplementedException(); } }
public override int PasswordAttemptWindow { get { throw new NotImplementedException(); } }
public override bool RequiresUniqueEmail { get { throw new NotImplementedException(); } }
public override MembershipPasswordFormat PasswordFormat { get { throw new NotImplementedException(); } }
public override int MinRequiredPasswordLength { get { throw new NotImplementedException(); } }
public override int MinRequiredNonAlphanumericCharacters { get { throw new NotImplementedException(); } }
public override string PasswordStrengthRegularExpression { get { throw new NotImplementedException(); } }
public override MembershipUser CreateUser(string username, string password, string email, string passwordQuestion, string passwordAnswer, bool isApproved, object providerUserKey, out MembershipCreateStatus status) { throw new NotImplementedException(); }
public override bool ChangePasswordQuestionAndAnswer(string username, string password, string newPasswordQuestion, string newPasswordAnswer) { throw new NotImplementedException(); }
public override string GetPassword(string username, string answer) { throw new NotImplementedException(); }
public override bool ChangePassword(string username, string oldPassword, string newPassword) { throw new NotImplementedException(); }
public override string ResetPassword(string username, string answer) { throw new NotImplementedException(); }
public override void UpdateUser(MembershipUser user) { throw new NotImplementedException(); }
public override bool UnlockUser(string userName) { throw new NotImplementedException(); }
public override MembershipUser GetUser(object providerUserKey, bool userIsOnline) { throw new NotImplementedException(); }
public override string GetUserNameByEmail(string email) { throw new NotImplementedException(); }
public override bool DeleteUser(string username, bool deleteAllRelatedData) { throw new NotImplementedException(); }
public override MembershipUserCollection GetAllUsers(int pageIndex, int pageSize, out int totalRecords) { throw new NotImplementedException(); }
public override int GetNumberOfUsersOnline() { throw new NotImplementedException(); }
public override MembershipUserCollection FindUsersByName(string usernameToMatch, int pageIndex, int pageSize, out int totalRecords) { throw new NotImplementedException(); }
public override MembershipUserCollection FindUsersByEmail(string emailToMatch, int pageIndex, int pageSize, out int totalRecords) { throw new NotImplementedException(); }
}
}
2. Profile Provider class
namespace XXXXX.Web.Providers
{
public class CustomProfileProvider : ProfileProvider
{
public override string ApplicationName { set; get; }
public override SettingsPropertyValueCollection GetPropertyValues(SettingsContext context, SettingsPropertyCollection collection)
{
var username = context["UserName"];
var result = new SettingsPropertyValueCollection();
result.Add(new SettingsPropertyValue(
new SettingsProperty(
"WelcomeMessage",
typeof(string),
null,
true,
string.Format("ようこそ {0}さん", username),
SettingsSerializeAs.String,
null,
false,
false)));
return result;
}
public override int DeleteProfiles(ProfileInfoCollection profiles) { throw new NotImplementedException(); }
public override int DeleteProfiles(string[] usernames) { throw new NotImplementedException(); }
public override int DeleteInactiveProfiles(ProfileAuthenticationOption authenticationOption, DateTime userInactiveSinceDate) { throw new NotImplementedException(); }
public override int GetNumberOfInactiveProfiles(ProfileAuthenticationOption authenticationOption, DateTime userInactiveSinceDate) { throw new NotImplementedException(); }
public override ProfileInfoCollection GetAllProfiles(ProfileAuthenticationOption authenticationOption, int pageIndex, int pageSize, out int totalRecords) { throw new NotImplementedException(); }
public override ProfileInfoCollection GetAllInactiveProfiles(ProfileAuthenticationOption authenticationOption, DateTime userInactiveSinceDate, int pageIndex, int pageSize, out int totalRecords) { throw new NotImplementedException(); }
public override ProfileInfoCollection FindProfilesByUserName(ProfileAuthenticationOption authenticationOption, string usernameToMatch, int pageIndex, int pageSize, out int totalRecords) { throw new NotImplementedException(); }
public override ProfileInfoCollection FindInactiveProfilesByUserName(ProfileAuthenticationOption authenticationOption, string usernameToMatch, DateTime userInactiveSinceDate, int pageIndex, int pageSize, out int totalRecords) { throw new NotImplementedException(); }
public override void SetPropertyValues(SettingsContext context, SettingsPropertyValueCollection collection) { throw new NotImplementedException(); }
}
}
3. Role Provider class
namespace XXXXX.Web.Providers
{
public class CustomRoleProvider : RoleProvider
{
public override string ApplicationName { set; get; }
public override string[] GetRolesForUser(string username)
{
if (username == "admin")
return new[] { "Administrators", "Users" };
if (username == "user")
return new[] { "Users" };
return null;
}
public override bool IsUserInRole(string username, string roleName)
{
if(username == "admin")
return roleName == "Administrators" || roleName == "Users";
if(username == "user")
return roleName == "Users";
return false;
}
public override void CreateRole(string roleName) { throw new NotImplementedException(); }
public override bool DeleteRole(string roleName, bool throwOnPopulatedRole) { throw new NotImplementedException(); }
public override bool RoleExists(string roleName) { throw new NotImplementedException(); }
public override void AddUsersToRoles(string[] usernames, string[] roleNames) { throw new NotImplementedException(); }
public override void RemoveUsersFromRoles(string[] usernames, string[] roleNames) { throw new NotImplementedException(); }
public override string[] GetUsersInRole(string roleName) { throw new NotImplementedException(); }
public override string[] GetAllRoles() { throw new NotImplementedException(); }
public override string[] FindUsersInRole(string roleName, string usernameToMatch) { throw new NotImplementedException(); }
}
}
4. User class
namespace XXXXX.Web.Providers
{
public class User : UserBase
{
public string WelcomeMessage { set; get; }
}
}
5. Authentication Domain Service class
[EnableClientAccess]
public class AuthenticationService : AuthenticationBase<
User> { }
6. Web.Config
<system.web>
<authentication mode="Forms" />
<membership defaultProvider="customProvider">
<providers>
<clear />
<add name="customProvider" type="XXXXX.Web.Providers.CustomMembershipProvider"/>
</providers>
</membership>
<profile enabled="true" defaultProvider="customProvider">
<properties>
<add name="WelcomeMessage" allowAnonymous="false"/>
</properties>
<providers>
<clear />
<add name="customProvider" type="XXXXX.Web.Providers.CustomProfileProvider"/>
</providers>
</profile>
<roleManager enabled="true" defaultProvider="customProvider">
<providers>
<clear />
<add name="customProvider" type="XXXXX.Web.Providers.CustomRoleProvider"/>
</providers>
</roleManager>
</system.web>
II. Client side ( XXXXX project )
7. App.xaml.cs
public App()
{
this.Startup += this.Application_Startup;
this.Exit += this.Application_Exit;
this.UnhandledException += this.Application_UnhandledException;
InitializeComponent();
WebContext webcontext = new WebContext(); webcontext.Authentication = new FormsAuthentication(); this.ApplicationLifetimeObjects.Add(webcontext);
}
private void Application_Startup(object sender, StartupEventArgs e)
{
this.Resources.Add("WebContext", WebContext.Current);
//this.RootVisual = new MainPage();
this.RootVisual = new BasePage();
}
Here is the pages for the simple login system.
8. BasePage.xaml
<UserControl x:Class="XXXXX.BasePage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="400">
</UserControl>
9.BasePage.xaml.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
namespace XXXXX
{
using XXXXX.Web;
public partial class BasePage : UserControl
{
public BasePage()
{
InitializeComponent();
if (this.Content == null)
{
this.Content = new LoginPage();
}
else
{
var user = WebContext.Current.User;
if (user.IsAuthenticated)
((BasePage)Parent).ShowMainPage();
else
((BasePage)Parent).ShowLoginPage();
}
}
public void ShowLoginPage()
{
this.Content = new LoginPage();
}
public void ShowMainPage()
{
this.Content = new MainPage();
}
}
}
** [IMPORTANT] **
10. MainPage.xaml.cs
add following code in the constructor.
var user = WebContext.Current.User;if (!user.IsAuthenticated) ((BasePage)Parent).ShowLoginPage();
I know that using "business application template" is easier than the above way, but I hope it would be more customizable.