ASP.NET Core身份验证:同一控制器中操作的承载令牌和Windows身份验证

时间:2019-09-25 08:13:59

标签: authentication asp.net-core

我想做的是在我的API中提出一种可以通过Windows身份验证或JWT承载身份验证访问的端点。

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

// 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->配置中设置 services.AddAuthentication(IISDefaults.AuthenticationScheme); 似乎如果没有必要在上面描述的实现中工作,但我真的不知道这行是什么,以及是否有必要(顺便说一句)。
  • 有没有更聪明/更漂亮的方法来检查用户类型?也许像是自定义属性

感谢您的建议!

1 个答案:

答案 0 :(得分:0)

  

似乎没有必要工作

那是因为WebHost.CreateDefaultBuilder(args)为您做到了。该方法将调用.UseIISIntegration();并在幕后添加相关服务。有关更多详细信息,请参见 Source code of invoking UseIISIntegration()Source of UseIISIntegration() method

  

有没有更聪明/更漂亮的方法来检查用户类型?也许像是自定义属性

您无需在action方法中手动检查if( user.GetType() == typeof(System.Security.Principal.WindowsPrincipal) {return ok;} return Unauthorized()。使用内置的AuthorizeAttribute代替:

[Authorize(AuthenticationSchemes = "Windows")]
[HttpGet("[action]")]
public IActionResult AuthorizeWindowsUser()
{
    var user = HttpContext.User;
    if (user.GetType() == typeof(System.Security.Principal.WindowsPrincipal))
    {
        return Ok();
    }
    return Unauthorized();
    return Ok();   // only users who are authorized with the Windows scheme can access this method
}

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

[Authorize]
[HttpGet("[action]")]
public IActionResult AuthorizeLoginUser()
{
    var user = HttpContext.User;
    if (user.GetType() == typeof(System.Security.Claims.ClaimsPrincipal))
    {
        return Ok();
    }
    return Unauthorized();
    return Ok();   // only users who are authorized with the default scheme can access this method
}