QQ登录

只需要一步,快速开始

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

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

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

823

主题

3

听众

4048

积分

我的地盘我做主

该用户从未签到

发帖功臣 元老勋章

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

; O( e% {( ?1 |% y% m6 o& a* e9 {

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

1 R8 K! U# h+ ~2 B3 R0 X

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

3 b) V, H& t& G( z# l) q5 U/ a1 T

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

2 }% y4 e) |$ l( f' X% q

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

* y+ N3 q# u5 n$ b

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

7 B* ~" Q2 A8 j* F

: [3 W. F" f5 y1 z* w

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

) b& G# @4 o& a. v$ d7 u8 g

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

' X+ a" q0 b( o6 }. L; l$ Z5 T

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

' X5 N. g, I1 s" O

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

; w4 T5 D, f" p; [

2 H9 s, O9 }9 ^+ H1 V8 n

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

) N x) |1 x: q# q

- F9 ]* W$ n$ v2 v6 }

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

; o3 _4 _. b% C8 ~+ ?7 a- g

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

y& r& D( Z( R- w& |2 H3 m- t

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

4 I. ?9 K3 |$ r* M$ }# D

interface ILoginServer: IAppServer

, q6 q: ?$ q# Q$ T5 L4 R! ^

{

; h& H9 G" k; |& v

[

1 C7 o# e7 e. {- ]) B; _) J

id(0x00000001)

+ g( x, Q, J4 w7 |1 r: D1 g) V4 ~* h

]

& {. G; r9 i7 ?2 X- h9 `

HRESULT _stdcall Login( void );

7 k" `3 u4 }! N) V/ |$ f

[

6 ^* h& {% L l

id(0x00000002)

/ s% e. ]) n' D) |: b

]

, d" T8 q3 W8 {. O

HRESULT _stdcall Logout( void );

. ~8 `/ S- z) f

};

0 |( l% r( H6 J

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

( S9 b; f% V9 O

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

0 J+ g3 v' S# d" B/ K% W1 S

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

' k+ }9 }0 {( m6 o$ b

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

% O" H# Y7 ]. u7 L3 w

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

7 R7 [/ V+ M" u' n B. I

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

! x% |: k. d! D' ^$ b* z3 Z9 i: p

virtual HRESULT __safecall AS_GetRecords(const WideString: ProviderName, in

+ h% o8 P" I0 w9 B9 O3 M* E

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

' g9 V! d6 Z1 L Z0 O3 X- b K

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

; f/ g! H) Y/ l' b

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

- V4 ^$ u4 }) B7 A+ j

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

y$ t+ R" Y+ l% ]4 Z

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

1 @! C4 H, K) L0 @. e

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

& t8 f, X7 W+ ^' Y

class TLoginServer : public TCRemoteDataModule

7 E0 t$ p _7 R' k& x+ K- t+ T# y6 w

{

8 e4 h0 u$ v. Z$ Y

...

/ j; s- j# t' K. _) M6 Q, C

private: // User declarations

0 v H8 i" V3 U% E/ b2 N( Z7 g! q

bool FLogin;

9 T+ _3 [5 s. S; _

void __fastcall SetLogin(bool value);

3 ?$ d2 N8 Z6 \$ r

bool __fastcall IsLogin(OleVariant &OwnerData);

, w" q: V4 |6 K" y6 w

...

2 r8 t" I. A0 o( U5 @ T2 D

__published:

* q: ~9 R6 e& B

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

" b- F7 \% U8 y8 u' I+ V

};

7 T, B; Z" f: e( S

在RDM实现类中

4 O; [! Q+ e9 i+ G7 }

class ATL_NO_VTABLE TLoginServerImpl: 。。。

6 A4 h( P3 L& F

{

! T: p: B; J! H

// ILoginServer

/ b3 w( ]1 G& v& y/ v9 x# c

protected:

$ i" E. M# ?: X

STDMETHOD(Login());

h& [) D: e- J) [

STDMETHOD(Logout());

- D5 K: K* h& m5 H# |& k

};

- |. [6 T! V$ H0 J% N/ y4 c

然后简单实现之

- p2 d* `1 T/ q6 C

__fastcall TLoginServer::TLoginServer(TComponent* Owner)

5 L& @1 [, j* S+ _) m

: TCRemoteDataModule(Owner), FLogin(false)

$ p% `* A: i2 Q6 U6 m& C" f

{

0 f. ^2 p+ _: ?& g3 m, ^

}

. y/ k" V5 D% ?$ S. S2 T6 h

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

; `" G8 _, n* J0 q$ \' v( g

void __fastcall TLoginServer::SetLogin(bool value)

" e4 O! l+ s) j& N9 f

{

- T" y, q/ D: W) |6 ^

if(FLogin != value)

x. `4 Q x. a# T

{

; I5 H- ?$ S$ G s3 o' |8 Q% f+ Q/ O

FLogin = value;

, m$ n; k0 ^/ f B) r2 A- l; R

dspAnimals->Exported = FLogin;

$ q; U+ j" x) `9 S8 A! ?4 x- x% c( g. ]

}

% E( z. g5 S1 ~3 F4 Z ~

}

9 H- ]; E2 `5 Y) D/ ^+ G$ L. j! D+ Z

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

9 i1 W0 ?) ^) M# B' c

STDMETHODIMP TLoginServerImpl:ogin()

. W2 i* W& G1 d' }2 L& i+ z

{

+ B# j- H9 D9 I

m_DataModule->Login = true;

8 Y1 b: }9 \6 b) d0 C J

return S_OK;

8 n8 A$ v1 @& J

}

/ G4 m% k# v9 b q& Q. j

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

8 x M9 x `# P3 x: n* q/ ~5 [

STDMETHODIMP TLoginServerImpl:ogout()

8 `. i+ f3 y4 ]3 j# ^. Z( n9 [

{

- Z1 [. l j4 n* B Y

m_DataModule->Login = false;

( _' C6 ~$ R. ^: {

return S_FALSE;

# Q' C. @( |/ L( X- S+ ?% U

}

0 y1 M9 A$ b2 q

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

$ |: j8 u* w. \

bool __fastcall TLoginServer::IsLogin(OleVariant &OwnerData)

0 A/ \1 R. ~& H! p

{

' Q3 \% s! @7 y: h4 I1 G

return FLogin;

* b$ ?# G; |! p& l( R

}

/ u) Z7 I4 w9 @0 V, x! P

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

9 `+ s+ C) t4 {7 N

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

) N! U1 Q; T6 h: o A& R/ X

1 ?# _9 l. |+ ?. t* Z- t a

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

7 J) Q& ]7 U. \9 f# V# K% Q

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

6 G0 S/ x2 A' Q! U

ILoginServerDisp dispLoginServer = (ILoginServer *)dispAppServer;

$ @" u/ n4 y: a' ]' f& I3 W( q" i

dispLoginServer.Login();

; J7 J8 X- [9 D% @' P0 z" f9 `

DM->cdsAnimals->Open();

5 p! G& i$ o2 j8 c" \. q, v

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

3 M& Q$ G2 I- `7 z3 s. n/ Q3 L

1 u9 a# c% g# k* t- u! o

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

: p( w8 ^" a' i) L& [/ c" {, |

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

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-8-13 08:58 , Processed in 0.390890 second(s), 51 queries .

回顶部