【问题标题】:Selfhosted WCF Service with SSL and Username and Password authentication具有 SSL 和用户名和密码身份验证的自托管 WCF 服务
【发布时间】:2014-03-12 10:51:35
【问题描述】:

我想从控制台应用程序发布 WCF 服务。出于安全目的,我想通过 SSL 进行通信,所以我创建了一个自签名证书。对于身份验证,我编写了自己的 UserNamePasswordValidator。不幸的是,这不起作用

这是我目前的代码:

服务器

public class Program
{
    public static void Main()
    {
        var baseAddress = new Uri("https://localhost:8080/SelfHostedUsernamePasswordService");

        using (var host = new ServiceHost(typeof(SelfHostedUsernamePasswordService), baseAddress))
        {
            var binding = new BasicHttpBinding(BasicHttpSecurityMode.TransportWithMessageCredential);
            binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Basic;
            binding.Security.Message.ClientCredentialType = BasicHttpMessageCredentialType.Certificate;

            var endpoint = host.AddServiceEndpoint(typeof(ISelfHostedUsernamePasswordService), binding, baseAddress);

            var cf = new ChannelFactory<ISelfHostedUsernamePasswordService>(binding, endpoint.Address);
            cf.Credentials.ClientCertificate.SetCertificate(
                StoreLocation.LocalMachine,
                StoreName.My,
                X509FindType.FindByThumbprint,
                "0000000000000000000000000000000000000000");

            var metadataBehavior = new ServiceMetadataBehavior();
            metadataBehavior.HttpsGetEnabled = true;
            metadataBehavior.MetadataExporter.PolicyVersion = PolicyVersion.Policy15;
            host.Description.Behaviors.Add(metadataBehavior);

            var credentialBehavior = new ServiceCredentials();
            credentialBehavior.UserNameAuthentication.CustomUserNamePasswordValidator = new UsernamePasswordValidator();
            credentialBehavior.UserNameAuthentication.UserNamePasswordValidationMode = UserNamePasswordValidationMode.Custom;
            host.Description.Behaviors.Add(credentialBehavior);

            host.Open();

            Console.WriteLine("The service is ready at {0}", baseAddress);
            Console.WriteLine("Press <Enter> to stop the service.");
            Console.ReadLine();

            host.Close();
        }
    }
}

public class UsernamePasswordValidator : UserNamePasswordValidator
{
    public override void Validate(string userName, string password)
    {
        if (!string.Equals(userName, "admin", StringComparison.OrdinalIgnoreCase) ||
            !string.Equals(password, "password", StringComparison.Ordinal))
        {
            Console.WriteLine("Validation failed.");
            throw new SecurityTokenException("Validation failed.");
        }
        Console.WriteLine("Validation successful.");
    }
}

客户

class Program
{
    static void Main()
    {
        using (var client = new SelfHostedUsernamePasswordServiceClient())
        {
            client.ClientCredentials.UserName.UserName = "admin";
            client.ClientCredentials.UserName.Password = "password";

            var result = client.GetData(12345);
            Console.WriteLine("Result from service: {0}", result);

            client.Close();
        }
    }
}

使用此代码,我得到一个 MessageSecurityException(找不到“System.IdentityModel.Tokens.UserNameSecurityToken”令牌类型的令牌身份验证器)。但我认为创建 TokenAuthenticator 时我走错了路……

顺便说一句,永远不会调用 UsernamePasswordValidator。

【问题讨论】:

    标签: c# wcf authentication ssl


    【解决方案1】:

    好的,知道了。

    我必须将 Transport CredentialType 设置为“Certificate”,将 Message CredentialType 设置为“UserName”。两边。

    这是工作代码:

    服务器

    public class Program
    {
        public static void Main()
        {
            var baseAddress = new Uri("https://localhost:8080/SelfHostedUsernamePasswordService");
    
            using (var host = new ServiceHost(typeof(SelfHostedUsernamePasswordService), baseAddress))
            {
                var binding = new BasicHttpBinding(BasicHttpSecurityMode.TransportWithMessageCredential);
                binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Certificate;
                binding.Security.Message.ClientCredentialType = BasicHttpMessageCredentialType.UserName;
    
                var endpoint = host.AddServiceEndpoint(typeof(ISelfHostedUsernamePasswordService), binding, baseAddress);
    
                var cf = new ChannelFactory<ISelfHostedUsernamePasswordService>(binding, endpoint.Address);
                cf.Credentials.ClientCertificate.SetCertificate(
                    StoreLocation.LocalMachine,
                    StoreName.My,
                    X509FindType.FindByThumbprint,
                    "0000000000000000000000000000000000000000");
    
                var credentialBehavior = new ServiceCredentials();
                credentialBehavior.UserNameAuthentication.CustomUserNamePasswordValidator = new UsernamePasswordValidator();
                credentialBehavior.UserNameAuthentication.UserNamePasswordValidationMode = UserNamePasswordValidationMode.Custom;
                credentialBehavior.IssuedTokenAuthentication.AllowUntrustedRsaIssuers = true;
                host.Description.Behaviors.Add(credentialBehavior);
    
                var metadataBehavior = new ServiceMetadataBehavior();
                metadataBehavior.HttpsGetEnabled = true;
                metadataBehavior.MetadataExporter.PolicyVersion = PolicyVersion.Policy15;
                host.Description.Behaviors.Add(metadataBehavior);
    
                host.Open();
    
                Console.WriteLine("The service is ready at {0}", baseAddress);
                Console.WriteLine("Press <Enter> to stop the service.");
                Console.ReadLine();
    
                host.Close();
            }
        }
    }
    
    public class UsernamePasswordValidator : UserNamePasswordValidator
    {
        public override void Validate(string userName, string password)
        {
            if (!string.Equals(userName, "admin", StringComparison.OrdinalIgnoreCase) ||
                !string.Equals(password, "password", StringComparison.Ordinal))
            {
                Console.WriteLine("Validation failed.");
                throw new SecurityTokenException("Validation failed.");
            }
            Console.WriteLine("Validation successful.");
        }
    }
    

    客户

    class Program
    {
        static void Main()
        {
            var remoteAddress = new EndpointAddress(new Uri("https://localhost:8080/SelfHostedUsernamePasswordService"));
    
            var binding = new BasicHttpBinding(BasicHttpSecurityMode.TransportWithMessageCredential);
            binding.Security.Message.ClientCredentialType = BasicHttpMessageCredentialType.UserName;
            binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Certificate;
    
            using (var client = new SelfHostedUsernamePasswordServiceClient(binding, remoteAddress))
            {
                client.ClientCredentials.UserName.UserName = "admin";
                client.ClientCredentials.UserName.Password = "password";
    
                var result = client.GetData(12345);
                Console.WriteLine("Got result from service: {0}", result);
                Console.ReadLine();
    
                client.Close();
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-13
      相关资源
      最近更新 更多