MVC IAuthenticationFilter Windows身份验证覆盖主体和缓存

时间:2017-07-07 23:00:39

标签: asp.net-mvc authentication caching cookies asp.net-mvc-5

提前抱歉这篇文章。

我有一个使用Windows身份验证的MVC应用程序。 许多角色和“系统操作”已存储在数据库中。 我创建了一个自定义主体,它有一个ClaimsPrincipal基础。 我还创建了一个实现IAuthenticationFilter的AuthenticationFilter。 在过滤器中,我创建了我的自定义主体的新实例,将角色和“系统操作”添加为声明,然后将其分配给filter.Principal。

从那里我有一个自定义AuthorizationAttribute,它将利用这些角色和系统操作。 (即每个控制器/动作都有[CustomAuthorizationAttribute(Roles =“blah”,SystemActions =“blah”)])

此外 - 我有一个免责声明页面 - 当用户同意时,需要在我的CustomPrincipal中存储声明。我的自定义授权属性然后检查该声明是否存在。

现在背景已经不在了; 问题是我需要以某种方式缓存此主体 - 这样我就不必在每个请求上都访问数据库。 我最好把它存放在会话中吗?还是饼干?或者还有其他方法吗? 各自的优点和缺点是什么? 我倾向于使用一个cookie - 虽然这个决定并不是很多地了解每个人的利弊(因此上面的问题)。 我将如何实施cookie?

在免责声明页面中,我需要添加“DisclaimerAccepted”声明,并更新缓存。

AuthFilter代码供参考:

public class AuthenticationFilter : ActionFilterAttribute, IAuthenticationFilter
{
    public void OnAuthentication(AuthenticationContext filterContext)
    {
        var principal = new CustomPrincipal(filterContext.Principal);

        var roles = GetRolesForUser(principal.Identity.Name);
        var systemActions = new List<SystemAction>();

        foreach (var role in roles)
        {
            principal.AddRole(role.Name);
            systemActions.AddRange(GetSystemActionsForRole(role.Id));
        }

        principal.AddSystemActions(systemActions.Select(a => a.Name));

        filterContext.Principal = principal;
    }

    public void OnAuthenticationChallenge(AuthenticationChallengeContext filterContext)
    {
        if (!filterContext.HttpContext.User.Identity.IsAuthenticated)
            filterContext.Result = new HttpUnauthorizedResult();
    }
}

1 个答案:

答案 0 :(得分:1)

  

问题是我需要以某种方式缓存这个主体 - 所以我   不必在每个请求上都打到数据库。我最好存放它   在会议中?

您可以使用我们在Cookie中存储声明的OWIN Cookie中间件,以便我们只查询数据库一次。

在后续请求中,OWIN Cookie中间件从cookie中检索声明,并将其添加到Principle对象。

  

另外 - 我有一个免责声明页面 - 当用户同意时,   需要在我的CustomPrincipal中存储声明。

如果您要添加新版权声明,则需要再次致电authenticationManager.SignIn(identity);

Startup.cs

启动时配置OWIN Cookie中间件。

[assembly: OwinStartup(typeof(YourApplication.Startup))]
namespace YourApplication
{
    public class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            app.UseCookieAuthentication(new CookieAuthenticationOptions
            {
                AuthenticationType = "ApplicationCookie",
                LoginPath = new PathString("/Account/Login")
            });
        }
    }
}

OwinAuthenticationService

public class OwinAuthenticationService : IAuthenticationService
{
    private readonly HttpContextBase _context;
    private const string AuthenticationType = "ApplicationCookie";

    public OwinAuthenticationService(HttpContextBase context)
    {
        _context = context;
    }

    public void SignIn(User user)
    {
        IList<Claim> claims = new List<Claim>
        {
            new Claim(ClaimTypes.Name, user.UserName),
            new Claim(ClaimTypes.GivenName, user.FirstName),
            new Claim(ClaimTypes.Surname, user.LastName),
        };

        ClaimsIdentity identity = new ClaimsIdentity(claims, AuthenticationType);

        IOwinContext context = _context.Request.GetOwinContext();
        IAuthenticationManager authenticationManager = context.Authentication;

        authenticationManager.SignIn(identity);
    }

    public void SignOut()
    {
        IOwinContext context = _context.Request.GetOwinContext();
        IAuthenticationManager authenticationManager = context.Authentication;

        authenticationManager.SignOut(AuthenticationType);
    }
}

您可以在GitHub查看我的工作示例项目。