有的页面需要用户认证之后才可以进入,通常都是在Filter的OnActionExecuting方法中我们需要获取当前用户。有两种情况不必登录:1.用户是登录的,也就是认证过的。2.用户上次登录了,但没有退出就关闭了页面,且还Cookie还没有过期。这个时候
Request.IsAuthenticated=true
所以用户不必再登录。
如果用户退出,也就是调用SignOut()
public void SignOut()
{
_cachedUser = null;
FormsAuthentication.SignOut();
}
这个时候获取不到认证用户。
Filter就会让用户返回到登录页面。
var user = WorkContext.CurrentUser;
if (user == null)
{
filterContext.Result = new RedirectResult("~/Account/Logon?returnUrl=" + returnUrl);
}
另外,在Ninject中无法注入HttpContextBase,但可以讲其换成属性。
public HttpContextBase HttpContext
{
get { return new HttpContextWrapper(System.Web.HttpContext.Current); }
}
而对于Filter可以属性注入。
[Inject]
public IAuthenticationService AuthenticationService { get; set; }
LoginValidAttribute 源码:
public class LoginValidAttribute : ActionFilterAttributeView Code
{
/// <summary>
/// 转到管理员登陆的界面
/// </summary>
private bool _isAdmin;
public LoginValidAttribute(bool isadmin = false)
{
_isAdmin = isadmin;
}
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
var contr = filterContext.RouteData.Values["controller"].ToString();
var action = filterContext.RouteData.Values["action"].ToString();
var parmdatas = filterContext.ActionParameters;
var parms = "?";
var i = 0;
var count = parmdatas.Count;
foreach (var parmdata in parmdatas)
{
i++;
if (i <= count - 1)
{
parms += parmdata.Key + "=" + parmdata.Value + "&";
}
else
{
parms += parmdata.Key + "=" + parmdata.Value;
}
}
if (count == 0) parms = "";
var returnUrl = string.Format("~/{0}/{1}{2}", contr, action, parms);
returnUrl = UrlHelper.GenerateContentUrl(returnUrl, filterContext.HttpContext);
var user = WorkContext.CurrentUser;
if (user == null)
{
filterContext.Result = new RedirectResult("~/Account/Logon?returnUrl=" + returnUrl);
}
// 如果已经登录 但不是角色,就需要跳转到只是页面 提示是管理员才能登录
}
[Inject]
public IWorkContext WorkContext { get; set; }
}
WebWorkContext:
public class WebWorkContext : IWorkContextView Code
{
#region Const
#endregion
#region Fields
private readonly IUserService _userService;
private User _cachedUser;
#endregion
public WebWorkContext( IUserService userService )
{
_userService = userService;
}
#region Utilities
protected virtual HttpCookie GetUserCookie()
{
if (HttpContext == null || HttpContext.Request == null)
return null;
return HttpContext.Request.Cookies[PortalConfig.UserCookieName];
}
protected virtual void SetUserCookie(Guid customerGuid)
{
if (HttpContext != null && HttpContext.Response != null)
{
var cookie = new HttpCookie(PortalConfig.UserCookieName);
cookie.HttpOnly = true;
cookie.Value = customerGuid.ToString();
if (customerGuid == Guid.Empty)
{
cookie.Expires = DateTime.Now.AddMonths(-1);
}
else
{
int cookieExpires = 24 * 30; //TODO make configurable
cookie.Expires = DateTime.Now.AddHours(cookieExpires);
}
HttpContext.Response.Cookies.Remove(PortalConfig.UserCookieName);
HttpContext.Response.Cookies.Add(cookie);
}
}
#endregion
public virtual User CurrentUser
{
get
{
User customer = AuthenticationService.GetAuthenticatedCustomer(); ;
//load guest customer
if (customer == null || customer.Deleted || !customer.Active)
{
var customerCookie = GetUserCookie();
if (customerCookie != null && !String.IsNullOrEmpty(customerCookie.Value))
{
Guid customerGuid;
if (Guid.TryParse(customerCookie.Value, out customerGuid))
{
var customerByCookie = _userService.GetUserByGuid(customerGuid);
if (customerByCookie != null &&IsCurrentUser)
//this customer (from cookie) should not be registered
//!customerByCookie.IsRegistered())
customer = customerByCookie;
}
}
}
//validation
if (customer!=null&&!customer.Deleted && customer.Active)
{
SetUserCookie(customer.UserGuid);
}
return customer;
;
}
set
{
SetUserCookie(value.UserGuid);
_cachedUser = value;
}
}
public User OriginalUserIfImpersonated { get; private set; }
public bool IsAdmin { get; set; }
public bool IsCurrentUser {
get { return AuthenticationService.IsCurrentUser; }
}
public HttpContextBase HttpContext
{
get { return new HttpContextWrapper(System.Web.HttpContext.Current); }
}
[Inject]
public IAuthenticationService AuthenticationService { get; set; }
}
FormsAuthenticationService:
public class FormsAuthenticationService : IAuthenticationServiceView Code
{
private readonly IUserService _userService;
private readonly TimeSpan _expirationTimeSpan;
private User _cachedUser;
public FormsAuthenticationService(IUserService userService)
{
_userService = userService;
_expirationTimeSpan = FormsAuthentication.Timeout;
}
public void SignIn(User user, bool createPersistentCookie)
{
var now = DateTime.UtcNow.ToLocalTime();
var ticket = new FormsAuthenticationTicket(1, user.Username, now, now.Add(_expirationTimeSpan),
createPersistentCookie, user.Username, FormsAuthentication.FormsCookiePath);
var encryptedTicket = FormsAuthentication.Encrypt(ticket);
var cookie = new HttpCookie(FormsAuthentication.FormsCookieName, encryptedTicket) {HttpOnly = true};
if (ticket.IsPersistent)
{
cookie.Expires = ticket.Expiration;
}
cookie.Secure = FormsAuthentication.RequireSSL;
cookie.Path = FormsAuthentication.FormsCookiePath;
if (FormsAuthentication.CookieDomain != null)
{
cookie.Domain = FormsAuthentication.CookieDomain;
}
HttpContext.Response.Cookies.Add(cookie);
//nop源码中没有这一句,务必保证webconfig中的认证是form的。
// FormsAuthentication.SetAuthCookie(user.Username, createPersistentCookie);
_cachedUser = user;
}
public void SignOut()
{
_cachedUser = null;
FormsAuthentication.SignOut();
}
public User GetAuthenticatedCustomer()
{
if (_cachedUser != null) return _cachedUser;
if (HttpContext == null || HttpContext.Request == null || !HttpContext.Request.IsAuthenticated ||
!(HttpContext.User.Identity is FormsIdentity))
{
return null;
}
var formsIdentity = (FormsIdentity)HttpContext.User.Identity;
var user = GetAuthenticatedUserFromTicket(formsIdentity.Ticket);
if (user != null && user.Active && !user.Deleted )//&& user.IsRegistered()
_cachedUser = user;
return _cachedUser;
}
public bool IsCurrentUser
{
get { return GetAuthenticatedCustomer() != null; }
}
public virtual User GetAuthenticatedUserFromTicket(FormsAuthenticationTicket ticket)
{
if (ticket == null)
throw new ArgumentNullException("ticket");
var usernameOrEmail = ticket.Name;
if (String.IsNullOrWhiteSpace(usernameOrEmail))
return null;
var user = _userService.GetUserByUsername(usernameOrEmail);
return user;
}
public HttpContextBase HttpContext
{
get { return new HttpContextWrapper(System.Web.HttpContext.Current); }
}
}