在.net 2.0中,在使用 remoting 的 TCP Channel, 用户认证是安全性问题探讨主题之一.本文将从两个角度来探讨用户认证问题, 并提出一个问题来寻求大家的解决方法!
一、两个通道类的区别
Tcp Channel :
服务器端注册通道
方式一:
(1)注册一个通道
TcpChannel channel = new TcpChannel(8086);
ChannelServices.RegisterChannel(channel, true);
(2)注册多个通道
由于IChannel的ChannelName属性和ChannelPriority属性都是只读的,所以通过下面的方式。
IDictionary props = new Hashtable();
props["name"] = "channelName";
props["port"] = 8086;
IChannel channel = new TcpChannel(props, new BinaryClientFormatterSin
ChannelServices.RegisterChannel(channel, true);
方式二:
(1)注册一个通道
TcpServerChannel channel=new TcpServerChannel(8086);
ChannelServices.RegisterChannel(channel, true);
(2)注册多个通道
IDictionary props = new Hashtable();
props["name"] = "channelName";
props["port"] = 8086;
IChannel channel = new TcpChannel(props, new BinaryServerFormatterSin
ChannelServices.RegisterChannel(channel, true);
(3)注册带客户端验证的通道
IAuthorizeRemotingConnec
channel =
ChannelServices.RegisterChannel(channel, true);
客户端注册通道
针对服务器端注册通道方式一的两类情况均采用下面的方式注册即可:
TcpChannel channel = new TcpChannel();
ChannelServices.RegisterChannel(channel, true);
针对服务器端注册通道方式二的采用下面的方式注册即可:
(1)和(3)的对应
TcpClientChannel tcpClientChannel = new TcpClientChannel();
ChannelServices.RegisterChannel(tcpChannel, true);
(2)的对应
TcpClientChannel tcpClientChannel = new TcpClientChannel("channelName", new BinaryClientFormatterSin
ChannelServices.RegisterChannel(tcpChannel, true);
从上面的演示可以看出:
(1) TcpChannel类都可以用在客户端和服务器端,它们都实现了IChannelReceiver, IChannelSender。
在客户端使用时,一般采用
TcpChannel channel = new TcpChannel();
TcpChannel () 初始化 TcpChannel 类的新实例,仅激活客户端信道,不激活服务器信道。
在服务器端使用时,一般采用
IChannel channel = new TcpChannel(props, new BinaryClientFormatterSin
可以指定的配置属性和接收器初始化 TcpChannel 类的新实例。IClientChannelSinkProvid
(2)
TcpServerChannel 类用在客户端, TcpClientChannel 类用在服务器端。(这句好象是废话:) )
区别:TcpChannel类是一个通用的信道类,在客户端和服务器端都可以使用,使用起来非常方便。TcpServerChannel 类和TcpClientChannel 类需要分别使用,但是如果你要通过编程的方式使用.Net 2.0 中的客户端验证,那就要使用TcpServerChannel 来完成了。当然,也可以通过配置文件的方式来完成对客户端验证。还有一点,使用TcpChannel类可以在服务器指定客户端信道接收器和服务器信道接收 器,客户端不用管,而TcpServerChannel 类和TcpClientChannel 类则分别指定自己的信道接收器。(不知道这句话是否正确?:))
二、下面就来从两个角度来探讨一下TCP Channel 用户认证.
方式一:采用编程的方式和配置文件的方式来完成对客户端验证。
先给出授权的类文件代码:
程序集名称为AuthorizationAssemblyNam
class AuthorizationModule : IAuthorizeRemotingConnection
{
}
IAuthorizeRemotingConnec
(1) 配置文件的方式:
服务器端的配置文件:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
</configuration>
(2) 编程的方式:
IAuthorizeRemotingConnec
IChannel channel =
ChannelServices.RegisterChannel(channel, true);
以上两种验证方式是针对IP地址和Windows用户。只要客户端调用远程服务,就是会自动执行上面接口中两个函数。虽然在一定程度上实现了安全性 验证,但是仍然不是我们想要的结果。我们希望的方式是:对于给定的服务(也就是远程对象提供的方法),一小部分不需要授权,比如登录验证服务,大部分服务 需要授权验证,比如管理员删除用户;在要授权验证时,采用的自动提交验证信息的方式,比如删除用户,我们希望是只传删除用户的ID,
即 DeleteUserById(string userId), 而不是连管理员的用户密码也一起作为参数传过去,即DeleteUserById(string adminId,adminpwd,string userId)。那么,下面就来探讨一下解决这个问题的答案:在远程处理中,可以通过CallContext类获得。
方式二:在远程处理中,可以通过CallContext类获得方式来完成对客户端验证。
第一步,创建自定义的类 PrincipalStorage,封装需要自动传递的消息。该对象需要序列化,且需要实现ILogicalThreadAffinative
using System;
using System.Runtime.Remoting.Messaging;
using System.Security.Principal;
namespace Novelty.WinServices
{
}
(2)客户端创建该对象并使用CallContext.SetData方法附加到上下文中,它能通过每个请求自动的传输到远程组件中。
using System;
using System.Threading;
using System.Runtime.Remoting.Messaging;
namespace Novelty.WinServices
{
}
(3)在远程组件中获取信息并验证它
using System;
using System.Threading;
using System.Runtime.Remoting.Messaging;
namespace Novelty.WinServices
{
}