zitadel-oidc/pkg/op/token.go
2020-01-31 15:22:16 +01:00

93 lines
2.7 KiB
Go

package op
import (
"time"
"github.com/caos/oidc/pkg/oidc"
)
type TokenCreator interface {
Issuer() string
Signer() Signer
Storage() Storage
Crypto() Crypto
}
func CreateTokenResponse(authReq AuthRequest, client Client, creator TokenCreator, createAccessToken bool, code string) (*oidc.AccessTokenResponse, error) {
var accessToken string
if createAccessToken {
var err error
accessToken, err = CreateAccessToken(authReq, client, creator)
if err != nil {
return nil, err
}
}
idToken, err := CreateIDToken(creator.Issuer(), authReq, client.IDTokenLifetime(), accessToken, code, creator.Signer())
if err != nil {
return nil, err
}
exp := uint64(client.AccessTokenLifetime().Seconds())
return &oidc.AccessTokenResponse{
AccessToken: accessToken,
IDToken: idToken,
TokenType: oidc.BearerToken,
ExpiresIn: exp,
}, nil
}
func CreateAccessToken(authReq AuthRequest, client Client, creator TokenCreator) (string, error) {
if client.AccessTokenType() == AccessTokenTypeJWT {
return CreateJWT(creator.Issuer(), authReq, client, creator.Signer())
}
return CreateBearerToken(authReq, creator.Crypto())
}
func CreateBearerToken(authReq AuthRequest, crypto Crypto) (string, error) {
return crypto.Encrypt(authReq.GetID())
}
func CreateJWT(issuer string, authReq AuthRequest, client Client, signer Signer) (string, error) {
now := time.Now().UTC()
nbf := now
exp := now.Add(client.AccessTokenLifetime())
claims := &oidc.AccessTokenClaims{
Issuer: issuer,
Subject: authReq.GetSubject(),
Audiences: authReq.GetAudience(),
Expiration: exp,
IssuedAt: now,
NotBefore: nbf,
}
return signer.SignAccessToken(claims)
}
func CreateIDToken(issuer string, authReq AuthRequest, validity time.Duration, accessToken, code string, signer Signer) (string, error) {
var err error
exp := time.Now().UTC().Add(validity)
claims := &oidc.IDTokenClaims{
Issuer: issuer,
Subject: authReq.GetSubject(),
Audiences: authReq.GetAudience(),
Expiration: exp,
IssuedAt: time.Now().UTC(),
AuthTime: authReq.GetAuthTime(),
Nonce: authReq.GetNonce(),
AuthenticationContextClassReference: authReq.GetACR(),
AuthenticationMethodsReferences: authReq.GetAMR(),
AuthorizedParty: authReq.GetClientID(),
}
if accessToken != "" {
claims.AccessTokenHash, err = oidc.ClaimHash(accessToken, signer.SignatureAlgorithm())
if err != nil {
return "", err
}
}
if code != "" {
claims.CodeHash, err = oidc.ClaimHash(code, signer.SignatureAlgorithm())
if err != nil {
return "", err
}
}
return signer.SignIDToken(claims)
}