天天看點

蜘蛛俠論壇核心架構分析1 - 如何設計與實作目前通路使用者

蜘蛛俠論壇采用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

蜘蛛俠論壇核心架構分析1 - 如何設計與實作目前通路使用者

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();

蜘蛛俠論壇核心架構分析1 - 如何設計與實作目前通路使用者

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

蜘蛛俠論壇核心架構分析1 - 如何設計與實作目前通路使用者

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

蜘蛛俠論壇核心架構分析1 - 如何設計與實作目前通路使用者

這裡我為了突出重點,是以把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

蜘蛛俠論壇核心架構分析1 - 如何設計與實作目前通路使用者

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;

蜘蛛俠論壇核心架構分析1 - 如何設計與實作目前通路使用者

大家可以看到黃色高亮度顯示的那幾行代碼,我對identity屬性進行了指派。

4: 如何在頁面中通路目前使用者?

\business\controls\forumusercontrol.cs

蜘蛛俠論壇核心架構分析1 - 如何設計與實作目前通路使用者

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);

蜘蛛俠論壇核心架構分析1 - 如何設計與實作目前通路使用者

forumusercontrol是一個基類usercontrol,我們可以在該控件中提供一個表示目前登陸使用者的屬性currentuser,這樣一來,我們在各個地方就可以很容易的通路我們自定義好的使用者對象啦。是不是很簡單呢?

好了, 以上就是蜘蛛俠論壇中目前登陸使用者的設計與實作。因為覺得可能對大家有用,是以寫出來與大家分享。