我使用 AuthorizeAttribute 检查用户是否设置了超过18岁的Cookie以访问网页。
这很好用,但我现在略有延伸。 由于所有视图都使用此属性,因此我使用它来允许我尽早启动我的网站。 如果对任何URL使用add?VIEWSITE = true,它将设置一个Session变量,并允许它们访问该站点。否则,他们会被引导到一个控股页面。
首次运行页面时,此工作正常。但是,我在页面上使用输出缓存,下次加载页面时,我的httpcontext.session为空?
我在属性中添加了“Order”变量,以确保它们以正确的顺序执行:
[OfAge(Order = 1)]
[OutputCache(Order = 2, Duration = 2000, VaryByParam = "categoryName")]
从我的属性中删除:
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
HttpRequestBase req = httpContext.Request;
HttpResponseBase res = httpContext.Response;
DateTime Live_Date = new DateTime(2011, 07, 01, 07, 0, 0);
if (DateTime.Now > Live_Date || req.QueryString["VIEWSITE"] != null || httpContext.Session["VIEWSITE"] != null)
{
httpContext.Session["VIEWSITE"] = true;
从缓存加载页面后,我有什么东西可供我读取/设置会话变量吗?
要清楚,它的httpContext.Session为null,而不是具体的httpContext.Session [“VIEWSITE”]
答案 0 :(得分:1)
3年后,我遇到了类似的问题。现在我不是专家,但我相信每个控制器上下文调用在它自己的空间中是唯一的,因此httpContext.Session在新调用时将为null。
我的问题出现在我希望在会话变量中存储(具有自定义应用程序权限)的已登录AD用户的形式。我也在AuthorizationAttribute上进行扩展,但是当此过滤器应用于控制器操作时,即使用户已保存,httpContext也为null。
对于与同一问题作斗争的人来说,解决这个问题的方法是创建一个基本控制器,其中该用户及其会话状态保存在其他控制器中(继承基本控制器)。
离。
我的模特:
public class LoggedInUser
{
public somenamespace.userclass UserProfile { get; set; }
public List<somenamespace.user_permission_class> UserPermissions { get; set; }
}
我的基本控制器:
public class ControllerBase : Controller
{
private LoggedInUser _LoginUser;
public LoggedInUser LoginUser
{
get
{
if (_LoginUser != null)
return _LoginUser;
if (Session["_LoginUser"] == null)
return null;
return Session["_LoginUser"] as LoggedInUser;
}
set
{
_LoginUser = value;
Session["_LoginUser"] = _LoginUser;
}
}
public void PerformUserSetup(string sUsername) // sUsername for testing another user, otherwise User.Identity will be used.
{
sUsername = string.IsNullOrEmpty(sUsername) ? User.Identity.Name : sUsername;
sUsername = (sUsername.IndexOf("\\") > 0) ? sUsername.Split('\\').ToArray()[1] : sUsername;
// Todo - SQL conversion to stored procedure
List<userclass> tmpUser = Root.Query<userclass>(/*sql to select user*/).ToList();
List<user_permission_class> tmpUserpermissions = Root.Query<user_permission_class>(/*sql to select user permissions*/).ToList();
LoggedInUser _LoginUser = new LoggedInUser();
_LoginUser.UserProfile = tmpUser.First();
_LoginUser.UserPermissions = tmpUserpermissions;
LoginUser = _LoginUser;
}
}
我的HomeController(任何MVC示例的标准):
public class HomeController : ControllerBase
{
[Authorize] // Standard AuthorizeAttribute (AD test)
public ActionResult Index()
{
if (Session["_LoginUser"] == null)
PerformUserSetup("");
return View();
}
}
我的自定义权限检查过滤器,我将在任何其他控制器操作上使用:
public class PermissionAuthorize : AuthorizeAttribute
{
private readonly string[] permissions;
public PermissionAuthorize(params string[] perms)
{
this.permissions = perms;
}
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
bool auth = false;
if (httpContext.Session["_LoginUser"] == null)
{
// Do nothing as auth is false.
}
else
{
// Check permissions and set auth = true if permission is valid.
auth = true;
}
return auth;
}
/* not using
public override void OnAuthorization(AuthorizationContext filterContext)
{
var tmp = filterContext.HttpContext.Session;
}
*/
protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
{
// Todo - direct to "unauth page"
base.HandleUnauthorizedRequest(filterContext);
}
}
用法:
public class Some_OtherController : /*PossibleNamespace?.*/ControllerBase
{
[PermissionAuthorize("somepermission")] // This was a CRUD application thus 1 permission per actionresult
public ActionResult ViewWhatever()
{
....
}
}