没有SetAuthCookie()的自定义MVC身份验证

时间:2015-02-25 21:14:19

标签: c# asp.net-mvc cookies asp.net-mvc-5 forms-authentication

由于我的项目的要求,我想为我的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过期的时间,以便登录保持活动状态。

一切似乎都运行良好,并且用户经过了正确的身份验证,如果他们未经过身份验证,我会将其重定向到登录页面,如果他们未经过身份验证,他们就无法访问这些方法任

我的问题是:

  1. 这种处理身份验证的方式是否安全。
  2. 就安全风险而言,我应该注意什么。
  3. 感谢。

1 个答案:

答案 0 :(得分:1)

您基本上需要查看创建自定义身份验证属性。

我不会在这里提供实际的实现,但这会让你走上正确的道路。

以下是基本表示: -

 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}
                    });
            }

        }
    }

我从Apress Book中拿到了这个,我正在阅读MVC5。如果OnAuthentification失败,则设置AuthenticationContext的Result属性,然后将其传递给AuthenticationChallengeContext,您可以在其中添加质询代码。

在我的示例中,用户被重定向到登录页面。

您需要做的就是将此AuthentificationAttribute放在您需要的操作方法上。

您应该能够在此处构建或使用您的客户安全代码。

您应该问自己,添加自定义安全措施是否是一个好主意,因为它可能会导致您想要的更多问题。