QQ登录

只需要一步,快速开始

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

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

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

823

主题

3

听众

4048

积分

我的地盘我做主

该用户从未签到

发帖功臣 元老勋章

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

' q/ O5 F$ v( n' ]

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

% c( z& E- Q- w8 z5 o. r

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

2 k2 W4 b. M+ q5 u8 S* e) T

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

1 G0 v d# E0 f- D

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

+ [) ^& Q6 j3 _. i1 b; t& y5 g% u. ?

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

2 `5 ^. F1 V. g! n* _* p! I# x

/ `1 ]9 Y6 l% @4 Q1 M2 m, I

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

1 A0 z% `5 a# m! j

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

$ [7 u4 X0 a9 v0 V6 A+ Q

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

6 p$ V9 o) }) H4 l9 p5 c7 S* J! {

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

: F ]) T4 i3 k/ ?: \) V6 f

# i z8 L; x5 S1 O; M$ Q

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

! o: T4 e- f( f

/ r" @: Z" ~ R, N, D2 X* C/ L

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

9 D( f) n; E1 k- c

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

+ f) s/ v5 ^& T6 G' ~9 C; [

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

: j1 m1 l0 c4 u1 F9 A( c! I

interface ILoginServer: IAppServer

- C/ s9 q- t: q5 T! V

{

1 H& v/ h3 Z2 {

[

a5 I E+ K; N) [

id(0x00000001)

4 k" O+ B) |/ k) W. M( U

]

9 q0 m( h' G! Y3 A6 f

HRESULT _stdcall Login( void );

8 _- D$ q1 a0 b* D

[

+ T1 X- g" F8 W9 c. [

id(0x00000002)

. l/ N& R) }. N/ i7 k3 P

]

+ I" N. Q* @/ i* D, C

HRESULT _stdcall Logout( void );

, T: r. F0 `5 y9 O

};

2 a* Q1 W" Q& O5 | P* ]

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

* F) H9 y5 I9 n

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

3 Y" u2 b+ j0 Q. y5 r ]

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

! Y* d, }4 |% p% B( M4 n7 @" P

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

/ G; f' k* ^! p/ C& S9 M% b) `

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

7 c+ m5 @$ V" T l4 m9 U

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

9 C5 U/ t; K f* e" b% n1 u

virtual HRESULT __safecall AS_GetRecords(const WideString: ProviderName, in

; E8 ]! f& l' Z0 ]! J e* Z

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

' b, g* e. Y# B7 l

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

) q$ r% [3 J3 T" S: h

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

7 _/ C* p4 }/ U% L! A

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

& U. p8 k w5 D) |) m

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

1 x: i7 u W( e% R; Z) @

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

# O* W5 Z D- D& T

class TLoginServer : public TCRemoteDataModule

. H. ^: L! B+ f7 r, @% e7 y

{

) h8 p$ [3 N) m1 C' S

...

% v( z8 N7 j# C: \9 ^: d

private: // User declarations

7 ]/ H. T. o8 Z3 @/ q6 X

bool FLogin;

" ?/ [9 G1 e( e$ u6 }; N2 y" h

void __fastcall SetLogin(bool value);

* ^( d, R8 U Q

bool __fastcall IsLogin(OleVariant &OwnerData);

( B3 }" @8 p! p. \

...

! P( z: s/ `6 W8 ^2 n5 N/ a9 @

__published:

% m8 s0 i3 D9 R8 Y1 Y

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

2 P2 l8 e% \! E) |8 i

};

. G- g2 i- U( ]" a$ [6 h; a; U9 c

在RDM实现类中

% S7 d2 d0 @7 T Q; D

class ATL_NO_VTABLE TLoginServerImpl: 。。。

+ C" U: h2 x+ {

{

) w1 v% P' d* |% l c; b; s

// ILoginServer

8 h. b) p H- O3 D7 H0 w

protected:

$ N ]0 p R/ l

STDMETHOD(Login());

: d v# a. ]4 ?4 H1 w ^

STDMETHOD(Logout());

* s8 N$ F0 {" Z; ^& u

};

1 G! x7 O. V) a

然后简单实现之

0 n7 F* r6 c* t1 x+ B$ S

__fastcall TLoginServer::TLoginServer(TComponent* Owner)

; z8 h1 R9 Q' z8 C

: TCRemoteDataModule(Owner), FLogin(false)

0 @5 J. B! q3 [# T- K& r8 P

{

2 I N# l1 y$ h0 ~6 X

}

5 ?& }+ E: ~7 ~; k/ @

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

" P0 t; n$ a( v" x) M

void __fastcall TLoginServer::SetLogin(bool value)

, N0 U, K4 _3 { m6 X7 K1 S# ]/ E

{

3 N4 ]7 ?; [* I/ w( x, O" e

if(FLogin != value)

/ T% S$ P# B H* J* E

{

# ]' A. ~; |% `2 w u

FLogin = value;

1 g) Q0 r& P3 X; S+ c7 ~* r

dspAnimals->Exported = FLogin;

7 r, R0 J2 {2 U) c: u

}

: l+ s# n3 E9 f; J

}

+ {( O8 P# T" C/ H0 y0 U

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

) w+ h: ~& e1 ~/ [) `

STDMETHODIMP TLoginServerImpl:ogin()

/ X/ t2 k" o; a

{

9 g; ~8 D3 `: S2 X/ C, A# E

m_DataModule->Login = true;

: E; B1 i/ M* f3 ^3 W' S

return S_OK;

3 u9 x* @! y* A. p) O3 X. o. q

}

; @0 \' }4 S8 J

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

/ K1 U2 B1 w+ ^& K

STDMETHODIMP TLoginServerImpl:ogout()

' ^6 G5 t% q" H' E# t6 G

{

# f8 H% P- k0 q+ ]

m_DataModule->Login = false;

9 z( K8 d- v; q2 m

return S_FALSE;

1 Q( {- X* A4 P# j+ E# G6 h S

}

" x _5 i1 Q |! b2 G; y+ R

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

7 E+ I: g: \% X

bool __fastcall TLoginServer::IsLogin(OleVariant &OwnerData)

. i! q) w% ?4 ?7 V& t

{

3 Y9 \1 \6 K/ n: b) I

return FLogin;

5 \2 \* p& p) M: K. U* S

}

# B" g- I% Y) f% [! P. s

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

8 g. J( f7 X5 K; s8 i+ Y" \' b

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

% \: e+ X* i T, I; A& `5 a- I

& A& k) {% y& S) {4 p" p% `

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

l8 M5 U" u/ B* V

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

. g3 W& t) z' v4 N! v; b/ j

ILoginServerDisp dispLoginServer = (ILoginServer *)dispAppServer;

3 ^$ `$ N; Z/ [/ [

dispLoginServer.Login();

" f; m2 T) I- @! d

DM->cdsAnimals->Open();

, J2 d3 O: f8 ?: p' @. W/ V

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

% h( l/ V7 M% e/ A' P! D: m

+ S8 f- i- N' e9 ~

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

; y+ c% z9 }8 s( s" k9 R7 k

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

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 06:45 , Processed in 0.640330 second(s), 52 queries .

回顶部