add nonce endpoint
This commit is contained in:
parent
364de7114a
commit
d6f5027480
112
mockid.go
112
mockid.go
|
@ -34,8 +34,13 @@ type PublicJWK struct {
|
|||
Y string `json:"y"`
|
||||
}
|
||||
|
||||
var nonces map[string]int64
|
||||
var jwksPrefix string
|
||||
|
||||
func init() {
|
||||
nonces = make(map[string]int64)
|
||||
}
|
||||
|
||||
func main() {
|
||||
done := make(chan bool)
|
||||
var port int
|
||||
|
@ -92,6 +97,34 @@ func main() {
|
|||
os.Exit(1)
|
||||
}
|
||||
|
||||
http.HandleFunc("/api/new-nonce", func(w http.ResponseWriter, r *http.Request) {
|
||||
baseURL := getBaseURL(r)
|
||||
/*
|
||||
res.statusCode = 200;
|
||||
res.setHeader("Cache-Control", "max-age=0, no-cache, no-store");
|
||||
// TODO
|
||||
//res.setHeader("Date", "Sun, 10 Mar 2019 08:04:45 GMT");
|
||||
// is this the expiration of the nonce itself? methinks maybe so
|
||||
//res.setHeader("Expires", "Sun, 10 Mar 2019 08:04:45 GMT");
|
||||
// TODO use one of the registered domains
|
||||
//var indexUrl = "https://acme-staging-v02.api.letsencrypt.org/index"
|
||||
*/
|
||||
//var port = (state.config.ipc && state.config.ipc.port || state._ipc.port || undefined);
|
||||
//var indexUrl = "http://localhost:" + port + "/index";
|
||||
indexUrl := baseURL + "/index";
|
||||
w.Header().Set("Link", "<" + indexUrl + ">;rel=\"index\"");
|
||||
w.Header().Set("Cache-Control", "max-age=0, no-cache, no-store");
|
||||
w.Header().Set("Pragma", "no-cache");
|
||||
//res.setHeader("Strict-Transport-Security", "max-age=604800");
|
||||
|
||||
w.Header().Set("X-Frame-Options", "DENY")
|
||||
issueNonce(w, r)
|
||||
})
|
||||
|
||||
http.HandleFunc("/api/new-account", requireNonce(func(w http.ResponseWriter, r *http.Request) {
|
||||
http.Error(w, "Not Implemented", http.StatusNotImplemented)
|
||||
}))
|
||||
|
||||
http.HandleFunc("/api/jwks", func(w http.ResponseWriter, r *http.Request) {
|
||||
log.Printf("%s %s %s", r.Method, r.Host, r.URL.Path)
|
||||
if "POST" != r.Method {
|
||||
|
@ -185,37 +218,20 @@ func main() {
|
|||
return
|
||||
}
|
||||
|
||||
var scheme string
|
||||
if nil != r.TLS || "https" == r.Header.Get("X-Forwarded-Proto") {
|
||||
scheme = "https://"
|
||||
} else {
|
||||
scheme = "http://"
|
||||
}
|
||||
baseURL := getBaseURL(r)
|
||||
w.Write([]byte(fmt.Sprintf(
|
||||
`{ "iss":%q, "jwks_url":%q }`, scheme+r.Host+"/", scheme+r.Host+"/.well-known/jwks.json",
|
||||
`{ "iss":%q, "jwks_url":%q }`, baseURL+"/", baseURL+"/.well-known/jwks.json",
|
||||
)))
|
||||
})
|
||||
|
||||
http.HandleFunc("/access_token", func(w http.ResponseWriter, r *http.Request) {
|
||||
log.Printf("%s %s\n", r.Method, r.URL.Path)
|
||||
var scheme string
|
||||
if nil != r.TLS || "https" == r.Header.Get("X-Forwarded-Proto") {
|
||||
scheme = "https://"
|
||||
} else {
|
||||
scheme = "http://"
|
||||
}
|
||||
_, _, token := genToken(scheme+r.Host, priv, r.URL.Query())
|
||||
_, _, token := genToken(getBaseURL(r), priv, r.URL.Query())
|
||||
fmt.Fprintf(w, token)
|
||||
})
|
||||
|
||||
http.HandleFunc("/authorization_header", func(w http.ResponseWriter, r *http.Request) {
|
||||
log.Printf("%s %s\n", r.Method, r.URL.Path)
|
||||
var scheme string
|
||||
if nil != r.TLS || "https" == r.Header.Get("X-Forwarded-Proto") {
|
||||
scheme = "https://"
|
||||
} else {
|
||||
scheme = "http://"
|
||||
}
|
||||
|
||||
var header string
|
||||
headers, _ := r.URL.Query()["header"]
|
||||
|
@ -233,7 +249,7 @@ func main() {
|
|||
prefix = prefixes[0]
|
||||
}
|
||||
|
||||
_, _, token := genToken(scheme+r.Host, priv, r.URL.Query())
|
||||
_, _, token := genToken(getBaseURL(r), priv, r.URL.Query())
|
||||
fmt.Fprintf(w, "%s: %s%s", header, prefix, token)
|
||||
})
|
||||
|
||||
|
@ -243,14 +259,9 @@ func main() {
|
|||
})
|
||||
|
||||
http.HandleFunc("/.well-known/openid-configuration", func(w http.ResponseWriter, r *http.Request) {
|
||||
var scheme string
|
||||
if nil != r.TLS || "https" == r.Header.Get("X-Forwarded-Proto") {
|
||||
scheme = "https://"
|
||||
} else {
|
||||
scheme = "http://"
|
||||
}
|
||||
baseURL := getBaseURL(r)
|
||||
log.Printf("%s %s\n", r.Method, r.URL.Path)
|
||||
fmt.Fprintf(w, `{ "issuer": "%s", "jwks_uri": "%s/.well-known/jwks.json" }`, scheme+r.Host, scheme+r.Host)
|
||||
fmt.Fprintf(w, `{ "issuer": "%s", "jwks_uri": "%s/.well-known/jwks.json" }`, baseURL, baseURL)
|
||||
})
|
||||
|
||||
http.HandleFunc("/.well-known/jwks.json", func(w http.ResponseWriter, r *http.Request) {
|
||||
|
@ -407,3 +418,48 @@ func thumbprintKey(pub *ecdsa.PublicKey) string {
|
|||
sha := sha256.Sum256(minpub)
|
||||
return base64.RawURLEncoding.EncodeToString(sha[:])
|
||||
}
|
||||
|
||||
func issueNonce(w http.ResponseWriter, r *http.Request) {
|
||||
b := make([]byte, 16)
|
||||
_, _ = rand.Read(b)
|
||||
nonce := base64.RawURLEncoding.EncodeToString(b);
|
||||
nonces[nonce] = time.Now().Unix()
|
||||
|
||||
w.Header().Set("Replay-Nonce", nonce);
|
||||
}
|
||||
|
||||
|
||||
func requireNonce(next http.HandlerFunc) http.HandlerFunc {
|
||||
return func (w http.ResponseWriter, r *http.Request) {
|
||||
nonce := r.Header.Get("Replay-Nonce")
|
||||
// TODO expire nonces every so often
|
||||
t := nonces[nonce]
|
||||
if 0 == t {
|
||||
http.Error(
|
||||
w,
|
||||
`{ "error": "invalid or expired nonce", "error_code": "ENONCE" }`,
|
||||
http.StatusBadRequest,
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
delete(nonces, nonce)
|
||||
issueNonce(w, r)
|
||||
|
||||
next(w, r);
|
||||
}
|
||||
}
|
||||
|
||||
func getBaseURL(r *http.Request) string {
|
||||
var scheme string
|
||||
if nil != r.TLS || "https" == r.Header.Get("X-Forwarded-Proto") {
|
||||
scheme = "https:"
|
||||
} else {
|
||||
scheme = "http:"
|
||||
}
|
||||
return fmt.Sprintf(
|
||||
"%s//%s",
|
||||
scheme,
|
||||
r.Host,
|
||||
)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue