Mam witrynę internetową MVC, która używa uwierzytelniania OAuth / token do uwierzytelniania żądań. Wszystkie odpowiednie kontrolery mają odpowiednie atrybuty, a uwierzytelnianie działa prawidłowo.
Problem polega na tym, że nie wszystkie żądania można autoryzować w zakresie atrybutu - niektóre sprawdzenia autoryzacji muszą być przeprowadzane w kodzie wywoływanym przez metody kontrolera - jaki jest prawidłowy sposób zwrócenia nieautoryzowanej odpowiedzi 401 w tym przypadku?
Próbowałem throw new HttpException(401, "Unauthorized access");
, ale kiedy to zrobię, kod statusu odpowiedzi to 500 i otrzymuję również ślad stosu. Nawet w naszym logowaniu DelegatingHandler widzimy, że odpowiedź to 500, a nie 401.
c#
asp.net-mvc
authorization
GoatInTheMachine
źródło
źródło
HttpResponseException
versus, kiedy zwrócićUnauthorized()
. Używanie wyjątku dla „oczekiwanego” błędu jest trochę anty-wzorzec, więc jeśli są przypadki, w których spodziewasz się, że wywołanie popełni ten błąd, powrótUnauthorized()
jest prawdopodobnie właściwym wywołaniem. OszczędzajHttpResponseException
na naprawdę nieoczekiwane.Odpowiedzi:
Powinieneś wyrzucać
HttpResponseException
ze swojej metody API, a nieHttpException
:Lub, jeśli chcesz podać niestandardową wiadomość:
źródło
Po prostu zwróć następujące informacje:
źródło
return Content<string>(HttpStatusCode.Unauthorized, "Message");
do tego.Alternatywnie do innych odpowiedzi możesz również użyć tego kodu, jeśli chcesz zwrócić
IActionResult
w kontrolerze ASP.NET.ASP.NET
Aktualizacja: ASP.NET Core
Powyższy kod nie działa w ASP.NET Core, możesz zamiast tego użyć jednego z nich:
Najwyraźniej fraza powodu jest dość opcjonalna ( czy w odpowiedzi HTTP można pominąć wyrażenie powodu? )
źródło
ControllerBase
klasa (używana przez ASP.NET Core WebAPI) nie ma jużContent
przeciążenia, które akceptuje kod stanu HTTP.HttpStatusCode.Unauthorized
), a nie 200.Content(...)
po prostu skrót do zwracania dowolnej treści z podanym kodem statusu HTTP. Jeśli chcesz wysłać 200, możesz użyćOk(...)
Otrzymujesz kod odpowiedzi 500, ponieważ rzucasz wyjątek (the
HttpException
), który wskazuje na jakiś rodzaj błędu serwera, to jest niewłaściwe podejście.Wystarczy ustawić kod statusu odpowiedzi .eg
źródło
Response
właściwości.Aby dodać do istniejącej odpowiedzi w ASP.NET Core> = 1,0, możesz
Aby przekazać informacje klientowi, możesz zadzwonić w ten sposób:
Na kliencie oprócz odpowiedzi 401 będziesz miał również przekazane dane. Na przykład w przypadku większości klientów możesz
await response.json()
to uzyskać.źródło
W .Net Core możesz użyć
zamiast
który ma tę zaletę, że przekierowuje na domyślną nieautoryzowaną stronę (Odmowa dostępu / Konta) zamiast podawania prostego 401
aby zmienić domyślną lokalizację, zmodyfikuj plik startup.cs
źródło
możesz użyć następującego kodu w asp.net core 2.0:
źródło
Postępujesz również zgodnie z tym kodem:
źródło