我有一个在ASP.NET MVC 5框架顶部使用c#编写的应用程序。
我通过继承ValidateCookieValueAction
类创建了自定义操作过滤器(即ActionFilterAttribute
)。我对我的多个操作方法使用ValidateCookieValueAction
属性。
过滤器的目的是确保用户在允许其进入操作之前具有cookie值。尽管存在安全问题,但过滤器效果很好。但是,在让用户进入之前,需要验证cookie值本身。
要验证cookie值,我需要一个DbContext
的实例,这样我就可以查询数据库并验证cookie值。
我知道我可以直接在ActionFilter中创建DbContext
的新实例。但是,我想要狂热。我希望能够从控制器传递我已创建的DbContext
实例,以允许我重用已在控制器中建立的连接。
以下是我的控制器设置方法
public class BaseController
{
protected IDbContext Context { get; private set; }
protected override void Initialize(RequestContext requestContext)
{
base.Initialize(requestContext);
Context = new DbContext();
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
Context.Dispose();
}
base.Dispose(disposing);
}
}
public class TestController : BaseController
{
[ValidateCookieValueAction]
public ActionResult Index()
{
// the uses is in!
return View();
}
}
这是我的动作过滤器类
public class ValidateCookieValueAction : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
base.OnActionExecuting(filterContext);
var cookie = new CookieJar(filterContext.HttpContext);
if (!cookie.Has(ContactListCookieName))
{
var Url = new UrlHelper(filterContext.RequestContext);
var url = Url.Action("Guest", "Test");
filterContext.Result = new RedirectResult(url);
}
}
}
如何将Context
的实例传递给ValidateCookieValueAction
?
答案 0 :(得分:1)
这与原始问题没有直接关系,但您似乎自己创建了身份验证机制。如果没有,请告诉我;我只是删除了这个答案。
ASP.NET已经有 ASP.NET标识 ,它比我们自己创建它更安全,更可靠。但是,如果要使用现有的自定义表,则可以使用基本上是ASP.NET标识子集的OWIN中间件。
使用OWIN中间件的主要优点是您可以使用ASP.NET MVC附带的 授权 属性。实施比您想象的要容易得多。
示例代码 -
OWIN Authentication Middle-ware
public class Startup
{
public void Configuration(IAppBuilder app)
{
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = "ApplicationCookie",
LoginPath = new PathString("/Account/Login")
});
}
}
Store access as role claim in Principle object
public void SignIn(User user, IList<string> roleNames)
{
IList<Claim> claims = new List<Claim>
{
new Claim(ClaimTypes.Sid, user.Id.ToString()),
new Claim(ClaimTypes.Name, user.UserName),
new Claim(ClaimTypes.GivenName, user.FirstName),
new Claim(ClaimTypes.Surname, user.LastName),
};
foreach (string roleName in roleNames)
{
claims.Add(new Claim(ClaimTypes.Role, roleName));
}
ClaimsIdentity identity = new ClaimsIdentity(claims, AuthenticationType);
IOwinContext context = _context.Request.GetOwinContext();
IAuthenticationManager authenticationManager = context.Authentication;
authenticationManager.SignIn(identity);
}
[Authorize(Roles = "CanViewHome")]
public class IndexController : Controller
{
[Authorize(Roles = "CanEditHome")]
public ActionResult Edit()
{
return View();
}
}
答案 1 :(得分:0)
默认情况下,当前上下文中已存在上下文。
在Startup.Configuration(IAppBuilder应用程序)
中app.CreatePerOwinContext(ApplicationDbContext.Create); // this already stores a DbContext
您可以使用
获取它var dbContext = HttpContext.GetOwinContext().Get<ApplicationDbContext>();
或者,您可以将Context存储在[TempData]或[Session]中。
如果你在同一个Request中重新获取它,那么只需在Context.Items []中抛出DbContext,这些只是当前Request的最后一个。
:
filterContext.Controller.TempData
控制器中的:
this.TempData