1. 程式人生 > >IdentityServer4主題之保護APIs

IdentityServer4主題之保護APIs

overview addm 實現 pan vcop ogg lte val 驗證

Protecting APIs 保護api

默認情況下IdentityServer將access token發布成JWT(json web token)格式的。

現在,每個相關的平臺都支持驗證JWT令牌,這裏可以找到一個很好的JWT庫列表。流行的庫如:

  • JWT bearer authentication handler for ASP.NET Core
  • JWT bearer authentication middleware for Katana
  • IdentityServer authentication middleware for Katana
  • jsonwebtoken for nodejs

保護基於Asp.net core的api需要做的事情就是在DI中配置jwt bearer authentication handler。並且在管道上面添加authentication中間件:

public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddMvc();

        services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
            .AddJwtBearer(options 
=> { // base-address of your identityserver options.Authority = "https://demo.identityserver.io"; // name of the API resource options.Audience = "api1"; }); } public void Configure(IApplicationBuilder app, ILoggerFactory loggerFactory) { app.UseAuthentication(); app.UseMvc(); } }

The IdentityServer authentication handler

我們的身份驗證處理程序(指IdentityServer4中提供的handler)與上面的處理程序(handler)有相同的用途(實際上它在內部使用Microsoft JWT庫),但是添加了一些額外的特性:

  • support for both JWTs and reference tokens //同時支持JWTs和引用token
  • extensible caching for reference tokens//為引用token支持緩存
  • unified configuration model//統一了配置模型
  • scope validation//範圍的檢查

對於最簡單的場景,我們的handler配置過程看起來和上面的代碼片段非常相似:

public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddMvc();
        //api保護是在api裏面做的,需要引入IdentityServer4.AccessTokenValidation這個nuget包。比如下面這個參數來自包中
        services.AddAuthentication(IdentityServerAuthenticationDefaults.AuthenticationScheme)
            .AddIdentityServerAuthentication(options =>
            {
                // base-address of your identityserver
                options.Authority = "https://demo.identityserver.io";

                // name of the API resource
                options.ApiName = "api1";
            });
    }

    public void Configure(IApplicationBuilder app, ILoggerFactory loggerFactory)
    {
        app.UseAuthentication();
        app.UseMvc();
    }
}

Supporting reference tokens支持引用token

如果進來的令牌不是JWT,我們的中間件將會聯系發現文檔(discovery document,就是./well-known/openid-configuration端點)中找到的內省端點(introspection endpoint)來驗證令牌。由於自省端點需要認證,所以你需要提供配置的API秘密,例如:

.AddIdentityServerAuthentication(options =>
{
    // base-address of your identityserver
    options.Authority = "https://demo.identityserver.io";

    // name of the API resource
    options.ApiName = "api1";
    options.ApiSecret = "secret";
})

通常,你不希望為每個傳入的請求對自省端點進行一次往返。中間件有一個內置的緩存,可以這樣啟用:

.AddIdentityServerAuthentication(options =>
{
    // base-address of your identityserver
    options.Authority = "https://demo.identityserver.io";

    // name of the API resource
    options.ApiName = "api1";
    options.ApiSecret = "secret";
    options.EnableCaching = true;
    options.CacheDuration = TimeSpan.FromMinutes(10); // that‘s the default
})
//處理程序將使用在DI容器中註冊的任何i分布式緩存實現(例如標準的memory分布式緩存)。

Validating scopes檢查請求的範圍

ApiName屬性(上面的代碼提到的這個屬性)檢查傳過來的token的audience(或者叫做aud)的claim,查看是否匹配。

在IdentityServer中你可以將API繼續細分成多個範圍。如果你需要這種粒度的分化那麽你可以使用ASP.NET Core 中的授權策略(authorization policy system)來檢查scope:

  • 創建全局的策略(基於MVCOpitons進行配置,添加到過濾器上)
services.AddMvcCore(options =>
    {
        // require scope1 or scope2。create是擴展方法,在內部
       //調用了requireclaim。
        var policy = ScopePolicy.Create("scope1", "scope2");
        options.Filters.Add(new AuthorizeFilter(policy));
    })
    .AddJsonFormatters()
    .AddAuthorization();
  • 構建一個範圍策略(基於AuthorizationOptions進行構建)
services.AddAuthorization(options =>
{
    options.AddPolicy("myPolicy", builder =>
    {
        // 來自identityserver的擴展方法
        builder.RequireScope("scope1");
        // and require scope2 or scope3
        builder.RequireScope("scope2", "scope3");
    });
});

IdentityServer4主題之保護APIs