1

Neu bei Authorization and Authentication, so fehlt mir vielleicht ein wichtiger Schritt ... Nur zahlreiche Referenzen, Anleitungen und Tutorials.Zugriff auf ASP.Net-Web-API oder Autorisierung nach dem Festlegen von Thread und HttpContext Principal

Ich muss möglicherweise etwas in meiner WebApiConfig tun?

public static class WebApiConfig 
{ 
    public static void Register(HttpConfiguration config) 
    { 
     config.MapHttpAttributeRoutes(); 

     config.Routes.MapHttpRoute(
      name: "DefaultApi", 
      routeTemplate: "api/{controller}/{id}", 
      defaults: new { id = RouteParameter.Optional } 
     ); 
    } 
} 

Oder vielleicht in meinem Global.asax:

public class WebApiApplication : System.Web.HttpApplication 
{ 
    private const string RootDocument = "/index.html"; 
    protected void Application_Start() 
    { 
     GlobalConfiguration.Configure(WebApiConfig.Register); 
    } 

    protected void Application_BeginRequest(Object sender, EventArgs e) 
    { 
     // Stuff to redirect to index.html unless it's an api url 
    } 
} 

Dies ist ein ASP.Net Web-API-Projekt .NET Framework Targeting 4.5.2 mit einem Schräg 2 Frontend und ich nichts tun, manuell auf die Frontend, vielleicht muss ich das tun? Mein lokaler Speicher, Sitzungsspeicher und Cookies sind im Browser leer.

Der SQL Server ich Zugriff auf eine sehr einfache Methode der Benutzeranmeldung, die eine Rolle und userId zurückgibt, die ich in meinem Repository aufrufen:

public static DbUser Logon(AuthUser user) 
    { 
     var parameters = new List<SqlParameter>(); 
     { 
      // Add parameters, get the DbUser (contains role and userId), and return the DbUser 
     } 
    } 

Logon-Frontend mit kantigem 2 eingebaut ist und macht ein Httppost mit Benutzername und Passwort nennen die folgenden API-Methode einreichen auf, eine Identität und Haupt und Einstellen des Gewinde Erstellen und Httpcontext:

// POST api/<controller> 
    [HttpPost] 
    public TokenUser Post(AuthUser user) 
    { 
     var dbUser = DBAccess.Repository.User.Logon(user); 

     var identity = new ClaimsIdentity(); 
     identity.AddClaim(new Claim(ClaimTypes.Name, "CwRole")); 
     identity.AddClaim(new Claim(ClaimTypes.Role, dbUser.AccessLevel)); 
     identity.AddClaim(new Claim(ClaimTypes.UserData, dbUser.ID.ToString())); 

     var principal = new ClaimsPrincipal(identity); 
     Thread.CurrentPrincipal = principal; 
     if (HttpContext.Current != null) 
      HttpContext.Current.User = principal; 

     // Other stuff and a return statement => 
     // Note I'm not actually doing anything manually with the token on the front end 
     // which may be why I'm not seeing it in the debugger's Resources tab... 
    } 

Wenn ich durch diesen Code Schritt kann ich deutlich sehen, dass Thread.CurrentPrincipal und Httpcontext .Current.User beide werden bevölkert, wie es scheint.

Aber wenn ich eine Aktion mit dem Attribut [Autorisieren] dekorieren, kann ich nicht darauf zugreifen, ob eingeloggt oder nicht.

 // Works fine 
     public IEnumerable<ItemGroup> Get() 
     { 
      return DBAccess.Repository.Item.GetItemGroups(); 
     } 

     // Responds with 401 (Unauthorized) no matter what 
     [Authorize] 
     public IEnumerable<RequestItem> Get() 
     { 
      return DBAccess.Repository.Item.GetRequestItems(); 
     } 

Also habe ich diese Methoden, zugegriffen sie über Browser-URL nach dem oben genannten Anmeldevorgang und trat durch, nur um festzustellen, dass der Benutzer nie wirklich gesetzt (Ansprüche alle leer sind, etc ...)

public class AuthController : ApiController 
{ 
    public bool Get() 
    { 
     // Stepping through, looks like User.Identity is not even set... 
     var authenticated = User.Identity.IsAuthenticated; 
     return authenticated; 
    } 

    public bool Get(string role) 
    { 
     // As a matter of fact, User doesn't have any claims or anything... 
     var user = User; 
     return user != null && user.IsInRole(role); 
    } 
} 

Also welchen Schritt fehlt mir, um den Principal zugänglich zu machen, nachdem er gesetzt wurde? Muss ich mit etwas anderem als den integrierten "Benutzer" -Methoden von WebApi darauf zugreifen oder etwas in meiner Konfiguration einstellen oder etwas manuell am Frontend tun?

+0

