如何限制对WCF中某些方法的访问?

我开始使用简单的WCF服务有点失落。 我有两种方法,我希望向世界公开一个,第二个我想限制某些用户。 最终,我希望能够使用客户端应用程序来使用受限制的方法。 到目前为止,我可以匿名访问这两种方法:

C#代码

namespace serviceSpace { [ServiceContract] interface ILocationService { [OperationContract] string GetLocation(string id); [OperationContract] string GetHiddenLocation(string id); } [AspNetCompatibilityRequirements( RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)] public class LocationService : ILocationService { [WebGet(UriTemplate = "Location/{id}")] public string GetLocation(string id) { return "O hai, I'm available to everyone."; } // only use this if authorized somehow [WebGet(UriTemplate = "Location/hush/{id}")] public string GetHiddenLocation(string id) { return "O hai, I can only be seen by certain users."; } } } 

组态

               

我该如何开始?

我找到的很多答案几乎都是我需要但不太对的。 我结束了设置ASP.net成员资格并实现自定义属性来提取授权标头并在请求进入时处理登录。所有的魔法都发生在下面的BeforeCallParseAuthorizationHeader中:

 public class UsernamePasswordAuthentication : Attribute, IOperationBehavior, IParameterInspector { public void ApplyDispatchBehavior(OperationDescription operationDescription, DispatchOperation dispatchOperation) { dispatchOperation.ParameterInspectors.Add(this); } public void AfterCall(string operationName, object[] outputs, object returnValue, object correlationState) { } public object BeforeCall(string operationName, object[] inputs) { var usernamePasswordString = parseAuthorizationHeader(WebOperationContext.Current.IncomingRequest); if (usernamePasswordString != null) { string[] usernamePasswordArray = usernamePasswordString.Split(new char[] { ':' }); string username = usernamePasswordArray[0]; string password = usernamePasswordArray[1]; if ((username != null) && (password != null) && (Membership.ValidateUser(username, password))) { Thread.CurrentPrincipal = new GenericPrincipal(new GenericIdentity(username), new string[0]); return null; } } // if we made it here the user is not authorized WebOperationContext.Current.OutgoingResponse.StatusCode = HttpStatusCode.Unauthorized; throw new WebFaultException("Unauthorized", HttpStatusCode.Unauthorized); } private string parseAuthorizationHeader(IncomingWebRequestContext request) { string rtnString = null; string authHeader = request.Headers["Authorization"]; if (authHeader != null) { var authStr = authHeader.Trim(); if (authStr.IndexOf("Basic", 0) == 0) { string encodedCredentials = authStr.Substring(6); byte[] decodedBytes = Convert.FromBase64String(encodedCredentials); rtnString = new ASCIIEncoding().GetString(decodedBytes); } } return rtnString; } public void AddBindingParameters(OperationDescription operationDescription, System.ServiceModel.Channels.BindingParameterCollection bindingParameters) { } public void ApplyClientBehavior(OperationDescription operationDescription, ClientOperation clientOperation) { } public void Validate(OperationDescription operationDescription) { } } 

从那里我只需要将我的新属性添加到服务合同条目。 对该方法的任何请求都将需要一个有效的授权标头,或者在进行任何进一步处理时将返回Not Authorized响应。

 [ServiceContract] interface ILocationService { [OperationContract] string GetLocation(string id); [OperationContract] [UsernamePasswordAuthentication] // this attribute will force authentication string GetHiddenLocation(string id); } 

使用以下步骤限制对特定Windows用户的访问:

  • 打开计算机管理Windows小程序。
  • 创建一个Windows组,其中包含您希望授予其访问权限的特定Windows用户。 例如,一个组可以称为“CalculatorClients”。
  • 将您的服务配置为要求ClientCredentialType =“Windows”。 这将要求客户端使用Windows身份validation进行连接。
  • 使用PrincipalPermission属性配置服务方法,以要求连接用户是CalculatorClients组的成员。
 // Only members of the CalculatorClients group can call this method. [PrincipalPermission(SecurityAction.Demand, Role = "CalculatorClients")] public double Add(double a, double b) { return a + b; }