QQ登录

只需要一步,快速开始

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

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

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

823

主题

3

听众

4048

积分

我的地盘我做主

该用户从未签到

发帖功臣 元老勋章

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

C3 z4 }3 G' y; A! W

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

5 n7 m& V" b) V: S! r. D1 R% a

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

; p% T& @4 ^0 J& W: ^$ ]

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

; C% W; S7 F+ ~. O" @, {

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

$ t9 ?# C4 b1 G2 a

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

( W- a% l4 K7 R: r( _

3 {' e- C- q2 G* g# f

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

8 U1 t7 k) p2 e5 l% S8 N- l1 F

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

# L: X& ]8 H' g2 t( V

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

* J i$ J' b+ H/ z

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

0 K- l8 k' L) p& m

3 k0 }( g, |# W

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

+ k. c: U5 N: F

* b* H: A! g6 W5 ]& F

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

. b. ?% y$ G. ?6 }0 T0 w( i+ m

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

3 a% i( E# O$ i3 `5 B

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

$ O8 v! U5 Y6 s# B

interface ILoginServer: IAppServer

' C+ r( A; c3 N2 Q4 C

{

. Y' U3 i1 B- i7 m+ k

[

e# L! T. _' b% H+ i( p

id(0x00000001)

) p2 ]# @" p: C }, x5 k- Y0 X

]

$ U" d. G% B! Q7 p+ a* j

HRESULT _stdcall Login( void );

2 h' Z. S7 t: `2 ~

[

' G# k/ v; b5 z$ u+ N- W

id(0x00000002)

5 j. v3 w A) q3 P" \& ?

]

$ R/ M+ b; W6 d

HRESULT _stdcall Logout( void );

" W1 n/ e: q. } f6 M( ]0 f) d7 z* P

};

' \! v5 E7 ?; E9 W( b% E& _

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

5 e" |+ o0 w4 h3 M% O# h. K

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

. i7 i; p& v; [- |0 X" \

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

- D! T( s/ d( g. g6 ]

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

) Z0 v" x/ [& Y3 o6 O2 E

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

/ w4 q- I" L# {% k% o! Z' T' t

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

* s2 _6 R0 e) G" U) |0 o8 c

virtual HRESULT __safecall AS_GetRecords(const WideString: ProviderName, in

3 y# C8 V7 p4 ^/ w# f* D* i

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

( `" {, b; H$ l: S. z

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

/ d+ t1 R& z( L5 Y2 P. ^6 x) H" @

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

5 Q2 D& H) z4 w" h# ?# \4 Z

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

& I5 n$ ^7 `5 r7 X' s( S

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

8 Z. {# V- i6 Y* c4 r( S

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

4 [, r8 W0 L o

class TLoginServer : public TCRemoteDataModule

( Y, \* H ~; U. h- t# R

{

2 v4 Z. I, Z5 [6 F! R, r0 R

...

; @ _% S# n+ M# P

private: // User declarations

4 u' j9 C, O) O

bool FLogin;

# w2 ~- z0 x0 U' U& l, [, L6 T

void __fastcall SetLogin(bool value);

' s* Z. y% W) \" K4 e

bool __fastcall IsLogin(OleVariant &OwnerData);

7 G0 Y( A2 L3 l# ?1 O3 Q1 e% N

...

( A( Y. i7 p, ~0 s

__published:

Z/ [$ g5 {0 ~

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

0 `$ t* w w E6 H

};

8 g. S. D) [* ^- I4 ]% {

在RDM实现类中

: D: T! a# _1 A

class ATL_NO_VTABLE TLoginServerImpl: 。。。

- \( D6 a6 p) R! b

{

( S, \) q# t5 Q& I6 S# K( W2 l

// ILoginServer

# l1 |' j4 e* R' ]

protected:

+ w6 Q8 j5 W. ? ~$ h7 t5 Y

STDMETHOD(Login());

) \, Y" J4 }9 r( U

STDMETHOD(Logout());

# ~, r5 `& V; ]3 V0 ~

};

/ \! i4 _5 q) F9 Z) L+ H" Q

然后简单实现之

# o2 |! F3 \ m# L

__fastcall TLoginServer::TLoginServer(TComponent* Owner)

* `: [/ H& u* A4 X7 X7 d, v9 @

: TCRemoteDataModule(Owner), FLogin(false)

/ V! P, d2 f) ?# A! r f% G$ E; y

{

# ^- }( H% P& a- S0 T5 P3 G

}

9 L7 ~, C2 L" V- o0 x6 t

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

; F. Z$ M# L3 {8 ~7 D/ e

void __fastcall TLoginServer::SetLogin(bool value)

4 a1 F( J' ?& F$ c Q8 Y; {! y- d

{

% o! I; @' J5 k( `8 `

if(FLogin != value)

* b8 U L: g. R7 E5 n* P/ l

{

! Y4 B1 F3 c! H5 n1 X" R' e; x

FLogin = value;

! W) A- T2 c' L( x. m

dspAnimals->Exported = FLogin;

0 _3 ?+ E6 @& H& |

}

+ J/ S" E* i! P4 l% n9 G

}

( _# j# X+ F' d t4 V5 }! Y5 _) I

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

6 W1 f$ M* Q7 T8 S

STDMETHODIMP TLoginServerImpl:ogin()

- U* u2 h. {1 e, X7 p1 T

{

3 l3 ]7 q4 k8 @$ K9 e

m_DataModule->Login = true;

8 B) p' j7 h) E) P; I

return S_OK;

* } V- j3 ^" U) i$ r& W# u0 O' o5 v

}

6 [, B. t% Z I8 u) A- u) F+ m

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

3 Q4 W8 X" c( R. P X: p: @

STDMETHODIMP TLoginServerImpl:ogout()

' e9 Q) i7 i/ P/ N/ y

{

, k0 f. Y& j' o) W8 ?6 C

m_DataModule->Login = false;

7 O; ^+ b6 X4 V ?2 M1 s

return S_FALSE;

. D. a4 n" Y2 R% f' J6 N

}

1 R7 _5 h3 K7 c/ u

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

+ [% t0 p3 D* ]; \# A7 o

bool __fastcall TLoginServer::IsLogin(OleVariant &OwnerData)

% |. x: ^/ B& Z' e% G4 |$ L' p

{

) i. g5 p6 X% `) Z- u6 r, G

return FLogin;

7 |7 S9 I2 W* a C& x; {

}

9 z F4 }5 W q; c

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

2 V" {, v4 N1 Y+ E9 Z4 Z

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

/ c) r) o$ s$ V0 P9 b

5 A. @& v" S3 P1 h. u; K0 F8 X

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

2 x5 w# L0 g* h) M D

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

{+ {/ k9 u. G" f; c9 I% [

ILoginServerDisp dispLoginServer = (ILoginServer *)dispAppServer;

8 E( p( r( p# z$ X# J Z: Q8 R, T6 m

dispLoginServer.Login();

4 [) |' p ^+ b+ L3 ]

DM->cdsAnimals->Open();

# W; |7 B K0 P6 R. t

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

+ U# X! Y( ^% R' H3 b* I5 _

, y* o0 H9 ~# k* A

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

: r6 Y+ w1 P1 }5 j& J

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

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-12 22:03 , Processed in 0.552667 second(s), 52 queries .

回顶部