Reputation: 5362
Because of the requirements of my project, I'm wanting to provide custom authenticate for my MVC controller actions. Therefore, I will not be using SetAuthCookie().
Intially I set a cookie as follows;
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);
The HttpCookie is being saved in the client browser with a encrypted FormsAuthenticationTicket.
Then within my controller actions, whenever I need to check and verify that the user is authenticated I call this method;
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;
}
Every time the user is re-authenticated, I am increasing the time out of when the cookie will expire, so that the login is keep alive.
Everything seems to work fine, and the users are correctly authenticated, and if they aren't authenticated I redirect them to a login page, and they can't access methods if they aren't authenticated either.
My questions are:
Thanks.
Upvotes: 0
Views: 1674
Reputation: 8640
You basically need to look at creating a Custom Authentication Attribute.
I'm not going to provide the actual implementation here, but this will put you on the right path.
Here's the basic representation :-
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}
});
}
}
}
I've took this from the Apress Book i'm currently reading on MVC5. If OnAuthentification fails, you set the Result property of the AuthenticationContext, this is then passed to the AuthenticationChallengeContext, where you can add your challenge code.
In my example, the user is redirected to the login page.
All you need t do, is place this AuthentificationAttribute on the Action Methods you require.
You should be able to build in or work your custome security code in to this.
You should really ask yourself if its a good idea to be adding custom security measures, as it can lead to more problems that you want.
Upvotes: 1