sebadob / rauthy

OpenID Connect Single Sign-On Identity & Access Management
https://sebadob.github.io/rauthy/
Apache License 2.0
297 stars 15 forks source link

Login redirect to rauthy results in: "400 Bad Request - Your request is malformed or incorrect" / `Invalid redirect uri` #535

Closed polarathene closed 1 month ago

polarathene commented 1 month ago

Recently I kept encountering this error while attempting to login (roundcube webmail as client) via rauthy:

image

# 400 Bad Request
Your request is malformed or incorrect, please see details.
Show Details >
  Invalid redirect uri

This is shown after clicking the Login with Rauthy button on the Roundcube login page. Searching around issues / discussions here for what is causing this has the suggestion that it's related to PUB_URL ENV, but I've had no luck messing around with that and other rauthy ENV.

I've just noticed that the redirect URI can be changed to http:// like I had it previously and the login process functions correctly again like I originally had it. It's only when that is set to https:// that login fails. That address has nothing pointing towards rauthy as a service though, so I'm rather confused why that change to https:// causes the vague error above.

# `http://` works:
http://rc.example.localhost/index.php/login/oauth

# `https://` doesn't work:
https://rc.example.localhost/index.php/login/oauth
sebadob commented 1 month ago

The PUB_URL has nothing to do with that. This is probably just a misconfiguration.
Either your client does not do what it should do, or you request a config on Rauthy's side that the client can't match.

You already found the config var you would need to adjust in that case, the allowed redirect URIs.
The only question left is:

Is your roundcube running on HTTPS and if yes, is it actually setting the redirect_uri query param during the redirect to Rauthy's /oidc/authorize correctly as well?

If it is running on HTTP, a redirect to HTTPS would not be possible of course. If it is running on HTTPS but does not set the correct redirect_uri, then the issue is on roundcube's side.

Rauthy does very strict validation. This means if any parameters during these requests do not match the ones that you configure on Rauthy's side, it will reject the request.

polarathene commented 1 month ago

Is your roundcube running on HTTPS

Yeah roundcube is accessible via http:// and https://

if yes, is it actually setting the redirect_uri query param during the redirect to Rauthy's /oidc/authorize correctly as well?

Yes I think so, here is the related roundcube config for URLs to rauthy. I've got this feature working correctly with Authelia so far (EDIT: I have double-checked Authelia config, it also was only configured for http:// redirect uri, so it should encounter the same problem), and rauthy works with http://.

$config['oauth_auth_uri'] = 'http://localhost:8080/auth/v1/oidc/authorize';
$config['oauth_token_uri'] = 'https://auth.example.test/auth/v1/oidc/token';
$config['oauth_identity_uri'] = 'https://auth.example.test/auth/v1/oidc/userinfo';

auth.example.test is actually behind a reverse proxy (Caddy) for container to container traffic. While to rule out Caddy affecting the web browser URL, I've got a direct http:// URI to rauthy.


When I click the login button this is the URL in the browser associated to the error:

http://localhost:8080/auth/v1/oidc/authorize?response_type=code&client_id=roundcube&scope=email+openid+profile&redirect_uri=http%3A%2F%2Frc.example.localhost%2Findex.php%2Flogin%2Foauth&state=OZTlcCmq8z7J

I'm not quite sure why it's being set to http here, or who is responsible for generating the URL. I assume that's roundcube, and my Authelia config perhaps was more lenient. I'll need to switch over and inspect there πŸ˜…

So... might not be caused by rauthy?

Rauthy does very strict validation. This means if any parameters during these requests do not match the ones that you configure on Rauthy's side, it will reject the request.

I figured it was something like that.

I'll try a few things on my end, and if I still have an issue I'll share a full compose.yaml to reproduce. I assume it's misconfiguration on my end, or whatever is affecting that URL to be generated incorrectly.

I still have rauthy ENV like COOKIE_MODE = danger-insecure still enabled from the http:// only working setup. I was going to remove that afterwards, but if that is affecting the https:// support here in some way I'll drop that πŸ˜“

polarathene commented 1 month ago

From what I've seen, it seems this might be an issue with Roundcube. Apologies for the noise.

sebadob commented 1 month ago

m not quite sure why it's being set to http here, or who is responsible for generating the URL. I assume that's roundcube, and my Authelia config perhaps was more lenient. I'll need to switch over and inspect there πŸ˜…

