|
8 | 8 | "fmt" |
9 | 9 | "log" |
10 | 10 | "net/http" |
11 | | - "strings" |
12 | 11 | "sync" |
13 | 12 | "time" |
14 | 13 |
|
@@ -138,11 +137,12 @@ func (a *OIDCAPI) LoginHandler() gin.HandlerFunc { |
138 | 137 | http.Error(w, "invalid client name", http.StatusBadRequest) |
139 | 138 | return |
140 | 139 | } |
141 | | - state, err := a.generateState(clientName) |
| 140 | + state, err := a.generateState() |
142 | 141 | if err != nil { |
143 | 142 | http.Error(w, fmt.Sprintf("failed to generate state: %v", err), http.StatusInternalServerError) |
144 | 143 | return |
145 | 144 | } |
| 145 | + a.storePendingSession(state, &pendingOIDCSession{ClientName: clientName, CreatedAt: time.Now()}) |
146 | 146 | rp.AuthURLHandler(func() string { return state }, a.Provider)(w, r) |
147 | 147 | }) |
148 | 148 | } |
@@ -180,8 +180,12 @@ func (a *OIDCAPI) CallbackHandler() gin.HandlerFunc { |
180 | 180 | http.Error(w, err.Error(), status) |
181 | 181 | return |
182 | 182 | } |
183 | | - clientName, _, _ := strings.Cut(state, ":") |
184 | | - client, err := a.createClient(clientName, user.ID) |
| 183 | + session, ok := a.popPendingSession(state) |
| 184 | + if !ok { |
| 185 | + http.Error(w, "unknown or expired state", http.StatusBadRequest) |
| 186 | + return |
| 187 | + } |
| 188 | + client, err := a.createClient(session.ClientName, user.ID) |
185 | 189 | if err != nil { |
186 | 190 | http.Error(w, fmt.Sprintf("failed to create client: %v", err), http.StatusInternalServerError) |
187 | 191 | return |
@@ -228,7 +232,7 @@ func (a *OIDCAPI) ExternalAuthorizeHandler(ctx *gin.Context) { |
228 | 232 | ctx.AbortWithError(http.StatusBadRequest, err) |
229 | 233 | return |
230 | 234 | } |
231 | | - state, err := a.generateState(req.Name) |
| 235 | + state, err := a.generateState() |
232 | 236 | if err != nil { |
233 | 237 | ctx.AbortWithError(http.StatusInternalServerError, err) |
234 | 238 | return |
@@ -314,12 +318,12 @@ func (a *OIDCAPI) ExternalTokenHandler(ctx *gin.Context) { |
314 | 318 | }) |
315 | 319 | } |
316 | 320 |
|
317 | | -func (a *OIDCAPI) generateState(name string) (string, error) { |
| 321 | +func (a *OIDCAPI) generateState() (string, error) { |
318 | 322 | nonce := make([]byte, 20) |
319 | 323 | if _, err := rand.Read(nonce); err != nil { |
320 | 324 | return "", err |
321 | 325 | } |
322 | | - return name + ":" + hex.EncodeToString(nonce), nil |
| 326 | + return hex.EncodeToString(nonce), nil |
323 | 327 | } |
324 | 328 |
|
325 | 329 | // resolveUser looks up or creates a user from OIDC userinfo claims. |
|
0 commit comments