QQ登录

只需要一步,快速开始

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

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

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

823

主题

3

听众

4048

积分

我的地盘我做主

该用户从未签到

发帖功臣 元老勋章

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

) b. a/ }7 s/ ] V; b) X

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

) a+ h% T, m; I' L; p0 s, H7 w e

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

% [) ^7 ~& }& [& [

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

- [2 ?0 B' D8 t/ \

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

- l7 l6 I% `0 Y. x

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

/ ^( G; J* g0 q. S. ]

" H, |! Z) |/ Q+ c7 J8 X

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

6 L* F) j5 a5 H

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

1 |! s' d d: A" w

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

* F! q+ Y; X% ]$ J% E

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

7 d4 n% {/ d# {8 h. F; x

3 s+ _, {5 N: g! F. K9 H+ c; p2 l

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

! q. P. U# m" F

6 C9 @! M( h8 _1 ^$ ~% {

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

. H, t! X$ W1 R& @

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

3 c7 r$ S' i$ W* J5 t" g" L. t

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

7 Q# g& H1 ? B

interface ILoginServer: IAppServer

% Y7 g1 I+ i1 l! z* l4 N

{

* S3 P' s* q" n. F4 y+ \ @

[

' ^* y# \- v; Q2 i5 w' c

id(0x00000001)

2 w; e! T0 E. d7 ], F+ J

]

6 b G( z2 S) W. h* n) o5 E

HRESULT _stdcall Login( void );

8 \' [7 L& `5 L {5 i w2 |9 x; c

[

. f4 Z4 A2 T8 x H9 f8 z2 J7 A

id(0x00000002)

0 M- _' G7 w7 N5 J

]

7 g0 i5 s+ I9 N+ q4 z

HRESULT _stdcall Logout( void );

, K' E9 Y" x7 N

};

9 h" L% U v9 b7 w. Y! W

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

8 i9 R( b* N. Y# g) J% r- G

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

\" E: n& B8 b" u6 g! j

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

, n" b0 p4 N+ m4 h* Y- }: w

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

) N. ~. Z6 b/ U

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

, p5 g5 A7 _- V8 z2 d% \2 A

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

: [' A5 r6 E7 [) A- V

virtual HRESULT __safecall AS_GetRecords(const WideString: ProviderName, in

5 K- X2 E) ^1 P8 T+ {1 n- l

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

9 }: s1 u* I) u5 G& a; g' f

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

& w" N9 W& [0 ]

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

5 K6 s2 V1 C9 n. K% [

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

) ], z& x6 T v% x

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

1 D1 ]3 g8 ?# |: w8 k9 Q: f& h

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

" P6 {( K% @1 T. T( {7 p9 o% T

class TLoginServer : public TCRemoteDataModule

; [: Y. A% Z" u: m& r# ^4 o

{

- c' @' v9 H! J+ {" @" s

...

0 `: d9 b' G4 v6 v5 @$ c

private: // User declarations

3 B: x1 @+ U+ S/ ~6 n

bool FLogin;

# p9 |& K) ^+ k

void __fastcall SetLogin(bool value);

3 u9 f& v2 }; B0 I4 j U

bool __fastcall IsLogin(OleVariant &OwnerData);

& \" w& |& h( }. q) P% N

...

* Q/ p! y- I5 [9 m1 a, q9 |2 }$ \

__published:

4 O' R! |. W6 j9 h

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

0 y3 u* s. r" {( [; k5 K0 A T

};

- P/ B6 b& r' i4 e

在RDM实现类中

) y, @$ h8 C- e/ o; ?3 O9 {2 S4 d

class ATL_NO_VTABLE TLoginServerImpl: 。。。

2 l9 e' v& h$ a

{

$ p$ U3 q, }1 J/ L' D

// ILoginServer

- n+ V- N! h% i! e$ \2 e* X; _% M4 }

protected:

. n& i+ G% e& G% y, @- a) e

STDMETHOD(Login());

. H$ E9 e% q" W

STDMETHOD(Logout());

4 u) ~2 ]4 {) g

};

6 w2 w4 b+ r6 N

然后简单实现之

% t2 h% d: I6 C( k

__fastcall TLoginServer::TLoginServer(TComponent* Owner)

& u, t2 Q: V! F/ ^$ N9 L, p

: TCRemoteDataModule(Owner), FLogin(false)

, z; I7 E4 B& |; H9 |

{

& I3 t4 B' F* \6 g

}

; ?/ ?: h9 w3 h) r3 ?1 Z8 \0 {& S5 X

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

6 b5 Z1 L- M, p! [

void __fastcall TLoginServer::SetLogin(bool value)

3 r+ K ?" B! }( F4 {

{

- v% M5 D2 D' o# W! Q: [8 ^# |8 g

if(FLogin != value)

$ J& K7 n) }1 C

{

' u( e( G) r6 X) ]; b# R

FLogin = value;

7 E$ N% _0 v1 e- ~: p

dspAnimals->Exported = FLogin;

2 h. w6 ]8 ?9 l) K; H

}

: f) }9 B4 ]( H5 v; a8 Y

}

+ i. n2 ^3 p- ^8 h1 f

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

4 n/ h, L! A( O, p+ R

STDMETHODIMP TLoginServerImpl:ogin()

0 o0 r, }0 C+ U4 d" u J

{

+ r( P: k& |) d4 K

m_DataModule->Login = true;

, A# C* O5 @1 C

return S_OK;

) a9 S1 X d1 S

}

7 v3 I5 w+ S# P6 i6 U

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

/ N! Z) {7 ^$ p' c8 a% f

STDMETHODIMP TLoginServerImpl:ogout()

4 y% p' ^$ P* v* p! T

{

, m& h! L- r4 a, n

m_DataModule->Login = false;

8 N1 U3 g/ q$ _& J

return S_FALSE;

, k( g9 j0 j! R

}

4 C% w7 N& J* D" {* U# ^

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

% M: u# {+ z; S7 t4 Q" q

bool __fastcall TLoginServer::IsLogin(OleVariant &OwnerData)

0 e$ p, K- A8 J* w9 \- n e9 L

{

; ?* J/ i3 M8 Z9 b; }$ W7 `9 j# z) K* k9 p

return FLogin;

% P. y0 Y% q+ W1 k6 G& I" R# i+ c

}

1 R" f5 |5 G! B$ o% g

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

% `8 J z2 w7 b) d

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

. e. p$ k" a) {# q- t4 f; R( @ @

2 l4 E$ ~$ ?5 i: E7 r3 \

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

5 q% }/ V. j1 r6 z. ?( s) }; W1 l5 r

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

( g' b4 ]6 ]5 U) v6 C5 _* e! ?

ILoginServerDisp dispLoginServer = (ILoginServer *)dispAppServer;

; F# N' k. i' C0 c

dispLoginServer.Login();

5 Z4 z0 Q ?2 j1 o1 f6 C% M: I; z

DM->cdsAnimals->Open();

, {7 t- v7 W$ f u& f7 X2 I. z

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

; C" p9 p- _. s) ]4 e

1 L+ S# E5 }" O$ q4 E/ N7 G! A. V

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

2 H1 A4 I: U5 y4 K+ O/ F$ m0 O6 W$ [, ]

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

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 12:08 , Processed in 0.317341 second(s), 52 queries .

回顶部