Woher kommt 'user' in' var dbUser = DBAccess.Repository.User.Logon (user); 'kommen Sie aus und wo führen Sie dieses Code-Snippet aus? Bitte geben Sie eine [MCVE] an. Ihre Snippets sind momentan nicht verbunden. – Nkosi

+0

Der Autorisierungsanbieter sollte in der webapiconfig.cs.Read hier hinzugefügt werden http://www.asp.net/web-api/overview/security/individual-accounts-in-web-api –

+0

@Nkosi Danke für die Rückmeldung. Ich habe Details hinzugefügt. Ich hasse es einfach, eine Menge Code in die Frage zu stecken, wenn ich nicht sicher bin, was für das Problem relevant ist ... – Methodician

Antwort

1

Sie verwenden die Anspruchsauthentifizierung, sodass Sie bei erfolgreicher Authentifizierung ein Token erhalten.Also, um das Token für die nachfolgenden/folgende Web-Api-Anfragen bestehen bleiben Sie auf einen der folgenden Wege tun müssen, bestehen

  1. Sie haben die Authentifizierung Detail zu einem Cookie setzen, die automatisch vom Browser angehängt werden alle nachfolgenden Anfragen ODER
  2. Sie können den Token im lokalen Speicher des Browsers für folgende Anfrage persistieren: Sie müssen das Claims Bearer Token an den Anforderungskopf [zur Authentifizierung] anhängen.

Option 1:

Einstellen Authentifizierungs-Cookie

FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(1, username, DateTime.Now, DateTime.Now.AddMinutes(30), true, userData); 
     string encTicket = FormsAuthentication.Encrypt(ticket); 
     HttpCookie faCookie = new HttpCookie(FormsAuthentication.FormsCookieName, encTicket); 
     Response.Cookies.Add(faCookie); 

Zugriff auf das Cookie zur Authentisierung in nachfolgenden Anforderungen.

HttpCookie authCookie = Request.Cookies[ 
      FormsAuthentication.FormsCookieName]; 
    if(authCookie != null) 
    { 
     //Extract the forms authentication cookie 
     FormsAuthenticationTicket authTicket = 
       FormsAuthentication.Decrypt(authCookie.Value); 
     // Create an Identity object 
     //CustomIdentity implements System.Web.Security.IIdentity 
     CustomIdentity id = GetUserIdentity(authTicket.Name); 
     //CustomPrincipal implements System.Web.Security.IPrincipal 
     CustomPrincipal newUser = new CustomPrincipal(); 
     Context.User = newUser; 
    } 

Option 2:

Sie können das Token erhalten und es zu Browser Local Storage speichern, und wann immer Sie eine Anfrage an jede API mit Autorisieren Stichwort machen, stellen Sie sicher, dass Sie die Bearer hinzufügen Token zum Anfrage-Header.

So etwas wie dieses

var authData = localStorageService.get('authorizationData'); 
     if (authData) { 
      config.headers.Authorization = 'Bearer ' + authData.token; 
     } 

Nach Artikel beschreibt die Token basierende Authentifizierung und hat Codebeispiel für Angular JS, sondern nur noch einen Blick http://bitoftech.net/2015/02/16/implement-oauth-json-web-tokens-authentication-in-asp-net-web-api-and-identity-2/

Schließlich

Für die Validierung auf dem Server Seite können Sie eine benutzerdefinierte Autorisierung anstelle der Standard schreiben, um das Token zu validieren und die Identität entsprechend festzulegen.

+0

Danke. Ich arbeite jetzt aber in Bezug auf den verlinkten Artikel: Ich kann Entity Framework nicht mit diesem Legacy-System verwenden und so weit ich weiß, schließt dies die Verwendung von "UserManager" und wahrscheinlich OAuth im Allgemeinen aus oder ich kann einfach nicht übersetzen ... – Methodician

+0

Ich habe ein StackOverflow-Thema zur ASP.Net-Mitgliedschaft mit Entity Framework gefunden. Hoffe, das hilft - http://Stackoverflow.com/a/6449001/2952405 –

+0

Also habe ich Ihre Antwort durchgearbeitet und stieß auf ein Problem, wo Response.Cookies.Add() nicht verfügbar ist, da dies ein ApiController ist, kein MVC-Controller ... – Methodician

0

OnAuthorization Ereignis tritt sehr früh in der Pipeline auf. Jede Art von ActionFilter läuft danach. Wie ich denke, haben Sie Ihren Authentifizierungscode (erstes Snippet) im Aktionsfilter oder irgendwo, das nach OnAuthorization Ereignis ausgeführt wird, geschrieben.

sollten Sie bedenken, dass Code, beispielsweise Übertragung dieses Ereignis (in global.asax.cs)

Application_PostAuthenticateRequest(Object sender, EventArgs e).

Und die elegantere Art und Weise ist Ihre individuellen AuthorizeAttribute zu implementieren und Benutzerinformationen von Request und setzen Principals bekommen.

Verwandte Themen