【问题标题】:How to use System.IdentityModel in own client-server application如何在自己的客户端-服务器应用程序中使用 System.IdentityModel
【发布时间】:2010-10-13 09:10:22
【问题描述】:

我有一个基于 TcpClient/TcpListener 和 SslStream 的简单客户端-服务器应用程序。客户端可以使用 X509Certificate 或在 SslStream 建立后发送用户名和密码向服务器验证自己的身份。

WCF 使用 System.IdentityModel 命名空间来进行身份验证,但 apparently 可以在任意应用程序中使用——这听起来很有趣。但是关于如何做到这一点的信息很少(或者我的 Google foo 今天很弱)。

所以,我的问题是:我需要做什么才能将 System.IdentityModel 与我的应用程序集成?我不确定我是否需要所有 ClaimSet 的东西,但如果用户可以仅使用他们的 Windows 帐户或任何其他提供的身份验证机制登录。 (不幸的是,我不能只切换到 WCF,而是必须使用自定义协议,但如果需要,我可以对其进行一些更改。)

【问题讨论】:

    标签: c# wcf-security .net-3.0


    【解决方案1】:

    我的 Google foo 确实很弱。答案就在我问题的链接后面。所以这里有几个this blog的链接,以防有人最终有同样的问题。

    首先,您应该尝试理解“声明集的东西”:

    然后,您需要知道声明集的来源:

    有了这些知识,它实际上变得非常简单。

    如果我理解正确的话,基本的工作流程应该是这样的:

    1. 客户端使用SecurityTokenProvider 创建一个SecurityToken
    2. 客户端使用SecurityTokenSerializer 序列化SecurityToken
    3. 服务器使用SecurityTokenSerializer 反序列化SecurityToken
    4. 服务器使用SecurityTokenAuthenticator 创建IAuthorizationPolicys
    5. 服务器从IAuthorizationPolicys 创建AuthorizationContext
    6. 完成

    例子:

    // Create the SecurityTokenProvider
    var p = new UserNameSecurityTokenProvider("username", "password");
    
    // Get the SecurityToken from the SecurityTokenProvider
    var t = p.GetToken(TimeSpan.FromSeconds(1.0)) as UserNameSecurityToken;
    
    // ... transmit SecurityToken to server ...
    
    // Create the SecurityTokenAuthenticator
    var a = new CustomUserNameSecurityTokenAuthenticator(
        UserNamePasswordValidator.None);
    
    // Create IAuthorizationPolicies from SecurityToken
    var i = a.ValidateToken(t);
    
    // Create AuthorizationContext from IAuthorizationPolicies
    var c = AuthorizationContext.CreateDefaultAuthorizationContext(i);
    ShowClaims(c.ClaimSets);
    

    对于X509SecurityTokens,使用X509SecurityTokenProvider/Authenticator。对于WindowsSecurityTokens,有一个WindowsSecurityTokenAuthenticator,但没有提供者;相反,使用WindowsSecurityToken 构造函数:

    var t = new WindowsSecurityToken(WindowsIdentity.GetCurrent());
    

    这很好用。到目前为止,我唯一省略的是令牌序列化。有一个SecurityTokenSerializer 类在.NET 框架中有一个实现:WCF 附带的WSSecurityTokenSerializer 类。

    序列化UserNameSecurityTokens 和X509SecurityTokens 就像一个魅力(没有尝试过反序列化),但序列化程序显然不支持WindowsSecurityTokens。这给我留下了我已经拥有的两种身份验证方法(证书和用户名/密码),因为我不想要AuthorizationContext,所以我会坚持我所拥有的:)

    【讨论】:

    • 如果有人感兴趣,我不确定是否应该在客户端创建 SecurityToken 并将其传输到服务器。对于 X.509 安全性,使用服务器启动 SslStream 并从服务器证书创建 X509SecurityToken 更有意义,对于 Windows 安全性,如果使用 NegotiateStream,则可以从协商流.RemoteIdentity 创建 WindowsSecurityToken。为了用户名/密码的安全,当然需要传输用户名和密码。
    【解决方案2】:

    我没有对现有解决方案发表评论的声誉,但我想将新 URL 发布到解决方案中列出的博客,因为这些不再有效。如果有人可以将其更改为评论,我将不胜感激。

    【讨论】:

    • 我在上面编辑了@dtb 的答案以反映固定链接。它应该在经过同行评审后立即出现。谢谢!
    • 截至 2016 年 9 月,部分链接已损坏
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多