2016-09-13 26 views
0

Ich habe eine ASP.NET MVC Kern Website mit einer Verbindung SQLite Daten mit ASP.NET Kern Berechtigung wie folgt aus:Rolle Aufenthalt ‚Berechtigungen‘, wenn Rolle ändern

// Startup.ConfigureServices 
services.AddAuthorization(e => 
{ 
    e.AddPolicy(Policies.UserRead, b => b.RequireRole("Editor", "Root")); 
} 

Dies ist eine der Maßnahmen, die den Zugang einschränkt zu Site mit Benutzerinformationen. (Policies.UserRead ist eine Konstante string). Diese Politik wird dann auf die Ansicht wie folgt angewandt:

[Authorize(Policies.UserRead)] 
public async Task<IActionResult> Index() 
{ 
} 

Dies funktioniert gut und nur Benutzer mit der Rolle Editor oder Root die Ansicht zugreifen können. Probleme treten jedoch auf, wenn die Rolle eines Benutzers geändert wird, während er eingeloggt ist, z.

  • Benutzer A (Rolle Editor) anmeldet und verwendet Index()-Erfolg
  • Benutzer B (Rolle Root) anmeldet und entfernt die Rolle Editor von Benutzer A
  • Ein Benutzer verwendet Index()-noch Erfolg

Sie würden erwarten, dass Benutzer A nicht aufzugreifen kannnicht mehr, weil er nicht mehr die Rolle Editor. Aber er kann es immer noch - solange er sich nicht abmeldet und sich wieder anmeldet, denn das erneute Einloggen behebt dieses Problem. Es scheint, als habe jemand (ich glaube, ClaimsPrincipal die Schuldige hier sind), um die Rolle zwischengespeichert - die OK wäre, wenn ich weiß, wie der Cache ...


Rollenwechselcode ungültig zu machen:

// get the user whos role is changed 
var targetUser = await _context.Users.SingleOrDefaultAsync(m => m.Id == model.Id); 
if (targetUser == null) return NotFound(); 

// get the user who changes the role 
var sourceUser = await _userManager.GetUserAsync(User); 
if (sourceUser == null) return RedirectToAction("Index"); 

// remove the current role 
await _userManager.RemoveFromRoleAsync(targetUser, targetUser.Role.ToString()); 

// add to the new role 
await _userManager.AddToRoleAsync(targetUser, model.Role.ToString()); 

// update & save the changes 
_context.Update(targetUser); 
await _context.SaveChangesAsync(); 

Dies ist im Grunde der Code, den ich benutze, um die Rolle eines Benutzers zu ändern (ich schneide die Ansicht/Modellteile aus, weil sie irrelevant sind). Anmerkungen:

  • targetUser und sourceUser beide ApplicationUser (die implementiert IdentityUser).

  • _userManger ist - wer hätte das gedacht - vom Typ UserManager<ApplicationManger>


Ich habe versucht, den Benutzer mit SignInManger<> Relog aber es scheint, wie Sie nur den aktuellen Benutzer abmelden kann - was würde Der Benutzer ändert die Rolle und nicht der Benutzer, dessen Rolle geändert werden soll.


Was fehlt mir? Es wäre nett, wenn der Benutzer nichts tun würde (z. B. sich wieder anmelden), um die Benutzerrolle "" zu aktualisieren.

+0

Verwenden Sie die Cookie-Authentifizierung? – Brad

Antwort

1

Das Problem ist, dass die Rollenansprüche des Benutzers im Cookie gespeichert werden (Standardimplementierung von aspnet identity). Wenn sich der Benutzer nicht abmeldet, selbst wenn sich die Rollen des Benutzers ändern, ändert sich das Autorisierungsergebnis nicht. Die Lösung ist ValidateAsync Ereignis zu verwenden. Example existiert in der offiziellen Dokumentation.

Eine andere mögliche Lösung besteht darin, Rollenansprüche aus dem Cookie auszuschließen und die Schadentransformation zu verwenden.

Dazu müssen Sie die CreateAsync Methode von UserClaimsPrincipalFactory überschreiben, siehe hierzu article, um die Ansprüche zu ändern. Dann können Sie claims transformation verwenden, um Rollenansprüche hinzuzufügen.