QQ登录

只需要一步,快速开始

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

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

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

823

主题

3

听众

4048

积分

我的地盘我做主

该用户从未签到

发帖功臣 元老勋章

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

8 y' n7 t& _* F. ~+ h/ U. u+ D

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

; @1 ]- _: b4 E: _

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

6 t" ^! x, M+ U$ o6 a

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

" j$ i+ Z) A( n$ G' Z

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

% o& a; W; S8 q9 w5 x

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

: D; s8 Z/ y; Q; \; U

3 v+ ^" ~; W C: ^. g5 w% t" |: T

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

2 r& U* _& z# h3 Z w# z

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

8 f! K/ R0 L9 ~' y

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

9 B4 p. x' R: T5 T

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

4 V4 K9 ]4 u! e R5 [; O7 U4 D

5 Y ]2 W4 m" H: h% C/ `) ^; L

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

8 f2 U2 R$ ?6 c* |% ?9 K; }

" v4 i- t0 p2 I: v" C0 c1 M

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

1 N) q1 t) f' y/ F: X" ~

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

+ |) }$ @- q7 Y: I

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

5 R& E" ^3 c, E/ v

interface ILoginServer: IAppServer

0 P6 Q6 t+ M Z+ I+ d0 X

{

, [) B3 N( Y( s3 {+ N$ k. `9 E

[

+ {/ a' W. W! w# P& [

id(0x00000001)

, m/ y6 O( a0 G! c/ } O/ ~4 V

]

; o9 x- d* C5 @+ a1 [: b

HRESULT _stdcall Login( void );

% G h+ |) V, C

[

- h: A8 x0 z. t

id(0x00000002)

5 ?- d3 S8 k. Q2 F

]

H& R" p* ?, l: ~7 d; @$ E9 T

HRESULT _stdcall Logout( void );

; ?# l' a0 j4 B

};

& n8 f2 V1 r$ T: n3 A/ O

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

4 N" P; d! V. s7 d8 c' N+ G6 w$ k* q: z6 q

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

2 k: _" {1 T% q6 R& H/ I( j0 [

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

2 S+ X2 Z7 k. C: m

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

" q' _8 c) ~, M

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

/ o6 `' o( ?+ U1 N3 n4 e

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

9 Q* e+ P7 B6 n+ H3 ]1 u, m9 R

virtual HRESULT __safecall AS_GetRecords(const WideString: ProviderName, in

+ l" A* D3 ]( ]% {

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

( w( S1 }" h6 N) C

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

( x! }; L2 ]3 v+ E! f$ D

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

u% U/ b+ h0 B( v

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

) s1 U7 Y5 }0 \& E, ?( Y t5 P3 {

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

5 y3 C2 _9 P7 r( R

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

2 ?" \3 z8 w0 Z* ]9 V

class TLoginServer : public TCRemoteDataModule

) d: O/ J Z y

{

1 _( q! V3 n2 w& W: G, x" h, F

...

! o# u! J# ?3 s8 |8 y

private: // User declarations

* E' H2 M$ F7 c/ m/ ^/ h1 ?( p9 R

bool FLogin;

C- g0 n' \# h0 {$ P! B8 W) l' X

void __fastcall SetLogin(bool value);

: x. C* G% t) A- j1 o0 A/ l5 F' C

bool __fastcall IsLogin(OleVariant &OwnerData);

" }. x! A% M% q- Y8 j' v, a

...

H' X% j, g6 z, `

__published:

! d3 Z) X( D& @2 Z2 k

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

, O3 h+ {4 S# Z/ ?) t$ T! I

};

2 ]7 w- W0 V( X

在RDM实现类中

5 d6 h V) A0 k! T' T6 C) ^2 K( J

class ATL_NO_VTABLE TLoginServerImpl: 。。。

5 b5 M- l; k1 ]: a1 G

{

8 L4 F7 ?5 @1 U$ x; s W$ H8 Y7 V

// ILoginServer

1 s, H8 b1 |5 Q$ G

protected:

b" k( v6 A/ i1 b: W; B+ Z

STDMETHOD(Login());

" b0 }$ m4 ?( B! ?0 y9 e; ?+ R

STDMETHOD(Logout());

2 B. T2 @" ]& D4 M; s, V7 R

};

& K5 \( X6 o+ Z

然后简单实现之

5 ?& ~; r" V* t) `8 v7 P1 |

__fastcall TLoginServer::TLoginServer(TComponent* Owner)

: H) c$ j R/ m7 d

: TCRemoteDataModule(Owner), FLogin(false)

! R4 N7 k# C" s, E. G

{

2 Q7 H8 P, m5 K' c

}

, n( S% L6 D' h+ X

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

$ L. v& g" n3 c' K8 q

void __fastcall TLoginServer::SetLogin(bool value)

; e$ y% X8 ?5 e' j

{

1 y O( T% u3 A

if(FLogin != value)

7 T1 c9 Z: l. W# v- Y4 n

{

4 p& [9 i& |: F" J

FLogin = value;

+ [7 [! K5 P: Z' v/ I% {

dspAnimals->Exported = FLogin;

' \" F, S, q1 F% M

}

5 E9 t- F- i" p: A i" j+ x

}

& d: ]+ l9 [4 M

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

/ }" i/ F1 {; o

STDMETHODIMP TLoginServerImpl:ogin()

; G( `3 G: o' W; z

{

* A) {" v4 |# i# @

m_DataModule->Login = true;

+ [' D2 f) h/ P( H

return S_OK;

: ?/ p2 r! u) q x- E

}

* }7 I M' M5 Q6 ?- J

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

( k4 {- [9 M1 I

STDMETHODIMP TLoginServerImpl:ogout()

- x) x$ N, U" ?" J; n8 W

{

. e6 c& @! }! @; `7 G: i: V

m_DataModule->Login = false;

+ b5 g1 [3 w9 |* h( ^( a T6 A, Y

return S_FALSE;

+ ^: u- X. t' b6 q# l

}

, Q( s; o7 }# k( {: B/ I) I

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

& t4 N2 X( ]6 v( [/ N9 V$ W

bool __fastcall TLoginServer::IsLogin(OleVariant &OwnerData)

5 z$ C0 V/ g. [* b6 a+ c5 E# t0 v

{

8 Z2 P: [8 r/ P2 _5 i

return FLogin;

0 n1 s; g1 K- L% a* R- b0 n! n

}

6 k1 Z2 Q: T1 M+ B, E

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

% y: R; P5 {8 G9 a. K3 r

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

$ i$ W0 `. B" V. }* |; I

z [1 y; H2 w

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

5 U1 c# `5 b4 u

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

4 y+ {) ]" e) k8 V

ILoginServerDisp dispLoginServer = (ILoginServer *)dispAppServer;

3 Q% s+ @, r1 R

dispLoginServer.Login();

4 M2 }0 X4 c% x% h

DM->cdsAnimals->Open();

2 i- b: q1 a- ]4 {3 b: G; T

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

/ j4 X/ _! Y8 [

+ S- Z6 H8 y* a

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

) y! h' |( q1 _+ ~# e+ Z

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

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 14:29 , Processed in 0.371579 second(s), 52 queries .

回顶部