Documentation
¶
Overview ¶
Package idproxy provides OIDC authentication middleware and MCP OAuth 2.1 Authorization Server functionality as a single Go library.
idproxy can be used as:
- An http.Handler middleware via Auth.Wrap() for any Go HTTP server
- A standalone reverse proxy binary (cmd/idproxy) for non-Go upstream servers
Features ¶
- Multiple OIDC provider support (EntraID, Google, Amazon Cognito, etc.)
- MCP OAuth 2.1 Authorization Server with PKCE (S256 only)
- SSE / Streamable HTTP transparent passthrough
- Cookie-based session management with encrypted JWT (gorilla/securecookie)
- Pluggable Store interface for session/token persistence (memory / DynamoDB / Redis / SQLite implementations)
- Dynamic Client Registration (RFC 7591)
- OAuth 2.1 refresh_token rotation with family revocation
Authentication flow (browser session) ¶
- Client request hits Auth.Wrap().
- If the request matches a BrowserAuth path (/login, /callback, /select), the corresponding handler is invoked.
- If the request has an Authorization: Bearer <jwt> header, the JWT is validated against the configured signing key and the user is injected into the request context.
- If the request has a session cookie, the cookie is decrypted and the session is fetched from Store; on success the user is injected.
- Otherwise: browser requests (Accept: text/html) are redirected to /login, API requests get 401 Unauthorized.
Post-login redirect behavior (v0.5.0+) ¶
After authentication completes, BrowserAuth redirects the user back to:
- The redirect_to query parameter passed to /login, if supplied.
- Otherwise Config.DefaultPostLoginPath, if non-empty.
- Otherwise "/" (legacy default).
Embedding applications that previously relied on the default "/" should either keep a handler mounted at "/", or set DefaultPostLoginPath. To run arbitrary post-authentication logic (e.g. cascade OAuth, account provisioning, audit logging), use the Config.OnAuthenticated hook. The hook is called once, right after the session cookie is issued.
See the README and examples/cascade-oauth for details.
Open redirect protection (opt-in, v0.5.0+) ¶
idproxy accepts arbitrary redirect_to values by default (legacy behavior). To prevent open-redirect attacks, opt in with (*Config).UseStrictPostLoginRedirectValidator() or by setting Config.PostLoginRedirectValidator manually.
The strict validator allows only:
- Relative paths starting with "/" (but not "//")
- Absolute HTTPS URLs whose host equals Config.ExternalURL's host
All other inputs (javascript:, data:, protocol-relative, backslashes, non-NFKC characters, control / format characters) are rejected with 400.
Store backend selection ¶
Pick the Store implementation based on deployment topology:
- store.NewMemoryStore() — single instance, no persistence
- store.NewDynamoDBStore(...) — Lambda / multi-instance / multi-AZ
- redis (store/redis package) — distributed cache, low-latency sessions
- sqlite (store/sqlite package)— single node with disk persistence
All implementations share the same Store interface. Refresh-token rotation is implemented with backend-specific atomicity primitives (Lua script for Redis, transaction CAS for SQLite, conditional update for DynamoDB).
Client ownership in Store implementations ¶
When you pass an externally-constructed client / db to a Store, ownership of that resource determines what happens at Close():
- DynamoDB: never closes the injected client (AWS SDK v2 convention).
- Redis: closes the injected client by default; opt out with redisstore.WithClientOwnership(false).
- SQLite: closes the injected db by default (NewWithDB is not yet exposed in v0.5.0; see roadmap).
See docs/store-coexistence.md for the full coexistence guide.
Index ¶
- Variables
- func S256Challenge(verifier string) string
- func StrictPostLoginRedirectValidator(externalURL string) func(string) error
- func VerifyS256(verifier, challenge string) bool
- type AccessTokenData
- type Auth
- type AuthCodeData
- type BearerValidator
- type BrowserAuth
- type ClientData
- type Config
- type OAuthConfig
- type OAuthServer
- type OIDCProvider
- type ProviderManager
- func (pm *ProviderManager) Count() int
- func (pm *ProviderManager) Get(issuer string) (*providerEntry, bool)
- func (pm *ProviderManager) List() []OIDCProvider
- func (pm *ProviderManager) OAuth2Config(issuer string) (*oauth2.Config, error)
- func (pm *ProviderManager) SelectionHTML() string
- func (pm *ProviderManager) Single() (*providerEntry, bool)
- func (pm *ProviderManager) Verifier(issuer string) (*oidc.IDTokenVerifier, error)
- type RefreshTokenData
- type Session
- type SessionManager
- func (sm *SessionManager) DeleteSession(ctx context.Context, w http.ResponseWriter, r *http.Request) error
- func (sm *SessionManager) GetSessionFromRequest(ctx context.Context, r *http.Request) (*Session, error)
- func (sm *SessionManager) IssueSession(ctx context.Context, user *User, ...) (*Session, error)
- func (sm *SessionManager) SetCookie(w http.ResponseWriter, sessionID string) error
- type Store
- type User
Constants ¶
This section is empty.
Variables ¶
var DefaultConfig = Config{ SessionMaxAge: 24 * time.Hour, AccessTokenTTL: 1 * time.Hour, RefreshTokenTTL: 30 * 24 * time.Hour, AuthCodeTTL: 10 * time.Minute, PathPrefix: "", }
DefaultConfig は Config のデフォルト値を保持する。
var DefaultScopes = []string{"openid", "email", "profile", "offline_access"}
DefaultScopes は OIDCProvider のデフォルトスコープ。 offline_access を含むことで IdP が refresh_token を返すようになる(IdP refresh_token 保存に必要)。
var ErrRefreshTokenAlreadyConsumed = errors.New("refresh token already consumed")
ErrRefreshTokenAlreadyConsumed はリフレッシュトークンが既に消費済みの場合に返されるエラー。 replay 検知時は data と共に返される(familyID の取得に使用)。
var ErrUnsafePostLoginRedirect = errors.New("idproxy: unsafe post-login redirect")
ErrUnsafePostLoginRedirect は PostLoginRedirectValidator がリダイレクト先を 拒否した時に返される sentinel エラー。利用側で errors.Is で判定できる。
Functions ¶
func S256Challenge ¶
S256Challenge は RFC 7636 S256 メソッドでコードチャレンジを生成する。 code_verifier を SHA-256 ハッシュし、base64url(パディングなし)でエンコードして返す。
OAuth 2.1 では S256 のみが必須であり、plain メソッドは禁止されている。
func StrictPostLoginRedirectValidator ¶ added in v0.5.0
StrictPostLoginRedirectValidator は post-login redirect 先を厳格に検査する `func(string) error` を返す。利用側が opt-in で安全側に切り替えるための helper。
externalURL は Config.ExternalURL と同一の値を渡す(同一 origin の絶対 URL 許可判定に使用する)。空文字列を渡した場合は「相対パスのみ許可」モードになる。
許可条件(多段検査、順番に評価する):
- `strings.TrimSpace` 後の入力に `unicode.IsControl` を含むなら reject
- backslash や HTML 構造文字 `\<>"'` を含むなら reject
- NFKC 正規化後と元の入力で差分があるなら reject(同形異字攻撃排除)
- `url.Parse` で scheme/host を取得し、以下のいずれかに合致するなら通過: - 相対パス: scheme="" かつ host="" かつ "/" で始まり "//" で始まらない - 同一 origin の絶対 URL: scheme="https" かつ host==externalURL の host
- それ以外は reject(`javascript:`/`data:`/`vbscript:`/`file:`/protocol-relative も拒否)
拒否時は `ErrUnsafePostLoginRedirect` を wrap した error を返す。
func VerifyS256 ¶
VerifyS256 は RFC 7636 S256 メソッドでコードチャレンジを検証する。 SHA256(verifier) の base64url が challenge と一致する場合に true を返す。 verifier または challenge が空文字列の場合は false を返す。
タイミングサイドチャネル攻撃を防ぐため、crypto/subtle.ConstantTimeCompare で比較する。
Types ¶
type AccessTokenData ¶
type AccessTokenData struct {
// JTI は JWT の一意識別子。
JTI string
// Subject はユーザーの OIDC sub クレーム。
Subject string
// Email はユーザーのメールアドレス。
Email string
// ClientID はトークンを発行した OAuth クライアントの ID。
ClientID string
// Scopes は付与されたスコープ。
Scopes []string
// IssuedAt はトークン発行日時。
IssuedAt time.Time
// ExpiresAt はトークン有効期限。
ExpiresAt time.Time
// Revoked はトークンがリボケーション済みかどうか。
Revoked bool
// IDToken は Config.StoreIDToken = true のとき、IdP が発行した生の ID Token 文字列。
// bearer.go での Validate 時に User.IDToken に伝播される。
// StoreIDToken = false(デフォルト)の場合は空文字列。
IDToken string
}
AccessTokenData はアクセストークンのメタデータを保持する。 トークン自体は JWT として自己完結するが、 リボケーション用に Store にも記録する。
type Auth ¶
type Auth struct {
// contains filtered or unexported fields
}
Auth はリクエスト認証ミドルウェアのメインエントリポイント。 Wrap() で http.Handler をラップし、リクエストの種類に応じて OAuth AS / Bearer 検証 / セッション検証 / ブラウザリダイレクト / 401 を判定する。
func (*Auth) SetOAuthServer ¶
SetOAuthServer は OAuth 2.1 AS ハンドラーを設定する。 M14-M17 で構築した OAuthServer を Wrap() の前に設定する。
func (*Auth) Wrap ¶
Wrap は認証ミドルウェアを返す。
リクエスト判定ロジック:
- BrowserAuth パス(/login, /callback, /select) → BrowserAuth に委譲
- OAuth AS パス(/.well-known/*, /register, /authorize, /token) → OAuthServer に委譲
- Authorization: Bearer ヘッダー → JWT 検証(M13 でスタブから本実装へ)
- セッション Cookie → SessionManager でセッション検証、User をコンテキストに注入
- Accept: text/html を含むブラウザリクエスト → ログインページへリダイレクト
- その他 API リクエスト → 401 Unauthorized
type AuthCodeData ¶
type AuthCodeData struct {
// Code は認可コード文字列(暗号論的乱数、32バイト hex)。
Code string
// ClientID は認可リクエストを送った OAuth クライアントの ID。
ClientID string
// RedirectURI は認可リクエストで指定されたリダイレクト URI。
RedirectURI string
// CodeChallenge は PKCE のコードチャレンジ(S256)。
CodeChallenge string
// CodeChallengeMethod は "S256" 固定。
CodeChallengeMethod string
// Scopes は認可されたスコープ。
Scopes []string
// User は認証済みユーザー情報。
User *User
// CreatedAt は認可コード発行日時。
CreatedAt time.Time
// ExpiresAt は認可コード有効期限(デフォルト10分)。
ExpiresAt time.Time
// Used は認可コードが既に使用済みかどうか。
// OAuth 2.1 では認可コードは1回のみ使用可能。
Used bool
// IDToken は Config.StoreIDToken = true のとき、IdP が発行した生の ID Token 文字列。
// authorization_code → access_token 発行時に AccessTokenData に伝播される。
// StoreIDToken = false(デフォルト)の場合は空文字列。
IDToken string
// IDPRefreshToken は IdP が発行した refresh_token。
// ブラウザ認証(OIDC コールバック)時に offline_access スコープ付きで取得した場合に保存される。
// authorization_code 経路で RefreshTokenData に伝播され、rotation 時に新しい id_token を取得するために使用する。
IDPRefreshToken string
}
AuthCodeData は OAuth 2.1 認可コードに紐づくデータを保持する。
type BearerValidator ¶
type BearerValidator struct {
// contains filtered or unexported fields
}
BearerValidator は Bearer JWT アクセストークンを検証する。 JWT の署名検証、クレーム検証、Store でのリボケーションチェックを行い、 認証済みの User を返す。
func NewBearerValidator ¶
func NewBearerValidator(cfg Config, store Store) (*BearerValidator, error)
NewBearerValidator は BearerValidator を構築する。 Config.OAuth が nil の場合、または SigningKey が ECDSA でない場合はエラーを返す。
type BrowserAuth ¶
type BrowserAuth struct {
// contains filtered or unexported fields
}
BrowserAuth はブラウザベースの OIDC 認証フローを処理する。 LoginHandler で IdP へのリダイレクトを行い、 CallbackHandler で認可コードを ID Token に交換してセッションを発行する。
func NewBrowserAuth ¶
func NewBrowserAuth(cfg Config, pm *ProviderManager, sm *SessionManager, store Store) *BrowserAuth
NewBrowserAuth は新しい BrowserAuth を生成する。
func (*BrowserAuth) CallbackHandler ¶
func (ba *BrowserAuth) CallbackHandler() http.Handler
CallbackHandler は GET /callback を処理する。 IdP からの認可コードを ID Token に交換し、セッションを発行して元の URL にリダイレクトする。
func (*BrowserAuth) LoginHandler ¶
func (ba *BrowserAuth) LoginHandler() http.Handler
LoginHandler は GET /login を処理し、IdP へのリダイレクトを行う。
クエリパラメータ:
- provider: 使用する IdP の Issuer URL(複数プロバイダー時に必須)
- redirect_to: 認証後のリダイレクト先 URL(デフォルト: "/")
単一プロバイダーの場合は provider パラメータを省略可能。
func (*BrowserAuth) SelectionHandler ¶
func (ba *BrowserAuth) SelectionHandler() http.Handler
SelectionHandler は複数 IdP 時のプロバイダー選択ページを表示する。 単一プロバイダーの場合は /login に直接リダイレクトする。
type ClientData ¶
type ClientData struct {
// ClientID は自動生成されたクライアント識別子(UUID v4)。
ClientID string `json:"client_id"`
// ClientName はクライアントの表示名。
ClientName string `json:"client_name,omitempty"`
// RedirectURIs は許可されたリダイレクト URI のリスト。
RedirectURIs []string `json:"redirect_uris"`
// GrantTypes は許可された grant_type(デフォルト: ["authorization_code"])。
GrantTypes []string `json:"grant_types"`
// ResponseTypes は許可された response_type(デフォルト: ["code"])。
ResponseTypes []string `json:"response_types"`
// TokenEndpointAuthMethod はトークンエンドポイントの認証方式(デフォルト: "none")。
TokenEndpointAuthMethod string `json:"token_endpoint_auth_method"`
// Scope はスペース区切りのスコープ文字列。
Scope string `json:"scope,omitempty"`
// CreatedAt はクライアント登録日時。
CreatedAt time.Time `json:"created_at"`
}
ClientData は動的登録されたクライアントの情報を保持する(RFC 7591)。
type Config ¶
type Config struct {
// Providers は OIDC プロバイダーのリスト(1つ以上必須)。
Providers []OIDCProvider
// AllowedDomains は許可するメールドメインのリスト。
// 空の場合、ドメインによる制限なし。
AllowedDomains []string
// AllowedEmails は許可する個別メールアドレスのリスト。
// AllowedDomains と OR 条件で評価される。
AllowedEmails []string
// ExternalURL はこのサービスの外部公開 URL。
// OAuth コールバック URL やメタデータの issuer として使用される。
// 例: "https://mcp-auth.example.com"
ExternalURL string
// CookieSecret は Cookie 暗号化用の秘密鍵(32バイト以上)。
CookieSecret []byte
// OAuth は OAuth 2.1 AS の設定。
// nil の場合、OAuth 2.1 AS エンドポイントは無効化される
//(ブラウザベース認証のみ)。
OAuth *OAuthConfig
// Store はセッション・トークン等の保存先。
// nil の場合、デフォルトの MemoryStore が使用される。
Store Store
// SessionMaxAge はブラウザセッションの最大有効期間。
// デフォルト: 24時間。
SessionMaxAge time.Duration
// AccessTokenTTL は OAuth 2.1 Access Token の有効期間。
// デフォルト: 1時間。
AccessTokenTTL time.Duration
// RefreshTokenTTL は OAuth 2.1 Refresh Token の有効期間。デフォルト: 30日。
RefreshTokenTTL time.Duration
// AuthCodeTTL は認可コードの有効期間。
// デフォルト: 10分。
AuthCodeTTL time.Duration
// Logger は slog.Logger インスタンス。
// nil の場合、slog.Default() を使用。
Logger *slog.Logger
// PathPrefix は OAuth 2.1 AS エンドポイントのパスプレフィックス。
// デフォルト: "" (ルート直下)。
// 例: "/auth" → /auth/authorize, /auth/token 等
PathPrefix string
// DefaultPostLoginPath は認証完了後のデフォルトリダイレクト先。
// 空文字列なら "/" を使用(現状互換)。
// `LoginHandler` の `redirect_to` クエリが未指定の場合に使用される。
// 先頭が "/" で始まる相対パスである必要があり、"//" で始まる
// protocol-relative URL は禁止(Validate でエラー)。
DefaultPostLoginPath string
// OnAuthenticated は認証完了時(CallbackHandler 内の session 発行直後)に
// 呼ばれるフック。
//
// 戻り値の解釈(4 状態):
// - handled=true, redirectTo="" : フック側で ResponseWriter に応答済み。
// BrowserAuth はリダイレクトしない。
// - handled=true, redirectTo!="" : フック側で応答済みと解釈し、redirectTo
// は無視される(godoc 上の契約)。
// - handled=false, redirectTo!="" : PostLoginRedirectValidator を通してから
// redirectTo へ 302。Validator が nil なら
// 直接 302、Validator がエラーを返すなら 500。
// - handled=false, redirectTo=="" : 現状通り state に保存された RedirectURI へ 302。
//
// 呼び出し前後で `r.Context().Err() != nil` を検出した場合、BrowserAuth は
// それ以降 ResponseWriter に何も書かずハンドラーを終了する(client cancellation 伝播)。
//
// フックは認証完了に同期で呼ばれるため、長い処理は呼び出し側で goroutine 化すること。
// フック内で panic が発生した場合、BrowserAuth は recover して 500 を返す
// (`http.ErrAbortHandler` だけは再 panic)。
OnAuthenticated func(w http.ResponseWriter, r *http.Request, user *User) (redirectTo string, handled bool)
// PostLoginRedirectValidator は post-login redirect 先の安全性を検証する関数。
//
// 適用される箇所:
// - `LoginHandler` の `redirect_to` クエリ
// - `SelectionHandler` の `redirect_to` クエリ
// - `Auth.Wrap` の未認証ブラウザリクエストで生成される `redirect_to`
// - `OAuthServer.redirectToLogin` の `redirect_to`
// - `OnAuthenticated` フック戻り値の `redirectTo`
//
// nil なら検査しない(v0.4.2 までの動作互換、純粋 API 追加)。
// `StrictPostLoginRedirectValidator(cfg.ExternalURL)` または
// `(*Config).UseStrictPostLoginRedirectValidator()` を呼ぶことで opt-in できる。
//
// Validator が non-nil でエラーを返した場合、入力起因のため 400 を返す(500 ではない)。
// Validator 内 panic は BrowserAuth 側で recover して 500 を返す。
PostLoginRedirectValidator func(redirectTo string) error
// StoreIDToken は、セッションに保存済みの生の ID Token を
// UserFromContext(ctx).IDToken 経由でハンドラーに公開するかどうかを指定する。
//
// デフォルト: false(既存動作を維持)。
//
// 注意: ID Token はこの設定に関わらず常にセッションストアに保存される。
// この設定は「保存するかどうか」ではなく「コンテキストへ露出するかどうか」を制御する。
//
// true にすると、OIDC コールバック(ブラウザ認証フロー)経由でログインしたとき、
// UserFromContext(ctx).IDToken に IdP が発行した ID Token 文字列がセットされる。
// Bearer Token フロー(セッションなし)では常に空文字列となる。
//
// 主な用途: AWS STS AssumeRoleWithWebIdentity など、
// IdP が発行したトークンをそのままダウンストリームサービスに渡す必要がある場合。
//
// 注意:
// - ストアの暗号化が有効であることを確認すること。
// - ID Token の有効期限(exp クレーム)はセッション有効期限より短い場合がある(多くの
// IdP では約 1 時間)。IDToken を使用する際は呼び出し側で exp を確認すること。
// 期限切れでも UserFromContext(ctx).IDToken は空でない文字列を返し続ける。
StoreIDToken bool
}
Config は idproxy の設定を保持する。
func (*Config) UseStrictPostLoginRedirectValidator ¶ added in v0.5.0
func (c *Config) UseStrictPostLoginRedirectValidator()
UseStrictPostLoginRedirectValidator は Config.PostLoginRedirectValidator に `StrictPostLoginRedirectValidator(c.ExternalURL)` を設定するヘルパー。
呼び出すと Strict Validator が opt-in され、相対パスおよび同一 origin の 絶対 URL のみが許可される。`Config.ExternalURL` の渡し忘れを防ぐため、 利用側はこのメソッド経由でセットすることを推奨する。
type OAuthConfig ¶
type OAuthConfig struct {
// SigningKey は JWT 署名用の秘密鍵。
// *ecdsa.PrivateKey(ES256)または *rsa.PrivateKey(RS256)。
SigningKey crypto.Signer
// SigningMethod は JWT 署名アルゴリズム。
// デフォルト: SigningKey の型から自動判定(ECDSA → ES256, RSA → RS256)。
SigningMethod jwt.SigningMethod
// ClientID は OAuth 2.1 クライアント ID。
// 静的クライアント設定用(動的クライアント登録は Phase 3 で追加)。
// 空の場合、/authorize エンドポイントは任意の client_id を受け付ける。
ClientID string
// AllowedRedirectURIs は許可するリダイレクト URI のリスト。
// /authorize エンドポイントで redirect_uri の検証に使用する。
// 空の場合、localhost の URI のみ許可する(開発用)。
AllowedRedirectURIs []string
}
OAuthConfig は OAuth 2.1 Authorization Server の設定。
type OAuthServer ¶
type OAuthServer struct {
// contains filtered or unexported fields
}
OAuthServer は OAuth 2.1 Authorization Server エンドポイントを提供する。 RFC 8414 メタデータ、JWKS、および /authorize を処理する。
func NewOAuthServer ¶
func NewOAuthServer(cfg Config, store Store, sm *SessionManager, pm *ProviderManager) (*OAuthServer, error)
NewOAuthServer は OAuthServer を構築する。 Config.OAuth が設定されている場合はその SigningKey(ECDSA P-256)を使用する。 Config.OAuth が nil の場合は ES256 鍵ペアを自動生成する。 sm は SessionManager(/authorize でユーザー認証確認に使用)。nil の場合もエラーにはしない。 pm は IdP refresh_token を使って id_token を更新するための ProviderManager。 nil の場合は IdP refresh をスキップして旧来の動作(古い IDToken を引き継ぐ)になる。
func (*OAuthServer) ServeHTTP ¶
func (s *OAuthServer) ServeHTTP(w http.ResponseWriter, r *http.Request)
ServeHTTP はリクエストを適切なハンドラーにルーティングする。
type OIDCProvider ¶
type OIDCProvider struct {
// Issuer は OIDC Issuer URL。
// 例: "https://accounts.google.com"
// 例: "https://login.microsoftonline.com/{tenant-id}/v2.0"
Issuer string
// ClientID は OAuth Client ID。
ClientID string
// ClientSecret は OAuth Client Secret。
ClientSecret string
// Scopes は要求するスコープ。
// デフォルト: ["openid", "email", "profile"]
Scopes []string
// Name はプロバイダーの表示名(ログイン画面等で使用)。
// 空の場合、Issuer から自動生成。
Name string
}
OIDCProvider は1つの OIDC プロバイダーの設定を保持する。
type ProviderManager ¶
type ProviderManager struct {
// contains filtered or unexported fields
}
ProviderManager は複数の OIDC プロバイダーを管理する。
func NewProviderManager ¶
func NewProviderManager(ctx context.Context, cfg Config) (*ProviderManager, error)
NewProviderManager は Config.Providers から ProviderManager を生成する。 各プロバイダーに対して OIDC Discovery を取得し、初期化を行う。
func (*ProviderManager) Get ¶
func (pm *ProviderManager) Get(issuer string) (*providerEntry, bool)
Get は Issuer URL に対応するプロバイダー情報を返す。
func (*ProviderManager) List ¶
func (pm *ProviderManager) List() []OIDCProvider
List は設定順序でプロバイダー一覧を返す。
func (*ProviderManager) OAuth2Config ¶
func (pm *ProviderManager) OAuth2Config(issuer string) (*oauth2.Config, error)
OAuth2Config は指定プロバイダーの oauth2.Config を返す。
func (*ProviderManager) SelectionHTML ¶
func (pm *ProviderManager) SelectionHTML() string
SelectionHTML は複数プロバイダー選択ページの HTML を生成する。
func (*ProviderManager) Single ¶
func (pm *ProviderManager) Single() (*providerEntry, bool)
Single は単一プロバイダーの場合にそのプロバイダーを返す。 複数の場合は nil, false を返す。
func (*ProviderManager) Verifier ¶
func (pm *ProviderManager) Verifier(issuer string) (*oidc.IDTokenVerifier, error)
Verifier は指定プロバイダーの IDTokenVerifier を返す。
type RefreshTokenData ¶ added in v0.3.0
type RefreshTokenData struct {
// ID は opaque リフレッシュトークン文字列(32バイト base64url)。
ID string
// FamilyID は同一 authorization_code から派生した全リフレッシュトークンに共通の UUID v4。
FamilyID string
// ClientID は発行時の OAuth クライアントの ID。
ClientID string
// Subject はユーザーの OIDC sub クレーム。
Subject string
// OIDCIssuer は元の OIDC プロバイダの issuer URL。
// Bearer アクセストークンの User.Issuer を復元するために使用する。
// セッション経由の User.Issuer(OIDC issuer)と Bearer JWT の iss(ExternalURL)が
// 異なるため、principal_id の一貫性を保つために明示的に保持する。
OIDCIssuer string
// Email はユーザーのメールアドレス(新 access_token 再発行用)。
Email string
// Name はユーザーの表示名(新 access_token 再発行用)。
Name string
// Scopes は付与されたスコープ。
Scopes []string
// IssuedAt はトークン発行日時。
IssuedAt time.Time
// ExpiresAt はトークン有効期限。
ExpiresAt time.Time
// Used は消費済みフラグ。ConsumeRefreshToken で true に更新される。
Used bool
// IDToken は Config.StoreIDToken = true のとき、IdP が発行した生の ID Token 文字列。
// refresh_token グラント時に新 AccessTokenData.IDToken に引き継がれる。
// StoreIDToken = false(デフォルト)の場合は空文字列。
IDToken string
// IDPRefreshToken は IdP が発行した refresh_token。
// authorization_code グラント時に AuthCodeData.IDPRefreshToken から引き継がれ、
// rotation 時に新しい id_token を取得するために使用する。
// 一部の IdP(Entra ID 等)は refresh_token を毎回 rotate するため、rotation 後の新しいトークンで上書きする。
IDPRefreshToken string
}
RefreshTokenData は OAuth 2.1 リフレッシュトークンに紐づくデータを保持する。 rotation + family tracking + replay detection に使用する。
注意(移行): IDToken フィールドの追加により、unkeyed struct literal (例: idproxy.RefreshTokenData{"id", "family", ...})を使用しているコードはコンパイルエラーになる。 keyed literal(例: idproxy.RefreshTokenData{ID: "...", FamilyID: "..."})に移行すること。
type Session ¶
type Session struct {
// ID はセッションの一意識別子(UUID v4)。
ID string
// User は認証済みユーザー情報。
User *User
// ProviderIssuer は認証に使用した IdP の Issuer URL。
ProviderIssuer string
// IDToken は IdP から取得した生の ID Token。
// セッション復元時の検証やクレーム参照に使用。
IDToken string
// IDPRefreshToken は IdP が発行した refresh_token。
// offline_access スコープ付きブラウザ認証時に保存される。
// OAuth 2.1 refresh_token rotation 時に新しい id_token を取得するために使用する。
IDPRefreshToken string
// CreatedAt はセッション作成日時。
CreatedAt time.Time
// ExpiresAt はセッション有効期限。
ExpiresAt time.Time
}
Session はブラウザセッションのデータを保持する。
type SessionManager ¶
type SessionManager struct {
// contains filtered or unexported fields
}
SessionManager は Cookie ベースのセッション管理を担当する。 gorilla/securecookie を使って Cookie を暗号化・署名し、 Store インターフェース経由でセッションデータを永続化する。
func NewSessionManager ¶
func NewSessionManager(cfg Config) (*SessionManager, error)
NewSessionManager は新しい SessionManager を生成する。 cfg.CookieSecret は 32 バイト以上が必要。 cfg.Store が nil の場合はエラーを返す。
func (*SessionManager) DeleteSession ¶
func (sm *SessionManager) DeleteSession(ctx context.Context, w http.ResponseWriter, r *http.Request) error
DeleteSession はセッションを削除し、Cookie を無効化する。 Cookie が存在しない場合は何もしない(冪等)。 Cookie の復号が失敗した場合でも、MaxAge=-1 の Cookie を必ず設定する。
func (*SessionManager) GetSessionFromRequest ¶
func (sm *SessionManager) GetSessionFromRequest(ctx context.Context, r *http.Request) (*Session, error)
GetSessionFromRequest はリクエストの Cookie からセッションを取得する。 Cookie が存在しない場合は nil, nil を返す(エラーではない)。 Cookie が無効(改ざん等)の場合は nil, error を返す。 Store にセッションが存在しない(期限切れを含む)場合は nil, nil を返す。
func (*SessionManager) IssueSession ¶
func (sm *SessionManager) IssueSession(ctx context.Context, user *User, providerIssuer, idToken, idpRefreshToken string) (*Session, error)
IssueSession は新しいセッションを発行し、Store に保存して返す。 セッション ID は UUID v4 で生成する。 idpRefreshToken は IdP が発行した refresh_token(offline_access スコープ取得時)。 取得できない場合(スコープ未設定等)は空文字列を渡す。
func (*SessionManager) SetCookie ¶
func (sm *SessionManager) SetCookie(w http.ResponseWriter, sessionID string) error
SetCookie はセッション ID を暗号化して Set-Cookie ヘッダーを設定する。
type Store ¶
type Store interface {
// セッション操作
SetSession(ctx context.Context, id string, session *Session, ttl time.Duration) error
GetSession(ctx context.Context, id string) (*Session, error)
DeleteSession(ctx context.Context, id string) error
// 認可コード操作(OAuth 2.1 AS 用)
SetAuthCode(ctx context.Context, code string, data *AuthCodeData, ttl time.Duration) error
GetAuthCode(ctx context.Context, code string) (*AuthCodeData, error)
DeleteAuthCode(ctx context.Context, code string) error
// アクセストークン操作(リボケーション用)
SetAccessToken(ctx context.Context, jti string, data *AccessTokenData, ttl time.Duration) error
GetAccessToken(ctx context.Context, jti string) (*AccessTokenData, error)
DeleteAccessToken(ctx context.Context, jti string) error
// クライアント操作(Dynamic Client Registration: RFC 7591)
SetClient(ctx context.Context, clientID string, data *ClientData) error
GetClient(ctx context.Context, clientID string) (*ClientData, error)
DeleteClient(ctx context.Context, clientID string) error
// リフレッシュトークン操作(OAuth 2.1 rotation + replay detection 用)
SetRefreshToken(ctx context.Context, id string, data *RefreshTokenData, ttl time.Duration) error
GetRefreshToken(ctx context.Context, id string) (*RefreshTokenData, error)
// ConsumeRefreshToken はリフレッシュトークンを消費する。
// 未登録または期限切れ: (nil, nil)
// 初回消費: (data, nil) — Used フラグを true に更新
// 2回目以降: (data, ErrRefreshTokenAlreadyConsumed) — familyID 取得のため data も返す
ConsumeRefreshToken(ctx context.Context, id string) (*RefreshTokenData, error)
SetFamilyRevocation(ctx context.Context, familyID string, ttl time.Duration) error
IsFamilyRevoked(ctx context.Context, familyID string) (bool, error)
// クリーンアップ
Cleanup(ctx context.Context) error
Close() error
}
Store はセッション、認可コード、アクセストークンの永続化インターフェース。
type User ¶
type User struct {
// Email はユーザーのメールアドレス。
Email string
// Name はユーザーの表示名。
Name string
// Subject は OIDC sub クレーム。
Subject string
// Issuer は認証に使用された IdP の Issuer URL。
Issuer string
// Claims は ID Token の全クレーム。
Claims map[string]interface{}
// IDToken は IdP が発行した生の ID Token 文字列。
// Config.StoreIDToken = true の場合のみセットされる。
// AWS STS AssumeRoleWithWebIdentity 等、IdP トークンが必要な用途に使用する。
IDToken string
}
User は認証済みユーザーの情報を保持する。
注意(移行): IDToken フィールドの追加により、unkeyed struct literal (例: idproxy.User{"email", "name", ...})を使用しているコードはコンパイルエラーになる。 keyed literal(例: idproxy.User{Email: "...", Name: "..."})に移行すること。
func UserFromContext ¶
UserFromContext はリクエストコンテキストから認証済みユーザー情報を取得する。 認証されていない場合は nil を返す。
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
cmd
|
|
|
idproxy
command
|
|
|
examples
|
|
|
basic
command
Package main は idproxy ライブラリを使った基本的なリバースプロキシの例です。
|
Package main は idproxy ライブラリを使った基本的なリバースプロキシの例です。 |
|
cascade-oauth
command
Package main は idproxy の OnAuthenticated フックを使った カスケード OAuth パターンの最小サンプルです。
|
Package main は idproxy の OnAuthenticated フックを使った カスケード OAuth パターンの最小サンプルです。 |
|
dynamodb-coexist
command
Package main は idproxy DynamoDB Store と利用側独自データ(同テーブル + 独自 GSI)の 共存サンプルです。
|
Package main は idproxy DynamoDB Store と利用側独自データ(同テーブル + 独自 GSI)の 共存サンプルです。 |
|
mcp-server
command
Package main は idproxy ライブラリを使った MCP サーバー保護の例です。
|
Package main は idproxy ライブラリを使った MCP サーバー保護の例です。 |
|
Package store provides implementations of the idproxy.Store interface for session, authorization code, and access token persistence.
|
Package store provides implementations of the idproxy.Store interface for session, authorization code, and access token persistence. |
|
redis
Package redis は idproxy.Store の Redis 実装を提供する。
|
Package redis は idproxy.Store の Redis 実装を提供する。 |
|
sqlite
Package sqlite は idproxy.Store の SQLite 実装を提供する。
|
Package sqlite は idproxy.Store の SQLite 実装を提供する。 |
|
storetest
Package storetest は idproxy.Store 実装の適合性テストスイートを提供する。
|
Package storetest は idproxy.Store 実装の適合性テストスイートを提供する。 |
|
Package testutil provides test helpers for idproxy, including a mock OIDC Identity Provider server for integration testing.
|
Package testutil provides test helpers for idproxy, including a mock OIDC Identity Provider server for integration testing. |