Silverlight安全性-保护您的Silverlight应用程序的安全(5)
WCF 数据服务中的授权
顾名思义,WCF 数据服务构建于 WCF 之上,以提供对数据源(通常大多数情况下可能是 LINQ-to-SQL 或 LINQ-to-Entity Framework 数据源)的基于 REST 的访问。 简而言之,这允许您使用映射到您的数 据源公开的实体集的 URL 访问您的数据(实体集通常会映射到数据库的表中)。 这些实体集的权限可在 服务代码隐藏文件内配置。 图 4 显示了 MyWcfDataService.svc.cs 文件的内容。
图 4 配置了实体集访问规则的 WCF 数据服务代码隐藏文件
Public class MyWcfDataService : DataService<SalesEntities>
{
// This method is called only once to initialize service-wide policies.
Public static void InitializeService(IDataServiceConfiguration config)
{
config.SetEntitySetAccessRule("Orders", EntitySetRights.AllRead);
config.SetEntitySetAccessRule("Products", EntitySetRights.AllRead |
EntitySetRights.WriteAppend | EntitySetRights.WriteDelete);
}}
在这里,我针对 Orders 实体集授予了“读取”权限,并且配置了 Products 实体集以允许完全读取 、插入新记录和删除现有记录。
但是,由于 WCF 数据服务会自动基于此配置提供对您的数据的访问,您无法直接访问代码,因此显然 无法实现任何特定授权逻辑。 WCF 数据服务支持允许开发人员在客户端和数据源之间实现逻辑的侦听器 。 例如,可以指定一个筛选特定实体集结果的查询侦听器。 图 5 中的示例显示了两个添加到 MyWcfDataService 类的查询侦听器。
图 5 WCF 数据服务中的查询侦听器
[QueryInterceptor("Products")]
Public Expression<Func<Product, bool>> OnQueryProducts()
{
String userName =ServiceSecurityContext.Current.PrimaryIdentity.Name;
return product => product.CreatedBy == userName;
}
[QueryInterceptor("Orders")]
Public Expression<Func<Comments, bool>> OnQueryOrders()
{
bool userInPrivateOrdersRole =
Thread.CurrentPrincipal.IsInRole("PrivateOrders");
return order => !order.Private|| userInPowerUserRole;
}
第一个侦听器被应用于 Products 实体集并确保了用户只能检索其自己创建的产品。 第二个侦听器确 保了只有 PrivateOrders 角色的用户才能读取标记“Private”的订单。
同样,可以指定在插入、修改或删除某个实体之前运行的更改侦听器,如下所示:
[ChangeInterceptor("Products")]
public void OnChangeProducts(Product product, UpdateOperations operations
{
if (product.CreatedBy != Thread.CurrentPrincipal.Identity.Name)
{
throw new DataServiceException(
"Only products created by a user can be deleted by that user");
}
}