WCF 数据服务身份验证

发布于 2024-10-30 18:38:34 字数 102 浏览 3 评论 0原文

- 是否可以使用基于证书的身份验证来保护 WCF 数据服务的安全?

- 是否有描述此过程的资源?

- 我们可以将消息安全性与 WCF 数据服务结合使用吗?

-Is it possible to secure a WCF Data Service by using certificate-based authentication ?

-Is there a resource that describes this process ?

-Can we use Message security with a WCF Data service ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

原野 2024-11-06 18:38:34

您所有问题的答案都是“是”。下面是 Microsoft 模式和实践团队提供的信息非常丰富的链接,可准确完成您正在寻找的任务。

http://msdn.microsoft.com/en-us/library/cc949005.aspx

The answer to all your questions is "yes". Below is a very informative link provided by the Patterns and Practices team at Microsoft to accomplish exactly what you are looking for.

http://msdn.microsoft.com/en-us/library/cc949005.aspx

莫相离 2024-11-06 18:38:34

基于证书的身份验证可以这样完成:

服务器端:

public class ODataService : DataService<Database>
    {
        public ODataService()
        {
            ProcessingPipeline.ProcessingRequest += ProcessingPipeline_ProcessingRequest;
        }

        void ProcessingPipeline_ProcessingRequest(object sender, DataServiceProcessingPipelineEventArgs e)
        {
            if (!HttpContext.Current.Request.ClientCertificate.IsPresent)
            {
                throw new DataServiceException(401, "401 Unauthorized");
            }

            var cert = new X509Certificate2(HttpContext.Current.Request.ClientCertificate.Certificate);
            if (!ValidateCertificate(cert))
            {
                throw new DataServiceException(401, "401 Unauthorized");
            }

            var identity = new GenericIdentity(cert.Subject, "ClientCertificate");
            var principal = new GenericPrincipal(identity, null);
            Thread.CurrentPrincipal = principal;
            HttpContext.Current.User = principal;
        }

        private bool ValidateCertificate(X509Certificate2 cert)
        {
            // do some validation
        }

客户端:

为数据库服务引用创建一个分部类 (DataServiceContext)

public partial class Database
{
    // ref: http://social.msdn.microsoft.com/Forums/en-US/0aa2a875-fd59-4f3e-a459-9f604b374749/how-do-i-use-certificate-based-authentication-with-data-services-client?forum=adodotnetdataservices
    private X509Certificate clientCertificate = null;
    public X509Certificate ClientCertificate
    {
        get
        {
            return clientCertificate;
        }
        set
        {
            if (value == null)
            {
                // if the event has been hooked up before, we should remove it
                if (clientCertificate != null)
                {
                    SendingRequest -= OnSendingRequest_AddCertificate;
                }
            }
            else
            {
                // hook up the event if its being set to something non-null
                if (clientCertificate == null)
                {
                   SendingRequest += OnSendingRequest_AddCertificate;
                }
            }

            clientCertificate = value;
        }
    }

    private void OnSendingRequest_AddCertificate(object sender, SendingRequestEventArgs args)
    {
        if (null != ClientCertificate)
        {
            (args.Request as HttpWebRequest).ClientCertificates.Add(ClientCertificate);
        }
    }

像这样使用

        Database db = new Database(new Uri(service));
        db.ClientCertificate = CertificateUtil.GetCertificateByThumbprint(StoreName.My,
                                                                          StoreLocation.LocalMachine,
                                                                          "<a thumbprint>");

私钥存储在客户端计算机上,公钥存储在本地计算机/受信任根 CA 的服务器上

请记住在 IIS 中要求/协商此站点的客户端证书。

(在 WCF 数据服务 5.2、VS 2012 上测试)

Certificate based Authentication can be done like this:

Server side:

public class ODataService : DataService<Database>
    {
        public ODataService()
        {
            ProcessingPipeline.ProcessingRequest += ProcessingPipeline_ProcessingRequest;
        }

        void ProcessingPipeline_ProcessingRequest(object sender, DataServiceProcessingPipelineEventArgs e)
        {
            if (!HttpContext.Current.Request.ClientCertificate.IsPresent)
            {
                throw new DataServiceException(401, "401 Unauthorized");
            }

            var cert = new X509Certificate2(HttpContext.Current.Request.ClientCertificate.Certificate);
            if (!ValidateCertificate(cert))
            {
                throw new DataServiceException(401, "401 Unauthorized");
            }

            var identity = new GenericIdentity(cert.Subject, "ClientCertificate");
            var principal = new GenericPrincipal(identity, null);
            Thread.CurrentPrincipal = principal;
            HttpContext.Current.User = principal;
        }

        private bool ValidateCertificate(X509Certificate2 cert)
        {
            // do some validation
        }

Client side:

Create a partial class for your database service reference (DataServiceContext)

public partial class Database
{
    // ref: http://social.msdn.microsoft.com/Forums/en-US/0aa2a875-fd59-4f3e-a459-9f604b374749/how-do-i-use-certificate-based-authentication-with-data-services-client?forum=adodotnetdataservices
    private X509Certificate clientCertificate = null;
    public X509Certificate ClientCertificate
    {
        get
        {
            return clientCertificate;
        }
        set
        {
            if (value == null)
            {
                // if the event has been hooked up before, we should remove it
                if (clientCertificate != null)
                {
                    SendingRequest -= OnSendingRequest_AddCertificate;
                }
            }
            else
            {
                // hook up the event if its being set to something non-null
                if (clientCertificate == null)
                {
                   SendingRequest += OnSendingRequest_AddCertificate;
                }
            }

            clientCertificate = value;
        }
    }

    private void OnSendingRequest_AddCertificate(object sender, SendingRequestEventArgs args)
    {
        if (null != ClientCertificate)
        {
            (args.Request as HttpWebRequest).ClientCertificates.Add(ClientCertificate);
        }
    }

Use it like this

        Database db = new Database(new Uri(service));
        db.ClientCertificate = CertificateUtil.GetCertificateByThumbprint(StoreName.My,
                                                                          StoreLocation.LocalMachine,
                                                                          "<a thumbprint>");

Private key stored on client computer, public key stored on server in Local machine/Trusted Root CA

Remember to require/negotiate client sertificate for this Site in IIS.

(Tested on WCF Data Services 5.2, VS 2012)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文