Um den aktuell in MVC5 angemeldeten Benutzer zu erhalten, mussten wir lediglich Folgendes tun:
using Microsoft.AspNet.Identity;
[Authorize]
public IHttpActionResult DoSomething() {
string currentUserId = User.Identity.GetUserId();
}
Mit ASP.NET Core dachte ich, dass dies funktionieren sollte, aber es gibt einen Fehler.
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);
}
Irgendwelche Ideen?
EDIT: Gerardos Antwort ist auf dem richtigen Weg, aber um die tatsächliche "ID" des Benutzers zu erhalten, scheint dies zu funktionieren:
ClaimsPrincipal currentUser = this.User;
var currentUserID = currentUser.FindFirst(ClaimTypes.NameIdentifier).Value;
.GetUserAsync()
ist langsamer, weil es in die DB geht.Antworten:
Angenommen, Ihr Code befindet sich in einem MVC-Controller:
public class MyController : Microsoft.AspNetCore.Mvc.Controller
Von der
Controller
Basisklasse können Sie dieIClaimsPrincipal
von derUser
Eigenschaft erhaltenSystem.Security.Claims.ClaimsPrincipal currentUser = this.User;
Sie können die Ansprüche direkt überprüfen (ohne einen Roundtrip zur Datenbank):
bool IsAdmin = currentUser.IsInRole("Admin"); var id = _userManager.GetUserId(User); // Get user id:
Andere Felder können von der Benutzerentität der Datenbank abgerufen werden:
Holen Sie sich den Benutzermanager mithilfe der Abhängigkeitsinjektion
private UserManager<ApplicationUser> _userManager; //class constructor public MyController(UserManager<ApplicationUser> userManager) { _userManager = userManager; }
Und benutze es:
var user = await _userManager.GetUserAsync(User); var email = user.Email;
quelle
IHttpContextAccessor
mit Abhängigkeitsinjektion empfangen und dann dieUser
aus dem http-Kontext abrufen . Fügen Sie einfach diesen Parameter zum Serviceklassenkonstruktor hinzu :IHttpContextAccessor contextAccessor
. Halten Sie den Accessor auf einem Feld_contextAccessor
und holen Sie ihn dann über die Servicemethoden ab_contextAccessor.HttpContext.User
.Wenn Sie Bearing Token Auth verwenden, geben die obigen Beispiele keinen Anwendungsbenutzer zurück.
Verwenden Sie stattdessen Folgendes:
ClaimsPrincipal currentUser = this.User; var currentUserName = currentUser.FindFirst(ClaimTypes.NameIdentifier).Value; ApplicationUser user = await _userManager.FindByNameAsync(currentUserName);
Dies funktioniert in apsnetcore 2.0. Habe es in früheren Versionen nicht versucht.
quelle
Für den Kontext habe ich ein Projekt mit der ASP.NET Core 2-Webanwendungsvorlage erstellt. Wählen Sie dann die Webanwendung (MVC) aus, klicken Sie auf die Schaltfläche Authentifizierung ändern und wählen Sie Einzelbenutzerkonten aus.
Aus dieser Vorlage wird eine Menge Infrastruktur für Sie aufgebaut. Suchen Sie die
ManageController
im Ordner Controller.Für diesen
ManageController
Klassenkonstruktor muss diese UserManager-Variable ausgefüllt sein:private readonly UserManager<ApplicationUser> _userManager;
Schauen Sie sich dann die Indexmethode [HttpPost] in dieser Klasse an. Sie erhalten den aktuellen Benutzer auf diese Weise:
var user = await _userManager.GetUserAsync(User);
Als Bonus-Hinweis möchten Sie hier alle benutzerdefinierten Felder des Benutzerprofils aktualisieren, das Sie der AspNetUsers-Tabelle hinzugefügt haben. Fügen Sie die Felder zur Ansicht hinzu und senden Sie diese Werte an das IndexViewModel, das dann an diese Post-Methode gesendet wird. Ich habe diesen Code nach der Standardlogik hinzugefügt, um die E-Mail-Adresse und die Telefonnummer festzulegen:
quelle
In .NET Core 2.0 ist der Benutzer bereits als Teil des zugrunde liegenden geerbten Controllers vorhanden. Verwenden Sie den Benutzer einfach wie gewohnt oder geben Sie ihn an einen beliebigen Repository-Code weiter.
[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" }); } }
Hierher erbt es es
#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; }
quelle
Nur wenn jemand interessiert ist, hat das bei mir funktioniert. Ich habe eine benutzerdefinierte Identität, die int für einen Primärschlüssel verwendet, sodass ich die GetUserAsync-Methode überschrieben habe
GetUserAsync überschreiben
public override Task<User> GetUserAsync(ClaimsPrincipal principal) { var userId = GetUserId(principal); return FindByNameAsync(userId); }
Identitätsbenutzer abrufen
var user = await _userManager.GetUserAsync(User);
Wenn Sie einen regulären Guid-Primärschlüssel verwenden, müssen Sie GetUserAsync nicht überschreiben. Dies setzt voraus, dass Ihr Token korrekt konfiguriert ist.
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; }
quelle
private readonly UserManager<AppUser> _userManager; public AccountsController(UserManager<AppUser> userManager) { _userManager = userManager; } [Authorize(Policy = "ApiUser")] [HttpGet("api/accounts/GetProfile", Name = "GetProfile")] public async Task<IActionResult> GetProfile() { var userId = ((ClaimsIdentity)User.Identity).FindFirst("Id").Value; var user = await _userManager.FindByIdAsync(userId); ProfileUpdateModel model = new ProfileUpdateModel(); model.Email = user.Email; model.FirstName = user.FirstName; model.LastName = user.LastName; model.PhoneNumber = user.PhoneNumber; return new OkObjectResult(model); }
quelle
Ich habe so etwas in meine Controller-Klasse aufgenommen und es hat funktioniert:
IdentityUser user = await userManager.FindByNameAsync(HttpContext.User.Identity.Name);
Dabei ist userManager eine Instanz der Microsoft.AspNetCore.Identity.UserManager-Klasse (mit allen damit verbundenen seltsamen Einstellungen).
quelle