theonedev/onedev · error · AuthenticationException

Unsolicited OIDC authentication response

Error message

Unsolicited OIDC authentication response

What it means

After a successful SSO login, SsoProcessPage.afterLogin redirects to the URL stored in the session under SESSION_ATTR_REDIRECT_URL, which the login flow sets when it initiates SSO. If that attribute is missing/blank when the OIDC response arrives, the page assumes the response was not solicited by this server and throws this AuthenticationException.

Solutions

  1. Restart the SSO login from OneDev (click the login link again) so a fresh session and redirect URL are established.
  2. Ensure the callback URL is only reached via the IdP redirect initiated from OneDev; remove bookmarks/probes to the callback endpoint.
  3. Fix session persistence on the server (sticky sessions / shared session store) if sessions are being lost behind a proxy.
  4. Increase OneDev session timeout or reduce IdP login-page dwell time.

Example fix

// before: bookmarked direct access to callback
GET https://onedev/~sso/process?code=...

// after: always start from OneDev
GET https://onedev/  -> click 'Sign in with SSO'
Defensive patterns

Strategy: retry

Validate before calling

// Client-side: only call the callback via the IdP redirect; check session cookie exists
if (!cookies.contains("onedev-session")) restartLoginFromOneDev();

Try / catch

try {
    ssoLogin();
} catch (AuthenticationException e) {
    if (e.getMessage().contains("Unsolicited")) {
        // session lost: restart the SSO flow from scratch
        restartLoginFromOneDev();
    } else throw e;
}

Prevention

When it happens

Trigger: OIDC provider posts the authentication response to the callback URL while no OneDev session attribute 'redirectUrlAfterLogin' exists — e.g. session expired between request start and callback, callback URL was hit directly (bookmarked/health-check), or the response is replayed/duplicated.

Common situations: User sat on the IdP login page long enough for the OneDev session to expire; reverse proxy/load balancer session stickiness issues losing the Wicket session; a monitoring probe or crawler hitting the callback URL; user re-submitting the OIDC response via browser refresh.

Understand the failure class

Related errors


AI-assisted analysis of theonedev/onedev@d44925c47c (2026-09-06). Data as JSON: /api/errors/c7caaf5e99f9006a. Report an issue: GitHub.

Appendix: source

Thrown at server-core/src/main/java/io/onedev/server/web/page/security/SsoProcessPage.java:241

		var groupNames = authenticated.getGroupNames();
		if (forNewUser && groupNames == null) 
			groupNames = new HashSet<String>();
		if (groupNames != null) {
			if (getProvider().getDefaultGroup() != null)
				groupNames.add(getProvider().getDefaultGroup().getName());
			if (settingService.getSecuritySetting().getDefaultGroupName() != null)
				groupNames.add(settingService.getSecuritySetting().getDefaultGroupName());
			membershipService.syncMemberships(user, groupNames);
		}
		
		if (authenticated.getSshKeys() != null)
			sshKeyService.syncSshKeys(user, authenticated.getSshKeys());									
	}

	private void afterLogin(User user) {		
		String redirectUrlAfterLogin = (String) getSession().getAttribute(SESSION_ATTR_REDIRECT_URL);
		if (StringUtils.isBlank(redirectUrlAfterLogin))
			throw new AuthenticationException(_T("Unsolicited OIDC authentication response"));

		SecurityUtils.getSubject().runAs(user.getPrincipals());
		WebSession.get().setSsoLogoutUrl(
				getProvider().getConnector().buildLogoutUrl(getProvider().getName()));

		throw new RedirectToUrlException(redirectUrlAfterLogin);	
	}

	private SsoProvider getProvider() {
		return providerModel.getObject();
	}

	@Override
	protected void onInitialize() {
		super.onInitialize();

		List<Tab> tabs = new ArrayList<>();
					

View on GitHub (pinned to d44925c47c)