Some OAuth2 providers return quite large structured tokens >32767 bytes. Gitea currently has a fixed maximum of 32767 bytes for these and unfortunately due to the convoluted nature of the dependent libraries the error returned is rather opaque. Here we manage the error a little better - detecting the rather opaque github.com/gorilla/securecookie.errEncodedValueTooLong and converting it to a more readable error. Further we provide a configurable option to increase the maximum size of the provided OAuth2 tokens. Fix #9907 Signed-off-by: Andrew Thornton <art27@cantab.net> Co-authored-by: techknowlogick <techknowlogick@gitea.io>tags/v1.13.0-dev
@@ -916,6 +916,8 @@ REFRESH_TOKEN_EXPIRATION_TIME=730 | |||
INVALIDATE_REFRESH_TOKENS=false | |||
; OAuth2 authentication secret for access and refresh tokens, change this to a unique string. | |||
JWT_SECRET=Bk0yK7Y9g_p56v86KaHqjSbxvNvu3SbKoOdOt2ZcXvU | |||
; Maximum length of oauth2 token/cookie stored on server | |||
MAX_TOKEN_LENGTH=32767 | |||
[i18n] | |||
LANGS = en-US,zh-CN,zh-HK,zh-TW,de-DE,fr-FR,nl-NL,lv-LV,ru-RU,uk-UA,ja-JP,es-ES,pt-BR,pl-PL,bg-BG,it-IT,fi-FI,tr-TR,cs-CZ,sr-SP,sv-SE,ko-KR |
@@ -587,6 +587,7 @@ NB: You must `REDIRECT_MACARON_LOG` and have `DISABLE_ROUTER_LOG` set to `false` | |||
- `REFRESH_TOKEN_EXPIRATION_TIME`: **730**: Lifetime of an OAuth2 access token in hours | |||
- `INVALIDATE_REFRESH_TOKEN`: **false**: Check if refresh token got already used | |||
- `JWT_SECRET`: **\<empty\>**: OAuth2 authentication secret for access and refresh tokens, change this a unique string. | |||
- `MAX_TOKEN_LENGTH`: **32767**: Maximum length of token/cookie to accept from OAuth2 provider | |||
## i18n (`i18n`) | |||
@@ -5,7 +5,6 @@ | |||
package oauth2 | |||
import ( | |||
"math" | |||
"net/http" | |||
"code.gitea.io/gitea/modules/log" | |||
@@ -26,7 +25,7 @@ import ( | |||
"github.com/markbates/goth/providers/openidConnect" | |||
"github.com/markbates/goth/providers/twitter" | |||
"github.com/markbates/goth/providers/yandex" | |||
"github.com/satori/go.uuid" | |||
uuid "github.com/satori/go.uuid" | |||
"xorm.io/xorm" | |||
) | |||
@@ -58,7 +57,7 @@ func Init(x *xorm.Engine) error { | |||
// when using OpenID Connect , since this can contain a large amount of extra information in the id_token | |||
// Note, when using the FilesystemStore only the session.ID is written to a browser cookie, so this is explicit for the storage on disk | |||
store.MaxLength(math.MaxInt16) | |||
store.MaxLength(setting.OAuth2.MaxTokenLength) | |||
gothic.Store = store | |||
gothic.SetState = func(req *http.Request) string { |
@@ -10,6 +10,7 @@ import ( | |||
"fmt" | |||
"io" | |||
"io/ioutil" | |||
"math" | |||
"net" | |||
"net/url" | |||
"os" | |||
@@ -323,11 +324,13 @@ var ( | |||
InvalidateRefreshTokens bool | |||
JWTSecretBytes []byte `ini:"-"` | |||
JWTSecretBase64 string `ini:"JWT_SECRET"` | |||
MaxTokenLength int | |||
}{ | |||
Enable: true, | |||
AccessTokenExpirationTime: 3600, | |||
RefreshTokenExpirationTime: 730, | |||
InvalidateRefreshTokens: false, | |||
MaxTokenLength: math.MaxInt16, | |||
} | |||
U2F = struct { |
@@ -670,6 +670,10 @@ func oAuth2UserLoginCallback(loginSource *models.LoginSource, request *http.Requ | |||
gothUser, err := oauth2.ProviderCallback(loginSource.Name, request, response) | |||
if err != nil { | |||
if err.Error() == "securecookie: the value is too long" { | |||
log.Error("OAuth2 Provider %s returned too long a token. Current max: %d. Either increase the [OAuth2] MAX_TOKEN_LENGTH or reduce the information returned from the OAuth2 provider", loginSource.Name, setting.OAuth2.MaxTokenLength) | |||
err = fmt.Errorf("OAuth2 Provider %s returned too long a token. Current max: %d. Either increase the [OAuth2] MAX_TOKEN_LENGTH or reduce the information returned from the OAuth2 provider", loginSource.Name, setting.OAuth2.MaxTokenLength) | |||
} | |||
return nil, goth.User{}, err | |||
} | |||