Your roundcube is responsible for creating this URI. Rauthy just validates the request against the configuration you allow for your roundcube client. If you want it to be available via both HTTP + HTTPS (just for testing hopefully), you can simply allow both redirect_uris for the client. You can add as many as you like. Just allow both versions and you should be fine.

In the end it makes a lot of sense to fix the issue in the first place of course. I can imagine that depending on how you access your roundcube UI, wether it's HTTP or HTTPS, that it builds the redirect_uri param with the same scheme.

From what I've seen, it seems this might be an issue with Roundcube. Apologies for the noise.

No worries. :)

polarathene commented 1 month ago

If you want it to be available via both HTTP + HTTPS (just for testing hopefully)

HTTP was just to make it initially a bit easier to test / setup locally, it'll all be HTTPS by the endπŸ‘


I can imagine that depending on how you access your roundcube UI, wether it's HTTP or HTTPS, that it builds the redirect_uri param with the same scheme.

Yes it seems that it was due to the reverse proxy handling TLS termination for HTTPS, then routing to the roundcube container HTTP port. As far as it was concerned it was HTTP traffic, so it only used http:// for the redirect_uri.

This was covered on their OAuth2 wiki page at the bottom. That became more apparent once I figured out this was due to the redirect_uri value πŸ˜…


For rauthy, if at all possible it might be a better UX if the "Show Details" information could provide a bit more context for the invalid_redirect_uri error... Perhaps something along the lines of "Expected , received via request ". That would help pinpoint better what exactly is invalid :)

That said, there's now this issue that's easy to discover if someone searches for anything in the title, which is good enough!


Closing as resolved πŸ₯³

sebadob commented 1 month ago

For rauthy, if at all possible it might be a better UX if the "Show Details" information could provide a bit more context for the invalid_redirect_uri error... Perhaps something along the lines of "Expected , received via request ". That would help pinpoint better what exactly is invalid :)

That would actually be a security issue. This can leak sensitive information and it does not show more details on purpose. The same is true for any invalid logins. You always get the same error message.

polarathene commented 1 month ago

That would actually be a security issue. This can leak sensitive information and it does not show more details on purpose.

Not saying it'd need to be by default, just that it'd have made the actual issue being reported easier to identify what was wrong.

Authelia doesn't show the values with it's error response, but the output it provides is still a better UX? It seems to have a generic error, but appends to that with more context. That context as seen below is more clear at clarifying the problem.

400 Bad Request status with JSON response body:

{
  "error": "invalid_request",
  "error_description": "The request is missing a required parameter, includes an invalid parameter value, includes a parameter more than once, or is otherwise malformed. The 'redirect_uri' parameter does not match any of the OAuth 2.0 Client's pre-registered 'redirect_uris'."
}
sebadob commented 1 month ago

400 Bad Request status with JSON response body:

Hmm got what you mean, but this is basically the exact same message as invalid redirect_uri, just with more words you need to read to get the same answer? And with a lot of additional "or" on top that make it even less clear?

I like to improve any UX of course, but I don't see how the longer, less clear message with the same meaning is better? I mean, I could add Malformed request: in front, yes. Can do this for all the possible validation error that can happen at that stage.

polarathene commented 1 month ago

TL;DR: A bit more context helps when you lack the familiarity to make sense of the vague hint, especially when it's the first integration attempt with a wider surface of unknowns as to where the problem might be.


With Authelia, I adapted a forward auth example on a basic page. That skipped the whole Dovecot + Roundcube integration part to just ensure everything else was working. I had not done such before that, so minimal examples for testing rauthy to reduce the problem area so I can rule out a bunch of concerns would probably help.


but this is basically the exact same message as invalid redirect_uri, just with more words you need to read to get the same answer? And with a lot of additional "or" on top that make it even less clear?

As a new user that wasn't as familiar with all the technical details with software like Rauthy, I had quite a bit to get familiar with to then adapt with the software I was integrating with (Docker Mailservers Dovecot service paired with Roundcube on the frontend). Each service had their own quirks I ran into, sometimes the origin of the problem was obscure.

