現在ログインしているユーザーをMVC5で取得するために必要なことは、次のとおりです。
using Microsoft.AspNet.Identity;
[Authorize]
public IHttpActionResult DoSomething() {
string currentUserId = User.Identity.GetUserId();
}
現在、ASP.NET Coreを使用すると、これは機能するはずですが、エラーがスローされます。
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Http;
private readonly UserManager<ApplicationUser> _userManager;
[HttpPost]
[Authorize]
public async Task<IActionResult> StartSession() {
var curUser = await _userManager.GetUserAsync(HttpContext.User);
}
何か案は?
EDIT: Gerardoの応答は順調ですが、ユーザーの実際の「Id」を取得するために、これはうまくいくようです:
ClaimsPrincipal currentUser = this.User;
var currentUserID = currentUser.FindFirst(ClaimTypes.NameIdentifier).Value;
コードがMVCコントローラー内にあると仮定します。
public class MyController : Microsoft.AspNetCore.Mvc.Controller
Controller
基本クラスから、IClaimsPrincipal
プロパティからUser
を取得できます。
System.Security.Claims.ClaimsPrincipal currentUser = this.User;
クレームを直接確認できます(データベースへのラウンドトリップなし):
bool IsAdmin = currentUser.IsInRole("Admin");
var id = _userManager.GetUserId(User); // Get user id:
他のフィールドは、データベースのユーザーエンティティから取得できます。
依存性注入を使用してユーザーマネージャーを取得する
private UserManager<ApplicationUser> _userManager;
//class constructor
public MyController(UserManager<ApplicationUser> userManager)
{
_userManager = userManager;
}
そしてそれを使用します:
var user = await _userManager.GetUserAsync(User);
var email = user.Email;
Bearing Token Authを使用している場合、上記のサンプルはアプリケーションユーザーを返しません。
代わりに、これを使用してください:
ClaimsPrincipal currentUser = this.User;
var currentUserName = currentUser.FindFirst(ClaimTypes.NameIdentifier).Value;
ApplicationUser user = await _userManager.FindByNameAsync(currentUserName);
これはapsnetcore 2.0で機能します。以前のバージョンでは試していません。
コンテキストについては、ASP.NET Core 2 Webアプリケーションテンプレートを使用してプロジェクトを作成しました。次に、Webアプリケーション(MVC)を選択し、[認証の変更]ボタンをクリックして、[個人ユーザーアカウント]を選択します。
このテンプレートから多くのインフラストラクチャが構築されています。 ControllersフォルダーでManageController
を見つけます。
このManageController
クラスコンストラクターには、このUserManager変数を設定する必要があります。
private readonly UserManager<ApplicationUser> _userManager;
次に、このクラスの[HttpPost] Indexメソッドを見てください。これらの方法で現在のユーザーを取得します。
var user = await _userManager.GetUserAsync(User);
おまけとして、これは、AspNetUsersテーブルに追加したユーザープロファイルのカスタムフィールドを更新する場所です。ビューにフィールドを追加し、それらの値をIndexViewModelに送信します。IndexViewModelはこのPostメソッドに送信されます。デフォルトのロジックの後にこのコードを追加して、メールアドレスと電話番号を設定しました。
user.FirstName = model.FirstName;
user.LastName = model.LastName;
user.Address1 = model.Address1;
user.Address2 = model.Address2;
user.City = model.City;
user.State = model.State;
user.Zip = model.Zip;
user.Company = model.Company;
user.Country = model.Country;
user.SetDisplayName();
user.SetProfileID();
_dbContext.Attach(user).State = EntityState.Modified;
_dbContext.SaveChanges();
.NET Core 2.0では、ユーザーは基になる継承されたコントローラーの一部として既に存在します。通常どおりユーザーを使用するか、リポジトリコードに渡します。
[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme, Policy = "TENANT")]
[HttpGet("issue-type-selection"), Produces("application/json")]
public async Task<IActionResult> IssueTypeSelection()
{
try
{
return new ObjectResult(await _item.IssueTypeSelection(User));
}
catch (ExceptionNotFound)
{
Response.StatusCode = (int)HttpStatusCode.BadRequest;
return Json(new
{
error = "invalid_grant",
error_description = "Item Not Found"
});
}
}
これは、それを継承する場所です
#region Assembly Microsoft.AspNetCore.Mvc.Core, Version=2.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60
// C:\Users\BhailDa\.nuget\packages\Microsoft.aspnetcore.mvc.core\2.0.0\lib\netstandard2.0\Microsoft.AspNetCore.Mvc.Core.dll
#endregion
using System;
using System.IO;
using System.Linq.Expressions;
using System.Runtime.CompilerServices;
using System.Security.Claims;
using System.Text;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc.ModelBinding;
using Microsoft.AspNetCore.Mvc.ModelBinding.Validation;
using Microsoft.AspNetCore.Routing;
using Microsoft.Net.Http.Headers;
namespace Microsoft.AspNetCore.Mvc
{
//
// Summary:
// A base class for an MVC controller without view support.
[Controller]
public abstract class ControllerBase
{
protected ControllerBase();
//
// Summary:
// Gets the System.Security.Claims.ClaimsPrincipal for user associated with the
// executing action.
public ClaimsPrincipal User { get; }
誰かが興味を持っているなら、これは私のために働いた。主キーにintを使用するカスタムIDがあるため、GetUserAsyncメソッドをオーバーライドしました
GetUserAsyncのオーバーライド
public override Task<User> GetUserAsync(ClaimsPrincipal principal)
{
var userId = GetUserId(principal);
return FindByNameAsync(userId);
}
IDユーザーの取得
var user = await _userManager.GetUserAsync(User);
通常のGuid主キーを使用している場合、GetUserAsyncをオーバーライドする必要はありません。これは、トークンが正しく構成されていることを前提としています。
public async Task<string> GenerateTokenAsync(string email)
{
var user = await _userManager.FindByEmailAsync(email);
var tokenHandler = new JwtSecurityTokenHandler();
var key = Encoding.ASCII.GetBytes(_tokenProviderOptions.SecretKey);
var userRoles = await _userManager.GetRolesAsync(user);
var roles = userRoles.Select(o => new Claim(ClaimTypes.Role, o));
var claims = new[]
{
new Claim(JwtRegisteredClaimNames.Sub, user.UserName),
new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),
new Claim(JwtRegisteredClaimNames.Iat, DateTime.UtcNow.ToString(CultureInfo.CurrentCulture)),
new Claim(JwtRegisteredClaimNames.GivenName, user.FirstName),
new Claim(JwtRegisteredClaimNames.FamilyName, user.LastName),
new Claim(JwtRegisteredClaimNames.Email, user.Email),
}
.Union(roles);
var tokenDescriptor = new SecurityTokenDescriptor
{
Subject = new ClaimsIdentity(claims),
Expires = DateTime.UtcNow.AddHours(_tokenProviderOptions.Expires),
SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256Signature)
};
var token = tokenHandler.CreateToken(tokenDescriptor);
return Task.FromResult(new JwtSecurityTokenHandler().WriteToken(token)).Result;
}
Controllerクラスに次のようなものを入れましたが、うまくいきました。
IdentityUser user = await userManager.FindByNameAsync(HttpContext.User.Identity.Name);
ここで、userManagerはMicrosoft.AspNetCore.Identity.UserManagerクラスのインスタンスです(それに伴うすべての奇妙なセットアップ)。