簡體   English   中英

如何使用Identity Server 4(JWT)進行基於角色的Web API授權

[英]How to do Role-based Web API Authorization using Identity Server 4 (JWT)

這對我來說是全新的,我仍在努力解決。 我已經設置了IDP(Identity Server 4),並且能夠配置客戶端以對其進行身份驗證(Angular 6 App),並且還可以配置客戶端以進行API身份驗證(Asp.Net Core 2.0)。 一切似乎都正常。

這是IDP中的客戶端定義:

new Client
            {
                ClientId = "ZooClient",
                ClientName = "Zoo Client",
                AllowedGrantTypes = GrantTypes.Implicit,
                AllowAccessTokensViaBrowser = true,
                RequireConsent = true,

                RedirectUris           = { "http://localhost:4200/home" },
                PostLogoutRedirectUris = { "http://localhost:4200/home" },
                AllowedCorsOrigins = { "http://localhost:4200" },

                AllowedScopes =
                {
                    IdentityServerConstants.StandardScopes.OpenId,
                    IdentityServerConstants.StandardScopes.Profile,
                    IdentityServerConstants.StandardScopes.Email,
                    IdentityServerConstants.StandardScopes.Phone,
                    IdentityServerConstants.StandardScopes.Address,
                    "roles",
                    "ZooWebAPI"
                }
            }

我在客戶端請求以下范圍:'openid個人資料電子郵件角色ZooWebAPI'

WebAPI的設置如下:

    public void ConfigureServices(IServiceCollection services)
    {
        services
            .AddMvcCore()
            .AddJsonFormatters()
            .AddAuthorization();

        services.AddCors();
        services.AddDistributedMemoryCache();

        services.AddAuthentication("Bearer")
            .AddIdentityServerAuthentication(options =>
            {
                options.Authority = "https://localhost:44317";
                options.RequireHttpsMetadata = false;
                options.ApiName = "ZooWebAPI";    
            });


    }

    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }

        app.UseCors(policy =>
        {
            policy.WithOrigins("http://localhost:4200");
            policy.AllowAnyHeader();
            policy.AllowAnyMethod();
            policy.AllowCredentials();
            policy.WithExposedHeaders("WWW-Authenticate");
        });

        app.UseAuthentication();
        app.UseMvc();
    }

通過使用[授權],我成功地保護了API:

[Route("api/[controller]")]
    [Authorize]
    public class ValuesController : Controller
    {
        // GET api/values
        [HttpGet]
        public ActionResult Get()
        {
            return new JsonResult(User.Claims.Select(
                c => new { c.Type, c.Value }));
        }
    }

一切正常,如果客戶端未通過身份驗證,瀏覽器將轉到IDP,需要身份驗證,使用訪問令牌重定向回去,然后將訪問令牌用於成功進行的API調用。

如果查看User對象中的Claims,可以看到一些信息,但沒有任何用戶信息。 我可以看到范圍等,但是沒有角色。 從我所讀的內容中可以預料到,API不應該在乎用戶正在調用什么,但是如何通過基於角色的API調用來限制我呢? 還是完全違反規格?

IDP有一個userinfo端點,該端點返回所有用戶信息,我認為可以在WebAPI中使用它,但是再次從閱讀中可以看出,它的意圖是僅從客戶端調用該端點。

無論如何,我想基於特定用戶的角色來限制Web API調用。 有人有任何建議,意見嗎? 另外,我想知道是什么用戶在撥打電話,我該怎么辦?

JWT示例:

在此處輸入圖片說明

謝謝

從我可以從您的信息中學到的東西,我可以告訴以下內容。

您正在通過外部提供程序登錄:Windows身份驗證。 您正在定義一些范圍,以將某些內容傳遞給令牌,以指示對特定資源的訪問。

您所說的User對象是從訪問令牌中填充的User類。 由於訪問令牌默認情況下不包括用戶個人資料聲明,因此您不會在User對象上使用它們。 這與直接使用Windows身份驗證(在用戶原則上提供用戶名)不同。

您需要采取其他措施來基於用戶登錄提供授權。您可以在以下幾點添加授權邏輯:

您可以根據在Identityserver的配置中定義的自定義范圍來定義聲明。 恕我直言,這是不可取的,因為它是固定於登錄方法而不是用戶登錄的。

您可以使用ClaimsTransformation(請參見下面的鏈接)。 這使您可以將聲明添加到方法開始時可用的聲明列表中。 這有一個缺點(對某些人來說是肯定的),這些額外的聲明不會被添加到訪問令牌本身中,只有在評估令牌的后端,才可以在您的代碼處理請求之前添加這些聲明。 。

您如何檢索這些聲明取決於您的業務需求。

如果需要用戶信息,則必須調用Identityserver的userinfo端點至少知道用戶名。 這就是該端點的目的。 基於此,您可以使用自己的邏輯來確定該用戶擁有的“角色”。

例如,我們創建了一個單獨的服務,可以根據用戶和訪問令牌中包含的范圍來配置和返回“角色”聲明。

UseClaimsTransformation .NET Core

UseClaimsTransformation .NET完整框架

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM