Published on InterSystems Developer Community (https://community.intersystems.com)

Home > Consuming a REST Sevice with Digest Authenctication

Question
Cristiano Silva · Jun 9, 2020

Consuming a REST Sevice with Digest Authenctication

Hi guys,

I'm trying to consume a REST Service that use Digest authentication, I'm trying to implement the authentication but I'm don't know where is my mistake.

Someone have already used this type of authentication.

Below the code I wrote to try to generate the response hash:

 // Algorithm reference: https://en.wikipedia.org/wiki/Digest_access_authentication
 //
 // Test data:
 // Do TestDigest^HC.Debug("posstman", "password", "/digest-auth", "postman-echo.com", 80)
 // Do TestDigest^HC.Debug("usr", "pwd", "/digest-auth/auth/usuario/senha/MD5", "httpbin.org", 80)
TestDigest(username, password, url, server, port) Public
{
Set httpRequest = ##Class(%Net.HttpRequest).%New()
Set httpRequest.Server = server
Set httpRequest.Port = port
Set statusCode = httpRequest.Send("GET", url)
If ($System.Status.IsError(statusCode))
{
Do $System.Status.DisplayError(statusCode)
}
Set authenticationData = httpRequest.HttpResponse.GetHeader("WWW-AUTHENTICATE")
Write !, "WWW-AUTHENTICATE: ", authenticationData, !
Set qop  = $$GetHeaderVar(authenticationData, "qop")
Set nonce = $$GetHeaderVar(authenticationData, "nonce")
Set realm = $$GetHeaderVar(authenticationData, "realm")
Set algorithm = $$GetHeaderVar(authenticationData, "algorithm")
Set nc = "00000001"
Set cnonce = $$HashValue($Horolog, 1)
Set hA1 = $$HashValue(username _ ":" _ realm _ ":" _ password)
If ($ZConvert(algorithm, "U") = "MD5-SESS")
{
Set hA1 = $$HashValue(hA1 _ ":" _ nonce _ ":" _ cnonce)
}
Set hA2 = $$HashValue("GET:" _ url)
If (qop '= "")
{
Set response = $$HashValue(hA1 _ ":" _ nonce _ ":" _ nc _ ":" _ cnonce _ ":" _ qop _ ":" _ hA2)
}
Else
{
Set response = $$HashValue(hA1 _ ":" _ nonce _ ":" _ hA2)
}
Set digestResponse = "Digest username=""*"",realm=""*"",nonce=""*"",uri=""*"",response=""*"",algorithm=""*"",qop=*,nc=*,cnonce=""*"""
Set digestResponse = $Replace(digestResponse, "*", username, 1, 1)
Set digestResponse = $Replace(digestResponse, "*", realm, 1, 1)
Set digestResponse = $Replace(digestResponse, "*", nonce, 1, 1)
Set digestResponse = $Replace(digestResponse, "*", url, 1, 1)
Set digestResponse = $Replace(digestResponse, "*", response, 1, 1)
Set digestResponse = $Replace(digestResponse, "*", algorithm, 1, 1)
Set digestResponse = $Replace(digestResponse, "*", qop, 1, 1)
Set digestResponse = $Replace(digestResponse, "*", nc, 1, 1)
Set digestResponse = $Replace(digestResponse, "*", cnonce, 1, 1)
//
Write !,"Authorization: ", digestResponse, !, !
//
Do httpRequest.SetHeader("Authorization", digestResponse)
//
Set statusCode = httpRequest.Send("GET", url)
If ($System.Status.IsError(statusCode))
{
Do $System.Status.DisplayError(statusCode)
}
Do httpRequest.HttpResponse.OutputToDevice()
}
HashValue(value) Public
{
Return $ZConvert(##Class(%xsd.hexBinary).LogicalToXSD($System.Encryption.MD5Hash(value)), "L")
}
GetHeaderVar(header, varName) Public 
{
    Set listVars = $ListFromString(header, ",")
    For index = 1 : 1 : $ListLength(listVars)
    {
    Set value = $List(listVars, index)
    If ($ZConvert(value, "U") [ $ZConvert(varName, "U"))
    {
    Return $Translate($Piece(value, "=", 2), """", "")
    }
    }
    Return ""
}
#Authentication #REST API #Caché #Ensemble #InterSystems IRIS

Source URL:https://community.intersystems.com/post/consuming-rest-sevice-digest-authenctication