客户端 - 服务器身份验证 - 使用SSPI?

客户端 - 服务器身份验证 - 使用SSPI?

问题描述:

我工作的一个客户端 - 服务器应用程序,我希望客户端验证自身使用用户的登录凭据的服务器上,但我不希望用户必须输入他们的用户名和密码。我当然不希望负责安全处理密码。我只需要用户向我证明他们是他们说他们是谁,然后我的服务器可以继续授予/拒绝命令,因为它为所欲为。

I'm working on a client-server application and I want the client to authenticate itself to the server using the user's logon credentials, but I don't want the user to have to type in their user name and password. I certainly don't want to be responsible for securely handling passwords. I only need the user to prove to me that they are who they say they are, and then my server can go ahead and grant/deny commands as it pleases.

我的用户是域的一部分,所以我希望能够使用,当他们登录他们创建的登录凭据。

My users are part of a domain, and so I want to be able to use the logon credentials they created when they logged in.

我不使用任何形式的网络服务,我也不想要。我同时控制客户端和服务器软件,无一不是用纯C#和用好醇'插座完成工作。

I'm not using any sort of web services, nor do I want to. I control both the client and server software, and both are written in pure C# and use good ol' sockets for getting work done.

我宁愿用纯C#/做到这一点。净,但我愿意使用不安全的C#和pinvokes到Win32 API,如果这意味着我会完成这项工作。

I'd prefer to do this with pure C#/.Net, but I'm open to using unsafe C# and pinvokes to win32 API if it means that I'll get the job done.

我读过的窗户约SSPI一点点,但我在黑暗中那种感觉,因为周围的这种应用程序的开发是新的我。

I've read a little bit about SSPI in windows, but I'm kind of feeling around in the dark since this sort of application development is new to me.

是否有人知道如何做到这一点?是SSPI的方式?一个人怎么使用SSPI从C#中? ?有没有一个.net原生方式,使我的代码可以保持便携

Does anybody know how to do this? Is SSPI the way? How does one use SSPI from within C#? Is there a .Net-native way so that my code can remain portable?

更​​新:

SSPI是这个正确的方法。 API是不是太难使用,但确实需要一个体面的项目包装成C#。

SSPI is the right approach for this. The API isn't too hard to use, but does require a decent-sized project to wrap into C#.

在研究必要的位来解决这个问题的过程中,我写了一个项目,在.net中提供SSPI。下面我介绍了Windows API SSPI接口的基础知识,使任何人都可以复制我的结果。如果你发现自己想在.net中使用SSPI,我可能会建议你使用的项目,我创建的解决这个问题:

In the process of researching the necessary bits to solve this question, I wrote a project to provide SSPI in .Net. Below I describe the basics of interfacing with the Windows SSPI API so that anybody may replicate my results. If you find yourself wanting to use SSPI in .Net, I may suggest you use the project I created to solve this:

NSspi - 一个.NET接口SSPI API

NSspi - A .Net interface to the SSPI API

SSPI为您提供原始字节数组包含身份验证令牌,你再决定如何传输 - 无论是在二进制格式的消息的插座,定制XML通道,.NET远程,某种形式的WCF的,心里很不舒服,甚至一个串口。你决定如何处理它们。随着SSPI一台服务器可以验证客户端,安全地识别客户,甚至执行基本的消息处理喜欢使用与客户建立的安全上下文加密/签名的程序。

SSPI provides you raw byte arrays containing authentication tokens that you then decide how to transmit - be it over a socket with binary-formatted messages, a custom XML channel, .Net Remoting, some form of WCF, heck, even a serial port. You get to decide how to deal with them. With SSPI a server can authenticate clients, securely identify the client, and even perform basic message handling procedures like encryption/signing using the security context established with the client.

的SSPI API是记录在这里: SSPI API概述一>

The SSPI API is documented here: SSPI API overview

