QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 2136|回复: 0
打印 上一主题 下一主题

socket连接多层程序安全性简述 - 连接

[复制链接]
字体大小: 正常 放大
韩冰        

823

主题

3

听众

4048

积分

我的地盘我做主

该用户从未签到

发帖功臣 元老勋章

跳转到指定楼层
1#
发表于 2005-1-26 01:08 |只看该作者 |倒序浏览
|招呼Ta 关注Ta

- ?1 q4 h$ u+ a" ?

前面hawkfly提到的在多层编程中,服务器端安全性验证的问题

; ]3 M# ~& s1 F6 _7 |1 Y/ T

在以socket方式实现MIDAS时尤为明显,DCOM/CORBA都有现成的

* e: }, a& J$ \8 H9 }

安全管理功能,而socket方式在这方面比较薄弱,没有现成的解决方案

9 z' Z; J, G2 ~7 y

现就我以前对MIDAS编程的理解,做一个简要的介绍,

7 ?0 S3 A p n8 W3 Y

以后有时间精力再详细举例说明

9 X! c$ t- h0 V& w' y6 j: c

* `+ F7 S! A# m) s4 J% ]

win2k中dcom的安全级别有7种,其中

1 s' A; g* z( g7 n

最低的“无”安全检查暂且不论

+ Y: F* G% S: S4 N1 f

默认的“身份验证”服务方式几句话也说不清,

& }& U( `( \2 c1 g: ?5 f" E

先放到一边,看看剩下的5种

6 F" E y; b8 `) Z- l F

6 P) G& s4 r: q# T: l' }, v; @9 n

1.连接,仅对初始连接进行安全检查

# [& [7 n. R# w+ ?& H2 |

6 W# S D% w) a L* [/ P8 I$ `

因为tcp/ip是稳固的连接,因此每个连接,也就是每个RemoteDataModule

- z' y+ T. x4 W/ n& [9 L* W6 ~

实例检测一次即可,实现方法很多,这里简要介绍一种最简单的

! @5 g, R$ j) c) `, }) D/ q$ H* l

可以在服务器端的TypeLibrary里面为你的服务器接口增加若干个方法,如

+ ]0 R& \2 L; u5 T6 O* Y5 [1 `

interface ILoginServer: IAppServer

+ M# m* e1 A2 a. O, A

{

5 J# n, F& T, M, p

[

/ n, e/ B1 z. w {& D

id(0x00000001)

5 `5 N/ C2 a$ h; Z7 x+ I2 ]

]

; ?7 a' j- a6 E

HRESULT _stdcall Login( void );

. {1 Y7 p2 S: T

[

+ E2 x" o8 z1 ]" H {5 C4 ?

id(0x00000002)

2 Q Q8 D( [5 j4 J+ g- e. c

]

* ~3 N5 X+ u* }* O: [

HRESULT _stdcall Logout( void );

, Z" {% q$ {0 K8 J8 ]1 H- s; ~

};

# h; y& y( H* w7 P

在方法中实现你的客户身份校验,而在校验之前,通过把RDM上所有的TDataSetProvider

; F4 x. _( J2 M7 z) B5 c& c

的Exported属性关掉即可让客户端无法看到服务器端的provider

' k w3 J% h. F: I" l1 T1 r

因为客户端实际上是在连接服务器成功后通过服务器之IAppServer接口访问

2 t5 D1 v2 B+ n

所有的Provider,如IAppServer::AS_GetProviderNames可以取得

0 m+ c+ D \: w, i/ ^9 }

服务器端所有exported的IProvider接口名称,而所有数据的取得、修改

8 c6 i. l( I9 c k" m( V

都是通过相应的ProviderName来指定的,如

# a0 R7 Z0 K1 g L; I

virtual HRESULT __safecall AS_GetRecords(const WideString: ProviderName, in

5 {9 ?9 Z5 k/ M

t Count, int &RecsOut, int Options, const WideString: CommandText, OleVarian

6 z% w9 ?# P% l& i5 m

t &arams, OleVariant: &OwnerData, OleVariant &GetRecords_result) = 0 ;

# j5 a* i& E% e( B0 A5 j

取得数据方法的第一个参数就是你需要操作的数据集名称……

/ w% J# q; t/ g8 ^

如果你把服务器RDM上所有的TDataSetProvider::Exported关掉,

]" r, n( E5 ~: W9 W

则客户端看不到任何Provider,也无法通过其ProviderName取得数据

' T( t* q# ^: \0 u( E; y, u

例如我在服务器端的RDM类中加入

- X6 h* M5 M4 y( ^) w3 U

class TLoginServer : public TCRemoteDataModule

- w9 l9 n: d1 J, i& f, _

{

+ Q: B+ w ^1 `, I) K# ^

...

* F% {, i4 D) M' y7 M

private: // User declarations

& _5 f6 ] l2 v

bool FLogin;

& [1 Y0 P' [1 t, o4 w1 r- O

void __fastcall SetLogin(bool value);

5 a7 P, l% s( ]3 ], U; B; n4 f

bool __fastcall IsLogin(OleVariant &OwnerData);

' v2 V d- j$ t+ `& h) f6 O8 W- t

...

2 r/ D% w, b' r; S

__published:

$ U! R# V r& _

__property bool Login = { read = FLogin, write = SetLogin };

, }1 L- @! d% x9 z' \

};

