edit README.md

add NOTICE file
Naming of repair methods
This commit is contained in:
xsl
2023-06-05 11:16:23 +08:00
parent 1a14757e21
commit d6cf6be6d4
16 changed files with 106 additions and 190 deletions

10
NOTICE Normal file
View File

@@ -0,0 +1,10 @@
xslasd/x-oidc
Copyright 2023 xslasd
This product includes software developed by the Apache Software Foundation (http://www.apache.org/).
This product includes software developed by go-jose (github.com/go-jose/go-jose/v3).
This product includes software developed by google/uuid (github.com/google/uuid).
This project referred to the redesign and implementation of interface functions for zitadel/oidc.
The above code files or parts of them are licensed under the Apache 2.0 License and are subject to the terms and conditions of the Apache 2.0 License.

View File

@@ -21,12 +21,14 @@ op.go definition and implementation of an OIDC OpenID Provider (server)
## Third-party Library ## Third-party Library
The library primarily depends on the third-party library "go-jose/v3". The library primarily depends on the third-party library "go-jose/v3".
The HTTP processing section uses an interface-based approach (with net/http being the default), which can be extended as needed. The HTTP processing section uses an interface-based approach , which can be extended as needed.
When starting OP, implement Config.OpenIDWrapper. By default, github. com/xslass/x-oidc/example/server/httpwrapper can be used. Implementation based on net/HTTP.
``` ```
github.com/go-jose/go-jose/v3 v3.0.0 github.com/go-jose/go-jose/v3 v3.0.0
github.com/google/uuid v1.3.0 github.com/google/uuid v1.3.0
golang.org/x/text v0.9.0 golang.org/x/text v0.9.0
``` ```
Special thanks to [zitadel/oidc](https://github.com/zitadel/oidc). This project referred to the redesign and implementation of interface functions for zitadel/oidc.
## Contributors ## Contributors
<a href="https://github.com/xslasd/x-oidc/graphs/contributors"> <a href="https://github.com/xslasd/x-oidc/graphs/contributors">

View File

@@ -1,13 +1,13 @@
package oidc package oidc
import ( import (
"github.com/xslasd/x-oidc/crypto"
"github.com/xslasd/x-oidc/storage" "github.com/xslasd/x-oidc/storage"
"github.com/xslasd/x-oidc/util"
) )
type Config struct { type Config struct {
Issuer string Issuer string
Crypto crypto.JWTCertifier Crypto util.JWTCertifier
Handler OpenIDHandler OpenIDWrapper OpenIDWrapper
Storage storage.IStorage Storage storage.IStorage
} }

View File

@@ -1,69 +0,0 @@
package crypto
import (
"crypto/aes"
"crypto/cipher"
"crypto/rand"
"encoding/base64"
"errors"
"io"
)
var ErrCipherTextBlockSize = errors.New("ciphertext block size is too short")
func EncryptAES(data string, key string) (string, error) {
encrypted, err := EncryptBytesAES([]byte(data), key)
if err != nil {
return "", err
}
return base64.RawURLEncoding.EncodeToString(encrypted), nil
}
func EncryptBytesAES(plainText []byte, key string) ([]byte, error) {
block, err := aes.NewCipher([]byte(key))
if err != nil {
return nil, err
}
cipherText := make([]byte, aes.BlockSize+len(plainText))
iv := cipherText[:aes.BlockSize]
if _, err = io.ReadFull(rand.Reader, iv); err != nil {
return nil, err
}
stream := cipher.NewCFBEncrypter(block, iv)
stream.XORKeyStream(cipherText[aes.BlockSize:], plainText)
return cipherText, nil
}
func DecryptAES(data string, key string) (string, error) {
text, err := base64.RawURLEncoding.DecodeString(data)
if err != nil {
return "", err
}
decrypted, err := DecryptBytesAES(text, key)
if err != nil {
return "", err
}
return string(decrypted), nil
}
func DecryptBytesAES(cipherText []byte, key string) ([]byte, error) {
block, err := aes.NewCipher([]byte(key))
if err != nil {
return nil, err
}
if len(cipherText) < aes.BlockSize {
return nil, ErrCipherTextBlockSize
}
iv := cipherText[:aes.BlockSize]
cipherText = cipherText[aes.BlockSize:]
stream := cipher.NewCFBDecrypter(block, iv)
stream.XORKeyStream(cipherText, cipherText)
return cipherText, err
}

View File

@@ -1,44 +0,0 @@
package crypto
import (
"crypto/sha256"
"crypto/sha512"
"encoding/base64"
"errors"
"fmt"
"github.com/go-jose/go-jose/v3"
"hash"
)
var ErrUnsupportedAlgorithm = errors.New("unsupported signing algorithm")
func GetHashAlgorithm(sigAlgorithm jose.SignatureAlgorithm) (hash.Hash, error) {
switch sigAlgorithm {
case jose.RS256, jose.ES256, jose.PS256, jose.HS256:
return sha256.New(), nil
case jose.RS384, jose.ES384, jose.PS384, jose.HS384:
return sha512.New384(), nil
case jose.RS512, jose.ES512, jose.PS512, jose.HS512:
return sha512.New(), nil
default:
return nil, fmt.Errorf("%w: %q", ErrUnsupportedAlgorithm, sigAlgorithm)
}
}
func ClaimHash(claim string, sigAlgorithm jose.SignatureAlgorithm) (string, error) {
hash, err := GetHashAlgorithm(sigAlgorithm)
if err != nil {
return "", err
}
return HashString(hash, claim, true), nil
}
func HashString(hash hash.Hash, s string, firstHalf bool) string {
hash.Write([]byte(s))
size := hash.Size()
if firstHalf {
size = size / 2
}
sum := hash.Sum(nil)[:size]
return base64.RawURLEncoding.EncodeToString(sum)
}

View File

@@ -53,6 +53,7 @@ var (
UnauthorizedClientGrantType = New(1031, UnsupportedGrantTypeErrorType, "The grantType '%s' unsupported", "") UnauthorizedClientGrantType = New(1031, UnsupportedGrantTypeErrorType, "The grantType '%s' unsupported", "")
AuthReqNotDone = New(1032, InvalidRequestErrorType, "Unfortunately, the user may be not logged in and/or additional interaction is required.", "") AuthReqNotDone = New(1032, InvalidRequestErrorType, "Unfortunately, the user may be not logged in and/or additional interaction is required.", "")
PublicKeyInvalid = New(1050, ServerErrorErrorType, "failed to decode PEM block containing public key", "") PublicKeyInvalid = New(1050, ServerErrorErrorType, "failed to decode PEM block containing public key", "")
PrivateKeyInvalid = New(1051, ServerErrorErrorType, "failed to decode PEM block containing private key", "") PrivateKeyInvalid = New(1051, ServerErrorErrorType, "failed to decode PEM block containing private key", "")
AlgorithmUnsupported = New(1052, ServerErrorErrorType, "unsupported jose signing algorithm: %s", "")
) )

View File

@@ -1,4 +1,4 @@
package handler package httpwrapper
import ( import (
"context" "context"
@@ -15,20 +15,20 @@ import (
"time" "time"
) )
type HttpHandler struct { type HttpWrapper struct {
handler *http.ServeMux handler *http.ServeMux
addr string addr string
logger log.Logger logger log.Logger
} }
func NewHttpHandler(addr string) *HttpHandler { func NewHttpHandler(addr string) *HttpWrapper {
return &HttpHandler{handler: http.DefaultServeMux, addr: addr} return &HttpWrapper{handler: http.DefaultServeMux, addr: addr}
} }
func (h *HttpHandler) SetLogger(logger log.Logger) { func (h *HttpWrapper) SetLogger(logger log.Logger) {
h.logger = logger h.logger = logger
} }
func (h *HttpHandler) ListenAndServe() error { func (h *HttpWrapper) ListenAndServe() error {
h.login() h.login()
var err error var err error
srv := &http.Server{ srv := &http.Server{
@@ -60,7 +60,7 @@ func (h *HttpHandler) ListenAndServe() error {
} }
} }
func (h *HttpHandler) DiscoveryJWKs(jwksEndpoint string, handler func() (*jose.JSONWebKeySet, error)) { func (h *HttpWrapper) DiscoveryJWKs(jwksEndpoint string, handler func() (*jose.JSONWebKeySet, error)) {
h.handler.HandleFunc(jwksEndpoint, func(w http.ResponseWriter, r *http.Request) { h.handler.HandleFunc(jwksEndpoint, func(w http.ResponseWriter, r *http.Request) {
data, err := handler() data, err := handler()
if err != nil { if err != nil {
@@ -74,7 +74,7 @@ func (h *HttpHandler) DiscoveryJWKs(jwksEndpoint string, handler func() (*jose.J
}) })
} }
func (h *HttpHandler) DiscoveryConfig(discoveryEndpoint string, handler func(req *x_oidc.DiscoveryConfigReq) *model.DiscoveryConfiguration) { func (h *HttpWrapper) DiscoveryConfig(discoveryEndpoint string, handler func(req *x_oidc.DiscoveryConfigReq) *model.DiscoveryConfiguration) {
h.handler.HandleFunc(discoveryEndpoint, func(w http.ResponseWriter, r *http.Request) { h.handler.HandleFunc(discoveryEndpoint, func(w http.ResponseWriter, r *http.Request) {
data := handler(&x_oidc.DiscoveryConfigReq{ data := handler(&x_oidc.DiscoveryConfigReq{
RegistrationEndpoint: "", RegistrationEndpoint: "",
@@ -88,7 +88,7 @@ func (h *HttpHandler) DiscoveryConfig(discoveryEndpoint string, handler func(req
}) })
} }
func (h *HttpHandler) Authorize(authorizationEndpoint string, handler func(ctx context.Context, req *x_oidc.AuthRequestReq) (string, error)) { func (h *HttpWrapper) Authorize(authorizationEndpoint string, handler func(ctx context.Context, req *x_oidc.AuthRequestReq) (string, error)) {
h.handler.HandleFunc(authorizationEndpoint, func(w http.ResponseWriter, r *http.Request) { h.handler.HandleFunc(authorizationEndpoint, func(w http.ResponseWriter, r *http.Request) {
var authRequestReq x_oidc.AuthRequestReq var authRequestReq x_oidc.AuthRequestReq
if r.Method == "GET" { if r.Method == "GET" {
@@ -136,7 +136,7 @@ func (h *HttpHandler) Authorize(authorizationEndpoint string, handler func(ctx c
}) })
} }
func (h *HttpHandler) EndSession(endSessionEndpoint string, handler func(ctx context.Context, req *x_oidc.EndSessionReq) (string, error)) { func (h *HttpWrapper) EndSession(endSessionEndpoint string, handler func(ctx context.Context, req *x_oidc.EndSessionReq) (string, error)) {
h.handler.HandleFunc(endSessionEndpoint, func(w http.ResponseWriter, r *http.Request) { h.handler.HandleFunc(endSessionEndpoint, func(w http.ResponseWriter, r *http.Request) {
var endSessionReq x_oidc.EndSessionReq var endSessionReq x_oidc.EndSessionReq
r.ParseForm() r.ParseForm()
@@ -168,7 +168,7 @@ func (h *HttpHandler) EndSession(endSessionEndpoint string, handler func(ctx con
}) })
} }
func (h *HttpHandler) Introspect(introspectionEndpoint string, handler func(ctx context.Context, req *x_oidc.IntrospectionReq, r *http.Request) (*model.IntrospectionModel, error)) { func (h *HttpWrapper) Introspect(introspectionEndpoint string, handler func(ctx context.Context, req *x_oidc.IntrospectionReq, r *http.Request) (*model.IntrospectionModel, error)) {
h.handler.HandleFunc(introspectionEndpoint, func(w http.ResponseWriter, r *http.Request) { h.handler.HandleFunc(introspectionEndpoint, func(w http.ResponseWriter, r *http.Request) {
var introspectionReq x_oidc.IntrospectionReq var introspectionReq x_oidc.IntrospectionReq
r.ParseForm() r.ParseForm()
@@ -207,7 +207,7 @@ func (h *HttpHandler) Introspect(introspectionEndpoint string, handler func(ctx
}) })
} }
func (h *HttpHandler) RevokeToken(revocationEndpoint string, handler func(ctx context.Context, req *x_oidc.RevokeTokenReq, r *http.Request) error) { func (h *HttpWrapper) RevokeToken(revocationEndpoint string, handler func(ctx context.Context, req *x_oidc.RevokeTokenReq, r *http.Request) error) {
h.handler.HandleFunc(revocationEndpoint, func(w http.ResponseWriter, r *http.Request) { h.handler.HandleFunc(revocationEndpoint, func(w http.ResponseWriter, r *http.Request) {
var revokeTokenReq x_oidc.RevokeTokenReq var revokeTokenReq x_oidc.RevokeTokenReq
r.ParseForm() r.ParseForm()
@@ -246,7 +246,7 @@ func (h *HttpHandler) RevokeToken(revocationEndpoint string, handler func(ctx co
}) })
} }
func (h *HttpHandler) TokenExchange(tokenExchangeEndpoint string, handler func(ctx context.Context, req *x_oidc.TokenExchangeReq, r *http.Request) (interface{}, error)) { func (h *HttpWrapper) TokenExchange(tokenExchangeEndpoint string, handler func(ctx context.Context, req *x_oidc.TokenExchangeReq, r *http.Request) (interface{}, error)) {
h.handler.HandleFunc(tokenExchangeEndpoint, func(w http.ResponseWriter, r *http.Request) { h.handler.HandleFunc(tokenExchangeEndpoint, func(w http.ResponseWriter, r *http.Request) {
var tokenExchangeReq x_oidc.TokenExchangeReq var tokenExchangeReq x_oidc.TokenExchangeReq
r.ParseForm() r.ParseForm()
@@ -315,7 +315,7 @@ func (h *HttpHandler) TokenExchange(tokenExchangeEndpoint string, handler func(c
}) })
} }
func (h *HttpHandler) Userinfo(userinfoEndpoint string, handler func(ctx context.Context, req *x_oidc.UserinfoReq, r *http.Request) (*model.UserInfo, error)) { func (h *HttpWrapper) Userinfo(userinfoEndpoint string, handler func(ctx context.Context, req *x_oidc.UserinfoReq, r *http.Request) (*model.UserInfo, error)) {
h.handler.HandleFunc(userinfoEndpoint, func(w http.ResponseWriter, r *http.Request) { h.handler.HandleFunc(userinfoEndpoint, func(w http.ResponseWriter, r *http.Request) {
var userinfoReq x_oidc.UserinfoReq var userinfoReq x_oidc.UserinfoReq
r.ParseForm() r.ParseForm()
@@ -340,7 +340,7 @@ func (h *HttpHandler) Userinfo(userinfoEndpoint string, handler func(ctx context
}) })
} }
func (h *HttpHandler) AuthorizeCallback(authorizeCallbackEndpoint string, handler func(ctx context.Context, req *x_oidc.AuthorizeCallbackReq) (callbackUrl string, err error)) { func (h *HttpWrapper) AuthorizeCallback(authorizeCallbackEndpoint string, handler func(ctx context.Context, req *x_oidc.AuthorizeCallbackReq) (callbackUrl string, err error)) {
h.handler.HandleFunc(authorizeCallbackEndpoint, func(w http.ResponseWriter, r *http.Request) { h.handler.HandleFunc(authorizeCallbackEndpoint, func(w http.ResponseWriter, r *http.Request) {
var authorizeCallbackReq x_oidc.AuthorizeCallbackReq var authorizeCallbackReq x_oidc.AuthorizeCallbackReq

View File

@@ -1,4 +1,4 @@
package handler package httpwrapper
import ( import (
"embed" "embed"
@@ -13,7 +13,7 @@ var (
templates = template.Must(template.ParseFS(templateFS, "templates/*.html")) templates = template.Must(template.ParseFS(templateFS, "templates/*.html"))
) )
func (h *HttpHandler) login() { func (h *HttpWrapper) login() {
h.handler.HandleFunc("/login", func(w http.ResponseWriter, r *http.Request) { h.handler.HandleFunc("/login", func(w http.ResponseWriter, r *http.Request) {
err := r.ParseForm() err := r.ParseForm()
if err != nil { if err != nil {
@@ -22,8 +22,7 @@ func (h *HttpHandler) login() {
} }
if r.Method == "GET" { if r.Method == "GET" {
templates.ExecuteTemplate(w, "login", map[string]string{ templates.ExecuteTemplate(w, "login", map[string]string{
"ID": r.Form.Get("request_id"), "ID": r.Form.Get("request_id"),
"Error": "",
}) })
} }
}) })

View File

@@ -0,0 +1,23 @@
{{ define "login" -}}
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Login</title>
</head>
<body style="display: flex; align-items: center; justify-content: center; height: 100vh;">
<form method="POST" action="/callback" style="height: 200px; width: 400px;">
<input type="hidden" name="id" value="{{.ID}}">
<div>
<label for="username">Username:</label>
<input id="username" name="username" style="width: 100%;height: 40px">
</div>
<div>
<label for="password">Password:(Correct password:test)</label>
<input id="password" type="password" name="password" style="width: 100%;height: 40px">
</div>
<button type="submit">Login</button>
</form>
</body>
</html>`
{{- end }}

View File

@@ -3,23 +3,23 @@ package main
import ( import (
"github.com/go-jose/go-jose/v3" "github.com/go-jose/go-jose/v3"
x_oidc "github.com/xslasd/x-oidc" x_oidc "github.com/xslasd/x-oidc"
"github.com/xslasd/x-oidc/crypto" "github.com/xslasd/x-oidc/example/server/httpwrapper"
"github.com/xslasd/x-oidc/example/server/handler"
"github.com/xslasd/x-oidc/example/server/storage" "github.com/xslasd/x-oidc/example/server/storage"
"github.com/xslasd/x-oidc/util"
) )
func main() { func main() {
httpHandler := handler.NewHttpHandler(":8080") httpHandler := httpwrapper.NewHttpHandler(":8080")
cr, err := crypto.NewJoseRSAJWT("private.pem", jose.RS256) cr, err := util.NewJoseRSAJWT("private.pem", jose.RS256)
if err != nil { if err != nil {
panic(err) panic(err)
} }
_, err = x_oidc.NewOpenIDProvider( _, err = x_oidc.NewOpenIDProvider(
&x_oidc.Config{ &x_oidc.Config{
Issuer: "http://localhost:8080", Issuer: "http://localhost:8080",
Handler: httpHandler, OpenIDWrapper: httpHandler,
Storage: storage.NewStorage(), Storage: storage.NewStorage(),
Crypto: cr, Crypto: cr,
}, },
x_oidc.WithAllowInsecure(true), x_oidc.WithAllowInsecure(true),
) )

View File

@@ -79,7 +79,7 @@ func (t *TokenClaims) CheckAuthorizationContextClassReference(acr string) error
type JWTClientTokenClaims struct { type JWTClientTokenClaims struct {
Issuer string `json:"iss"` Issuer string `json:"iss"`
Subject string `json:"sub"` Subject string `json:"sub"`
Audience []string `json:"aud"` //todo array or string Audience Audience `json:"aud"`
IssuedAt int64 `json:"iat"` IssuedAt int64 `json:"iat"`
ExpiresAt int64 `json:"exp"` ExpiresAt int64 `json:"exp"`

8
op.go
View File

@@ -17,7 +17,7 @@ type OpenIDProvider struct {
opt *OpenIDOption opt *OpenIDOption
} }
type OpenIDHandler interface { type OpenIDWrapper interface {
SetLogger(logger log.Logger) SetLogger(logger log.Logger)
DiscoveryJWKs(jwksEndpoint string, handler func() (*jose.JSONWebKeySet, error)) DiscoveryJWKs(jwksEndpoint string, handler func() (*jose.JSONWebKeySet, error))
@@ -38,7 +38,7 @@ func NewOpenIDProvider(cfg *Config, opts ...Option) (*OpenIDProvider, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
if cfg.Handler == nil { if cfg.OpenIDWrapper == nil {
return nil, ecode.HandlerIsNull return nil, ecode.HandlerIsNull
} }
if cfg.Storage == nil { if cfg.Storage == nil {
@@ -52,10 +52,10 @@ func NewOpenIDProvider(cfg *Config, opts ...Option) (*OpenIDProvider, error) {
if !opt.allowInsecure && !util.IsHttpsPrefix(cfg.Issuer) { if !opt.allowInsecure && !util.IsHttpsPrefix(cfg.Issuer) {
return nil, ecode.IssuerHTTPSInvalid return nil, ecode.IssuerHTTPSInvalid
} }
handler := srv.cfg.Handler handler := srv.cfg.OpenIDWrapper
srv.printBanner() srv.printBanner()
cfg.Storage.SetLogger(opt.logger) cfg.Storage.SetLogger(opt.logger)
cfg.Handler.SetLogger(opt.logger) cfg.OpenIDWrapper.SetLogger(opt.logger)
handler.DiscoveryJWKs(opt.jwksPath, srv.discoveryJWKs) handler.DiscoveryJWKs(opt.jwksPath, srv.discoveryJWKs)
opt.logger.Infof("JWKsEndpoint -> %s", opt.jwksEndpoint) opt.logger.Infof("JWKsEndpoint -> %s", opt.jwksEndpoint)
handler.DiscoveryConfig(opt.discoveryPath, srv.discoveryConfig) handler.DiscoveryConfig(opt.discoveryPath, srv.discoveryConfig)

View File

@@ -8,7 +8,6 @@ import (
"github.com/go-jose/go-jose/v3" "github.com/go-jose/go-jose/v3"
"github.com/go-jose/go-jose/v3/jwt" "github.com/go-jose/go-jose/v3/jwt"
"github.com/xslasd/x-oidc/constant" "github.com/xslasd/x-oidc/constant"
"github.com/xslasd/x-oidc/crypto"
"github.com/xslasd/x-oidc/ecode" "github.com/xslasd/x-oidc/ecode"
"github.com/xslasd/x-oidc/model" "github.com/xslasd/x-oidc/model"
"github.com/xslasd/x-oidc/util" "github.com/xslasd/x-oidc/util"
@@ -66,7 +65,7 @@ func (o OIDCClient) GenerateCodeChallenge(CodeChallengeMethod string) string {
return util.RandomString(43) return util.RandomString(43)
case constant.CodeChallengeMethodS256: case constant.CodeChallengeMethodS256:
codeChallenge := util.RandomString(43) codeChallenge := util.RandomString(43)
return crypto.HashString(sha256.New(), codeChallenge, false) return util.HashString(sha256.New(), codeChallenge, false)
} }
return "" return ""
} }

View File

@@ -6,9 +6,9 @@ import (
"fmt" "fmt"
"github.com/go-jose/go-jose/v3" "github.com/go-jose/go-jose/v3"
"github.com/xslasd/x-oidc/constant" "github.com/xslasd/x-oidc/constant"
"github.com/xslasd/x-oidc/crypto"
"github.com/xslasd/x-oidc/ecode" "github.com/xslasd/x-oidc/ecode"
"github.com/xslasd/x-oidc/storage" "github.com/xslasd/x-oidc/storage"
"github.com/xslasd/x-oidc/util"
"net/http" "net/http"
"net/url" "net/url"
"strings" "strings"
@@ -136,8 +136,7 @@ func authorizeCodeChallenge(req *TokenExchangeReq, authReq *storage.AuthRequest)
} }
switch authReq.CodeChallengeMethod { switch authReq.CodeChallengeMethod {
case constant.CodeChallengeMethodS256: case constant.CodeChallengeMethodS256:
req.CodeVerifier = crypto.HashString(sha256.New(), req.CodeVerifier, false) req.CodeVerifier = util.HashString(sha256.New(), req.CodeVerifier, false)
default:
} }
if req.CodeVerifier != authReq.CodeChallenge { if req.CodeVerifier != authReq.CodeChallenge {
fmt.Println("debug: CodeChallengeInvalid") fmt.Println("debug: CodeChallengeInvalid")

View File

@@ -24,17 +24,3 @@ func ValidateIssuer(issuer string) error {
func IsHttpsPrefix(issuer string) bool { func IsHttpsPrefix(issuer string) bool {
return strings.HasPrefix(issuer, constant.HttpsPrefix) return strings.HasPrefix(issuer, constant.HttpsPrefix)
} }
func GetQueryString(queryMap map[string]string) string {
if queryMap == nil || len(queryMap) == 0 {
return ""
}
queryValue := url.Values{}
for key, value := range queryMap {
if value == "" {
continue
}
queryValue.Add(key, value)
}
return queryValue.Encode()
}

View File

@@ -1,9 +1,12 @@
package crypto package util
import ( import (
"crypto/rand" "crypto/rand"
"crypto/rsa" "crypto/rsa"
"crypto/sha256"
"crypto/sha512"
"crypto/x509" "crypto/x509"
"encoding/base64"
"encoding/hex" "encoding/hex"
"encoding/pem" "encoding/pem"
"fmt" "fmt"
@@ -11,6 +14,7 @@ import (
"github.com/go-jose/go-jose/v3/jwt" "github.com/go-jose/go-jose/v3/jwt"
"github.com/google/uuid" "github.com/google/uuid"
"github.com/xslasd/x-oidc/ecode" "github.com/xslasd/x-oidc/ecode"
"hash"
"os" "os"
) )
@@ -132,7 +136,6 @@ func (j JoseRSAJWT) ParseJWT(token string, payload interface{}) error {
//} //}
// //
//func (j JoseHMACJWT) GenerateJWT(claims interface{}) (string, error) { //func (j JoseHMACJWT) GenerateJWT(claims interface{}) (string, error) {
// // 创建一个 JWT 签名者
// signer, err := jose.NewSigner(jose.SigningKey{Algorithm: jose.HS256, Key: j.signingKey}, nil) // signer, err := jose.NewSigner(jose.SigningKey{Algorithm: jose.HS256, Key: j.signingKey}, nil)
// if err != nil { // if err != nil {
// fmt.Println("Error creating signer:", err) // fmt.Println("Error creating signer:", err)
@@ -161,19 +164,26 @@ func (j JoseRSAJWT) ParseJWT(token string, payload interface{}) error {
// err = json.Unmarshal(b, payload) // err = json.Unmarshal(b, payload)
// return err // return err
//} //}
//
//func Sign(object interface{}, signingKey jose.SigningKey) (string, error) { func GetHashAlgorithm(sigAlgorithm jose.SignatureAlgorithm) (hash.Hash, error) {
// signer, err := jose.NewSigner(signingKey, &jose.SignerOptions{}) switch sigAlgorithm {
// if err != nil { case jose.RS256, jose.ES256, jose.PS256, jose.HS256:
// return "", err return sha256.New(), nil
// } case jose.RS384, jose.ES384, jose.PS384, jose.HS384:
// payload, err := json.Marshal(object) return sha512.New384(), nil
// if err != nil { case jose.RS512, jose.ES512, jose.PS512, jose.HS512:
// return "", err return sha512.New(), nil
// } default:
// result, err := signer.Sign(payload) return nil, ecode.AlgorithmUnsupported.SetDescriptionf(string(sigAlgorithm))
// if err != nil { }
// return "", err }
// }
// return result.CompactSerialize() func HashString(hash hash.Hash, s string, firstHalf bool) string {
//} hash.Write([]byte(s))
size := hash.Size()
if firstHalf {
size = size / 2
}
sum := hash.Sum(nil)[:size]
return base64.RawURLEncoding.EncodeToString(sum)
}