AuthorizeHandler is the handler for the /authorize route required params ?redirect_uri = redirect url ?response_mode = to decide if result should be html or re-direct state[recommended] = to prevent CSRF attack (for authorizer its compulsory) code_challenge = to prevent CSRF attack code_challenge_me
()
| 74 | // code_challenge = to prevent CSRF attack |
| 75 | // code_challenge_method = to prevent CSRF attack [only sh256 is supported] |
| 76 | func (h *httpProvider) AuthorizeHandler() gin.HandlerFunc { |
| 77 | log := h.Log.With().Str("func", "AuthorizeHandler").Logger() |
| 78 | return func(gc *gin.Context) { |
| 79 | redirectURI := strings.TrimSpace(gc.Query("redirect_uri")) |
| 80 | responseType := strings.TrimSpace(gc.Query("response_type")) |
| 81 | state := strings.TrimSpace(gc.Query("state")) |
| 82 | codeChallenge := strings.TrimSpace(gc.Query("code_challenge")) |
| 83 | scopeString := strings.TrimSpace(gc.Query("scope")) |
| 84 | clientID := strings.TrimSpace(gc.Query("client_id")) |
| 85 | responseMode := strings.TrimSpace(gc.Query("response_mode")) |
| 86 | rawResponseMode := responseMode |
| 87 | nonce := strings.TrimSpace(gc.Query("nonce")) |
| 88 | screenHint := strings.TrimSpace(gc.Query("screen_hint")) |
| 89 | |
| 90 | // OIDC Core §3.1.2.1 standard authorization request parameters. |
| 91 | loginHint := strings.TrimSpace(gc.Query("login_hint")) |
| 92 | uiLocales := strings.TrimSpace(gc.Query("ui_locales")) |
| 93 | prompt := strings.TrimSpace(gc.Query("prompt")) |
| 94 | maxAgeStr := strings.TrimSpace(gc.Query("max_age")) |
| 95 | idTokenHint := strings.TrimSpace(gc.Query("id_token_hint")) |
| 96 | |
| 97 | // max_age is advisory. Parse per OIDC Core §3.1.2.1: |
| 98 | // - negative or non-integer → treat as absent (no constraint) |
| 99 | // - max_age=0 → force re-auth (equivalent to prompt=login) |
| 100 | // - positive → compare against session age (handled below) |
| 101 | maxAge := -1 // sentinel: "not supplied" |
| 102 | maxAgeZero := false |
| 103 | if maxAgeStr != "" { |
| 104 | if parsed, err := strconv.Atoi(maxAgeStr); err == nil && parsed >= 0 { |
| 105 | maxAge = parsed |
| 106 | if parsed == 0 { |
| 107 | maxAgeZero = true |
| 108 | } |
| 109 | } |
| 110 | } |
| 111 | |
| 112 | // id_token_hint is advisory per OIDC Core §3.1.2.1. Validate |
| 113 | // structurally; on failure log at debug and continue. |
| 114 | hintedSub := h.parseIDTokenHintSubject(idTokenHint) |
| 115 | if idTokenHint != "" && hintedSub == "" { |
| 116 | log.Debug().Msg("id_token_hint provided but invalid — ignoring per OIDC Core §3.1.2.1") |
| 117 | } |
| 118 | |
| 119 | // prompt=consent / prompt=select_account are accepted but |
| 120 | // not yet implemented — proceed normally. |
| 121 | if prompt == "consent" || prompt == "select_account" { |
| 122 | log.Debug().Str("prompt", prompt).Msg("prompt value accepted but not implemented — proceeding normally") |
| 123 | } |
| 124 | |
| 125 | var scope []string |
| 126 | if scopeString == "" { |
| 127 | scope = []string{"openid", "profile", "email"} |
| 128 | } else { |
| 129 | scope = strings.Split(scopeString, " ") |
| 130 | } |
| 131 | |
| 132 | if responseMode == "" { |
| 133 | responseMode = h.Config.DefaultAuthorizeResponseMode |
nothing calls this directly
no test coverage detected