稳扎稳打Silverlight(60) - 4.0通信之WCF RIA Services: 权限验证
稳扎稳打Silverlight(60) - 4.0通信之WCF RIA Services: 权限验证
作者:webabcd
介绍
Silverlight 4.0 之 WCF RIA Services:权限验证
在线DEMO
http://www.cnblogs.com/webabcd/archive/2010/08/09/1795417.html
示例
演示在 WCF RIA Services 框架中实现权限验证的方法
1、服务端
MyDomainService.cs
代码
/*
* 一个 Domain Service 服务
*/
namespace Silverlight40.Web.Service
{
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Data;
using System.Linq;
using System.ServiceModel.DomainServices.EntityFramework;
using System.ServiceModel.DomainServices.Hosting;
using System.ServiceModel.DomainServices.Server;
using Silverlight40.Web.Model;
/*
* 用 LinqToEntities 实现 Domain Service 则继承 LinqToSqlDomainService<NorthwindEntities>;用 LinqToSql 实现 Domain Service 则继承 LinqToSqlDomainService<NorthwindEntities>
* Domain Service 内所有对客户端可见的方法都应该是 public 的,Domain Service 内的方法不支持重载
* 对客户端可见的方法要满足命名约定,或为其指定对应的 Attribute。当前支持 6 种数据操作:Query, Update, Insert, Delete, Invoke, Named Update, 详见文档
*
* [EnableClientAccess()] - 该类对客户端可见
* [EnableClientAccess(RequiresSecureEndpoint = true)] - 使用 HTTPS 协议
* [Ignore] - 指定的方法不作为服务而公开
* [Query(IsComposable=true)] - 支持客户端的 linq 查询,而且此查询会被在服务端执行
*
* 在多个 Domain Services 间共享实体:通过 [ExternalReference], [Association()], Context.AddReference() 实现,详见文档
*/
// 服务端的类名为:MyDomainService,则其生成的客户端上下文的类名为:MyDomainContext
[EnableClientAccess()]
public class MyDomainService : LinqToEntitiesDomainService<NorthwindEntities>
{
[Query(IsDefault = true)]
public IQueryable<Category> GetCategories()
{
return this.ObjectContext.Categories;
}
public void InsertCategory(Category category)
{
if ((category.EntityState != EntityState.Detached))
{
this.ObjectContext.ObjectStateManager.ChangeObjectState(category, EntityState.Added);
}
else
{
this.ObjectContext.Categories.AddObject(category);
}
}
public void UpdateCategory(Category currentCategory)
{
this.ObjectContext.Categories.AttachAsModified(currentCategory, this.ChangeSet.GetOriginal(currentCategory));
}
public void DeleteCategory(Category category)
{
if ((category.EntityState == EntityState.Detached))
{
this.ObjectContext.Categories.Attach(category);
}
this.ObjectContext.Categories.DeleteObject(category);
}
[Query(IsDefault = true)]
public IQueryable<Product> GetProducts()
{
return this.ObjectContext.Products;
}
public IQueryable<Product> GetProductsBySort(string sort)
{
return ObjectContext.Products.OrderBy(sort);
}
public void InsertProduct(Product product)
{
if ((product.EntityState != EntityState.Detached))
{
this.ObjectContext.ObjectStateManager.ChangeObjectState(product, EntityState.Added);
}
else
{
this.ObjectContext.Products.AddObject(product);
}
}
public void UpdateProduct(Product currentProduct)
{
this.ObjectContext.Products.AttachAsModified(currentProduct, this.ChangeSet.GetOriginal(currentProduct));
}
public void DeleteProduct(Product product)
{
if ((product.EntityState == EntityState.Detached))
{
this.ObjectContext.Products.Attach(product);
}
this.ObjectContext.Products.DeleteObject(product);
}
public IQueryable<Product> GetProductsByCategoryId(int categoryId)
{
return this.ObjectContext.Products.Where(p => p.CategoryID == categoryId);
}
// 通过验证的并且角色属于“管理员”的用户才有权限调用此方法
[Invoke]
[RequiresAuthentication()]
[RequiresRole("管理员")]
public string GetAuthenticationStatus()
{
return "看到了这条信息,就证明你有权限";
}
}
}
* 一个 Domain Service 服务
*/
namespace Silverlight40.Web.Service
{
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Data;
using System.Linq;
using System.ServiceModel.DomainServices.EntityFramework;
using System.ServiceModel.DomainServices.Hosting;
using System.ServiceModel.DomainServices.Server;
using Silverlight40.Web.Model;
/*
* 用 LinqToEntities 实现 Domain Service 则继承 LinqToSqlDomainService<NorthwindEntities>;用 LinqToSql 实现 Domain Service 则继承 LinqToSqlDomainService<NorthwindEntities>
* Domain Service 内所有对客户端可见的方法都应该是 public 的,Domain Service 内的方法不支持重载
* 对客户端可见的方法要满足命名约定,或为其指定对应的 Attribute。当前支持 6 种数据操作:Query, Update, Insert, Delete, Invoke, Named Update, 详见文档
*
* [EnableClientAccess()] - 该类对客户端可见
* [EnableClientAccess(RequiresSecureEndpoint = true)] - 使用 HTTPS 协议
* [Ignore] - 指定的方法不作为服务而公开
* [Query(IsComposable=true)] - 支持客户端的 linq 查询,而且此查询会被在服务端执行
*
* 在多个 Domain Services 间共享实体:通过 [ExternalReference], [Association()], Context.AddReference() 实现,详见文档
*/
// 服务端的类名为:MyDomainService,则其生成的客户端上下文的类名为:MyDomainContext
[EnableClientAccess()]
public class MyDomainService : LinqToEntitiesDomainService<NorthwindEntities>
{
[Query(IsDefault = true)]
public IQueryable<Category> GetCategories()
{
return this.ObjectContext.Categories;
}
public void InsertCategory(Category category)
{
if ((category.EntityState != EntityState.Detached))
{
this.ObjectContext.ObjectStateManager.ChangeObjectState(category, EntityState.Added);
}
else
{
this.ObjectContext.Categories.AddObject(category);
}
}
public void UpdateCategory(Category currentCategory)
{
this.ObjectContext.Categories.AttachAsModified(currentCategory, this.ChangeSet.GetOriginal(currentCategory));
}
public void DeleteCategory(Category category)
{
if ((category.EntityState == EntityState.Detached))
{
this.ObjectContext.Categories.Attach(category);
}
this.ObjectContext.Categories.DeleteObject(category);
}
[Query(IsDefault = true)]
public IQueryable<Product> GetProducts()
{
return this.ObjectContext.Products;
}
public IQueryable<Product> GetProductsBySort(string sort)
{
return ObjectContext.Products.OrderBy(sort);
}
public void InsertProduct(Product product)
{
if ((product.EntityState != EntityState.Detached))
{
this.ObjectContext.ObjectStateManager.ChangeObjectState(product, EntityState.Added);
}
else
{
this.ObjectContext.Products.AddObject(product);
}
}
public void UpdateProduct(Product currentProduct)
{
this.ObjectContext.Products.AttachAsModified(currentProduct, this.ChangeSet.GetOriginal(currentProduct));
}
public void DeleteProduct(Product product)
{
if ((product.EntityState == EntityState.Detached))
{
this.ObjectContext.Products.Attach(product);
}
this.ObjectContext.Products.DeleteObject(product);
}
public IQueryable<Product> GetProductsByCategoryId(int categoryId)
{
return this.ObjectContext.Products.Where(p => p.CategoryID == categoryId);
}
// 通过验证的并且角色属于“管理员”的用户才有权限调用此方法
[Invoke]
[RequiresAuthentication()]
[RequiresRole("管理员")]
public string GetAuthenticationStatus()
{
return "看到了这条信息,就证明你有权限";
}
}
}
MyDomainService.metadata.cs
代码
/*
* [MetadataTypeAttribute()] - 指定类的元数据对象
* [Include] - 生成的客户端上下文包含此字段
* [Exclude] - 生成的客户端上下文不包含此字段
* [Composition] - 指定字段为关联数据,即父实体增删改查时,此关联数据也会做相应的变化。指定此 Attribute 后,需显式指定其为 [Include]
* 注:如果使用 DomainDataSource 则不能将字段设置为 [Composition]
* [Editable(true)], [Editable(false)] - 指定字段是否可编辑
*
* 支持 Data Annotation 方式的数据验证:DataTypeAttribute(具有很多常用的数据类型的验证), RangeAttribute, RegularExpressionAttribute, RequiredAttribute, StringLengthAttribute 等
* 注:如果需要将自定义的验证既作用于服务端又作用于客户端,则需要把自定义的验证逻辑代码设置为 shared 模式
*/
namespace Silverlight40.Web.Model
{
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Data.Objects.DataClasses;
using System.Linq;
using System.ServiceModel.DomainServices.Hosting;
using System.ServiceModel.DomainServices.Server;
using Silverlight40.Web.Service.Validation;
[MetadataTypeAttribute(typeof(Category.CategoryMetadata))]
[CustomValidation(typeof(CategoryValidator), "ValidateCategory")] // 演示通过自定义的实体验证器来实现验证
public partial class Category
{
internal sealed class CategoryMetadata
{
private CategoryMetadata()
{
}
[Key()]
public int CategoryID { get; set; }
[Display(Name = "类别名称")] // 显示用
[Numeric(ErrorMessage = "字段“{0}”必须是数字")] // 演示通过继承 RegularExpressionAttribute 实现字段的自定义验证
[StartsWith(ErrorMessage = "{0}")] // 演示通过继承 ValidationAttribute 实现字段的自定义验证
[CustomValidation(typeof(EndsWidthValidator), "ValidateCategoryName")] // 演示通过自定义的字段验证器来实现验证
public string CategoryName { get; set; }
public string Description { get; set; }
[Exclude]
public byte[] Picture { get; set; }
[Include]
[Composition]
public EntityCollection<Product> Products { get; set; }
}
}
[MetadataTypeAttribute(typeof(Product.ProductMetadata))]
public partial class Product
{
internal sealed class ProductMetadata
{
private ProductMetadata()
{
}
public Category Category { get; set; }
public Nullable<int> CategoryID { get; set; }
public bool Discontinued { get; set; }
public EntityCollection<Order_Detail> Order_Details { get; set; }
[Display(Order = 0, Name = "产品ID")]
public int ProductID { get; set; }
[Display(Order = 1, Name = "产品名称")]
public string ProductName { get; set; }
public string QuantityPerUnit { get; set; }
public Nullable<short> ReorderLevel { get; set; }
public Supplier Supplier { get; set; }
public Nullable<int> SupplierID { get; set; }
public Nullable<decimal> UnitPrice { get; set; }
public Nullable<short> UnitsInStock { get; set; }
public Nullable<short> UnitsOnOrder { get; set; }
}
}
}
* [MetadataTypeAttribute()] - 指定类的元数据对象
* [Include] - 生成的客户端上下文包含此字段
* [Exclude] - 生成的客户端上下文不包含此字段
* [Composition] - 指定字段为关联数据,即父实体增删改查时,此关联数据也会做相应的变化。指定此 Attribute 后,需显式指定其为 [Include]
* 注:如果使用 DomainDataSource 则不能将字段设置为 [Composition]
* [Editable(true)], [Editable(false)] - 指定字段是否可编辑
*
* 支持 Data Annotation 方式的数据验证:DataTypeAttribute(具有很多常用的数据类型的验证), RangeAttribute, RegularExpressionAttribute, RequiredAttribute, StringLengthAttribute 等
* 注:如果需要将自定义的验证既作用于服务端又作用于客户端,则需要把自定义的验证逻辑代码设置为 shared 模式
*/
namespace Silverlight40.Web.Model
{
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Data.Objects.DataClasses;
using System.Linq;
using System.ServiceModel.DomainServices.Hosting;
using System.ServiceModel.DomainServices.Server;
using Silverlight40.Web.Service.Validation;
[MetadataTypeAttribute(typeof(Category.CategoryMetadata))]
[CustomValidation(typeof(CategoryValidator), "ValidateCategory")] // 演示通过自定义的实体验证器来实现验证
public partial class Category
{
internal sealed class CategoryMetadata
{
private CategoryMetadata()
{
}
[Key()]
public int CategoryID { get; set; }
[Display(Name = "类别名称")] // 显示用
[Numeric(ErrorMessage = "字段“{0}”必须是数字")] // 演示通过继承 RegularExpressionAttribute 实现字段的自定义验证
[StartsWith(ErrorMessage = "{0}")] // 演示通过继承 ValidationAttribute 实现字段的自定义验证
[CustomValidation(typeof(EndsWidthValidator), "ValidateCategoryName")] // 演示通过自定义的字段验证器来实现验证
public string CategoryName { get; set; }
public string Description { get; set; }
[Exclude]
public byte[] Picture { get; set; }
[Include]
[Composition]
public EntityCollection<Product> Products { get; set; }
}
}
[MetadataTypeAttribute(typeof(Product.ProductMetadata))]
public partial class Product
{
internal sealed class ProductMetadata
{
private ProductMetadata()
{
}
public Category Category { get; set; }
public Nullable<int> CategoryID { get; set; }
public bool Discontinued { get; set; }
public EntityCollection<Order_Detail> Order_Details { get; set; }
[Display(Order = 0, Name = "产品ID")]
public int ProductID { get; set; }
[Display(Order = 1, Name = "产品名称")]
public string ProductName { get; set; }
public string QuantityPerUnit { get; set; }
public Nullable<short> ReorderLevel { get; set; }
public Supplier Supplier { get; set; }
public Nullable<int> SupplierID { get; set; }
public Nullable<decimal> UnitPrice { get; set; }
public Nullable<short> UnitsInStock { get; set; }
public Nullable<short> UnitsOnOrder { get; set; }
}
}
}
MyAuthenticationDomainService.cs
代码
/*
* 实现自定义的权限验证(基于 Forms 验证)
*/
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.ServiceModel.DomainServices.Hosting;
using System.ServiceModel.DomainServices.Server;
using System.ServiceModel.DomainServices.Server.ApplicationServices;
using System.Security.Principal;
namespace Silverlight40.Web.Service
{
// AuthenticationBase<T> - 要实现自定义的验证逻辑需要继承这个基类,“T”是用户实体类型(其要实现 System.ServiceModel.DomainServices.Server.ApplicationServices.IUser 接口)
[EnableClientAccess]
public class MyAuthenticationDomainService : AuthenticationBase<User>
{
// 本例只做演示,所以不会和数据库交互,如果需要和数据库交互就用 MyDomainService
private MyDomainService _context = new MyDomainService();
// 根据用户名和密码判断其是否是合法用户,如果是合法用户则写入 cookie
protected override bool ValidateUser(string username, string password)
{
if (username == "webabcd" && password == "111111")
{
System.Web.Security.FormsAuthentication.SetAuthCookie("webabcd", true);
return true;
}
return false;
}
// 获取当前已验证的用户信息
protected override User GetAuthenticatedUser(IPrincipal pricipal)
{
User user = new User();
user.Name = pricipal.Identity.Name;
user.Nickname = "我是 Nickname";
user.Roles = new string[] { "管理员", "开发" };
return user;
}
// 初始化
public override void Initialize(DomainServiceContext context)
{
this._context.Initialize(context);
base.Initialize(context);
}
// 释放资源
protected override void Dispose(bool disposing)
{
if (disposing)
this._context.Dispose();
base.Dispose(disposing);
}
}
// 自定义的用户实体类型,继承自 UserBase(UserBase 实现了 System.ServiceModel.DomainServices.Server.ApplicationServices.IUser 接口)
public class User : UserBase
{
public string Nickname { get; set; }
}
}
* 实现自定义的权限验证(基于 Forms 验证)
*/
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.ServiceModel.DomainServices.Hosting;
using System.ServiceModel.DomainServices.Server;
using System.ServiceModel.DomainServices.Server.ApplicationServices;
using System.Security.Principal;
namespace Silverlight40.Web.Service
{
// AuthenticationBase<T> - 要实现自定义的验证逻辑需要继承这个基类,“T”是用户实体类型(其要实现 System.ServiceModel.DomainServices.Server.ApplicationServices.IUser 接口)
[EnableClientAccess]
public class MyAuthenticationDomainService : AuthenticationBase<User>
{
// 本例只做演示,所以不会和数据库交互,如果需要和数据库交互就用 MyDomainService
private MyDomainService _context = new MyDomainService();
// 根据用户名和密码判断其是否是合法用户,如果是合法用户则写入 cookie
protected override bool ValidateUser(string username, string password)
{
if (username == "webabcd" && password == "111111")
{
System.Web.Security.FormsAuthentication.SetAuthCookie("webabcd", true);
return true;
}
return false;
}
// 获取当前已验证的用户信息
protected override User GetAuthenticatedUser(IPrincipal pricipal)
{
User user = new User();
user.Name = pricipal.Identity.Name;
user.Nickname = "我是 Nickname";
user.Roles = new string[] { "管理员", "开发" };
return user;
}
// 初始化
public override void Initialize(DomainServiceContext context)
{
this._context.Initialize(context);
base.Initialize(context);
}
// 释放资源
protected override void Dispose(bool disposing)
{
if (disposing)
this._context.Dispose();
base.Dispose(disposing);
}
}
// 自定义的用户实体类型,继承自 UserBase(UserBase 实现了 System.ServiceModel.DomainServices.Server.ApplicationServices.IUser 接口)
public class User : UserBase
{
public string Nickname { get; set; }
}
}
MyRoleProvider.cs
代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Security;
namespace Silverlight40.Web.Service
{
public class MyRoleProvider : RoleProvider
{
public override void AddUsersToRoles(string[] usernames, string[] roleNames)
{
throw new NotImplementedException();
}
public override string ApplicationName
{
get
{
throw new NotImplementedException();
}
set
{
throw new NotImplementedException();
}
}
public override void CreateRole(string roleName)
{
throw new NotImplementedException();
}
public override bool DeleteRole(string roleName, bool throwOnPopulatedRole)
{
throw new NotImplementedException();
}
public override string[] FindUsersInRole(string roleName, string usernameToMatch)
{
throw new NotImplementedException();
}
public override string[] GetAllRoles()
{
throw new NotImplementedException();
}
// 这是必须要重写的方法
// 当 Domain Service 的方法被声明为 [RequiresRole("...")] 时,其通过此方法来判断当前用户是否属于指定的角色
public override string[] GetRolesForUser(string username)
{
return new string[] { "管理员", "开发" };
}
public override string[] GetUsersInRole(string roleName)
{
throw new NotImplementedException();
}
public override bool IsUserInRole(string username, string roleName)
{
throw new NotImplementedException();
}
public override void RemoveUsersFromRoles(string[] usernames, string[] roleNames)
{
throw new NotImplementedException();
}
public override bool RoleExists(string roleName)
{
throw new NotImplementedException();
}
}
}
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Security;
namespace Silverlight40.Web.Service
{
public class MyRoleProvider : RoleProvider
{
public override void AddUsersToRoles(string[] usernames, string[] roleNames)
{
throw new NotImplementedException();
}
public override string ApplicationName
{
get
{
throw new NotImplementedException();
}
set
{
throw new NotImplementedException();
}
}
public override void CreateRole(string roleName)
{
throw new NotImplementedException();
}
public override bool DeleteRole(string roleName, bool throwOnPopulatedRole)
{
throw new NotImplementedException();
}
public override string[] FindUsersInRole(string roleName, string usernameToMatch)
{
throw new NotImplementedException();
}
public override string[] GetAllRoles()
{
throw new NotImplementedException();
}
// 这是必须要重写的方法
// 当 Domain Service 的方法被声明为 [RequiresRole("...")] 时,其通过此方法来判断当前用户是否属于指定的角色
public override string[] GetRolesForUser(string username)
{
return new string[] { "管理员", "开发" };
}
public override string[] GetUsersInRole(string roleName)
{
throw new NotImplementedException();
}
public override bool IsUserInRole(string username, string roleName)
{
throw new NotImplementedException();
}
public override void RemoveUsersFromRoles(string[] usernames, string[] roleNames)
{
throw new NotImplementedException();
}
public override bool RoleExists(string roleName)
{
throw new NotImplementedException();
}
}
}
Web.config
代码
<authentication mode="Forms">
<forms name=".WCFRIAServices" />
</authentication>
<roleManager enabled="true" defaultProvider="MyRoleProvider">
<providers>
<add name="MyRoleProvider" type="Silverlight40.Web.Service.MyRoleProvider" />
</providers>
</roleManager>
<forms name=".WCFRIAServices" />
</authentication>
<roleManager enabled="true" defaultProvider="MyRoleProvider">
<providers>
<add name="MyRoleProvider" type="Silverlight40.Web.Service.MyRoleProvider" />
</providers>
</roleManager>
2、客户端
AuthenticationDemo.xaml
代码
<navigation:Page x:Class="Silverlight40.WCFRIAServices.AuthenticationDemo"
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"
xmlns:navigation="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Navigation"
Title="AuthenticationDemo Page">
<Grid x:Name="LayoutRoot">
<StackPanel HorizontalAlignment="Left">
<!--
用于登录/注销的操作
-->
<StackPanel Orientation="Horizontal" Margin="5">
<TextBlock Text="账号:" />
<TextBox Name="txtUserName" Text="webabcd" />
<TextBlock Text="账号:" />
<TextBox Name="txtPassword" Text="111111" />
<Button Name="btnLogin" Content="登录" Click="btnLogin_Click" />
<Button Name="btnLogout" Content="注销" Click="btnLogout_Click" />
</StackPanel>
<!--
用于显示登录状态
-->
<StackPanel Orientation="Horizontal" Margin="5">
<TextBlock Text="登录状态:" />
<TextBlock Name="lblStatus" Text="" />
</StackPanel>
<!--
通过绑定到 WebContext 的方式,显示登录用户的信息
-->
<TextBlock Text="{Binding Source={StaticResource WebContext}, Path=User.Nickname}" Margin="5" />
<!--
已登录的用户会返回正确的结果,未登录的用户会返回“拒绝访问”
-->
<Button Name="btnAuthenticationTest" Content="权限测试" Click="btnAuthenticationTest_Click" />
</StackPanel>
</Grid>
</navigation:Page>
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"
xmlns:navigation="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Navigation"
Title="AuthenticationDemo Page">
<Grid x:Name="LayoutRoot">
<StackPanel HorizontalAlignment="Left">
<!--
用于登录/注销的操作
-->
<StackPanel Orientation="Horizontal" Margin="5">
<TextBlock Text="账号:" />
<TextBox Name="txtUserName" Text="webabcd" />
<TextBlock Text="账号:" />
<TextBox Name="txtPassword" Text="111111" />
<Button Name="btnLogin" Content="登录" Click="btnLogin_Click" />
<Button Name="btnLogout" Content="注销" Click="btnLogout_Click" />
</StackPanel>
<!--
用于显示登录状态
-->
<StackPanel Orientation="Horizontal" Margin="5">
<TextBlock Text="登录状态:" />
<TextBlock Name="lblStatus" Text="" />
</StackPanel>
<!--
通过绑定到 WebContext 的方式,显示登录用户的信息
-->
<TextBlock Text="{Binding Source={StaticResource WebContext}, Path=User.Nickname}" Margin="5" />
<!--
已登录的用户会返回正确的结果,未登录的用户会返回“拒绝访问”
-->
<Button Name="btnAuthenticationTest" Content="权限测试" Click="btnAuthenticationTest_Click" />
</StackPanel>
</Grid>
</navigation:Page>
AuthenticationDemo.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;
using System.Windows.Navigation;
using System.ServiceModel.DomainServices.Client.ApplicationServices;
using Silverlight40.Web.Service;
using System.ServiceModel.DomainServices.Client;
namespace Silverlight40.WCFRIAServices
{
public partial class AuthenticationDemo : Page
{
public AuthenticationDemo()
{
InitializeComponent();
}
// 如果当前用户已经通过验证,则获取其用户信息
protected override void OnNavigatedTo(NavigationEventArgs e)
{
WebContext.Current.Authentication.LoadUser(delegate
{
if (WebContext.Current.User.IsAuthenticated)
{
lblStatus.Text = string.Format("登录成功,当前用户:{0},昵称:{1},所属角色:{2}",
WebContext.Current.User.Name,
WebContext.Current.User.Nickname,
string.Join(",", WebContext.Current.User.Roles));
}
},
null);
}
// 根据用户名和密码做身份验证
private void btnLogin_Click(object sender, RoutedEventArgs e)
{
LoginParameters lp = new LoginParameters(txtUserName.Text, txtPassword.Text, true, null);
WebContext.Current.Authentication.Login(
lp,
(lo) =>
{
if (lo.HasError)
{
lblStatus.Text = lo.Error.ToString();
}
else if (lo.LoginSuccess == false)
{
lblStatus.Text = "验证失败";
}
else if (lo.LoginSuccess == true)
{
lblStatus.Text = string.Format("登录成功,当前用户:{0},昵称:{1},所属角色:{2}",
WebContext.Current.User.Name,
WebContext.Current.User.Nickname,
string.Join(",", WebContext.Current.User.Roles));
}
},
null);
}
// 注销
private void btnLogout_Click(object sender, RoutedEventArgs e)
{
WebContext.Current.Authentication.Logout(
(lo) =>
{
if (lo.HasError)
lblStatus.Text = lo.Error.ToString();
else
lblStatus.Text = "注销成功";
},
null);
}
// 通过验证的并且角色属于“管理员”的用户才有权限访问 GetAuthenticationStatus 方法
private void btnAuthenticationTest_Click(object sender, RoutedEventArgs e)
{
// if (WebContext.Current.User.IsInRole("管理员"))
if (true)
{
MyDomainContext context = new MyDomainContext();
InvokeOperation<string> io = context.GetAuthenticationStatus();
io.Completed += delegate
{
if (io.HasError)
{
MessageBox.Show(io.Error.Message);
io.MarkErrorAsHandled();
}
else
{
MessageBox.Show(io.Value);
}
};
}
}
}
}
* 用于演示权限验证
*/
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;
using System.Windows.Navigation;
using System.ServiceModel.DomainServices.Client.ApplicationServices;
using Silverlight40.Web.Service;
using System.ServiceModel.DomainServices.Client;
namespace Silverlight40.WCFRIAServices
{
public partial class AuthenticationDemo : Page
{
public AuthenticationDemo()
{
InitializeComponent();
}
// 如果当前用户已经通过验证,则获取其用户信息
protected override void OnNavigatedTo(NavigationEventArgs e)
{
WebContext.Current.Authentication.LoadUser(delegate
{
if (WebContext.Current.User.IsAuthenticated)
{
lblStatus.Text = string.Format("登录成功,当前用户:{0},昵称:{1},所属角色:{2}",
WebContext.Current.User.Name,
WebContext.Current.User.Nickname,
string.Join(",", WebContext.Current.User.Roles));
}
},
null);
}
// 根据用户名和密码做身份验证
private void btnLogin_Click(object sender, RoutedEventArgs e)
{
LoginParameters lp = new LoginParameters(txtUserName.Text, txtPassword.Text, true, null);
WebContext.Current.Authentication.Login(
lp,
(lo) =>
{
if (lo.HasError)
{
lblStatus.Text = lo.Error.ToString();
}
else if (lo.LoginSuccess == false)
{
lblStatus.Text = "验证失败";
}
else if (lo.LoginSuccess == true)
{
lblStatus.Text = string.Format("登录成功,当前用户:{0},昵称:{1},所属角色:{2}",
WebContext.Current.User.Name,
WebContext.Current.User.Nickname,
string.Join(",", WebContext.Current.User.Roles));
}
},
null);
}
// 注销
private void btnLogout_Click(object sender, RoutedEventArgs e)
{
WebContext.Current.Authentication.Logout(
(lo) =>
{
if (lo.HasError)
lblStatus.Text = lo.Error.ToString();
else
lblStatus.Text = "注销成功";
},
null);
}
// 通过验证的并且角色属于“管理员”的用户才有权限访问 GetAuthenticationStatus 方法
private void btnAuthenticationTest_Click(object sender, RoutedEventArgs e)
{
// if (WebContext.Current.User.IsInRole("管理员"))
if (true)
{
MyDomainContext context = new MyDomainContext();
InvokeOperation<string> io = context.GetAuthenticationStatus();
io.Completed += delegate
{
if (io.HasError)
{
MessageBox.Show(io.Error.Message);
io.MarkErrorAsHandled();
}
else
{
MessageBox.Show(io.Value);
}
};
}
}
}
}
OK
[源码下载]