mirror of
https://github.com/pomerium/pomerium.git
synced 2025-04-28 18:06:34 +02:00
* identity: add support for verifying access and identity tokens * allow overriding with policy option * authenticate: add verify endpoints * wip * implement session creation * add verify test * implement idp token login * fix tests * add pr permission * make session ids route-specific * rename method * add test * add access token test * test for newUserFromIDPClaims * more tests * make the session id per-idp * use type for * add test * remove nil checks
109 lines
2.8 KiB
Go
109 lines
2.8 KiB
Go
// Package authenticateapi has the types and methods for the authenticate api.
|
|
package authenticateapi
|
|
|
|
import (
|
|
"bytes"
|
|
"context"
|
|
"encoding/json"
|
|
"fmt"
|
|
"io"
|
|
"net/http"
|
|
"net/url"
|
|
|
|
"github.com/pomerium/pomerium/internal/jwtutil"
|
|
)
|
|
|
|
// VerifyAccessTokenRequest is used to verify access tokens.
|
|
type VerifyAccessTokenRequest struct {
|
|
AccessToken string `json:"accessToken"`
|
|
IdentityProviderID string `json:"identityProviderId,omitempty"`
|
|
}
|
|
|
|
// VerifyIdentityTokenRequest is used to verify identity tokens.
|
|
type VerifyIdentityTokenRequest struct {
|
|
IdentityToken string `json:"identityToken"`
|
|
IdentityProviderID string `json:"identityProviderId,omitempty"`
|
|
}
|
|
|
|
// VerifyTokenResponse is the result of verifying an access or identity token.
|
|
type VerifyTokenResponse struct {
|
|
Valid bool `json:"valid"`
|
|
Claims jwtutil.Claims `json:"claims,omitempty"`
|
|
}
|
|
|
|
// An API is an api client for the authenticate service.
|
|
type API struct {
|
|
authenticateURL *url.URL
|
|
transport http.RoundTripper
|
|
}
|
|
|
|
// New creates a new API client.
|
|
func New(
|
|
authenticateURL *url.URL,
|
|
transport http.RoundTripper,
|
|
) *API {
|
|
return &API{
|
|
authenticateURL: authenticateURL,
|
|
transport: transport,
|
|
}
|
|
}
|
|
|
|
// VerifyAccessToken verifies an access token.
|
|
func (api *API) VerifyAccessToken(ctx context.Context, request *VerifyAccessTokenRequest) (*VerifyTokenResponse, error) {
|
|
var response VerifyTokenResponse
|
|
err := api.call(ctx, "verify-access-token", request, &response)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return &response, nil
|
|
}
|
|
|
|
// VerifyIdentityToken verifies an identity token.
|
|
func (api *API) VerifyIdentityToken(ctx context.Context, request *VerifyIdentityTokenRequest) (*VerifyTokenResponse, error) {
|
|
var response VerifyTokenResponse
|
|
err := api.call(ctx, "verify-identity-token", request, &response)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return &response, nil
|
|
}
|
|
|
|
func (api *API) call(
|
|
ctx context.Context,
|
|
endpoint string,
|
|
request, response any,
|
|
) error {
|
|
u := api.authenticateURL.ResolveReference(&url.URL{
|
|
Path: "/.pomerium/" + endpoint,
|
|
})
|
|
|
|
body, err := json.Marshal(request)
|
|
if err != nil {
|
|
return fmt.Errorf("error marshaling %s http request: %w", endpoint, err)
|
|
}
|
|
|
|
req, err := http.NewRequestWithContext(ctx, http.MethodPost, u.String(), bytes.NewReader(body))
|
|
if err != nil {
|
|
return fmt.Errorf("error creating %s http request: %w", endpoint, err)
|
|
}
|
|
|
|
res, err := (&http.Client{
|
|
Transport: api.transport,
|
|
}).Do(req)
|
|
if err != nil {
|
|
return fmt.Errorf("error executing %s http request: %w", endpoint, err)
|
|
}
|
|
defer res.Body.Close()
|
|
|
|
body, err = io.ReadAll(res.Body)
|
|
if err != nil {
|
|
return fmt.Errorf("error reading %s http response: %w", endpoint, err)
|
|
}
|
|
|
|
err = json.Unmarshal(body, &response)
|
|
if err != nil {
|
|
return fmt.Errorf("error reading %s http response (body=%s): %w", endpoint, body, err)
|
|
}
|
|
|
|
return nil
|
|
}
|