Our problem is due to komga being served on a baseurl, inside of a system that relies on an established baseurl system.
Logging into komga overwrites the basic auth credentials stored for the rest of the system. This would be acceptable if komga did not force the "email" format for the username
Either
None available
We have implemented Komga in our "media server" application toolbox, you can find the feature merge commit here, and this is how we use our basic auth for other applications (sonarr example). A username always corresponds to the linux user's name.
Logging into komga overwrites the basic auth credentials stored for the rest of the system
Can you clarify that part? What is komga overriding exactly?
Our problem is due to komga being served on a baseurl, inside of a system that relies on an established baseurl system
What's does that mean? Can you clarify or give an example?
Heya, Thanks for the fast response!
Can you clarify that part? What is komga overriding exactly?
Komga is setting the basic auth credentials in the browser. I have not looked too deeply into your codebase, but one of our other maintainers showed me this reference https://github.com/gotson/komga/blob/3834d415aea2d61067c7b428468d5b7531f9c964/komga/src/main/kotlin/org/gotson/komga/infrastructure/swagger/SwaggerConfiguration.kt#L26
What's does that mean? Can you clarify or give an example?
When a user install our toolbox, the root of their domain runs a python-based panel, which uses basic-auth. The .htpasswd file is generated from the toolbox, and uses the same credential pair that is used for the user on the linux machine (e.g. for SSH, etc.)
Most of our other applications are set up to use this basic auth as a rudimentary for of SSO. This means if you log into the panel, your credentials are valid for visiting your torrent client, your Sonarr instance, etc.
As Komga overwrites the basic auth in the browser's session, this "logs the user out" of the SSO.
Let me know if you'd like any further clarifications :)
Komga doesn't overwrite anything. Your project is using ngnix for reverse proxying everything to the different apps from what I can see from the PR your linked above. You need to configure ngnix to _not_ send the basic auth information used at the proxy level to the site that is being proxied, else there is a conflict.
I did a bit of digging, basic Auth (and any kind of Auth actually) can be shared on the same server (canonical url) if they don't share the same realm.
On your code base you use the same realm everywhere for all the apps (that's the nginx parameter of the auth_basic directive).
In Komga there's no realm set, so the default of Spring Security is used (Realm).
There shouldn't be any need for any change in Komga for this to work, changes should be done in your project to use proper realms between the various apps, and not forward the basic auth credentials from the proxy to the subsites.
Hey again, thanks for the tips.
So I've tried what you suggested by setting a different "realm" for the komga endpoint, and it indeed does not break the rest of our configuration. A different issue arises as this it breaks komga's auth mechanisms somewhat.
The komga nginx config in the recording below was set to this
location /komga {
proxy_pass http://127.0.0.1:6800/komga;
auth_basic "Realm";
}
I'll let you know if I'm able to find something else, let me know if you'd like to see some of the headers or anything
On your code base you use the same realm everywhere for all the apps (that's the nginx parameter of the
auth_basicdirective).
We do this on purpose for the reason of having this "SSO" mechanism.
You shouldn't need to set any auth for the Komga endpoint I think, and I think you need to disable the forwarding of the auth, apparently it can be done like so proxy_set_header Authorization "";
So that seems to resolve the basic auth popups, but it seems to break Komga's auth mechanism slightly further.
First I thought I forgot my password but then when I tried with a fresh install, I could not even create an account.
The example below uses this conf
location /komga {
proxy_pass http://127.0.0.1:6800/komga;
auth_basic "Realm";
proxy_set_header Authorization "";
}
From the looks of it, the register/claim endpoint works as it returns a 200 and the JSON of the ID and everything.
The login/me returns a 401 with the following raw headers in the request and response respectively.
GET /komga/api/v1/users/me HTTP/1.1
Host: 10.211.55.6
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:88.0) Gecko/20100101 Firefox/88.0
Accept: application/json, text/plain, */*
Accept-Language: en,en-US;q=0.7,cs;q=0.3
Accept-Encoding: gzip, deflate, br
X-Requested-With: XMLHttpRequest
Authorization: Basic <This here a token>
DNT: 1
Connection: keep-alive
Referer: https://10.211.55.6/komga/login?redirect=%2Fdashboard
Cookie: JSESSIONID=7A9FE976FB1E310139735620EB8C8940
Pragma: no-cache
Cache-Control: no-cache
HTTP/1.1 401
Server: nginx
Date: Sat, 08 May 2021 12:41:18 GMT
Content-Length: 0
Connection: keep-alive
Vary: Origin
Vary: Access-Control-Request-Method
Vary: Access-Control-Request-Headers
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
X-Frame-Options: DENY
While I am not a Kotlin/JS webdev in any way; as a constructiove suggestion, what are your thoughts on bearer authentication with JWT tokens instead of basic auth? Do you think the effort would justify the benefit? It's the same philosophy of storing the token on the client, and not using a cookie/session for it.
When I was googling Spring boot vue authentication it popped up before anything with cookies or sessions, ha! https://bezkoder.com/vue-3-authentication-jwt/
Try to disable auth via auth_basic off. You don't need to setup basic Auth at the proxy level for Komga.
Changing that to off achieves the same as the last example above. Setting the header to remove Auth completely will not allow the basic auth to pass between the client and komga as the nginx will wash it out.
location /komga {
proxy_pass http://127.0.0.1:6800/komga;
auth_basic off;
proxy_set_header Authorization "";
}
And removing proxy_set_header Authorization ""; and leaving it to auth_basic off will produce the same issues as we already tried in https://github.com/gotson/komga/issues/531#issuecomment-835310637
When calling the /me endpoint the call is triggered by javascript, with the login / password provided. A session ID cookie is returned. That cookie is used for authentication afterwards.
Basic auth is not managed by the browser directly.
Just to check, are you clearing all your browser's cache and credentials or using incognito mode to test every single configuration?
I do the following with every example above:
~/.komga and restart the komga serviceQuick question : do any of the other apps you proxy have authentication? Or do you disable the app's authentication and let nginx do the auth centrally?
Well, it's a mix of both of the two. We use the basic auth for authentication wherever we can, and if it can do authorization for us too then that's extra awesome.
Apps like Sonarr which I linked above, have all app-side authentication disabled, and nginx handles the authentication with basic auth. This allows us to do the "SSO". These apps don't really have authorization built in.
But some apps, like our panel and a couple others use it for authorization too. For example, Nextcloud does the same (you log in via panel, and nextcloud will check the header against its own database and log the user in accordingly), and that lives on a baseurl as well. The requirement there is for the nextcloud username and password in its database being identical, which is something we handle in our installation. Ideally for us, this would be the case with Komga as well, but it would require a transition from email -> username by possibly just removing the validation in the registration/login forms, as the database should not complain about that change. (But hey that's a call of yours to make :))
We also use the basic auth in order to assign a correct session of a torrent client's webui to the user (e.g. rutorrent, transmission, etc.; you just log in and nginx correctly "assigns" the right socket to you based off the username), but this falls more into the "no app-side auth and let nginx do it" category.
Applications that do not support zero authentication and do not support basicauth for "SSO" are then just unmanaged, and we do not use basic auth on them. Wherever possible, we try to pre-create the user with the same system credentials to avoid confusion. I was under the assumption this was the case with komga originally as I was testing the panel on a baseurl. Switching to bearer/JWT would put Komga into this category as well.
Sorry for the wall of text ha
Unlike arr services komga is more of management and reading service where you can create users and allow different library access. So disabling authentication might won't work. That means every user will have access to all the libraries as they will be logging in with same credentials or basic authentication.
Unlike arr services komga is more of management and reading service where you can create users and allow different library access. So disabling authentication might won't work. That means every user will have access to all the libraries as they will be logging in with same credentials or basic authentication.
Indeed, I'm aware of this and it would have to limit the app to a single user as I mention in the OP, which I assume that would require quite a lot of modifications.
I would assume it would be easier to add an extra column for JWT in the database and switch to bearer authentication logic, or disabling the email verification on the registration and find-replacing the field to "username" or "login" (which might avoid creating DB migrations altogether). Bear in mind I have next to no vue.js knowledge and am only working on assumptions.
The latter of these two suggestions would allow us to use the basic auth for SSO with authorization which would integrate amazingly into our setup.
Thanks for the details on how your project work.
While checking stuff on http authentication, I stumbled upon something called proxy authentication : https://developer.mozilla.org/en-US/docs/Web/HTTP/Authentication#proxy_authentication
As both resource authentication and proxy authentication can coexist, a different set of headers and status codes is needed.
I think this is what you actually need in nginx. Not sure how to use the proxy authentication header instead of the normal one, but that seems to be the solution you need.
As for the changes in Komga you suggest.
First I don't think a project should need changing because an integration of it doesn't work. Imagine integrating a closed source paid software which won't change how would you do it then? You would have to adapt on your end.
Secondly, the changes you propose could as well be done on your side. Using an email instead of username is something you could apply on your end.
Moreover, the changes you propose don't necessarily make sense for Komga:
Using the same login and password between the proxy and the apps is also not an ideal solution, it creates coupling on the format.
If tomorrow next cloud has a strong password requirement, but another app has a different password requirement, and they are not compatible, then you're screwed.
Hope that clarifies my view on things. I think the proxy authentication mentioned above should work.
Thanks for the details on how your project work.
While checking stuff on http authentication, I stumbled upon something called proxy authentication : https://developer.mozilla.org/en-US/docs/Web/HTTP/Authentication#proxy_authentication
As both resource authentication and proxy authentication can coexist, a different set of headers and status codes is needed.
I think this is what you actually need in nginx. Not sure how to use the proxy authentication header instead of the normal one, but that seems to be the solution you need.
Thanks, I'll look into this later on, it's time to enjoy the terraces opening here this weekend :)
First I don't think a project should need changing because an integration of it doesn't work. Imagine integrating a closed source paid software which won't change how would you do it then? You would have to adapt on your end.
On paper, this is indeed true. However there's also certain unwritten standards which have been established for how these mechanisms work, which other applications have been working with before, and no modification was needed on their end to integrate into our project. Komga stands out in this regard.
Secondly, the changes you propose could as well be done on your side. Using an email instead of username is something you could apply on your end.
This could be possible, but it's the wrong effort in the wrong place. We do not intend to make modifications to the application, maintain the JDK and node environment on the end-user's machine. We _do_ have build systems in place for libtorrent-based torrent clients, but that is due to our end-users wanting to tweak it at their own discretion, and not for ensuring compatibility of the web frontend with the rest of the applications.
Moreover, the changes you propose don't necessarily make sense for Komga:
These first two changes are indeed not the most favourable ones. There could be something in the area of adding another column to the user table for a username that could also be used for authentication, but yeah that's just yet one more proposal on its own.
* using different authentication methods is something that could happen, but keep in mind that Komga offers an OPDS feed, and OPDS only supports basic authentication. So basic authentication will remain anyhow. Moreover, let's say there was another authentication mechanism, if someday your project switch from basic Auth to that same authentication scheme, the same problem would happen, because right now the problem is that both the proxy and the app uses the same authentication mechanism.
I don't believe we would run into the same issue with authentication collision using bearer auth, the primary technology under OAuth2. Multiple bearer tokens is a well-know usecase. It essentially is a solution to this very problem of basicauth collision.
On a side note, we do intend to support Authelia in the future.
Furthermore you can have different authentication methods for different endpoints. We're specifically talking about the HTTP web front end here, the authentication of an API/OPDS/etc. is not necessarily much of my concern in this situation. Either way, Calibre-web, Calibre Content Server, Mango and other applications already have a working solution for this problem, and they offer session/cookie based OR basic-auth authorization which is not constrained by an email address format. The important bit there is that they're flexible, offer a choice, and cooperate with the expected deployment of basic auth for authorization.
If tomorrow next cloud has a strong password requirement, but another app has a different password requirement, and they are not compatible, then you're screwed.
We already have a password requirement which is stronger than most apps through the use of cracklib. We have previously made adjustments to password policy so this wouldn't be anything new to us either.
Besides, if that happens, Nextcloud would gracefully handle this as it does not overwrite the basic auth when it is not successful against its database, and offers alternative authentication methods. The only way to log a user out with basic auth is to overwrite the stored credentials with invalid ones.
To sum up, the choices for authentication made in Komga are very out of sync with the expected standard among these kinds of projects. I understand this is a personal hobby project and it is not my place to tell you what to do, but I do want to point out some of the shortcomings and offer you an insight in how you could improve this situation for yourself as well as your end-users for the long term.
We would love to include your project in our toolbox, but given this incompatibility which is unique compared to the other 50+ applications we've come to support, we might have to reconsider its inclusion.
Anyhow, I will still see what I can hack together with the RP suggestions you gave, if you still have any other tips that could ensure this compatibility, let me know.
Thanks in advance, and a nice sunday!
Secondly, the changes you propose could as well be done on your side. Using an email instead of username is something you could apply on your end.
This could be possible, but it's the wrong effort in the wrong place. We do not intend to make modifications to the application, maintain the JDK and node environment on the end-user's machine. We _do_ have build systems in place for libtorrent-based torrent clients, but that is due to our end-users wanting to tweak it at their own discretion, and not for ensuring compatibility of the web frontend with the rest of the applications.
Sorry if I was unclear, I did not meant for you to do changes in Komga, but for you to adapt your project to use email based username instead of non-email.
I don't believe we would run into the same issue with authentication collision using bearer auth, the primary technology under OAuth2. Multiple bearer tokens is a well-know usecase. It essentially is a solution to this very problem of basicauth collision.
Yes you would. The Authentication header would still be shared, and you would have the same conflict. That's why the Proxy-Authentication header makes sense.
they offer session/cookie based OR basic-auth authorization
Session/Cookie still needs to be triggered by providing username/password. Komga is also using sessions via cookies.
out of sync with the expected standard among these kinds of projects
That's a very personal view. Komga is using standards that fit security requirements. Basic Auth is a very good way to provide a login/password for authentication, and as mentioned previously it is only used once in the frontend to get a session cookie.
I do want to point out some of the shortcomings and offer you an insight in how you could improve this situation for yourself as well as your end-users for the long term.
I am sorry, but the only shortcoming i see is that it cannot be integrated in a project who chose very specific and, IMHO, incorrect ways of integrating SSO for multiple apps. It may have worked for you until now, but it has clear limitations, and doesn't follow the usual designs for SSO.
Thanks in advance, and a nice sunday!
Have a good one!
Most helpful comment
Thanks, I'll look into this later on, it's time to enjoy the terraces opening here this weekend :)
On paper, this is indeed true. However there's also certain unwritten standards which have been established for how these mechanisms work, which other applications have been working with before, and no modification was needed on their end to integrate into our project. Komga stands out in this regard.
This could be possible, but it's the wrong effort in the wrong place. We do not intend to make modifications to the application, maintain the JDK and node environment on the end-user's machine. We _do_ have build systems in place for libtorrent-based torrent clients, but that is due to our end-users wanting to tweak it at their own discretion, and not for ensuring compatibility of the web frontend with the rest of the applications.
These first two changes are indeed not the most favourable ones. There could be something in the area of adding another column to the user table for a username that could also be used for authentication, but yeah that's just yet one more proposal on its own.
I don't believe we would run into the same issue with authentication collision using bearer auth, the primary technology under OAuth2. Multiple bearer tokens is a well-know usecase. It essentially is a solution to this very problem of basicauth collision.
On a side note, we do intend to support Authelia in the future.
Furthermore you can have different authentication methods for different endpoints. We're specifically talking about the HTTP web front end here, the authentication of an API/OPDS/etc. is not necessarily much of my concern in this situation. Either way, Calibre-web, Calibre Content Server, Mango and other applications already have a working solution for this problem, and they offer session/cookie based OR basic-auth authorization which is not constrained by an email address format. The important bit there is that they're flexible, offer a choice, and cooperate with the expected deployment of basic auth for authorization.
We already have a password requirement which is stronger than most apps through the use of
cracklib. We have previously made adjustments to password policy so this wouldn't be anything new to us either.Besides, if that happens, Nextcloud would gracefully handle this as it does not overwrite the basic auth when it is not successful against its database, and offers alternative authentication methods. The only way to log a user out with basic auth is to overwrite the stored credentials with invalid ones.
To sum up, the choices for authentication made in Komga are very out of sync with the expected standard among these kinds of projects. I understand this is a personal hobby project and it is not my place to tell you what to do, but I do want to point out some of the shortcomings and offer you an insight in how you could improve this situation for yourself as well as your end-users for the long term.
We would love to include your project in our toolbox, but given this incompatibility which is unique compared to the other 50+ applications we've come to support, we might have to reconsider its inclusion.
Anyhow, I will still see what I can hack together with the RP suggestions you gave, if you still have any other tips that could ensure this compatibility, let me know.
Thanks in advance, and a nice sunday!