Laden...

[Gelöst] ASP.NET Core 2.0 mit Identity Server: User.Identity.Name bleibt Null

Erstellt von emuuu vor 6 Jahren Letzter Beitrag vor 6 Jahren 2.233 Views
emuuu Themenstarter:in
286 Beiträge seit 2011
vor 6 Jahren
[Gelöst] ASP.NET Core 2.0 mit Identity Server: User.Identity.Name bleibt Null

Guten Tag zusammen,

ich habe leider aktuell ein Problem mit meiner Authentifizierung bei dem ich nicht weiter komme:
Ich habe einen IdentityServer laufen mittels dem neben einer API ein MVC-Client geschützt werden soll.
Es funktioniert soweit auch alles gut bis zu dem Punkt wo nach dem Redirect und Login der ClaimsPrincial (Context.User) zurückgegeben wird. Dieser enthält eine Identity mit vier Claims (sid, sub, idpc, name). Allerdings ist der Name-Value der Identity null und der NameClaimType sowie RoleClaimType haben den Value "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name" (bzw. /role).
Einerseits sollte der Name nicht null sein, andererseits gebe ich beim Login noch ein paar weitere Claims mit, die gar nicht übernommen werden.

Ich habe auf dem IdentityServer testweise den Login direkt aufgerufen: Hier stimmen sowohl die Values als auch die zusätzlichen Claims.

Auf dem IdSrv sieht der Login wie folgt aus:


                            var acc = await _account.GetAccountDataByUserID(user.Id);
                            if (acc != null)
                            { 
                                var accountClaims = new Claim[]
                                {
                                new Claim(ClaimTypes.GivenName, acc.Contact.GivenName),
                                new Claim(ClaimTypes.Surname, acc.Contact.Surname)
                                };
                                await HttpContext.SignInAsync(user.Id, user.UserName, props, claims: employeeClaims);
                            }

Dies habe ich von Getting Started with IdentityServer 4 by ScottBrady, ergänzt um die Claims

Der Startup in meinem MVC-Client wie folgt:


            JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();

            services.AddAuthentication(options =>
            {
                options.DefaultScheme = "Cookies";
                options.DefaultChallengeScheme = "oidc";
            })
            .AddCookie("Cookies")
            .AddOpenIdConnect("oidc", options =>
            {
                options.SignInScheme = "Cookies";
                options.Authority = "http://localhost:5000";
                options.RequireHttpsMetadata = false;

                options.ClientId = "test_web_client";
                options.ClientSecret = "superSecretPassword";
                options.ResponseType = "code id_token";

                options.Scope.Add("api_v1");
                options.Scope.Add("offline_access");

                options.GetClaimsFromUserInfoEndpoint = true;
                options.SaveTokens = true;
            });

Übernommen von IdentityServer4 Quickstart Sample 6 (AspNetIdentity)

Mittlerweile erfolglos ausprobiert hab ich:
Claimtypen in der ApiResource manuell nachtragen
Sowie allerlei erfolgloses Try'n'Error mit Google & AuthenticationScheme
Für Denkanreize wäre ich dankbar.

Vielen Dank im Voraus und beste Grüße
emuuu

2+2=5( (für extrem große Werte von 2)

16.806 Beiträge seit 2008
vor 6 Jahren

Ein Login kann beim Identity Server nur der Host selbst machen und nicht der Client.
Der Host hat die Informationen, welche Clients welche Claims sehen dürfen bzw. im Token beim Redirect mitgeliefert werden..

Ein Login direkt auf dem Client gibt es nicht; es muss hier ein Redirect geben.
Mir scheint so, dass Du hier grundlegend etwas falsch gemacht hast - und nicht nur der Name leer ist, sondern dass überhaupt keine Authentifizierung existiert.

Claims werden über die Allowed Scopes mitgeteilt.
Sehe ich bei Dir nirgends - im Beispiel, das Du verlinkt hast, aber schon.

Claims sind aber nicht dafür gedacht, dass jeder Krempel mitgeliefert wird.
Der Token sollte so klein wie möglich bleiben und nur das notwendigste als Claim mitgegeben werden.

emuuu Themenstarter:in
286 Beiträge seit 2011
vor 6 Jahren

Ein Login kann beim Identity Server nur der Host selbst machen und nicht der Client.

Das ist schon klar.
Vielleicht hätte ich meinen Aufbau mehr erläutern sollen. Ich habe drei Dienste:

  • IdentityServer auf Port 5000
  • WebApi auf 5001
  • MVC-Client auf 5002

Controller X im MVC-Client ist mit [Authorize] versehen, woraufhin ein Redirect auf den IdentityServer stattfindet, der die Authentifizierung durchführt und mich dann zum Controller zurückschickt. Hier möchte ich nun

name = Context.User?.GetDisplayName();

ausführen, erhalte aber leider nur die SubjectID zurück (da Identity.Name = null)
Die Identity die ich zurückerhalte hat den AuthenticationType "Federation", IsAuthenticated=true und 4 Claims:
sid, sub, idp & name
Ich bin mir also recht sicher es vom grundsätzlichen Aufbau her richtig gemacht zu haben. Und eine valide Authentifizierung zurückerhalte.

Claims werden über die Allowed Scopes mitgeteilt

Die Scopes sind bei mir persistent abgelegt und werden vom IdSvr dementsprechend abgerufen:
openid
profile
email
role
api_v1
Die genaue Implementierung hatte ich der Übersicht wegen nicht gepostet, da imho dort der Fehler nicht liegt

Ich will in den Claims auch nicht allen möglichen Krempel mitliefern sondern zusätzlich nur den Vor- sowie Nachnamen.

2+2=5( (für extrem große Werte von 2)

16.806 Beiträge seit 2008
vor 6 Jahren

Der Name einer ClaimsIdentity ergibt sich aus dem ClaimType.Name.
Und IIRC haben die Claims beim SignIn nichts mit den Scopes zutun.

emuuu Themenstarter:in
286 Beiträge seit 2011
vor 6 Jahren

Problem gelöst:


                options.TokenValidationParameters = new TokenValidationParameters
                {
                    NameClaimType = "name",
                    RoleClaimType = "role"
                };

Im MVC-Client unter services.AddOpenIdConnect() ergänzt und schon funktioniert es problemlos.

2+2=5( (für extrem große Werte von 2)