2020-07-04 19:19:36 +01:00
|
|
|
package middleware
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"context"
|
2020-11-15 18:57:48 -08:00
|
|
|
"fmt"
|
2020-07-04 19:19:36 +01:00
|
|
|
|
2021-07-17 09:55:05 -07:00
|
|
|
"github.com/coreos/go-oidc/v3/oidc"
|
2020-09-30 01:44:42 +09:00
|
|
|
sessionsapi "github.com/oauth2-proxy/oauth2-proxy/v7/pkg/apis/sessions"
|
2025-10-30 09:26:14 +01:00
|
|
|
"github.com/oauth2-proxy/oauth2-proxy/v7/pkg/util/ptr"
|
2020-07-04 19:19:36 +01:00
|
|
|
)
|
|
|
|
|
|
2020-11-15 18:57:48 -08:00
|
|
|
// TokenToSessionFunc takes a raw ID Token and converts it into a SessionState.
|
|
|
|
|
type TokenToSessionFunc func(ctx context.Context, token string) (*sessionsapi.SessionState, error)
|
2020-10-23 23:34:06 -07:00
|
|
|
|
2020-11-15 18:57:48 -08:00
|
|
|
// VerifyFunc takes a raw bearer token and verifies it returning the converted
|
|
|
|
|
// oidc.IDToken representation of the token.
|
|
|
|
|
type VerifyFunc func(ctx context.Context, token string) (*oidc.IDToken, error)
|
2020-07-04 19:19:36 +01:00
|
|
|
|
2020-11-15 18:57:48 -08:00
|
|
|
// CreateTokenToSessionFunc provides a handler that is a default implementation
|
|
|
|
|
// for converting a JWT into a session.
|
|
|
|
|
func CreateTokenToSessionFunc(verify VerifyFunc) TokenToSessionFunc {
|
|
|
|
|
return func(ctx context.Context, token string) (*sessionsapi.SessionState, error) {
|
|
|
|
|
var claims struct {
|
2022-03-07 18:54:24 +02:00
|
|
|
Subject string `json:"sub"`
|
|
|
|
|
Email string `json:"email"`
|
|
|
|
|
Verified *bool `json:"email_verified"`
|
|
|
|
|
PreferredUsername string `json:"preferred_username"`
|
|
|
|
|
Groups []string `json:"groups"`
|
2020-11-15 18:57:48 -08:00
|
|
|
}
|
2020-07-04 19:19:36 +01:00
|
|
|
|
2020-11-15 18:57:48 -08:00
|
|
|
idToken, err := verify(ctx, token)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if err := idToken.Claims(&claims); err != nil {
|
|
|
|
|
return nil, fmt.Errorf("failed to parse bearer token claims: %v", err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if claims.Email == "" {
|
|
|
|
|
claims.Email = claims.Subject
|
|
|
|
|
}
|
|
|
|
|
|
2025-11-07 23:26:00 +01:00
|
|
|
// Ensure email is verified
|
|
|
|
|
// If the email is not verified, return an error
|
|
|
|
|
// If the email_verified claim is missing, assume it is verified
|
|
|
|
|
if !ptr.Deref(claims.Verified, true) {
|
2020-11-15 18:57:48 -08:00
|
|
|
return nil, fmt.Errorf("email in id_token (%s) isn't verified", claims.Email)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
newSession := &sessionsapi.SessionState{
|
|
|
|
|
Email: claims.Email,
|
|
|
|
|
User: claims.Subject,
|
2022-03-07 18:54:24 +02:00
|
|
|
Groups: claims.Groups,
|
2020-11-15 18:57:48 -08:00
|
|
|
PreferredUsername: claims.PreferredUsername,
|
|
|
|
|
AccessToken: token,
|
|
|
|
|
IDToken: token,
|
|
|
|
|
RefreshToken: "",
|
|
|
|
|
ExpiresOn: &idToken.Expiry,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return newSession, nil
|
|
|
|
|
}
|
2020-07-04 19:19:36 +01:00
|
|
|
}
|