Related: https://pagure.io/koji/issue/3393
/tests will be fixed when we agree on solution/
pretty please pagure-ci rebuild
I'll start with the big one. I'm not sure we should use cookies for this. Cookies are tied to browser behavior and the hub is not intended to be accessed with a browser. Also, while python-requests makes using cookies fairly easy for us, things might be more involved for non-python clients.
The key thing we need to do here is get this information out of the url. The simplest thing is probably to just put this data in a custom header of the client request.
Next big things are fallback behaviors.
In the current version of this PR, the hub no longer supports the url parameters at all (in fact the args parameter to the session class is unused). This means that version n-1 will be able effectively authenticate with the version where this lands.
args
I realize that we want to expunge these url parameters, but I think we should allow for backwards compatibility for at least a brief time. Best thing is probably to have a hub config option to allow it it and deprecate the behavior. We can remove it in a later version.
Secondly, while the client code does have fallback behavior, it ends up sending every call twice which is not ideal. The client should remember that the server needs the fallback.
Server could report in sinfo that the new behavior is expected. Client could easily cue its behavior off of that.
I'll start with the big one. I'm not sure we should use cookies for this. Cookies are tied to browser behavior and the hub is not intended to be accessed with a browser. Also, while python-requests makes using cookies fairly easy for us, things might be more involved for non-python clients. The key thing we need to do here is get this information out of the url. The simplest thing is probably to just put this data in a custom header of the client request.
Yep, it looks like safer solution, on the other hand, cookies are pretty standard now even for xmlrpc. User-side cookie is de facto just a header - is there any important difference to handling custom header? With potential future things like automatic session reauth for expiring sessions we would probably end with cookie-like behaviour.
ping @mikem
on the other hand, cookies are pretty standard now even for xmlrpc.
I'm not sure that's true.
On the flip side, for REST apis it seems like JWT is an emerging standard (not that I'm suggesting we use those right now).
With potential future things like automatic session reauth for expiring sessions we would probably end with cookie-like behaviour.
Ultimately, cookies are solving a much larger problem than auth and bring with them a very complex history.
I think that while we may overlap a bit with some aspects of cookies, that overlap is not going to be perfect or complete.
rebased onto f0713af0a6f684bdf7a277cee10df3b070efca93
2 new commits added
use header-based auth
cookies-based sessions
The RH Bugzilla authors recently had to solve a similar problem. They added an "Authorization" header, like this:
Authorization: Bearer <api-key-string>
I like this implementation because it's very simple for client authors. In particular, there's only one value to handle instead of Koji's two (session-id and session-key). Can we use this opportunity to start dropping session-id handling?
session-id
session-key
I wonder how easy it will be for non-Python XML-RPC clients to add HTTP headers. I did it for my txbugzilla library but I don't have experience with the other ecosystems like the java or go clients that perform a lot of authenticated calls.
callnum
Re: token as a single point of failure - yes, this is the case for essentially all web applications. I think we should set SSLRequireSSL for the entire Koji application in Apache (see #2163).
SSLRequireSSL
Maybe the word "Bearer" in an Authorization header is simply too generic and too easy for developers to confuse with OpenID (it originally came from OpenID).
What if you renamed the header in this PR from "X-Session-Data" to "X-Koji-Session"? I think that would be clearer in logs and client libraries what this is.
I wonder how easy it will be for non-Python XML-RPC clients to add HTTP headers
Even in python, the native xmlrpc.client lib only added the headers option in 3.8. It would not be surprising if other implementations don't make this easy since headers aren't really part of the xmlrpc spec.
headers
In Koji, we handle our connections with python-requests and only use the xmlrpc lib for encoding and decoding the request, so we've been able to control our headers for a while. Good thing too, since we'll need to backport this for py2.
we can theoretically drop session-id with ensuring that session-key is really unique (this is not true now)
Easiest way to ensure uniqueness is to embed the session-id. We already embed the userid, and it looks like a very simple change to include the session id.
I do like the idea of keeping this header simpler, so a single key with session-id embedded would be preferred. That should allow us to simplify these changes a bit (e.g. avoid importing email and simplify the header parsing in auth.py.
auth.py
Might be better to invert the sense of the config option to AllowURLSessions. Also, it should not be grouped with the kerberos-specific options. The more general auth settings are a bit later.
AllowURLSessions
@mikem So, you mean just passing 'X-Session-Id' via headers and leave callnum in query string?
So, you mean just passing 'X-Session-Id' via headers and leave callnum in query string?
Hmm, so I guess I'd say specify that in a separate header for callnum. It looks like passing callnum is technically optional, so if a 3rd party client leaves this out it should just skip the callnum check.
As far as header naming, it appears that using the "X- prefix is deprecated, so perhaps is it simpler to just prefix everything with Koji-, e.g.
Koji-
Koji-Session-Id Koji-Session-Callnum
Another aspect of your question is whether we want to support mixing the two when AllowURLSessions is set, and I think probably not. I'd like to encourage code for move forward and it would be nice to get those urls cleaner.
rebased onto 261880638845301676202815cc20b85850edf49a
Ok, I think this is about where it needs to be. Just a couple things.
import email
self.message = 'no session header or session args'
1 new commit added
remove unused code
:thumbsup:
Metadata Update from @tkopecek: - Pull-request tagged with: testing-ready
Metadata Update from @jobrauer: - Pull-request untagged with: testing-ready
Testing-ready temporarily removed due to a merge conflict on the testing branch.
Metadata Update from @jobrauer: - Pull-request tagged with: testing-ready
rebased onto 91cea0d8be6e4eb474e6d60fb55889b9fbfed6b5
Metadata Update from @jcupova: - Pull-request tagged with: testing-ready
rebased onto f8c38509a6adb4b48bcfcee6855a3bc873e5d294
Metadata Update from @jobrauer: - Pull-request tagged with: testing-done
fix tests
Commit fcee31ab fixes this pull-request
Pull-Request has been merged by tkopecek
Related: https://pagure.io/koji/issue/3393