gitea icon indicating copy to clipboard operation
gitea copied to clipboard

OIDC users don't stay logged in

Open MrMeeb opened this issue 2 years ago • 20 comments

Description

I have configured Gitea to auth with Authentik via OIDC. Prior to that I was using local users, so the session would persist over a longer period, especially when 'Remember me' was ticked. I've noticed that when authenticating with OIDC, I don't remain logged in after closing the browser. This means users have to go through two extra clicks every time they visit in a new browser session.

Gitea Version

1.21.1

Can you reproduce the bug on the Gitea demo site?

Yes

Log Gist

No response

Screenshots

No response

Git Version

No response

Operating System

No response

How are you running Gitea?

Ubuntu/Docker

Database

MySQL/MariaDB

MrMeeb avatar Dec 07 '23 21:12 MrMeeb

I have exactly the same issue (Gitea v1.22.3). I also have a Gitea + Authentik PoC. But the big problem for me is that the login does not persist. Local users can log in without any problems and remain logged in for the time configured in the app.ini. This works perfectly. The corresponding remember cookie is also set. If a user logs in via OIDC, however, no cookie is set, only the session cookie. Accordingly, these users have to log in again and again

Other apps that are connected to my OIDC provider do not have this issue. The users remain logged in there. Therefore, this should definitely have something to do with the implementation in Gitea (simply no cookie is set).

But now I'm not sure whether this might even be intentional, because it's basically also a security problem. I am noticing this in the other apps. Once you are logged in there, you stay logged in, even if you log out of the provider (Authentik). Therefore, you should remain logged in even if the user has been blocked or deleted by an admin in Authentik. Of course, this makes the whole SSO issue a bit of a one-way street if you don't have a single logout. It might therefore be better to use LDAP integration in Gitea. Authentik also offers this. Maybe this problem does not exist there.

I'm also not sure whether this is due to the implementation or a general problem with OIDC itself.

p7kdev avatar Nov 07 '24 08:11 p7kdev

For what it's worth, I've somewhat eased the issue by editing the sign-in button to go straight to the OIDC flow. So it skips Gitea's login page.

MrMeeb avatar Nov 07 '24 12:11 MrMeeb

the following thread seems relevant: https://forum.gitea.com/t/gitea-keycloak-login-session-time/9869

and i can confirm, when using local login, i have a gitea_incredible cookie set to the LOGIN_REMEMBER_DAYS offset.

but with OIDC login, no such cookie exists, and those that do are essentially 24 hours, thus i get logged out daily.

eleith avatar Nov 08 '24 16:11 eleith

@MrMeeb may I ask how did you manage this?

The instance I use is private only so it would help a lot with an automatic redirect.

johansmitsnl avatar Feb 12 '25 15:02 johansmitsnl

@MrMeeb may I ask how did you manage this?

The instance I use is private only so it would help a lot with an automatic redirect.

@johansmitsnl Not MrMeeb, but here is my setup using Caddy as reverse proxy:

@gitea host gitea.example.org
handle @gitea {
	# Convenience redirect to skip Gitea's own login screen and go
	# directly to SSO instead.
	rewrite /user/login /user/oauth2/Authelia

	reverse_proxy <gitea hostname>:<gitea port>
}

Note that Authelia here is the name of the authentication source as configurable in your Gitea instance at https://gitea.example.org/-/admin/auths

ItsJustRuby avatar Jun 03 '25 04:06 ItsJustRuby

With regards to the main topic: I am running Gitea 1.23.8 and encountering the same issue, being logged out from Gitea regularly while still being logged in to Authelia as SSO provider configured by OIDC.

auth.go respects the "Remember me" setting and sets an according cookie but AFAICT this never happens (and can't? shouldn't?) during the OIDC flow.

This cookie is checked in web.go when landing on the Gitea home page and an automatic redirect to /user/login happens if it is set (which accordingly performs auto login).

AFAICT this second check is missing functionality to get the current "logged in" status from the SSO provider, if configured - but I am not knowledgeable enough about authentication here to know if the correct solution wouldn't be setting the same cookies during SSO login as during normal login.

I hope this analysis will help resolve this issue 🙂

ItsJustRuby avatar Jun 03 '25 04:06 ItsJustRuby

I’d like to add that I’m also experiencing this issue on the latest Gitea version.

In my case, I’ve configured both Passkey (via YubiKey) and OIDC as authentication methods. Login works correctly, but the session never persists after closing the browser — even when "Remember This Device" is expected to function.

However, when using Password + TOTP login, the "Remember Me" option works and keeps the session alive as intended.

This makes Passkey and OIDC inconvenient for regular use, as users must re-authenticate every time they reopen the browser.

It would be very helpful if session persistence could be supported for these external authentication methods as well. Thanks!

skyone-wzw avatar Jul 13 '25 16:07 skyone-wzw

I’d like to add that I’m also experiencing this issue on the latest Gitea version.

In my case, I’ve configured both Passkey (via YubiKey) and OIDC as authentication methods. Login works correctly, but the session never persists after closing the browser — even when "Remember This Device" is expected to function.

However, when using Password + TOTP login, the "Remember Me" option works and keeps the session alive as intended.

This makes Passkey and OIDC inconvenient for regular use, as users must re-authenticate every time they reopen the browser.

It would be very helpful if session persistence could be supported for these external authentication methods as well. Thanks!

I am experiencing the exact same as this. When logging in with OIDC, cookies are made to clear after the session ends. When logging in without OIDC, they are back to the default 7 days.

