WCF和身份验证

Sta*_*ker 6 c# wcf web-services

每次请求发送到WCF并在服务器上检查该值并决定是否发出请求时,我需要从客户端传递一个值,任何人都可以写一个例子吗?我不知道这是怎么实现的

case:我根据客户端的硬件生成一个密钥,我希望将该密钥发送到服务器,每次请求检查服务器db中是否接受密钥,然后决定是否处理请求.

提前致谢.

Sta*_*ker 1

首先我们需要在客户端实现Behavior和inspector来发送Key来验证客户端:

 class AuthenticationBehaviour : IEndpointBehavior
{
    #region IEndpointBehavior Members

    public void AddBindingParameters(ServiceEndpoint endpoint, System.ServiceModel.Channels.BindingParameterCollection bindingParameters)
    {
    }

    public void ApplyClientBehavior(ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.ClientRuntime clientRuntime)
    {
        AuthenticationMessageInspector inspector = new AuthenticationMessageInspector();
        clientRuntime.MessageInspectors.Add(inspector);
    }

    public void ApplyDispatchBehavior(ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.EndpointDispatcher endpointDispatcher)
    {
        //AuthenticationMessageInspector inspector = new AuthenticationMessageInspector();
        //endpointDispatcher.DispatchRuntime.MessageInspectors.Add(inspector);
    }

    public void Validate(ServiceEndpoint endpoint)
    {
    }

    class AuthenticationMessageInspector : IClientMessageInspector
{
    private const string HeaderKey = "Authentication";

    public object BeforeSendRequest(ref Message request, IClientChannel channel)
    {

        if (Session.MachineId == 0)
        {
            Session.MachineId = LicenseGenerator.GenerateLicense();
        }


        request.Headers.Add(MessageHeader.CreateHeader(HeaderKey, string.Empty, Session.MachineId));
        return null;
    }

    public void AfterReceiveReply(ref Message reply, object correlationState)
    {

    }
}
Run Code Online (Sandbox Code Playgroud)

现在我们需要在服务器端(WCF 服务)实现行为和检查器来检查发出的每个请求并提取标头然后验证它:

  public class AuthenticationBehaviour : IEndpointBehavior
{
    #region IEndpointBehavior Members

    public void AddBindingParameters(ServiceEndpoint endpoint, System.ServiceModel.Channels.BindingParameterCollection bindingParameters)
    {
    }

    public void ApplyClientBehavior(ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.ClientRuntime clientRuntime)
    {
        //AuthenticationMessageInspector inspector = new AuthenticationMessageInspector();
        //clientRuntime.MessageInspectors.Add(inspector);
    }

    public void ApplyDispatchBehavior(ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.EndpointDispatcher endpointDispatcher)
    {
        AuthenticationMessageInspector inspector = new AuthenticationMessageInspector();
        endpointDispatcher.DispatchRuntime.MessageInspectors.Add(inspector);
        //Console.WriteLine("Dispatcher Applied!");
    }

    public void Validate(ServiceEndpoint endpoint)
    {
    }

    #endregion
}

   public class AuthenticationMessageInspector : IDispatchMessageInspector

{

    #region Members
    private string conStr = "", commStr = "";
    public IDbConnection Connection { get; set; }
    public IDbCommand Command { get; set; }
    public IDataReader Reader { get; set; }

    #endregion        
    private const string HeaderKey = "Authentication";
    public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext)
    {
        //Console.WriteLine("recieved Request! ");
        int headerIndex = request.Headers.FindHeader(HeaderKey, string.Empty);
        if (headerIndex < 0 || string.IsNullOrEmpty(request.Headers.GetHeader<String>(headerIndex)))
        {

            throw (new Exception("Access Denied!\n"));
            return null;
        } 


        bool valid = Validate(request.Headers.GetHeader<String>(headerIndex));
        if (!valid)
        {
            Console.WriteLine("recieved Request! From " + request.Headers.GetHeader<String>(headerIndex) + " and Access Denied!\n");
            throw (new Exception("Access Denied!\n" + request.Headers.GetHeader<String>(headerIndex) + " License Number is not athourized! "));         
        }
        if (headerIndex != -1)
        {
            Console.WriteLine("recieved Request! From " + request.Headers.GetHeader<String>(headerIndex));
        }
        return null;

    }

    public void BeforeSendReply(ref Message reply, object correlationState)
    {

    }
}
Run Code Online (Sandbox Code Playgroud)

现在让我们注册行为:

            _routingHost.Description.Endpoints[0].Behaviors.Add(new Gateway.Controllers.AuthenticationBehaviour());
_routingHost.Open();
Run Code Online (Sandbox Code Playgroud)

就是这样,谢谢。