如何在同一操作上支持多个Bearer令牌处理程序?

时间:2019-05-13 19:03:57

标签: asp.net-core-2.0 asp.net-authorization

我有一个具有OAuth(某种)实现的应用程序。我们正在迁移使用Identity Server进行OAuth,现在我需要在某些Controllers / Actions上同时支持两种身份验证方案。

每个Auth方法的承载令牌明显不同。一个是GUID,另一个是Identity Server生成的适当令牌。

我需要的是某种方式来查看令牌,并说字符串长度<= 36的任何内容都应该是旧方法。还要使用Identity Server。

根控制器具有基本的[Authorize]属性。另外,如果我切换方案中列出的第一个作品的顺序。

这是我的Startup.cs代码

        services.AddAuthentication(options =>
        {
            options.DefaultAuthenticateScheme = Constants.CompanyBearerScheme;
            options.DefaultChallengeScheme = Constants.CompanyBearerScheme;
        }).AddJwtBearer(options =>
        {
            options.Authority = "https://identityserverurl";
            options.Audience = "APISCOPE";
            options.RequireHttpsMetadata = true;
        }).AddBearerToken(Constants.CompanyBearerScheme, o =>
        {
            o.ConnectionString = bearerTokenHandlerOptions.ConnectionString;
            o.DefaultScopes = bearerTokenHandlerOptions.DefaultScopes;
        })

示例操作

    [Authorize(AuthenticationSchemes = "CompanyBearer,Bearer")]
    [HttpGet("TEST")]
    public async Task<IActionResult> TestAuthentication()
    {
    return Ok();
    }

样品申请

GET {{Url}}/Api/TEST
Authorization: Bearer SOMETOKEN

1 个答案:

答案 0 :(得分:0)

我知道了。

需要使用自定义策略方案来比较传入的请求。

 services.AddAuthentication(options =>
        {
            options.DefaultAuthenticateScheme = Constants.DefaultSelectorPolicy;
            options.DefaultChallengeScheme = Constants.DefaultSelectorPolicy;
        })
        .AddPolicyScheme(Constants.DefaultSelectorPolicy, Constants.DefaultSelectorPolicy, options =>
        {
            options.ForwardDefaultSelector = ctx =>
            {
                if (!ctx.Request.Headers.ContainsKey("Authorization"))
                {
                    return null;
                }

                var authorizationHeader = ctx.Request.Headers["Authorization"];

                var authorization = AuthenticationHeaderValue.Parse(authorizationHeader);

                if (authorization.Scheme.ToLower() != "bearer")
                {
                    return null;
                }

                if (authorization.Parameter.Length > 36)
                {
                    return "Bearer";
                }

                return Constants.CompanyBearerScheme;
            };
        })