QQ登录

只需要一步,快速开始

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

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

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

823

主题

3

听众

4048

积分

我的地盘我做主

该用户从未签到

发帖功臣 元老勋章

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

0 s0 t8 x8 d$ g( p6 j: C% w

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

+ p o- |, @6 {9 _/ U9 B* G

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

+ x. O2 b2 ?; Z! O* ~

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

, G/ ?/ d; q* M

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

5 s, I$ D- p; o$ s& S/ G. x( g

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

4 Q% E, F( K( c8 Z% A( [1 Z+ @9 @6 f

2 {- w# J' o( t& \ O# `

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

* |" z4 z) F( T5 S# i& {. q

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

: O* t+ J& B( I5 J( W% I) m

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

0 f2 T3 b2 @0 D7 k3 s0 v# d

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

6 ?3 d2 i: N/ G! A- P

+ s" r I9 k; @+ V7 n6 X

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

5 R6 Z2 e) P7 E+ C

4 j3 ~8 i( b! I- H6 b

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

" O, N5 o8 u* G9 o) Z! d) \

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

( D- B" g; V$ `

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

6 T% q- x( G' x. V

interface ILoginServer: IAppServer

# ~: q) F6 j1 E; m( y4 v

{

* |; t8 y8 d. m' ?' O E

[

) g# F& {% H! g% {

id(0x00000001)

9 r0 N- ]4 K P0 W, i% @, |

]

6 j& m- \. h- s5 U6 t) S

HRESULT _stdcall Login( void );

: i7 {( }) Q# e) U% k, P- ^$ m- o

[

+ k* |* J$ z0 L2 }3 n! A

id(0x00000002)

, }' C" v. {' n

]

$ ~+ I; K+ s( z7 B \9 l: L

HRESULT _stdcall Logout( void );

8 J5 K+ u0 C5 {# H' n) z8 d4 W* Y

};

5 C+ T( o9 F/ V

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

# `& w7 U+ W0 V- f; h$ t' P

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

& { `2 z, U. L

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

+ [+ Z: o0 H7 U$ {' ?

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

/ \9 ~. R8 L7 }$ e3 }8 j+ @

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

0 J5 H: T- p7 t: r2 X2 o: K& Q. l3 Q

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

$ g. K* l' O3 t3 f+ n; w3 h& @

virtual HRESULT __safecall AS_GetRecords(const WideString: ProviderName, in

8 m- G1 Y9 P' R v' }6 n( ?

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

5 a) m6 e0 Y- u$ A% g- @- E

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

& ` r; G4 z3 b0 l: ?: h7 y

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

4 S$ T! _/ `' a. ^7 z

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

# w8 k* W) J" P, A4 t7 H2 w; P* t

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

! i2 _* T% A. e( ]2 y; Q

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

$ h z/ g0 x8 W& G0 ~

class TLoginServer : public TCRemoteDataModule

3 }* P' m( K$ p1 p. H

{

' v9 k2 g; i) V' a2 E

...

l. Q; x0 P* D" H+ m2 ^9 t! b& t

private: // User declarations

4 z/ y# h, \1 o& O! p4 u

bool FLogin;

' U( A5 I4 Y% M/ _2 g( v

void __fastcall SetLogin(bool value);

% x% o: a! } U3 L# p8 v

bool __fastcall IsLogin(OleVariant &OwnerData);

1 Q t- |6 W: c8 }9 X

...

' B" e+ ^5 d2 k8 e; R6 ~* b

__published:

* ]- R( Z; b7 O$ i+ X7 O

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

1 I3 T9 p0 A. @0 P

};

; L" k0 O6 h- Q( r8 S

在RDM实现类中

9 F2 h: Y6 \* f7 k9 [( @# {

class ATL_NO_VTABLE TLoginServerImpl: 。。。

* V) Q# p5 n9 u+ @ ]/ n/ M+ g

{

0 C6 j- L+ k! u' D I

// ILoginServer

c( z5 D) \) |$ e1 t

protected:

5 A5 g9 S' O- S# v* n" x9 m

STDMETHOD(Login());

' h. `# b: f8 l; a+ k) C$ ?5 T& `2 V

STDMETHOD(Logout());

% l/ I. U' M$ p O$ y c" }

};

' g' L5 j3 u4 a: [( s3 E a! Q

然后简单实现之

* r4 U& I2 u. I$ r( O

__fastcall TLoginServer::TLoginServer(TComponent* Owner)

# @- h% d2 X: v4 h. v9 ^1 R

: TCRemoteDataModule(Owner), FLogin(false)

2 u- Z0 E1 }" ?

{

- i0 }/ s, J" a1 S0 N8 K

}

. z) b+ }) c3 n- X! n% q+ I' q

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

: _0 e7 j3 b! g2 u, }7 H# k

void __fastcall TLoginServer::SetLogin(bool value)

9 \- n T: k. `

{

1 N3 l p! d$ M8 L1 v

if(FLogin != value)

+ y$ V7 @3 o: n' V2 h

{

- z1 p, r9 n/ C% ]: Z6 i6 ?+ V

FLogin = value;

( S; r7 N' n; Q2 t0 s, t. B5 K4 \

dspAnimals->Exported = FLogin;

+ m4 N. X; { E( X3 ]5 P

}

4 j+ N8 W5 H) L* H/ q

}

: V. q, Y+ r7 K; A5 L6 |# C

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

# B1 U" T1 d' o

STDMETHODIMP TLoginServerImpl:ogin()

: }: x4 b' w8 h1 S/ w

{

) |1 R$ n- r3 D6 V7 p

m_DataModule->Login = true;

+ T7 w t# q8 t. h0 d7 \& O

return S_OK;

- J5 z. u: b: `5 W/ _, Z- x) b

}

/ c+ h/ v$ B$ @4 \5 x8 d2 H$ L {4 b

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

o, n9 n0 `( t' Z0 c: \" t

STDMETHODIMP TLoginServerImpl:ogout()

# Q" l7 ]% c/ X

{

5 P4 Q0 K F8 B' Z) Z8 ]7 C

m_DataModule->Login = false;

+ y& G0 Y" A7 T; _

return S_FALSE;

I# M+ g+ O% L- x

}

+ z! c! A* O; ~! O2 l- o

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

) h# L" L% G# H9 r& U0 p

bool __fastcall TLoginServer::IsLogin(OleVariant &OwnerData)

4 L! |5 _: P) v c, k

{

; {5 y" N6 i- l) E

return FLogin;

* R% c: k2 K9 `, e

}

H* J* G3 { }! k; x. N

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

4 G) z3 E9 g% p, R% R' g9 z

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

& T4 w2 `2 z8 V; l

/ N# d" i* Y' \

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

& a3 @/ P6 j" K8 d- F1 c0 Z

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

; a8 O) ^! ]* } @6 J

ILoginServerDisp dispLoginServer = (ILoginServer *)dispAppServer;

, E) W# K( v5 U) |1 m

dispLoginServer.Login();

0 j+ B' \( E& g+ x. m& j

DM->cdsAnimals->Open();

+ W& G) m& Z# A

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

8 _" W5 ?! e- U* D8 y) W& y

1 h/ a% l: _! i- u4 K" i- _

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

% ~, Y# W% q* ?& S- c: L

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

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-18 10:41 , Processed in 0.393360 second(s), 52 queries .

回顶部