2016-07-23 29 views
12

對於ASP.NET Core的不同RC,在如何獲取當前登錄用戶的標識中存在大量不同的答案。我想在這裏問一個確定的問題。請注意,project.json現擁有「Microsoft.AspNetCore.Identity.EntityFrameworkCore」:「1.0.0」在Entity Framework Core中獲取當前用戶標識的正確方法

在RC1中,你可以做這樣的事情:

using Microsoft.AspNet.Identity; 
using System.Security.Claims; 

User.GetUserId(); 

但隨着新發布的版本EF核心1,Microsoft.AspNet.Identity不是正確的版本。

有建議使用的UserManager,這似乎是很多剛剛拿到當前登錄的用戶:

private Task<ApplicationUser> GetCurrentUserAsync() => _userManager.GetUserAsync(HttpContext.User); 

var user = await GetCurrentUserAsync(); 
var userId = user?.Id; 

另一種方法,我發現是:

private readonly UserManager<ApplicationUser> _userManager; 
_userManager.GetUserId(User) 
與ASP

左右。 NET Core 1 RTM和EF Core 1與project.json中的以下庫,獲取當前登錄用戶的ID的正確方法是什麼?

"Microsoft.AspNetCore.Identity.EntityFrameworkCore": "1.0.0", 
"Microsoft.AspNetCore.Mvc": "1.0.0", 
+0

請不要將標籤置於問題標題! http://stackoverflow.com/help/tagging – Tseng

回答

11

ASP.NET核心身份在startup.cs通過DI注入 - 這樣你只需要通過一個構造注入的UserManager

UserManager<ApplicationUser> userManager 

然後,您可以使用方法如下

_userManager.GetUserId(User); 

當您使用個人用戶帳戶創建新的ASP.NET Core 1項目時,這就是它在示例Web應用程序中使用的方式。

16

如果從withing控制器,然後使用的UserManager來獲得用戶ID訪問,這是非常低效的,因爲你是一個往返到數據庫。如果您正在使用ClaimsIdentity,你可以做這樣的事情來獲得用戶ID:

var claimsIdentity = (ClaimsIdentity)this.User.Identity; 
var claim = claimsIdentity.FindFirst(System.Security.Claims.ClaimTypes.NameIdentifier); 
var userId = claim.Value; 

這種方法只是讀這已經是存在於餅乾,而這又是自動反序列化,並存儲用戶ID在ClaimsIdentity實例中。

我用這個輔助類:

public static class UserHelpers 
{ 
    public static string GetUserId(this IPrincipal principal) 
    { 
     var claimsIdentity = (ClaimsIdentity)principal.Identity; 
     var claim = claimsIdentity.FindFirst(System.Security.Claims.ClaimTypes.NameIdentifier); 
     return claim.Value; 
    } 
} 

所以得到一個用戶ID變爲:

var userId = this.User.GetUserId(); 

如果由於某種原因,所需要的要求是不存在於權利要求 colleciton,您可以在創建用戶時輕鬆添加它ClaimsIdentity

public class ApplicaionUser : IdentityUser 
{ 
    public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<User> manager) 
    { 
     var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie); 
     userIdentity.AddClaim(new Claim(ClaimTypes.NameIdentifier, this.UserId)); 
     return userIdentity; 
    } 
} 
+0

即時通訊沒有內置的方式來獲取當前登錄的用戶名。此方法與舊的Users.Identity.GetUserId()的工作方式或行爲方式有何不同? – Reza

+0

此方法使用與舊的GetUserId相同的基本邏輯。區別在於,您可以直接在User對象而不是User.Idenity對象上調用它。檢查這個答案的比較http://stackoverflow.com/a/28520274/1396972。我相信他們之所以刪除它是因爲對ClaimsIdentity的投訴,這違反了LSP。 –

+0

用於框架4.5.2上的asp.net核心應用程序。添加nuget軟件包Microsoft.AspNet.Identity引起歧義並與現有框架引用發生衝突。 –

2

下面的單行是上面其他答案的更簡潔的版本。

var user = User.FindFirst(ClaimTypes.NameIdentifier).Value; 

爲了解釋遠一點,我想用認證的最基本的形式,而不在數據庫中的任何表,所以我選擇了這一個 - 從核心文檔 Using Cookie Authentication without ASP.NET Core Identity

得到這個工作,第一步是在Startup.cs中的AccountController添加服務

services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme) 
    .AddCookie(CookieAuthenticationDefaults.AuthenticationScheme, options => 
     { 
     options.LoginPath = new PathString("/Account/Login/"); 
     options.LogoutPath = new PathString("/Account/Logoff/"); 
     options.AccessDeniedPath = new PathString("/Account/AccessDenied/"); 
     options.Cookie.SecurePolicy = CookieSecurePolicy.SameAsRequest; 
     }); 

services.ConfigureApplicationCookie(identityOptionsCookies => 
{ 
    // See https://andrewlock.net/automatically-validating-anti-forgery-tokens-in-asp-net-core-with-the-autovalidateantiforgerytokenattribute/ 
    identityOptionsCookies.Cookie.SecurePolicy = CookieSecurePolicy.SameAsRequest; 
}); 

然後在回傳已進入一個有效的用戶ID和密碼,以最簡單的聲明身份驗證只是將登錄ID添加爲聲明,例如

變種權利要求=新列表 { 新要求(ClaimTypes.NameIdentifier,loginViewModel.Guid,ClaimValueTypes.String,發行人), };

  var claimsIdentity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme); 

      var principal = new ClaimsPrincipal(claimsIdentity); 

      await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, principal, 
       new AuthenticationProperties 
       { 
        ExpiresUtc = DateTime.UtcNow.AddMinutes(_cookieTimeoutInMinutes), 
        IsPersistent = true, 
        AllowRefresh = false 
       }); 

登錄完成後,您可以按上述一行代碼中所述檢索用戶標識。有關更詳細的步驟,請參閱上面的Milos Mrdovic的回答。

var user = User.FindFirst(ClaimTypes.NameIdentifier).Value; 

有關更多信息,請參閱Claims-Based Authorization

+0

完成@PetterFriberg :)。 –

相關問題