Files
saml-oidc-bridge/internal/oidc/client.go
Shamil Nunhuck 920a79b2e9 initial commit
2025-11-08 10:18:19 +00:00

71 lines
1.6 KiB
Go

package oidc
import (
"context"
"fmt"
"net/url"
gooidc "github.com/coreos/go-oidc/v3/oidc"
"golang.org/x/oauth2"
"shamilnunhuck/saml-oidc-bridge/internal/config"
)
type Client struct {
Verifier *gooidc.IDTokenVerifier
OAuth2 *oauth2.Config
}
func NewClient(cfg *config.Config) (*Client, error) {
ctx := context.Background()
provider, err := gooidc.NewProvider(ctx, cfg.OIDC.Issuer)
if err != nil {
return nil, err
}
verifier := provider.Verifier(&gooidc.Config{ClientID: cfg.OIDC.ClientID})
redirect := cfg.Server.ExternalURL + cfg.OIDC.RedirectPath
scopes := []string{"openid"}
scopes = append(scopes, cfg.OIDC.Scopes...)
oauth2cfg := &oauth2.Config{
ClientID: cfg.OIDC.ClientID,
ClientSecret: cfg.OIDC.ClientSecret,
Endpoint: provider.Endpoint(),
Scopes: scopes,
RedirectURL: redirect,
}
return &Client{Verifier: verifier, OAuth2: oauth2cfg}, nil
}
type Claims struct {
Subject string `json:"sub"`
Email string `json:"email"`
Name string `json:"name"`
Groups []string `json:"groups"`
}
func (c *Client) AuthCodeURL(state string, extra url.Values) string {
return c.OAuth2.AuthCodeURL(state)
}
func (c *Client) ExchangeAndVerify(ctx context.Context, code string) (*Claims, error) {
token, err := c.OAuth2.Exchange(ctx, code)
if err != nil {
return nil, err
}
rawID, ok := token.Extra("id_token").(string)
if !ok {
return nil, fmt.Errorf("no id_token in token response")
}
idt, err := c.Verifier.Verify(ctx, rawID)
if err != nil {
return nil, err
}
var cl Claims
if err := idt.Claims(&cl); err != nil {
return nil, err
}
return &cl, nil
}