QQ登录

只需要一步,快速开始

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

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

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

823

主题

3

听众

4048

积分

我的地盘我做主

该用户从未签到

发帖功臣 元老勋章

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

3 K! y, ~( i3 j' q$ ]- L) P

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

+ C# u3 ~1 X# r: w' W

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

R/ r5 Z- v" D8 A" Y

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

! r6 _, W. n/ }. E+ n/ t, ~

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

3 n2 y& p) c6 K: s' h

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

1 T9 \2 k. [5 `

: Z( {- r$ b: z( n& ~- U$ l

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

$ W: f& H' K* G$ m+ m( |& }$ @+ u

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

$ J% D2 Q2 G& q/ c

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

: Y* x& s( c) _

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

0 W! a! b S2 ~ h

7 j$ Y* E0 g5 _: q

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

. ^7 C. ?7 D, U# u5 F

3 U$ A$ |/ ]* N4 F; V6 q" y

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

7 z1 O/ K9 B5 w$ N0 x2 p& y

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

& K" C3 }: s6 ^2 F! ~

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

7 P( |! ~5 U3 O' N* U

interface ILoginServer: IAppServer

; X. {3 K; D2 [# W" j2 c6 a8 [

{

: F9 h w& W1 R6 p0 M# e

[

0 F. N& m- U' s" U; v

id(0x00000001)

" N" {2 m+ l4 k2 S7 [0 w5 W8 l* a

]

9 N2 W% ?5 b: a

HRESULT _stdcall Login( void );

5 N( ~% I' e; A1 R

[

) |3 w, o: Q6 A1 L5 i; ^

id(0x00000002)

3 K! @ d4 z' T4 n! m; P

]

; i3 Z/ s) s" d9 c

HRESULT _stdcall Logout( void );

' ]0 c+ ` \$ W5 B# M7 u* a4 Y

};

* q1 y8 |% S" ]3 I- c! z

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

: v" m9 P$ O- @4 X2 V& X5 _5 m

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

' q! t/ ?" `; q( C4 D7 U" e

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

, [0 w8 o7 _3 {7 ]$ F

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

* h) {- [. d! w* o

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

% s4 T: k6 U/ j

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

% \2 L) m( i/ ]4 D$ |2 f; }

virtual HRESULT __safecall AS_GetRecords(const WideString: ProviderName, in

( |% e$ z# w W; K1 ?, ~( o

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

5 w) V2 \$ K; G0 {: L- ~0 k

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

9 H5 W; c. l- J+ C

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

. N- K2 q5 H. c# _ ]* |3 X

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

1 }7 g# s0 \7 R# }

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

4 ^3 k; b3 C/ w1 H9 J* Y" D

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

1 d- [4 a) D' D4 N

class TLoginServer : public TCRemoteDataModule

! N1 z% u4 U+ L; @

{

! F- l- Z& t2 U0 D- z8 L# P

...

) d; t: S% _2 p: C

private: // User declarations

+ c- F* \9 c9 {' D9 b( P' e

bool FLogin;

/ \5 I0 e+ t0 L! V9 _% t

void __fastcall SetLogin(bool value);

" n" g3 R7 H4 X7 w4 }9 J, E

bool __fastcall IsLogin(OleVariant &OwnerData);

+ ]3 S5 W; F# V. q, |

...

9 ]* M# y, D# t# c2 V5 ~

__published:

5 u* C5 _* g4 K1 ?! M' e

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

% ?. H; e/ I) i S3 {

};

% F* L: E# Q$ j4 e) M8 ]) Y

在RDM实现类中

7 ]4 z) k$ W- w* l; E: f

class ATL_NO_VTABLE TLoginServerImpl: 。。。

6 D: \2 |0 M# C* K4 b

{

5 Y2 o7 Z2 ?3 P3 z7 O

// ILoginServer

6 x$ w W. X7 U9 i8 b6 f

protected:

3 Q& k8 k# \% x8 _- k. h Z" B

STDMETHOD(Login());

1 J1 ~2 W+ @- f$ b* O- V( n; u

STDMETHOD(Logout());

: o6 l4 j1 r% q7 D

};

; S1 ~4 x, [ r0 R/ A* V

然后简单实现之

' d% K" M* R6 ?0 Q6 J

__fastcall TLoginServer::TLoginServer(TComponent* Owner)

5 _/ _9 y! A e2 G$ f8 q5 U

: TCRemoteDataModule(Owner), FLogin(false)

c6 H7 B. E( ]) H* [+ \0 T

{

7 l8 g) n. g9 F# E

}

2 G$ R7 e4 }( j4 W

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

/ ?# h- e1 [6 m

void __fastcall TLoginServer::SetLogin(bool value)

& s; h0 U6 G% z" ^4 _$ a7 J

{

, Q9 j; r3 s% n1 ^' }9 D

if(FLogin != value)

H4 b/ Q5 W1 o/ V$ r6 g8 A% V O

{

5 y* i2 @, w9 E' Y! ?' E$ v

FLogin = value;

" W, ?/ Q9 Q: G

dspAnimals->Exported = FLogin;

. b. R" k* M0 U! f4 G

}

4 Z0 g8 l) }8 N0 w5 g4 y

}

( U& m; ?/ g6 {8 V2 T

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

0 D' O/ g0 m2 ?' w* ^3 d

STDMETHODIMP TLoginServerImpl:ogin()

9 B( S$ {3 X: v+ W7 `5 N

{

" l. s |, N3 n$ [ G

m_DataModule->Login = true;

( w# ^& E& J! G* [2 h

return S_OK;

+ n( V+ |" X# l* f# H6 _0 B

}

. p5 q- l& q) R' Q! `

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

0 N, u, Q1 P p$ j7 o

STDMETHODIMP TLoginServerImpl:ogout()

$ k2 W( J9 I3 e' L/ J6 ?

{

7 R" B' \$ d& a5 x3 |

m_DataModule->Login = false;

6 K0 W1 ?; a- x; i3 E/ O

return S_FALSE;

7 g. Y! v9 ^ F

}

, \+ z- c" e+ y* I! k9 T

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

+ ?" [, Q$ ^! n- r

bool __fastcall TLoginServer::IsLogin(OleVariant &OwnerData)

# O r8 ]' P3 w1 B3 h

{

' y8 ^" w, j0 Y5 Q% G1 c

return FLogin;

8 \. Y1 a2 ~4 i$ ]

}

9 N) O2 n4 a! T' {2 ]9 k0 e m

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

6 g; L6 [' Z$ a& }2 M

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

) ]( T4 S' C. P: S5 s3 I: ]

& m2 U0 y! m6 `6 b

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

% C: t' E! \' u7 f8 `3 R$ r

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

4 h' ~; R. ~* [: k) t! D

ILoginServerDisp dispLoginServer = (ILoginServer *)dispAppServer;

' ~( b; T% d- _% ?6 R

dispLoginServer.Login();

6 V j5 W- e% H( i. d

DM->cdsAnimals->Open();

# }+ x6 F ^ n, }

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

, _' p0 S1 N! @' j& e( C" f

' [4 Z0 s( ^* s) ?; {/ o0 G2 Z

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

: s0 l# i1 k6 _ p6 N8 O. j- U/ v

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

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-4-19 22:54 , Processed in 0.417722 second(s), 52 queries .

回顶部