【问题标题】:asp.net core 2.0 authorize with a specific schemeasp.net core 2.0 授权特定方案
【发布时间】:2018-06-02 17:56:15
【问题描述】:

我有一个带有 cookie 和 jwt 身份验证方案的应用程序。这是ConfigureServices 代码:

var authTokenSettings = configuration.GetSection(nameof(TokenProviderSettings)).Get<TokenProviderSettings>();

services.AddAuthentication(options =>
{
    options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
    options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddCookie(authSection.AuthenticationScheme, u =>
{
    u.Cookie.Name = authSection.AuthCookieName;
    u.LoginPath = new PathString(authSection.LoginPath);
    u.AccessDeniedPath = "/Home/Index";
})
.AddJwtBearer(JwtBearerDefaults.AuthenticationScheme, options =>
{
    options.RequireHttpsMetadata = false;
    options.TokenValidationParameters = new TokenValidationParameters
    {
        ValidateIssuer = true,
        ValidIssuer = authTokenSettings.Issuer,
        ValidateAudience = true,
        ValidAudience = authTokenSettings.Audience,
        ValidateLifetime = true,
        IssuerSigningKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(authTokenSettings.Key)),
        ValidateIssuerSigningKey = true,
    };
});

现在我需要在一种方法上使用 cookie 方案,在另一种方法上使用 jwt。我已经添加了适当的属性

([Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)])

但是这些属性被忽略了,使用默认方案。如果我没有指定默认方案,我会得到这个异常:

System.InvalidOperationException: 没有 authenticationScheme 指定,但没有找到 DefaultChallengeScheme。

代码有什么问题?

【问题讨论】:

  • 忽略属性是什么意思?您将 Jwt 指定为 Authorize 属性中的方案,这 也是 根据您的配置的默认值。所以当然你会得到“默认”方案。 – 您不能单独使用 cookie 身份验证,因为它不能单独挑战。它将质询请求传递给默认质询方案,因此使用您的配置,您将继续运行 Jwt 身份验证。
  • 我有带有 cookie 身份验证的应用程序,并为 2 种方法添加 jwt 之一。如果我将 cookie 身份验证方案设置为默认值 - jwt 身份验证将被忽略
  • 你确定它被忽略了吗?还是只是它在您的默认值之后运行?

标签: authentication cookies asp.net-core jwt


【解决方案1】:

我已经解决了这个问题。属性[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)] 仅在添加到控制器时定义身份验证方案,而不是在操作中

【讨论】:

  • 我认为这不是真的。我认为您可能需要在“混合”控制器中的每个操作上都有 [Authorize] 属性,而不是在控制器级别设置一个并尝试“覆盖”特定操作。
  • 我已经尝试过了,但遇到了上述问题。当我将我的控制器分成 2 个不同的控制器并为每个控制器添加属性时 - 它起作用了
【解决方案2】:

不需要单独的控制器,可以实现IControllerModelConvention

public class AddAuthorizeFiltersControllerConvention : IControllerModelConvention
{
    public void Apply(ControllerModel controller)
    {
        if (controller.ControllerName.Contains("Api"))
        {
            controller.Filters.Add(new AuthorizeFilter("apipolicy"));
        }
        else
        {
            controller.Filters.Add(new AuthorizeFilter("defaultpolicy"));
        }
    }
}

或者实现 IActionModelConvention

public class AddAuthorizeFiltersActionConvention : IActionModelConvention
{
    public void Apply(ActionModel action)
    {
        if (action.ActionName.Contains("GetUser"))
        {
            action.Filters.Add(new AuthorizeFilter("apipolicy"));
        }
        else
        {
            action.Filters.Add(new AuthorizeFilter("defaultpolicy"));
        }
    }
}

参考和信用https://joonasw.net/view/apply-authz-by-default

【讨论】:

  • 您的代码有错误。如果您过滤某些操作但使用“action.Controller.Filters”,它会将其应用于相关控制器,因此应用于此控制器中的所有操作。请改用“action.Filters”。
猜你喜欢
  • 2018-04-03
  • 2018-09-29
  • 2018-08-25
  • 1970-01-01
  • 1970-01-01
  • 2011-04-27
  • 2021-03-17
  • 1970-01-01
  • 2020-09-25
相关资源
最近更新 更多