feat: add back support for request oidc param

This commit is contained in:
Stavros
2026-06-06 18:01:59 +03:00
parent f078e3549e
commit 47b7f1e6f2
6 changed files with 84 additions and 21 deletions
+5 -1
View File
@@ -126,7 +126,11 @@ export const LoginPage = () => {
});
redirectTimer.current = window.setTimeout(() => {
window.location.replace(`/continue${compiledParams}`);
if (screenParams.login_for === "oidc") {
window.location.replace(`/oidc/authorize${compiledParams}`);
} else {
window.location.replace(`/continue${compiledParams}`);
}
}, 500);
},
onError: (error: AxiosError) => {
+5 -1
View File
@@ -42,7 +42,11 @@ export const TotpPage = () => {
});
redirectTimer.current = window.setTimeout(() => {
window.location.replace(`/continue${compiledParams}`);
if (screenParams.login_for === "oidc") {
window.location.replace(`/oidc/authorize${compiledParams}`);
} else {
window.location.replace(`/continue${compiledParams}`);
}
}, 500);
},
onError: () => {
+5
View File
@@ -13,6 +13,7 @@ require (
github.com/google/go-querystring v1.2.0
github.com/google/uuid v1.6.0
github.com/jackc/pgx/v5 v5.10.0
github.com/lestrrat-go/jwx/v4 v4.0.2
github.com/mdp/qrterminal/v3 v3.2.1
github.com/pquerna/otp v1.5.0
github.com/rs/zerolog v1.35.1
@@ -86,6 +87,7 @@ require (
github.com/goccy/go-json v0.10.5 // indirect
github.com/goccy/go-yaml v1.19.2 // indirect
github.com/godbus/dbus/v5 v5.1.1-0.20230522191255-76236955d466 // indirect
github.com/golang-jwt/jwt/v5 v5.3.1 // indirect
github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 // indirect
github.com/google/btree v1.1.3 // indirect
github.com/google/go-cmp v0.7.0 // indirect
@@ -101,6 +103,8 @@ require (
github.com/klauspost/compress v1.18.5 // indirect
github.com/klauspost/cpuid/v2 v2.3.0 // indirect
github.com/leodido/go-urn v1.4.0 // indirect
github.com/lestrrat-go/dsig v1.3.0 // indirect
github.com/lestrrat-go/option/v3 v3.0.0-alpha1 // indirect
github.com/lucasb-eyer/go-colorful v1.3.0 // indirect
github.com/mattn/go-colorable v0.1.14 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
@@ -140,6 +144,7 @@ require (
github.com/tailscale/wireguard-go v0.0.0-20260527010701-b48af7099cad // indirect
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
github.com/ugorji/go/codec v1.3.1 // indirect
github.com/valyala/fastjson v1.6.10 // indirect
github.com/x448/float16 v0.8.4 // indirect
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect
go.mongodb.org/mongo-driver/v2 v2.5.0 // indirect
+10
View File
@@ -216,6 +216,8 @@ github.com/goccy/go-yaml v1.19.2 h1:PmFC1S6h8ljIz6gMRBopkjP1TVT7xuwrButHID66PoM=
github.com/goccy/go-yaml v1.19.2/go.mod h1:XBurs7gK8ATbW4ZPGKgcbrY1Br56PdM69F7LkFRi1kA=
github.com/godbus/dbus/v5 v5.1.1-0.20230522191255-76236955d466 h1:sQspH8M4niEijh3PFscJRLDnkL547IeP7kpPe3uUhEg=
github.com/godbus/dbus/v5 v5.1.1-0.20230522191255-76236955d466/go.mod h1:ZiQxhyQ+bbbfxUKVvjfO498oPYvtYhZzycal3G/NHmU=
github.com/golang-jwt/jwt/v5 v5.3.1 h1:kYf81DTWFe7t+1VvL7eS+jKFVWaUnK9cB1qbwn63YCY=
github.com/golang-jwt/jwt/v5 v5.3.1/go.mod h1:fxCRLWMO43lRc8nhHWY6LGqRcf+1gQWArsqaEUEa5bE=
github.com/golang-migrate/migrate/v4 v4.19.1 h1:OCyb44lFuQfYXYLx1SCxPZQGU7mcaZ7gH9yH4jSFbBA=
github.com/golang-migrate/migrate/v4 v4.19.1/go.mod h1:CTcgfjxhaUtsLipnLoQRWCrjYXycRz/g5+RWDuYgPrE=
github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 h1:f+oWsMOmNPc8JmEHVZIycC7hBoQxHH9pNKQORJNozsQ=
@@ -301,6 +303,12 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ=
github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI=
github.com/lestrrat-go/dsig v1.3.0 h1:phjMOCXvYzhuIgn7Voe2rex8z166vGfxRxmqM25P9/Q=
github.com/lestrrat-go/dsig v1.3.0/go.mod h1:RD2eOaidyPvpc7IJQoO3Qq52RWdy8ZcJs8lrOnoa1Kc=
github.com/lestrrat-go/jwx/v4 v4.0.2 h1:T3lzN2dynOt6SuowT08ZWo/cPs3YsB0GHZSXKvfE0uQ=
github.com/lestrrat-go/jwx/v4 v4.0.2/go.mod h1:F2a0rSyXsqLAL0orBZGOXrzQGv018Tx4eiEWWYR7Yzo=
github.com/lestrrat-go/option/v3 v3.0.0-alpha1 h1:dvdzLwm/Ba5CJUF3jQP7w/iNYSLfy7yyh9XXNa1WjxI=
github.com/lestrrat-go/option/v3 v3.0.0-alpha1/go.mod h1:5KSg20dfsKkNJtjDmaQRLZVXuUrzuCCcz/gbDK0pfKk=
github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw=
github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
github.com/lucasb-eyer/go-colorful v1.3.0 h1:2/yBRLdWBZKrf7gB40FoiKfAWYQ0lqNcbuQwVHXptag=
@@ -453,6 +461,8 @@ github.com/u-root/uio v0.0.0-20240224005618-d2acac8f3701 h1:pyC9PaHYZFgEKFdlp3G8
github.com/u-root/uio v0.0.0-20240224005618-d2acac8f3701/go.mod h1:P3a5rG4X7tI17Nn3aOIAYr5HbIMukwXG0urG0WuL8OA=
github.com/ugorji/go/codec v1.3.1 h1:waO7eEiFDwidsBN6agj1vJQ4AG7lh2yqXyOXqhgQuyY=
github.com/ugorji/go/codec v1.3.1/go.mod h1:pRBVtBSKl77K30Bv8R2P+cLSGaTtex6fsA2Wjqmfxj4=
github.com/valyala/fastjson v1.6.10 h1:/yjJg8jaVQdYR3arGxPE2X5z89xrlhS0eGXdv+ADTh4=
github.com/valyala/fastjson v1.6.10/go.mod h1:e6FubmQouUNP73jtMLmcbxS6ydWIpOfhz34TSfO3JaE=
github.com/vishvananda/netns v0.0.5 h1:DfiHV+j8bA32MFM7bfEunvT8IAqQ/NzSJHtcmW5zdEY=
github.com/vishvananda/netns v0.0.5/go.mod h1:SpkAiCQRtJ6TvvxPnOSyH3BMl6unz3xZlaprSwhNNJM=
github.com/weppos/publicsuffix-go v0.50.3 h1:eT5dcjHQcVDNc0igpFEsGHKIip30feuB2zuuI9eJxiE=
+30 -11
View File
@@ -117,15 +117,36 @@ func (controller *OIDCController) authorize(c *gin.Context) {
var req service.AuthorizeRequest
err := c.ShouldBindWith(&req, binding.Query)
reqQueries := c.Request.URL.Query()
if err != nil {
controller.authorizeError(c, authorizeErrorParams{
err: err,
reason: "Failed to bind JSON",
reasonPublic: "The client provided an invalid authorization request",
})
return
if reqQueries.Get("request") != "" {
requestObject, err := controller.oidc.DecodeAuthorizeJWT(reqQueries.Get("request"))
if err != nil {
controller.authorizeError(c, authorizeErrorParams{
err: err,
reason: "Failed to decode request object",
reasonPublic: "The client provided an invalid request object",
})
return
}
req = *requestObject
} else {
var queryReq service.AuthorizeRequest
err := c.ShouldBindWith(&queryReq, binding.Query)
if err != nil {
controller.authorizeError(c, authorizeErrorParams{
err: err,
reason: "Failed to bind query parameters",
reasonPublic: "The client provided invalid query parameters",
})
return
}
req = queryReq
}
client, ok := controller.oidc.GetClient(req.ClientID)
@@ -139,9 +160,7 @@ func (controller *OIDCController) authorize(c *gin.Context) {
return
}
// TODO: handle request= parameter with JWTs
err = controller.oidc.ValidateAuthorizeParams(req)
err := controller.oidc.ValidateAuthorizeParams(req)
if err != nil {
controller.log.App.Warn().Err(err).Msg("Failed to validate authorize params")
+29 -8
View File
@@ -20,6 +20,7 @@ import (
"slices"
"github.com/go-jose/go-jose/v4"
"github.com/golang-jwt/jwt/v5"
"github.com/steveiliop56/ding"
"github.com/tinyauthapp/tinyauth/internal/model"
"github.com/tinyauthapp/tinyauth/internal/repository"
@@ -106,14 +107,15 @@ type TokenResponse struct {
}
type AuthorizeRequest struct {
Scope string `form:"scope" binding:"required"`
ResponseType string `form:"response_type" binding:"required"`
ClientID string `form:"client_id" binding:"required"`
RedirectURI string `form:"redirect_uri" binding:"required"`
State string `form:"state"`
Nonce string `form:"nonce"`
CodeChallenge string `form:"code_challenge"`
CodeChallengeMethod string `form:"code_challenge_method"`
jwt.Claims
Scope string `form:"scope" binding:"required" json:"scope"`
ResponseType string `form:"response_type" binding:"required" json:"response_type"`
ClientID string `form:"client_id" binding:"required" json:"client_id"`
RedirectURI string `form:"redirect_uri" binding:"required" json:"redirect_uri"`
State string `form:"state" json:"state"`
Nonce string `form:"nonce" json:"nonce"`
CodeChallenge string `form:"code_challenge" json:"code_challenge"`
CodeChallengeMethod string `form:"code_challenge_method" json:"code_challenge_method"`
}
type AuthorizeCodeEntry struct {
@@ -883,3 +885,22 @@ func (service *OIDCService) GetAuthorizeRequestByTicket(ticket string) (*Authori
func (service *OIDCService) DeleteAuthorizeRequestTicket(ticket string) {
service.caches.authorize.Delete(ticket)
}
// TODO: support signed request objects in the future
func (service *OIDCService) DecodeAuthorizeJWT(tokenString string) (*AuthorizeRequest, error) {
var req AuthorizeRequest
token, _, err := jwt.NewParser().ParseUnverified(tokenString, &req)
if err != nil {
return nil, fmt.Errorf("failed to parse authorize request jwt: %w", err)
}
claims, ok := token.Claims.(*AuthorizeRequest)
if !ok {
return nil, errors.New("failed to parse claims from authorize request jwt")
}
return claims, nil
}