$http digest authentication with credentials via DNN web api


#1

I am trying to authenticate $http requests against our ASP.Net DotNetNuke (DNN) web api methods using an Ionic/Angular mobile app. I have spent a few days on this with little success and a deadline looming. I can access and receive web api data via [AllowAnonymous] methods, such as the following C# method:

    [HttpGet]
    [AllowAnonymous]
    public HttpResponseMessage HelloWorld(string testData)
    {
        return Request.CreateResponse(HttpStatusCode.OK, "Hello World: " + testData);
    }

…called using the following JS (not currently using promises but it will after I figure out the authentication piece):

loginService.helloWorld = function (data) {
    $http({
        method: 'GET',
        url: 'https://myworkdomain.com/DesktopModules/AcmeService/API/CoreService/HelloWorld',
        headers: {
            'Content-Type': 'application/json'
        },
        params: {
            testData: data
        }
    }).
    then(function (response) {
        console.log("success:", response)
    }, function (response) {
        console.log("error:", response)
    });
}

The problem comes when trying to access a secure web api method requiring user credentials, such as the following test method:

    [DnnAuthorize]
    [HttpGet]
    [HttpOptions]
    public HttpResponseMessage HelloWorldSecure()
    {
        return Request.CreateResponse(HttpStatusCode.OK, "Hello from HelloWorldSecure()");
    }

…called using the following JS (I’ve tried many variations of this but haven’t yet found the correct one):

loginService.helloWorldSecure = function () {
    var req = {
        method: 'GET',
        url: 'https://myworkdomain.com/DesktopModules/AcmeService/API/CoreService/HelloWorldSecure',
        headers: {
            'Content-Type': 'application/json',
            'Authorization': 'Digest ' + btoa('myusername:mypassword')
        }
    }

    $http(req).
    then(function (response) {
        console.log("success:", response)
    }, function (response) {
        console.log("error:", response)
    });
}

I’ve placed the following in the ASP.Net (DNN) web.config file (I’ve seen it thrown about in my many Googling sessions):

< httpProtocol>
< customHeaders>
< add name=“Access-Control-Allow-Origin” value="*"/>
< add name=“Access-Control-Allow-Headers” value=“Origin, X-Requested-With, Content-Type, Accept”/>
< add name=“Access-Control-Allow-Methods” value=“GET, POST, PUT, DELETE, OPTIONS”/>
< /customHeaders>
< /httpProtocol>

Initially, I was encountering HTTP Status Code 405 (Method Not Allowed), but annotating the web api methods with [HttpOptions] overcame that issue (not sure it is the correct way but it worked). Now the returned HTTP Status Code is 401 (Unauthorized). The solution is likely fairly simple but it has eluded me for the past several days. Any help is greatly appreciated!

Thanks,
Troy

p.s. Returned headers via Chrome dev tools/Ionic Lab:

Request Headers:
Access-Control-Request-Headers:accept, authorizationAccess-Control-Request-Method:GETOrigin:http://localhost:8100Referer:http://localhost:8100/?ionicplatform=iosUser-Agent:Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) ionic-lab/1.0.0-beta.2 Chrome/43.0.2357.65 Electron/0.29.1 Safari/537.36

Response Headers:
Access-Control-Allow-Headers:Origin, X-Requested-With, Content-Type, AcceptAccess-Control-Allow-Methods:GET, POST, PUT, DELETE, OPTIONSAccess-Control-Allow-Origin:*Cache-Control:no-cacheContent-Length:61Content-Type:application/json; charset=utf-8Date:Mon, 28 Sep 2015 21:24:07 GMTExpires:-1Pragma:no-cacheServer:Microsoft-IIS/8.5WWW-Authenticate:Digest realm=“DNNAPI”, nonce=“OS8yOC8yMDE1IDQ6MjU6MDcgUE0”, opaque=“0000000000000000”, stale=False, algorithm=MD5, qop=“auth”, Basic realm="DNNAPI"X-AspNet-Version:4.0.30319X-Powered-By:ASP.NET

Response:
XMLHttpRequest cannot load https://myworkdomain.com/DesktopModules/AcmeService/API/Core/Login. Invalid HTTP status code 401