Use a single library for JWTs

Signed-off-by: ItalyPaleAle <43508+ItalyPaleAle@users.noreply.github.com>
This commit is contained in:
ItalyPaleAle 2023-02-15 19:35:53 +00:00
parent 210c8c3c59
commit 052618ddcb
4 changed files with 73 additions and 36 deletions

View File

@ -121,9 +121,14 @@ linters-settings:
packages-with-error-message: packages-with-error-message:
- "github.com/Sirupsen/logrus": "must use github.com/dapr/kit/logger" - "github.com/Sirupsen/logrus": "must use github.com/dapr/kit/logger"
- "github.com/agrea/ptr": "must use github.com/dapr/kit/ptr" - "github.com/agrea/ptr": "must use github.com/dapr/kit/ptr"
- "github.com/cenkalti/backoff": "must use github.com/cenkalti/backoff/v4" - "github.com/cenkalti/backoff$": "must use github.com/cenkalti/backoff/v4"
- "github.com/cenkalti/backoff/v2": "must use github.com/cenkalti/backoff/v4" - "github.com/cenkalti/backoff/v2": "must use github.com/cenkalti/backoff/v4"
- "github.com/cenkalti/backoff/v3": "must use github.com/cenkalti/backoff/v4" - "github.com/cenkalti/backoff/v3": "must use github.com/cenkalti/backoff/v4"
- "github.com/dgrijalva/jwt-go": "must use github.com/lestrrat-go/jwx/v2"
- "github.com/golang-jwt/jwt$": "must use github.com/lestrrat-go/jwx/v2"
- "github.com/golang-jwt/jwt/v4": "must use github.com/lestrrat-go/jwx/v2"
- "github.com/lestrrat-go/jwx/jwa": "must use github.com/lestrrat-go/jwx/v2"
- "github.com/lestrrat-go/jwx/jwt": "must use github.com/lestrrat-go/jwx/v2"
misspell: misspell:
# Correct spellings using locale preferences for US or UK. # Correct spellings using locale preferences for US or UK.
# Default is to use a neutral variety of English. # Default is to use a neutral variety of English.

View File

