【问题标题】:ASP.NET Core Authentication : Bearer Token for an action and Windows Authentication for another in the same controllerASP.NET Core 身份验证:一个操作的承载令牌和同一控制器中另一个的 Windows 身份验证
【发布时间】:2020-01-25 09:19:11
【问题描述】:

我想做的是在我的 API 中提出可以通过 Windows 身份验证或 JWT 不记名身份验证访问的不同类型的端点。

Startup.cs --> Configure中,身份验证配置如下,以允许使用所需参数进行承载身份验证:

// Add JWT Bearer
services.AddAuthentication(x =>
{
    x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
    x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
}).AddJwtBearer(x =>
{
    x.RequireHttpsMetadata = false;
    x.SaveToken = true;
    x.TokenValidationParameters = new TokenValidationParameters
    {
        ValidateIssuerSigningKey = true,
        IssuerSigningKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(tokenManagement.Secret)),
        ValidIssuer = tokenManagement.Issuer,
        ValidateIssuer = true,
        ValidateLifetime = true,
        ValidateAudience = false,
        ClockSkew = TimeSpan.FromSeconds(tokenManagement.ClockSkewSeconds)
    };
});

为了保护我的端点,我尝试了这样的方法:

// THIS WAY I CAN LIMIT TO WINDOWS CREDENTIAL
[Authorize]
[HttpGet("[action]")]
public IActionResult AuthorizeWindowsUser()
{
    var user = HttpContext.User;
    if (user.GetType() == typeof(System.Security.Principal.WindowsPrincipal))
    {
        return Ok();
    }
    return Unauthorized();
}

// THIS WAY I CAN LIMIT TO JWT
[Authorize]
[HttpGet("[action]")]
public IActionResult AuthorizeLoginUser()
{
    var user = HttpContext.User;
    if (user.GetType() == typeof(System.Security.Claims.ClaimsPrincipal))
    {
        return Ok();
    }
    return Unauthorized();
}

它正在工作,但我的问题是:

  • 这看起来合乎逻辑吗?我的目标是保护提供用户令牌的端点。一个端点将受到 JWT 令牌(刷新令牌)和特定角色的保护,一个端点将受到 Windows 凭据的保护。
  • 我错过了什么吗?当我只使用 Windows 身份验证时,我曾经在我的 Startup.cs --> Configure 中设置 services.AddAuthentication(IISDefaults.AuthenticationScheme);似乎没有必要在上面描述的实现中工作,但我真的不知道这条线是做什么的以及是否有必要(顺便说一句,似乎没有)。
  • 是否有更智能/更漂亮的方法来检查用户类型?可能类似于自定义属性

感谢您的建议!

【问题讨论】:

    标签: authentication asp.net-core


    【解决方案1】:

    好像没有必要工作

    那是因为WebHost.CreateDefaultBuilder(args) 为您完成了这项工作。该方法将调用.UseIISIntegration(); 并在后台添加相关服务。有关更多详细信息,请参阅 Source code of invoking UseIISIntegration()Source of UseIISIntegration() method

    是否有更智能/更漂亮的方法来检查用户类型?也许类似于自定义属性

    您不必在操作方法中手动检查if( user.GetType() == typeof(System.Security.Principal.WindowsPrincipal) {return ok;} return Unauthorized()。请改用内置的AuthorizeAttribute

    [授权(AuthenticationSchemes = "Windows")] [HttpGet("[动作]")] 公共 IActionResult AuthorizeWindowsUser() { var user = HttpContext.User; if (user.GetType() == typeof(System.Security.Principal.WindowsPrincipal)) { 返回确定(); } return Unauthorized(); 返回确定(); // 只有使用 Windows 方案授权的用户才能访问此方法 }

    Jwt Bearer 也是如此。由于您已将JwtBearerDefaults.AuthenticationScheme 配置为默认身份验证方案,因此在使用[Authorize()] 属性注释时可以省略AuthenticationSchemes 参数:

    [授权] [HttpGet("[动作]")] 公共 IActionResult AuthorizeLoginUser() { var user = HttpContext.User; if (user.GetType() == typeof(System.Security.Claims.ClaimsPrincipal)) { 返回确定(); } return Unauthorized(); 返回确定(); // 只有使用默认方案授权的用户才能访问此方法 }

    【讨论】:

    • 哇,[Authorize(AuthenticationSchemes = "Windows")] 正是我所需要的,非常感谢您的回答和相关的解释,非常有帮助。
    猜你喜欢
    • 2023-04-10
    • 2018-04-23
    • 2018-01-24
    • 2021-12-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-16
    • 2010-10-27
    相关资源
    最近更新 更多