jestem Mając podobne problemy tutaj, jak w mojej aplikacji internetowej używam prostego systemu uwierzytelniania plików cookie, który używa metody stylu AoP do sprawdzenia dowolne kontrolery z atrybutem, następnie otrzymają aktualny kontekst (czy to ze statycznego HttpContext.Current, czy z docelowego obiektu wywołania w zależności od typu przechwytywacza), a następnie sprawdzą, czy plik cookie istnieje, zawiera właściwe dane, a następnie weryfikuje token z bazą danych lub pamięcią podręczną, itp.
W każdym razie to podejście może być również stosowane w Signalr, chociaż jest nieco bardziej długotrwały i stosuje iniekcję zależności.Zasadniczo owijanie wywołań centralnych wymaganym atrybutem, a następnie skonfigurowanie konfiguracji DI/IoC w celu przechwycenia tych wywołań, a następnie pobranie instancji centralnej w przechwytywarce i pobranie pliku cookie (lub niestandardowego mechanizmu uwierzytelniania) z żądania, weryfikacja wszystko jest poprawne lub nie, a jeśli nie, wyrzuć new HttpException("403", "Not authenticated");
, który powinien wykopać użytkownika i powrócić, zanim jeszcze uderzy w twoją metodę piasty, w ten sposób możesz umieścić logikę w jednym miejscu (twój przechwytujący lub klasa przechwytywacz pochłania), a następnie po prostu zawiń dowolną metodę, która wymaga użycia tego uwierzytelnienia za pomocą twojego atrybutu.
używam Ninject i rozszerzenie przechwytywania, ale większość z głównych DI Ramy te dni mieć jakąś formę IoC wtyczek/rozszerzeń, takich jak Autofac, Windsor, Spring itp
Jeśli nie byli zadowoleni schodząc trasę wprowadzenia DI i/lub AOP do twojego bieżącego projektu, to może mógłbyś po prostu stworzyć niestandardową instancję huba, która zawiera twoją logikę uwierzytelniania, a następnie po prostu użyć tego w twoich koncentratorach, więc ok nadal będziesz ręcznie wywoływać logikę uwierzytelniania z każdego Metoda koncentrująca, którą chcesz chronić, ale jej kod jest mniejszy, a więc coś takiego:
public class AuthorisableHub : Hub
{
private ISomeAuthenticationToken GetSomeAuthenticationTokenFromRequest(Request request) // probably a SignalR specific request object
{
// Get your token from the querystring or cookie etc
}
private bool IsAuthenticationTokenValid(ISomeAuthenticationToken token)
{
// Perform some validation, be it simple or db based and return result
}
protected void PerformUserAuthentication()
{
var token = GetSomeAuthenticationTokenFromRequest(Context.Request);
var isRequestValid = IsAuthenticationTokenValid(token);
if(!isRequestValid)
{ throw new HttpException(403, "<Some forbidden message here>"); }
}
}
public class MyFancyPantsHub : AuthorisableHub
{
public void TellAllClientsSomethingSecret(ISecret secret)
{
PerformUserAuthentication();
// Do stuff with the secret as it should have bombed the user out
// before it reaches here if working correctly
}
}
Nie jest doskonały, ale działałby (myślę), jestem też pewien, że kiedyś przeczytałem gdzieś, że Huby są nowo utworzone dla każdej prośby, a jeśli to prawda, to możesz umieścić tę logikę w swoim konstruktorze, jeśli chcesz zastosować uwierzytelnianie do każdej akcji w centrum.
Nadzieja, która pomaga lub daje pomysły ... byłaby zainteresowana wiedzą, w jaki sposób udało się rozwiązać problem w końcu.
Zaimplementowałem zabezpieczenia oparte na tokenach, przekazując wygenerowany token użytkownika z każdym żądaniem SignalR za pośrednictwem ciągu zapytania (tj. $ .connection.hub.qs). Klient wyszukuje klucz, który przekreśla użytkownika, a na serwerze pobieram token, a następnie ładuję użytkownika z krzyżyka ref. Działa, ale jest dość brzydka, a ponadto nie mogę wymyślić, jak wyczyścić zabezpieczenia przed wywołaniem metody ValidateToken(), która rzuca na błąd. –
Każda aktualizacja w tej sprawie? Znalazłeś już lepszy sposób na zrobienie tego? Znam dokładnie tę samą sytuację. – BowserKingKoopa