12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788 |
- package isapi
- import (
- "crypto/md5"
- "encoding/json"
- "fmt"
- "log"
- "strings"
- )
- // Challenge WWW-Authorization头部的值
- type Challenge struct {
- Realm string
- Domain string
- Nonce string
- Opaque string
- Stale string
- Algorithm string
- Qop string
- }
- // Response 作为Authorization头部的值
- type Response struct {
- Username string
- Realm string
- Nonce string
- URI string
- Qop string
- Cnonce string
- Nc string
- Response string
- }
- func MD5(s string) string {
- return fmt.Sprintf("%x", md5.Sum([]byte(s)))
- }
- // NewChallenge 根据WWW-Authorization的值生成Challenge
- func NewChallenge(header string) *Challenge {
- var m = make(map[string]string, 5)
- str := header[7:]
- split := strings.Split(str, ",")
- for _, v := range split {
- s := strings.Split(v, "=")
- k := strings.Trim(s[0], " ")
- m[k] = strings.Trim(s[1], "\"")
- }
- // Marshall digest
- b, err := json.Marshal(m)
- if err != nil {
- log.Fatalln("Error:", err)
- }
- // Unmarshall into struct
- challenge := Challenge{}
- if err := json.Unmarshal(b, &challenge); err != nil {
- log.Fatalln("Error:", err)
- }
- return &challenge
- }
- // Authorize 生成 Response #客户端需要对服务端认证时cnonce应是变化的#
- func (c *Challenge) Authorize(username, password, method, uri string) *Response {
- // MD5(<username>:<realm>:<password>)
- a1 := MD5(fmt.Sprintf("%s:%s:%s", username, c.Realm, password))
- // MD5(<request-method>:<uri>)
- a2 := MD5(fmt.Sprintf("%s:%s", method, uri))
- // MD5(MD5(A1):<auth>:<nc>:<cnonce>:<qop>:MD5(A2))
- response := MD5(fmt.Sprintf("%s:%s:%s:%s:%s:%s", a1, c.Nonce, "00000001", "0a4f113b", c.Qop, a2))
- return &Response{
- Username: username,
- Realm: c.Realm,
- Nonce: c.Nonce,
- URI: uri,
- Qop: c.Qop,
- Cnonce: "0a4f113b",
- Nc: "00000001",
- Response: response,
- }
- }
- // 生成字符串作为Authorization的值
- func (r *Response) String() string {
- return fmt.Sprintf(`Digest username="%s", realm="%s", nonce="%s", uri="%s", qop=%s, nc=%s, cnonce="%s", response="%s"`, r.Username, r.Realm, r.Nonce, r.URI, r.Qop, r.Nc, r.Cnonce, r.Response)
- }
|