我们有一个用C#编写的服务器(Framework 3.5 SP1)。客户使用我们的服务器API编写客户端应用最近,我们创建了几个级别的许可方案,如Basic,Intermediate和All。如果您有基本许可证,那么您可以在我们的API上调用几种方法。同样,如果你有中级,你会得到一些额外的方法来调用,如果你有All,那么你可以调用所有的方法。
当服务器启动时,它获取许可证类型。现在在每种方法中,我都必须检查许可证的类型,并决定是否继续使用该功能或返回。
例如,方法InterMediateMethod()
只能由中间许可证和所有许可证使用。所以我必须这样。
public void InterMediateMethod()
{
if(licenseType == "Basic")
{
throw new Exception("Access denied");
}
}
对我来说,这是非常蹩脚的方法。有没有更好的方法来做到这一点?有没有任何声明方法通过定义一些自定义属性来做到这一点?我查看了创建自定义CodeAccessSecurityAttribute
,但没有取得很好的成功。
答案 0 :(得分:2)
由于你在每个方法中都添加了“if”逻辑(而且上帝知道还有什么),你可能会发现使用PostSharp(AOP框架)来实现同样的目标更容易,但就个人而言,我不喜欢喜欢这两种方法......
我认为如果为每个许可证维护三个不同的分支(源代码)会更加清洁,这可能会增加一些维护(可能不是)的开销,但至少要保持干净,简单。
我也对别人对此有何看法感兴趣。
好帖,我喜欢......
答案 1 :(得分:2)
可能一种简单而干净的方法是添加一个代理API,它复制所有API方法并将它们暴露给客户端。调用时,代理会将调用转发给您的实际方法,或返回“未许可”错误。代理可以构建为三个单独的(基本,中间,全部)类,您的服务器将为您的客户端许可创建适当代理的实例。这样做的优点是性能开销最小(因为您只检查一次许可证)。您可能甚至不需要为“所有”级别使用代理,因此它将获得最大性能。根据你现有的设计,可能很难理解这一点。
另一种可能性是重新设计并将您的API分解为基本/中间/所有“部分”,并将它们放在单独的程序集中,这样可以通过许可证启用/禁用整个程序集,并尝试调用未经许可的方法只能返回“找不到方法”错误(例如,如果您只是没有加载所需的程序集,则会自动发生TypeLoadException)。这将使测试和维护变得更加容易,并且再次避免在每个方法级别进行检查。
如果你不能这样做,至少尝试使用比每个方法手写的“if”语句更集中的系统。
示例(可能与现有设计兼容或不兼容)包括:
为每个方法添加自定义属性,并让服务器调度代码在将调用传递给方法之前使用反射检查此属性。
添加自定义属性以标记方法,并使用PostSharp将标准位代码注入到将根据许可证读取和测试属性的方法中。
使用PostSharp添加代码来测试许可证,但是将每个方法的许可证详细信息放在更加数据驱动的系统中(例如,使用XML文件而不是属性来描述方法权限)。这样,您就可以通过编辑单个文件轻松更改整个服务器的许可,并允许您以后轻松添加全新级别或类型的许可。
希望能给你一些想法。
答案 2 :(得分:0)
您可能真的想考虑购买许可解决方案,而不是自己动手。我们使用Desaware并对它非常满意。
在方法级别执行许可将带您进入一个受伤的世界。对此进行维护将是一场噩梦,它根本无法扩展。
您应该真正关注产品的组件化。您的代码应该大致属于“功能”,可以捆绑到“组件”中。诀窍是让每个组件进行许可检查,并拥有一个许可解决方案,知道许可是否包含组件。
我们产品的组件通常在汇编级别,但对于我们的Web产品,它们可以达到ASP.Net服务器控制级别。
答案 3 :(得分:0)
这可能很难维持 您可以尝试使用策略模式 This可以作为您的起点。
答案 4 :(得分:0)
我想知道人们如何授权SOA服务。它们可以按服务或每个端点获得许可。
答案 5 :(得分:0)
我同意@Ostati的答案,你应该保留代码的3个分支。
我将进一步扩展,然后我将公开3种不同的服务(最好是WCF服务)并颁发授予特定服务访问权限的证书。这样,如果有人试图访问更高级别的功能,他们将无法访问服务期限。