-
Notifications
You must be signed in to change notification settings - Fork 24
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
HTTP 401 MUST return a WWW-Authenticate header #65
Comments
Worth noting that while RFC 2616 is of course obsolete, the current RFC has similar language (https://datatracker.ietf.org/doc/html/rfc7235). |
@MattMenke2 thanks for the reminder about updated RFCs--based on the obsolete one I was going to say 403 might not be appropriate, but per updated RFCs it should be OK: "The client SHOULD NOT automatically repeat the request with the same credentials. The client MAY repeat the request with new or different credentials. " citation I agree it seems cumbersome to define a new authentication scheme just for this. I feel like I've seen (don't ask me for examples) a few cases where a service returned 403 when a 401 might have made more sense. Now I'm wondering how often that was because the engineer didn't want to bother returning the WWW-authenticate header but needed to comply with the spec. 😂 |
I think a 403 would be reasonable, though I'm no expert on how 403 are typically used (or intended to be used). Another option would be to return a 200 with a no-cache, no-store header. Main advantage of the 4xx status code is that it informs any intermediaries that this is an error and should not be cached, and potentially shows up in any applicable logs as an error. |
Separating it out from an error code would also allow redirecting browsers that don't support to, e.g., an alternative login flow or whatnot, rather than having to sniff browser version to determine compatibility. So return a redirect + challenge. If browser knows how to handle the request, it send credentials. Otherwise, it follows the redirect. That's how Sec-Session-Storage (?) works. I guess as specified, the 401s aren't actually normal loads, but rather browser-initiated loads in response to other requests, so I that capability may not be useful here. |
Uh oh. As I read this, I think I've stepped into a can of worms. Three observations:
So this leaves me a bit confused! On the one hand, I think point 3 above matches your point, @MattMenke2, that these aren't normal page loads, so the advantage of serving existing error codes is limited. On the other hand, point 2 suggests to me that it's important that unexpected errors from But, point (1) makes me think the server can choose to merely return a Whew! Now, I sort of think the state machine for client-side behavior is something like:
All of that suggests to me that we can just get rid of specifying HTTP response codes entirely on calls to Sorry for the very long response. Does that reasoning make sense? Footnotes
|
Oh, and to my comment
I think this means that if there is an error code from |
Alternatively, could just consider the session refreshed until it's refresh time again, or the server tells us otherwise, but since I don't think we tell the server in normal requests about the live session, unlike cookies, killing the session on error does seem reasonable to me. |
I think there are a few options:
I don't feel strongly about this (I argued for 302 for a long time, primarily for backwards compatibility). Happy to update as needed to what others want. I think right now, I would propose we try (1) unless we meet large resistance. I should say currently there is an option where the refresh requests doesn't happen, but instead the browser start signing every request and the server can reply with 401. So the client need to expect 401 on different requests, but all requests that can have a 401 response have "Sec-Session-Response: JWT" header in the request. |
302 feels right, but may cause the wrong things to happen in browsers/clients that handle this differently. Since the DBSC process starts authentication, wouldn't it make sense that the www-authenticate header is still returned with the matching information? Is somehow using this incompatible with DBSC? |
I don't see how a 3xx code makes any sense, since the followup request is made to the same URL, so it's not a redirect. |
3xx can be used with a redirect to yourself (or a new url as needed) as it works with current web standards. I agree that 401 feel more right to me. |
Redirects provide error handling, without having to send a full error page to display to the user to browsers that support the feature. With a 401, if you want an error page, you have to send it out every single time you want the cookies, even if it's supported by nearly every browser that visits your site. |
And just to make sure we're on the same page: First response, say for https://foo/cookie-request would get the challenge header and a redirect to https://foo/cookie-request-not-supported. If the browser can handle the challenge with another network request, it does so, and then re-requests https://foo/cookie-request with any additional cookies that it set. If it does not, it follows the redirect to an error page / alternative login. So the redirect would be for browsers that don't support the feature. Alternatively, a server could just send a 4xx error page...Basically, the response code handling, and the header handling are entirely independent. If a browser sees the header, it sends another fetch, and then re-requests the original URL, regardless of the status code. If it does not, normal handling proceeds. So the HTTP status code and this feature have no interactions with each other. We don't need a new status code. Edit: Nor do we need to require the use of a specific pre-existing one. |
@MattMenke2 I might be misreading you, but just to reiterate one point which may or may not be clear: as described here, the |
So it's been 3 months since I made the comment folks were responding to, and haven't thought about this stuff since, so I've completely lost all context. I still think a 401 is wrong here, since this is not structured at all like HTTP auth. We also don't even need a special response code here - this is a request that's being managed by code that's looking for the challenge, all we need is the challenge header, not a special response code, if we want to make a new request. The network layer doesn't need to know what's going on at all (well, requests do need to bypass the cache, but that's just an HTTP-network fetch, already covered by the fetch spec, as opposed to an HTTP-network-or-cache fetch. So the response code is entirely irrelevant, if this is structured as multiple network requests managed outside the network layer, as opposed to the network layer retrying a network request. |
Yes, your point is similar to mine: the client knows this is a special
“refresh” request, so the specific response code isn’t too important, as
you say.
…On Thu, Sep 26, 2024 at 22:46 Matt Menke ***@***.***> wrote:
So it's been 3 months since I made the comment folks were responding to,
and haven't thought about this stuff since, so I've completely lost all
context.
I still think a 401 is wrong here, since this is not structured at all
like HTTP auth. We also don't even need a special response code here - this
is a request that's being managed by code that's looking for the challenge,
all we need is the challenge header, not a special response code, if we
want to make a new request. The network layer doesn't need to know what's
going on at all (well, requests do need to bypass the cache, but that's
just an HTTP-network fetch, already covered by the fetch spec, as opposed
to an HTTP-network-or-cache fetch. So the response code is entirely
irrelevant, if this is structured as multiple network requests managed
outside the network layer, as opposed to the network layer retrying a
network request.
—
Reply to this email directly, view it on GitHub
<#65 (comment)>, or
unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAOW7C42UZDN6QQ5ODLWSOLZYRXB7AVCNFSM6AAAAABLQIWJPWVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDGNZXHEYDKNRVGU>
.
You are receiving this because you authored the thread.Message ID:
***@***.***>
|
We initially wrote here that the HTTP request that triggers a challenge/response should serve an HTTP 401 response code and a
Sec-Session-Challenge
header.But per https://datatracker.ietf.org/doc/html/rfc2616#section-10.4.2, a 401 MUST return a
WWW-Authenticate
header.Without having put any thought into this, I can see a few obvious options:
Sec-Session-Challenge
header with aWWW-Authenticate
header.I see the point of doing (1) just to avoid violating the spec--(2) seems like a better choice for that. And I could see some value in reusing HTTP authentication if we think that the DBSC-style challenge/response authn will be useful on its own (and thus is worth fleshing out "standalone", without the whole refresh/session-management stuff).
But I am not sure the value there is worth trying to make this fit the existing HTTP authentication paradigm; option (2) thus seems better to me.
Curious to hear what others think! Should we just return a 403 instead?
The text was updated successfully, but these errors were encountered: