QQ登录

只需要一步,快速开始

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

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

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

823

主题

3

听众

4048

积分

我的地盘我做主

该用户从未签到

发帖功臣 元老勋章

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

' Q/ j- F& N/ i1 O

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

. K+ u3 D4 ]- ?+ q8 F' k

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

1 w* D4 g( f H7 z, J; u

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

$ Y f. k4 \9 y9 L- @9 i: s4 m

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

: r$ y3 j' u! c

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

8 \) B3 u$ Y( C# B# c

. F4 r, I. V t8 d% [, i" K ?

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

; Z8 p! c* W0 h l: l, J2 R" S3 J

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

. e i: a8 U* ?

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

) }! }. H8 E8 q& n2 U

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

4 L' V1 J2 |, f5 q$ V' C% U

1 O3 ~ m; R8 s

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

/ K/ R( Y# B3 f# d

6 K- H) ?# g( Q% H3 E, A: b

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

W2 v) p. M: B- ~3 F( F2 ~7 m

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

8 T* A% [+ J \1 Q

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

6 i G2 ^9 i4 t8 _! f9 R6 k j! l

interface ILoginServer: IAppServer

3 V2 {5 c8 Q$ ? ^8 |/ C

{

- H3 ^% b r1 ~

[

+ _) m! L7 R8 u4 F% ?4 z

id(0x00000001)

2 |1 S+ K* l) V

]

) P6 `7 G, N! |9 C

HRESULT _stdcall Login( void );

4 y8 X9 A9 ?# \; e

[

2 k3 r; }0 _- }! F

id(0x00000002)

4 Z5 M7 \! Y* B) H/ ~

]

$ `+ K$ J8 R. s

HRESULT _stdcall Logout( void );

0 C {& m( J0 Y1 F) e* R1 ]

};

$ X1 B6 Y9 L5 ^- ]( B

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

5 ^' }6 K" E. r' a# ~+ }

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

# }6 P9 ~# {/ ]( A

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

) y; C0 s Q) |7 f/ c9 H _ a' g

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

5 d. \3 U( f9 Y$ \: l; P8 o

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

4 y/ ]" V. N3 {) u* {; r

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

' F5 e! K, B: S* p! R V

virtual HRESULT __safecall AS_GetRecords(const WideString: ProviderName, in

- V5 t) R" k/ r/ ^# s8 F+ Y

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

% I% B0 w1 M/ w* }1 j, |; E4 G5 j

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

, Y3 z# c+ ?4 R9 ^: R) l4 _

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

6 ]' r p2 G* N% ?* w

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

, q8 U; y: L5 b

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

/ h+ j! `5 Q$ H2 M5 w; k( Z

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

- |5 V* j9 k3 D9 P6 p. O

class TLoginServer : public TCRemoteDataModule

- U% Q! y! V, R9 d

{

0 {5 s5 R, Y1 b6 m4 u$ ?

...

. H- i& @- b9 M I7 w+ U. L

private: // User declarations

4 p# l8 X+ }) O6 Q' B2 }3 ? y/ l

bool FLogin;

8 K4 T; r7 q7 G

void __fastcall SetLogin(bool value);

# P U z5 s. q' r, a! W+ P" T% j

bool __fastcall IsLogin(OleVariant &OwnerData);

K$ I- Q. g. _! s. ` T

...

+ t- ]$ @/ \( V" h/ ~# M

__published:

- a7 [ }$ Z$ Z, ~8 |7 v& \1 T

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

4 `0 A7 I( W' g8 X- T

};

" \4 F; U- V P& v+ n& |

在RDM实现类中

7 f! `% M( o. m/ C4 e

class ATL_NO_VTABLE TLoginServerImpl: 。。。

* g( A8 _2 [* E9 W5 k+ [

{

: C, n# M% \1 \! {) F

// ILoginServer

8 l6 b% E4 O. q! K; S g4 L% J, K

protected:

& h# n& F+ \- V4 H

STDMETHOD(Login());

9 \, C1 h8 X3 \, ?; f

STDMETHOD(Logout());

7 }- m, c: U3 f0 e' i* m* o! g8 U

};

$ v: m; c6 y, S/ I8 d) A' l, W6 K

然后简单实现之

) @2 ?7 E" D2 P

__fastcall TLoginServer::TLoginServer(TComponent* Owner)

0 a2 H2 l4 O; \% F7 }; s

: TCRemoteDataModule(Owner), FLogin(false)

. G7 e& R: r6 c4 ^7 G

{

( c8 b* v& p$ F* ?" x, o

}

% b8 |8 }1 v- b/ k6 W( r0 B

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

: p3 v' k1 E; b9 V8 w, R4 R( S: j

void __fastcall TLoginServer::SetLogin(bool value)

; ]: [" d, G7 w: c0 \* G

{

+ G8 j: c5 E' x, v) L$ }' a O

if(FLogin != value)

6 c: p; d, c; D6 r @! i; n2 Z

{

+ j; e7 w) J- a5 q, M) h! h

FLogin = value;

: A7 S/ }7 C# G( j1 z

dspAnimals->Exported = FLogin;

% P+ q9 K( }' g0 }5 F- i

}

9 V7 e! Z' t5 P2 R' q$ L

}

) v7 E( f2 A6 o4 }& \

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

; [ b; G m! L. v) d6 ~

STDMETHODIMP TLoginServerImpl:ogin()

# j$ P0 m6 Q# ~; e

{

& t7 H J( S! V% o9 q- M

m_DataModule->Login = true;

' e! o( i7 |- u: c2 m! M, h4 i0 p

return S_OK;

# J7 W9 B, k& ~: v+ I0 t

}

! x; M) O) ]0 ?$ k' P/ E

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

5 {4 q% V/ y& m7 e7 R

STDMETHODIMP TLoginServerImpl:ogout()

# T4 S; m1 p' D& q, M/ k, m t

{

" }0 N+ X( D" v( q/ S5 l) d

m_DataModule->Login = false;

# ]8 q. _2 g$ a8 n ^& L6 Z

return S_FALSE;

- _5 [$ g( C- `+ j6 t" w) N {9 J

}

& v! V/ L7 s* V7 H- q

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

4 m1 s/ U. ~; z

bool __fastcall TLoginServer::IsLogin(OleVariant &OwnerData)

( e- C$ N* Z7 b1 N( E: V/ h, o9 T, Z

{

8 B3 a |9 x( W3 ]5 @) Y: u

return FLogin;

, g% h! o, U# I0 y! H

}

" N- L; R8 K+ V8 {/ b

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

$ I" M$ V) l, l* j) s+ L3 l+ a

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

$ y U) r& T9 c# |, s' H9 e) @, w

$ O( x7 s! L% F6 c" x/ N$ h( m

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

5 H$ _/ n! G1 f" l

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

( P& [" @* w4 r" n' Q' n

ILoginServerDisp dispLoginServer = (ILoginServer *)dispAppServer;

4 f2 v, a. A0 e* A2 O' E6 d V8 B" A

dispLoginServer.Login();

* Z% W: W3 N `- N8 q q% }

DM->cdsAnimals->Open();

. T1 P/ U' {" {- z) T7 t) g

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

& E) _, o) _3 e& i

4 \& ~" {3 k! W1 }

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

7 B/ z1 A O6 _! r3 W1 {1 u! 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-4-20 16:55 , Processed in 0.424775 second(s), 52 queries .

回顶部