如何限制访问WCF中的一些方法? [英] How do I restrict access to some methods in WCF?

查看:173
本文介绍了如何限制访问WCF中的一些方法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am a bit lost getting started with a simple WCF service. I have two methods and I want to expose one to the world and the second one I want to limit to certain users. Eventually I want to be able to use a client application to use the restricted method. So far I can access both methods anonymously:

C#code

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.";
        }


    }
}

配置

<?xml version="1.0"?>
<configuration>
  <system.web>
    <compilation debug="true" targetFramework="4.0" />
  </system.web>
  <system.serviceModel>
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true"/>    
    <standardEndpoints>
      <webHttpEndpoint>
        <standardEndpoint name="" helpEnabled="true" 
          automaticFormatSelectionEnabled="true"/>
      </webHttpEndpoint>
    </standardEndpoints>
  </system.serviceModel>
</configuration>

我该如何开始?

推荐答案

很多,我发现是我需要的东西差不多但不完全正确的答案。我结束了设立ASP.net成员资格和实现自定义属性来拉Authorization头并且登录流程作为请求进来了。所有的魅力来的 BeforeCall 的发生和 ParseAuthorizationHeader 如下:

A lot of the answers I found were almost what I needed but not quite right. I wound up setting up ASP.net membership and implementing a custom attribute to pull an authorization header and process login as the request came in. All of the magic happens in BeforeCall and ParseAuthorizationHeader below:

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<string>("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)
    {
    }

}

从那里,我只需要我的新属性添加到服务合同条目。该方法的任何请求都需要一个有效的授权头或的没有获得许可的答复将用做任何进一步处理送回来。

From there I just need to add my new attribute to the service contract entries. Any request to that method will require a valid authorization header or a Not Authorized response will be sent back with doing any further processing.

[ServiceContract]
interface ILocationService
{
    [OperationContract]
    string GetLocation(string id);

    [OperationContract]
    [UsernamePasswordAuthentication]  // this attribute will force authentication
    string GetHiddenLocation(string id);
}

这篇关于如何限制访问WCF中的一些方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