没有 SetAuthCookie() 的自定义 MVC 身份验证
Custom MVC Authentication without SetAuthCookie()
由于我的项目要求,我想为我的 MVC 控制器操作提供自定义身份验证。因此,我不会使用 SetAuthCookie()。
最初我设置了一个cookie如下;
string userData = EncDec.MakeString(user.Email + "|" + user.UserId);
//the Cookie and FormsAuthenticationTicket expiration date/time is the same
DateTime cookieExpiry = DateTime.Now.AddMinutes(AccountPage.MvcApplication.COOKIE_EXPIRY_MINUTES);
FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(
1, // ticket version
user.UserName, // authenticated username
DateTime.Now, // issueDate
cookieExpiry, // expiryDate
false, // true to persist across browser sessions
userData, // can be used to store additional user data
FormsAuthentication.FormsCookiePath); // the path for the cookie
string encryptedTicket = FormsAuthentication.Encrypt(ticket);
//create the cookie
HttpCookie cookie = new HttpCookie("ADV_" + Extensions.ControllerExtensionMethods.GetGuid(this), encryptedTicket);
cookie.Secure = true;
cookie.HttpOnly = true;
cookie.Expires = cookieExpiry;
Response.Cookies.Add(cookie);
HttpCookie 与加密的 FormsAuthenticationTicket 一起保存在客户端浏览器中。
然后在我的控制器操作中,每当我需要检查并验证用户是否已通过身份验证时,我都会调用此方法;
public static FormsAuthenticationTicket IsAuthenticated(string guid)
{
HttpCookie cookie = HttpContext.Current.Request.Cookies["ADV_" + guid];
if (cookie != null)
{
string encryptedTicket = cookie.Value;
FormsAuthenticationTicket ticket = FormsAuthentication.Decrypt(encryptedTicket);
if (!ticket.Expired)
{
//if the user is authenticated and the cookie hasn't expired we increase the expiry of the cookie - keep alive
DateTime cookieExpiry = DateTime.Now.AddMinutes(AccountPage.MvcApplication.COOKIE_EXPIRY_MINUTES);
//create a new ticket based on the existing one
FormsAuthenticationTicket newTicket = new FormsAuthenticationTicket(
ticket.Version, // ticket version
ticket.Name, // authenticated username
ticket.IssueDate, // issueDate
cookieExpiry, // expiryDate, changed to keep alive if user is navigating around site
false, // true to persist across browser sessions
ticket.UserData, // can be used to store additional user data
ticket.CookiePath); // the path for the cookie
string newEncryptedTicket = FormsAuthentication.Encrypt(newTicket);
//keep alive
HttpCookie newCookie = new HttpCookie("ADV_" + guid, newEncryptedTicket);
newCookie.Secure = true;
newCookie.HttpOnly = true;
newCookie.Expires = cookieExpiry;
HttpContext.Current.Response.Cookies.Set(newCookie);
return newTicket;
}
}
return null;
}
每次重新验证用户时,我都会增加 cookie 过期的时间,以便登录保持活动状态。
一切似乎都正常,并且用户已正确通过身份验证,如果他们未通过身份验证,我会将他们重定向到登录页面,如果他们也未通过身份验证,他们将无法访问方法。
我的问题是:
- 这种处理身份验证的方式安全吗?
- 在安全风险方面,有什么我应该注意的吗?
谢谢。
您基本上需要查看创建自定义身份验证属性。
我不打算在这里提供实际的实现,但这会让你走上正确的道路。
这是基本表示:-
public class GoogleAuthAttribute : FilterAttribute, IAuthenticationFilter
{
public void OnAuthentication(AuthenticationContext filterContext)
{
IIdentity ident = filterContext.Principal.Identity;
if (!ident.IsAuthenticated || !ident.Name.EndsWith("@google.com"))
{
filterContext.Result = new HttpUnauthorizedResult();
}
}
public void OnAuthenticationChallenge(AuthenticationChallengeContext filterContext)
{
if (filterContext.Result == null || filterContext.Result is HttpUnauthorizedResult)
{
filterContext.Result =
new RedirectToRouteResult(new RouteValueDictionary
{
{"controller", "GoogleAccount"},
{"action", "Login"},
{"returnUrl", filterContext.HttpContext.Request.RawUrl}
});
}
}
}
我是从我目前正在阅读的关于 MVC5 的 Apress 书中摘录的。如果 OnAuthentification 失败,您设置 AuthenticationContext 的结果 属性,然后将其传递给 AuthenticationChallengeContext,您可以在其中添加您的质询代码。
在我的示例中,用户被重定向到登录页面。
您需要做的就是将此 AuthentificationAttribute 放在您需要的操作方法上。
您应该能够在其中构建或使用您的客户安全代码。
您真的应该问问自己,添加自定义安全措施是否是个好主意,因为它可能会导致您想要的更多问题。
由于我的项目要求,我想为我的 MVC 控制器操作提供自定义身份验证。因此,我不会使用 SetAuthCookie()。
最初我设置了一个cookie如下;
string userData = EncDec.MakeString(user.Email + "|" + user.UserId);
//the Cookie and FormsAuthenticationTicket expiration date/time is the same
DateTime cookieExpiry = DateTime.Now.AddMinutes(AccountPage.MvcApplication.COOKIE_EXPIRY_MINUTES);
FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(
1, // ticket version
user.UserName, // authenticated username
DateTime.Now, // issueDate
cookieExpiry, // expiryDate
false, // true to persist across browser sessions
userData, // can be used to store additional user data
FormsAuthentication.FormsCookiePath); // the path for the cookie
string encryptedTicket = FormsAuthentication.Encrypt(ticket);
//create the cookie
HttpCookie cookie = new HttpCookie("ADV_" + Extensions.ControllerExtensionMethods.GetGuid(this), encryptedTicket);
cookie.Secure = true;
cookie.HttpOnly = true;
cookie.Expires = cookieExpiry;
Response.Cookies.Add(cookie);
HttpCookie 与加密的 FormsAuthenticationTicket 一起保存在客户端浏览器中。
然后在我的控制器操作中,每当我需要检查并验证用户是否已通过身份验证时,我都会调用此方法;
public static FormsAuthenticationTicket IsAuthenticated(string guid)
{
HttpCookie cookie = HttpContext.Current.Request.Cookies["ADV_" + guid];
if (cookie != null)
{
string encryptedTicket = cookie.Value;
FormsAuthenticationTicket ticket = FormsAuthentication.Decrypt(encryptedTicket);
if (!ticket.Expired)
{
//if the user is authenticated and the cookie hasn't expired we increase the expiry of the cookie - keep alive
DateTime cookieExpiry = DateTime.Now.AddMinutes(AccountPage.MvcApplication.COOKIE_EXPIRY_MINUTES);
//create a new ticket based on the existing one
FormsAuthenticationTicket newTicket = new FormsAuthenticationTicket(
ticket.Version, // ticket version
ticket.Name, // authenticated username
ticket.IssueDate, // issueDate
cookieExpiry, // expiryDate, changed to keep alive if user is navigating around site
false, // true to persist across browser sessions
ticket.UserData, // can be used to store additional user data
ticket.CookiePath); // the path for the cookie
string newEncryptedTicket = FormsAuthentication.Encrypt(newTicket);
//keep alive
HttpCookie newCookie = new HttpCookie("ADV_" + guid, newEncryptedTicket);
newCookie.Secure = true;
newCookie.HttpOnly = true;
newCookie.Expires = cookieExpiry;
HttpContext.Current.Response.Cookies.Set(newCookie);
return newTicket;
}
}
return null;
}
每次重新验证用户时,我都会增加 cookie 过期的时间,以便登录保持活动状态。
一切似乎都正常,并且用户已正确通过身份验证,如果他们未通过身份验证,我会将他们重定向到登录页面,如果他们也未通过身份验证,他们将无法访问方法。
我的问题是:
- 这种处理身份验证的方式安全吗?
- 在安全风险方面,有什么我应该注意的吗?
谢谢。
您基本上需要查看创建自定义身份验证属性。
我不打算在这里提供实际的实现,但这会让你走上正确的道路。
这是基本表示:-
public class GoogleAuthAttribute : FilterAttribute, IAuthenticationFilter
{
public void OnAuthentication(AuthenticationContext filterContext)
{
IIdentity ident = filterContext.Principal.Identity;
if (!ident.IsAuthenticated || !ident.Name.EndsWith("@google.com"))
{
filterContext.Result = new HttpUnauthorizedResult();
}
}
public void OnAuthenticationChallenge(AuthenticationChallengeContext filterContext)
{
if (filterContext.Result == null || filterContext.Result is HttpUnauthorizedResult)
{
filterContext.Result =
new RedirectToRouteResult(new RouteValueDictionary
{
{"controller", "GoogleAccount"},
{"action", "Login"},
{"returnUrl", filterContext.HttpContext.Request.RawUrl}
});
}
}
}
我是从我目前正在阅读的关于 MVC5 的 Apress 书中摘录的。如果 OnAuthentification 失败,您设置 AuthenticationContext 的结果 属性,然后将其传递给 AuthenticationChallengeContext,您可以在其中添加您的质询代码。
在我的示例中,用户被重定向到登录页面。
您需要做的就是将此 AuthentificationAttribute 放在您需要的操作方法上。
您应该能够在其中构建或使用您的客户安全代码。
您真的应该问问自己,添加自定义安全措施是否是个好主意,因为它可能会导致您想要的更多问题。