https://github.com/icholy/digest
Go HTTP Digest Access Authentication
https://github.com/icholy/digest
Last synced: over 1 year ago
JSON representation
Go HTTP Digest Access Authentication
- Host: GitHub
- URL: https://github.com/icholy/digest
- Owner: icholy
- License: mit
- Created: 2020-06-03T21:08:11.000Z (about 6 years ago)
- Default Branch: master
- Last Pushed: 2024-06-13T16:16:39.000Z (about 2 years ago)
- Last Synced: 2024-10-16T00:30:48.150Z (almost 2 years ago)
- Language: Go
- Homepage:
- Size: 64.5 KB
- Stars: 59
- Watchers: 4
- Forks: 14
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# HTTP Digest Access Authentication
[](https://pkg.go.dev/github.com/icholy/digest)
> This package provides a http.RoundTripper implementation which re-uses digest challenges
``` go
package main
import (
"net/http"
"github.com/icholy/digest"
)
func main() {
client := &http.Client{
Transport: &digest.Transport{
Username: "foo",
Password: "bar",
},
}
res, err := client.Get("http://localhost:8080/some_outdated_service")
if err != nil {
panic(err)
}
defer res.Body.Close()
}
```
## Using Cookies
If you're using an `http.CookieJar` the `digest.Transport` needs a reference to it.
``` go
package main
import (
"net/http"
"net/http/cookiejar"
"github.com/icholy/digest"
)
func main() {
jar, _ := cookiejar.New(nil)
client := &http.Client{
Transport: &digest.Transport{
Jar: jar,
Username: "foo",
Password: "bar",
},
}
res, err := client.Get("http://localhost:8080/digest_with_cookies")
if err != nil {
panic(err)
}
defer res.Body.Close()
}
```
## Custom Authenticate Header
``` go
package main
import (
"net/http"
"github.com/icholy/digest"
)
func main() {
client := &http.Client{
Transport: &digest.Transport{
Username: "foo",
Password: "bar",
FindChallenge: func(h http.Header) (*digest.Challenge, error) {
value := h.Get("Custom-Authenticate-Header")
if value == "" {
return nil, digest.ErrNoChallenge
}
return digest.ParseChallenge(value)
},
},
}
res, err := client.Get("http://localhost:8080/non_compliant")
if err != nil {
panic(err)
}
defer res.Body.Close()
}
```
## Override Digest Options
``` go
package main
import (
"fmt"
"net/http"
"github.com/icholy/digest"
)
func main() {
client := &http.Client{
Transport: &digest.Transport{
Digest: func(req *http.Request, chal *digest.Challenge, opt digest.Options) (*digest.Credentials, error) {
switch req.URL.Hostname() {
case "badauth.org":
opt.Username = "foo"
opt.Password = "bar"
case "poorsecurity.com":
opt.Username = "zoo"
opt.Password = "boo"
default:
return nil, fmt.Errorf("unsuported host: %q", req.URL)
}
return digest.Digest(chal, opt)
},
},
}
res, err := client.Get("http://poorsecurity.com/legacy.php")
if err != nil {
panic(err)
}
defer res.Body.Close()
}
```
## Low Level API
``` go
func main() {
// get the challenge from a 401 response
header := res.Header.Get("WWW-Authenticate")
chal, _ := digest.ParseChallenge(header)
// use it to create credentials for the next request
cred, _ := digest.Digest(chal, digest.Options{
Username: "foo",
Password: "bar",
Method: req.Method,
URI: req.URL.RequestURI(),
GetBody: req.GetBody,
Count: 1,
})
req.Header.Set("Authorization", cred.String())
// if you use the same challenge again, you must increment the Count
cred2, _ := digest.Digest(chal, digest.Options{
Username: "foo",
Password: "bar",
Method: req2.Method,
URI: req2.URL.RequestURI(),
GetBody: req2.GetBody,
Count: 2,
})
req2.Header.Set("Authorization", cred.String())
}
```