1

I have a WCF service that is configured programmatically - No XML config file. I am trying to implement a Custom Username Password Validation using a repository database table to verify against. I do not wish to require Windows Usernames / passwords on client - server. I am using NetTCPBinding.

I know how to create a CustomValidator, and how to assign it to the ServiceBehavior. My issue is that I do not know how to set the RepositoryConnection string for the validator when the service instantiates it (I am not sure how that mechanism works anyway.) this property of my validator is what I need to set - programmatically - Please remember I am not using any XML CONFIG FILE . public string RepositoryConnection { get; set;}

I know my NetTCPBinding will need to be changed and as this is my first WCF Security Attempt any comments are welcome and I will try to update question to provide any further info requested. I post relevant parts of code below.

public static NetTcpBinding SetNetTCPBinding(string name, string ns)
{
    NetTcpBinding binding = new NetTcpBinding(); //SecurityMode.None);
    binding.Security.Mode = SecurityMode.Transport;
    binding.Security.Message.ClientCredentialType = MessageCredentialType.Windows;
    binding.Security.Transport.ClientCredentialType = TcpClientCredentialType.Windows;
    binding.Security.Transport.ProtectionLevel = ProtectionLevel.None;
}


public class ServiceUserNamePasswordValidator : UserNamePasswordValidator
{
    **public string RepositoryConnection { get; set;}**

    public override void Validate(string userName, string password)
    {
            try
            {
                if (string.IsNullOrEmpty(userName) || password == null)
                {
                    //throw new ArgumentNullException();
                    throw new FaultException("Username cannot be null or empty; Password cannot be null and should not be empty");
                }
                IGenericDataRepository<MyAppDBData.Users> repositorySingle = new GenericDataRepository<MyAppDBData.Users>(RepositoryConnection);
                MyAppDBData.Users USER = new MyAppDBData.Users();

                USER = repositorySingle.GetSingle(d => d.Name.ToLower() == userName.ToLower() && d.Password == password);

                if (USER == null)
                {
                    // This throws an informative fault to the client.
                    throw new FaultException("Unknown Username or Incorrect Password");
                }
            }
            finally{
            }
   }
}

Here is where I have looked for answers - aside from gargling it.

WCF Authentication: Custom Username and Password Validator asp.net

WCF custom username and password validation is not executed

WCF netTCPBinding

WCF TransportCredentialOnly not sending username and password

Windows Authentication / Encryption in WCF With NetTcpBinding

Community
  • 1
  • 1
Ken
  • 2,518
  • 2
  • 27
  • 35

1 Answers1

3

I have taken the sample here

WebServiceHost host = new ServiceHost(typeof(CloudService), httpUri);
host.Description.Behaviors.Find<ServiceCredentials>().UserNameAuthentication
    .UserNamePasswordValidationMode = UserNamePasswordValidationMode.Custom;
host.Description.Behaviors.Find<ServiceCredentials>().UserNameAuthentication
    .CustomUserNamePasswordValidator = new ServiceUserNamePasswordValidator(repositoryConnectionString);

So you may pass repository name/connstring as constructor parameter, or initialize validator prior to assign it to the host property.

Mimas
  • 525
  • 3
  • 7
  • I was at that page and saw the x509 stuff and that threw me. I have this - should I change anything binding.Security.Mode = SecurityMode.Transport; // should I change to(With Message Credential)?; binding.Security.Message.ClientCredentialType = MessageCredentialType.UserName; binding.Security.Transport.ClientCredentialType = TcpClientCredentialType.Windows; binding.Security.Transport.ProtectionLevel = ProtectionLevel.None; – Ken Nov 11 '15 at 14:34
  • I think here https://msdn.microsoft.com/en-us/library/aa702565.aspx all valid combinations of Mode/ClientCredentialType good described. In a nutshell "message security -> UserName", "Transport security -> Basic" – Mimas Nov 11 '15 at 16:04