Deploy ASP.NET MVC Site on IIS6 – Windows Server 2003

I built a new ASP.NET MVC 4 (.NET 4) web application, but client wanted it to be hosted on their older Windows Server 2003 running IIS 6. While hosting I got 403 error because IIS6 comes with .Net framework 2.0.

I have figured out what we need to do inorder to host the mvc site on IIS6. We do need all the appropriate MVC assemblies in the application bin folder, otherwise we will have to install mvc on server. But the server must have .net Framework 4.0.

Steps :

1. Install the .NET 4 Framework.

2. Make sure ASP.NET v4.0.30319 is ?Allowed? under Web Service Extensions in IIS ? it is ?Prohibited? by default.

3. IIS Website Configuration: Right click on your new website and select ?Properties?:

a. Under the ?Home Directory? tab, make sure that ?Execute permissions? is set to ?Scripts only? .
b. Under the ?ASP.NET? tab, make sure that the ASP.NET version is set to ?4.0.30319?.
c. Click on the ?Configuration? button in the ?Home Directory? tab and make sure that all the Application extensions are mapped to .NET 4 versions of the dlls.
d. Add a ?Wildcard application mapping? ? click on ?Insert? and enter ?C:\WINDOWS\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll? as the ?Executable?. Leave ?Verify that file exists? unchecked.

Basic Authentication in ASP.Net MVC Web API

ASP.NET Web API is a great tool to create lightweight, HTTP services that reach a broad range of clients, including all browsers and mobile platforms.

In most of scenarios we need authentication to restrict services . There are two ways to restrict it

– Forms authentication
– Windows authentication

Forms authentication is a mechanism that works well in interactive web applications, but Windows authentication is not widely used. Now days services are invoked from the browser using jquery or javascripts for mobile platforms because application are widely used on mobile devices.

HTTP authentication is part of the standard protocol and can be easily handled by client and mobile platforms. To implement Basic authentication in ASP.NET Web API by extending AuthorizeAttribute. But its sometimes not working well, Another a custom message handler by deriving from DelegateHandler class.

Below is the code sample which is deriving from DelegateHandler class and working well.

Code Block:

public class BasicAuthMessageHandler : DelegatingHandler
{
private const string BasicAuthResponseHeader = "WWW-Authenticate";
private const string BasicAuthResponseHeaderValue = "Basic";

public IProvidePrincipal PrincipalProvider = new DummyPrincipalProvider();

public BasicAuthMessageHandler(HttpConfiguration httpConfiguration)
{
InnerHandler = new HttpControllerDispatcher(httpConfiguration);
}

protected override System.Threading.Tasks.Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
AuthenticationHeaderValue authValue = request.Headers.Authorization;
if (authValue != null && !String.IsNullOrWhiteSpace(authValue.Parameter))
{
Credentials parsedCredentials = ParseAuthorizationHeader(authValue.Parameter);
if (parsedCredentials != null)
{
IPrincipal myPrincipal = PrincipalProvider.CreatePrincipal(parsedCredentials.Username, parsedCredentials.Password);
Thread.CurrentPrincipal = myPrincipal;
HttpContext.Current.User = myPrincipal;
}
}
return base.SendAsync(request, cancellationToken)
.ContinueWith(task =>
{
var response = task.Result;
if (response.StatusCode == HttpStatusCode.Unauthorized
&& !response.Headers.Contains(BasicAuthResponseHeader))
{
response.Headers.Add(BasicAuthResponseHeader
, BasicAuthResponseHeaderValue);
}

if (response.StatusCode == HttpStatusCode.Unauthorized)
{
var content = new StringContent("Invalid Credentials");
response.Content = content;
response.StatusCode = System.Net.HttpStatusCode.Unauthorized;
}
return response;
});
}

private Credentials ParseAuthorizationHeader(string authHeader)
{
string[] credentials = Encoding.ASCII.GetString(Convert
.FromBase64String(authHeader))
.Split(
new[] { ':' });
if (credentials.Length != 2 || string.IsNullOrEmpty(credentials[0])
|| string.IsNullOrEmpty(credentials[1])) return null;
return new Credentials()
{
Username = credentials[0],
Password = credentials[1],
};
}
}

public interface IProvidePrincipal
{
IPrincipal CreatePrincipal(string username, string password);
}

public class Credentials
{
public string Username { get; set; }
public string Password { get; set; }
}

public class DummyPrincipalProvider : IProvidePrincipal
{
public IPrincipal CreatePrincipal(string username, string password)
{
//check user using any membership provider Websecurity/Membership
if (!WebSecurity.Login(username, password, persistCookie: false))
{
return null;
}
var identity = new GenericIdentity(username);
IPrincipal principal = new GenericPrincipal(identity, Roles.GetRolesForUser(username));
return principal;
}
}

WebApiConfig:

config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{action}/{id}",
defaults: new { id = RouteParameter.Optional },
constraints: null,
handler: new BasicAuthMessageHandler(GlobalConfiguration.Configuration)

Controller:

[Authorize]
public class ValuesController : ApiController
{
// GET api/values
public IEnumerable<string> Get()
{
return new string[] { "first", "second" };
}
}

Client:

using (HttpClient client = new HttpClient())
{
client.BaseAddress = new Uri("http://example.com");
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Authorization", Convert.ToBase64String(Encoding.ASCII.GetBytes(String.Format("{0}:{1}", userName, password))));
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
var Response =await client.GetAsync("api/accounts/validateuser");
}