如何在自己的客户端 - 服务器应用程序中使用 System.IdentityModel [英] How to use System.IdentityModel in own client-server application

查看:10
本文介绍了如何在自己的客户端 - 服务器应用程序中使用 System.IdentityModel的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

WCF 使用 System.IdentityModel 命名空间进行身份验证,但 显然 可以在任意应用程序中使用——这听起来很有趣.不过,关于如何执行此操作的信息很少(或者我的 Google foo 今天很弱).

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

解决方案

我的 Google foo 确实很弱.答案就在我问题中的链接后面.所以这里有几个指向这个博客的链接,以防有人最终遇到同样的问题.

首先,你应该试着理解那个声明集的东西":

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

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

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

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

示例:

//创建 SecurityTokenProvidervar p = new UserNameSecurityTokenProvider("用户名", "密码");//从 SecurityTokenProvider 获取 SecurityTokenvar t = p.GetToken(TimeSpan.FromSeconds(1.0)) 作为 UserNameSecurityToken;//... 将 SecurityToken 传输到服务器 ...//创建 SecurityTokenAuthenticatorvar a = new CustomUserNameSecurityTokenAuthenticator(UserNamePasswordValidator.None);//从 SecurityToken 创建 IAuthorizationPoliciesvar i = a.ValidateToken(t);//从 IAuthorizationPolicies 创建 AuthorizationContextvar c = AuthorizationContext.CreateDefaultAuthorizationContext(i);ShowClaims(c.ClaimSets);

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

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

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

序列化 UserNameSecurityTokens 和 X509SecurityTokens 就像一个魅力(没有尝试反序列化),但 WindowsSecurityTokens 显然不受支持序列化器.这给我留下了我已经拥有的两种身份验证方法(证书和用户名/密码),而且由于我不想要 AuthorizationContext 无论如何,我会坚持我拥有的 :)

I've got a simple client-server application based on TcpClient/TcpListener and SslStream. Clients can authenticate themselves to the server using a X509Certificate or by sending a user name and password after the SslStream has been established.

WCF makes use of the System.IdentityModel namespace for authentication purposes, but apparently that can be used in arbitrary applications--which sounds interesting. Information on how to do this is sparse though (or my Google foo is weak today).

So, my question is: What do I need to do to integrate System.IdentityModel with my application? I'm not sure if I need all that ClaimSet stuff, but it would be nice if users could log in just using their Windows account or any other provided authentication mechanism. (Unfortunately I can't just switch to WCF but have to use the custom protocol, although I can make some changes to it if necessary.)

解决方案

My Google foo was indeed weak. The answer is right behind the link in my question. So here are a couple of links to this blog in case somebody has the same question eventually.

First, you should try to understand "that claim set stuff":

Then, you need to know where claim sets come from:

Armed with this knowledge, it actually becomes quite simple.

If I understand it correctly, the basic workflow would be something like this:

  1. Client creates a SecurityToken using a SecurityTokenProvider
  2. Client serializes the SecurityToken using a SecurityTokenSerializer
  3. Server deserializes the SecurityToken using a SecurityTokenSerializer
  4. Server creates IAuthorizationPolicys using a SecurityTokenAuthenticator
  5. Server creates AuthorizationContext from IAuthorizationPolicys
  6. Done

Example:

// 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);

For X509SecurityTokens use a X509SecurityTokenProvider/Authenticator. For WindowsSecurityTokens there's a WindowsSecurityTokenAuthenticator but not a provider; instead, use the WindowsSecurityToken constructor:

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

This works quite well. The only thing I omitted so far above is the token serialization. There is a SecurityTokenSerializer class which has one implementation in the .NET framework: the WSSecurityTokenSerializer class which comes with WCF.

Serializing UserNameSecurityTokens and X509SecurityTokens works like a charm (haven't tried deserialization), but WindowsSecurityTokens are apparently not supported by the serializer. This leaves me with the two authentication methods that I already have (certificates and username/password) and, as I didn't want that AuthorizationContext anyway, I'll stick with what I have :)

这篇关于如何在自己的客户端 - 服务器应用程序中使用 System.IdentityModel的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