Authentication on WCF Data Service or OData: Windows Authentication Part#1

In this article, I am going to show how to enable windows authentication on WCF Data Service.

Follow the below steps

Step 1

Create WCF Data Service.

Read below how to create WCF Data Service and introduction to OData.

http://dhananjaykumar.net/2010/06/13/introduction-to-wcf-data-service-and-odata/

While creating data model to be exposed as WCF Data Service, we need to take care of only one thing that Data model should be created as SQL Login

So while creating data connection for data model connect to data base through SQL Login.

Step 2

Host WCF Data Service in IIS. WCF Data Service can be hosted in exactly the same way a WCF Service can be hosted.

Read below how to host WCF 4.0 service in IIS 7.5

http://dhananjaykumar.net/2010/09/07/walkthrough-on-creating-wcf-4-0-service-and-hosting-in-iis-7-5/

Step 3

Now we need to configure WCF Service hosted in IIS for Windows authentication.

Here I have hosted WCF Data Service in WcfDataService IIS web site.

Select WcfDataService and in IIS category you can see Authentication tab.

On clicking on Authentication tab, you can see various authentication options.

Enable Windows authentication and disable all other authentication

To enable or disable a particular option just click on that and at left top you can see the option to toggle

Now by completing this step you have enabled the Windows authentication on WCF Data Service hosted in IIS.

Passing credential from .Net Client

If client windows domain is having access to server then

If client is not running in windows domain which is having access to server then credential we need to pass the as below,

So to fetch all the records

Program.cs


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Services.Client;
using ConsoleApplication1.ServiceReference1;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {

            NorthwindEntities1 entity = new NorthwindEntities1
                                       (new Uri("http://localhost:7890/wcfdataservice1.svc/"));
            entity.Credentials = System.Net.CredentialCache.DefaultCredentials;
            entity.Credentials = new System.Net.NetworkCredential("UserName", "Password", "Domian");
            try
            {

                var result = from r in entity.Products select r;
                foreach (var r in result)
                {
                    Console.WriteLine(r.ProductName);
                }
            }
            catch (DataServiceQueryException ex)
            {
                Console.WriteLine(ex.StackTrace);
            }




        }


    }
}



In above article we saw how to enable Windows authentication on WCF Data Service and then how to consume from .Net client. In next article we will see how to consume Windows authenticated WCF Data Service from SilverLight client.

IgnoreDataMember attribute in WCF POCO Serialization

POCO stands for PLAIN OLD CLR OBJECT.

If  in WCF we are using

1. Complex Data type for example custom class

2. And not attributing this custom class as DataContract and properties of the class as DataMember

3. If we want to expose the below custom class to client and not using DataContractSeraliazer then all public properties will be automatically serialized

public class MyCustomData
{
    public string Name { get; set; }
    public string RollNumber { get; set; }
    public string Subject { get; set; }
}

Automatically POCO (Plain old CLR Object) is serialized without using DataContract attribute. So to test this, let us create service contract

    [ServiceContract]
    public interface IService1
    {
        [OperationContract]
        MyCustomData GetData();
    }

And service implementation is as below


    public class Service1 : IService1
    {
        public MyCustomData GetData()
        {
            MyCustomData data = new MyCustomData { Name = "John", RollNumber = "1", Subject = "WCF" };
            return data;
        }
    }

So when we consume this service at client side

clip_image002

We can use that as above

Program.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ConsoleApplication1.ServiceReference1;
namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            Service1Client proxy = new Service1Client();
            MyCustomData data = proxy.GetData();
            Console.WriteLine(data.Name + data.Subject + data.RollNumber);
            Console.ReadKey(true);
        }
    }
}

Now we know how we could serialize custom data or class without using DataContractSerlializer. But if we notice all the public property are serialized. If we want to hide some of public property from serialization then we will use IgnoreDataMember

 public class MyCustomData
    {

        public string Name { get; set; }
        [IgnoreDataMember]
        public string RollNumber { get; set; }
        public string Subject { get; set; }
    }

Add the namespace System.RunTime.Serilization to work with IgnoreDataMember attribute.

Now we are hiding public property RollNumber with IgnoreDataMember attribute , so at the client side when we try to access RollNumber property on custom class MyCustomData we will get the below compile time error.

clip_image004[5]

Error says there is no definition for RollNumber is present at the client side.