2015-12-26 52 views
2

我正在使用ASP.NET MVC 5和SignalR編寫一個簡單的聊天應用程序。該應用程序不需要任何複雜的身份驗證邏輯。用戶只需輸入他們的登錄信息並進入系統(如果在db之前沒有這樣的用戶,它就會被創建)。在ASP.NET MVC中填充User.Identity 5

我的意圖是使用Session來保存登錄的用戶和他們的信息(ID從數據庫和登錄/用戶名)和寫一個全球性的過濾器,以檢查用戶是否對每個請求驗證。儘管我遇到了SignalR的一些問題。從SignalR Hub訪問會話是不可能的,而我需要它來查找發送消息的用戶的登錄名。

由於FAS,因爲我發現,它可能使用SignalR的背景下User.Identity工作。但是,在我的情況下,Uder.Identity完全是空的。大概是因爲我已經創建了應用程序'無身份驗證',並且User.Identity用於獲取用戶數據的機制並不知道我的會話操作。

的問題是,是否有可能優雅柵間User.Identity到我的應用程序,並使其認識到會議?以創建單個用戶帳戶的ASP.NET MVC項目創建了一個東西,像亂

public AccountController() : 
this(new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(new ApplicationDbContext()))) 
{ 

} 

,這就是我不希望有任何方式我的應用程序是什麼,因爲我不想把它寫儘可能乾淨而不是使用我不熟悉的任何解決方案。我也不需要任何外部登錄提供商,餅乾等

我在想實現一些內存在我自己的存儲。但是,我仍然需要在某個時間清理這家店。我雖然在Session_End事件被激發時清理它。但是,如果Session中存在我不想擁有的數據,則只會觸發此事件,因爲獨立的內存存儲並依賴Session事件進行清理會非常尷尬,此外,還需要設置Session中的一些數據只是爲了確保Session_End會觸發。

回答

1

下面是我提出的解決方案。它仍然不是我想要的那樣清楚,它使用cookies,所以任何補充都是值得歡迎的。

首先,我必須安裝Microsoft.AspNet.Identity.Owin包,並且其所有的依賴。

然後我註冊了我的身份驗證如下:然後

 private void ConfigureAuth(IAppBuilder app) 
     { 
      app.UseCookieAuthentication(new CookieAuthenticationOptions 
      { 
       AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie, 
       LoginPath = new PathString("/Account/Login") 
      }); 
     } 

這種方法被稱爲Startup.cs文件的配置方法。

爲了與認證工作,需要IAuthenticationManager的一個實例。我把它注射到我的控制器,並使用Ninject來解決依賴

kernel.Bind<IAuthenticationManager>().ToMethod(_ => HttpContext.Current.GetOwinContext().Authentication).InRequestScope(); 

下面是該用戶被重定向時AUTH需要(在ConfigureAuth方法由於LOGINPATH)到賬戶控制器的登錄方法:

[HttpPost] 
    public ActionResult Login(LoginViewModel model) 
    { 
     if (!ModelState.IsValid) 
     { 
      return View(model); 
     } 
     var user = authenticationService.AuthenticateUser(model.Login); 
     IdentitySignIn(user.Id, user.Login); 
     return RedirectToAction("Index", "Home"); 
    } 

AuthenticationService是我自己的類,它與數據庫通信並執行登錄來創建或返回用戶。

IdentitySignIn聲明如下:

 private void IdentitySignIn(int userId, string userLogin) 
     { 
      var claims = new List<Claim>(); 
      claims.Add(new Claim(ClaimTypes.PrimarySid, userId.ToString())); 
      claims.Add(new Claim(ClaimTypes.Name, userLogin)); 

      var identity = new ClaimsIdentity(claims, DefaultAuthenticationTypes.ApplicationCookie); 

      authenticationManager.SignIn(new AuthenticationProperties() 
       { 
        ExpiresUtc = DateTime.UtcNow.AddDays(200), 
        IsPersistent = true 
       }, identity); 
     } 

此方法創建具有適當信息的cookie。但有一件事。當我檢查cookie過期日期時,它不是當前日期加上200天,這是有點尷尬。

SignOut方法很簡單:

 public void IdentitySignout() 
     { 
      authenticationManager.SignOut(DefaultAuthenticationTypes.ApplicationCookie); 
     } 

所以,User.Identity現在與Identity.Name屬性SignalR樞紐訪問。

要做的事:通過類似User.Identity.Id的方式訪問Id屬性也不錯。據我所知,它需要實施自定義校長。 我還在考慮使用Cookie來實現某種會話,以在客戶端存儲會話ID,儘管它肯定比使用Identity需要更多的時間。

增加: 爲了獲得用戶ID,一個可能使用IdentityExtensions的擴展方法:

(在輪轂內)

Context.User.Identity.GetUserId() 

爲了這個工作,索賠用戶ID的值應該具有ClaimTypes.NameIdentifier類型。

var claims = new List<Claim>(); 
claims.Add(new Claim(ClaimTypes.NameIdentifier, userId.ToString())); 
claims.Add(new Claim(ClaimTypes.Name, userLogin)); 

更新2:

以下是關於這個問題,極大地幫助了我一些額外的鏈接。我不包含MS指南的鏈接,因爲它們很容易找到。

http://leastprivilege.com/2015/07/21/the-state-of-security-in-asp-net-5-and-mvc-6-claims-authentication/

http://weblog.west-wind.com/posts/2015/Apr/29/Adding-minimal-OWIN-Identity-Authentication-to-an-Existing-ASPNET-MVC-Application