2017-08-15 6 views
15

Im Erstellen einer Website mit einer API, benötigt die API Validierung, so dass der Benutzer nur seine eigenen Daten erhält. Ich habe die folgende Middleware geschrieben, um den Login zu validieren..net-core middleware return blank Ergebnis

public class ApiAuthenticationMiddleware 
{ 
    private readonly RequestDelegate _next; 
    private readonly UserManager<ApplicationUser> _userManager; 
    private readonly SignInManager<ApplicationUser> _signInManager; 

    public ApiAuthenticationMiddleware(RequestDelegate next, 
     SignInManager<ApplicationUser> signInManager, 
     UserManager<ApplicationUser> usermanager) 
    { 
     _next = next; 
     _signInManager = signInManager; 
     _userManager = usermanager; 
    } 

    public async Task Invoke(HttpContext context) 
    { 
     if (!context.Request.Query.ContainsKey("password") || !context.Request.Query.ContainsKey("email")) 
     { 
      context.Response.StatusCode = 401; //UnAuthorized 
      await context.Response.WriteAsync("Invalid User Key"); 
      return; 
     } 
     var email = context.Request.Query["email"]; 
     var password = context.Request.Query["password"]; 

     var result = await _signInManager.PasswordSignInAsync(email, password, false, lockoutOnFailure: false); 
     if (result.Succeeded) 
     { 
      await _next.Invoke(context); 
     } 
     else if (//some more checks) 
      context.Response.StatusCode = 401; //UnAuthorized 
      await context.Response.WriteAsync("Invalid User Key"); 
      return; 
     } 
    } 
} 

Was ich will, ist, dass eine leere Seite oder eine Fehlermeldung wie „Invalid User Key“ wird angezeigt, wenn der Benutzer keine gültige Anmeldung hat. Wie auch immer, im Moment wird die Homepage zurückgegeben (weil meine Middleware vor usemvc aufgerufen wird und die return-Anweisung die Controller-Anfrage von usemvc überspringt).

Mein entsprechender Code in der configure-Methode in startup.cs

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) 
    { 

     app.UseIdentity(); 
     app.UseWhen(x => (x.Request.Path.StartsWithSegments("/api", StringComparison.OrdinalIgnoreCase)), 
      builder => 
      { 
       builder.UseMiddleware<ApiAuthenticationMiddleware>(); 
      }); 
     app.UseStaticFiles(); 
     app.UseMvc(routes => 
     { 
      routes.MapRoute(
       name: "default", 
       template: "{controller=Home}/{action=Index}/{id?}"); 
     }); 
    } 

Wie kann ich meine Middleware mache eine leere Seite mit dem Statuscode zurückgeben?

Bitte erklären Sie den Grund, wenn Sie den Vorschlag ablehnen, damit ich die Frage verbessern kann und weiß, was ich falsch gemacht habe.

aktualisieren

Nachdem eine Menge Dinge versuchen, fand ich, dass, wenn ich zu entfernen:

context.Response.StatusCode = 401; //UnAuthorized 

Es funktioniert wie erwartet, der Benutzer die Nachricht in gegeben wird:

await context.Response.WriteAsync("Invalid User Key"); 

Howerver Ich möchte nicht, dass der Benutzer einen 200 Statuscode bei der Anmeldung erhält, sondern einen 401 Statuscode. Bei Verwendung der Statuscodezeile wird der Benutzer jedoch umgeleitet. Wie kann ich den Statuscode ohne Umleitung senden?

+0

Warum nicht 'mit Authorize' Attribute – CodeNotFound

+0

Autorisieren ein Benutzer übernehmen in (via Cookie, wenn im richtigen) angemeldet ist Im eine API für eine mobile App zu machen, so dass der App sendet Anfragen, die von einem gültigen sein muss. Authorize wird auch auf die Registrierungsseite umleiten, wenn sie nicht eingeloggt ist, was nicht das Verhalten ist, das ich für meine API haben möchte. –

+0

Ich würde mir die OpenId Middleware ansehen. Diese Middleware arbeitet mit dem Autorize-Attribut –

Antwort

4

Ich habe eine Ahnung, dass app.UseIdentity() Standardverhalten hat, dass wenn eine 403/401 auftritt, wird es die Antwort abfangen und eine Umleitung initiieren. Versuchen Sie es auskommentieren und sehen, ob es funktioniert.

Alternative Lösung zu finden unter: https://stackoverflow.com/a/43456151/3948882

Letzte Bemerkung: Ich stark ermutigen, keine Anmeldeinformationen für jede Anforderung übergeben. Ich empfehle, vorgefertigte Auth-Provider zu verwenden und als Middleware zu implementieren. Das Authorize Attribut sollte für Anforderungen ausreichen und kann tun, was Sie suchen. Wenn Sie etwas Besonderes zurückgeben möchten, können Sie die Antwort mit Middleware überschreiben, wie die app.UseIdentity() Middleware möglicherweise umleiten.

0

Versuchen Sie, .Clear() zu verwenden, bevor Sie den StatusCode setzen.

  context.Response.Clear(); 
      context.Response.StatusCode = (int)HttpStatusCode.Unauthorized; 
      await context.Response.WriteAsync("Unauthorized");