具体看看以下功能:


  • AcquireCredentialsHandle


    • 获取一个句柄某种形式的凭据(例如,当前用户登录)。由服务器和客户端使用。


    • 客户端用于建立安全环境与服务器


    • 将服务器用于建立与客户端的安全上下文。

    典型的工作流程是,每一方将使用AcquireCredentialsHandle初始化其凭据。验证周期,然后开始和进展如下:

    The typical workflow is that each side will initialize their credentials using AcquireCredentialsHandle. The authentication cycle then starts and progresses as follows:


    • 客户端调用的InitializeSecurityContext,提供没有输入记号,这在的形式返回输出令牌一个字节数组。 ISC返回ContinueNeeded,以表明身份验证周期是不完整的。

    • 客户端发送的令牌通过任何手段意欲服务器。

    • 服务器喂收到的令牌作为输入AcceptSecurityContext并产生自己的输出令牌。 ASC还返回'ContinueNeeded'以指示认证
      周期是不完整的。

    • 然后,服务器将其输出发送令牌给客户端。

    • 客户端提供了服务器令牌作为输入的InitializeSecurityContext,返回新的输出令牌。

    • 客户端发送了新的输出令牌到服务器。

    • ...

    • The client invokes InitializeSecurityContext, providing no input tokens, which returns output tokens in the form of a byte array. ISC returns 'ContinueNeeded' to indicate that the authentication cycle is not complete.
    • The client sends the tokens to the server by whichever means it desires.
    • The server feeds the received tokens as input to AcceptSecurityContext and produces its own output tokens. ASC also returns 'ContinueNeeded' to indicate that the authentication cycle is not complete.
    • The server then sends its output tokens to the client.
    • The client provides the servers tokens as input to InitializeSecurityContext, which returns new output tokens.
    • The client sends his new output tokens to the server.
    • ...

    这循环下去,直到客户端看到的InitializeSecurityContext返回'OK'和服务器看到AcceptSecurityContext返回'OK'。每个功能可以返回OK,并仍然提供输出标记(由非空返回所指示的),以表明它仍具有将数据发送到另一侧。这是客户如何知道它的一半完成,但服务器的仍然是不完整的;反之,如果在服务器客户端之前完成。哪一方完成第一(返回'OK')依赖于特定的安全包被SSPI引擎盖下使用,任何SSPI消费者应该意识到这一点。

    This cycle continues until the client sees InitializeSecurityContext return 'OK' and the server sees AcceptSecurityContext return 'OK'. Each function may return 'OK' and still provide an output token (as indicated by a non-null return), to indicate that it still has to send data to the other side. This is how the client knows that its half is done but the server's is still incomplete; and vice versa if the server completes before the client. Which side completes first (returns 'OK') depends on the specific security package being used under the hood by SSPI, and any SSPI consumer should be aware of this.

    以上信息应该对任何人足以成为要想在他们的应用程序提供了Windows集成身份验证并复制我的结果与SSPI系统连接。

    The information above should be enough for anybody to being interfacing with the SSPI system in order to provide 'Windows Integrated Authentication' in their application and replicate my results.

    下面是我早先回答,因为我学会了如何调用SSPI API。

    Below is my earlier answer as I learned how to invoke the SSPI API.

    我已经忘记了这个问题,并不约而同地回到了这个问题前几天一时兴起。我确实需要解决,虽然在一两年内这个问题:)

    I had forgotten about this question, and coincidentally returned to this problem a few days ago on a whim. I do need to solve this problem in a year or two though :)

    这是.NET中可能的,我目前正在开发一个.net SSPI包装,我打算发布。

    It is possible in .Net, and I am currently developing a .Net SSPI wrapper that I intend to publish.

    我立足我的工作了一些的SSPI样本微软中我发现了。

    I'm basing my work off of some SSPI samples from Microsoft I found.

    该示例包含一个C ++ / CLI管理组件实现SSPI API的必要组成部分(文件夹 Microsoft\Samples\Security\SSPI\SSPI 从REMSSPI.exe文件中提取)。然后,他们有两个用户界面,客户端应用程序和服务器应用程序,无论是用C#编写的利用这个API来执行SSPI认证。

    The sample contains a C++/CLI managed assembly that implements the necessary parts of the SSPI API (in the folder Microsoft\Samples\Security\SSPI\SSPI extracted from the REMSSPI.exe file). They then have two UIs, a client application and a server application, both written in C# that make use of this API to perform SSPI authentication.

    的用户界面使用的.NET远程处理设施,以配合到一起,但如果我理解正确的SSPI API,唯一的信息在客户端和服务器需要交换包含的byte [] S含有安全上下文令牌数据,这些数据可以很容易地集成到任何通信基础设施你想; 。在我的情况,我自己设计的二进制协议

    The UIs make use of the .Net remoting facility to tie it all together, but if I understand the SSPI API correctly, the only information that the client and server need to exchange consists of byte[]s containing security context token data, which can easily be integrated into whatever communications infrastructure you want; in my case, a binary protocol of my own design.

    在获取样本的一些注意事项的工作 - 他们有'SSPI'库源,VS下最好的编译2005年,虽然我已经得到了它在2008年的工作;因为它们使用了不提倡使用的语言结构2010或以上需要一些返工。您可能还需要修改是你的平台SDK的一部分的头文件,因为它们使用const的指针赋值给unconst变量,我不知道一个更好的方法,使编译器高兴(我从来没有使用C ++ / CLI之前)。

    Some notes on getting the sample to work - they have the 'SSPI' library source, which best compiles under VS 2005, though I've gotten it to work under 2008; 2010 or above would require some rework since they use language constructs that were deprecated. You may also need to modify header files that are part of your platform SDK, because they make use of const pointer assignments to unconst variables, and I don't know a better way to make the compiler happy (I've never used C++/CLI before).

    他们确实包括在Microsoft\Samples\Security\SSPI\bin文件夹编译SSPI DLL。为了获取客户端/服务器二进制工作,你必须在该DLL复制到自己的bin目录下,否则失败大会决议

    They do include a compiled SSPI dll in the Microsoft\Samples\Security\SSPI\bin folder. To get the client/server binaries to work, you have to copy that dll to their bin directory, else the fail assembly resolution.

    总结一下:


    • 下载REMSSPI.exe样品自行解压。

    • 提取REMSSPI.exe文件(两次..)

    • Microsoft\Samples\Security\SSPI\


      • bin\ - 包含编译的dll Microsoft.Samples.Security.SSPI.dll

      • SSPI\ - 包含源对DLL

      • Sample\ - 包含UI代码


        • bin\ - 包含构建UI样品。复制文件SSPI.dll这里并运行 ControlPanel.Client.exe ControlPanel.Server.exe

        • Go here to download the REMSSPI.exe sample self-extracting zip.
        • Extract the REMSSPI.exe file (twice..)
        • Microsoft\Samples\Security\SSPI\
          • bin\ - contains compiled dll Microsoft.Samples.Security.SSPI.dll
          • SSPI\ - contains source to dll
          • Sample\ - contains UI source code
            • bin\ - Contains build UI samples. Copy the SSPI.dll file here and run ControlPanel.Client.exe and ControlPanel.Server.exe