identityserver 默认以jwt(json web令牌)格式发出访问令牌。

今天的每个相关平台都支持验证jwt令牌,可以找到一个很好的jwt库列表。热门库例如:

  • asp.net core的jwt bearer authentication handler
  • katana的jwt bearer authentication middleware
  • katana的identityserver authentication middleware
  • nodejs的

保护基于asp.net core的api只需在di中配置jwt承载认证处理程序,并将认证中间件添加到管道:

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();
    }
}

29.1 identityserver身份验证处理程序

我们的身份验证处理程序与上述处理程序的用途相同(实际上它在内部使用microsoft jwt库),但添加了一些其他功能:

  • 支持jwt和参考令牌
  • 用于引用标记的可扩展缓存
  • 统一配置模型
  • 范围验证

对于最简单的情况,我们的处理程序配置看起来非常类似于上面的代码段:

public class startup
{
    public void configureservices(iservicecollection services)
    {
        services.addmvc();

        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();
    }
}

你可以从nuget或github获得包。

29.2 支持引用标记

如果传入令牌不是jwt,我们的中间件将联系发现文档中的内省端点以验证令牌。由于内省端点需要身份验证,因此您需要提供已配置的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容器中注册的任何idistributedcache实现(例如标准的memorydistributedcache)。

29.3 验证范围

所述apiname属性检查该令牌具有匹配观众(或短aud),如权利要求。

在identityserver中,您还可以将api细分为多个范围。如果需要该粒度,可以使用asp.net core授权策略系统来检查范围。

29.3.1 制定全球政策:

services
    .addmvccore(options =>
    {
        // require scope1 or scope2
        var policy = scopepolicy.create("scope1", "scope2");
        options.filters.add(new authorizefilter(policy));
    })
    .addjsonformatters()
    .addauthorization();

29.3.2 制定范围政策:

services.addauthorization(options =>
{
    options.addpolicy("mypolicy", builder =>
    {
        // require scope1
        builder.requirescope("scope1");
        // and require scope2 or scope3
        builder.requirescope("scope2", "scope3");
    });
});

github地址