Monday, March 18, 2013

WCF – Security Using Membership and Role Providers


The default providers for the authentication (Membership) and authorization (Role), aspnet providers can be configured for WCF to have “Message” security with client credential type as “UserName”. The below example demonstrated is using “WsHttpBinding”.
When user (client) requests the service, user is supposed to pass the user credentials which are validated by WCF using Configured Membership and Roleproviders.

For “UserName”  message credential type, client is supposed to communicate with service using service certificate. Hence created and configured service certificate.


Service Code :

public class Service : IService
    {
        [PrincipalPermission(SecurityAction.Demand, Role = "Role1")]
        [OperationBehavior(Impersonation= ImpersonationOption.Allowed)]
        public DateTime GetServerDateTime()
        {
            ServiceSecurityContext ctx= ServiceSecurityContext.Current;
            return DateTime.Now;
        }

         [PrincipalPermission(SecurityAction.Demand, Role = "Role2")]
           [OperationBehavior(Impersonation = ImpersonationOption.Allowed)]
        public string GetServerName()
        {
            ServiceSecurityContext ctx = ServiceSecurityContext.Current;
            return Dns.GetHostName();
        }
    }

Client Code :
     static void Main(string[] args)
        {
            try
            {
                MainService.ServiceClient client = new MainService.ServiceClient();
                //"user1" has only role "Role1", hence only authorized to invoke "GetServerDateTime"
                //but not "GetServerName"
                client.ClientCredentials.UserName.UserName = "user1";
                client.ClientCredentials.UserName.Password = "Password@123";
                Console.WriteLine("Server DateTime : {0}", client.GetServerDateTime());
                Console.WriteLine("Server Name : {0}", client.GetServerName());
            }
            catch (Exception exp)
            {
                Console.WriteLine("Error : " + exp.Message);
            }
            Console.Read();
        }

Output :