QQ登录

只需要一步,快速开始

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

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

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

823

主题

3

听众

4048

积分

我的地盘我做主

该用户从未签到

发帖功臣 元老勋章

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

7 X& ?! J, p( I$ \* ^: g

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

8 T* q8 h, ~1 |0 J) y) f4 m' h/ \- C

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

; U8 s% S9 o! O3 |8 Y6 H% E2 P& ~9 I

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

6 k$ @+ s- J, n5 L. K% M

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

7 u7 K9 F# l3 y

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

% P# z; \* M. M+ ?* |5 Y

7 s" @/ V! ~# H) Y+ W

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

# B) }( H- v* B6 N, ?

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

3 s5 x. m! P3 K( X, B/ l) p( u# l

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

+ h& [% A. S3 n8 p$ ?$ H. [

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

) E' Y, W4 ~3 _ T

& q" a. J! e! S, W6 f

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

3 C8 b8 p s+ Y$ ~4 |

9 | k( g, p2 y' h. E

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

& b) v1 u/ H0 z; {( e& O5 }8 q

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

/ M- l" g0 c: k! l

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

0 F9 e* S9 Q1 o1 h

interface ILoginServer: IAppServer

( u( h1 m' e( c+ ~

{

2 w* o7 b1 n, {8 x

[

D; H; I" R" L- v3 S

id(0x00000001)

# F: W Z! R2 ~

]

- X( u( Q# b! y) |: K" O

HRESULT _stdcall Login( void );

' X8 w1 J1 z4 q; @! h0 d+ {- I

[

; |# Y% V) S; K7 ]3 q

id(0x00000002)

) J+ T$ e( X, m3 h( T2 H

]

0 V( e" X" U9 a* M0 n/ v

HRESULT _stdcall Logout( void );

1 n/ r! p3 P: W" N2 M

};

7 S% r! I5 a3 B/ V

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

" S) p- |2 U& c( B

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

5 x; f* ]3 O( C: _* J2 n: z

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

0 P4 {- S/ w% ~% @. _. a6 f6 Z

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

( w; J: W" x- \

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

1 {" l- e1 _, t2 \/ ~+ j

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

9 z1 p4 o: n: R- a+ X* H! E

virtual HRESULT __safecall AS_GetRecords(const WideString: ProviderName, in

! w: {' W2 n' C! _6 m

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

$ }; M9 f6 T6 j( e

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

; R8 U0 }- x" t; N5 ~

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

) g% }/ R' K* _0 M$ I5 w

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

) _8 }( c7 a8 D5 u

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

* ~1 D' |- x c# J9 c6 m$ f& Z6 H

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

+ w* q+ j/ E4 S+ E

class TLoginServer : public TCRemoteDataModule

- a# R# |. U7 [2 ~4 {# W4 q+ B0 c

{

4 i8 v) w3 p7 v/ }; t

...

! a4 Z& F' ^+ M7 w8 n( m0 @

private: // User declarations

3 w9 M$ {" W4 t& J7 f/ `7 C

bool FLogin;

, { ~4 _! i( M# Q# d# B

void __fastcall SetLogin(bool value);

2 U- {% |4 p4 T3 O3 b0 c- W) @# s

bool __fastcall IsLogin(OleVariant &OwnerData);

' k) u, k: C7 `- ^/ a

...

o& o& d3 D" z- e1 X

__published:

' [* R& t3 @ q" w

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

/ m: D4 j" D6 ^9 Z

};

' b+ k& Y/ P$ Y

在RDM实现类中

2 m2 V3 C B. \7 S5 q

class ATL_NO_VTABLE TLoginServerImpl: 。。。

' S# p; t, |3 L5 R; ?0 H# j

{

8 N+ G8 i" _0 m/ c, a9 g

// ILoginServer

; U; C: Q9 F" F0 S! d

protected:

5 K4 c, V1 N+ l! @- K; }6 A

STDMETHOD(Login());

4 w- e- Q% ^ |% W p

STDMETHOD(Logout());

5 ^# `* R# Q& C5 j. N" h6 G/ Q

};

( b% V$ j! }% o7 B/ V7 W! x

然后简单实现之

# I* e" k8 s3 B# L* f& k" m

__fastcall TLoginServer::TLoginServer(TComponent* Owner)

9 j* g8 Q+ M1 C9 l1 M

: TCRemoteDataModule(Owner), FLogin(false)

: _" {" G: J" S9 ?

{

+ ]. N# s! r: q1 b$ i) {3 m

}

: C) R2 q" D: @4 k$ C! B! C2 S3 e

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

8 Z8 v* ~5 Y2 _% x( K- O; `

void __fastcall TLoginServer::SetLogin(bool value)

9 N, w) Y5 I3 r

{

- h5 }% S) R7 V! a- c

if(FLogin != value)

3 _" {- f: E1 c5 r% O& t+ K

{

: @3 e& I* h9 M& ~

FLogin = value;

/ k, I1 _# A$ e2 X6 C8 @% `

dspAnimals->Exported = FLogin;

2 @' G/ w6 X- j' j0 q/ o

}

/ x& t/ \$ H; M$ M7 c8 D

}

! Q8 m! e+ N' g5 s% q

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

0 S2 z1 r- ] q# M/ I' _

STDMETHODIMP TLoginServerImpl:ogin()

4 P" ^/ d6 p" L/ L

{

( V5 J! G* C( E

m_DataModule->Login = true;

8 M# z( ]& Q7 C+ K9 G: A6 i

return S_OK;

3 m9 U1 K6 H$ j7 ?& X! R

}

" M/ H4 P0 w: l+ I: F$ C

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

$ i% ?, N$ z+ L" h- x" o

STDMETHODIMP TLoginServerImpl:ogout()

. Z X `( d$ [

{

9 a& J, B1 u5 ^/ M

m_DataModule->Login = false;

. F. s, Y3 p% V

return S_FALSE;

( h, D7 `3 |0 L0 |* Y5 [

}

. q8 L/ X; _0 v5 y3 U8 v

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

! b4 V: C. L" k# ]2 J( ^

bool __fastcall TLoginServer::IsLogin(OleVariant &OwnerData)

( v- ~- ^ M5 v

{

# e5 k% I! Q& J, A: V8 L7 E# W6 ~

return FLogin;

% k# Q W( O% w9 m& L- p0 ]

}

! H1 Z0 w9 _2 m- y; |2 m+ O

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

( R. Z. u' [' P: f) b# w

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

o+ K8 y6 Q6 m5 W2 g5 |

$ L% a* P: q5 q. Z# ?. {# O

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

# T% G N$ x3 c3 [

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

( B8 u0 Y' A2 q' v3 ^' h! j. _% K% X

ILoginServerDisp dispLoginServer = (ILoginServer *)dispAppServer;

7 h2 D1 t0 [* U7 K

dispLoginServer.Login();

0 ?. U# y( S3 h+ Z0 I& [

DM->cdsAnimals->Open();

. i5 i& f% a. t3 f: Y

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

$ J1 [/ G: ]- ?

8 a5 q- @. F6 J! [

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

( z: }4 @' l5 q7 F% ~. [

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

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-15 18:27 , Processed in 0.507439 second(s), 53 queries .

回顶部