QQ登录

只需要一步,快速开始

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

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

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

823

主题

3

听众

4048

积分

我的地盘我做主

该用户从未签到

发帖功臣 元老勋章

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

, y. j f: ]) l' z4 K2 X* Y

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

% b# q% d9 q8 }9 q# D

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

2 |! i5 X0 K& N# h

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

) W3 G4 M6 t4 {& ^* _

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

' t Q, @9 i9 {- {

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

3 E R* }) g1 n e) J! ?

2 G0 N# v2 N/ e4 H z3 K

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

+ \: P( Y" E% M* i: D$ x

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

$ x& s9 T8 e$ Q$ b

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

1 M( _4 z: f! g/ e

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

0 O- T9 @2 X0 ]. }6 a

6 ?6 F* v% @0 Y6 n

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

6 V& s: o) p' v& t C

6 ~9 r( D. H1 C) _

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

" u& H! B7 U, p7 L$ ^! Y' l# i1 M

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

" M9 I; n" [1 Y! `1 ~# r" O

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

! v; `0 u# |2 M. c1 C

interface ILoginServer: IAppServer

# h7 x& S/ x% I/ Z7 |

{

* @ F; [* r9 P4 a. ^" T& q

[

" r: N1 T7 f6 b* i1 B( t

id(0x00000001)

& A# z" |4 ^! |+ r

]

! k0 U( T: `; {8 @$ b

HRESULT _stdcall Login( void );

2 p/ D' e" s* P' }% T: L

[

2 d7 c$ o1 \0 b( l: @) }, ~) P

id(0x00000002)

! j# a5 d; q8 M: r) _

]

d' z+ A$ f- \, B% b! A1 `! v

HRESULT _stdcall Logout( void );

9 C. u. \- w x5 ]4 y+ l5 |

};

+ h- X5 j0 A4 d( w8 o4 Y( c0 y

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

. i0 k" |( [/ f" G4 x- _* x

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

/ u) n k& v" _

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

' f6 n& `4 R/ N7 l5 R" Q4 `

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

5 x; Q7 V4 M8 M

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

i& l- [9 j# l# d+ h" e# s1 ?

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

2 @) p* G$ O, Y7 W' y* F w7 z, f

virtual HRESULT __safecall AS_GetRecords(const WideString: ProviderName, in

- v- [' p& M' F( R2 k

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

$ o0 H0 a9 u& G- t& t, @, |

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

& h5 U. U9 B3 I! H, F2 `

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

2 p6 g8 _. D }

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

: ?- A+ f# m+ v' @; \4 d( s

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

$ ^! \' K/ p4 \3 T

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

. w3 H) G6 M- i- q& Y. [# L% }

class TLoginServer : public TCRemoteDataModule

' D- z6 e' N$ i" o/ V. m

{

* v) N0 W5 W5 `2 L( q

...

! s% @6 X+ w: `1 O7 ]3 G; M$ A

private: // User declarations

/ V/ }1 L3 x* O x

bool FLogin;

6 d3 H: F0 }) E4 u. F0 v

void __fastcall SetLogin(bool value);

* {) k( I; ]4 P3 q% [

bool __fastcall IsLogin(OleVariant &OwnerData);

$ X- T1 P* @' k+ @

...

& l" Y) u$ H6 B! a& N4 ~9 q7 S6 W$ I

__published:

0 _' \: Y* C8 r+ q

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

1 d ]% w7 ]0 K2 u' o+ J

};

% W* k& G6 R! y- ~- h

在RDM实现类中

! _# z% x; A' Q4 Y0 N

class ATL_NO_VTABLE TLoginServerImpl: 。。。

1 h# n8 N, n+ T0 z1 Z2 r! v

{

2 k' ?- V& ~% g1 `

// ILoginServer

( c* S2 j% }2 l1 `' f* R3 m5 @$ p

protected:

3 d: |2 C4 K1 O+ T% q0 N& ]" A9 ]

STDMETHOD(Login());

5 T1 k7 z7 n% e( Z; j1 v1 D

STDMETHOD(Logout());

. g# X W" N7 |& ]

};

2 G* ]+ e4 @% R1 H. n4 m3 ?

然后简单实现之

) E- o" f% h8 q; _$ m+ V

__fastcall TLoginServer::TLoginServer(TComponent* Owner)

% O: @* R) Y; ]+ z4 R* T) ]

: TCRemoteDataModule(Owner), FLogin(false)

2 A& H) ?2 s0 a

{

- @: M2 ~, i, s( G' s% K

}

N7 n: t: A& U- ~* ^. T( Z

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

' s2 O$ x [$ B& R6 P

void __fastcall TLoginServer::SetLogin(bool value)

* M; w/ O i. C3 U

{

- R1 o! H( h( a+ t# m! C C

if(FLogin != value)

& X! H* J) R! T

{

) T% B, |' x( t/ F+ R, T

FLogin = value;

/ i; g) s7 x+ s0 g& b# t

dspAnimals->Exported = FLogin;

4 X5 F! Q5 V/ n1 F2 B# i( h

}

! z, y2 ]$ s9 }- Q3 U7 t1 g% \4 \

}

' e! s7 P- u. p" _& K

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

, S6 f1 j/ `, f9 z+ A) Q1 W% s

STDMETHODIMP TLoginServerImpl:ogin()

3 c" t' _8 p6 w, K) s

{

* Q( a( V* p6 S

m_DataModule->Login = true;

0 J8 u+ o+ ~' @) r& S! o+ g

return S_OK;

' `6 M; G+ M- E3 ~

}

- K, P7 h! A7 J8 ]/ A9 _

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

/ Q$ s+ T! w3 }/ y9 Q7 I0 K

STDMETHODIMP TLoginServerImpl:ogout()

: ?+ V3 b: C: D4 H6 {1 F o- D

{

$ Q* z, D( ?0 e

m_DataModule->Login = false;

( M5 X$ y; P% h p$ j3 f3 j/ G# H, B

return S_FALSE;

j4 U' m- ? X: H

}

. @2 V# k3 D: e- F

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

2 A5 k: b" g6 J: H; B

bool __fastcall TLoginServer::IsLogin(OleVariant &OwnerData)

# K2 N9 N8 u6 s d

{

; q, M" w) G1 s6 X8 ~

return FLogin;

( j6 `- M0 w: E A0 h1 S/ W

}

: ]$ r' Q: ~) K) K8 v: p2 ~: T

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

1 ^2 y1 A& n4 ^9 `

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

1 M( [( ?* V& s- r- K' k& E" J

1 b9 F1 c6 R; l5 _% W

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

3 K" ~( \# J9 L/ N( _

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

) s+ `4 H* {- ]1 d

ILoginServerDisp dispLoginServer = (ILoginServer *)dispAppServer;

# n/ X0 \/ c9 x. X5 R ^

dispLoginServer.Login();

' D! }% W/ e7 y, i

DM->cdsAnimals->Open();

3 }! f& r2 F S* Y2 U. Q

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

. Y, o. \( B7 x# d3 s

/ S+ N% z+ B6 [) o" R% k

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

/ H% p& K/ ]# D% t) @

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

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-10 23:34 , Processed in 0.436571 second(s), 51 queries .

回顶部