|
3 M& n! A, F/ m
2. 呼叫 对连接其间每次呼叫进行安全检查 3 f# X. a6 S. G
& E% @- o" P/ Z0 g6 Q; G 对应于MIDAS中其实就是每次取、改数据时对用户进行检查
6 z+ c/ A7 y. [! _/ V: w' W 因为所有客户端都是通过IAppServer接口对服务器进行操作
% u! U1 Z$ B' {8 E2 A4 b 因此一劳永逸的方法是自己提供IAppServer接口的实现,
" \+ ]0 e' N- F$ Z) E4 _ 考察一个实例 ) z' C3 G6 G9 ]* f* V/ T @
e" h6 }; F( L; R$ k
class ATL_NO_VTABLE TLoginServerImpl e5 p( b5 @9 \; U% h
: REMOTEDATAMODULE_IMPL(TLoginServerImpl, LoginServer, TLoginServer, ILogin # Q: ]1 ~6 n K5 q; h0 i7 }; X
Server), % p0 f) |- [* l) Y% {" [) c. H- ~
public IConnectionPointContainerImpl<TLoginServerImpl>, ( b0 |, ^1 P/ \, g& a
public TEvents_LoginServer<TLoginServerImpl> a' _) U/ l5 j, t6 R9 }
{ ; U4 o+ x# t2 v$ v% `8 H x9 x+ h+ P
...
k8 l2 Q. E' O7 g} - J( Z5 g0 F# h V5 l
BCB中是用REMOTEDATAMODULE_IMPL宏封装了IAppServer实现的定义 - e) I7 Q. M6 s$ P) R, B, n
5 P+ ^# O, I5 x+ O4 }! n
#define REMOTEDATAMODULE_IMPL(cppClass, CoClass, VclClass, intf) \
5 y7 W; D5 w" F( q6 a public CComObjectRootEx<CComObjectThreadModel>, \ % Z) ^) H$ B" m8 B
public CComCoClass<cppClass, &CLSID_##CoClass>, \ % ^. T6 _% E1 M; l- t7 a
public IAppServerImpl<VclClass, cppClass, intf, &IID_##intf, \ ; w2 N: Q6 J( a/ `" \
LIBID_OF_##CoClass>
l9 L: L3 |; D: b# x . {8 M8 P H2 M. l
这里的IAppServerImpl是BCB用来实现IAppServer的模板类 3 [% c u' h8 @: W9 S1 h
而IAppServerImpl的实现代码在atlvcl.h文件中,很简洁 . S: V& U4 Z. t& G9 S
完全可以通过实现自己的相应模板类来实现在IAppServer
8 q( d) R, l9 \; k/ s 一级实现用户身份检验功能。这样做效率最高,但比较麻烦
0 U. g J% x# `2 { 有兴趣的朋友可以自己下去试试,这里不再详细说明
1 { H* r1 i0 z4 o& }
$ R4 Y$ O# Y C+ S: i 注意基本上所有的IAppServer方法都提供了一个OleVariant& OwnerData
K+ l6 r0 N& o6 _7 L/ F8 a 参数,可以通过此参数取得足够的用户信息,用以校验 - M8 A: u, r) y: k0 `* _5 j0 e
比如偶比较喜欢给客户一个实时生成的SessionID(GUID类型) $ z7 ^% P6 {2 ?8 V$ l0 j
然后将之与服务器端已知的特定用户信息一起hash一把,呵呵
4 f$ _4 r! X( n2 |/ I2 o+ p
, g1 _& |. A a 次一级的方法是利用现有的VCL结构提供的事件来解决 & I! i( T7 ~3 a
不过这样做就有点麻烦了,呵呵,你必须在所有需要有
# C( V( l. e& E' x0 L 安全检验功能的TDatasetProvider的基本上所有BeforeXXX - d$ b, M+ t( G* k2 p4 S
事件里面增加相应的安全检验功能,如
4 {4 k* T6 ]8 O& _* A5 s if(!IsLogin(OwnerData))
3 d: m0 z j. N: n# T) k { # R$ w# l0 g/ X* z
throw Exception("Please login first!");
' r3 N1 n8 L3 R5 J& u } 5 P1 w7 R+ Q& X8 C* K2 e
出错直接抛出一个异常即可,系统会自动捕获返回给客户端 % p" D1 m# z% A5 w) \# Z
好在大部分的beforeXXX事件都是TRemoteEvent类型,可以共用一段代码
3 V3 r/ w f8 ]6 M" E 而在客户端需要做的事情就是在合适的时刻login/logout 3 R5 ^+ h+ X; K0 u5 l( C
然后在相应的TClientDataSet::BeforeXXX事件中将 3 C2 O; ~* i( s+ z7 Z
OleVariant &OwnerData设置成相应的数据
; a9 c2 n3 U; Q6 u
0 G, Q S' J& L& X 一种变通的办法可以重载你的TSocketConnection类 # ~7 ]$ }& L$ g/ }
将每次对IAppServer接口的调用中的OwnerData加一个 , a4 ~: S3 F, Y# b8 j) r/ Z
自己的鉴定信息头,然后在服务器端剥离,呵呵
9 q) x7 S- t8 u2 K 这个方法有兴趣自己试试好了 |