How to authenticate in WCF services in BasicHttpBinding?
Asked Answered
A

3

4

I am developing WCF services with basicHttpBinding, these services should be accessible using .net 1.1 & .net 2.0, for this purpose I am using basicHttpBinding.
In old ASMX web services I assed one Soap Header (AuthHeader) to authenticate the user every request.

How Can I authenticate in WCF using basicHttpBinding? Any sample Or tutorial will helpfull.


nRk

Abelmosk answered 24/11, 2009 at 4:16 Comment(0)
S
7

You can use AuthHeader as you did before switching to WCF. Maybe it will be more convinient for you, cause the princples will remain the same. The bad thing i see in this solution is a plain text password transfer. Anyway, it's just another option and you can encrypt/decrypt the password somehow.

In this case you should implement your own your IDispatchMessageInspector & IClientMessageInspector, like

[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
}

In a sample i placed to header only username, but you can implement your a class containing username and password and use it instead of string. On the client:

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
}

Then you should place attribute CredentialsExtractorBehaviorAttribute on your service implementation class.

[CredentialsExtractorBehavior]
public class DummyService : IDummyService
{
   ... impl ...
}

And on the client side you should do the following:

        using (DummyServiceClient c = new DummyServiceClient("TcpEndpoint"))
        {
            c.ChannelFactory.Endpoint.Contract.Behaviors.Add(
                new CredentialsInserter("_username_"));
            c.DummyMethod();
        }
Sjoberg answered 18/12, 2009 at 10:5 Comment(0)
S
3

First of all - yes you can! It depends on whether you use Transport or Message binding - if you're internet-facing, you're more likely to use message-based security.

Unfortunately, for message-based security, basicHttpBinding only supports certificates which is a bit of a pain.

wsHttpBinding on the other hand would support username/password or other methods as well.

You'd configure wsHttpBinding with username/password client credentials over message-based security like this:

  <system.serviceModel>
    <bindings>
      <wsHttpBinding>
        <binding name="wsUserName">
          <security mode="Message">
            <message clientCredentialType="UserName"/>
          </security>
        </binding>
      </wsHttpBinding>
    </bindings>
    <services>
      <service name="yourservice">
        <endpoint name="YourEndpoint"
                  address=""
                  binding="wsHttpBinding"
                  bindingConfiguration="wsUserName"
                  contract="IYourService" />
      </service>
    </services>
  </system.serviceModel>

The section under <bindings> defines a binding configuration for wsHttpBinding that uses message-security with username/password client credentials.

The section under <service> defines a sample service that uses wsHttpBinding and that references that binding configuration that we just defined.

On the server side, you could now use the username/password that's being sent over the wire to validate your callers either in your Active Directory (everyone calling needs an AD account with you), or in the ASP.NET membership system database; or if you really really must, you could write your own authentication mechanism, too.

Find a lot of useful information on WCF security at Codeplex - excellent resource.

Sorcim answered 24/11, 2009 at 5:40 Comment(2)
Thanks, marc_s, I will go through the codeplex material. So, I can only validate against certificates in basicHttpBiding. that mean I cannot validate the user against username & password? Is there any other in basichttpBiding to validate/Authenticate against Username & password? -- nrkAbelmosk
@nrk: yes, if you use message-security in basicHttpBinding, you can only use certificates to authenticate. If you would use transport security, then you could use other means of authenticationSorcim
B
0

Check the scenarios here to try to match one to your situation. Each scenario is provided with a chceklist of items required to implement the solution.

Beckibeckie answered 3/12, 2009 at 15:52 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.