QQ登录

只需要一步,快速开始

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

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

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

823

主题

3

听众

4048

积分

我的地盘我做主

该用户从未签到

发帖功臣 元老勋章

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

- y% u% Y. d' b

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

& D8 s3 k. R# x3 x" b' a* w6 c! h

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

( ~: n$ n6 W! x ~4 ]( x

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

% C: ?6 \& y* v& {( V5 D2 @" t! _

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

. E/ Z) g3 I% g6 g

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

8 B: X! l) w& g3 S X

- f1 u' S7 H& z

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

. k3 I5 k/ g9 y4 M

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

6 `% g/ e5 ^6 [& z& L

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

+ h x8 }$ ^* i" A4 I) n, Y( e7 ?: J

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

7 s* S7 x' l: I% s1 x3 S6 a! p* T

; S9 j9 q1 Q5 }8 W# d9 P

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

9 F2 {4 O1 {" B, _, k

+ }6 I5 I6 `% g# T

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

: x4 N9 ~1 O$ r% H4 L! [

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

% t9 y: A( T* {! I8 I, ~: _

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

$ ^" t9 E' ^8 s' z7 c

interface ILoginServer: IAppServer

( a( @; X- O4 k6 a0 h6 T" q

{

8 z. g$ @- S m6 y% P s

[

* w- r* o1 {3 @& N" s# W7 |

id(0x00000001)

4 V" M( ^' F) k& z: D% S

]

- V' f5 G2 `0 F# ?, e; U

HRESULT _stdcall Login( void );

. }2 ?/ o; j0 [1 ~# U% c6 R

[

0 @& |9 E6 a" ~( |3 z

id(0x00000002)

* {2 Q. l. J O+ t. d. C @6 t

]

& y$ @, y1 M8 {& t( n. V! j

HRESULT _stdcall Logout( void );

/ W# D: \. U% p1 S4 b

};

, c) q- h. x* n% t5 I* F% |; Y+ G

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

. q9 \% u( X# m: G" S6 A! [6 a& \

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

, V' ~6 I2 z( M- ^5 P

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

- f8 o; M# a' U

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

2 z* ~4 E% I: C2 L6 M2 J, O

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

3 o* `: W. m" t3 E u, K# i: J' c

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

) a; R4 u0 Z8 V, ] b, w% J

virtual HRESULT __safecall AS_GetRecords(const WideString: ProviderName, in

3 V, p' e) j& D" }9 Z

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

0 n, `* i4 \3 F: X) E

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

2 {$ O3 |" R# M4 t0 J3 @; b0 q

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

0 u: B7 o! j2 b: e7 j

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

7 g, O, S$ a5 z- g' H

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

* k1 I& _/ y0 B- i; @

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

; |0 M2 ~& n7 w; U k6 {) {

class TLoginServer : public TCRemoteDataModule

, `3 H/ [5 _+ v7 }, J

{

* e; A& Z. J. l, f: H

...

+ k# ]7 ?4 n7 F5 Q9 l

private: // User declarations

! v W' {" l/ H/ j9 v0 V! J Z- V

bool FLogin;

$ f2 d9 u, W+ V5 ]! c

void __fastcall SetLogin(bool value);

: V% f2 {% c/ p4 X1 P+ ~) q

bool __fastcall IsLogin(OleVariant &OwnerData);

" X9 R5 t7 |( f. _

...

/ }7 i( t& G$ }- V' e2 N4 `3 ~8 l8 R

__published:

! B4 M/ _; t; a- U. m" ^

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

+ R% H C+ ?7 G, \4 I+ f

};

$ [% C6 N& J$ `- P4 Q! k$ Q

在RDM实现类中

" }! G% o& G$ z4 |( d7 n4 k; l6 b

class ATL_NO_VTABLE TLoginServerImpl: 。。。

) j. @$ @0 {7 E+ z: _( S& b. G

{

* y; d" [$ S5 L

// ILoginServer

' {6 u2 Z# v: i P) x3 `+ M1 |

protected:

- d0 C) o1 G6 Y0 z

STDMETHOD(Login());

0 B" D+ _ N' w0 T5 a( g

STDMETHOD(Logout());

, _/ \& z8 f2 `2 t8 {0 ?$ L6 [

};

8 H. W( K8 u: {- @$ Q& P

然后简单实现之

6 y- n/ l. p; x7 I* l# e

__fastcall TLoginServer::TLoginServer(TComponent* Owner)

( e8 X7 ^# Y" Y1 r( _& }

: TCRemoteDataModule(Owner), FLogin(false)

) s# F0 q% W" \) }9 D

{

6 L- l0 v3 j! \

}

) F7 k! c, \5 ^$ M

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

, Q/ M4 M8 U. ^8 o

void __fastcall TLoginServer::SetLogin(bool value)

( F; x. a' d- |; ^1 i

{

# I3 @- }! H) S8 |! Q

if(FLogin != value)

6 Q0 T2 U+ {( [. }! `

{

! y' O) \2 a ~: x

FLogin = value;

+ F( G/ j. G) X7 J# a* l

dspAnimals->Exported = FLogin;

# z C; d5 h, B6 a! W

}

7 v1 [( C. m2 b) [$ o: |( `2 }

}

' P* L/ U' U3 j F% Q5 |& o" v" e, S

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

( Y$ w f* s9 M) x0 L2 g

STDMETHODIMP TLoginServerImpl:ogin()

3 [9 h, D5 }) ~- W

{

1 R# h5 `/ |1 p( O' u

m_DataModule->Login = true;

& X( v- J* v' k& F

return S_OK;

6 r/ H' |3 G. B/ L+ j, |. B1 |/ l

}

! L: d4 s- `- @% E& T' d8 T- |

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

$ Q; d9 F9 ?# h

STDMETHODIMP TLoginServerImpl:ogout()

1 Y7 n3 l3 x7 {) I" q4 X: m

{

( Z& [( n& N9 P& S. k

m_DataModule->Login = false;

; c2 w% B! d# D: b6 I+ f3 U

return S_FALSE;

! R j( `: T; u+ [( {3 S

}

6 W/ o; q, b' ^( v

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

4 R' `8 y3 t, Q* F, m) I

bool __fastcall TLoginServer::IsLogin(OleVariant &OwnerData)

/ [. E- w; \0 M& m

{

$ v2 }; G. \4 {7 Z; L2 ^

return FLogin;

' ?# K4 n6 `( E( k

}

9 v/ s+ r2 j& C2 v4 T0 j

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

* g: u; U3 H" W8 N# E/ F! X! Q8 b

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

+ X' g- t' ?4 f( W

: J6 c" `1 k. ~$ ?

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

% n) Z3 E( _+ _4 x; R2 |) f

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

; w/ d* F; ]: p& h8 K2 u

ILoginServerDisp dispLoginServer = (ILoginServer *)dispAppServer;

1 j% \- M" `! w! i/ a8 e, i

dispLoginServer.Login();

( @& k ^9 X V: \2 H7 d

DM->cdsAnimals->Open();

$ A; R4 J8 p& e. |; }7 q' A

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

% ]4 R% @$ O2 I7 w! \7 |1 S( h

# m1 @( B( F$ M j- j

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

+ ^; B9 M/ I% E v4 l; e! z5 V) \7 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-13 07:21 , Processed in 0.367130 second(s), 51 queries .

回顶部