Basic but complete authentication flow

This commit is contained in:
2020-05-20 11:13:14 +02:00
parent 81778121fb
commit 61aae078b5
32 changed files with 626 additions and 442 deletions

View File

@ -0,0 +1,56 @@
package token
import (
"github.com/pkg/errors"
"gopkg.in/square/go-jose.v2"
"gopkg.in/square/go-jose.v2/jwt"
)
const (
jwtIssuer = "hydra-passwordless"
)
type privateClaims struct {
Challenge string `json:"challenge"`
}
func Generate(signingKey, encryptionKey, email, challenge string) (string, error) {
sig, err := jose.NewSigner(
jose.SigningKey{
Algorithm: jose.HS256,
Key: []byte(signingKey),
},
(&jose.SignerOptions{}).WithType("JWT"),
)
if err != nil {
return "", errors.Wrap(err, "could not create jwt signer")
}
enc, err := jose.NewEncrypter(
jose.A256GCM,
jose.Recipient{
Algorithm: jose.DIRECT,
Key: []byte(encryptionKey),
},
(&jose.EncrypterOptions{}).WithType("JWT").WithContentType("JWT"))
if err != nil {
return "", errors.Wrap(err, "could not create jwt encrypter")
}
claims := jwt.Claims{
Subject: email,
Issuer: jwtIssuer,
Audience: jwt.Audience{jwtIssuer},
}
privateClaims := privateClaims{
Challenge: challenge,
}
raw, err := jwt.SignedAndEncrypted(sig, enc).Claims(claims).Claims(privateClaims).CompactSerialize()
if err != nil {
return "", errors.Wrap(err, "could not sign and encrypt jwt")
}
return raw, nil
}

27
internal/token/verify.go Normal file
View File

@ -0,0 +1,27 @@
package token
import (
"github.com/pkg/errors"
"gopkg.in/square/go-jose.v2/jwt"
)
func Verify(signingKey, encryptionKey, raw string) (string, string, error) {
token, err := jwt.ParseSignedAndEncrypted(raw)
if err != nil {
return "", "", errors.Wrap(err, "could not parse token")
}
nested, err := token.Decrypt([]byte(encryptionKey))
if err != nil {
return "", "", errors.Wrap(err, "could not decrypt token")
}
baseClaims := jwt.Claims{}
privateClaims := privateClaims{}
if err := nested.Claims([]byte(signingKey), &baseClaims, &privateClaims); err != nil {
return "", "", errors.Wrap(err, "could not validate claims")
}
return baseClaims.Subject, privateClaims.Challenge, nil
}