2016-11-28 49 views
8

ile rol tabanlı yetkilendirme Kullanıcı rollerine dayalı olarak API'mime erişim sağlamak için IdentityServer4 kullanarak "Rol Tabanlı Yetkilendirme" uygulamaya çalışıyorum. Örneğin, kullanıcı için FreeUser ve PaidUser olmak üzere iki rol almak istiyorum ve [Authorize (Roller = "FreeUser") kullanarak Authorize Attribute aracılığıyla API'ya erişim vermek istiyorum)), lütfen bana Nasıl Yardım Bunu başarabilir miyim IdentityServer4

Ben şu çözüm yapısı:

  1. IdentityServer
  2. WebAPI
  3. JavaScript İstemci

şöyle benim JavaScript istemci kaydedildi:

new Client 
      { 
       ClientId = "js", 
       ClientName = "javascript client", 
       AllowedGrantTypes = GrantTypes.Implicit, 
       AllowAccessTokensViaBrowser= true, 
       RedirectUris = {"http://localhost:5004/callback.html"}, 
       PostLogoutRedirectUris = {"http://localhost:5004/index.html"}, 
       AllowedCorsOrigins = {"http://localhost:5004"}, 

       AllowedScopes = 
       { 
        StandardScopes.OpenId.Name, 
        StandardScopes.Profile.Name, 
        "api1", 
        "role", 
        StandardScopes.AllClaims.Name 
       } 
      } 

Kapsamları

return new List<Scope> 
     { 
      StandardScopes.OpenId, 
      StandardScopes.Profile, 

      new Scope 
      { 
       Name = "api1", 
       Description = "My API" 
      }, 
      new Scope 
      { 
       Enabled = true, 
       Name = "role", 
       DisplayName = "Role(s)", 
       Description = "roles of user", 
       Type = ScopeType.Identity, 
       Claims = new List<ScopeClaim> 
       { 
        new ScopeClaim("role",false) 
       } 
      }, 
      StandardScopes.AllClaims 
     }; 

Kullanıcılar

return new List<InMemoryUser> 
     { 
      new InMemoryUser 
      { 
       Subject = "1", 
       Username = "alice", 
       Password = "password", 

       Claims = new List<Claim> 
       { 
        new Claim("name", "Alice"), 
        new Claim("website", "https://alice.com"), 
        new Claim("role","FreeUser") 
       } 
      }, 
      new InMemoryUser 
      { 
       Subject = "2", 
       Username = "bob", 
       Password = "password", 

       Claims = new List<Claim> 
       { 
        new Claim("name", "Bob"), 
        new Claim("website", "https://bob.com"), 
        new Claim("role","PaidUser") 
       } 
      } 
     }; 

WebAPI Startup.cs

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) 
    { 
     loggerFactory.AddConsole(Configuration.GetSection("Logging")); 
     loggerFactory.AddDebug(); 


     JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear(); 
     app.UseCors("default"); 
     app.UseIdentityServerAuthentication(new IdentityServerAuthenticationOptions 
     { 
      Authority = "http://localhost:5000", 
      ScopeName = "api1", 
      // AdditionalScopes = new List<string> { "openid","profile", "role" }, 
      RequireHttpsMetadata = false 
     }); 

     app.UseMvc(); 
    } 

Web Api kontrolörü

namespace Api.Controllers 
{ 
[Route("[controller]")] 

public class IdentityController : ControllerBase 
{ 
    [HttpGet] 
    [Authorize(Roles = "PaidUser")] 
    public IActionResult Get() 
    { 
     return new JsonResult(from c in User.Claims select new { c.Type, c.Value }); 
    } 

    [Authorize(Roles = "FreeUser")] 
    [HttpGet] 
    [Route("getfree")] 
    public IActionResult GetFreeUser() 
    { 
     return new JsonResult(from c in User.Claims select new { c.Type, c.Value }); 
    } 
} 
} 

JavaScript İstemci İşte app.js Ben IdentityServer aracılığıyla kullanıcının girişi ve bir API isteği yapmaya çalışıyorum.

var mgr = new Oidc.UserManager(config); 
mgr.getUser().then(function (user) { 
if (user) { 
    log("User logged in", user.profile); 
} else { 
    log("User is not logged in."); 
} 
}); 

function login() { 
    mgr.signinRedirect(); 
} 

function api() { 
mgr.getUser().then(function (user) { 
    var url = "http://localhost:5001/identity/getfree"; 

    var xhr = new XMLHttpRequest(); 
    xhr.open("GET", url); 
    xhr.onload = function() { 
     log(xhr.status, JSON.parse(xhr.responseText)); 
    }; 

    xhr.setRequestHeader("Authorization", "Bearer " + user.access_token); 
    xhr.send(); 
    }); 
} 

function logout() { 
    mgr.signoutRedirect(); 
} 

Oturum açma akışı iyi çalışıyor ve başarıyla oturum açabiliyorum ve erişim belirtecinde rol alabiliyorum. Ben düğmesine tıklayarak API için bir istek yaptığınızda

enter image description here

new Claim(ClaimTypes.Role, "FreeUser")

değiştirin new Claim("role","FreeUser") enter image description here

cevap

5

, ben aşağıdaki gibi kapsam yapılandırmış varsayalım.

scope:"openid profile api1 role" 

Sorununuzun ana nedeni, erişim belirtiminin erişim belirtecinizde yer almamasıdır.

Erişim belirtecine eklemek için api1 kapsamına aşağıdaki gibi bir rol isteği ekleyin.

   new Scope 
       { 
        Name = "api1", 
        DisplayName = "API1 access", 
        Description = "My API", 
        Type = ScopeType.Resource, 
        IncludeAllClaimsForUser = true, 
        Claims = new List<ScopeClaim> 
        { 
         new ScopeClaim(ClaimTypes.Name), 
         new ScopeClaim(ClaimTypes.Role) 
        } 
       } 

Sorunu hata ayıklama yardımı için cevabımı buradan okuyabilirsiniz. implementing roles in identity server 4 with asp.net identity

Tam çalışma çözümü burada. https://github.com/weliwita/IdentityServer4.Samples/tree/40844310

+0

harika ... şimdi iyi çalışıyor .. Nasıl unuttum inanamıyorum Bunu kapsamına eklemek için .. teşekkürler zaten .. –

+0

@muhammadwaqas Ben cevabı kabul etmeliyim – Learner

2

.. aşağıdaki hatayı alıyorum sonra (Api'si Çağrı) Ya da bir oluşturmak Bu gibi ilkeler:

services.AddAuthorization(options => 
{ 
    options.AddPolicy("FreeUser", policy => policy.RequireClaim("role", "FreeUser")); 
}); 

ve bize bunu e: javascript istemci için yapılandırma nesnesi sağlanmamış olması göz önüne alındığında

Authorize[(Policy = "FreeUser")] 
+0

Yanıtınız için teşekkürler, her iki yöntemi de denedim, ancak sonuç aynı, bir API isteği yaparken ilke eklendiğinde, API için iki istekte bulunur, ilkinde 204 [İçerik Yok] durumu yazıyor kod ikincisi 403 ile başarısız olur .. İddiaları durumunda sonuç yine aynıdır 403 .. orada eksik bir şey var mı? .. –