, G! a7 o$ }" |, A8 k( S/ v

在RDM实现类中

3 I( f0 A1 n$ M5 D `

class ATL_NO_VTABLE TLoginServerImpl: 。。。

8 [- i+ X: F' W% n8 D* g

{

8 }* a( v9 g7 F5 K: [

// ILoginServer

- o ], R' u! B& X

protected:

1 U- P( b8 p( t/ V

STDMETHOD(Login());

5 g$ Z; C+ j+ X( D9 u

STDMETHOD(Logout());

! p# h& {; q* i( Z+ J5 e0 Q

};

! e. }# M3 P, {' F( |

然后简单实现之

# x i- q) Q' M$ h: O# @! h

__fastcall TLoginServer::TLoginServer(TComponent* Owner)

3 z# B- d, `5 ~1 f& _+ }

: TCRemoteDataModule(Owner), FLogin(false)

4 i o! \# U- Q+ N$ v

{

# n4 @9 q9 K0 |2 h; L

}

4 {- |1 \" v3 t( ~$ v

//---------------------------------------------------------------------------

2 U8 {% A# ?( D5 s$ s, I

void __fastcall TLoginServer::SetLogin(bool value)

# A7 H3 }6 Z7 o, A

{

R1 e3 J$ G+ `

if(FLogin != value)

" L g$ {8 Q0 W& r& N+ h% y

{

5 @6 M% K- c! m9 W. p9 H' b$ P

FLogin = value;

5 V/ i. p6 ^$ o `

dspAnimals->Exported = FLogin;

/ m6 P8 o# Q; {6 d/ q& K1 ?

}

3 k6 F' A0 F4 d

}

/ A! f% Z4 S E7 `

//---------------------------------------------------------------------------

5 m& v+ H9 d' j* ]! ^0 _& W

STDMETHODIMP TLoginServerImpl:ogin()

) {2 [, H0 l. W1 P6 \: S

{

$ R/ {+ a! o) f" n7 e7 @

m_DataModule->Login = true;

* ^( B( w+ ? u

return S_OK;

! h- ~. w8 t2 N$ [+ T# R; P

}

% b: a# i& H* T( U3 @0 O( v

//---------------------------------------------------------------------------

$ \# [, D( ^' ^

STDMETHODIMP TLoginServerImpl:ogout()

; X* q* `5 H" s4 X

{

* w' \! U3 Y5 {9 ?) I# [% y

m_DataModule->Login = false;

! }9 Y3 `) H d# U$ f) x7 ]

return S_FALSE;

: T$ H; g* o0 I, y5 t

}

( {6 n! n# }% _6 N2 A

//---------------------------------------------------------------------------

9 P7 |3 P8 e8 ?* n+ q0 X

bool __fastcall TLoginServer::IsLogin(OleVariant &OwnerData)

9 P, \2 J* F8 L& d, x

{

1 a" J" e! K+ m2 k

return FLogin;

6 S4 ~3 m) h; F4 P

}

" ]) D; h) `- Q; r6 }: s6 q' ]

easy 这样除非你的客户端成功调用Login方法,否则他是无法使用

, P* Y3 {1 ^# D# w1 g) L

dspAnimals这个数据集Provider的,成功调用后手工打开的数据集使用完全相同

; @: u& L! Z) M0 x

+ [# U$ X0 x6 u' C% A# W+ |+ s

比如客户端可以用如下代码

* {) U) N; A1 F6 D+ o2 z$ L; d

IDispatch *dispAppServer = (IDispatch*)(DM->Connection->AppServer);

1 b; D3 t" A- `) b$ y

ILoginServerDisp dispLoginServer = (ILoginServer *)dispAppServer;

* ^6 \" |( @2 h( y' ^ ]3 z N

dispLoginServer.Login();

+ f7 c6 {# n+ K h! V

DM->cdsAnimals->Open();

, {; |! o* s! _

实现注册,并且打开相应数据集……

2 W( s5 {- t1 ?: P

7 j0 O6 p7 x, F6 Y3 V# [

因为大多数的三层程序对安全性要求并不高,因此这样的安全检测对

( O% S( {/ s( K4 @+ C) ^3 q

绝大多数程序应该足以……

zan
转播转播0 分享淘帖0 分享分享0 收藏收藏0 支持支持0 反对反对0 微信微信
您需要登录后才可以回帖 登录 | 注册地址

qq
收缩
  • 电话咨询

  • 04714969085
fastpost

关于我们| 联系我们| 诚征英才| 对外合作| 产品服务| QQ

手机版|Archiver| |繁體中文 手机客户端  

蒙公网安备 15010502000194号

Powered by Discuz! X2.5   © 2001-2013 数学建模网-数学中国 ( 蒙ICP备14002410号-3 蒙BBS备-0002号 )     论坛法律顾问:王兆丰

GMT+8, 2026-6-16 02:26 , Processed in 0.412697 second(s), 52 queries .

回顶部