|
, ~ T# F9 \3 X: M0 r4 Z2. 呼叫 对连接其间每次呼叫进行安全检查 * C. j* a+ R" N5 G" L7 F4 A
% H+ L2 Y9 v$ S {; l" k 对应于MIDAS中其实就是每次取、改数据时对用户进行检查 ) d- x4 ^( d8 P# {
因为所有客户端都是通过IAppServer接口对服务器进行操作
2 T3 E$ L8 [* n; ~# k 因此一劳永逸的方法是自己提供IAppServer接口的实现,
, f; g# E' ~( O% r9 S# q$ m 考察一个实例
; i X6 w5 @8 g 6 r, b: J8 `* h3 `' c) X. {: Q2 L( b
class ATL_NO_VTABLE TLoginServerImpl
1 Q C" q! [8 i5 r! ^# L9 Z : REMOTEDATAMODULE_IMPL(TLoginServerImpl, LoginServer, TLoginServer, ILogin
2 b& x. c6 P4 ]1 m5 h" f5 pServer),
6 m0 E2 Y- f: ^* j- j' F2 t public IConnectionPointContainerImpl<TLoginServerImpl>,
5 K5 T) P# k' S6 Q& r+ G% O3 a" } public TEvents_LoginServer<TLoginServerImpl> + } B2 v4 \ b
{ % Q, X+ u) P6 r+ T, @2 R# d
...
: H5 S Z0 ?. e5 [7 K}
) T: c; `. r& s" C BCB中是用REMOTEDATAMODULE_IMPL宏封装了IAppServer实现的定义 2 K. M( V. F2 k' B/ f& _& u" v
5 }- p2 g8 q) W# F6 D" a' u
#define REMOTEDATAMODULE_IMPL(cppClass, CoClass, VclClass, intf) \ + `( V. V8 W. p6 o
public CComObjectRootEx<CComObjectThreadModel>, \ ) E+ P7 g9 v+ f! A9 F
public CComCoClass<cppClass, &CLSID_##CoClass>, \
% h$ z: N7 g$ O. H# T public IAppServerImpl<VclClass, cppClass, intf, &IID_##intf, \ 6 }( Z8 D$ O B0 P7 |! V
LIBID_OF_##CoClass> ; e: H* A2 Q$ p* K
" Q* G4 Z0 W+ i/ q9 u o 这里的IAppServerImpl是BCB用来实现IAppServer的模板类
& d- u2 P$ E& c5 w8 g$ E ~ 而IAppServerImpl的实现代码在atlvcl.h文件中,很简洁
d' b; X0 K. } 完全可以通过实现自己的相应模板类来实现在IAppServer
2 X1 q. z" y5 z; l 一级实现用户身份检验功能。这样做效率最高,但比较麻烦 / N, M& { P. ~ t' c
有兴趣的朋友可以自己下去试试,这里不再详细说明 ( e% F) D$ @& U5 a; G! T
& `' c K" c* |) _9 |7 p- w* j
注意基本上所有的IAppServer方法都提供了一个OleVariant& OwnerData
0 J( D+ V" [! I! l& Z8 N+ y+ g 参数,可以通过此参数取得足够的用户信息,用以校验
$ q8 K5 a( u, S8 T 比如偶比较喜欢给客户一个实时生成的SessionID(GUID类型) ( B: Q* R8 |/ W4 m6 h: E
然后将之与服务器端已知的特定用户信息一起hash一把,呵呵
! {4 a1 t6 S% x" P, k/ ~- m) j) P, ~
$ ~ A% g" ]) W' ~' r 次一级的方法是利用现有的VCL结构提供的事件来解决 - `4 D, Z. Q! F5 s3 s
不过这样做就有点麻烦了,呵呵,你必须在所有需要有
* ^9 F% \$ U( |+ k2 W 安全检验功能的TDatasetProvider的基本上所有BeforeXXX 5 X& ]8 u/ } Z0 e7 p: w
事件里面增加相应的安全检验功能,如
+ M" d; e* _/ S5 U, o5 C if(!IsLogin(OwnerData))
4 ]7 M6 r2 V8 p/ L; @) a% U& Y {
- j& V3 h+ ]3 ~0 v- e throw Exception("Please login first!");
* c/ l3 k4 p+ ^+ R* h+ z } 5 s, |7 v0 p* t% w- l6 Z
出错直接抛出一个异常即可,系统会自动捕获返回给客户端
4 P$ g; ?2 P( @4 I 好在大部分的beforeXXX事件都是TRemoteEvent类型,可以共用一段代码
* O! {+ }) \! Y2 k, f 而在客户端需要做的事情就是在合适的时刻login/logout + r, Y" o- K! k: S
然后在相应的TClientDataSet::BeforeXXX事件中将
4 ]8 r2 J8 o) F: t' U* {' v+ k OleVariant &OwnerData设置成相应的数据
! ]# w8 Z! P; E$ h
: h1 J5 A8 k/ u/ @ 一种变通的办法可以重载你的TSocketConnection类 8 g# _' C( f& S: J e
将每次对IAppServer接口的调用中的OwnerData加一个
5 A; ^6 b: Q, O 自己的鉴定信息头,然后在服务器端剥离,呵呵
1 N4 C0 s$ b0 G; }5 _3 ~4 W; Z 这个方法有兴趣自己试试好了 |