我正在寻找有关如何处理以下方案的一些最佳实践 - 从WCF服务层流向UI的权限:
我有使用PrincipalPermission属性修饰的方法的WCF服务。我想要一种方法允许客户端在调用方法之前检查它们是否具有所需的权限。
这方面的一个基本示例可能是检查用户是否可以执行特定功能(比如提交订单),然后可以使用该功能启用/禁用UI中的按钮。
可能的选择是向服务添加“{chatty”操作,例如bool CanSubmitOrder()
,或者使用单个方法OrderServicePermissions GetPermissions()
返回带有属性CanSubmitOrder
的消息?然后,我可以将“提交订单”按钮的启用状态设置为结果。
那么有人知道更好的方法,甚至是最佳实践吗?
提前致谢!
答案 0 :(得分:0)
在服务调用上拥有PrincipalPermission
属性的重点在于,您不必提前检查调用者是否有权调用 - 如果他没有,则WCF运行时会抛出异常。
为什么不依靠这种内置机制?为什么不将您的服务调用放在try..catch块中并处理异常(如果实际发生的话)?无论如何,它应该是“例外”的情况,对吗?
除了你所描述的,我没有看到任何其他“神奇”的方式。但普遍接受的做法是在发生任何例外时调用和处理它们。
马克
答案 1 :(得分:0)
好吧,如果您能够将应用程序发展为使用Windows Identity Foundation(WIF)来保护您的服务,则可以使用RequestSecurityTokenResponse的DisplayToken属性来实现此目的。
假设您的安全令牌服务支持它,显示令牌可以包含一个声明集,允许您将权限传递到UI,比如禁用绑定到用户无法调用的服务的控件。显示令牌是为CardSpace实现的WS-Trust的扩展,因此它不太可能在Windows世界之外得到广泛支持。
请注意,有些人认为显示令牌是坏消息并且违反了第一个身份法则:
http://www.francisshanahan.com
虽然其他人认为这是解决常见问题的合理而实用的解决方案:
http://blogs.msdn.com/b/vbertocci/archive/2007/10/31/on-displaytoken.aspx
答案 2 :(得分:0)
实现检查逻辑有两种通用类型:
分享图书馆。例如“RIA Services + Silverlight”。
加号:易于实施。
减少:没有互操作性(仅限.NET);每个库更改所需的客户端更新。
在服务部分实施常用方法验证。 加密:互操作性,如果检查逻辑已更改,则无需更新客户端
错误:可能很复杂,因为它只在你身上
如果我们使用SOA,最好使用第二种选择,只要您不在仅在.NET无处不在的公司中使用应用程序。
让我们考虑一下常见的例子。我们有一个windows / wpf表单。并且有两个字段:string类型的“surname”,int类型的“age”;和一个“保存”按钮。我们需要在客户端实施一些检查
1)对于某些用户按钮,“保存”被禁用;
2)姓氏不能为空,最大长度为256;
3)年龄不能低于0;
调用保存方法是
void Save(string surname, int age);
在服务中创建第二个方法,该方法返回带有验证信息的PermissonAnswerDTO的对象类型;
PermissonAnswerDTO SaveValidate(string surname, int age);
和主要验证方法
// If arguments are wrong
[FaultContract(typeof(NotSupportedException))]
// If the user have permisson to invoke this method
[FaultContract(typeof(CustomNotEnoughPermission))]
PermissonAnswerDTO Validate(string methodName, object[] methodParams);
在窗口加载时调用Validate("SaveValidate", null)
。如果抛出CustomNotEnoughPermission类型的异常,则阻止“保存”按钮。
如果用户可以保存,则调用用户的数据Validate("SaveValidate", object[2]{"Surname", "-60"};
。 -60无效,因此我们获得PermissonAnswerDTO类型的答案对象,其中包含以下信息:
ParameterName: "age",
ExceptionMessage: "age cannot be less then null".
我们可以优雅地向用户显示此信息。
我的想法是,有一天微软将实施这一点,并像往常一样称之为新技术。大多数情况下,微软的技术并没有像宣传的那样具有革命性。例如Windows Identity Foundation和Reactive Extensions。
[DataContract]
public class ParameterExceptionExplanaitonDTO
{
[DataMember]
public string ParameterName;
[DataMember]
public string ExceptionMessage;
}
[DataContract]
public class PermissonAnswerDTO
{
[DataMember]
public bool IsValid;
[DataMember]
public ParameterExceptionExplanaitonDTO[] ParameterExceptions;
}
public class Service1 : WcfContracts.IService1
{
// If arguments are wrong
[FaultContract(typeof(NotSupportedException))]
// If the user have permisson to invoke this method
[FaultContract(typeof(CustomNotEnoughPermission))]
public PermissonAnswerDTO Validate(string methodName, object[] methodParams)
{
//1) Using Reflection find the method with name = <methodName + Validate>
//2) Using Reflection cast each object in "object[] methodParams" to the required type
//3) Invoke method
}
private PermissonAnswerDTO GetUserNameValidate(int id)
{
//logic to check param
}
public string GetUserName(int id)
{
// if the user calls method we need validate parameter
GetUserNameValidate(id);
//some logic to retreive name
}
}