2017-01-16 54 views
5

儘管我很高興IdentityServer4存在,並且使我身份驗證方面的許多方面變得更容易,但我偶然發現了這個問題以及許多討論在社區內增加角色。如何把ASP.net身份角色放入Identityserver4身份令牌

我的要求很簡單:

  1. 我開發誰需要進行身份驗證和授權
  2. 我需要一個系統來存儲我的用戶(姓名,PWD,角色,手機的身份應用程序(xamarin形式)... ) - > ASP.net身份
  3. 我需要一個系統,以我的用戶進行身份驗證 - > IdentityServer每個用戶4個
  4. 作用是非常有限的(用戶/管理員),但不改變
  5. 我需要一個API和後端一個MVC管理網站(asp.net核心)
  6. 我想限制訪問使用[授權(角色=「管理員」)]一些API/MVC控制器

我花了無數的時間嘗試不同的配置,獲得身份驗證後身份驗證身份角色被傳遞給我的MVC應用程序,但沒有運氣。目的如第6點所述。

我也花了無數小時閱讀,但我有一種感覺,自版本v1.0.0以來,角色的實現IdentityServer4.AspIdentity發生了很大變化。

在閱讀了很多關於此之後,仍然不清楚如何實際執行此操作,因爲似乎僅在2個月前描述的一些解決方案不再有效。

所以,現在我認爲有兩條路徑:僅請求身份令牌 和使用AlwaysIncludeInIdToken

  1. 進入角色的身份令牌?
  2. 讓客戶端使用userinfo端點檢索角色 並以某種方式將它們注入httpcontext(?)以允許mvc使用[Authorize(Roles = 「Admin」)]進行檢查?

無論如何,這是我的假設。

因此,請詳細說明並解釋/說明文件,以便我們能夠以持久的方式開始實施此操作?一些可行的例子也很棒。

+0

可以確認角色存在在令牌?如果他們這樣做,我可能會知道是什麼導致你的痛苦。 – Lutando

+0

不,我不能得到任何索賠(角色,定製索賠...)補充。所以我研究了很多,並找到了下面描述的兩種解決方案。我現在可以在Identity Server級別和客戶端級別添加聲明。當然,任何提出更好的建議都是值得歡迎的。 – Laobu

回答

6

因此,經調查後,我拿出2層的方法來做到這一點:

  1. 包括關於身份服務器端
  2. 包括在客戶端角色/其他索賠角色/其他索賠

包括關於標識的服務器端

拉維punjwani在「如何添加additi給出了答案onal聲明將包含在使用ASP.Net身份與IdentityServer4的access_token中。他的解決方案仍處於草案中,但該解決方案允許您在將令牌發送回客戶端之前添加任何聲明。這是鏈接:How to add additional claims to be included in the access_token using ASP.Net Identity with IdentityServer4

包括在客戶端

這一個是有點艱難,因爲它涉及到客戶端的請求管道加入「IClaimsTransformer」。結果是,每次請求,Claimstransformer將檢索用戶的聲明並將其添加到用戶標識聲明(令牌)中。 Claimstransformer的設置並不容易,因爲要讓DI工作起來很困難,但經過大量研究後,Celow解決方案可以幫助我。

自定義ClaimsTransformer類完成改造的中間件: 公共類KarekeClaimsTransformer:IClaimsTransformer { 私人只讀的UserManager _userManager;

public KarekeClaimsTransformer(UserManager<ApplicationUser> userManager) 
    { 
     _userManager = userManager; 
    } 

    public async Task<ClaimsPrincipal> TransformAsync(ClaimsTransformationContext context) 
    { 
     if (context.Principal.Identity.IsAuthenticated) 
     { 
      Claim userId = context.Principal.FindFirst("sub"); 

      if (context.Principal.FindFirst("role") == null && userId != null) 
      { 
       ApplicationUser user = await _userManager.FindByIdAsync(userId.Value); 
       var roles = await _userManager.GetRolesAsync(user); 
       foreach (var role in roles) 
       { 
        ((ClaimsIdentity)context.Principal.Identity).AddClaim(new Claim(JwtClaimTypes.Role, role, 
         "http://schemas.microsoft.com/ws/2008/06/identity/claims/role")); 
       } 
      } 
     } 
     return Task.FromResult(context.Principal).Result; 
    } 
} 

在客戶端啓動類,你需要將它添加到範圍在ConfigureServices

public void ConfigureServices(IServiceCollection services) 
    { 
     // Add framework services. 
     services.AddDbContext<ApplicationDbContext>(options => 
      options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"))); 

     ... 
     services.AddScoped<IClaimsTransformer, KarekeClaimsTransformer>(); 
     // Add framework services. 
     services.AddMvc(); 
    } 

最後,加入配置:

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

     app.UseIdentityServerAuthentication(new IdentityServerAuthenticationOptions 
     { 
      Authority = "http://localhost:5000", 
      RequireHttpsMetadata = false, 

      ApiName = "api1" 
     }); 

     app.UseClaimsTransformation((context) => 
     { 
      IClaimsTransformer transformer = context.Context.RequestServices.GetRequiredService<IClaimsTransformer>(); 
      return transformer.TransformAsync(context); 
     }); 

     app.UseMvc(routes => 
     { 
      routes.MapRoute(
       name: "default", 
       template: "api/{controller}/{action?}/{id?}"); 
     }); 
    }