C# 将WindowsAuthentication与数据库中存储的规则相结合

C# 将WindowsAuthentication与数据库中存储的规则相结合,c#,asp.net-mvc,asp.net-mvc-5,C#,Asp.net Mvc,Asp.net Mvc 5,我有一个ASP.NET MVC5应用程序,它使用WindowsAuhhentication对用户进行身份验证。现在,我需要为这个应用程序添加一个安全层,并希望基于标准MVC安全模型,使用authorized属性。这依赖于User.IsInRole,但当前它将返回用户所属的组。我不想将角色作为组存储在广告中,相反,我只想将每个用户的角色存储在我的数据库中 所以问题是,我如何覆盖WindowsPrincipal中的IsInRole方法,或者我可以创建一个自定义Principal来实现我想要的功能 我

我有一个ASP.NET MVC5应用程序,它使用WindowsAuhhentication对用户进行身份验证。现在,我需要为这个应用程序添加一个安全层,并希望基于标准MVC安全模型,使用authorized属性。这依赖于User.IsInRole,但当前它将返回用户所属的组。我不想将角色作为组存储在广告中,相反,我只想将每个用户的角色存储在我的数据库中

所以问题是,我如何覆盖WindowsPrincipal中的IsInRole方法,或者我可以创建一个自定义Principal来实现我想要的功能

我发现了很多关于类似主题的信息,但其中大多数似乎都参考了MVC4,从我收集的信息来看,MVC4和MVC5之间的整个安全模型都发生了变化。那么现在最好的方法是什么呢

非常感谢所有的帮助和指点

干杯,迈克


另外,如果有人知道如何最好地将EF、IOC和缓存融入其中,那就太好了。

我发现与旧的会员资格提供商相比,MVC5 Asp.Identity对开发人员非常友好。。。这可能是目前缺乏文档的原因。它实际上是直观的

如果身份验证规则驻留在数据库中,EntityFramework将把存储过程转换为复杂类型。完成后,您可以创建一个“AuthenticationService”服务层,并根据需要使用DI将复杂类型注入Asp.Identity

要自定义Asp.Net Identity,您只需将属性添加到IdentityModels.cs和AccountViewModels.cs,默认情况下,Asp.Identity使用ApplicationDbContext,您无需对其进行任何配置


此外,您可以使用与User.IsInRole类似的方式访问用户信息。

好的,这就是我所做的。我真的很想得到人们对我的最佳实践和改进的反馈

我创建了一个从WindowsPrincipal派生的新主体,并使用重写的IsInRole方法

public class QSDPrincipal : WindowsPrincipal
{
    private readonly IUserService userService;

    public QSDPrincipal(WindowsIdentity ntIdentity,
        IUserService userService) :
        base(ntIdentity)
    {
        this.userService = userService;
    }

    public override bool IsInRole(string role)
    {
        return userService.CurrentUserIsInRole(role);
    }
}
这使用DI来填充位于我的BL层中的userService对象。因此,我必须配置容器以正确构建它

container.RegisterType<WindowsIdentity>(new HierarchicalLifetimeManager(),
    new InjectionFactory(x => (WindowsIdentity)HttpContext.Current.User.Identity));

container.RegisterType<IPrincipal, QSDPrincipal>(new HierarchicalLifetimeManager());
然后在UserService本身中,我实现了一个方法,并实现了一些简单的缓存,这样每个请求只进行一次DB查询

public bool CurrentUserIsInRole(string role)
{
    return CurrentUserRoles.Contains(role);
}

private IEnumerable<string> currentUserRoles;

public IEnumerable<string> CurrentUserRoles
{
    get
    {
        if (currentUserRoles == null)
        {
                 var user = GetCurrentUser();

            currentUserRoles = new List<string>
            {
                user.Role.Name
            };
        }

        return currentUserRoles;
    }
}
就这样,一切似乎都起了作用

非常感谢您的想法和改进


为迈克干杯

谢谢你的回答,但是,如果我没看错的话,你认为我想使用表单身份验证,而我没有。应用程序使用Windows身份验证,需要继续使用Windows身份验证。
public bool CurrentUserIsInRole(string role)
{
    return CurrentUserRoles.Contains(role);
}

private IEnumerable<string> currentUserRoles;

public IEnumerable<string> CurrentUserRoles
{
    get
    {
        if (currentUserRoles == null)
        {
                 var user = GetCurrentUser();

            currentUserRoles = new List<string>
            {
                user.Role.Name
            };
        }

        return currentUserRoles;
    }
}