Prior to Rauthy I had looked into Ory Hydra (was getting unwieldly as the first experience) and Kanidm (had some issues, wasn't sure if related to enforced HTTPS/TLS, so looked for another alternative to try), after Rauthy (which was working with HTTP) I tried Authelia to cross-check issues.

In addition to that there was the whole Docker => WSL2 => Windows 11 host stack along with some DNS concerns I was having.

invalid redirect_uri was non-obvious at the time while juggling all of that. I think I encountered it initially when I was just focused on the basic HTTP setup, resolved it and then got it again with HTTPS and couldn't figure out if it was something I misconfigured on Rauthy, something to do with Roundcube, or part of the whole OAuth2/OIDC flow that was a bit tricky for me to troubleshoot.

I understood that the redirect URI was not considered valid, but I had little context as to what rauthy was hinting at beyond that. I made sure that it wasn't anything to do with the reverse proxy by taking that out of the mix. I had example.localhost domain for access from the browser, and example.test for access between containers, I wasn't sure if there was an issue related to that.

I had not even considered looking through the long URL for a redirect_uri key there to notice a single character (http:// vs https://) was the actual problem. That only became apparent after realizing that the problem was avoided by reverting back to http:// with the redirect URI, even though I was using HTTPS for both Roundcube and Rauthy.

Roundcube being routed to via reverse proxy to the Roundcube containers port 80 after terminating TLS apparently affected that software here. I did not know at the time who was responsible for constructing that URL in the login flow or if the Roundcube service was using an incorrect URI scheme because of information it was getting from Rauthy (the only place I had configured a redirect URI explicitly). It required knowing of a setting in Roundcube to fix that, so that it forced HTTPS, or for Rauthy to at least have an http:// redirect URI configured (which would then have the reverse proxy redirect back to HTTPS). I wanted to know what was preventing the https:// URI from being correctly configured / functional.

I also wasn't sure during this if there might be some issue with caching / cookies and the like. I recall with some browsers (Firefox perhaps?) they would not always clear cache for redirects (such as perma redirect responses). So as a user with all that going on, I was a bit lost from the unfamiliarity.

For you I understand it'd be much more obvious πŸ˜… (I had avoided reporting an issue for hours while trying to figure it out, then reached out as I continued the troubleshooting)

As for how Authelia is more helpful:

The request is missing a required parameter, includes an invalid parameter value, includes a parameter more than once, or is otherwise malformed _The 'redirect_uri' parameter does not match any of the OAuth 2.0 Client's pre-registered 'redirecturis'.

The first line is rather generic / broad, so not that helpful. The 2nd line is specific to the actual error from the request though.

I now know that that it's because there is a mismatch in what is configured for the client at the IDP. It's not just "invalid" which could imply I misconfigured that at the IDP.

The experience for me visually was: Roundcube login (click button) => 400 Bad Request

I clicked a button, redirected to the IDP but something about that was problematic. invalid redirect_uri and the relation to a request was not a lot for me to go by given all the above concerns. I did not click that redirect_uri was referring specifically to the OAuth2 client redirect URI, Authelia made that connection much more clear.

Other issues I had experienced in this process was after clicking the button I get redirected to auth service and back to the login page and there's a failure encountered somewhere to troubleshoot.

One that was more confusing was being presented the IDP login page, but as I started typing the credentials, I was redirected back to Roundcube login page and notified the login failed.


I like to improve any UX of course, but I don't see how the longer, less clear message with the same meaning is better?

This was just my experience, and I recall a few other issues/discussions here at Rauthy related to invalid redirect_uri (which I landed on early in the troubleshooting process), but they resolved it by configuring Rauthy ENV PUB_URL / LISTEN_SCHEME and such which had nothing to do with the issue I actually had.

I consider the discussion in this issue to be sufficient. If I came across this information for invalid redirect_uri I'd have solved it much more quickly 😝

So I don't think you need to improve the error message. "Show details" just wasn't that helpful when all it had was invalid redirect_uri to go on at the time is all πŸ€·β€β™‚οΈ

If others chime in with similar problems (or somehow miss this issue), then it might be worthwhile to provide a bit more guidance with the error message content.

sebadob commented 1 month ago

Okay, that makes sense.

The good thing is that even though I need to check the request params in a few places, I can pretty easily add a hint to all of them, just mentioneing that the request is malformed and so on. That should help in cases like yours when dealing with so many issues at once.

The PUB_URL can make trouble with a bad config when the redirect for Rauthy's own login does not work, yes.

I guess I will add a Troubleshooting section to the docs and just write down some common issues. That should help a lot as well. The only problem is, that it is quite hard for me to come up with common things because for me all of this is 2nd nature of course, but I can at least start and improve while new questions come up.

Thanks alot!