2017-08-15 21 views
15

Tworzę witrynę internetową z interfejsem API, API wymaga sprawdzania poprawności, więc użytkownik otrzymuje tylko własne dane. Napisałem następujące oprogramowanie pośrednie, aby zweryfikować logowanie..NET-core middleware return blank result

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; 
     } 
    } 
} 

Co chcę jest, że pusta strona lub komunikat o błędzie, jak „Nieprawidłowy klucz użytkownika” jest wyświetlane, jeśli użytkownik nie ma poprawny login. Jednakże, w tym momencie jest zwracana strona główna (ponieważ moje oprogramowanie pośrednie jest wywoływane przed usemvc, a instrukcja return pomija żądanie kontrolera wykonane przez usemvc).

Moja odpowiedni kod w metodzie skonfigurować w 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?}"); 
     }); 
    } 

Jak mogę uczynić mój middleware zwraca pustą stronę z kodem stanu?

Proszę wyjaśnić powód, dla którego przestaje obowiązywać, więc mogę poprawić pytanie i wiedzieć, co zrobiłem źle.

Aktualizacja

Po wypróbowaniu wiele rzeczy znalazłem, że kiedy usunąć:

context.Response.StatusCode = 401; //UnAuthorized 

To działa zgodnie z oczekiwaniami, użytkownik otrzyma wiadomość podaną w:

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

Howerver Nie chcę, aby użytkownik uzyskał kod statusu 200 w przypadku niepowodzenia logowania, ale kod statusu 401. Ale przy korzystaniu z linii statuscode użytkownik jest przekierowywany. Jak mogę wysłać kod statusu bez przekierowania?

+0

Dlaczego nie używając 'Authorize' przypisują – CodeNotFound

+0

autoryzacji zakłada użytkownik jest zalogowany (przez ciasteczka, jeśli im prawidłowe) Im dokonywania API dla aplikacji mobilnej więc aplikacja wysyła żądania, które musi być z ważnego użytkownika. Autoryzuję także przekieruje do strony rejestru, jeśli nie loggedin, co nie jest zachowanie, które chcę dla mojego API. –

+0

Chciałbym rzucić okiem na OpenId Middleware. To oprogramowanie pośrednie współpracuje z atrybutem Authorize –

Odpowiedz

4

Mam przeczucie, że app.UseIdentity() ma domyślne zachowanie, że gdy pojawi się 403/401, przechwyci odpowiedź i zainicjuje przekierowanie. Spróbuj go skomentować i sprawdź, czy działa.

rozwiązanie alternatywne patrz: https://stackoverflow.com/a/43456151/3948882

Ostatni komentarz: Gorąco zachęcam nie przechodząc poświadczenia dla każdego żądania. Polecam korzystanie z wcześniej stworzonych dostawców auth i wdrażanie ich jako oprogramowania pośredniczącego. Atrybut Authorize powinien wystarczyć dla żądań i może zrobić to, czego szukasz. Jeśli chcesz zwrócić coś specjalnego, możesz zastąpić odpowiedź za pomocą oprogramowania pośredniego, takiego jak oprogramowanie pośrednie app.UseIdentity() z przekierowaniem.

0

Spróbuj użyć .Clear() przed ustawieniem kodu statusu.

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