thesyntaxslinger avatar Oct 20 '25 05:10 thesyntaxslinger

Since this has been annoying me for so long. I have just made a bit of a bandaid fix with a user script to auto log into the authelia instance. I have my authelia setup to auto log in without a consent so this is a nice fix for my environment.

// ==UserScript==
// @name        Auto sign into Authelia
// @namespace   Violentmonkey Scripts
// @match       https://gitea.yourdomain.tld/user/login*
// @match       https://gitea.yourdomain.tld/
// ==/UserScript==

(function autoSignIn() {
    // check to see if we are on the authelia default homepage
    const rootHeader = document.querySelector('h2.tw-text-balance');
    if (rootHeader) {
        // click the sign in link
        const signInLink = Array.from(document.querySelectorAll('a.item')).find(a =>
            a.textContent.includes('Sign In')
        );
        if (signInLink) {
            signInLink.click();
            return; // this will exit the script since the script will fire again on the next page
        }
    }

    // check for the SSO link
    const autheliaLink = Array.from(document.querySelectorAll('a.oauth-login-link')).find(a =>
        a.textContent.includes('Sign in with')
    );
    // click the link then exit
    if (autheliaLink) {
        autheliaLink.click();
        return;
    };
})();

Can we get a bump on this? Quite an annoying issue and sort of defeats the whole purpose of SSO.

thesyntaxslinger avatar Nov 09 '25 06:11 thesyntaxslinger

May be specific to some OIDC provider implementations. I'm running Gitea with Keycloak OIDC provider with LOGIN_REMEMBER_DAYS = 365 and get logged out only like once per month when Keycloak expires the session, so it's working fine with Keycloak at least.

If someone could provide a reproduction repo, that would surely help narrow this down.

silverwind avatar Nov 21 '25 11:11 silverwind

I looked into this issue a while back and I think I had it narrowed down to incorrect use of the Expires cookie parameter. If Expires is omitted and Max-Age is not set, then the cookie will become a session cookie which is "removed when the session ends" (the exact meaning of this is a bit underdefined but theoretically it means when the browser is closed).

gjabell avatar Nov 21 '25 12:11 gjabell

That sound plausible. Normally without SSO, the user can choose whether they want a session cookie or not by checking "Remember me", which in turn should control the Expires attribute. With SSO, there is no such checkbox, so the only option is to always set Expires to mark the cookie as a non-session one, we should verify it does that.

Maybe someone affected could confirm whether their gitea cookie has an Expires set or not in their browser devtools.

silverwind avatar Nov 21 '25 12:11 silverwind

Mine certainly seems to use the session cookies:

Image

The callback request where the cookie is set also lacks both Expires and Max-Age which explains why it becomes a session cookie:

Image

gjabell avatar Nov 21 '25 12:11 gjabell

Odd, my cookie is marked as "Session" too in Firefox but even when I close and re-open my browser it is being sent again on the first request to gitea and I stay logged in. Maybe there is some detail about session cookies that we miss.

Image

silverwind avatar Nov 21 '25 13:11 silverwind

🤔 Interesting; I can reproduce this behavior in both Firefox and Chromium. Firefox I have a bit of a specific setup so I could see that deleting session tokens automatically but Chromium is fairly default IIRC which I guess means it's not browser-specific.

gjabell avatar Nov 21 '25 14:11 gjabell

Aha, in Chromium at least it seems to be related to the "on startup" behavior:

Image

With the "continue where you left off" option it keeps the session token around even after a restart (which makes sense I guess).

Interestingly I have FF configured to open my previous pages on startup but it doesn't keep the session there, but that may be because of some additional configuration I'm forgetting.

gjabell avatar Nov 21 '25 14:11 gjabell

So are we certain that browser deleting the cookie is the culprit?

If yes, we could probably add Expiry to these cookies using LOGIN_REMEMBER_DAYS for OIDC. I think with OIDC, there is some other mechanism in play that limits the lifetime of a session, so what is set on the cookie should not matter.

silverwind avatar Nov 21 '25 15:11 silverwind

I think it's very likely. Having Expiry on the cookie for LOGIN_REMEMBER_DAYS makes sense I think, since it brings it to parity with logging in directly through Gitea.

One thing maybe to consider is that (from what I understand) the Gitea session is not bound in any way to the OIDC session, since it uses Gitea's own cookie and not an OIDC-native token. In other words, OIDC is used to perform the initial authentication but then Gitea takes over from there, meaning the OIDC provider is not contacted after that point until the Gitea session expires and the user wants to login again. Ultimately this means it's possible for the OIDC session to have already expired but the Gitea token to still be valid, but I think it's not possible to fix this without using OIDC-native tokens.

gjabell avatar Nov 21 '25 15:11 gjabell

I guess ideally we should match the cookie's lifetime to match the one of the OIDC session. I wonder what actually happens if the OIDC session expires while the cookie is still alive. I assume the user would be kicked to the login page?

silverwind avatar Nov 21 '25 15:11 silverwind

It might have info about the session lifetime in the OIDC callback response; that way it could intelligently set the Expire header without needing the user to synchronize their LOGIN_REMEMBER_DAYS manually.

Right now since the sessions aren't related, if the Gitea token expires and you try to login again, you'll be redirected to the OIDC provider and then whether you have to login to OIDC depends on whether its session is still valid. Conversely it's possible that the OIDC session has already expired some time ago but Gitea continues to function without a login as its session is still valid (e.g. OIDC session is 7d but Gitea is 30d).

gjabell avatar Nov 21 '25 15:11 gjabell