如何在BasicHttpBinding中的WCF服务中进行身份验证?

nRk*_*nRk 4 wcf basichttpbinding wcf-authentication wcf-security

我正在使用basicHttpBinding开发WCF服务,这些服务应该可以使用.net 1.1和.net 2.0访问,为此我使用basicHttpBinding.
在旧的ASMX Web服务中,我选择了一个Soap Header(AuthHeader)来对每个请求的用户进行身份验证.

如何使用basicHttpBinding在WCF中进行身份验证?任何样本或教程都会有所帮助.


NRK

fsp*_*rit 7

您可以像切换到WCF之前一样使用AuthHeader.也许它会更方便你,因为princples将保持不变.我在这个解决方案中看到的坏处是纯文本密码传输.无论如何,它只是另一种选择,您可以以某种方式加密/解密密码.

在这种情况下,您应该实现自己的IDispatchMessageInspector和IClientMessageInspector,如

[AttributeUsage(AttributeTargets.Class)]
public class CredentialsExtractorBehaviorAttribute : Attribute, IContractBehavior, IDispatchMessageInspector
{
    #region IContractBehavior implementation.

    public void ApplyDispatchBehavior(ContractDescription contractDescription, ServiceEndpoint endpoint,
                                      DispatchRuntime dispatchRuntime)
    {
        dispatchRuntime.MessageInspectors.Add(this);
    }

    ... empty interface methods impl skipped ...

    #endregion

    #region IDispatchMessageInspector implementation.

    public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext)
    {
        int i = request.Headers.FindHeader("username", "sec");
        if (-1 != i)
        {
            string username = request.Headers.GetHeader<string>("username", "sec");
            ... do smth ...
        }
        return null;
    }

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

    #endregion
}
Run Code Online (Sandbox Code Playgroud)

在一个示例中,我只放置标题用户名,但您可以实现包含用户名和密码的类,并使用它而不是字符串.在客户端:

internal class CredentialsInserter : IContractBehavior, IClientMessageInspector
{
    private string m_username;

    public CredentialsInserter(string username)
    {
        m_username = username;
    }

    #region IContractBehavior implementation.

    ... empty interface methods impl skipped ...

    public void ApplyClientBehavior(ContractDescription contractDescription, ServiceEndpoint endpoint,
                                    ClientRuntime clientRuntime)
    {
        clientRuntime.MessageInspectors.Add(this);
    }

    #endregion

    #region IClientMessageInspector implementation.

    public object BeforeSendRequest(ref Message request, IClientChannel channel)
    {
        MessageHeader<string> mh = new MessageHeader<string>(m_username);
        request.Headers.Add(mh.GetUntypedHeader("username", "sec"));
        return null;
    }

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

    #endregion
}
Run Code Online (Sandbox Code Playgroud)

然后,您应该在服务实现类上放置属性CredentialsExtractorBehaviorAttribute.

[CredentialsExtractorBehavior]
public class DummyService : IDummyService
{
   ... impl ...
}
Run Code Online (Sandbox Code Playgroud)

在客户端,您应该执行以下操作:

        using (DummyServiceClient c = new DummyServiceClient("TcpEndpoint"))
        {
            c.ChannelFactory.Endpoint.Contract.Behaviors.Add(
                new CredentialsInserter("_username_"));
            c.DummyMethod();
        }
Run Code Online (Sandbox Code Playgroud)