Laden...

Blazor Server-Side Cookie Authentication

Erstellt von Duesmannr vor 2 Jahren Letzter Beitrag vor 2 Jahren 1.640 Views
D
Duesmannr Themenstarter:in
161 Beiträge seit 2017
vor 2 Jahren
Blazor Server-Side Cookie Authentication

Morgen,

Ausgangssituation: Blazor Server-Side .NET 5
Ziel: Einfache Authentication ohne Identity via Cookie.

Soweit ich das verstanden habe, wird man ein- und ausgeloggt über den


AuthenticationStateProvider

Dieser kann bei den Services mit


ServerAuthenticationStateProvider

registriert werden.

Dann kann man mit einem AuthenticationState


AuthenticationState authenticationState = new AuthenticationState(ClaimsPrincipal)

als Parameter den StateProvider aufrufen


(AuthenticationStateProvider as ServerAuthenticationStateProvider).SetAuthenticationState(authenticationState);

Was mir jetzt fehlt, dass die Informationen gespeichert und ausgelesen werden. Und da kommt Cookie ins Spiel.

Bei den Services habe ich das hinzugefügt


services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
                .AddCookie(options =>
                {
                    options.LoginPath = "/User/Login";
                    options.LogoutPath = "/User/Logout/";
                });

und bei der App, dass


app.UseAuthentication();
app.UseAuthorization();

Aber wie geht es jetzt weiter mit dem Cookie?
Was man noch machen kann, ist eine eigene Implementierung vom AuthenticationStateProvider, aber das hilft mir auch nicht weiter.

Alle Beispiele die ich finde nehmen irgendein HttpContext um sich anzumelden etc. (Bspw. hier: how-to-authenticate-a-user-with-blazor-server)
Aber ich habe noch keine Lösung ohne Identity gefunden bzw. auch keine mit Identity die ich auf meinen Fall adaptieren könnte.

Habt Ihr eine Idee?

Grüße
duesmannr

16.806 Beiträge seit 2008
vor 2 Jahren

Was willst Du mit "ohne Identity" ausdrücken? Was ist Identity für Dich?
Es gibt im ASP.NET Ökosystem viel, das mit Identity bezeichnet wird; angefangen von der gesamten Authentifizierungspipeline bis zur Provider Implementierung, die aber "ASP.NET Core Identity" heisst und nicht "Identity".

Ob Blazor Server-Side oder Client Side spielt keine Rolle; die Grundidee ist immer die selbe:
Authentifiziert wird gegen eine OAuth Schnittstelle, der Identity Token wird im Client abgelegt (i.d.R. im Storage).
Gegen APIs wird dann mit einem Access Token gearbeitet.

Du kannst prinzipiell die Cookie Authentication Pipeline nutzen, sie gilt aber bei APIs als unsicher.
Hier kann man aber viel falsch machen (wie bei jeder SPA mit Cookies), was dann in Sicherheitslücken endet, weshalb das nicht so ne dolle Idee ist. zB kannst Du einen Cookie nicht als ungültig erkären, sodass Du hier eine manuelle Implementierung brauchst, um die Gültigkeit eines Cookies zu checken.
Es gibt hier auch kein fertiges Konstrukt, wie Du einen Benutzer validierst; musst alles selbst schreiben.

Erstellen würdest Du den Cookie in der SPA (über HttpContext.SignInAsync()); der Cookie muss so designed sein, dass er vom Backend erkannt wird (Naming, Domain..).

D
Duesmannr Themenstarter:in
161 Beiträge seit 2017
vor 2 Jahren

Moin Abt,

ich meine die Standard implementierte Authentifizierung von Microsoft, wenn man bei der Erstellung den Authentication Type auf Individual Accounts setzt.

Der dadurch erzeugte ApplicationDbContext der vom IdentityDbContext erbt, sowie die Standard Login/Logout etc. Seiten von Identity, brauche ich alles nicht.

Bei Blazor Server-Side gibt es keinen direkten HttpContext, weil die Kommunikation über SignalR läuft.
Dafür ist ja dann der AuthenticationStateProvider da.

Mit dem Code kann ich mich auch anmelden (Razor Page, User Verifizierung seitens DB ausgeschlossen)


List<Claim> claims = new()
        {
            new(ClaimTypes.Email, this.Model.Username)
        };

        ClaimsIdentity claimsIdentity = new(claims, CookieAuthenticationDefaults.AuthenticationScheme);

        ClaimsPrincipal claimsPrincipal = new(claimsIdentity);

        AuthenticationState authenticationState = new AuthenticationState(claimsPrincipal);

        (AuthenticationStateProvider as ServerAuthenticationStateProvider).SetAuthenticationState(Task.FromResult(authenticationState));

Durch das setzen des AuthenticationState sehe ich beispielsweise diese h1


<AuthorizeView>
    <Authorized>
        <h1>You´re authorized.</h1>
    </Authorized>
</AuthorizeView>

auf der gleichen Seite.

Was mir aber jetzt fehlt, dass der State gespeichert wird, was ja über das Cookie laufen würde, wenn ich es richtig verstehe.
Und wie dieser dann wieder dazu führt, dass der User weiterhin angemeldet ist.

16.806 Beiträge seit 2008
vor 2 Jahren

ich meine die Standard implementierte Authentifizierung von Microsoft, wenn man bei der Erstellung den Authentication Type auf Individual Accounts setzt.

Projekt Templates von Visual Studio / .NET CLI sind nur Beispiele. Gefallen sie Dir nicht, dann fang mit nacktem Code an und nicht mit den Templates.

Bei Blazor Server-Side gibt es keinen direkten HttpContext, weil die Kommunikation über SignalR läuft.

Nein, es gibt im Client keinen (eingebauten) HTTP Context, weil Du Dich direkt im Client befindest und hier lokal arbeitest und nicht über HTTP.
In der Server-Komponente hast Du sehr wohl einen HTTP Context.

Bei Blazor Server ist SignalR eigentlich für das Nachladen von Abhängigkeiten da; wird im Falle von AuthenticationStateProvider aber auch für die eingebaute Authentifizierung verwendet.

Was mir aber jetzt fehlt, dass der State gespeichert wird, was ja über das Cookie laufen würde, wenn ich es richtig verstehe.

Alle Authentifizierungen, die im Client erfolgen (egal ob Angular, React, Blazor or whatever) können umgangen werden. Willst Du eine sichere Authentifizierung, dann muss diese immer über den Server erfolgen; kriegste in diesem Fall geschenkt über den AuthenticationStateProvider, sodass der Client hier mit dem Server für die Authentifizierung über diesen Kanal kommuniziert.
Eigene Informationen in einem Client speichert man in allen SPAs i.d.R. im Protected Storage, bei Blazor meist über ProtectedSessionStorage; nicht über Cookies.

Soweit ich weiß wird aber nichts in AuthenticationStateProvider per default gespeichert.
Müsstest einen eigenen machen, der Zeug in ProtectedSessionStorage ablegt.

Edit: erster Google Treffer dazu: Session Authentication with ASP.NET Core 3.1 Blazor Server Side

D
Duesmannr Themenstarter:in
161 Beiträge seit 2017
vor 2 Jahren

bei Blazor meist über ProtectedSessionStorage; nicht über Cookies.

Der Storage sagt mir auf Anhieb nichts, gucke ich mir mal an.

Soweit ich weiß wird aber nichts in AuthenticationStateProvider per default gespeichert.

Das ist korrekt.

Edit: erster Google Treffer dazu:
>

Habe ich auch schon des Öfteren überflogen. Dann gucke ich mir das nochmal genauer an.

Vorerst danke 🙂