Mamy aplikację, która korzysta z członkostwa ASP.net w celu zapewnienia podstawowych mechanizmów logowania. Wszystko działa dobrze, ale ostatnio odkryliśmy, że jeśli spróbujesz przejść do strony logowania po zalogowaniu, nastąpi przekierowanie na stronę "Nieautoryzowane".Członkostwo ASP.NET Logowanie przekierowujące do nieautoryzowanego po zalogowaniu użytkownika
Przykładowy przepływ użytkownika.
Użytkownik przechodzi do zabezpieczonej strony (cała aplikacja wymaga zalogowania, jest tam nawet strona główna, którą można odwiedzić, po prostu przekierowuje bezpośrednio do logowania). To przekierowuje je do https://www.example.com/Account/Login.
Użytkownik loguje się i jest przekierowywany na stronę główną https://www.example.com/. Są one zalogowane i wszystko działa poprawnie.
użytkownik kliknie zakładkę, która okazuje się być ustawiona na https://www.example.com/Account/Login
użytkownik jest przekierowywany do rodzajowego Nieautoryzowany stronie.
mam atrybut <Authorize()>
na moim AccountController ale atrybut <AllowAnonymous()>
sprawie działań „login”, który jak widzieliśmy wcześniej, działa dobrze, kiedy nie jesteś zalogowany, ale kiedy jesteś wydaje się w sposób trochę pomieszania.
AccountController
<Authorize()> _
Public Class AccountController
'''other functions go here'''
<AllowAnonymous()> _
Public Function Login(ByVal returnUrl As String) As ActionResult
ViewData("ReturnUrl") = returnUrl
Return View()
End Function
filtr AuthorizeRedirect
<AttributeUsage(AttributeTargets.[Class] Or AttributeTargets.Method)> _
Public Class AuthorizeRedirect
Inherits AuthorizeAttribute
Private Const IS_AUTHORIZED As String = "isAuthorized"
Public RedirectUrl As String = "~/Home/Unauthorized"
Protected Overrides Function AuthorizeCore(httpContext As System.Web.HttpContextBase) As Boolean
Dim isAuthorized As Boolean = MyBase.AuthorizeCore(httpContext)
httpContext.Items.Add(IS_AUTHORIZED, isAuthorized)
Return isAuthorized
End Function
Public Overrides Sub OnAuthorization(filterContext As AuthorizationContext)
MyBase.OnAuthorization(filterContext)
Dim isAuthorized = If(filterContext.HttpContext.Items(IS_AUTHORIZED) IsNot Nothing, Convert.ToBoolean(filterContext.HttpContext.Items(IS_AUTHORIZED)), False)
If Not isAuthorized AndAlso filterContext.RequestContext.HttpContext.User.Identity.IsAuthenticated Then
filterContext.RequestContext.HttpContext.Response.Redirect(RedirectUrl)
End If
End Sub
End Class
Widząc to wszystko myślałem, że najprostszym rozwiązaniem byłoby sprawdzić, czy użytkownik jest już zalogowany na mój login działania i przekierowanie je same, coś takiego.
<AllowAnonymous()> _
Public Function Login(ByVal returnUrl As String) As ActionResult
If User.Identity.IsAuthenticated() Then
Return RedirectToAction("Index", "Home")
End If
ViewData("ReturnUrl") = returnUrl
Return View()
End Function
Ale AuthorizeFilter zawsze skacze w pierwszej okazji, co jest zrozumiałe, ale nie mogę dość dowiedzieć się ostatni brakujący kawałek. Chcę tylko, aby nie wyświetlał się komunikat "Nie masz uprawnień do oglądania tej strony", jeśli użytkownik wejdzie na ekran logowania po zalogowaniu, a raczej przekieruje go na stronę główną. czego mi brakuje?
Edytuj, aby dokonać rzeczy nieco jaśniejsze
Kiedy już zalogowany, idę do /Account/Login
. To 302
przekierowuje mnie do /Home/Unauthorized
(moja strona niestandardowa). Jednak nadal jestem zalogowany. Żąda
Network
Nieuprawnione strona. Zauważ, że podświetlone żółte sekcje pokazują, że wciąż jestem zalogowany. Pojawia się tylko wtedy, gdy jesteś zalogowany. Kiedy się nie zalogujesz, nie dostajesz tego.
Problem wydaje się być to, że aplikacja nie wie, co zrobić, gdy jestem już zalogowany i próbuje przejść do strony, która ma atrybut [AllowAnonymous]
na nim. Jeśli cokolwiek, to zachowanie, które tu widzę, jest lepsze od tego, że ponownie daje mi stronę logowania, ponieważ byłoby to mylące, ale nadal nie jest idealne.
Edycja 2 - Krocząc przez linię kodu przez linię
Oto wyniki wstępnej przez linię kodu po linii.
Page /Account/Login
zalogowaniu się.
Pierwszy punkt przerwania w OnAuthorization
sub w AuthorizeRedirect
filtra.
Public Overrides Sub OnAuthorization(filterContext As AuthorizationContext)
MyBase.OnAuthorization(filterContext)
Dim isAuthorized = If(filterContext.HttpContext.Items(IS_AUTHORIZED) IsNot Nothing, Convert.ToBoolean(filterContext.HttpContext.Items(IS_AUTHORIZED)), False)
If Not isAuthorized AndAlso filterContext.RequestContext.HttpContext.User.Identity.IsAuthenticated Then
filterContext.RequestContext.HttpContext.Response.Redirect(RedirectUrl)
End If
End Sub
Linia rozpoczynająca się od Dim isAuthorized
zwraca Fałsz. filterContext.HttpContext.Items(IS_AUTHORIZED)
jest niczym (nie ma na liście pozycji).
Oznacza to, że następna instrukcja If ma wartość True (Nie jest autoryzowana iAlso ... IsAuthenticated), co powoduje przekierowanie do RedirectUrl
.
Po tym zdarzeniu wydaje się, że cofa się o te same czynności, z tą różnicą, że wartość ta jest równa false, co oznacza, że przekierowanie nie występuje, chociaż domyślam się, że jest to po prostu ładowanie i uruchamianie strony "Nieautoryzowane". ten sam kod ponownie.
Podjęto próbę dodania następującego bloku na górę funkcji Login
urządzenia AccountController
.
If User.Identity.IsAuthenticated() Then
Return RedirectToAction("Index", "Home")
End If
Ale, oczywiście, ponieważ filtr jest prowadzony przed wystąpić działania tego kodu nie jest trafiony, dopóki po to już przekierowanie mnie do Unauthorized
(zweryfikowane przez przechodzeniu).
Gdzie jest stosowane "AuthorizeRedirect"? –
Nie mam teraz dostępu do kodu, ale jestem pewien, że jest skonfigurowany w standardowym FilterConfig z czymś takim jak "filters.add (Authorizeredirect)" –
wydaje się, że użytkownik jest nieautoryzowany. Czy to prawda? czy możesz trafić/home/index po przekierowaniu do nieautoryzowanego? –