QQ登录

只需要一步,快速开始

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

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

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

823

主题

3

听众

4048

积分

我的地盘我做主

该用户从未签到

发帖功臣 元老勋章

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

$ G) }* T! d8 | B( N. B" H# @

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

4 Y* G2 A' j a& o2 l

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

0 w1 C* d7 o; p3 l3 f6 h

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

! v8 U8 E8 R; _% x

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

* Y; i6 y9 W" j1 n

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

) [% T7 D/ f6 K5 n) V* T( V

3 @; s k- L2 |& Z7 S0 R, ^1 t

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

3 d b+ p5 }/ y6 b* t8 v8 a

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

' i8 b6 g' K$ X' W. O: @! a& @

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

0 W0 F: r9 |0 W9 ? m( j) W

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

. |2 U' n4 B5 W

l: L# _) g( o9 a! j* x' B

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

& T( i6 I0 }5 }. {; e! V

2 f! X- ]: j6 V5 Z

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

+ m5 u' W7 \5 _9 F, I" c% l! `

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

4 @0 W" R% I- O2 v' a2 {! L' x* ]

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

& h2 R7 V0 f6 H

interface ILoginServer: IAppServer

2 @3 b7 [2 Q! I- m( h3 x8 R9 o M

{

: o# J9 K) @5 q" u; K- p

[

8 `1 T/ p# z3 `! P( _* Z; c- Y

id(0x00000001)

9 m3 F# O* D% f, _: s% y0 y, ^

]

( ~1 z$ V4 @, V+ B

HRESULT _stdcall Login( void );

$ Q0 `8 k) D# v2 d

[

' S6 Z) L* W X& `( v9 {

id(0x00000002)

; R% \, x7 Q( m* T! f! M9 T' [6 o

]

6 @( H7 c: N& i% m* ^* y9 m

HRESULT _stdcall Logout( void );

2 e# z* [: h1 x/ R; M) |+ t; N" m6 a

};

: x% M: J# i0 d2 J

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

C5 ~! L# t4 o, v) M, }

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

. E U+ V p* W

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

8 W; e9 f0 k, j, @3 V8 t

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

7 D$ U; g' H6 ]

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

% c) V4 b; r2 ?! B8 w! O

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

+ |. ?' T j7 a9 o. o: ]

virtual HRESULT __safecall AS_GetRecords(const WideString: ProviderName, in

) ^0 m5 q( L% J% m: C9 O

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

5 u, G, l" @/ C6 M

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

7 \# b9 U5 s* v% V; }( s4 V. e

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

2 W/ n$ s. _: Z# \6 h' k2 M

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

1 r: v- H8 z6 ]+ [7 h2 E

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

6 u8 B4 i6 ?/ K# o0 m6 l

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

6 c2 H6 N* Z& }, F3 p0 ?

class TLoginServer : public TCRemoteDataModule

0 x: o8 U& U( s& \8 X

{

6 d) \9 Z# T, u2 S0 Z* V

...

! O) D4 o. }1 ^8 J" i8 C

private: // User declarations

7 h$ B1 s( b2 u ^* T8 ^+ ? o

bool FLogin;

6 }$ f( [! F t, b& `2 T* Q

void __fastcall SetLogin(bool value);

! x5 q, O' k- @

bool __fastcall IsLogin(OleVariant &OwnerData);

2 e' B. y3 T) N9 w

...

6 H1 z7 C$ ]' z/ ]6 [9 v

__published:

/ x" l3 P, R9 |6 ?! I: @3 E& o

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

+ ~" r$ W" v% `

};

* {' ] c9 P4 `

在RDM实现类中

( ]4 g- ?) m+ y- U% y7 g0 o# e) i

class ATL_NO_VTABLE TLoginServerImpl: 。。。

8 f2 O* z% }' @1 Z8 |5 H, Y) _4 B( f

{

9 y; b1 }; U1 F9 m1 P, [& y) I; U

// ILoginServer

: r( }! N- @) ^

protected:

3 L4 P% F) z% F

STDMETHOD(Login());

; X' E8 W2 Y: ]: {3 K: ^. R

STDMETHOD(Logout());

8 a2 |1 M9 J* J Z4 s. x9 q

};

: k8 Y5 S2 y& S. p8 R- G

然后简单实现之

; j& {/ T7 x3 k' c" F5 U: o6 J

__fastcall TLoginServer::TLoginServer(TComponent* Owner)

& d5 C% k" X5 R x- W3 ^

: TCRemoteDataModule(Owner), FLogin(false)

+ @8 `) h2 N, v4 `6 _

{

8 m* d4 \( h6 U& x: I) G2 `

}

3 O9 S# e: l, k# Z( h% X, }

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

& w0 k# ^$ v9 E

void __fastcall TLoginServer::SetLogin(bool value)

0 l7 }1 w9 `" n

{

& u0 v( l+ A4 f/ S, v; }" e

if(FLogin != value)

9 ^# f* l) B8 B; ]

{

8 z/ t% q) C. `7 x, l! t

FLogin = value;

5 O/ Q3 D+ d7 X! m* u" s; V

dspAnimals->Exported = FLogin;

8 W _9 |8 a( |, o. q

}

0 ~2 J& L$ q$ {& S! l, C4 Q

}

% L+ V/ {5 d2 x* g* T

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

$ _1 q; ?9 p4 U. ^6 I: f0 J& s2 T! u

STDMETHODIMP TLoginServerImpl:ogin()

2 q/ w5 z2 o4 L$ S3 M1 V5 ^

{

% |- L; Y0 H7 N3 X5 `$ Z b1 q

m_DataModule->Login = true;

% d3 P+ j2 v. [2 h; o

return S_OK;

, ` z6 J/ [4 E1 P' \: u3 Z+ |. s- ]" Z

}

/ G+ X; {" A7 J/ s

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

7 b7 O! U8 z/ J/ P

STDMETHODIMP TLoginServerImpl:ogout()

8 l, x6 q7 O: G- f

{

1 S# i u1 O2 K! F8 L/ D& g. q

m_DataModule->Login = false;

8 h% H/ X: D$ j \ X1 d

return S_FALSE;

$ @$ B2 X$ a+ o+ z2 s6 K

}

1 o* j, e8 ^1 q. G9 ~+ j# L1 L- h# M

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

* p* k5 d. Y+ f4 E3 v: s( O% \

bool __fastcall TLoginServer::IsLogin(OleVariant &OwnerData)

9 F9 j! R, T& v: b/ c$ f

{

) a! q U7 ^5 E9 I4 ], B. C

return FLogin;

2 e0 M$ x8 b, N/ L$ M

}

8 ^% g. w/ _% j3 |5 h

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

) p5 W8 M3 C, S' _9 u+ I4 C

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

8 B* ^/ P% J+ p$ S; _

+ t( i3 l! s% H

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

8 |0 F! T/ w$ Z8 v5 I0 {# w9 s2 E0 B

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

6 g* z1 \& k o) G4 ]0 H8 _7 ?

ILoginServerDisp dispLoginServer = (ILoginServer *)dispAppServer;

! D. [$ j y b) o

dispLoginServer.Login();

V `) h) \( w$ {

DM->cdsAnimals->Open();

1 c0 _ E! V$ v- ]

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

9 n5 \( k, o+ ~ M

# r6 }) @$ O3 h' ^0 \

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

9 H! z8 g& s/ W+ o+ 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 09:21 , Processed in 0.424844 second(s), 52 queries .

回顶部