C# 客户端服务器身份验证-使用SSPI?
我正在处理客户机-服务器应用程序,我希望客户机使用用户的登录凭据向服务器进行身份验证,但我不希望用户必须键入用户名和密码。我当然不想对安全处理密码负责。我只需要用户向我证明他们是他们所说的人,然后我的服务器就可以随心所欲地授予/拒绝命令 我的用户是域的一部分,因此我希望能够使用他们登录时创建的登录凭据 我没有使用任何类型的web服务,也不想使用。我控制客户机和服务器软件,它们都是用纯C语言编写的,并且使用良好的ol'套接字来完成工作 我更愿意使用纯C#/.Net来实现这一点,但如果这意味着我可以完成任务,我愿意在win32 API中使用不安全的C#和pinvokes 我读过一些关于windows中SSPI的书,但我有点摸不着头脑,因为这种应用程序开发对我来说是新的C# 客户端服务器身份验证-使用SSPI?,c#,.net,windows-authentication,sspi,C#,.net,Windows Authentication,Sspi,我正在处理客户机-服务器应用程序,我希望客户机使用用户的登录凭据向服务器进行身份验证,但我不希望用户必须键入用户名和密码。我当然不想对安全处理密码负责。我只需要用户向我证明他们是他们所说的人,然后我的服务器就可以随心所欲地授予/拒绝命令 我的用户是域的一部分,因此我希望能够使用他们登录时创建的登录凭据 我没有使用任何类型的web服务,也不想使用。我控制客户机和服务器软件,它们都是用纯C语言编写的,并且使用良好的ol'套接字来完成工作 我更愿意使用纯C#/.Net来实现这一点,但如果这意味着我可以
有人知道怎么做吗?SSPI就是这样吗?如何从C#内部使用SSPI?有没有一种.Net原生方式可以让我的代码保持可移植性?尼古拉是正确的;没有一种.NET本机方式来完成您正在做的事情(至少不使用低级.NET套接字支持)。当然,您可以在掩体下进行一些互操作的黑魔术,但是如果客户端和服务器都在您的控制之下,您可能需要考虑稍微向上移动堆栈,并使用更高级的API,例如WCF,它具有.NET原生支持Windows集成身份验证。 根据您的问题和所描述的环境,您将能够使用NetTcpBinding,它提供了高性能,并为您正在寻找的身份验证/标识流提供了管道(它还提供了一种使用ServiceAuthorizationManager类处理授权的相当干净的方法)。如果不知道你的应用程序/服务的细节,我不可能提供一个“如何”来实现你想要做的事情,但我可以提供一个相当简单的例子。更新: SSPI是实现这一点的正确方法。该API不太难使用,但确实需要一个相当大的项目才能包装成C 在研究解决这个问题所需的位的过程中,我编写了一个在.Net中提供SSPI的项目。下面我将介绍与Windows SSPI API接口的基础知识,以便任何人都可以复制我的结果。如果您发现自己想要在.Net中使用SSPI,我建议您使用我创建的项目来解决此问题: SSPI为您提供原始字节数组,其中包含身份验证令牌,然后您可以决定如何传输这些令牌—可以是通过带有二进制格式消息的套接字、自定义XML通道、.Net远程处理、某种形式的WCF、heck,甚至是串行端口。你得决定如何对付他们。使用SSPI,服务器可以对客户端进行身份验证,安全地识别客户端,甚至使用与客户端建立的安全上下文执行基本的消息处理过程,如加密/签名 SSPI API记录在此处: 具体看一下以下功能:
-
- 获取某种形式的凭据(例如,当前用户的登录)的句柄。由服务器和客户端使用
-
- 客户端用于与服务器建立安全上下文
-
- 服务器用于与客户端建立安全上下文
- 客户端调用InitializeSecurityContext,不提供输入令牌,它以字节数组的形式返回输出令牌。ISC返回“ContinueNeeded”以指示身份验证周期未完成
- 客户机通过其希望的任何方式将令牌发送到服务器
- 服务器将收到的令牌作为输入提供给AcceptSecurityContext,并生成自己的输出令牌。ASC还返回“ContinueNeeded”以指示身份验证 循环未完成
- 然后,服务器将其输出令牌发送到客户端
- 客户端提供服务器令牌作为InitializeSecurityContext的输入,InitializeSecurityContext返回新的输出令牌李>
- 客户机将其新的输出令牌发送到服务器
我已经忘记了这个问题,几天前偶然又回到这个问题上来。不过,我确实需要在一两年内解决这个问题:) 这在.Net中是可能的,我目前正在开发一个.Net SSPI包装器,我打算发布它 我的工作基于我从微软找到的一些 此示例包含一个C++/CLI托管程序集,该程序集实现SSPI API的必要部分(位于文件夹
Microsoft\Samples\S中)
using System;
using System.Security;
using System.Security.Permissions;
using System.Security.Principal;
namespace WindowsIdentityTest
{
class Program
{
[PrincipalPermission(SecurityAction.Demand, Authenticated = true)]
static string SomeServerAction()
{ return "Authenticated users can access"; }
[PrincipalPermission(SecurityAction.Demand, Role = "BUILTIN\\Administrateurs")]
static string SomeCriticalServerAction()
{ return "Only Admins can access"; }
static void Main(string[] args)
{
//This allows to perform security checks against the current Identity.
AppDomain.CurrentDomain.SetPrincipalPolicy(PrincipalPolicy.WindowsPrincipal);
try
{
Console.WriteLine(SomeServerAction());
Console.WriteLine(SomeCriticalServerAction());
}
catch (SecurityException sec)
{
Console.WriteLine(string.Format("{0} : {1}\n------------\n{2}"
, sec.GetType()
, sec.Message
, sec.StackTrace));
}
catch (Exception ex)
{
Console.WriteLine("This shall not appen.");
}
Console.WriteLine("Press enter to quit.");
Console.ReadLine();
}
}
}
SecPkgContext_NativeNames pinfo;
QueryContextAttributesEx(&m_securitycontext, SECPKG_ATTR_NATIVE_NAMES, &pinfo);
SecPkgContext_NativeNames
{
SEC_CHAR *sClientName;
SEC_CHAR *sServerName;
}