提前抱歉这篇文章。
我有一个使用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();
}
}
答案 0 :(得分:1)
问题是我需要以某种方式缓存这个主体 - 所以我 不必在每个请求上都打到数据库。我最好存放它 在会议中?
您可以使用我们在Cookie中存储声明的OWIN Cookie中间件,以便我们只查询数据库一次。
在后续请求中,OWIN Cookie中间件从cookie中检索声明,并将其添加到Principle对象。
另外 - 我有一个免责声明页面 - 当用户同意时, 需要在我的CustomPrincipal中存储声明。
如果您要添加新版权声明,则需要再次致电authenticationManager.SignIn(identity);
。
启动时配置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")
});
}
}
}
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查看我的工作示例项目。