Epson TM-T88V-i digest authentication not working - symfony

My Epson TM-T88V-i receipt printer tries to fetch XML data from a server URL which needs the printer to authenticate via HTTP digest. (this Epson feature is called "Server Direct Print")
From the printer's web console I'm able to send a test request to the server but HTTP digest authentication fails. Same happens if I let the printer try to authenticate at the server.
If I try to access the URL via browser the HTTP digest username+password box appears and if I enter the credentials the XML gets displayed in the browser as expected. This shows, that the HTTP digest mechanism on server side is set up correctly (I'm using the PHP framework Symfony 2.8).
On server side I see following log information:
Step 1
[2016-04-03 16:33:01] security.INFO: An AuthenticationException was
thrown; redirecting to authentication entry point.
{"exception":"[object]
(Symfony\Component\Security\Core\Exception\AuthenticationCredentialsNotFoundException(code:
0): A Token was not found in the TokenStorage. at /home/.../src/Symfony/Component/Security/Http/Firewall/AccessListener.php:53)"}
Step 2
[2016-04-03 16:33:01] security.DEBUG: Calling Authentication entry
point.
Step 3
[2016-04-03 16:33:01] security.DEBUG: Digest Authorization header
received from user agent. {"header":"username=\"printer\",
realm=\"example\",
nonce=\"MTQ1OTk5Mzk4MS40NjQ3OmI0OTVmN2ZkZTlhYmE1NmNjNDIxNmIxMWU0OGVmYjUz\", uri=\"/export\", cnonce=\"MDAxNjM0\", nc=00000001, qop=\"auth\",
response=\"c6ad88607624efd17f7de602f6ee9def\""}
Step 4
[2016-04-03 16:33:01] security.DEBUG: Unexpected response from the
DigestAuth received; is the header returning a clear text passwords?
{"expected":"741bff6abed513b6948c26eae529b6b6","received":"c6ad88607624efd17f7de602f6ee9def"}
Step 5
[2016-04-03 16:33:01] security.INFO: Digest authentication failed.
{"exception":"[object]
(Symfony\Component\Security\Core\Exception\BadCredentialsException(code:
0): Incorrect response at
/home/.../src/Symfony/Component/Security/Http/Firewall/DigestAuthenticationListener.php:107)"}
The log file tells us what happens server side:
In Step 1+2 the Epson tries to access the server URL which is HTTP digest protected and the server sends a 401 "unauthorized" response with a nonce (we don't see this in this log file)
In Step 3 the Epson sends the HTTP digest client authorization request including all necessary data. The response parameter contains a hash which should be generated out of the other authorization parameters
In Step 4 my symfony 2.8 application says, that the hashed response parameter which was sent by the Epson in step 3 is not the one which was expected by the HTTP digest process.
Step 5 finally shows, that the HTTP digest authentication failed.
As far as I understand, the digest authentication process (as described on wikipedia) is correct, except that the Epson doesn't calculate the correct hash in his authentication request.
Does anyone know why the Epson sends a wrong response parameter or did someone make this scenario work?

I could resolve the problem after 2 days of debugging. The length of my digest auth password was 40 chars. I reduced it somewhat about 20 chars. Not it works, dohhh.

Related

HTTP status for "email not verified"

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.

Digest Authentication not working in JMeter

I wanted to have digest authentication Authorization header added in very http request and hence added HTTP Authorization Manager under thread group. I added URL,username, password, domain, realm (both to same name) and selected BASIC_DIGEST as the option (I wanted only digest authentication).
I also uncommented http.authentication.preemptive$Boolean=true in httpclient.parameters and uncommented httpclient.parameters.file=C:\apache-jmeter-2.12\apache-jmeter2.12\bin\httpclient.parameters in jmeter.properties file.
After done, I closed my jmeter and started it again. When I gave a run and did a wireshark capture, I figured out that GET was sent with NO Authorization header, and server sends a 401 response and jmeter closes socket and fails the case.
I am not sure what I have done wrong. Awaiting for your comments.
JMeter Logs:
2014/11/20 13:19:35 INFO - jmeter.threads.JMeterThread: Thread started: Thread Group 1-1
2014/11/20 13:19:35 INFO - org.apache.commons.httpclient.auth.AuthChallengeProcessor: digest authentication scheme selected
2014/11/20 13:19:35 INFO - org.apache.commons.httpclient.HttpMethodDirector: No credentials available for DIGEST 'users#perf.tb.com'#192.168.100.30:80
Realm should not be required for digest authentication, domain is quite enough
Make sure that you're using either HttpClient3.1 or HttpClient4 implementation
See Windows Authentication with Apache JMeter guide for details on how to configure HTTP Authorization Manager for digest and kerberos authentication types

Windows authentication multiple requests

I am using Windows Authentication to secure ASP.NET MVC5 application.
Everything works ok, I'm prompted to enter credentials via browser popup, and content it served properly.
However I do notice constantly that some requests are being sent 2 times, or more, with receiving 401 (Unauthorized) code, but shortly after requests are issued again and 200 (OK) is returned.
I assume that is part of negotiation with WWW-Authenticate and Authorize requests headers, but what is unclear to me is why this has to happen all the time even though credentials were supplied at the very start?
Is this normal behavior?
If not, how can it be fixed?
If yes, is it a big performance hit?
Attached is the combined screenshot of Fiddler and Firefox developer console.
What you are experiencing is the normal behavior. Here is a (very) short description of how the authentication works:
Request is sent to server (without credentials) => not authenticated (your first request)
Server responds with 401 (Access denied)
Browser gets error and sends credentials back => authenticated (your second request)
After the 3rd step, if the server has not received the requested credentials, it sends another 401 response and the browser displays the 401 error page. A more complete description can be found here.

Inconsistent security behaviour on IIS

We have a secured WCF service with WsHttpBinding, Client & Server certificates & transport security with Claim Based Authorization.
Everything works fine 50 % of the time. When we do request to a secure endpoint, we get the correct response. But if we send the same request again immidiatly after the first we get the following response:
The HTTP request was forbidden with client authentication scheme 'Anonymous'.
If we then send a request again, we get normal behaviour. So the odd requests work and the even not.
But after some more investigation in the problem. We noticed that if there is at least 1:40 minutes between the previous request, we don't get the error response.
What we can confirm from the debugger and logging. The client sends the credentials to the service. We don't enter System.ServiceModel if we have the Authentication response. In the IIS trace logs we get this on a good request:
Authentication: SSL/PCT
User from token: Domain\CertifacteUserName
and this on a bad request:
Authentication: NOT_AVAILABLE
User from token:
Also in the IIS Trace logging. If we send the second request, we see that the ConnId and RawConnId are the same on both requests. And if we make multiple successful request (By allowing some time between requests) they are different for each request.
It seems to me IIS is not getting the Credentials we send, when they are there. Is this due to caching? Or something else? Does anyone has a solution.

RESTful Login Failure: Return 401 or Custom Response

This is a conceptual question.
I have a client (mobile) application which needs to support a login action against a RESTful web service. Because the web service is RESTful, this amounts to the client accepting a username/password from the user, verifying that username/password with the service, and then just remembering to send that username/password with all subsequent requests.
All other responses in this web service are provided in a JSON format.
The question is, when I query the web service simply to find out whether a given username/password are valid, should the web service always respond with JSON data telling me its successful or unsuccessful, or should it return HTTP 200 on good credentials and HTTP 401 on bad credentials.
The reason I ask is that some other RESTful services use 401 for bad credentials even when you're just asking if the credentials are valid. However, my understanding of 401 responses are that they represent a resource that you are not supposed to have access to without valid credentials. But the login resource SHOULD be accessible to anyone because the entire purpose of the login resource is to tell you if your credentials are valid.
Put another way, it seems to me that a request like:
myservice.com/this/is/a/user/action
should return 401 if bad credentials are provided. But a request like:
myservice.com/are/these/credentials/valid
should never return 401 because that particular URL (request) is authorized with or without valid credentials.
I'd like to hear some justified opinions one way or the other on this. What is the standard way of handling this, and is the standard way of handling this logically appropriate?
First off. 401 is the proper response code to send when a failed login has happened.
401 Unauthorized
Similar to 403 Forbidden, but specifically for use when authentication is required and has failed or has not yet been provided. The response must include a WWW-Authenticate header field containing a challenge applicable to the requested resource.
Your confusion about, myservice.com/are/these/credentials/valid sending back 401 when you just do a check, I think is based on the fact that doing boolean requests in REST often is wrong by the RESTful constraints. Every request should return a resource. Doing boolean questions in a RESTful service is a slippery sloop down to RPC.
Now I don't know how the services that you looked on are behaving. But a good way of solving this is to have something like an Account object, that you try to GET. If your credentials are correct, you will get the Account object, if you don't want to waste bandwidth just to do a "check" you can do a HEAD on the same resource.
An Account Object is also a nice place to store all those pesky boolean values that otherwise would be tricky to create individual resources for.
401 should be sent only when the request needs authorization header field and authorization fails. Since the Login API doesn't require authorization, hence 401 is the wrong error code in my opinion
As per the standard here https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
*10.4.2 401 Unauthorized
The request requires user authentication. The response MUST include a WWW-Authenticate header field (section 14.47) containing a challenge applicable to the requested resource. The client MAY repeat the request with a suitable Authorization header field (section 14.8). If the request already included Authorization credentials, then the 401 response indicates that authorization has been refused for those credentials. 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 SHOULD be presented the entity that was given in the response, since that entity might include relevant diagnostic information. HTTP access authentication is explained in "HTTP Authentication: Basic and Digest Access Authentication" [43].*
If the 401 response code is misleading for user authentication, the API can send HTTP status code 200 OK for both successful and failed authentication, but set a custom header on the authentication successful response and omit that header on failed logins.
The client can check if the header exists or not and decide the action.
Example: SpringBoot API Response
The call to OK when login is successful sets the header "gotyouin" with a value (anything). Call to failed does not add the header and client can treat this as a failed login attempt.
public class LoginResponseEntityHelper {
public static ResponseEntity<?> ok(String token) {
return ResponseEntity.status(HttpStatus.OK).header("gotyouin", token).body(null);
}
public static ResponseEntity<?> failed() {
return ResponseEntity.status(HttpStatus.OK).body(null);
}}
It is logical to use 401 http status code when access to a resource is denied because the request lacks or has incorrect credentials. And when correct credentials are provided, the request should complete successfully granting access to the protected resource.
Applicable for your case: myservice.com/this/is/a/user/action.
Maybe we should be clear about this credentials
In most secure applications, credentials are needed to access protected resource(s). These credentials can be sent along every request via HTTP header. Specifically the Authorization Header.
Therefore the Authorization header contains credentials to allow a user to access protected resource(s).
Remember that a user who was verified successfully as an authorized user(successful login), is the one given this priviledged credentials to allow for access on protected resources on the server.
From the server point of view, a HTTP request targeting a protected resource yet it is lacking credentials or containing invalid credentials may cause to validly send back 401 response code.
Therefore the Login API should not send a 401 response code because of a failed login attempt. It is misleading. Reasoning out that you are requesting to the server application via the Login API to grant you with credentials required to access resources that are protected. By itself, the Login API is not a protected resource.
So what is the correct response status?
Well I will opine towards sending back a 400 response code because a failed login attempt is a client error who is at fault for not providing the correct username or password.
According to RFC standards about 400 code:
The 400 (Bad Request) status code indicates that the server cannot or will not process the request due to something that is perceived to be a client error (e.g., malformed request syntax, invalid request message framing, or deceptive request routing)
Again I will reiterate that failed login is a client error due to providing details that are incorrect. Sending back a 400 doesn't have to mean that the request syntax is malformed. But a malformed syntax is one of the reasons.
Sending a 401 would really be misleading as the user doesn't need to provide authentication information to access the login API.

Resources