Reputation: 3865
What are your approaches to give clients the possibility to test a mvc website/application before going live?
I have an asp.net mvc 4 web application. A beta.mydomain.com and a public.mydomain.com - On the beta, only someone with user/password should have access. But the Forms Authentication should still work.
My current best solution is:
->> The problem is that the user is actually Logged In (means User.IsAuthenticated returns true) - But the App internally uses Forms Authentication. Can both be combined?
I've found some similar questions but no real solution to this:
https://serverfault.com/questions/175643/how-do-i-secure-a-net-mvc-website-prior-to-launch
Password protect a directory in IIS 7 (.Net MVC 2)
IIS Password prompt for given folder ASP.NET MVC
Password protect ASP.NET web application in IIS 7.5
I've read a lot on this topic and cannot believe this is not possible. What is your approach when deploying an alpha/beta for a client to test it before it goes live?
Upvotes: 3
Views: 1544
Reputation: 47164
If you just want to make sure your website is accessible for a limited audience (e.g. test users) the easiest would be to add a Basic or Digest authentication on top of your existing authentication.
Implement it as an ActionFilterAttribute
and add it to your global filter collection if your deployment scenario (production vs. staging etc.) calls for protection:
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
bool basicAuthenticationEnabled = true; // AppSettings etc.
if (basicAuthenticationEnabled)
filters.Add(new BasicAuthenticationAttribute());
filters.Add(new HandleErrorAttribute())
}
An implementation of the corresponding BasicAuthenticationAttribute
class could look this:
public class BasicAuthenticationAttribute : ActionFilterAttribute
{
private const string Realm = "MyRealm";
private const string UserName = "MyUserName";
private const string Password = "MyPassword";
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
var authorizationHeader = filterContext.RequestContext.HttpContext.Request.Headers["Authorization"];
if (authorizationHeader != null && authorizationHeader.StartsWith("Basic"))
{
var credentials = Encoding.ASCII.GetString(
Convert.FromBase64String(authorizationHeader.Substring(6))
).Split(':');
if (credentials[0].Equals(UserName) && credentials[1].Equals(Password))
{
base.OnActionExecuting(filterContext);
return;
}
}
// send require authentication
var response = filterContext.HttpContext.Response;
response .StatusCode = 401;
response .AddHeader("WWW-Authenticate", String.Format("Basic realm=\"{0}\"", Realm));
response .End();
}
}
Anyhow, I highly recommend using the Digest authentication because it applies a hash function to a password before sending it over the network, which is - at least a little bit - safer than basic access authentication, which sends plaintext.
You can find an implememtation for a DigestAuthorizationAttribute
class and more information here:
Upvotes: 3