蜘蛛俠論壇采用forms驗證方式。
1: 當使用者輸入使用者名和密碼并登陸, 此時, 我們會将目前使用者的身份辨別儲存到用戶端:
檔案:
\core\managers\membermanager.cs
代碼:
cookiemanager.addcookietoresponse(
formsauthentication.getauthcookie(member.memberid.value.tostring(), false), expiredays);
2: 使用者登陸後, asp.net下次就自動知道目前通路使用者的身份辨別了. 我們可以通過如下方式擷取目前登陸使用者的辨別:
httpcontext.current.user.identity.name
另外, 如何判斷一個使用者是否處于登陸狀态? 我們可以通過如下的方式來判斷:
httpcontext.current.request.isauthenticated
如果該屬性傳回true,則表示目前使用者已登陸,否則,表示未登陸。
3: 在什麼時候擷取目前使用者的所有資訊?
asp.net提供了一個時機,讓我們對使用者執行身份驗證。該時機就是application對象的authenticaterequest事件。是以,我們可以在該事件的處理函數中确定目前通路使用者是否已經登陸,
\core\components\common\httpmodule.cs

private void application_authenticaterequest(object source, eventargs e)
{
httprequest request = httpcontext.current.request;
if (request.url.localpath.tolower().endswith(".aspx")
|| request.url.localpath.tolower().endswith(".ashx"))
{
setcurrentuser();
}
}
private void setcurrentuser()
if (!httpcontext.current.request.isauthenticated)
httpcontext.current.user = usermanager.getanonymoususer();
else
try
{
user user = usermanager.getuser(new guid(httpcontext.current.user.identity.name));
if (user != null)
{
httpcontext.current.user = user;
}
else
membermanager.logout();
httpcontext.current.user = usermanager.getanonymoususer();
}
catch
membermanager.logout();
httpcontext.current.user = usermanager.getanonymoususer();

大家可以看到,我們在authenticaterequest事件的處理函數中确定一個目前使用者,setcurrentuser函數實作該功能。該函數首先判斷目前使用者是否已經登陸,如果未登陸,則擷取一個匿名使用者對象,并指派給httpcontext.current.user;如果已經登陸,則根據使用者辨別從資料庫擷取登陸使用者對象,并同樣把該使用者對象指派給httpcontext.current.user;這裡有一個很關鍵的問題,我們為什麼可以把目前擷取的使用者對象指派給httpcontext.current.user?其實很簡單,我們隻要讓我們自己定義的user類實作iprinciple接口即可,user類的代碼如下:

public class user : entity, iprincipal
private iidentity identity = null;
#region implementation of iprincipal
public iidentity identity
get
return identity;
set
identity = value;
public bool isinrole(string rolename)
//return true or false by your own logic.
return false;
#endregion

這裡我為了突出重點,是以把user類的其他不相關的東西删除了。大家可以看到,我們隻要讓user類實作iprinciple接口就行了。然後我們可以為user類包含很多我們自定義的屬性。
這樣的做法有什麼好處呢?其實我們也完全可以把目前使用者放在session或cache等其他地方。我覺得最大的好處就是自然,因為asp.net提供給我們的httpcontext.current.user對象的意圖就是表示目前發送請求的使用者執行個體,但因為該對象所存儲的資訊非常少,基本上就隻存放了一個辨別目前登陸使用者的辨別(如使用者名)。但大部分情況下,我們都需要更多的使用者資訊,是以就自然而然很容易想到擴充該user屬性。
當然還有一個需要說明的細節是,
因為我們自己建立了一個新的user對象,并且指派給了httpcontext.current.user,而指派之前,httpcontext.current.user.identity不為空,是以為了一緻,我們也應該給我們自己定義的user類的identity屬性指派。
\core\userrolepermissions\user.cs

public static user getanonymoususer()
user user = activator.createinstance(configuration.instance.usertype) as user;
user.setroles(configuration.instance.anonymousdefaultrolelist);
user.identity = new genericidentity(string.empty);
return user;
public static user getuser(guid memberid)
trequest<user> request = new trequest<user>();
request.data = activator.createinstance(configuration.instance.usertype) as user;
request.data.memberid.value = memberid;
entitylist users = engine.getall(request);
user user = null;
if (users.count > 0)
user = users[0] as user;
if (user != null)
initializeuser(user);
private static void initializeuser(user user)
tentitylist<role> roles = new tentitylist<role>();
foreach (userandrole userandrole in rolemanager.getuserroles(user.entityid.value))
roles.add(userandrole.role);
user.setroles(roles);
user.identity = httpcontext.current.user.identity;

大家可以看到黃色高亮度顯示的那幾行代碼,我對identity屬性進行了指派。
4: 如何在頁面中通路目前使用者?
\business\controls\forumusercontrol.cs

public class forumusercontrol : baseusercontrol
protected forumuser currentuser
return httpcontext.current.user as forumuser;
protected bool validatepermission(permissiontype permission)
return currentuser.getpermissions().validatepermission((long)permission);
protected bool validatepermission(permissiontype permission, entity entity)
return currentuser.getpermissions(entity).validatepermission((long)permission);

forumusercontrol是一個基類usercontrol,我們可以在該控件中提供一個表示目前登陸使用者的屬性currentuser,這樣一來,我們在各個地方就可以很容易的通路我們自定義好的使用者對象啦。是不是很簡單呢?
好了, 以上就是蜘蛛俠論壇中目前登陸使用者的設計與實作。因為覺得可能對大家有用,是以寫出來與大家分享。