集中控制多个intraweb应用的登录

本文探讨如何实现对多个Intraweb应用程序的集中控制,特别是聚焦于登录过程的统一管理。通过共享DLL或者使用中央认证服务,可以确保用户只需登录一次即可访问所有关联应用,提高用户体验并增强系统安全性。
KeyLife富翁笔记
(此作品参加“Borland ALM 产品开发者竞赛参赛”,请大家给他打分。)
作者: yeskert1
标题: 集中控制多个intraweb应用的登录
关键字: intraweb,login,isapidll
分类: 开发经验
密级: 参赛
(评分: ★★★ , 回复: 7, 阅读: 1077)  »»

问题的提出:
  我们正在开发一个较大的工程,为了分工也为了模块清晰,工程分了多个模块。但整个工程是需要登录来确认身份,并且根据身份确定登录这的权限。当然,不能为每个模块都开发一个登录界面,我们希望通过一个程序控制所有程序。

思路:
  建立一个login.dll,它来实现登录功能,并且它提供一个界面,该界面能够连接到各个模块,当然,参数也传递过去。而各个模块只有得到正确的参数(userid和password)才能正确执行。
问题:
1、参数如何传递
2、参数如何不在客户端出现
3、各个模块如何调试

                          一、建立login.dll

一.1 ServerController内容:
unit ServerController;
{PUBDIST}

interface

uses
  Classes,
  DatamoduleUnit,
  IWServerControllerBase, IWAppForm, IWApplication,
  SysUtils;

type
  TIWServerController = class(TIWServerControllerBase)
    procedure IWServerControllerBaseNewSession(ASession: TIWApplication;
      var VMainForm: TIWAppForm);
    procedure IWServerControllerBaseCreate(Sender: TObject);
  private
  public
  end;

 
  TUserSession = class(TComponent)
  public
    datamodule1:Tdatamodule1;
    user_id,user_name:string;
   
    constructor Create(AOwner: TComponent); override;
    destructor destroy; override;

    function check_user(u_id,u_pwd:string):boolean;
   
  end;

  function UserSession: TUserSession;
//自定义的几个函数和过程
  function cut_it(s:string):string;  
  procedure movetoDLL(DLLName:string;frm:TIWAppForm);
  procedure movetoDLLAnonym(DLLName:string;frm:TIWAppForm);
  function DLL2longURL(DLLName:string):string;
  function DLL2longURLWithUser(DLLName:string):string;
 
implementation
{$R *.dfm}

uses
  IWInit,Registry,StrUtils,login_mainIWU;
function DLL2longURL(DLLName:string):string;
begin
   result:='http://'+RWebApplication.Request.Host+'/'+cut_it(RWebApplication.URLBase)+DLLName;
end;
function DLL2longURLWithUser(DLLName:string):string;
begin
   result:=DLL2longURL(DLLName)+'?userid='+UserSession.user_id+'&password='+UserSession.user_pwd;
end;
function cut_it(s:string):string;
var i,j:integer;
begin
   i:=pos('/',s);
   while i>0 do begin
      j:=i;
      i:=posEx('/',s,i+1);
   end;
   result:=copy(s,1,j);
end;

procedure movetoDLL(DLLName:string;frm:TIWAppForm);
begin
   frm.addtoinitproc('window.open("'+DLL2longURLWithUser(DLLName)+'","","");')
end;
procedure movetoDLLAnonym(DLLName:string;frm:TIWAppForm);
begin
   frm.addtoinitproc('window.open("'+DLL2longURL(DLLName)+'","","");')
end;
function UserSession: TUserSession;
begin
  Result := TUserSession(RWebApplication.Data);
end;

{ TUserSession }

constructor TUserSession.Create(AOwner: TComponent);
begin
  inherited;
  datamodule1:=Tdatamodule1.Create(AOwner);
end;
destructor TUserSession.destroy;
begin
   inherited ;
end;
function TUserSession.check_user(u_id,u_pwd:string):boolean;
begin
   result:=true;
end;

procedure TIWServerController.IWServerControllerBaseNewSession(
  ASession: TIWApplication; var VMainForm: TIWAppForm);
begin  
  ASession.Data := TUserSession.Create(ASession);
end;  