@ -14,10 +14,15 @@ limitations under the License.
package apns package apns
import ( import (
"crypto"
"errors"
"fmt"
"sync" "sync"
"time" "time"
jwt "github.com/golang-jwt/jwt/v4" "github.com/lestrrat-go/jwx/v2/jwa"
"github.com/lestrrat-go/jwx/v2/jwk"
"github.com/lestrrat-go/jwx/v2/jwt"
"github.com/dapr/kit/logger" "github.com/dapr/kit/logger"
) )
@ -35,7 +40,26 @@ type authorizationBuilder struct {
tokenExpiresAt time.Time tokenExpiresAt time.Time
keyID string keyID string
teamID string teamID string
privateKey interface{} privateKey crypto.PrivateKey
pk jwk.Key
}
func (a *authorizationBuilder) setPK() error {
if a.privateKey == nil {
return errors.New("privateKey property is nil")
}
if a.keyID == "" {
return errors.New("keyID property is nil")
}
pk, err := jwk.FromRaw(a.privateKey)
if err != nil {
return fmt.Errorf("failed to parse private key: %w", err)
}
pk.Set("kid", a.keyID)
a.pk = pk
return nil
} }
func (a *authorizationBuilder) getAuthorizationHeader() (string, error) { func (a *authorizationBuilder) getAuthorizationHeader() (string, error) {
@ -64,20 +88,28 @@ func (a *authorizationBuilder) generateAuthorizationHeader() (string, error) {
a.logger.Debug("Authorization token expired; generating new token") a.logger.Debug("Authorization token expired; generating new token")
now := time.Now() var err error
// TODO: Use jwt.RegisteredClaims instead of jwt.StandardClaims. if a.pk == nil {
claims := jwt.StandardClaims{ //nolint:staticcheck err = a.setPK()
IssuedAt: time.Now().Unix(), if err != nil {
Issuer: a.teamID, return "", err
} }
token := jwt.NewWithClaims(jwt.SigningMethodES256, claims)
token.Header["kid"] = a.keyID
signedToken, err := token.SignedString(a.privateKey)
if err != nil {
return "", err
} }
a.authorizationHeader = "bearer " + signedToken now := time.Now()
token, err := jwt.NewBuilder().
Issuer(a.teamID).
IssuedAt(now).
Build()
if err != nil {
return "", fmt.Errorf("failed to build token: %w", err)
}
signed, err := jwt.Sign(token, jwt.WithKey(jwa.ES256, a.pk))
if err != nil {
return "", fmt.Errorf("failed to sign token: %w", err)
}
a.authorizationHeader = "bearer " + string(signed)
a.tokenExpiresAt = now.Add(expirationMinutes) a.tokenExpiresAt = now.Add(expirationMinutes)
return a.authorizationHeader, nil return a.authorizationHeader, nil

View File

@ -24,7 +24,8 @@ import (
"github.com/Azure/azure-sdk-for-go/sdk/azcore" "github.com/Azure/azure-sdk-for-go/sdk/azcore"
"github.com/Azure/azure-sdk-for-go/sdk/azcore/policy" "github.com/Azure/azure-sdk-for-go/sdk/azcore/policy"
jwt "github.com/golang-jwt/jwt/v4" "github.com/lestrrat-go/jwx/v2/jwa"
"github.com/lestrrat-go/jwx/v2/jwt"
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/dapr/components-contrib/bindings" "github.com/dapr/components-contrib/bindings"
@ -251,7 +252,9 @@ func (s *SignalR) Invoke(ctx context.Context, req *bindings.InvokeRequest) (*bin
} }
// Returns an access token for a request to the given URL // Returns an access token for a request to the given URL
func (s *SignalR) getToken(ctx context.Context, url string) (token string, err error) { func (s *SignalR) getToken(ctx context.Context, url string) (string, error) {
var err error
// If we have an Azure AD token provider, use that first // If we have an Azure AD token provider, use that first
if s.aadToken != nil { if s.aadToken != nil {
var at azcore.AccessToken var at azcore.AccessToken
@ -261,24 +264,21 @@ func (s *SignalR) getToken(ctx context.Context, url string) (token string, err e
if err != nil { if err != nil {
return "", err return "", err
} }
token = at.Token return at.Token, nil
} else {
// TODO: Use jwt.RegisteredClaims instead
claims := &jwt.StandardClaims{ //nolint:staticcheck
ExpiresAt: time.Now().Add(15 * time.Minute).Unix(),
Audience: url,
}
err = claims.Valid()
if err != nil {
return "", err
}
jwtToken := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
token, err = jwtToken.SignedString([]byte(s.accessKey))
if err != nil {
return "", err
}
} }
return token, nil now := time.Now()
token, err := jwt.NewBuilder().
Audience([]string{url}).
Expiration(now.Add(15 * time.Minute)).
Build()
if err != nil {
return "", fmt.Errorf("failed to build token: %w", err)
}
signed, err := jwt.Sign(token, jwt.WithKey(jwa.HS256, s.accessKey))
if err != nil {
return "", fmt.Errorf("failed to sign token: %w", err)
}
return string(signed), nil
} }

2
go.mod
View File

@ -61,7 +61,6 @@ require (
github.com/go-redis/redis/v9 v9.0.0-rc.2 github.com/go-redis/redis/v9 v9.0.0-rc.2
github.com/go-sql-driver/mysql v1.7.0 github.com/go-sql-driver/mysql v1.7.0
github.com/gocql/gocql v1.3.1 github.com/gocql/gocql v1.3.1
github.com/golang-jwt/jwt/v4 v4.4.3
github.com/golang/mock v1.6.0 github.com/golang/mock v1.6.0
github.com/google/uuid v1.3.0 github.com/google/uuid v1.3.0
github.com/googleapis/gax-go/v2 v2.7.0 github.com/googleapis/gax-go/v2 v2.7.0
@ -225,6 +224,7 @@ require (
github.com/gogo/protobuf v1.3.2 // indirect github.com/gogo/protobuf v1.3.2 // indirect
github.com/gogo/status v1.1.1 // indirect github.com/gogo/status v1.1.1 // indirect
github.com/golang-jwt/jwt v3.2.2+incompatible // indirect github.com/golang-jwt/jwt v3.2.2+incompatible // indirect
github.com/golang-jwt/jwt/v4 v4.4.3 // indirect
github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe // indirect github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe // indirect
github.com/golang-sql/sqlexp v0.1.0 // indirect github.com/golang-sql/sqlexp v0.1.0 // indirect
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect