|
1 b, z6 s$ i0 `1 G
2. 呼叫 对连接其间每次呼叫进行安全检查
9 C/ J! y. J! U! X
8 j( y/ P# S6 z- f+ s% _* u 对应于MIDAS中其实就是每次取、改数据时对用户进行检查
. |2 X5 N2 x( }) x% x0 O 因为所有客户端都是通过IAppServer接口对服务器进行操作 - K8 Z t: B+ h- ^
因此一劳永逸的方法是自己提供IAppServer接口的实现,
$ `+ { f6 g1 O" {# X( y 考察一个实例 3 |# ]( g3 w! Z1 R
$ G) g& ^* t: A- g! R$ U& j. oclass ATL_NO_VTABLE TLoginServerImpl
3 n. i3 L% F9 r% ?+ X2 E# i : REMOTEDATAMODULE_IMPL(TLoginServerImpl, LoginServer, TLoginServer, ILogin
! z0 S! E/ p5 L- C- y n8 ZServer),
, j5 r* N. z) q7 E( h, | public IConnectionPointContainerImpl<TLoginServerImpl>,
. ?7 b$ R6 O) i& H1 V public TEvents_LoginServer<TLoginServerImpl> 1 p v. r. V: b4 r! }7 X( A+ r% W
{ : a- t& C) g O7 c; e4 X
... . R2 m* C& y/ R. ~
} 4 _; {/ A. `( e! ~9 M* X* \% a
BCB中是用REMOTEDATAMODULE_IMPL宏封装了IAppServer实现的定义 ( i9 p2 U3 x; I& y7 j
/ i+ m' S$ b M1 H5 Y& `+ b2 d#define REMOTEDATAMODULE_IMPL(cppClass, CoClass, VclClass, intf) \ , q% l& r9 |- _; T5 J6 r) H; ~5 p
public CComObjectRootEx<CComObjectThreadModel>, \ ( c. |# X# x. q8 j* k0 M
public CComCoClass<cppClass, &CLSID_##CoClass>, \ & z( Y) G* d5 ^
public IAppServerImpl<VclClass, cppClass, intf, &IID_##intf, \
8 e( q6 ` z6 N LIBID_OF_##CoClass> & b I% W8 G# H# J q; M
5 H4 v, L) ?: F
这里的IAppServerImpl是BCB用来实现IAppServer的模板类
& E: w4 c; Y2 c* n 而IAppServerImpl的实现代码在atlvcl.h文件中,很简洁
! F8 B! K2 w' R- g& d9 I 完全可以通过实现自己的相应模板类来实现在IAppServer % r) v. \+ A, q+ V$ V
一级实现用户身份检验功能。这样做效率最高,但比较麻烦 8 S- v9 K( v# U! w
有兴趣的朋友可以自己下去试试,这里不再详细说明
?6 v9 J" X9 l k
' s& p7 d+ j J! T% Q 注意基本上所有的IAppServer方法都提供了一个OleVariant& OwnerData
: C T: L9 N: O1 r0 j" o 参数,可以通过此参数取得足够的用户信息,用以校验 S0 o' L5 q8 U( @1 ^; [5 H* z( N$ n
比如偶比较喜欢给客户一个实时生成的SessionID(GUID类型) ' y7 @8 C. B3 _" x" k/ p/ `# s
然后将之与服务器端已知的特定用户信息一起hash一把,呵呵
i5 i9 k" \. m. v: T" b 4 ?% }- H1 Z# w8 S: E1 |
次一级的方法是利用现有的VCL结构提供的事件来解决
. X s9 @5 L" v( n- j1 Y 不过这样做就有点麻烦了,呵呵,你必须在所有需要有 9 m2 m6 ^4 o1 L% q. V- n
安全检验功能的TDatasetProvider的基本上所有BeforeXXX % f8 M' N* K% N
事件里面增加相应的安全检验功能,如 " c7 f7 F4 M" m
if(!IsLogin(OwnerData))
6 t' c/ G* A: ?" D3 z+ s {
& j' ]' n( x2 x* t! v0 N throw Exception("Please login first!"); " G& c7 L# T0 w: U* f: D0 Z
} $ Z" G- p3 n' w0 @4 X
出错直接抛出一个异常即可,系统会自动捕获返回给客户端
; `) p6 g/ {4 r$ T5 r: `5 E4 o 好在大部分的beforeXXX事件都是TRemoteEvent类型,可以共用一段代码 9 {* @$ T8 i, O( p( e2 N
而在客户端需要做的事情就是在合适的时刻login/logout
5 m' m( W9 W) K5 A$ n m 然后在相应的TClientDataSet::BeforeXXX事件中将
/ [, p% W9 v% |& @8 I: J- o OleVariant &OwnerData设置成相应的数据 9 N, t9 a% m5 |) i
- p1 X$ {# p* D' ^+ ?. O* l
一种变通的办法可以重载你的TSocketConnection类 2 j4 }; u( I! F2 b, Q
将每次对IAppServer接口的调用中的OwnerData加一个 * |* U8 S& o% N8 B/ h. w9 k& p) _% \
自己的鉴定信息头,然后在服务器端剥离,呵呵
8 T' l1 X9 \& D5 q5 @; E5 C; F 这个方法有兴趣自己试试好了 |