【问题标题】:ASP.NET Core - Authorization Using Windows AuthenticationASP.NET Core - 使用 Windows 身份验证进行授权
【发布时间】:2019-04-30 15:46:24
【问题描述】:

我已将我的 Web api 配置为使用 Windows 身份验证。我的目标本质上是根据用户 Windows 帐户限制我的控制器中的某些操作。有些将能够执行读取操作,而另一些将能够执行将写入底层数据库的操作。我找到了大量关于如何设置基于声明的授权的文档,这是我认为我需要走的路线。我还没有找到如何使用 windows auth 进行设置。我想我错过了一个中间步骤,例如将 Windows 身份验证注册为身份提供者?

startup.cs

public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc();

    services.AddAuthentication(IISDefaults.AuthenticationScheme);

    services.AddAuthorization(options =>
    {
        options.AddPolicy("readOnly", policy =>
                          policy.RequireClaim(`???????????????????????`));
        options.AddPolicy("write", policy =>
                          policy.RequireClaim(`???????????????????????`));
    });
}

控制器

[Authorize(Policy = "ReadOnly")]
public class MyController : Controller
{
    public ActionResult SomeReadOnlyAction()
    {
        //Return data from database
    }

    [Authorize(Policy = "Write")]
    public ActionResult AWriteAction()
    {
        //Create/Update/Delete data from database
    }
}

我想问这个问题的另一种方法是如何配置或访问声明/角色等...使用 Windows 身份验证。

【问题讨论】:

  • 你有电话到services.AddAuthentication(...)吗?
  • 不,我没有......
  • 你是绝对正确的。我已将其添加并更新了上面的代码。我想我的下一个问题是我如何访问凭据然后围绕它构建一个策略,以便我可以在我的控制器操作上使用特定的授权属性?

标签: c# iis asp.net-core authorization windows-authentication


【解决方案1】:

您似乎想通过策略使用基于声明的授权。在您的应用程序中设置 windows 身份验证后,您可以向 ClaimsPrincipal 添加自定义声明,检查用户身份并确认当前用户拥有的权限:

  1. 您可以向您的应用程序添加声明转换服务:

    class ClaimsTransformer : IClaimsTransformation
    {
        public Task<ClaimsPrincipal> TransformAsync(ClaimsPrincipal principal)
        {
            var id = ((ClaimsIdentity)principal.Identity);
    
            var ci = new ClaimsIdentity(id.Claims, id.AuthenticationType, id.NameClaimType, id.RoleClaimType);
            if (ci.Name.Equals("name"))
            {
                ci.AddClaim(new Claim("permission", "readOnly"));
            }
            else
            {
                ci.AddClaim(new Claim("permission", "write"));
    
            }
    
    
            var cp = new ClaimsPrincipal(ci);
    
            return Task.FromResult(cp);
        }
    }
    
  2. 添加到 Startup.cs(.net Core 2.0) :

        services.AddTransient<IClaimsTransformation, ClaimsTransformer>();
    
  3. 制定您的政策:

        services.AddAuthorization(options =>
        {
            options.AddPolicy("Readonly", policy =>
                              policy.RequireClaim("permission", "readOnly"));
    
            options.AddPolicy("Write", policy =>
                            policy.RequireClaim("permission", "write"));
        });
    
  4. 通过要求此政策来限制对控制器或操作的访问:

        [Authorize(Policy = "Write")]
        public IActionResult Contact()
        {
            ViewData["Message"] = "Your contact page.";
    
            return View();
        }
    

如果您已经在 AD 中添加了组(写入、只读)并将相关用户添加到组中,您也可以检查组:

public static class Security
{
    public static bool IsInGroup(this ClaimsPrincipal User, string GroupName)
    {
        var groups = new List<string>();

        var wi = (WindowsIdentity)User.Identity;
        if (wi.Groups != null)
        {
            foreach (var group in wi.Groups)
            {
                try
                {
                    groups.Add(group.Translate(typeof(NTAccount)).ToString());
                }
                catch (Exception)
                {
                    // ignored
                }
            }
            return groups.Contains(GroupName);
        }
        return false;
    }
}

并像这样使用:

 if (User.IsInGroup("GroupName"))
 {

 }

【讨论】:

  • 这太棒了! if(User.IsInGroup)... 去哪儿了?它会被丢弃在ClaimsTransformer 类中吗?
  • 或者你会用它作为 ClaimsTransformer 的替代品吗?
  • @LCaraway,这取决于你,它可以在任何班级。
  • group.Translate() 运行时会返回异常,说明工作站和主域之间的信任关系失败...
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-04-16
  • 1970-01-01
  • 1970-01-01
  • 2021-01-07
  • 2017-04-15
  • 2017-05-28
  • 2021-01-16
相关资源
最近更新 更多