end.

    这个单元没有特别需要说明的,其中的check_user是示意性质的,填上实际的代码即可。
    这个单元里定义了几个全局函数和过程,以便其他地方调用。

一.2 登录窗口(单元)内容,略。

一.3 主窗口。当登录成功后,显示这个窗口,通过该窗口可以连接到其他模块。
    这个窗口唯一要说明的是如何连接到其他模块,请看其中一个连接的代码:
procedure TFrmTop.IWLinkTestClick(Sender: TObject);
begin
    movetodll('test.dll',RWebApplication.ActiveForm  as TIWAPPForm)
end;
其中 movetodll在ServerController单元里已经定义过了。系统假设test.dll与login.dll放在同一个目录下。

                                   二、建立其他模块
我们知道login.dll已经将参数传递过来,在其他模块里如何接收?看看其他模块的ServerController单元就明白了:
unit ServerController;
{PUBDIST}

interface

uses
  Classes,
  DatamoduleUnit,
  IWServerControllerBase, IWAppForm, IWApplication,
  SysUtils;
type

  TIWServerController = class(TIWServerControllerBase)
    procedure IWServerControllerBaseNewSession(ASession: TIWApplication;
      var VMainForm: TIWAppForm);
    procedure IWServerControllerBaseCreate(Sender: TObject);
  private
  public
  end;


  TUserSession = class(TComponent)
  public
    datamodule1:Tdatamodule1;
    user_id,user_name:string;    
    //
    constructor Create(AOwner: TComponent); override;  
    function check_user(u_id,u_pwd:string):boolean;    
  end;

function UserSession: TUserSession;

implementation
{$R *.dfm}

uses
  IWInit,Registry,StrUtils;

constructor TUserSession.Create(AOwner: TComponent);
begin
  inherited;
  datamodule1:=Tdatamodule1.Create(AOwner);  
end;

function TUserSession.check_user(u_id,u_pwd:string):boolean;
begin
  result:=false;
  //你的代码
  result:=true;
end;

procedure TIWServerController.IWServerControllerBaseNewSession(
  ASession: TIWApplication; var VMainForm: TIWAppForm);
var userid,pwd:string;
begin  
  ASession.Data := TUserSession.Create(ASession);
  with ASession.RunParams do begin
         userid:=Values['userid'];
         pwd:=Values['password'] ;        
  end;
  //userid:='0';pwd:='111111';   //请注意!!!调试时使用!!!

  with usersession do
        if (userid='') or(not check_user(userid,pwd))  then  
           ASession.Terminate('对不起,你没有这个权限。');
end;

end.
   当创建一个新的session的时候,要判断是否有参数过来,如果没有参数,或者有参数但不被许可,那么“对不起,你没有这个权限。”。
   本例中,每个模块都有自己的check_user,也许你不需要这样。
   现在,每个模块都已经得到了传过来的口令和密码了,进一步的工作就是你自己的事情了。
但是,事情并没有就此结束,传递过来的参数会显示在客户端。这是不能接受的。我也在等待更好的解决办法,但在更好的解决办法出现之前,还用我原来的方法吧——这个方法我在别处说过:
在各个模块的主窗口的javascript属性里加上这样的代码:
var str=location.href;
pos=str.indexOf("?");
if (pos>=0) {
location=str.substring(0,pos);
}
   可以看出,代码在客户端将参数截去了,这导致页面更新了一次,这也不算什么问题,因为仅仅多访问一次服务器而已。不过,客户端会跳出一个警告框,这很烦。去掉这个警告框很容易,只要将IWServerController的showResyncWarning置成false即可。
   还要提醒一下:login.dll里使用的参数名称必须跟其他模块使用的参数名称一样,事先要约定好。

   到这里应该说大功告成了。下面是“完美主义者”的讨论:
1、客户端真的看不到参数了吗?其实,既然带参数的url成功的访问了服务器,ie的下拉框里难免会留下痕迹。怎么办?两个思路:
     A 你告诉浏览器:不要保存我的url。至于怎样“告诉”,我也不会!
     B 口令加密,即使看到又如何?
2、其他模块如何调试?平时,我都是通过另一个产生exe的工程来调试,我想你也是。但程序需要参数,怎么办?看到上面代码中的注释了吗?这一行就是用来调试的。当然,你在浏览器中,输入url时手工添加参数也行。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值