Den lör 24 maj 2025 kl 14:01 skrev Branko Čibej <br...@apache.org>:
> On 23. 5. 25 23:48, Peter Balogh wrote: > > Hi, > > The reason I choose the 499 status code, that it was the cleanest way to > reroute the 2FA case in auth.c dispatch_auth function > Hard-coding the 401 can also accomplish this > But without that, I have two directions I can take, and I'd appreciate > some insight, what should I try next: > > 1. > I can provide a response with 401 status and valid WWW-Authenticate header > where I control the realm string > I can use that to intercept the 2FA request in > svn_ra_serf__credentials_callback in libsvn_ra_serf util.c, and do the 2FA > input > That combined with bearer token, that we return could work without > modifying serf > > 2. > I can introduce a new serf__authn_scheme_t, and have a cleaner > implementation, but it means serf would have an unofficial auth scheme > implementation > > I'm all for doing the right thing, working out how to extend the RFC, but > I have 0 knowledge or experience doing that > I'm happy to help any way I can, but I'd rather not wait for months, > before implementing this :) > > What do you think, what route should I explore next? > Do I have a change to get the 1. version approved by the svn community? > Do I have a change to get the 2. version approved by the serf community? > :) > > > > I guess that you realise by now that there's a large overlap between the > two. :) > > I just read through RFC 7235 and the way I read this, It's perfectly OK > and blessed from on high to use status 401 to require a multi-factor token. > The interaction would look like this: > > > 1. Client: sends request to URL > 2. Server: responds with 401 + WWW-Authenticate for initial > username+password authentication, with Subversion's realm=... parameter > 3. Client: sends to URL + Authorization with username and password > > (This is how it works now, regardless of authentication type, and the > client continues to send further requests with the same Authorization > header. In the multi-factor scenario, what happens next is; I'll illustrate > with TOTP): > > 4. Server responds with 401 + "WWW-Authenticate: TOTP realm=..." > 5. Client: sends to URL + "Authorization: TOTP 123456" (the time-based > PIN) > 6. Server: processes the request and responds with a generated token > in a header (or cookies). The token could be a JWT if we want more control > or a random token as suggested by Greg. > 7. Client sends "Authorization: Bearer <token>" with further requests. > > > This works for other 2FA schemes, too; for example, in step 4 the server > could respond with "WWW-Authenticate: SCRAM challenge=Y2hhbGxlbmdlPw==, > realm=..." and in step 5 the client would respond with "Authenticate: > SCRAM cmVzcG9uc2Uh", using the shared secret and the challenge to > generate the token. > > This does not require any changes in Serf and is, as far as I can see, > compliant with RFC 7235. But you do need an authentication handler on the > server side to handle the second (and third and fourth... there's no reason > this would be limited to two factors). Also if you use some random token, > the authn handler has to store it and eventually invalidate it; a JWT > contains its expiration time, removing the need for a token database on the > server, but it's a bit of a pain to implement. > > On the Subversion client side, libsvn_ra_serf might have to grow another > hook for multi-factor callbacks, and we'd need another authentication > provider that would store the shared-secret per realm, similar to what the > username provider does now. > This sounds very good to me, much like the understanding I have at the moment. As I understand WWW-Authenticate, it is possible to add multiple authentications at the same time. If we would have a server-wide 2FA setting (ie, all users are required ot use 2FA), we could possibly combine steps 2 and 4 into a single step, saving a roundtrip to the server. (We don't need to know the user before requesting a TOTP - as long as we get the username we can verify it afterwards). Only maybe if it is difficult to send multiple Authorization: headers. Kind regards, Daniel > > > > Best regards, > Peter > > On 2025. 05. 23. 17:28, Branko Čibej wrote: > > On 23. 5. 25 17:05, Daniel Sahlberg wrote: > > Den fre 23 maj 2025 kl 00:35 skrev Peter Balogh<pe...@svnplus.com> > <pe...@svnplus.com>: > > Hi, > > So basically the patch becomes this > I can't say I like the actual branch condition, but I'm open to > suggestions :) > > Hi, > > I have not studied the patches in detail but I'm not so sure if I like the > idea of Serf special-casing / hardcoding a custom response reason. I feel > it would be better to offloading this to Subversion since we control both > ends there. > > > > I agree. Serf is a general-purpose HTTP client, what we're talking about > here is application-level behaviour. Serf already offloads authentication > to the application, I also can't see a reason why this would be > special-cased in Serf. > > Also, RFC7235 [1] require a 401 response to send a WWW-Authenticate header > - I don't know if it would be possible to use this to send the challenge. > > > I have to read up on WWW-Authenticate. ISTR that aside from telling the > client /how/ to authenticate, it's there also support complex > authentication processes. > > The response could then be added as a header field. Would it be possible > for the server to return a bearer token (= more or less the same as a > Set-Cookie) that we could store client-side to include on future requests? > > > I'm surprised that multi-step challenge/response mechanism isn't already > standardised in HTTP. True, all the multi-factor schemes I've used to date > are for authentication flow in browsers, where the server presents a user > interface. For headless cases, things like API tokens tend to be generated > in advance through an out of band channel (again, usually through a UI in a > browser). App tokens are, again, not multi-factor authentication. > > Maybe we will have to invent an HTTP workflow for this, but let's not go > it alone. This is, after all, the ASF and there are a few people around > that are ... quite knowledgeable about HTTP. I suggest we consult. Worst > case, there may be an IETF RFC waiting to be written. > > -- Brane > > > P.S.: I say "worst case" because it should've been written long ago > instead of people using status 499 and stuff like that. > > >