QQ登录

只需要一步,快速开始

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

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

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

823

主题

3

听众

4048

积分

我的地盘我做主

该用户从未签到

发帖功臣 元老勋章

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

0 q) k& W3 c5 w" Y9 Q

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

( X) t' x0 i2 h/ T6 \

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

3 `5 Q8 G4 S! F& c) G

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

: w; [8 H# I1 }' i8 p% m

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

& ^% U; S, o1 e& Z

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

u5 F4 w7 C6 j0 s4 c

8 n. M3 _( D) p4 r

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

: y9 e; F+ ]- ?( F. L

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

) e( X' O7 M1 b3 W% Q, e4 N* ]

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

( [* j* U! |1 s: L/ `5 C( d3 D

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

( U) T$ d1 D2 S6 x* e' s

: Y( ` w/ ?( X

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

; S l* d U) W" X5 X

* a5 W, ^6 P. T0 A2 @/ K

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

3 d2 ?2 H# t( x

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

, ^* g' J' F& q: Q) ]

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

# x0 D, ?/ V% O" w, k1 v

interface ILoginServer: IAppServer

t5 |1 q7 J* B. o

{

6 s! B6 T, |0 m( }# ^1 N' n8 m

[

4 j$ v7 a* e/ t

id(0x00000001)

& U* ~& D# T7 \

]

. H8 Q# L* r Q8 d7 J

HRESULT _stdcall Login( void );

8 ]2 v/ S# T2 _$ s5 g" ]

[

r) H3 D* \" z. e- k u) C2 g

id(0x00000002)

* E& x! [# |, v- v$ t

]

( z# p5 l7 D: ]4 N/ b& k$ ^

HRESULT _stdcall Logout( void );

) \; M) J, {7 F" O, `! |( W' \

};

% m; t" c. G' V* i) p0 p# l

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

4 d) n* }. v- A3 t( m

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

% c I3 @9 r* L9 V% b! `+ e

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

& S7 T! @- e+ j" I( M. \0 o

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

; a9 y# p9 @) F1 r p. t

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

6 \" O9 U1 d# r) ?7 u

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

& r& `4 F) s+ F* h3 I% Q4 F) C( S

virtual HRESULT __safecall AS_GetRecords(const WideString: ProviderName, in

5 e' E0 |! T, M( u& y# X

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

: i* C4 u; x. C

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

6 M" o9 z4 W Y/ E; I. Y" C

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

, R8 C" e2 x* |: `0 V

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

" P1 `! }! ]$ Q

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

+ V; B' l* `/ e2 J& W- O7 ~

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

% K# X8 D3 R' \- G& o# }; l1 L

class TLoginServer : public TCRemoteDataModule

7 G: ^% Q* l1 J- q. q

{

) y) e& u2 O3 D8 y, o; A' h1 G2 a

...

* f: M1 I. z/ U1 C$ e

private: // User declarations

- r4 C! s" a, `

bool FLogin;

! T( ^; L- r+ O

void __fastcall SetLogin(bool value);

E J; q3 i" N( m4 h

bool __fastcall IsLogin(OleVariant &OwnerData);

* p' L, E# p' n1 l+ b/ H

...

; H8 J) n# U6 B+ q

__published:

; m4 U U% K# ~

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

9 L- Z6 i, \! j" c( A$ ?6 C

};

" `7 B: t) i5 H# d

在RDM实现类中

9 {/ r; [9 ~' U/ J- o4 d" r

class ATL_NO_VTABLE TLoginServerImpl: 。。。

' V; ]6 h; m3 U

{

/ ~ r7 o! R% J) _) h, u2 h% A U) c

// ILoginServer

" v( w* o( S1 `3 Z2 e# T

protected:

+ C* E$ B6 b# T

STDMETHOD(Login());

) O+ E# C/ Q& v; b: j6 r2 \: j

STDMETHOD(Logout());

* R5 N! k' {- k2 X7 _0 U$ v

};

D' o, D$ X, Q9 U/ B+ f( v

然后简单实现之

* t4 }5 P& w: |; x: C* ?

__fastcall TLoginServer::TLoginServer(TComponent* Owner)

: r/ n s$ ?2 W$ I) ^) ]9 M

: TCRemoteDataModule(Owner), FLogin(false)

' v; J( v& N; _4 \$ q0 X) c

{

& ^& A7 ~ ~4 D6 Z/ p1 U

}

9 a. Q& j! ^2 ]- p+ {6 a4 \2 ~+ z

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

; _1 |% o v/ E+ ]7 s2 n5 d. ?

void __fastcall TLoginServer::SetLogin(bool value)

/ u9 r0 e; w3 `) t7 l9 Q

{

# F8 E& P, H& l# g: U8 v* u- i! p, |

if(FLogin != value)

* C) k9 B _0 W7 A* Q4 G# ]6 L) p

{

, w( \) Z3 }1 B1 d! l3 B) C

FLogin = value;

' q o4 y7 i- J, i- ?' V

dspAnimals->Exported = FLogin;

) h8 `; |4 ^% v( I% d: n

}

, q; c/ R$ w7 f. k& ?1 V3 Y5 |

}

8 y, P/ b' f1 \$ a

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

# M3 `: j4 ^, t' f9 y2 U

STDMETHODIMP TLoginServerImpl:ogin()

0 [% i1 N1 ^# u& t6 z y

{

7 R+ @" }* G0 b8 y6 Y0 P

m_DataModule->Login = true;

* k: \* }* {2 ^1 P! K0 n

return S_OK;

3 }* V; D! x9 Z7 l& D4 W

}

2 M& ?9 n. E" h5 F

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

& [* q9 h8 z4 t e: O) m

STDMETHODIMP TLoginServerImpl:ogout()

8 j& u! ^+ T# F0 t8 P

{

c3 z8 a; X$ V5 Q

m_DataModule->Login = false;

( O! B8 g6 W: @4 |: e

return S_FALSE;

, W9 U) ], R- v% Q2 g, P

}

1 g4 j* T7 ~5 y7 n3 l

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

7 F. v4 d. X, T

bool __fastcall TLoginServer::IsLogin(OleVariant &OwnerData)

6 x, R. m) L, @2 e ~

{

4 Y' e( p+ R, [) Z

return FLogin;

! j2 j* V' @$ L& H' d+ e

}

2 C6 n/ V( [* e% u$ ~) i s

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

7 i; e2 j$ Y* j" l, z

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

' i8 Q& V- T8 K8 p

/ v9 w4 B+ P2 v

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

' R2 l3 x3 j, y- e' }

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

( g6 X/ n4 i. l4 B' O. h: ]

ILoginServerDisp dispLoginServer = (ILoginServer *)dispAppServer;

' @0 B, x. V/ t' v; G& W

dispLoginServer.Login();

6 F$ g, I2 V; m. Y

DM->cdsAnimals->Open();

4 [9 Z3 \0 [0 a

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

8 Y3 f( w0 l" U9 c: ~/ ?

3 ?9 y- l- |3 G

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

8 C. K6 }$ }3 A/ f

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

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-8-13 07:54 , Processed in 0.521219 second(s), 51 queries .

回顶部