2017-07-08 4 views
0

Ich arbeite an der Web-API mit AngularJS. Ich hatte Web-API-Token-Mechanismus vor wenigen Tagen implementiert und in der Lage, die Anwendung mit dem Zugriffstoken anzumelden. Ich habe externe DB-Tabelle anstelle von ASP.NET-Identitätstabelle verwendet, um Benutzer zu autorisieren.Wie man Benutzerinformationen nach Anmeldung und Zugriff auf mehrere WEB-API-Controller an einem Ort speichert

Ich möchte Benutzerinformationen in der Klasse speichern, so dass sie leicht von verschiedenen Controllern zugegriffen werden kann, nachdem Benutzer angemeldet ist. Derzeit verwende ich ClaimsIdentity in Controller-Klasse, um die Benutzerinformationen zu erhalten.

UserIdentityViewModel.cs

public class UserIdentityViewModel 
    { 
     public string UserName { get; set; } 
     public Guid UserId { get; set; } 
    } 

Startup.cs

public class Startup 
    { 
     public void Configuration(IAppBuilder app) 
     {     
      app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll); 
      var myProvider = new AuthorizationServerProvider(); 
      OAuthAuthorizationServerOptions options = new OAuthAuthorizationServerOptions 
      { 
       AllowInsecureHttp = true, 
       TokenEndpointPath = new PathString("/Token"), 
       AccessTokenExpireTimeSpan = TimeSpan.FromDays(1), 
       Provider = myProvider 
      }; 
      app.UseOAuthAuthorizationServer(options); 

      app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions()); 
     } 
    } 

AuthorizationServerProvider.cs

public class AuthorizationServerProvider : OAuthAuthorizationServerProvider 
    { 
     public override async Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context) 
     { 
      context.Validated(); // 
     } 

     public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context) 
     {   
      string userId = context.UserName; 
      string password = context.Password; 

      EmployeeAccessBLL chkEmpAccessBLL = new EmployeeAccessBLL(); 
      EmployeeAccessViewModel vmEmployeeAccess = chkEmpAccessBLL.CheckEmployeeAccess(Convert.ToInt32(userId), password); 

      if(vmEmployeeAccess != null) 
      { 
       var identity = new ClaimsIdentity(context.Options.AuthenticationType); 
       identity.AddClaim(new Claim("username", vmEmployeeAccess.EmpName)); 
       identity.AddClaim(new Claim("userid", Convert.ToString(vmEmployeeAccess.EmployeeId))); 

       UserIdentityViewModel vmUser = new UserIdentityViewModel(); 
       vmUser.UserId = vmEmployeeAccess.EmployeeId; 
       vmUser.UserName = vmEmployeeAccess.EmpName; 

       context.Validated(identity); 
      } 
      else 
      { 
       context.SetError("invalid_grant", "Provided username and password is incorrect"); 
       return; 
      } 
     }  
    } 

EventController.cs

public class StreamEventController : ApiController 
    { 
     [Authorize] 
     [Route("api/addevent")] 
     [HttpPost] 
     public List<string> AddEvent(StreamEventViewModel vmEvent) 
     { 
      //Able to get User Information from Identity.Claims 
      var identity = (ClaimsIdentity)User.Identity; 
      string userId = identity.Claims 
          .Where(c => c.Type == "userid") 
          .Select(c => c.Value).FirstOrDefault(); 

      //Not able to get User Information from following as new object instance gets created 
      UserIdentityViewModel vmUser = new UserIdentityViewModel(); 

      vmEvent.CreatedBy = vmUser.UserId; 
      vmEvent.ModifiedBy = vmUser.UserId; 
     } 
} 

Statt zu schreiben „Identity.Claims“ in jedem Verfahren von jedem Controller ich einfach get/set-Ansatz oder eine andere Methode zu erhalten Benutzerinformationen verwenden möchten. Die Verwendung der statischen Klasse ist meiner Meinung nach auch schlecht, da sie eine Information des Benutzers speichert und mehrere Benutzer-Login-Informationen übersehen werden.

Bitte helfen Sie mir und teilen Sie mir den besten Ansatz, der in anderen Web-API-Projekten für die Anmeldung verwendet wurde.

Antwort

1

Sie können eine private Variable hinzufügen, die im Konstruktor des Reglers festgelegt werden, wie folgt aus:

// Should only be used in protected methods. 
private ClaimsIdentity ThisUser = null; 

public MyController() 
{ 
    if (User.Identity.IsAuthenticated) 
     ThisUser = (ClaimsIdentity)User.Identity; 
} 

[Authorize] 
[Route("api/addevent")] 
[HttpPost] 
public List<string> AddEvent(StreamEventViewModel vmEvent) 
{ 
    string userId = ThisUser.FindFirstValue("userid"); 

} 

oder eine Benutzerklasse erstellen, in dem Sie alle Eigenschaften laden:

private UserClass ThisUser = null; 

public MyController() 
{ 
    if (User.Identity.IsAuthenticated) 
     ThisUser = new UserClass(User); 
} 

[Authorize] 
[Route("api/addevent")] 
[HttpPost] 
public List<string> AddEvent(StreamEventViewModel vmEvent) 
{ 
    string userId = ThisUser.UserId; 

} 

Wo UserClass ist etwas wie:

public class UserClass 
{ 
    public string UserId { get; private set; } 

    public UserClass(IPrincipal user) 
    { 
     UserId = user.FindFirstValue("userid"); 
    } 
} 

Aber das ist nur Overhead für die gleiche Sache. Sie können Dinge in eine Erweiterung verschieben. In diesem Fall erhalten Sie so etwas wie:

public static class RequestExtensions 
{ 
    public static UserClass GetUser(this HttpRequestMessage request) 
    { 
     return new UserClass(request.GetOwinContext().Authentication.User); 
    } 

    public static ClaimsIdentiy GetUser2(this HttpRequestMessage request) 
    { 
     return new (ClaimsIdentity)request.GetOwinContext().Authentication.User; 
    } 
} 

Welche Sie können auch anrufen:

[Authorize] 
[Route("api/addevent")] 
[HttpPost] 
public List<string> AddEvent(StreamEventViewModel vmEvent) 
{ 
    string userId = Request.GetUser.UserId; 

    string userId2 = Request.GetUser2.FindFirstValue("userid"); 

} 

ich glaube, ich würde gehen für Request.GetUser2.FindFirstValue("userid");

Der Code, den Sie soll eine Idee geben. Ich habe den Code nicht getestet, aber ich denke, es sollte funktionieren.

+0

Vielen Dank Ruard für die besten Optionen. Wie Sie erwähnt haben, habe ich versucht und erhalten ein erfolgreiches Ergebnis mit den Erweiterungsmethoden. – user1843970

Verwandte Themen