feat: forward sub from oidc providers

This commit is contained in:
Stavros
2025-12-26 18:28:53 +02:00
parent 2d8af0510e
commit eef674a4e6
12 changed files with 21 additions and 0 deletions

View File

@@ -0,0 +1 @@
ALTER TABLE "sessions" DROP COLUMN "oauth_sub";

View File

@@ -0,0 +1 @@
ALTER TABLE "sessions" ADD COLUMN "oauth_sub" TEXT;

View File

@@ -79,6 +79,7 @@ const DefaultNamePrefix = "TINYAUTH_"
// OAuth/OIDC config
type Claims struct {
Sub string `json:"sub"`
Name string `json:"name"`
Email string `json:"email"`
PreferredUsername string `json:"preferred_username"`
@@ -125,6 +126,7 @@ type SessionCookie struct {
TotpPending bool
OAuthGroups string
OAuthName string
OAuthSub string
}
type UserContext struct {
@@ -138,6 +140,7 @@ type UserContext struct {
OAuthGroups string
TotpEnabled bool
OAuthName string
OAuthSub string
}
// API responses and queries

View File

@@ -21,6 +21,7 @@ type UserContextResponse struct {
OAuth bool `json:"oauth"`
TotpPending bool `json:"totpPending"`
OAuthName string `json:"oauthName"`
OAuthSub string `json:"oauthSub"`
}
type AppContextResponse struct {
@@ -89,6 +90,7 @@ func (controller *ContextController) userContextHandler(c *gin.Context) {
OAuth: context.OAuth,
TotpPending: context.TotpPending,
OAuthName: context.OAuthName,
OAuthSub: context.OAuthSub,
}
if err != nil {

View File

@@ -44,6 +44,7 @@ var userContext = config.UserContext{
TotpPending: false,
OAuthGroups: "",
TotpEnabled: false,
OAuthSub: "",
}
func setupContextController(middlewares *[]gin.HandlerFunc) (*gin.Engine, *httptest.ResponseRecorder) {

View File

@@ -197,6 +197,7 @@ func (controller *OAuthController) oauthCallbackHandler(c *gin.Context) {
Provider: req.Provider,
OAuthGroups: utils.CoalesceToString(user.Groups),
OAuthName: service.GetName(),
OAuthSub: user.Sub,
}
log.Trace().Interface("session_cookie", sessionCookie).Msg("Creating session cookie")

View File

@@ -239,6 +239,7 @@ func (controller *ProxyController) proxyHandler(c *gin.Context) {
c.Header("Remote-Name", utils.SanitizeHeader(userContext.Name))
c.Header("Remote-Email", utils.SanitizeHeader(userContext.Email))
c.Header("Remote-Groups", utils.SanitizeHeader(userContext.OAuthGroups))
c.Header("Remote-Sub", utils.SanitizeHeader(userContext.OAuthSub))
controller.setHeaders(c, acls)

View File

@@ -99,6 +99,7 @@ func (m *ContextMiddleware) Middleware() gin.HandlerFunc {
Provider: cookie.Provider,
OAuthGroups: cookie.OAuthGroups,
OAuthName: cookie.OAuthName,
OAuthSub: cookie.OAuthSub,
IsLoggedIn: true,
OAuth: true,
})

View File

@@ -10,4 +10,5 @@ type Session struct {
OAuthGroups string `gorm:"column:oauth_groups"`
Expiry int64 `gorm:"column:expiry"`
OAuthName string `gorm:"column:oauth_name"`
OAuthSub string `gorm:"column:oauth_sub"`
}

View File

@@ -213,6 +213,7 @@ func (auth *AuthService) CreateSessionCookie(c *gin.Context, data *config.Sessio
OAuthGroups: data.OAuthGroups,
Expiry: time.Now().Add(time.Duration(expiry) * time.Second).Unix(),
OAuthName: data.OAuthName,
OAuthSub: data.OAuthSub,
}
err = gorm.G[model.Session](auth.database).Create(c, &session)
@@ -314,6 +315,7 @@ func (auth *AuthService) GetSessionCookie(c *gin.Context) (config.SessionCookie,
TotpPending: session.TOTPPending,
OAuthGroups: session.OAuthGroups,
OAuthName: session.OAuthName,
OAuthSub: session.OAuthSub,
}, nil
}

View File

@@ -173,6 +173,9 @@ func (github *GithubOAuthService) Userinfo() (config.Claims, error) {
user.PreferredUsername = userInfo.Login
user.Name = userInfo.Name
// Github does not implement OIDC, so no sub is available
user.Sub = "not_available_dont_use_me"
return user, nil
}

View File

@@ -22,6 +22,7 @@ var GoogleOAuthScopes = []string{"https://www.googleapis.com/auth/userinfo.email
type GoogleUserInfoResponse struct {
Email string `json:"email"`
Name string `json:"name"`
Id string `json:"id"`
}
type GoogleOAuthService struct {
@@ -117,6 +118,9 @@ func (google *GoogleOAuthService) Userinfo() (config.Claims, error) {
user.Name = userInfo.Name
user.Email = userInfo.Email
// We can use the id as the sub
user.Sub = userInfo.Id
return user, nil
}