2009-04-22 70 views
4

基本上,我登錄到我的網站使用OpenId,非常類似於我所假設的那樣。當我得到信息時,我把它放入數據庫並創建我的「註冊用戶」。我設置我的AuthCookie:像Stack Overflow這樣的站點如何在ASP.NET MVC中傳遞用戶信息?

FormsAuthentication.SetAuthCookie(user.Profile.MyProfile.DisplayName, false); 

然後我可以使用這個用戶名。但是,我想傳入整個對象而不是顯示名稱的字符串。所以我的問題是:

SO是如何做到的?

它們是否擴展/覆蓋SetAuthCookie(string, bool)方法來接受用戶對象,即SetAuthCookie(User(object), bool)

什麼是最好的方式來堅持一個User對象,以便它可以在我的Web應用程序的每個頁面上的UserControl上使用?

在此先感謝!

+0

你在使用使用OpenID登錄?我以前使用過http://code.google.com/p/dotnetopenid/取得了一些成功 - 我確定它提供了示例,說明您在此處要做什麼。 – Noldorin 2009-04-22 23:14:59

+0

我正在使用他們的ASP.NET MVC示例登錄。只是核心,然後拿起他們的方法在案例語句(這是我上面的行代碼。原來,代碼看起來像這樣... FormsAuthentication.SetAuthCookie( response.ClaimedIdentifier,false);我剛剛用我的用戶顯示名稱替換了字符串,我希望能夠用它來推送一些基本信息,就像他們在這裏讓他們知道你的分數,你的userId(在超鏈接中 – 2009-04-22 23:32:03

回答

3

您可以通過implementing您的自定義Membership Provider或擴展現有的行爲來實現此行爲。提供者根據密鑰(或者僅僅根據用戶名)存儲用戶信息,並提供對類的訪問,不管你希望如何,你可以擴展這個類。因此,當您撥打FormsAuthentication.SetAuthCookie(...)時,您基本上可以設置可以作爲提供商訪問的用戶密鑰。

當您撥打Membership.GetUser()時,會員基礎設施將調用底層提供商並調用其提供當前用戶密鑰的GetUser(...)方法。因此您將收到當前的用戶對象。

1

一種方法是在控制器中注入一個負責檢索當前登錄用戶信息的類。這是我如何做到的。我創建了一個名爲WebUserSession的類,它實現了一個名爲IUserSession的接口。然後,我只是在創建控制器實例時使用依賴注入將其注入到控制器中。我在我的界面上實現了一個名爲GetCurrentUser的方法,該方法將返回一個User對象,通過將它傳遞給視圖,我可以根據需要在我的操作中使用它。

using System.Security.Principal; 
using System.Web; 

public interface IUserSession 
{ 
    User GetCurrentUser(); 
} 

public class WebUserSession : IUserSession 
{ 
    public User GetCurrentUser() 
    { 
     IIdentity identity = HttpContext.Current.User.Identity; 
     if (!identity.IsAuthenticated) 
     { 
      return null; 
     } 

     User currentUser = // logic to grab user by identity.Name; 
     return currentUser; 
    } 
} 

public class SomeController : Controller 
{ 
    private readonly IUserSession _userSession; 

    public SomeController(IUserSession userSession) 
    { 
     _userSession = userSession; 
    } 

    public ActionResult Index() 
    { 
     User user = _userSession.GetCurrentUser(); 
     return View(user); 
    } 
} 

正如你所看到的,你現在有機會,如果需要獲取用戶。當然,如果你願意,你可以改變GetCurrentUser方法來首先查看會話或者其他一些方法,所以你不會一直訪問數據庫。

2

傑夫,

正如我在上面你的問題評論說,你必須使用的用戶名ClaimedIdentifier - 也就是說,要SetAuthCookie第一個參數。這有一個巨大的安全原因。如果您想更多地瞭解原因,請隨時在[email protected]上發起主題。

現在關於你關於整個用戶對象的問題......如果你想把它作爲一個cookie發送出去,你必須將你的用戶對象序列化爲一個字符串,然後你必須在一些防止用戶篡改的方式。你可能也想加密它。 Blah等等,這是很多的工作,你最終會得到一個大的cookie來回發送你不需要的每個Web請求。

我在我的應用程序中解決您所述問題的方法是將靜態屬性添加到名爲CurrentUser的Global.asax.cs文件中。就像這樣:

public static User CurrentUser { 
    get { 
     User user = HttpContext.Current.Items["CurrentUser"] as User; 
     if (user == null && HttpContext.Current.User.Identity.IsAuthenticated) { 
      user = Database.LookupUserByClaimedIdentifier(HttpContext.Current.User.Identity.Name); 
      HttpContext.Current.Items["CurrentUser"] = user; 
     } 
     return user; 
    } 
} 

通知我緩存結果在HttpContext.Current.Items詞典,這是具體到一個HTTP請求,並保持用戶獲取到一個單一的命中 - 只有獲取它的第一次如果一個頁面實際上需要CurrentUser信息。

因此,一個頁面可以很容易地獲取當前登錄的用戶信息是這樣的:

User user = Global.CurrentUser; 
if (user != null) { // unnecessary check if this is a page that users must be authenticated to access 
    int age = user.Age; // whatever you need here 
}