I've been reading a ton of stuff online about authentication and authorization and finally settled on some code that seems to be working...but I don't fully understand everything that it's doing (as far as the FormsAuthenticationTicket).
The MVC app I'm working with will be handling some sensitive data and I want to triple check everything I do that is related to authentication and authorization.
I am using Windows auth;
<authentication mode="Windows" />
<authorization>
<deny users="?"/>
</authorization>
I have a set of tables in SQL Server with additional User and Permission information.
In my Global.asax I have the following methods inspired from
http://www.codeproject.com/Articles/5182/Insight-into-Security-Model-using-Principal-and-Id
protected void WindowsAuthentication_OnAuthenticate(object sender, WindowsAuthenticationEventArgs e)
{
if (e.Identity == null || !e.Identity.IsAuthenticated)
{
//Redirect to error or access denied page
}
string userData = e.Identity.AuthenticationType;
var cachedUser = HttpContext.Current.Cache[e.Identity.Name] as User;
if (cachedUser == null)
{
var user = repo.GetUserByFullUserName(e.Identity.Name);
HttpContext.Current.Cache.Insert(e.Identity.Name, user, null, DateTime.Now.AddMinutes(2), Cache.NoSlidingExpiration);
cachedUser = HttpContext.Current.Cache[e.Identity.Name] as User;
}
var userIdentity = e.Identity.Name;
var formsAuthTicket = new FormsAuthenticationTicket(1, e.Identity.Name, DateTime.Now, DateTime.Now.AddMinutes(2), false, userData);
var encryptedTicket = FormsAuthentication.Encrypt(formsAuthTicket);
var httpcook = new HttpCookie("authCookie", encryptedTicket);
Response.Cookies.Add(httpcook);
}
protected void Application_AuthenticateRequest(object sender, EventArgs e)
{
if (Request.IsAuthenticated)
{
var httpcook = Context.Request.Cookies["authCookie"];
var formsAuthTicket = FormsAuthentication.Decrypt(httpcook.Value);
var cachedUser = GetCachedUser(formsAuthTicket.Name);
if (cachedUser == null)
{
cachedUser = CreateCachedUser(formsAuthTicket.Name);
}
var genIdentity = new GenericCustomIdentity(cachedUser, Request.IsAuthenticated, formsAuthTicket.UserData);
var genPrincipal = new GenericCustomPrincipal(genIdentity, cachedUser);
HttpContext.Current.User = genPrincipal;
}
}
So here are my questions:
Why have a FormsAuthenticationTicket in the WindowsAuthentication_OnAuthenticate method? Can't I just build my Identity and Principal objects in the WinAuth method?
Is storing User data in HttpContext.Current.Cache a security risk? Since these methods are called numerous times I don't want to hit the db every single request. Is there a better/more secure alternative?
I am unfamiliar with using FormsAuthenticationTickets, Identity, and Principal so any comments or suggestions would be greatly appreciated. Sorry, this wasn't a question.
Difference between Basic Authentication and Windows authentication. Windows authentication authenticates the user by validating the credentials against the user account in a Windows domain. Basic authentication verifies the credentials that are provided in a form against the user account that is stored in a database.
The FormsAuthenticationTicket class is used to create an object that represents the authentication ticket that is used by forms authentication to identify an authenticated user.
Enabling Windows Authentication First, while developing an MVC application, you use the ASP.NET Development Web Server included with Visual Studio. By default, the ASP.NET Development Web Server executes all pages in the context of the current Windows account (whatever account you used to log into Windows).
No. You can use Windows Authentication even if your server is not a member of an Active Directory domain.
Why have a FormsAuthenticationTicket in the WindowsAuthentication_OnAuthenticate method? Can't I just build my Identity and Principal objects in the WinAuth method?
The Identity and Principal objects only exist during the current call/request from the client. They are part of the HttpContext and are, for lack of a better term, disposed of at the end of the request. Once the person who was authenticated connects again, there is a new request created, and by default they are not authenitcated.
The FormsAuthenticationTicket (By Default) uses a cookie on the client side to store authentication information for each subsequent request. This allows the Application_AuthenticateRequest
method to use the cookie to reauthorize the request.
Is storing User data in HttpContext.Current.Cache a security risk? Since these methods are called numerous times I don't want to hit the db every single request. Is there a better/more secure alternative?
The HttpContext.Cache is stored in memory. If the server resets or the app pool restarts for any reason the cache is gone.
Yes it's a security risk, you're storing user information is server memory. The risk however is very small, unless someone had your code to see how you were using the cache, and could upload code to read the cache.
I am unfamiliar with using FormsAuthenticationTickets, Identity, and Principal so any comments or suggestions would be greatly appreciated. Sorry, this wasn't a question.
How about links to HttpContext.User (IPrincipal) with it's property Identity of type IIdentity. Not the most descriptive answer, but both interfaces are extremely basic.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With