Re: http-client egg and authentication
> Instead, you'd have to pass in an intarweb request object instead of an > URI, and construct the Authorization header yourself. Code: (import (chicken base)) (import (chicken io)) (import http-client) (import intarweb) (import uri-common) (define url "http://localhost:12345;) (define user "myuser") (define pass "mypass") (let* ((authorization-header `(authorization #(basic ((username . ,user) (password . ,pass) (request (make-request uri: (uri-reference url) headers: (headers (list authorization-header) (with-input-from-request request #f read-string)) Request: GET / HTTP/1.1 Authorization: Basic bXl1c2VyOm15cGFzcw== Host: localhost:12345 User-Agent: http-client/1.2 (CHICKEN Scheme HTTP-client) signature.asc Description: PGP signature
Re: http-client egg and authentication
On Mon, Sep 26, 2022 at 12:15:10AM +0200, Christian Himpe wrote: > Dear All, > > so I found this recent StackOverflow issue: > https://stackoverflow.com/questions/72904388/how-do-i-use-http-basic-auth-with-http-client > based on which I tried to use `make-uri` and pass the URI record (including > credentials) to the http-client. This also gives a 403 reply from the server. > I also tried manually encoding `"myuser:mypass"` as base64 without use. Hi there, I had a look since I didn't really remember and couldn't get it to work either. But after some re-reading of RFC2617, it made sense to me: Normally, a server should respond with 401 Unauthorized and a WWW-Authenticate header containing the acceptable authentication types, and, in case of digest authentication, a challenge. Given a username and password, http-client can't really (in general) simply send a basic auth header to the server. This would be needlessly insecure in case the server accepts (only) digest auth. And of course, sending a digest auth header is impossible since it requires receiving a challenge nonce first. So I guess you're (somewhat) out of luck, if your server doesn't correctly respond with a 401 response on the initial request, you can't rely on the builtin authentication mechanism. Instead, you'd have to pass in an intarweb request object instead of an URI, and construct the Authorization header yourself. > As a sidenote, using `uri-common`, I was not able to get a slash between port > and path from `make-uri`; I had to use `(update-uri (uri-reference ...) ...)`. You probably forgot to use a list with a slash symbol at the start. That makes a path absolute. '(/ "foo" "bar") is /foo/bar, whereas '("foo" "bar") is foo/bar. It's a bit awkward, but that's how it works. Cheers, Peter signature.asc Description: PGP signature
Re: http-client egg and authentication
Dear All, so I found this recent StackOverflow issue: https://stackoverflow.com/questions/72904388/how-do-i-use-http-basic-auth-with-http-client based on which I tried to use `make-uri` and pass the URI record (including credentials) to the http-client. This also gives a 403 reply from the server. I also tried manually encoding `"myuser:mypass"` as base64 without use. As a sidenote, using `uri-common`, I was not able to get a slash between port and path from `make-uri`; I had to use `(update-uri (uri-reference ...) ...)`. @Vasilij: Thanks for testing and explaining. Best Christian Christian Himpe schrieb am 2022-09-25: > Dear All, > I am exploring the use of the http-client egg ( > http://wiki.call-cc.org/eggref/5/http-client ) for communicating with a > database server. For this I need some basic authentication, which I did not > get to work. I tried including: > (determine-username/password (lambda (uri realm) (values "myuser" "mypass"))) > (see http://wiki.call-cc.org/eggref/5/http-client#authentication-support ), > which returns a 403 (Forbidden). However, authenticated communication works > with the server from the shell with "curl" using the argument "--user > myuser:mypass" ( https://curl.se/docs/manpage.html#-u ). > I assume I am missing, overlooking or doing something wrong here. Does > somebody have experience with this, or know some sample code? > Thank You > Christian
Re: http-client egg and authentication
Hello Christian, I've experimented by setting up a listener with `nc -nlvp 12345` and firing requests against localhost:12345 curl: GET / HTTP/1.1 Host: localhost:12345 Authorization: Basic bXl1c2VyOm15cGFzcw== User-Agent: curl/7.85.0 Accept: */* http-client: GET / HTTP/1.1 Host: localhost:12345 User-Agent: http-client/1.2 (CHICKEN Scheme HTTP-client) This confirms what you've seen. However, if you look at the documentation of `determine-username/password`, the following jumps at me: > The procedure in this parameter is called whenever the remote host > requests authentication via a 401 Unauthorized response. Since the listener does not request authentication, the procedure is never invoked. If you want to unconditionally set this header, pass it explicitly. Vasilij signature.asc Description: PGP signature
http-client egg and authentication
Dear All, I am exploring the use of the http-client egg ( http://wiki.call-cc.org/eggref/5/http-client ) for communicating with a database server. For this I need some basic authentication, which I did not get to work. I tried including: (determine-username/password (lambda (uri realm) (values "myuser" "mypass"))) (see http://wiki.call-cc.org/eggref/5/http-client#authentication-support ), which returns a 403 (Forbidden). However, authenticated communication works with the server from the shell with "curl" using the argument "--user myuser:mypass" ( https://curl.se/docs/manpage.html#-u ). I assume I am missing, overlooking or doing something wrong here. Does somebody have experience with this, or know some sample code? Thank You Christian