musium
musium

Reputation: 3072

WCF authentication from html/javascript client

I’m working on a jQuery mobiel app. I’ve a RESTful WCF service which provides some JSON data, which the jqm app consumes.

Now I need to implement an authentication for the service.

Currently it looks something like this:

Diagram.

Upvotes: 0

Views: 652

Answers (1)

Daniel Blankensteiner
Daniel Blankensteiner

Reputation: 76

If you are hosting your service in IIS and you want a custom username/password-validator, you could solve the problem by implementing a HttpModule that will implement Basic-authentication.

public class AuthenticationModule : IHttpModule
{
    void IHttpModule.Dispose() {}

    void IHttpModule.Init(HttpApplication context)
    {
        context.AuthenticateRequest += ContextOnAuthenticateRequest;
        context.EndRequest += ContextOnEndRequest;
    }

    private void ContextOnEndRequest(object sender, EventArgs eventArgs)
    {
        HttpContext context = HttpContext.Current;

        if(context.Response.StatusCode != 401)
            return;

        context.Response.AddHeader("WWW-Authenticate", "Basic realm=\"SomeRealm\"");
    }

    private void ContextOnAuthenticateRequest(object sender, EventArgs eventArgs)
    {
        HttpContext context = HttpContext.Current;
        string authHeader = context.Request.Headers["Authorization"];
        if(string.IsNullOrWhiteSpace(authHeader) || !authHeader.StartsWith("Basic "))
            DenyAccess();

        try
        {
            var encoded = authHeader.Substring(6);
            var decoded = Encoding.UTF8.GetString(Convert.FromBase64String(encoded));
            var splits = decoded.Split(':');
            var username = splits[0];
            var password = splits[1];

            var principal = //TODO Validate and return a class implementing System.Security.Principal.IPrincipal
            if (principal != null)
                context.User = principal;
            else
                DenyAccess();
        }
        catch(Exception e)
        {
            DenyAccess();
        }
    }

    private void DenyAccess()
    {
        var context = HttpContext.Current;
        context.Response.StatusCode = 401;
        context.Response.End();
    }
}

In your operation you can get the user by writing: ServiceSecurityContext.Current.PrimaryIdentity And also remember to set aspNetCompatibilityEnabled to true.

From your js-client, just include this in the header: Authorization: Basic Base64EncodedStringWithUsername:Password

Best regards db

Upvotes: 1

Related Questions