feat: service account token exchange

This commit is contained in:
adlerhurst 2020-09-02 17:52:22 +02:00
parent c828290ef1
commit 7a109a763d
7 changed files with 71 additions and 10 deletions

View file

@ -273,6 +273,11 @@ func (p *DefaultOP) Signer() Signer {
func (p *DefaultOP) Crypto() Crypto {
return p.crypto
}
func (p *DefaultOP) Verifier() rp.Verifier {
return p.verifier
}
func (p *DefaultOP) HandleReady(w http.ResponseWriter, r *http.Request) {
probes := []ProbesFn{
ReadySigner(p.Signer()),
@ -299,9 +304,13 @@ func (p *DefaultOP) HandleExchange(w http.ResponseWriter, r *http.Request) {
RequestError(w, r, ErrInvalidRequest("grant_type missing"))
return
}
if reqType == string(oidc.GrantTypeCode) {
switch reqType {
case string(oidc.GrantTypeCode):
CodeExchange(w, r, p)
return
case string(oidc.GrantTypeBearer):
JWTExchange(w, r, p)
return
}
TokenExchange(w, r, p)
}

View file

@ -3,11 +3,13 @@ package op
import (
"context"
"errors"
"fmt"
"net/http"
"github.com/gorilla/schema"
"github.com/caos/oidc/pkg/oidc"
"github.com/caos/oidc/pkg/rp"
"github.com/caos/oidc/pkg/utils"
)
@ -20,6 +22,11 @@ type Exchanger interface {
AuthMethodPostSupported() bool
}
type VerifyExchanger interface {
Exchanger
Verifier() rp.Verifier
}
func CodeExchange(w http.ResponseWriter, r *http.Request, exchanger Exchanger) {
tokenReq, err := ParseAccessTokenRequest(r, exchanger.Decoder())
if err != nil {
@ -116,6 +123,33 @@ func AuthorizeCodeChallenge(ctx context.Context, tokenReq *oidc.AccessTokenReque
return authReq, nil
}
func JWTExchange(w http.ResponseWriter, r *http.Request, exchanger VerifyExchanger) {
assertion, err := ParseJWTTokenRequest(r, exchanger.Decoder())
if err != nil {
RequestError(w, r, err)
}
claims, err := exchanger.Verifier().Verify(r.Context(), "", assertion)
fmt.Println(claims, err)
_ = assertion
}
func ParseJWTTokenRequest(r *http.Request, decoder *schema.Decoder) (string, error) {
err := r.ParseForm()
if err != nil {
return "", ErrInvalidRequest("error parsing form")
}
tokenReq := new(struct {
Token string `schema:"assertion"`
})
err = decoder.Decode(tokenReq, r.Form)
if err != nil {
return "", ErrInvalidRequest("error decoding form")
}
//TODO: validations
return tokenReq.Token, nil
}
func TokenExchange(w http.ResponseWriter, r *http.Request, exchanger Exchanger) {
tokenRequest, err := ParseTokenExchangeRequest(w, r)
if err != nil {