Add basic authentication to WCF service hosted in Azure

You can add basic authentication to your WCF service by adding a so-called HTTP module to the project with your service contract. The Http module intercepts the web service calls before they reach the actual service. The code of code file UserNameAuthenticator.cs is added at the bottom of the post. The only thing you will have to do next, is add the http module to the web.config:

<configuration>

<system.webServer>
<modules>
<add name=”BasicAuthenticationModule” type=”DSPGateway.ServiceContract.UserNameAuthenticator” />
</modules>
</system.webServer>

Code file:

using System;
using System.Collections.Generic;
using System.Text;
using System.Web;
using System.Web.Security;
using System.Security.Principal;

namespace DSPGateway.ServiceContract
{
class UserNameAuthenticator : IHttpModule
{
public UserNameAuthenticator()
{
}
public void Init(HttpApplication application)
{
application.AuthenticateRequest += new EventHandler(this.OnAuthenticateRequest);
application.EndRequest += new EventHandler(this.OnEndRequest);
}
public void OnAuthenticateRequest(object source, EventArgs eventArgs)
{
HttpApplication app = (HttpApplication)source;
//the Authorization header is checked if present
string authHeader = app.Request.Headers[“Authorization”];
if (!string.IsNullOrEmpty(authHeader))
{
string authStr = app.Request.Headers[“Authorization”];
if (authStr == null || authStr.Length == 0)
{
// No credentials; anonymous request
return;
}
authStr = authStr.Trim();
if (authStr.IndexOf(“Basic”, 0) != 0)
{
// header is not correct…we’ll pass it along and
// assume someone else will handle it
return;
}
authStr = authStr.Trim();
string encodedCredentials = authStr.Substring(6);
byte[] decodedBytes =
Convert.FromBase64String(encodedCredentials);
string s = new ASCIIEncoding().GetString(decodedBytes);
string[] userPass = s.Split(new char[] { ‘:’ });
string username = userPass[0];
string password = userPass[1];
if (username == “user” && password == “password“)
{
app.Context.User = new GenericPrincipal(new GenericIdentity(username, “DSP”), null);
}
else
{
DenyAccess(app);
return;
}
}
else
{
app.Response.StatusCode = 401;
app.Response.End();
}
}
public void OnEndRequest(object source, EventArgs eventArgs)
{
//the authorization header is not present
//the status of response is set to 401 and it ended
//the end request will check if it is 401 and add
//the authentication header so the client knows
//it needs to send credentials to authenticate
if (HttpContext.Current.Response.StatusCode == 401)
{
HttpContext context = HttpContext.Current;
context.Response.StatusCode = 401;
context.Response.AddHeader(“WWW-Authenticate”, “Basic Realm”);
}
}
private void DenyAccess(HttpApplication app)
{
app.Response.StatusCode = 401;
app.Response.StatusDescription = “Access Denied”;

// Write to response stream as well, to give user visual
// indication of error during development
app.Response.Write(“401 Access Denied – invalid acccount”);
app.CompleteRequest();
}
public void Dispose()
{
}
}
}

Leave a Reply

Your email address will not be published. Required fields are marked *