We have a REST service deployed in production, which returns an XML serialised representation of a simple object.
When calling the REST 'get' method, we see a very strange problem, whereby after all our user code is finished (according to our own logs), we get a 401 in the browser which is rendering the object XML. It's failing server-side during the execution of the 'return' statement in the REST method.
We think we understand this part of the problem... The object contains an enum, whose value is actually returned from a database. In this particular case we have managed to assign an integer value to the enum which isn't defined in the Enumeration itself (This behaviour is permitted, and is the reason for Enum.IsDefined method: http://msdn.microsoft.com/en-us/library/system.enum.isdefined.aspx)
Our assumption is that when the REST framework code processes the 'return' statement, it then tries to serialise the Enum to a text value, and blows up because no name (string) exists for the specified value.
Strangely though, rather than getting a yellow screen of death or similar, we get a 401 (and a prompt for credentials in the browser).
We were wondering if ASP.NET / IIS does some sort of Server.Transfer in these cases, but perhaps it doesn't have filesystem permissions to the page it is transferring to - ? We're baffled as to what is going on under the bonnet! There is no client-side redirect.
Any ideas anyone?
An HTTP status code of 401 means Unauthorized. From wikipedia:
401 Unauthorized
Similar to 403 Forbidden, but specifically for use when authentication is possible but has failed or not yet been provided.[2] The response must include a WWW-Authenticate header field containing a challenge applicable to the requested resource. See Basic access authentication and Digest access authentication.
I would start looking at how your authentication is set up.
Related
I have seen the list of all HTTP status codes.
However to me it looks like there is no code for "email not verified" (used for authentication/authorization).
Did you ever had the same "problem"? What HTTP status code did you use?
I guess it should be a code starting with a 4 as it's a "client error".
The 4xx class of status code is intended for situations in which the client seems to have erred:
6.5. Client Error 4xx
The 4xx (Client Error) class of status code indicates that the client
seems to have erred. Except when responding to a HEAD request, the
server SHOULD send a representation containing an explanation of the
error situation, and whether it is a temporary or permanent
condition. These status codes are applicable to any request method.
User agents SHOULD display any included representation to the user.
For authentication and authorization, 401 and 403 are the proper status codes to be used, respectively. Regardless of the status code, you should always describe that reason of the error in the response payload.
401 Unauthorized
Use this status code for problems with HTTP authentication, that is, invalid credentials.
3.1. 401 Unauthorized
The 401 (Unauthorized) status code indicates that the request has not
been applied because it lacks valid authentication credentials for
the target resource. The server generating a 401 response MUST send
a WWW-Authenticate header field containing at least one
challenge applicable to the target resource.
If the request included authentication credentials, then the 401
response indicates that authorization has been refused for those
credentials. The user agent MAY repeat the request with a new or
replaced Authorization header field. If the 401
response contains the same challenge as the prior response, and the
user agent has already attempted authentication at least once, then
the user agent SHOULD present the enclosed representation to the
user, since it usually contains relevant diagnostic information.
403 Forbidden
Use this status code for problems with authorization, that is, the credentials are valid but they are insufficient to grant access.
6.5.3. 403 Forbidden
The 403 (Forbidden) status code indicates that the server understood
the request but refuses to authorize it. A server that wishes to
make public why the request has been forbidden can describe that
reason in the response payload (if any).
If authentication credentials were provided in the request, the
server considers them insufficient to grant access. The client
SHOULD NOT automatically repeat the request with the same
credentials. The client MAY repeat the request with new or different
credentials. However, a request might be forbidden for reasons
unrelated to the credentials. [...]
While CodeCaster has provided a very definitive answer as a comment, that which is correct is sometimes not appropriate.
Firstly, you'll see there is no mention of email addresses in the specs. Similarly there is no mention of shoe sizes, model railway gauges, breeds of dogs nor many other things. It is not relevant to HTTP. This is just a data item.
You seem to have some state associated with this data item which you use for authentication purposes - but don't provide any explanation of that state nor how it is applied. I assume that you mean that the "not verified" state means that the only association between the data item and the user interacting with your site is an assertion of the user. And further that you do not allow the user to authenticate with this as a token.
It may seem I'm being pedantic here - but there are other, valid interpretations of "email not verified". You should have provided more information in your question.
There's another gap in your story: which request are we taking about here? Again, I'll take the liberty of assuming that the request is an attempt to authenticate.
In this case, there is nothing intrinsically wrong with the request. There is nothing intrinsically wrong with the client. There is nothing intrinsically wrong at the server. Not permitting the user to authenticate is a policy decision based on the data.
Another critical bit of information missing from your question is what is actually making the request. If its a form sent by a browser, then returning anything other than a 200 OK (or 204, or a redirect to a 200) to MSIE will, by default, cause the browser to display an internal message and not the content you send.
OTOH if the client is an application running on the users device, or an Ajax request, then you control the API and can define your own semantics. If you want to return a 692 status code to represent this condition, then you can return a 692 error code. You can even inject your own headers in the response (by convention these should begin with 'X-').
In the defined state the authentication fails. But returning a 401 response will prompt a browser to attempt HTTP authentication - which doesn't address the issue.
IMHO, the nearest existing code is 403 or 422. But based on the information you've supplied I can't say if thats what you should be using.
I am using webMethods from the SAG and it seems if the service
pub.client.http
throws an exception on status code 401 "Unauthorized".
This leads me to the problem that I cannot handle the status code because nothing is written to the pipeline.
getLastError
does contain the string "Unauthorized" but not the status code.
Except that I do not want to start parsing exception messages...
Any ideas?
The output parameter header from the pub.client.http call should contain the information you’re after:
header Document Conditional. HTTP response headers.
Key Description
lines Document Fields in the response header, where key names represent
field names and values represent field values.
status String HTTP status code of the response.
statusMessage String HTTP status message of the response.
See the webMethods Integration Server Built-In Services Reference page 122 for more details.
Asked a SAG senior consultant.
This is the normal behavior.
There is no flag which you can set to enforce suppression of this exception...
You can suppress the exception and have the HTTP 401 status returned like any other HTTP response. Go to the IS Admin Extended Settings and set:
watt.net.http401.throwException=false
Note this is a server-wide setting, so it will affect all your applications/services that use pub.client:http.
According the comment from #Hugo Ferreira probably there are ACL restriction whether inside your webMethods environment, or your client URLs.
Things you should consider:
Do your webMethods server located inside closed environment wherein need to get connected to proxy to get to the outgoing request. Which is likely you can investigate by run web-browser program directly from your wM server towards the URL address (i.e using SSH to run firefox in my case and popup appeared)
The client that your request will go to, have HTTP for authentication requests
Solution
To pass this all you need to do is input the auth user/password or any other auth mechanism i.e kerberos, token, etc. inside the pub.client:http
Sometimes (when the resource is requested too often) I'm intercepting the presentation of a (HTML) resource with a captcha. The interception doesn't produce any redirection. It happens all at the same URI.
I'm wondering now which HTTP status code would fit most for these requirements:
it should fit semantically.
Google should understand that this interception is a temporary condition which should not affect the existing resource in its index.
A web browser will display the response body with the captcha.
These are my candidates which I identified so far:
409 Conflict
The request could not be completed due to a conflict with the current state of the resource. This code is only allowed in situations where it is expected that the user might be able to resolve the conflict and resubmit the request. The response body SHOULD include enough information for the user to recognize the source of the conflict.
This sounds perfect. The conflict state comes from those clients requesting the resource too often. The response also includes enough information to identify the source of conflict plus resolve it.
503 Service Unavailable
The server is currently unable to handle the request due to a temporary overloading […] of the server. The implication is that this is a temporary condition […]. If known, the length of the delay MAY be indicated in a Retry-After header.
This sounds moderately appropriate. I might even know the length of delay and provide such header. But I'm missing here the point that the user can resolve the problem. Furthermore the scope is too broad (overloaded server vs. overloaded resource).
You may want to consider status code 429, defined in https://www.rfc-editor.org/rfc/rfc6585#section-4.
For me 422 is somewhat accurate for this case:
response status code indicates that the server understands the content
type of the request entity, and the syntax of the request entity is
correct, but it was unable to process the contained instructions.
FWIW I'm using 498.
wikipedia:
Code 498 indicates an expired or otherwise invalid token.
498 Invalid Token (Esri)
Returned by ArcGIS for Server. Code 498 indicates an expired or otherwise invalid token.[74]
I'm doing an AJAX call to set the username. If the username is already taken what HTTP code should I return?
You can use 409 Conflict.
Indicates that the request could not be processed because of conflict in the current state.
I would choose 422 Unprocessable Entity . Lot's of rails developers use this for all validation errors.
And yes, it is totally appropriate to evaluate the error status and render the error message with javascript. This is especially useful, if you are using the same actions for an API. Then your ajax requests are accessing the same API that you would expose to other developers.
There is no rule here, it is up to you. However, as #rationalboss said, it makes sense to return 200 with a message since the HTTP request has succeeded, the error is unrelated to the request.
400 errors mean the request itself was not correct in some way, like wrong verb or missing parameters.
The question here is about interpretation, both from software clients and from humans and it might be better to stay away from error codes when there is no HTTP error.
There is no HTTP Code for name already taken. Please see List of HTTP Status Codes.
If you are using AJAX calls to set the username, why not just show the error in HTML? This is more user-friendly as your visitors would know what the actual error means, instead of seeing some 4XX code.
How do you communicate an error to the web service consumer ?
For example, my web service has a function to insert employee into db.Suppose while inserting the data , the database gave an error,what should be the best way to inform the user about the error.
One way is to depict it through the return value of the web service method but what to do when the function is supposed to return a complex object like employee when there is no error ,and will send an error string when there is an error ?
For SOAP: That is what faults are used for
SOAP faults are used to carry error information within a SOAP message. The fault is for SOAP what an exception is for a programming language.
When your client's request succeeds, you send back a valid response with the Employee structure, when it fails, you send back a fault with details of what went wrong.
For REST: Use HTTP Error Codes
Unlike SOAP, REST web services do not have a convention for returning errors but the simplest is to use the ones everybody understands.
For example you might send a HTTP 404 Not Found when a record is missing, a HTTP 500 Server Error when something happend on the database etc, and return HTTP 200 OK with your result when everything is fine and dandy.