4

Ich arbeite an einer asp.net MVC-Anwendung mit Identity Server 4 als Token-Service. Ich habe auch eine API, die einige sichere Ressourcen hat. Ich möchte Rollen (Authorization) für API implementieren. Ich möchte sicherstellen, dass nur eine autorisierte Ressource mit gültiger Rolle auf einen API-Endpunkt zugreifen kann, andernfalls 401 (nicht autorisierter Fehler).Implementierung von Rollen in Identity Server 4 mit asp.net Identität

Hier sind meine Konfigurationen:

Kunde

  new Client() 
      { 
       ClientId = "mvcClient", 
       ClientName = "MVC Client",      
       AllowedGrantTypes = GrantTypes.HybridAndClientCredentials, 

       ClientSecrets = new List<Secret>() 
       { 
        new Secret("secret".Sha256()) 
       }, 

       RequireConsent = false; 

       // where to redirect to after login 
       RedirectUris = { "http://localhost:5002/signin-oidc" }, 
       // where to redirect to after logout 
       PostLogoutRedirectUris = { "http://localhost:5002" }, 

       AllowedScopes = 
       { 
        StandardScopes.OpenId.Name, 
        StandardScopes.Profile.Name, 
        StandardScopes.OfflineAccess.Name, 
        StandardScopes.Roles.Name, 
        "API" 
       } 
      } 

Scopes

return new List<Scope>() 
      { 
       StandardScopes.OpenId, // subject id 
       StandardScopes.Profile, // first name, last name 
       StandardScopes.OfflineAccess, // requesting refresh tokens for long lived API access 
       StandardScopes.Roles, 
       new Scope() 
       { 
        Name = "API", 
        Description = "API desc", 
        Type = ScopeType.Resource, 
        Emphasize = true, 
        IncludeAllClaimsForUser = true, 
        Claims = new List<ScopeClaim> 
        { 
         new ScopeClaim(ClaimTypes.Name),  
         new ScopeClaim(ClaimTypes.Role) 
        } 
       } 
      }; 

Benutzer

new InMemoryUser() 
       { 
        Subject = "1", 
        Username = "testuser", 
        Password = "password", 
        Claims = new List<Claim>() 
        { 
         new Claim("name", "Alice"), 
         new Claim("Website", "http://alice.com"), 
         new Claim(JwtClaimTypes.Role, "admin") 

        } 
       } 

und in Serverstart i hat dieses Bild:

services.AddIdentityServer() .AddTemporarySigningCredential() .AddSigningCredential (cert) .AddInMemoryClients (Config.GetClients()) .AddInMemoryScopes (Config.GetScopes()) .AddInMemoryUsers (Config.GetUsers())

in api Start, ich habe dies:

app.UseIdentityServerAuthentication(new IdentityServerAuthenticationOptions() 
      { 
       Authority = "http://localhost:5000", 
       ScopeName = "NamfusAPI", 
       RequireHttpsMetadata = false 
      }); 

in api Controller, ich habe dies:

[Authorize(Roles = "admin")] 
     public IActionResult Get() 
     { 
      return new JsonResult(from c in User.Claims select new {c.Type, c.Value }); 
     } 

in MVC-Client Startup, ich habe dies:

JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear(); 

app.UseCookieAuthentication(new CookieAuthenticationOptions() 
      { 
       AuthenticationScheme = "Cookies" 
      }); 


      var oidcOptions = new OpenIdConnectOptions() 
      { 
       AuthenticationScheme = "oidc", 
       SignInScheme = "Cookies", 

       Authority = "http://localhost:5000", 
       RequireHttpsMetadata = false, 

       ClientId = "mvcClient", 
       ClientSecret = "secret", 
       SaveTokens = true, 
       GetClaimsFromUserInfoEndpoint = true, 
       ResponseType = "code id_token", // hybrid flow 

      }; 


      oidcOptions.Scope.Clear(); 
      oidcOptions.Scope.Add("openid"); 
      oidcOptions.Scope.Add("profile"); 
      oidcOptions.Scope.Add("NamfusAPI"); 
      oidcOptions.Scope.Add("offline_access"); 
      oidcOptions.Scope.Add("roles"); 

ich die api so zu nennen versuchen:

public async Task<IActionResult> CallApiUsingUserAccessToken() 
     { 
      var accessToken = await HttpContext.Authentication.GetTokenAsync("access_token"); 

      var client = new HttpClient(); 
      client.SetBearerToken(accessToken); 
      var content = await client.GetStringAsync("http://localhost:5001/identity"); 

      ViewBag.Json = JArray.Parse(content).ToString(); 
      return View("json"); 
     } 

Ich erhalte Zugriffstoken, aber wenn ein Anruf zu api (Identität/get) gemacht wird, bekomme ich 302 error Forbidden (im Chrome-Netzwerk zeigt es 500 interne Serverfehler). Wenn ich Attribut API Autorisieren von

[Authorize(Roles = "admin")] 
      public IActionResult Get() 

zu (ohne Rolle) ändern:

[Authorize] 
     public IActionResult Get() 

es funktioniert und ich Daten von api in mvc App. Wie kann ich Rollen in diesem Code anwenden?

Bitte vorschlagen.

+0

ziemlich sicher, dass Sie sollten nicht beide 'AddTemporarySigningCredential tun()' und 'AddSigningCredential (cert)'? –

Antwort

2

Zuerst müssen Sie "API" Bereich in Ihrer OpenIdConnectOptions() anfordern.

oidcOptions.Scope.Add("API"); 

oder

Scope = { "API", "offline_access",..}, 

Dann müssen Sie überprüfen, ob die Rolle Anspruch in der Liste der Ansprüche Verfügung, um Ihre API Controler enthalten ist (nicht gelten die Rollen noch in autorisieren Attribut filtern. Setzen Sie ein Debug-Punkt innerhalb der Controller-Methode und erweitern Benutzereigenschaft).Überprüfen Sie, ob die Art der Rolle Anspruch empfangen Sie (aufgeführt in den Ansprüchen Collection) entspricht User.Identity.RoleClaimType Eigenschaft

enter image description here

Wenn die Rolle Fallart Sie haben und User.Identity.RoleClaimType nicht übereinstimmt, autorisieren Attribut mit Filter Rollen werden nicht Arbeit. Sie können die korrekte RoleClaimType in IdentityServerAuthenticationOptions set() wie folgt

app.UseIdentityServerAuthentication(new IdentityServerAuthenticationOptions 
     { 
      Authority = "http://localhost:5000", 
      ScopeName = "API", 
      RoleClaimType = ClaimTypes.Role, 
      RequireHttpsMetadata = false 
     }); 
+0

rawel danke für die antwort. Ich sehe RoleClaimType nicht verfügbar ist, wenn ich RoleClaimType = ClaimTypes.Role versuchen, in mvc-Client wie diese 'code'var oidcOptions = new OpenIdConnectOptions() { AuthenticationScheme = "OIDC", SignInScheme = "Cookies", Authority = "http: // localhost: 5000", RequireHttpsMetadata = false, GetClaimsFromUserInfoEndpoint = true, RoleClaimType = ClaimTypes.Role, }; 'code' –

+0

Dies sollte zu Api hinzugefügt werden. Zu IdentityServerAuthenticationOptions – rawel

+0

sehe ich, dass die User.Claims -Eigenschaft im Controller null ist, während RoleCalimtype in identity denselben Wert wie oben gezeigt hat. –

Verwandte Themen