QQ登录

只需要一步,快速开始

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

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

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

823

主题

3

听众

4048

积分

我的地盘我做主

该用户从未签到

发帖功臣 元老勋章

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

* _3 Z( q. s, M" U9 _

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

! d3 P# {; }3 ^) ]2 r# H) J

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

" q7 n) I/ K" Y7 m

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

w) v# d6 X5 V6 l: k* L

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

% z! R4 ^+ k2 [; c7 k6 w; Z. l2 T2 H

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

0 a2 A: @3 P# Z5 _5 N) V6 i

# S1 C" g! J: r

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

' |1 Z) n$ T7 L

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

2 g) R. \+ l }: T' U" }6 F% b/ ~7 i

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

# [/ z6 `3 P" v

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

" U+ }6 d2 ^5 E+ N1 d$ V

4 B7 R! u4 H- ^* C2 h

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

; U. U- H H8 o6 N7 ]( i& H9 H

0 a7 a+ k, Z d, g

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

" L. G5 u, j: S5 G& P

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

" w% D5 | I" ?

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

$ ]3 l! m" m7 O- K9 ^

interface ILoginServer: IAppServer

& d7 i6 L8 Y9 S; o4 c

{

" O; E7 b1 h% L6 S) \

[

4 H+ a! T: i2 ]' b

id(0x00000001)

4 \) I6 R4 g P; e3 o: G0 L$ a

]

, Z& }/ m3 B3 Y6 n: M1 z' L

HRESULT _stdcall Login( void );

4 ]% r! m% E1 n! g

[

* o8 v2 C9 ^& \2 {6 `- x4 p# ]6 f

id(0x00000002)

; S! l f: R! z/ T. b i2 H

]

- q, y+ q; m$ ~, S: ?& K+ U0 v3 i, m

HRESULT _stdcall Logout( void );

; }9 _# S: m; \( Y& K

};

$ `$ x6 ]+ d+ H$ w

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

/ A- \( {! M1 |( r; C1 F

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

$ }0 f( @, Y( F% k4 E

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

" d' R# ~ e0 ?$ o2 c

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

6 z% I. N$ ^1 m) ?9 [; j$ K

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

) c" x L# ^1 x$ r6 ]" i5 l) t$ [$ ?

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

) M5 I' o# E3 u1 i9 u

virtual HRESULT __safecall AS_GetRecords(const WideString: ProviderName, in

; R4 C g5 K! v9 N$ `/ l

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

) s- T4 t8 ?% N2 v

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

! R1 y1 Y8 E* G+ v5 Z- ]5 i

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

9 y7 l N; l7 l& s( ?

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

( ^. Y$ }; Y3 y2 a1 P1 s

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

' G: i6 ?0 r ^5 e

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

; T; ]: y$ _/ C& k+ [

class TLoginServer : public TCRemoteDataModule

' k5 X+ K5 k' J$ v

{

9 @9 ^8 K. W: p X

...

5 t+ O7 [7 q" C3 @2 f3 _4 R

private: // User declarations

9 A! x4 D2 m5 U: `/ z5 j5 V

bool FLogin;

$ p1 ?2 B" C B

void __fastcall SetLogin(bool value);

6 V8 O7 m: `6 P' E8 J$ X! p9 K

bool __fastcall IsLogin(OleVariant &OwnerData);

) \5 F9 C+ ]! ~7 M3 k) | n

...

: K& b( L/ j3 W7 D4 |

__published:

* A+ l0 Z! q7 x1 X! Z! V1 M

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

2 P( Q8 f# x& b2 r! r

};

4 O3 K2 l4 G4 p3 c

在RDM实现类中

/ R# ?! v% R) ? U+ k6 v C! g

class ATL_NO_VTABLE TLoginServerImpl: 。。。

3 n, q% h) t# e! [

{

6 h3 {1 G0 o. {6 P

// ILoginServer

/ r& x% v: Z5 m( ]5 o( @9 q; v+ L8 M

protected:

- s/ X; i2 F0 f9 g% S

STDMETHOD(Login());

! E8 G' O4 d# r( a" x! R9 q

STDMETHOD(Logout());

4 a3 U1 n x! o1 t+ a$ q- d, w9 `

};

0 t- Y& i a% v: Y

然后简单实现之

5 k. C, @; w$ T9 i

__fastcall TLoginServer::TLoginServer(TComponent* Owner)

+ N# \, u0 m; F" J+ @

: TCRemoteDataModule(Owner), FLogin(false)

! `- N1 s. v7 }0 Z3 {5 v/ A

{

/ t8 n0 m+ E2 }8 N

}

8 b4 T; o; H& N$ Q- }0 {" W+ u

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

D& c. F- x. p ^

void __fastcall TLoginServer::SetLogin(bool value)

8 u: h* o% E, P1 i

{

1 ?2 e* N" v2 I1 n/ ?( ]4 g" {! C

if(FLogin != value)

0 D j# f3 T' @5 \4 Y1 N; L. V

{

' S% k; i3 v) `5 A

FLogin = value;

! ^) ^0 @, r+ |# ?! x* C4 q

dspAnimals->Exported = FLogin;

4 @9 k/ M) Z7 u& b

}

* j4 o V3 X0 E& v0 U

}

- d% V; ?9 s5 J3 o

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

# ^# ?# h/ |! Y, O

STDMETHODIMP TLoginServerImpl:ogin()

, u( | l* B3 n

{

* w0 w7 T8 O i( t P

m_DataModule->Login = true;

# T: o8 s8 Y9 u5 L( q% H. ]

return S_OK;

2 J* q- u! O0 C5 F" y; p$ M8 ^

}

1 p0 q5 X& o7 z6 D; t

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

+ R6 L7 R6 n& A/ y1 Q. G

STDMETHODIMP TLoginServerImpl:ogout()

; s" T/ |2 |" L. h/ k

{

) y; b. w: L: R

m_DataModule->Login = false;

! X4 E& u0 h$ m* p, L) U

return S_FALSE;

. s( e8 U; ^% P7 I+ F9 D

}

$ z& f3 p% y& v8 d- E

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

( u- G- a! e* y1 V8 t# X

bool __fastcall TLoginServer::IsLogin(OleVariant &OwnerData)

6 x# {: R1 r3 o! C

{

, r3 ^6 p* `* s5 l5 t5 D6 t4 Q

return FLogin;

4 V; l m9 {9 k& \7 }$ n( I

}

+ u, n0 I9 N$ u8 ~

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

) O( T: N4 r0 ]2 x c

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

8 U' C' O6 Y* e- d' J, B9 ?. {7 B+ q

& E, k& g3 z, u/ X' X$ I, D

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

9 E" \3 j C* |1 Q

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

1 v& N) e6 Q: }" f" T3 K: Z j( P

ILoginServerDisp dispLoginServer = (ILoginServer *)dispAppServer;

. R4 v; h! V/ a# a0 n) x

dispLoginServer.Login();

) ?3 C3 n8 J5 a8 u- b

DM->cdsAnimals->Open();

/ I7 v+ N, m5 n' [$ ~, e5 H- z# m

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

0 V* K7 y9 ]! W

/ {6 d" o3 s) O7 T7 g

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

$ J Z# c- v9 R8 B/ r6 s$ c# M. x2 R. n8 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-11 13:32 , Processed in 0.405933 second(s), 52 queries .

回顶部