允许匿名访问单个WCF服务方法

我有一个带有消息安全性和用户名凭据的WCF服务。 我的大多数方法都是以

[PrincipalPermission(SecurityAction.Demand, Role = ConstStrings.Roles.Admin)] 

并且这些方法应该仅由经过身份validation的用户调用。

我想添加一个匿名调用的方法,但是我收到一个错误:

未提供用户名。 在ClientCredentials中指定用户名。

我喜欢类似于MVC的[AllowAnonymous]属性

一种选择是实现您自己的ServiceAuthorizationManager并使用您自己的自定义属性而不是PrincipalPermission

基本上,您必须从ServiceAuthorizationManagerinheritance。 通过将以下配置添加到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。