LAN HTTP "Authorization: Basic" not working

I have tried for a couple hours to get Basic Authorization to work. I'm using a device handler of mine that I have ported to a Hubitat driver. I create the request with something like this:

private getAction(uri){ 
  def userpass
  
  if(password != null && password != "") 
    userpass = encodeCredentials("admin", password)
    
  def headers = getHeader(userpass)

  def hubAction = new hubitat.device.HubAction(
    method: "GET",
    path: uri,
    headers: headers,
    body: "\r\n\r\n"
  )
  return hubAction    
}
private encodeCredentials(username, password){
	def userpassascii = "${username}:${password}"
    def userpass = "Basic " + userpassascii.bytes.encodeBase64().toString()
    return userpass
}

private getHeader(userpass = null){
    def headers = [:]
    headers.put("Host", getHostAddress())
    headers.put("Content-Type", "application/x-www-form-urlencoded")
    if (userpass != null)
       headers.put("Authorization", userpass)
    return headers
}

You can see that when the headers are created, it is adding "Authorization:Basic encoded-username-password" to the request. If I remove the authorization, then the request goes through fine (if I disable the password on the receiving device). I've inspected the headers, uri, etc. by logging the variables and the request looks good. Using SmartThings or the curl command also works.

If someone could help me out, that would be great!

As strange as this might sound, try making sure "AUTHORIZATION" is in all caps along with all your other header values.

I have similar code working at that seems to be the only difference I can see. Let me know if that works.

Thanks for the tip, but I still couldn't get it to work. I can mess around with a little more later, but interestingly this is working:

private getAction(uri){ 
  updateDNI()
  def userpass
  def response
  if(password != null && password != "") 
      userpass = encodeCredentials("admin", password)
    
  def headers = getHeader(userpass)
    
  def params = [
    uri: "http://${getHostAddress()}${uri}",
    headers: headers
  ]

  httpGet(params) { resp ->
    response = resp.data
  }

  return response    
}

The other methods are the exact same. Maybe you know why one way would work and the other wouldn't? At least I have a workaround. I did some packet sniffing to try and find the difference between the two requests:

Doesn't work

GET /on HTTP/1.1
Accept: */*
User-Agent: Linux UPnP/1.0 Hubitat
Host: 10.37.21.22
Content-Type: application/x-www-form-urlencoded
Authorization: Basic xxxxxxxxxxxxxxxxxxxx
Content-Length: 4

Works

GET /on HTTP/1.1
Accept: */*
Authorization: Basic xxxxxxxxxxxxxxxxxxxx
Host: 10.37.21.22:80
Content-Type: application/x-www-form-urlencoded
Connection: Keep-Alive
Accept-Encoding: gzip,deflate

I then tried to build the headers in the non-working request the same as the working version, but it didn't make a difference. Wish I could figure it out, but since I have something that works I'll probably call it day. :slight_smile:

I ran into this exact thing as well I think. I have posted about it in a few places but lack any real technical experience to know what is going on.

Basically my rpi would reject a command using hubaction but a seemingly identical get command worked.

LOL at least I think we are both talking about the same thing. The logs on my pi showed the requests did not look quite identical. Like you requests work from nearly everywhere else. Just not the hubaction.

There is the original post - again I don't really know if it related - seems similar to me.