feat: add well-known jwks.json endpoint
This commit is contained in:
parent
ad46210112
commit
145091dce1
|
@ -20,8 +20,6 @@ const (
|
|||
EnvKeyAuthorizerURL = "AUTHORIZER_URL"
|
||||
// EnvKeyPort key for env variable PORT
|
||||
EnvKeyPort = "PORT"
|
||||
// EnvKeyClientID key for env variable CLIENT_ID
|
||||
EnvKeyClientID = "CLIENT_ID"
|
||||
|
||||
// EnvKeyAdminSecret key for env variable ADMIN_SECRET
|
||||
EnvKeyAdminSecret = "ADMIN_SECRET"
|
||||
|
@ -95,8 +93,14 @@ const (
|
|||
EnvKeyOrganizationName = "ORGANIZATION_NAME"
|
||||
// EnvKeyOrganizationLogo key for env variable ORGANIZATION_LOGO
|
||||
EnvKeyOrganizationLogo = "ORGANIZATION_LOGO"
|
||||
// EnvKeyIsProd key for env variable IS_PROD
|
||||
EnvKeyIsProd = "IS_PROD"
|
||||
// EnvKeyCustomAccessTokenScript key for env variable CUSTOM_ACCESS_TOKEN_SCRIPT
|
||||
EnvKeyCustomAccessTokenScript = "CUSTOM_ACCESS_TOKEN_SCRIPT"
|
||||
|
||||
// Not Exposed Keys
|
||||
// EnvKeyClientID key for env variable CLIENT_ID
|
||||
EnvKeyClientID = "CLIENT_ID"
|
||||
// EnvKeyJWK key for env variable JWK
|
||||
EnvKeyJWK = "JWK"
|
||||
// EnvKeyIsProd key for env variable IS_PROD
|
||||
EnvKeyIsProd = "IS_PROD"
|
||||
)
|
||||
|
|
29
server/crypto/common.go
Normal file
29
server/crypto/common.go
Normal file
|
@ -0,0 +1,29 @@
|
|||
package crypto
|
||||
|
||||
import (
|
||||
"crypto/x509"
|
||||
|
||||
"gopkg.in/square/go-jose.v2"
|
||||
)
|
||||
|
||||
// GetPubJWK returns JWK for given keys
|
||||
func GetPubJWK(algo, keyID string, publicKey interface{}) (string, error) {
|
||||
jwk := &jose.JSONWebKeySet{
|
||||
Keys: []jose.JSONWebKey{
|
||||
{
|
||||
Algorithm: algo,
|
||||
Key: publicKey,
|
||||
Use: "sig",
|
||||
KeyID: keyID,
|
||||
Certificates: []*x509.Certificate{},
|
||||
CertificateThumbprintSHA1: []uint8{},
|
||||
CertificateThumbprintSHA256: []uint8{},
|
||||
},
|
||||
},
|
||||
}
|
||||
jwkPublicKey, err := jwk.Keys[0].MarshalJSON()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return string(jwkPublicKey), nil
|
||||
}
|
|
@ -10,18 +10,24 @@ import (
|
|||
)
|
||||
|
||||
// NewECDSAKey to generate new ECDSA Key if env is not set
|
||||
func NewECDSAKey() (*ecdsa.PrivateKey, string, string, error) {
|
||||
// returns key instance, private key string, public key string, jwk string, error
|
||||
func NewECDSAKey(algo, keyID string) (*ecdsa.PrivateKey, string, string, string, error) {
|
||||
key, err := ecdsa.GenerateKey(elliptic.P384(), rand.Reader)
|
||||
if err != nil {
|
||||
return nil, "", "", err
|
||||
return nil, "", "", "", err
|
||||
}
|
||||
|
||||
privateKey, publicKey, err := AsECDSAStr(key, &key.PublicKey)
|
||||
if err != nil {
|
||||
return nil, "", "", err
|
||||
return nil, "", "", "", err
|
||||
}
|
||||
|
||||
return key, privateKey, publicKey, err
|
||||
jwkPublicKey, err := GetPubJWK(algo, keyID, &key.PublicKey)
|
||||
if err != nil {
|
||||
return nil, "", "", "", err
|
||||
}
|
||||
|
||||
return key, privateKey, publicKey, string(jwkPublicKey), err
|
||||
}
|
||||
|
||||
// IsECDSA checks if given string is valid ECDSA algo
|
||||
|
|
|
@ -1,11 +1,18 @@
|
|||
package crypto
|
||||
|
||||
import "github.com/google/uuid"
|
||||
import (
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
|
||||
// NewHMAC key returns new key that can be used to ecnrypt data using HMAC algo
|
||||
func NewHMACKey() string {
|
||||
// returns key, string, error
|
||||
func NewHMACKey(algo, keyID string) (string, string, error) {
|
||||
key := uuid.New().String()
|
||||
return key
|
||||
jwkPublicKey, err := GetPubJWK(algo, keyID, []byte(key))
|
||||
if err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
return key, string(jwkPublicKey), nil
|
||||
}
|
||||
|
||||
// IsHMACValid checks if given string is valid HMCA algo
|
||||
|
|
|
@ -9,18 +9,24 @@ import (
|
|||
)
|
||||
|
||||
// NewRSAKey to generate new RSA Key if env is not set
|
||||
func NewRSAKey() (*rsa.PrivateKey, string, string, error) {
|
||||
// returns key instance, private key string, public key string, jwk string, error
|
||||
func NewRSAKey(algo, keyID string) (*rsa.PrivateKey, string, string, string, error) {
|
||||
key, err := rsa.GenerateKey(rand.Reader, 2048)
|
||||
if err != nil {
|
||||
return nil, "", "", err
|
||||
return nil, "", "", "", err
|
||||
}
|
||||
|
||||
privateKey, publicKey, err := AsRSAStr(key, &key.PublicKey)
|
||||
if err != nil {
|
||||
return nil, "", "", err
|
||||
return nil, "", "", "", err
|
||||
}
|
||||
|
||||
return key, privateKey, publicKey, err
|
||||
jwkPublicKey, err := GetPubJWK(algo, keyID, &key.PublicKey)
|
||||
if err != nil {
|
||||
return nil, "", "", "", err
|
||||
}
|
||||
|
||||
return key, privateKey, publicKey, string(jwkPublicKey), err
|
||||
}
|
||||
|
||||
// IsRSA checks if given string is valid RSA algo
|
||||
|
@ -46,11 +52,8 @@ func ExportRsaPrivateKeyAsPemStr(privkey *rsa.PrivateKey) string {
|
|||
}
|
||||
|
||||
// ExportRsaPublicKeyAsPemStr to get RSA public key as pem string
|
||||
func ExportRsaPublicKeyAsPemStr(pubkey *rsa.PublicKey) (string, error) {
|
||||
pubkeyBytes, err := x509.MarshalPKIXPublicKey(pubkey)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
func ExportRsaPublicKeyAsPemStr(pubkey *rsa.PublicKey) string {
|
||||
pubkeyBytes := x509.MarshalPKCS1PublicKey(pubkey)
|
||||
pubkeyPem := pem.EncodeToMemory(
|
||||
&pem.Block{
|
||||
Type: "RSA PUBLIC KEY",
|
||||
|
@ -58,7 +61,7 @@ func ExportRsaPublicKeyAsPemStr(pubkey *rsa.PublicKey) (string, error) {
|
|||
},
|
||||
)
|
||||
|
||||
return string(pubkeyPem), nil
|
||||
return string(pubkeyPem)
|
||||
}
|
||||
|
||||
// ParseRsaPrivateKeyFromPemStr to parse RSA private key from pem string
|
||||
|
@ -83,28 +86,19 @@ func ParseRsaPublicKeyFromPemStr(pubPEM string) (*rsa.PublicKey, error) {
|
|||
return nil, errors.New("failed to parse PEM block containing the key")
|
||||
}
|
||||
|
||||
pub, err := x509.ParsePKIXPublicKey(block.Bytes)
|
||||
pub, err := x509.ParsePKCS1PublicKey(block.Bytes)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
switch pub := pub.(type) {
|
||||
case *rsa.PublicKey:
|
||||
return pub, nil
|
||||
default:
|
||||
break // fall through
|
||||
}
|
||||
return nil, errors.New("Key type is not RSA")
|
||||
return pub, nil
|
||||
}
|
||||
|
||||
// AsRSAStr returns private, public key string or error
|
||||
func AsRSAStr(privateKey *rsa.PrivateKey, publickKey *rsa.PublicKey) (string, string, error) {
|
||||
// Export the keys to pem string
|
||||
privPem := ExportRsaPrivateKeyAsPemStr(privateKey)
|
||||
pubPem, err := ExportRsaPublicKeyAsPemStr(publickKey)
|
||||
if err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
pubPem := ExportRsaPublicKeyAsPemStr(publickKey)
|
||||
|
||||
// Import the keys from pem string
|
||||
privParsed, err := ParseRsaPrivateKeyFromPemStr(privPem)
|
||||
|
@ -118,10 +112,7 @@ func AsRSAStr(privateKey *rsa.PrivateKey, publickKey *rsa.PublicKey) (string, st
|
|||
|
||||
// Export the newly imported keys
|
||||
privParsedPem := ExportRsaPrivateKeyAsPemStr(privParsed)
|
||||
pubParsedPem, err := ExportRsaPublicKeyAsPemStr(pubParsed)
|
||||
if err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
pubParsedPem := ExportRsaPublicKeyAsPemStr(pubParsed)
|
||||
|
||||
return privParsedPem, pubParsedPem, nil
|
||||
}
|
||||
|
|
45
server/env/env.go
vendored
45
server/env/env.go
vendored
|
@ -11,6 +11,7 @@ import (
|
|||
"github.com/authorizerdev/authorizer/server/envstore"
|
||||
"github.com/authorizerdev/authorizer/server/utils"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/google/uuid"
|
||||
"github.com/joho/godotenv"
|
||||
)
|
||||
|
||||
|
@ -77,6 +78,13 @@ func InitAllEnv() error {
|
|||
envData = envstore.EnvInMemoryStoreObj.GetEnvStoreClone()
|
||||
}
|
||||
|
||||
clientID := envData.StringEnv[constants.EnvKeyClientID]
|
||||
// unique client id for each instance
|
||||
if clientID == "" {
|
||||
clientID = uuid.New().String()
|
||||
envData.StringEnv[constants.EnvKeyClientID] = clientID
|
||||
}
|
||||
|
||||
if envData.StringEnv[constants.EnvKeyEnv] == "" {
|
||||
envData.StringEnv[constants.EnvKeyEnv] = os.Getenv(constants.EnvKeyEnv)
|
||||
if envData.StringEnv[constants.EnvKeyEnv] == "" {
|
||||
|
@ -126,8 +134,8 @@ func InitAllEnv() error {
|
|||
envData.StringEnv[constants.EnvKeySenderEmail] = os.Getenv(constants.EnvKeySenderEmail)
|
||||
}
|
||||
|
||||
algo := ""
|
||||
if envData.StringEnv[constants.EnvKeyJwtType] == "" {
|
||||
algo := envData.StringEnv[constants.EnvKeyJwtType]
|
||||
if algo == "" {
|
||||
envData.StringEnv[constants.EnvKeyJwtType] = os.Getenv(constants.EnvKeyJwtType)
|
||||
if envData.StringEnv[constants.EnvKeyJwtType] == "" {
|
||||
envData.StringEnv[constants.EnvKeyJwtType] = "RS256"
|
||||
|
@ -143,12 +151,21 @@ func InitAllEnv() error {
|
|||
if envData.StringEnv[constants.EnvKeyJwtSecret] == "" && crypto.IsHMACA(algo) {
|
||||
envData.StringEnv[constants.EnvKeyJwtSecret] = os.Getenv(constants.EnvKeyJwtSecret)
|
||||
if envData.StringEnv[constants.EnvKeyJwtSecret] == "" {
|
||||
envData.StringEnv[constants.EnvKeyJwtSecret] = crypto.NewHMACKey()
|
||||
envData.StringEnv[constants.EnvKeyJwtSecret], envData.StringEnv[constants.EnvKeyJWK], err = crypto.NewHMACKey(algo, clientID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
envData.StringEnv[constants.EnvKeyJWK], err = crypto.GetPubJWK(algo, clientID, []byte(envData.StringEnv[constants.EnvKeyJwtSecret]))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if crypto.IsRSA(algo) || crypto.IsECDSA(algo) {
|
||||
privateKey, publicKey := "", ""
|
||||
privateKey, publicKey, jwk := "", "", ""
|
||||
|
||||
if envData.StringEnv[constants.EnvKeyJwtPrivateKey] == "" {
|
||||
privateKey = os.Getenv(constants.EnvKeyJwtPrivateKey)
|
||||
|
@ -162,12 +179,12 @@ func InitAllEnv() error {
|
|||
// if either of them is not present generate new keys
|
||||
if privateKey == "" || publicKey == "" {
|
||||
if crypto.IsRSA(algo) {
|
||||
_, privateKey, publicKey, err = crypto.NewRSAKey()
|
||||
_, privateKey, publicKey, jwk, err = crypto.NewRSAKey(algo, clientID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else if crypto.IsECDSA(algo) {
|
||||
_, privateKey, publicKey, err = crypto.NewECDSAKey()
|
||||
_, privateKey, publicKey, jwk, err = crypto.NewECDSAKey(algo, clientID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -180,7 +197,12 @@ func InitAllEnv() error {
|
|||
return err
|
||||
}
|
||||
|
||||
_, err = crypto.ParseRsaPublicKeyFromPemStr(publicKey)
|
||||
publicKeyInstance, err := crypto.ParseRsaPublicKeyFromPemStr(publicKey)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
jwk, err = crypto.GetPubJWK(algo, clientID, publicKeyInstance)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -190,15 +212,22 @@ func InitAllEnv() error {
|
|||
return err
|
||||
}
|
||||
|
||||
_, err = crypto.ParseEcdsaPublicKeyFromPemStr(publicKey)
|
||||
publicKeyInstance, err := crypto.ParseEcdsaPublicKeyFromPemStr(publicKey)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
jwk, err = crypto.GetPubJWK(algo, clientID, publicKeyInstance)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
envData.StringEnv[constants.EnvKeyJWK] = jwk
|
||||
envData.StringEnv[constants.EnvKeyJwtPrivateKey] = privateKey
|
||||
envData.StringEnv[constants.EnvKeyJwtPublicKey] = publicKey
|
||||
|
||||
}
|
||||
|
||||
if envData.StringEnv[constants.EnvKeyJwtRoleClaim] == "" {
|
||||
|
|
4
server/env/persist_env.go
vendored
4
server/env/persist_env.go
vendored
|
@ -178,9 +178,5 @@ func PersistEnv() error {
|
|||
}
|
||||
}
|
||||
|
||||
// ID of env is used to identify the config and declared as client id
|
||||
// this client id can be used in `aud` section of JWT token
|
||||
envstore.EnvInMemoryStoreObj.UpdateEnvVariable(constants.StringStoreIdentifier, constants.EnvKeyClientID, env.ID)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -30,6 +30,7 @@ require (
|
|||
google.golang.org/protobuf v1.27.1 // indirect
|
||||
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect
|
||||
gopkg.in/mail.v2 v2.3.1
|
||||
gopkg.in/square/go-jose.v2 v2.6.0 // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
gorm.io/driver/mysql v1.2.1
|
||||
gorm.io/driver/postgres v1.2.3
|
||||
|
|
|
@ -69,6 +69,9 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
|
|||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/dchest/uniuri v0.0.0-20160212164326-8902c56451e9/go.mod h1:GgB8SF9nRG+GqaDtLcwJZsQFhcogVCJ79j4EdT0c2V4=
|
||||
github.com/decred/dcrd/crypto/blake256 v1.0.0/go.mod h1:sQl2p6Y26YV+ZOcSTP6thNdn47hh8kt6rqSlvmrXFAc=
|
||||
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.0-20210816181553-5444fa50b93d h1:1iy2qD6JEhHKKhUOA9IWs7mjco7lnw2qx8FsRI2wirE=
|
||||
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.0-20210816181553-5444fa50b93d/go.mod h1:tmAIfUFEirG/Y8jhZ9M+h36obRZAk/1fcSpXwAVlfqE=
|
||||
github.com/denisenkom/go-mssqldb v0.11.0 h1:9rHa233rhdOyrz2GcP9NM+gi2psgJZ4GWDpL/7ND8HI=
|
||||
github.com/denisenkom/go-mssqldb v0.11.0/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU=
|
||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
|
||||
|
@ -106,6 +109,8 @@ github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfC
|
|||
github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
|
||||
github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk=
|
||||
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
||||
github.com/goccy/go-json v0.9.4 h1:L8MLKG2mvVXiQu07qB6hmfqeSYQdOnqPot2GhsIwIaI=
|
||||
github.com/goccy/go-json v0.9.4/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
|
||||
github.com/gofrs/uuid v4.0.0+incompatible h1:1SD/1F5pU8p29ybwgQSwpQk+mwdRrXCYuPhW6m+TnJw=
|
||||
github.com/gofrs/uuid v4.0.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
|
||||
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
|
||||
|
@ -256,6 +261,18 @@ github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
|||
github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII=
|
||||
github.com/leodido/go-urn v1.2.1 h1:BqpAaACuzVSgi/VLzGZIobT2z4v53pjosyNd9Yv6n/w=
|
||||
github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY=
|
||||
github.com/lestrrat-go/backoff/v2 v2.0.8 h1:oNb5E5isby2kiro9AgdHLv5N5tint1AnDVVf2E2un5A=
|
||||
github.com/lestrrat-go/backoff/v2 v2.0.8/go.mod h1:rHP/q/r9aT27n24JQLa7JhSQZCKBBOiM/uP402WwN8Y=
|
||||
github.com/lestrrat-go/blackmagic v1.0.0 h1:XzdxDbuQTz0RZZEmdU7cnQxUtFUzgCSPq8RCz4BxIi4=
|
||||
github.com/lestrrat-go/blackmagic v1.0.0/go.mod h1:TNgH//0vYSs8VXDCfkZLgIrVTTXQELZffUV0tz3MtdQ=
|
||||
github.com/lestrrat-go/httpcc v1.0.0 h1:FszVC6cKfDvBKcJv646+lkh4GydQg2Z29scgUfkOpYc=
|
||||
github.com/lestrrat-go/httpcc v1.0.0/go.mod h1:tGS/u00Vh5N6FHNkExqGGNId8e0Big+++0Gf8MBnAvE=
|
||||
github.com/lestrrat-go/iter v1.0.1 h1:q8faalr2dY6o8bV45uwrxq12bRa1ezKrB6oM9FUgN4A=
|
||||
github.com/lestrrat-go/iter v1.0.1/go.mod h1:zIdgO1mRKhn8l9vrZJZz9TUMMFbQbLeTsbqPDrJ/OJc=
|
||||
github.com/lestrrat-go/jwx v1.2.19 h1:qxxLmAXNwZpTTvjc4PH21nT7I4wPK6lVv3lVNcZPnUk=
|
||||
github.com/lestrrat-go/jwx v1.2.19/go.mod h1:bWTBO7IHHVMtNunM8so9MT8wD+euEY1PzGEyCnuI2qM=
|
||||
github.com/lestrrat-go/option v1.0.0 h1:WqAWL8kh8VcSoD6xjSH34/1m8yxluXQbDeKNfvFeEO4=
|
||||
github.com/lestrrat-go/option v1.0.0/go.mod h1:5ZHFbivi4xwXxhxY9XHDe2FHo6/Z7WWmtT7T5nBBp3I=
|
||||
github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||
github.com/lib/pq v1.1.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||
github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||
|
@ -386,6 +403,7 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U
|
|||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20201203163018-be400aefbc4c/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
|
||||
golang.org/x/crypto v0.0.0-20201216223049-8b5274cf687f/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
|
||||
golang.org/x/crypto v0.0.0-20201217014255-9d1352758620/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
|
||||
golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 h1:7I4JAnoQBe7ZtJcBaYHi5UtiO8tQHbUSXxL+pnGRANg=
|
||||
|
@ -684,6 +702,8 @@ gopkg.in/sourcemap.v1 v1.0.5 h1:inv58fC9f9J3TK2Y2R1NPntXEn3/wjWHkonhIUODNTI=
|
|||
gopkg.in/sourcemap.v1 v1.0.5/go.mod h1:2RlvNNSMglmRrcvhfuzp4hQHwOtjxlbjX7UPY/GXb78=
|
||||
gopkg.in/square/go-jose.v2 v2.5.1 h1:7odma5RETjNHWJnR32wx8t+Io4djHE1PqxCFx3iiZ2w=
|
||||
gopkg.in/square/go-jose.v2 v2.5.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI=
|
||||
gopkg.in/square/go-jose.v2 v2.6.0 h1:NGk74WTnPKBNUhNzQX7PYcTLUjoq7mzKk2OKbvwk2iI=
|
||||
gopkg.in/square/go-jose.v2 v2.6.0/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI=
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
|
|
21
server/handlers/jwks.go
Normal file
21
server/handlers/jwks.go
Normal file
|
@ -0,0 +1,21 @@
|
|||
package handlers
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/authorizerdev/authorizer/server/constants"
|
||||
"github.com/authorizerdev/authorizer/server/envstore"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
func JWKsHandler() gin.HandlerFunc {
|
||||
var data map[string]string
|
||||
json.Unmarshal([]byte(envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyJWK)), &data)
|
||||
return func(c *gin.Context) {
|
||||
c.JSON(200, gin.H{
|
||||
"keys": []map[string]string{
|
||||
data,
|
||||
},
|
||||
})
|
||||
}
|
||||
}
|
|
@ -1,8 +1,6 @@
|
|||
package handlers
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
|
||||
"github.com/authorizerdev/authorizer/server/constants"
|
||||
|
@ -13,11 +11,6 @@ import (
|
|||
// OpenIDConfigurationHandler handler for open-id configurations
|
||||
func OpenIDConfigurationHandler() gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
if strings.Contains(envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyJwtType), "HS") {
|
||||
c.JSON(400, gin.H{"error": "openid not supported for HSA algorithm"})
|
||||
return
|
||||
}
|
||||
|
||||
issuer := utils.GetHost(c)
|
||||
jwtType := envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyJwtType)
|
||||
|
||||
|
@ -26,7 +19,7 @@ func OpenIDConfigurationHandler() gin.HandlerFunc {
|
|||
"authorization_endpoint": issuer + "/authorize",
|
||||
"token_endpoint": issuer + "/oauth/token",
|
||||
"userinfo_endpoint": issuer + "/userinfo",
|
||||
"jwks_uri": issuer + "/jwks.json",
|
||||
"jwks_uri": issuer + "/.well-known/jwks.json",
|
||||
"response_types_supported": []string{"code", "token", "id_token", "code token", "code id_token", "token id_token", "code token id_token"},
|
||||
"scopes_supported": []string{"openid", "email", "profile", "email_verified", "given_name", "family_name", "nick_name", "picture"},
|
||||
"response_modes_supported": []string{"query", "fragment", "form_post"},
|
||||
|
|
|
@ -22,6 +22,7 @@ func InitRouter() *gin.Engine {
|
|||
router.GET("/verify_email", handlers.VerifyEmailHandler())
|
||||
// OPEN ID routes
|
||||
router.GET("/.well-known/openid-configuration", handlers.OpenIDConfigurationHandler())
|
||||
router.GET("/.well-known/jwks.json", handlers.JWKsHandler())
|
||||
|
||||
router.LoadHTMLGlob("templates/*")
|
||||
// login page app related routes.
|
||||
|
|
|
@ -98,7 +98,7 @@ func CreateAccessToken(user models.User, roles []string) (string, int64, error)
|
|||
claimKey := envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyJwtRoleClaim)
|
||||
customClaims := jwt.MapClaims{
|
||||
"iss": "",
|
||||
"aud": "",
|
||||
"aud": envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyClientID),
|
||||
"nonce": "",
|
||||
"sub": user.ID,
|
||||
"exp": expiresAt,
|
||||
|
|
Loading…
Reference in New Issue
Block a user