开发者

WCF Security: what is the way to go with many servers and server identity being unimportant?

开发者 https://www.devze.com 2023-02-16 08:03 出处:网络
So I\'ve done some research and found out that, indeed, WCF prevents us from sending username/password in clear text. The basic argument is that \"it is not secure, because it allows a hacker to inter

So I've done some research and found out that, indeed, WCF prevents us from sending username/password in clear text. The basic argument is that "it is not secure, because it allows a hacker to intercept credentials". Hence, a secure channel is required, and for that, the server needs an X.509 certificate.

Ok, point taken. But here's a problem: said certificate needs to be truste开发者_JAVA百科d on the client. But why?

A trusted certificate is commonly used on Internet-open servers to enable clients to verify the server's identity (i.e. make sure they're not connecting to a bogus server). But what if server's identity is not important in a given context?

My product consists of two applications. Let's call them client and server1.

The basic scenario is this:

  1. The user connects to a network that has one or more of those servers installed and opens the client application
  2. The client uses WCF discovery to find any servers on the network

    (or, optionally, the user can specify server's address manually)

  3. The user chooses which server he wants to connect to, and then enters username/password for that server
  4. The connection is established, the client does some calls to the server on behalf of the user

One can see how in this scenario, the user doesn't need to verify that the server is not bogus. Even if he wanted to, there is nothing to verify against. After all, the only thing we know about the server is that it supports our protocol, and that fact doesn't need verification.

In other words, I need communication confidentiality and client authentication, but not server authentication.

It would be bad enough to ask my customers to purchase a certificate from a trusted authority for every server, but it would be even worse not being able to explain why exactly they need it.

Given all the above mentioned points, I see three possibilities:

  1. The WCF designers simply didn't think about this scenario. That is, WCF doesn't support it.

    (at least natively; yes, I am aware of Yaron Naveh's creation).

  2. I am missing some detail that implies that the certificate does have to be trusted after all.

  3. There is a way (unknown to me) to use certificate just for encryption and not for server's authentication, and thus avoid making it a trusted one.

So the question is:

Which of these three options is the case? And if it's the third one, what is that way? (My fingers are crossed for number 3 :-)

.

.


1 It is important to note that the term "server" is not used in the "Internet" sense here. That is, the server is not a computer on the web, but rather a program that gets installed on some computer, not necessarily even connected to the Internet. And there going to be many of these, installed by different customers on their sites, most times without my direct knowledge.


To avoid certificate validation, add following in system.serviceModel/behaviors/endpointBehaviors/behavior/clientCredentials/serviceCertificate element:

<authentication certificateValidationMode="None" />


Each "server" doesn't have to have it's own unique identity. All "server" instances could use the same identity and you just configure the client to expect that identity no matter which "server" it's talking to. That way the client doesn't care as long as all "servers" use the same identity. Essentially this boils down to buying/generating a single certificate for the "server" identity and just making sure that all your "server" instances use this identity in their communication.

From a "server" configuration perspective you just make sure that keypair is installed and use the <serviceCertificate> configuration element to use it:

<behavior name="MyServiceBehavior">
    <!-- ... -->
    <serviceCertificate findValue="AcmeCorpServer" storeLocation="LocalMachine" storeName="My" X509FindType="FindBySubjectName" />
    <!-- ... -->
</behavior>

And then on clients you just make sure you have the public key installed and configure the endpoint behavior:

<behavior name="MyEndpointBehavior">
    <!-- ... -->
    <clientCredentials>
        <clientCertificate findValue="MyClient" storeLocation="CurrentUser" storeName="My" X509FindType="FindBySubjectName" />
        <serviceCertificate>
            <defaultCertificate findValue="AcmeCorpServer" storeLocation="CurrentUser" storeName="TrustedPeople" X509FindType="FindBySubjectName" />
        </serviceCertificate>
    </clientCredentials>
    <!-- ... -->
</behavior>

This is more of a coarse grained approach to security, but it seems like it would fit your particular needs. It's basically like saying "allow my client to talk to any service that might ever exist as long as we can validate the identity to be our identity".

Finally, if you can't/don't want to do this with configuration for some reason (i.e. you can't/don't want to put things into certificate stores) there's ways to do it programatically as well by loading the X.509 certificate manually and then assigning it to the client/server behavior at runtime.

0

精彩评论

暂无评论...
验证码 换一张
取 消