Skip to content

Sign-out answers 403

This page helps you when your app signs a user out with a POST to /auth/logout and gets 403 Forbidden back.

The auth server answers 403 Forbidden with a plain-text body, not a page:

Your request was refused for security reasons. Please reload the page and try again.

The user stays signed in. The auth server’s log has a cross-origin request refused warning, whose explanation and remedy fields say which check refused the request. No audit event is written.

The auth server refuses a POST that comes from another site, unless it can tell the request is safe. That’s what stops any web page from submitting forms to the auth server on a user’s behalf.

For /auth/logout, a POST is safe when it carries an id_token_hint. A POST without one is exactly what the auth server’s own “Are you sure you want to sign out?” screen submits when the user clicks Yes. Accepting it from another site would let any page sign your users out without asking them, so the auth server refuses it.

So the usual cause is a self-submitting form on your app’s page that posts to /auth/logout without an id_token_hint. Your app’s origin differs from the auth server’s, whether it’s another site or another host on the same domain, such as app.example.com beside auth.example.com.

On the same domain, the warning’s explanation speaks of a sibling host and a deployment misconfiguration, and its remedy of serving the form from one origin. That’s meant for the auth server’s own forms, as in When the confirmation screen itself answers 403. When the form is your app’s, use the fix that follows.

Pick one:

  • Send the id_token_hint in the form, with the ID token the user signed in with. A cross-site POST with a hint is accepted. If the auth server can confirm the hint, the user is signed out straight away. If it can’t, it answers 303 See Other back to GET /auth/logout, which shows the confirmation screen.
  • Use a GET. Send the browser to /auth/logout with a link or a redirect. A GET is never refused this way, and without a hint the user sees the confirmation screen.

POST is worth it when you have an id_token_hint, because it keeps the ID token out of the address bar, the browser’s history and the Referer header.

When the confirmation screen itself answers 403

Section titled “When the confirmation screen itself answers 403”

If clicking Yes on the auth server’s own “Are you sure you want to sign out?” screen answers 403, the form and the auth server look like two different sites to the browser, though they’re the same. The same refusal then hits every form the auth server serves, the sign-in page included. The warning’s explanation names one of these:

  • The browser reached the auth server on another hostname, port or scheme than the one it’s configured with, such as a bare domain beside a www host, or http beside https. Use exactly GOIABADA_AUTHSERVER_BASEURL.
  • A proxy rewrote the Host header, so it no longer matches the Origin the browser sent. Configure the proxy to pass the original Host on, such as proxy_set_header Host $host; in Nginx.
  • The page was served with Referrer-Policy: no-referrer, so the browser sent Origin: null. The auth server sets same-origin itself: check that nothing in front of it replaces that header.