QQ登录

只需要一步,快速开始

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

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

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

823

主题

3

听众

4048

积分

我的地盘我做主

该用户从未签到

发帖功臣 元老勋章

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

$ X% l* i! ~1 @; @9 L

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

" F2 A: k4 b+ V: u$ _

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

( e( \7 z, u. ?0 S3 X

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

: H; Z$ h" r' \. B) E

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

# \% O! ~" i, z. G) Q

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

j1 @5 s4 q8 Y9 F5 s$ h5 I- d' I! L

- R: _) I, `+ u" ?# u. {5 ~- x; C* E

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

$ C) r$ x7 N; y" f( t+ L+ S w

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

) O4 D* [3 R& I, f

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

1 E% C! i# U3 V+ w$ x

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

3 K. q- ~+ q, |8 d

9 Q. E0 c* R @' u: A7 Q

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

3 s, d. L- Q4 B

: H2 p; L) S0 N; d+ h3 x$ S9 P

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

4 t. G" s, h" N8 M0 l; r

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

3 a( k+ s: ~! I" J: C

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

5 i1 s: v% |" g( {

interface ILoginServer: IAppServer

" C( W1 ?% L! ]& c% J, H( D

{

- Y6 g, @' @9 j5 j/ v: A% Q' V

[

, ~! ~2 |5 Y! V

id(0x00000001)

: F- j4 H0 k/ f" Q; H u

]

7 v+ q/ ~" k" A1 {

HRESULT _stdcall Login( void );

" D- {; ^/ [" S0 ?$ M0 D

[

: [7 m# U' J' l6 _

id(0x00000002)

! G% |4 S9 W3 E/ y

]

: | J- A- ]/ l- y( l2 u4 T

HRESULT _stdcall Logout( void );

5 d x5 k) L& s- A5 _2 k

};

, p2 h/ b/ V1 e; ]# ?: c6 L

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

! x" L3 y1 L3 s5 F- A* N

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

: s7 }8 a5 k' \% n/ N7 [

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

9 B$ X: i' J( f) o9 c

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

* e3 h5 X- \+ o- W0 ?2 ?

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

3 A0 t5 w0 s* K" k& m

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

+ p' W" w' ?8 g

virtual HRESULT __safecall AS_GetRecords(const WideString: ProviderName, in

; M& N( x# ]( W8 `: x1 ?

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

) T2 a+ C% N% Q$ K i" b. o% C2 F

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

2 c; O$ z- c& M9 @" [! J# ?

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

) w A/ [& r: i9 ^: _

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

+ m/ W! r& h% [* o* c( B6 _2 l+ Y U$ }

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

' t9 E) o6 J @) d! Z

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

& O; K# W( K" B! ] M) @! D

class TLoginServer : public TCRemoteDataModule

* I* I6 B8 ~1 s

{

6 @! K' [: B# H! ]! T) N

...

" K( t/ O4 k: D" Z

private: // User declarations

" K# E! a) ~0 j8 Y, p

bool FLogin;

6 q) X/ i0 I4 `+ u4 o7 i* k3 o( P

void __fastcall SetLogin(bool value);

( U& ]; p* e% r+ H" M

bool __fastcall IsLogin(OleVariant &OwnerData);

, ]! |; p8 `1 k5 v

...

2 \, ?& [) W. p; D/ J: O

__published:

7 U$ Z' @5 q4 N) z5 u: q

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

+ f9 l( A+ \- [

};

0 o {6 O8 I) U: @4 D

在RDM实现类中

1 y4 k; ~# R4 o/ n+ R

class ATL_NO_VTABLE TLoginServerImpl: 。。。

% m& j8 S% V R' d- P9 W7 B

{

1 q& l0 d6 L7 N8 G1 v

// ILoginServer

2 u% @; k8 K Y

protected:

$ N! O! G4 K9 r0 ?- v, y- s4 f

STDMETHOD(Login());

& E1 N: I( O) t

STDMETHOD(Logout());

" B8 \5 _& F% J; ?* ]

};

0 Y, [* ]* L. e$ T, m9 C

然后简单实现之

& E# I9 ~* \8 @- u

__fastcall TLoginServer::TLoginServer(TComponent* Owner)

; j4 o& i- j L" O3 s- k

: TCRemoteDataModule(Owner), FLogin(false)

2 I7 p3 m4 v. Y4 Z

{

( {9 ~) N" N K# Z$ k9 o |# B

}

* {5 b+ `7 g9 ^

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

. E' y, b: O' Y+ h+ } F

void __fastcall TLoginServer::SetLogin(bool value)

8 t" Q1 Q i: Q8 B' q

{

; f8 p+ s8 Y4 U$ Q+ y6 L6 x, t

if(FLogin != value)

2 W6 c0 r; O0 z8 s# {9 I e

{

! j7 v8 _ g2 I) P# G" @

FLogin = value;

/ X# J k9 I# @6 f% ?

dspAnimals->Exported = FLogin;

8 D3 m5 `+ `" K0 ]/ x

}

- U3 t3 w# ]0 \+ N4 A% P

}

/ r) O" k, t$ V+ u$ [

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

+ [: m! @4 o5 `* D. a2 ]8 ?# l; W

STDMETHODIMP TLoginServerImpl:ogin()

& @6 C" i0 E: x- f4 E5 W( e* \

{

X0 n, P3 x3 x7 T P

m_DataModule->Login = true;

! A2 v p+ q, ~3 e& B; Y. T

return S_OK;

" N- d, T" ?% i! u2 C: \* ]9 A. m

}

$ L' R# F; `7 v8 {( S9 P8 W

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

+ K8 u2 y" X' n$ ^

STDMETHODIMP TLoginServerImpl:ogout()

5 w1 v r9 N; f4 }( A

{

* Y/ U+ f' B6 T- \

m_DataModule->Login = false;

8 M4 ]" {5 X$ K0 d! Y9 c+ O

return S_FALSE;

2 q9 ?: @, W* f* D0 x

}

z& h, _7 U/ N r. o ?- e' w

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

9 J7 a& ~ t) Y( \3 A1 G

bool __fastcall TLoginServer::IsLogin(OleVariant &OwnerData)

. H6 h/ L; }3 T2 ^5 B) Y4 j

{

# b* w9 Q$ g1 Q/ Q! ?

return FLogin;

]6 I8 y2 K! p6 V% J

}

E( [6 ]0 a9 l1 ^

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

q- Z, p0 m+ E

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

* g7 E8 k) W1 v5 j: k

2 y: A2 {) Z2 r. J5 Y( Y

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

7 I2 G" A. X' w5 j# s

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

: P/ `3 I& K( U6 p* f8 z

ILoginServerDisp dispLoginServer = (ILoginServer *)dispAppServer;

0 e" c1 Q: O" \0 r, ^

dispLoginServer.Login();

1 b7 Z! F' D, n+ g u" s6 i: M

DM->cdsAnimals->Open();

8 s$ l. i$ y& D8 d

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

, _, c. l1 g0 |- L! v; G

1 o" a" h7 r; g P; D+ V

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

. ]7 ^0 a, @3 a0 M) N: r

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

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-13 02:52 , Processed in 0.337004 second(s), 52 queries .

回顶部