此外,许多组织利用微软活动目录(AD)和Novell的Netware目录服务(NDS),再结合一个适当的Web服务器,在Web服务器上提供用户
识别功能。
用户识别一般通过基于Web的应用程序中的一个登录页面来完成,目录可以作为另一种替代验证方法。这被称作单点登录(SSO)。下面我们来了解如何在
Novell Netware环境下使用NDS为目录服务。为在代码和NDS之间建立连接,我们使用Novell的NWDir1控件。
客户端探测
首先,我们来了解如何使用这个控件进行客户端探测。在下面的样本实例(列表A)中,我们使用VBScript实现这一功能。
列表A
<HTML>
<HEAD>
<TITLE>Netware User Detection Sample</TITLE>
<SCRIPT LANGUAGE="VBScript">
Sub WhoAmI_OnClick()
if (NWDir1.LoginName) then
msgbox NWDir1.LoginName
else
msgbox "No Logged In User"
end
End Sub
</SCRIPT>
</HEAD>
<OBJECT ID="NWDir1" CLASSID="CLSID:4F021AE3-9E98-11D0-
A808-00C04FDCD94A" CODEBASE="http://www.novell.com/nds/controls/
nwdir.ocx">
</OBJECT>
<BODY>
<INPUT NAME = "WhoAmI" type="button" VALUE="Who Am I ?"><p>
</BODY>
</HTML>
按下按钮后,代码显示NWDir1控件LoginName属性的值,或者如果当前没有用户登录,则显示一段消息。虽然在上面的例子中我们使用一个消息框
来显示信息,但我们也可以用上述信息在一个表盘中显示用户名,或用它使用户登录应用程序,但用户不必看到或填写登录窗口。
服务器端用户探测
上面我们已经讨论了客户端探测,接下来我们说明如何在服务器端进行用户探测。在这个例子中,我们使用一个基于Web的应用程序登录窗口。首先,我们需要
一个样本登录页面,如列表B所示。
列表B
<HTML>
<HEAD>
<TITLE>NDS Authentication Login Screen</TITLE>
<SCRIPT LANGUAGE="javascript" TYPE="text/javascript">
function checkUser()
{
var URL="/scripts/usercheck.asp?"
URL=URL + "username=" + escape(document.slf.txtUsername.value);
URL=URL + "&password=" + escape(document.slf.txtPassword.value);
URL=URL + "&domain=" + escape(document.slf.dropOffices.value);
// get the IFrame
var myIFramesArray=document.getElementsByName('ajaxframe');
// if we have the IFrame
if (myIFramesArray.length>0)
{
// change the URL of the IFrame
myIFramesArray[0].src=URL;
}
} </HEAD>
<BODY>
<DIV ID='loginForm' NAME='loginForm'>
<FORM NAME='slf'>
User Name : <INPUT TYPE='text' NAME='txtUsername' SIZE='20'><p>
Password : <INPUT TYPE='password' NAME='txtPassword' SIZE='20'><p>
Office Location :
<SELECT NAME='dropOffices' ID='dropOffices' SIZE='1' CLASS='Select'>
<OPTION VALUE='NDS:DEMO_TREESite1'>Site 1</OPTION>
<OPTION VALUE='NDS:DEMO_TREESite2'>Site 2</OPTION>
<OPTION VALUE='NDS:DEMO_TREESite3'>Site 3</OPTION>
</SELECT>
<P>
<INPUT TYPE='button' VALUE='Log In' ONCLICK="checkUser()">
</FORM>
</DIV>
<IFRAME NAME="ajaxframe" ID="ajaxframe" WIDTH="800" HEIGHT="200"
STYLE="display:none"></IFRAME>
</BODY>
</HTML>
按下按钮后,checkUser函数用一些QueryString参数(用户在表单中输入)建立一个URL。建立URL后,它被作为IFrame的源
URL提交,并依次将参数提交给服务器端脚本。这等同于一个标准的HTTP GET请求,它设定TARGET属性为IFrame。但是,在上面的例子
中,为提高例子的易懂性,我用代码完成了上述操作。
服务器端验证
下一个例子将在服务器端执行验证。这个简单的Classic ASP页(列表C)将尝试根据选定的NDS域验证用户提供的证书,然后以简单HTML页的
形式给IFrame发送一个响应。在代码中,我们创建了一个NWDir控件实例,然后使用NDS树中的UserName和Domain试图定位用户。
如果无法定位用户,代码将通知用户。如果可以定位用户,则用ValidatePassword函数检查所提供的密码。如果登录有效,我们建立一个简单的
HTML页面发送给IFrame,它将通知确认登录的父页面。
列表C
<%
OPTION EXPLICITDIM sCurrentUsername
DIM sCurrentPassword
DIM sCurrentNetworkPath
DIM sCheckLogin' get the data off the form
sCurrentUsername = Request.QueryString("username")
sCurrentPassword = Request.QueryString("password")
sCurrentNetworkPath = Request.QueryString("domain")
' create the NDDS object
SET NWDir1=Server.CreateObject("NWDirLib.NWDirCtrl.1″)
' set the value
NWDir1.Fullname = sCurrentNetworkPath
SET entry=NWDir1.FindEntry(sCurrentNetworkPath & "" &
sCurrentUsername)
' if we can't find the user then redirect to the login page
IF entry IS nothing Then
loginFailed
ELSE
' attempt a login
sCheckLogin =
NWDir1.Entries(sCurrentUserName).ValidatePassword(sCurrentPassword)
' if the login is ok
IF sCheckLogin = True THEN
' close the HTML header and start the doc
Response.Write("<HTML>" & Chr(13))
Response.Write("<HEAD>" & Chr(13))
Response.Write("</HEAD>" & Chr(13))
Response.Write("<BODY ONLOAD='alert(" & Chr(34) & sCurrentUsername &
Chr(34) & ")'>" & Chr(13))
Response.Write("</BODY>" & Chr(13))
Response.Write("</HTML>" & Chr(13))
' otherwise login failed, so bounce back to the login page
ELSE
loginFailed
END IF
END IF
' drop the connection to the NDS object
SET NWDir1=Nothing
SUB loginFailed
Response.Write("<HTML>" & Chr(13))
Response.Write("<HEAD>" & Chr(13))
Response.Write("<SCRIPT LANGUAGE='javascript' TYPE='text/javascript'>"
& Chr(13))
Response.Write(" function loginFailed()" & Chr(13))
Response.Write(" {" & Chr(13))
Response.Write(" alert(' Login Failed for user " & sCurrentUsername &
"');" & Chr(13))
Response.Write(" }" & Chr(13))
Response.Write("</SCRIPT>" & Chr(13))
Response.Write("</HEAD>" & Chr(13))
Response.Write("<BODY ONLOAD='loginFailed()'>")
Response.Write("</BODY>" & Chr(13))
Response.Write("</HTML>" & Chr(13))
end sub
%>
最后会弹出一条消息,通知用户他们是否成功登录。虽然这个例子没有多大价值,但你可以方便地对它进行修订,创建一个ASP会话,或为应用程序保存用户证
书的cookie。
如果结合上述两种方法,你可以创建一个登录窗口,它只有在用户根据NDS目录没有通过验证的情况下才会出现;否则,他们就得以无缝处理,好像他们已经通
过登录窗口登录。这即是一个SSO应用程序的例子。
其它应用
在上面的三个例子中,我们建立了根据Novell NDS目录在客户端和服务器端探测和验证用户的方法。你也可以根据MSDN中的样本代码,编写一个应
用于微软活动目录环境下的类似应用。