mirror of
https://github.com/casdoor/casdoor.git
synced 2025-07-03 04:10:20 +08:00
feat: add more crypto algorithm for jwt signing (#3150)
* feat: add more algorithm support for JWT signing * feat: add i18n support * feat: add i18n support * feat: optimize if statement * fix: remove additional space line
This commit is contained in:
@ -17,6 +17,7 @@ package object
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/casdoor/casdoor/util"
|
||||
@ -378,36 +379,52 @@ func generateJwtToken(application *Application, user *User, nonce string, scope
|
||||
application.TokenFormat = "JWT"
|
||||
}
|
||||
|
||||
var jwtMethod jwt.SigningMethod
|
||||
|
||||
if application.TokenSigningMethod == "RS256" {
|
||||
jwtMethod = jwt.SigningMethodRS256
|
||||
} else if application.TokenSigningMethod == "RS512" {
|
||||
jwtMethod = jwt.SigningMethodRS512
|
||||
} else if application.TokenSigningMethod == "ES256" {
|
||||
jwtMethod = jwt.SigningMethodES256
|
||||
} else if application.TokenSigningMethod == "ES512" {
|
||||
jwtMethod = jwt.SigningMethodES512
|
||||
} else if application.TokenSigningMethod == "ES384" {
|
||||
jwtMethod = jwt.SigningMethodES384
|
||||
} else {
|
||||
jwtMethod = jwt.SigningMethodRS256
|
||||
}
|
||||
|
||||
// the JWT token length in "JWT-Empty" mode will be very short, as User object only has two properties: owner and name
|
||||
if application.TokenFormat == "JWT" {
|
||||
claimsWithoutThirdIdp := getClaimsWithoutThirdIdp(claims)
|
||||
|
||||
token = jwt.NewWithClaims(jwt.SigningMethodRS256, claimsWithoutThirdIdp)
|
||||
token = jwt.NewWithClaims(jwtMethod, claimsWithoutThirdIdp)
|
||||
claimsWithoutThirdIdp.ExpiresAt = jwt.NewNumericDate(refreshExpireTime)
|
||||
claimsWithoutThirdIdp.TokenType = "refresh-token"
|
||||
refreshToken = jwt.NewWithClaims(jwt.SigningMethodRS256, claimsWithoutThirdIdp)
|
||||
refreshToken = jwt.NewWithClaims(jwtMethod, claimsWithoutThirdIdp)
|
||||
} else if application.TokenFormat == "JWT-Empty" {
|
||||
claimsShort := getShortClaims(claims)
|
||||
|
||||
token = jwt.NewWithClaims(jwt.SigningMethodRS256, claimsShort)
|
||||
token = jwt.NewWithClaims(jwtMethod, claimsShort)
|
||||
claimsShort.ExpiresAt = jwt.NewNumericDate(refreshExpireTime)
|
||||
claimsShort.TokenType = "refresh-token"
|
||||
refreshToken = jwt.NewWithClaims(jwt.SigningMethodRS256, claimsShort)
|
||||
refreshToken = jwt.NewWithClaims(jwtMethod, claimsShort)
|
||||
} else if application.TokenFormat == "JWT-Custom" {
|
||||
claimsCustom := getClaimsCustom(claims, application.TokenFields)
|
||||
|
||||
token = jwt.NewWithClaims(jwt.SigningMethodRS256, claimsCustom)
|
||||
token = jwt.NewWithClaims(jwtMethod, claimsCustom)
|
||||
refreshClaims := getClaimsCustom(claims, application.TokenFields)
|
||||
refreshClaims["exp"] = jwt.NewNumericDate(refreshExpireTime)
|
||||
refreshClaims["TokenType"] = "refresh-token"
|
||||
refreshToken = jwt.NewWithClaims(jwt.SigningMethodRS256, refreshClaims)
|
||||
refreshToken = jwt.NewWithClaims(jwtMethod, refreshClaims)
|
||||
} else if application.TokenFormat == "JWT-Standard" {
|
||||
claimsStandard := getStandardClaims(claims)
|
||||
|
||||
token = jwt.NewWithClaims(jwt.SigningMethodRS256, claimsStandard)
|
||||
token = jwt.NewWithClaims(jwtMethod, claimsStandard)
|
||||
claimsStandard.ExpiresAt = jwt.NewNumericDate(refreshExpireTime)
|
||||
claimsStandard.TokenType = "refresh-token"
|
||||
refreshToken = jwt.NewWithClaims(jwt.SigningMethodRS256, claimsStandard)
|
||||
refreshToken = jwt.NewWithClaims(jwtMethod, claimsStandard)
|
||||
} else {
|
||||
return "", "", "", fmt.Errorf("unknown application TokenFormat: %s", application.TokenFormat)
|
||||
}
|
||||
@ -425,34 +442,57 @@ func generateJwtToken(application *Application, user *User, nonce string, scope
|
||||
}
|
||||
}
|
||||
|
||||
// RSA private key
|
||||
key, err := jwt.ParseRSAPrivateKeyFromPEM([]byte(cert.PrivateKey))
|
||||
var (
|
||||
tokenString string
|
||||
refreshTokenString string
|
||||
key interface{}
|
||||
)
|
||||
|
||||
if strings.Contains(application.TokenSigningMethod, "RS") || application.TokenSigningMethod == "" {
|
||||
// RSA private key
|
||||
key, err = jwt.ParseRSAPrivateKeyFromPEM([]byte(cert.PrivateKey))
|
||||
} else if strings.Contains(application.TokenSigningMethod, "ES") {
|
||||
// ES private key
|
||||
key, err = jwt.ParseECPrivateKeyFromPEM([]byte(cert.PrivateKey))
|
||||
} else if strings.Contains(application.TokenSigningMethod, "Ed") {
|
||||
// Ed private key
|
||||
key, err = jwt.ParseEdPrivateKeyFromPEM([]byte(cert.PrivateKey))
|
||||
}
|
||||
if err != nil {
|
||||
return "", "", "", err
|
||||
}
|
||||
|
||||
token.Header["kid"] = cert.Name
|
||||
tokenString, err := token.SignedString(key)
|
||||
tokenString, err = token.SignedString(key)
|
||||
if err != nil {
|
||||
return "", "", "", err
|
||||
}
|
||||
refreshTokenString, err := refreshToken.SignedString(key)
|
||||
refreshTokenString, err = refreshToken.SignedString(key)
|
||||
|
||||
return tokenString, refreshTokenString, name, err
|
||||
}
|
||||
|
||||
func ParseJwtToken(token string, cert *Cert) (*Claims, error) {
|
||||
t, err := jwt.ParseWithClaims(token, &Claims{}, func(token *jwt.Token) (interface{}, error) {
|
||||
if _, ok := token.Method.(*jwt.SigningMethodRSA); !ok {
|
||||
return nil, fmt.Errorf("unexpected signing method: %v", token.Header["alg"])
|
||||
}
|
||||
var (
|
||||
certificate interface{}
|
||||
err error
|
||||
)
|
||||
|
||||
if cert.Certificate == "" {
|
||||
return nil, fmt.Errorf("the certificate field should not be empty for the cert: %v", cert)
|
||||
}
|
||||
|
||||
// RSA certificate
|
||||
certificate, err := jwt.ParseRSAPublicKeyFromPEM([]byte(cert.Certificate))
|
||||
if _, ok := token.Method.(*jwt.SigningMethodRSA); ok {
|
||||
// RSA certificate
|
||||
certificate, err = jwt.ParseRSAPublicKeyFromPEM([]byte(cert.Certificate))
|
||||
} else if _, ok := token.Method.(*jwt.SigningMethodECDSA); ok {
|
||||
// ES certificate
|
||||
certificate, err = jwt.ParseECPublicKeyFromPEM([]byte(cert.Certificate))
|
||||
} else {
|
||||
return nil, fmt.Errorf("unexpected signing method: %v", token.Header["alg"])
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
Reference in New Issue
Block a user