允许匿名访问单个WCF服务方法
我有一个带有消息安全性和用户名凭据的WCF服务。 我的大多数方法都是以
[PrincipalPermission(SecurityAction.Demand, Role = ConstStrings.Roles.Admin)]
并且这些方法应该仅由经过身份validation的用户调用。
我想添加一个匿名调用的方法,但是我收到一个错误:
未提供用户名。 在ClientCredentials中指定用户名。
我喜欢类似于MVC的[AllowAnonymous]
属性
一种选择是实现您自己的ServiceAuthorizationManager
并使用您自己的自定义属性而不是PrincipalPermission
基本上,您必须从ServiceAuthorizationManager
inheritance。 通过将以下配置添加到web.config中,将其插入到WCF管道中(假设您的类在Org.Namespace命名空间中称为“CustomAuthorizationManager”)。
在自定义Authorization类中,您必须覆盖CheckAccessCore
方法,如下所示。 在那里,您可以检查您创建的自定义属性(这将是您将使用您想要的任何属性创建的普通.Net属性)。
protected override bool CheckAccessCore(OperationContext operationContext) { string action = operationContext.IncomingMessageHeaders.Action; DispatchOperation operation = operationContext.EndpointDispatcher.DispatchRuntime.Operations.FirstOrDefault(o => o.Action == action); Type hostType = operationContext.Host.Description.ServiceType; MethodInfo method = hostType.GetMethod(operation.Name); var myCustomAttributeOnMethod = method.GetCustomAttributes(true).Where(a => a.GetType() == typeof (MyCustomAttribute)).Cast(); . . . }
现在,您可以检查自定义属性并根据需要执行任何function。 例如,如果设置了自定义属性的“AllowAnonymous”标志,则可以跳过角色检查。 否则,您可能会获得用户的Windows身份并检查他们是否处于特定角色。
当然,您需要使用自定义属性而不是PrincipalPermission来装饰相关方法。
总而言之,您所做的基本上是使用您自己的普通自定义.Net属性来装饰您的所有方法,该属性提供一些信息。 即此方法允许匿名,此方法需要此角色等。然后,您更新web.config文件以告知WCF使用您自己的服务授权管理器。 您可以实现自己的服务授权管理器,您可以访问正在调用的方法,检查它的自定义属性并相应地说“Yay”或“Nay”。
您可以按照上面的建议执行操作,然后使用此代码段检查调用的特定方法:
var requestedOperation = OperationContext.Current.IncomingMessageHeaders.Action.Split('/').Last();
这将导致以下结果:
public override void Validate(string userName, string password) { if(String.IsNullOrEmpty(userName) && String.IsNullOrEmpty(password)) { var requestedOperation = OperationContext.Current.IncomingMessageHeaders.Action.Split('/').Last(); if("myAnonymousOperation" == requestedOperation) { // Allow anonymous access here. return; } } // Allow/deny users that provide credentials ValidateOtherCredentials(userName, password); }
您可以实现自定义UserNamePasswordValidator
如本教程中所示。 此validation器需要实现Validate
方法,以允许匿名访问。
public override void Validate(string userName, string password) { if(String.IsNullOrEmpty(userName) && String.IsNullOrEmpty(password)) { // Allow anonymous access here. return; } // Allow/deny users that provide credentials ValidateOtherCredentials(userName, password); }
注意:如果允许匿名访问,则使用PrincipalPermission
的授权过程仍需要凭据。 我不确定,但这可能会在运行时导致exception。