NetTalk Central

Author Topic: Implementing HTTP Authentication on a Server  (Read 5787 times)

Poul

  • Full Member
  • ***
  • Posts: 160
    • View Profile
Implementing HTTP Authentication on a Server
« on: January 16, 2017, 10:24:48 AM »
Hello, are there any examples,documentation,tips,webinars?

My main goal is to simplify REST access for a WebService, but i would also like to have it as the default for a webbrowser.
(I am returning XML by default to the Browser, but JSON for the Webclients who request it)

I see lots of plumbing bits for the Authentication/token etc, but nothing the puts it altogether

For example: in my webservice method i can set it to "user must be logged in"
Which does an immediate "401 Unauthorizd"
I suppose a Webclient would know to send the Credentials, but i believe i should be
putting something like "WWW-Authenticate: Basic" in the header.
is there a simple way to do that before the
 
Code: [Select]
If p_web.GetSessionLoggedIn() = 0
    p_web.SendError (401,'Unauthorized', 'A login is required to view this page')
    Return
end

my current assumption is that i have to handle things myself in the CheckForToken routine
but its unclear if that's the intention or best place.

poul

Bruce

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 11250
    • View Profile
Re: Implementing HTTP Authentication on a Server
« Reply #1 on: January 16, 2017, 10:13:39 PM »
Hi Poul,

So, on the server side, HTTP Authentication is completely handled for you. All you have to do is validate the user/password combination.

In WebHandler is a method, .Authenticate.
This has 2 parameters, user and password - you write the code here to "see if those are ok" just like you would in say LoginForm.
Remember to Open/Close any tables you need.
Return true for ok, and false for not ok.

BASIC Authentication will end up here.
You can also call this method from LoginForm (in place of the user test there) so consolidating your authentication code in one place.

Digest Authentication is less used these days. (Basic Authentication, when used over a TLS connection is better than Digest. Digest is better than Basic when used over non-TLS. But ideally password connections should always be over TLS).
For TLS authentication you need to populate the .GetPassword method instead.

>> I suppose a Webclient would know to send the Credentials,
>> i should be putting something like "WWW-Authenticate: Basic" in the header.

yes. I'll make that a switch you can set. That'll be in 9.18.

cheers
Bruce


« Last Edit: January 16, 2017, 11:10:25 PM by Bruce »

Poul

  • Full Member
  • ***
  • Posts: 160
    • View Profile
Re: Implementing HTTP Authentication on a Server
« Reply #2 on: January 17, 2017, 10:04:47 AM »
Thank you that helps.

Is there something I can do to make sure that the Webservice  401 response
is formatted appropriately ( JSON rather than HTML?)

poul

Bruce

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 11250
    • View Profile
Re: Implementing HTTP Authentication on a Server
« Reply #3 on: January 17, 2017, 09:47:24 PM »
In the WebServer procedure (not webHandler) you'd override the .MakeErrorPage method.
See netweb.clw for an example of it.

Poul

  • Full Member
  • ***
  • Posts: 160
    • View Profile
Re: Implementing HTTP Authentication on a Server
« Reply #4 on: January 19, 2017, 04:23:33 PM »
I cannot get DIGEST to work and I think its because the response formulae  in CreateAuthorizationString 
that i use in my web client is not the same as the response formulae in  HeaderAuthentication that is used by my server to confirm the response
 
my client sends something like this
Code: [Select]
Digest username="ServiceLoginName", realm="", qop="auth", algorithm="MD5", uri="/", nonce="", nc=00000001, cnonce="", opaque="", response="e711aca2bffef0ef1ae1cc9435237648"
when i provide the same password to GetPassword in my server it seems to calculate a different/incorrect response - so fails

I don't know what the correct structure is for the digest, so i assume the CreateAuthorizationString  code is more correct as I assume it has been  in production and tested against none Nettalk servers.

To correct this I tweaked my Netweb.Clw NetWebServerWorkerBase.HeaderAuthentication  Procedure() so that it does the same as CreateAuthorizationString  does
Code: [Select]
...
 If password.Length()
      TempString1 = username.GetValue() & ':' & item.GetValue() & ':' & Password.GetValue()   
      NetMD5(TempString1, len(clip(TempString1)), TempString1)
      item.setvalue(str.GetLine(str.InLine('uri=', , , , , , st:begins)))
      item.SetValue(item.Between('"','"'))
      item.prepend('GET:')    ! <=============== Fix: this is effectively the way CreateAuthorizationString  does this part
!      item.prepend('GET:/')  ! <=============== Was THIS
      TempString2 = item.getvalue()
      NetMD5(TempString2, len(clip(TempString2)), TempString2)
...

Part of me feels this should be the otherway around as GET:// feels more right and the fix should be in CreateAuthorizationString
but i dunno, perhaps its just inconsistent assumptions about how to deal with some of these optional values (uri in particular)
so don't know if this will work when i expose my webservice to non clarion developers...
which is correct?
poul


Bruce

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 11250
    • View Profile
Re: Implementing HTTP Authentication on a Server
« Reply #5 on: January 19, 2017, 10:57:01 PM »
>> as I assume it has been  in production and tested against none Nettalk servers.

It was tested when done, but I think I recall the client changing at some point - presumably for compatibility reasons.
(From release notes it appears to be build 9.09 in May 2016.)

I've tweaked the server now to march (that will be in 9.18).

Regarding production - we don't use Digest authentication in servers at all, and I expect it's pretty rare generally. It's only useful in the case where you are logging in on a non-secure connection, which frankly you should be avoiding. Basic authentication is better when using SSL.

Cheers
Bruce


Poul

  • Full Member
  • ***
  • Posts: 160
    • View Profile
Re: Implementing HTTP Authentication on a Server
« Reply #6 on: January 20, 2017, 03:06:17 PM »
Yes , i meant to type non Nettalk servers in production - as you have to make the digest  work for them with NT clients.
to be clear  i can assume the issue is on the server side?  CreateAuthorizationString yields what you believe is correct?
so my tweak should suffix until 9.18




Bruce

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 11250
    • View Profile
Re: Implementing HTTP Authentication on a Server
« Reply #7 on: January 23, 2017, 12:06:05 AM »
correct.