Missing www-authenticate header when receiving 401 responses.

Hello,

As per section 4.1 of RFC-7235, when an HTTP server returns a 401 response, it must also return a WWW-Authenticate header :

A server generating a 401 (Unauthorized) response MUST send a 
WWW-Authenticate header field containing at least one challenge.


However, when the refinitiv server returns 401, it returns the following header :

Authorization: WWW-Authenticate: Signature realm="World-Check One API",algorithm="hmac-sha256",headers="(request-target) host date content-type content-length"


This is indeed an "Authorization" header, not a WWW-Authenticate, and it cannot be used to extract the signature challenge in a clean generic way.

As long as this header is returned (in place of "WWW-Authenticate"), the only way of generating a valid Authorization header on the client side is to use preemptive authorization.

This might be fine for code crafted especially to access the refinitiv server, but it won't work for generic code (gateways and/or proxies, etc...). For instance, we use a gateway that handles all authorization computing for different providers, and it cannot process refinitiv queries because of this issue.

Are you aware of this issue, and do you plan to fix this at some point ?

Thanks in advance.

Answers

  • @parabellum

    Please allow us some time to get back with response on this.


    In the mean time, can you please elaborate "This is indeed an "Authorization" header, not a WWW-Authenticate, and it cannot be used to extract the signature challenge in a clean generic way. "

    Thanks.

  • Thank you for your response.


    I wrote that it is indeed an Authorization header because the header received starts with the string "Authorization:", instead of "WWW-Authenticate:".

    Authorization: WWW-Authenticate: Signature realm="World-Check One API",algorithm="hmac-sha256",headers="(request-target) host date content-type content-length" 


    The server should have sent this string instead :

    WWW-Authenticate: Signature realm="World-Check One API",algorithm="hmac-sha256",headers="(request-target) host date content-type content-length" 

    This last example tells the client that it should authenticate to the server using a Signature (along with the expected parameters).

    This is what is defined in the HTTP Authentication specifications ( https://tools.ietf.org/html/rfc7235#section-4.1 ).


    Also, I believe there is another compliance problem regarding the signature string construction ( https://tools.ietf.org/id/draft-cavage-http-signatures-12.html#rfc.section.2.3 ) :
    for POST queries, you expect the payload to be appended to the message being signed ; but this fact does not appear in the "headers" parameter returned by the server (it only contains "(request-target) host date content-type content-length").
    But this should go in another ticket I guess ;)

  • Another error I noticed, is that when replying with 401 to a GET request, refinitiv does not return the expected "headers" value.

    we get :

    headers="(request-target) host date content-type content-length" 

    whereas (since it's a GET query), it should be :

    headers="(request-target) host date" 

    Attached is a copy of postman's console for the faulty exchange...
    image


    This according signature authentication scheme is specified in RFC7235 ( https://tools.ietf.org/id/draft-cavage-http-signatures-12.html )

  • @parabellum

    I am still trying to get the answer from the dev team. Please allow me some time so that I can get back with updates on this.

  • kanmu
    kanmu Newcomer

    @Irfan.Khan I have same issue as @parabellum.

    > Another error I noticed, is that when replying with 401 to a GET request, refinitiv does not return the expected "headers" value.

    I also found that the expected headers for signature differs by API, regardless of request method.

    For example, according to Postman Collection's Pre-request Script,

    SEQ-screen-async: Screen a case (POST /cases/caseSystemId/screeningRequest) expects only

    headers="(request-target) host date"

    , while other POST API such as SEQ-screen-sync-simple: Perform Synchronous Screening: Simple (POST /cases/screeningRequest), expects

    headers="(request-target) host date content-type content-length"

    It's hard to distinguish which of headers list we need to use for the particular API.

    Is there any rules? How can we decide which of headers list should be used for the particular API?

  • Dear, did you have a solution to your problem?, I think I present the same and I can't solve it.

  • I believe i have the same error . although the headers that work for Linux do not from a windows box. Hope this gets more responses. I've addded/ removed every possible headed from the successful postman hits

  • Any updates to this? We are experiencing the same issue.

  • Hi @marc_etter,

    Thank you for reaching out. Could you kindly provide more detailed information regarding the issue you are encountering?

    Thanks,

    Ram.

  • When sending a request that contains an incorrect HMAC signature, the API responds with a 401 status code, without a WWW-Authenticate header. Instead, the WWW-Authenticate header is contained inside an Authorization header, exactly as described by the original post.

    Unfortunately this then causes an Exception inside Java Spring's WebClient: HTTP protocol violation: Authentication challenge without WWW-Authenticate header, which prevents us from otherwise handling this error gracefully.

  • @marc_etter,

    We are currently consulting with our team regarding updates related to this concern and will provide you with a response as soon as possible

    Thanks,

    Ram.