feat: Token Exchange (RFC 8693) (#255)

This change implements OAuth2 Token Exchange in OP according to RFC 8693 (and client code)

Some implementation details:

- OP parses and verifies subject/actor tokens natively if they were issued by OP
- Third-party tokens verification is also possible by implementing additional storage interface
- Token exchange can issue only OP's native tokens (id_token, access_token and refresh_token) with static issuer
This commit is contained in:
Emil Bektimirov 2023-02-19 14:57:46 +01:00 committed by GitHub
parent 9291ca9908
commit 8e298791d7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
16 changed files with 961 additions and 59 deletions

View file

@ -90,6 +90,9 @@ func CallEndSessionEndpoint(request interface{}, authFn interface{}, caller EndS
return http.ErrUseLastResponse
}
resp, err := client.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()
if resp.StatusCode < 200 || resp.StatusCode >= 400 {
body, err := io.ReadAll(resp.Body)
@ -148,6 +151,18 @@ func CallRevokeEndpoint(request interface{}, authFn interface{}, caller RevokeCa
return nil
}
func CallTokenExchangeEndpoint(request interface{}, authFn interface{}, caller TokenEndpointCaller) (resp *oidc.TokenExchangeResponse, err error) {
req, err := httphelper.FormRequest(caller.TokenEndpoint(), request, Encoder, authFn)
if err != nil {
return nil, err
}
tokenRes := new(oidc.TokenExchangeResponse)
if err := httphelper.HttpRequest(caller.HttpClient(), req, &tokenRes); err != nil {
return nil, err
}
return tokenRes, nil
}
func NewSignerFromPrivateKeyByte(key []byte, keyID string) (jose.Signer, error) {
privateKey, err := crypto.BytesToPrivateKey(key)
if err != nil {