go-mockid/mockid/api/verify.go

88 lines
2.2 KiB
Go

package api
import (
"encoding/base64"
"encoding/json"
"io"
"log"
"net/http"
"strings"
"git.coolaj86.com/coolaj86/go-mockid/xkeypairs"
)
// VerifyJWT will verify both JWT and uncompressed JWS
func Verify(w http.ResponseWriter, r *http.Request) {
if "POST" != r.Method {
http.Error(w, "Method Not Allowed", http.StatusMethodNotAllowed)
return
}
var jws *xkeypairs.JWS
authzParts := strings.Split(r.Header.Get("Authorization"), " ")
lenAuthz := len(authzParts)
if 2 == lenAuthz {
jwt := authzParts[1]
jwsParts := strings.Split(jwt, ".")
if 3 == len(jwsParts) {
jws = &xkeypairs.JWS{
Protected: jwsParts[0],
Payload: jwsParts[1],
Signature: jwsParts[2],
}
}
}
if nil == jws {
if 0 != lenAuthz {
http.Error(w, "Bad Request: malformed Authorization header", http.StatusBadRequest)
return
}
decoder := json.NewDecoder(r.Body)
err := decoder.Decode(&jws)
if nil != err && io.EOF != err {
log.Printf("json decode error: %s", err)
http.Error(w, "Bad Request: invalid JWS body", http.StatusBadRequest)
return
}
defer r.Body.Close()
}
protected, err := base64.RawURLEncoding.DecodeString(jws.Protected)
if nil != err {
http.Error(w, "Bad Request: invalid JWS header base64Url encoding", http.StatusBadRequest)
return
}
if err := json.Unmarshal([]byte(protected), &jws.Header); nil != err {
log.Printf("json decode error: %s", err)
http.Error(w, "Bad Request: invalid JWS header", http.StatusBadRequest)
return
}
payload, err := base64.RawURLEncoding.DecodeString(jws.Payload)
if nil != err {
http.Error(w, "Bad Request: invalid JWS payload base64Url encoding", http.StatusBadRequest)
return
}
if err := json.Unmarshal([]byte(payload), &jws.Claims); nil != err {
log.Printf("json decode error: %s", err)
http.Error(w, "Bad Request: invalid JWS claims", http.StatusBadRequest)
return
}
ok, err := xkeypairs.VerifyClaims(nil, jws)
if nil != err {
log.Printf("jws verify error: %s", err)
http.Error(w, "Bad Request: could not verify JWS claims", http.StatusBadRequest)
return
}
if !ok {
http.Error(w, "Bad Request: invalid JWS signature", http.StatusBadRequest)
return
}
b := []byte(`{"success":true}`)
w.Write(append(b, '\n'))
}