I have one question, i'm trying to to authenticate to AD via LDAP, and when i put invalid credentials i got exception message like this:
LDAPException(resultCode=49 (invalid credentials), errorMessage='80090308: LdapErr: DSID-0C0903A9, comment: AcceptSecurityContext error, data 52e, v1db0, and this is ok, but more exact reason of this exception is in part"data 52e", and it tell's me "invalid credentials ". When credentials are good but for example "password expired" in exception message i will get "data 532". This part of message can have different values depending of exception reason (533-account disabled, 701-account expired etc.). My problem is how to catch only this part of exception message. I want to handle the exception according to this error code. Fore example :
switch(err_code){
case 52e:
System.out.println("invalid credentials");
break;
case "530,":
System.out.println("not permitted to logon at this time");
break;
}
But I don't want to use regular expresions to match error code. Any ideas?
These codes are probably specific to Active Directory implementation. Have a look at the explanation to the similar question.
Related
Which HTTP status code is correct for Subscription Canceled exception?
I need to throw an exception when the user tries to accesses a certain page.
I checked a few statuses like Payment Required, but it's not satisfying the requirement. Any suggestion?
Which HTTP status code is correct for Subscription cancel exception?
HTTP status codes belong to the transfer documents over a network domain.
So the specifics of what is going on in your domain don't particularly matter - the idea is to understand the error condition in terms of document transfer, and work from there.
In this case, the best fit is likely 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).
It may help to imagine how this example would play out on a web site. For the human user, you would return a bunch of HTML explaining that their subscription had been cancelled, perhaps with links to resources that would allow the user to re-subscribe, and so on.
For the browser, you would have the HTTP meta data, including the status code, so that the browser would understand the general purpose semantics of the message (for instance, should earlier representations of the resource be invalidated in the cache).
it's a API request from front-end.
This doesn't really enter into the discussion; the motivation for the uniform interface is that we can swap out the implementations at either end of the conversation and the semantics of the self descriptive messages don't change.
I would say that correct Response code is:
401 Unauthorized
Since by the definition the user Cancelled his subscription and cannot more access paid content, therefore user is Unauthorized for that.
In the other words User is Authenticated but Unaouthorized to do this request.
I'd like to offer an alternative solution. 403 errors make a lot of sense here, as access is denied for a resource. However, this could be difficult to handle in the front-end, because it's indiscernible from a 403 error caused by lacking permissions or roles. A 402 error is non-standard, but "Payment Required" would be easier to program around. If using a non-standard HTTP code is allowed, I believe this to be a more suitable status to return from an API based on a cancelled subscription, or a lack of a valid subscription in general.
My question is similar to this one. However, I am using the API Java Client Library with a service account, making calls to the API from my server.
My code is following this guide, which is very simple. However, I can't seem to get an appropriate error for my request. This is how I build my AndroidPublisher:
val credential = GoogleCredential.fromStream(FileInputStream(
"/path/to/json"
)).createScoped(Collections.singleton(AndroidPublisherScopes.ANDROIDPUBLISHER))
androidPublisher = AndroidPublisher.Builder(httpTransport, JSON_FACTORY, credential)
.setApplicationName(packageName)
.build()
Where the JSON is generated from the Developer Console, under Service Accounts. This is how I make my request:
androidPublisher.purchases().subscriptions().get(packageName, "valid-sku", "invalid-token").execute()
My subscription ID is valid but my token is invalid. I expect an error such as "invalid token" in the response. However, what I get is:
com.google.api.client.googleapis.json.GoogleJsonResponseException: 400 Bad Request
{
"code" : 400,
"errors" : [ {
"domain" : "global",
"message" : "Invalid Value",
"reason" : "invalid"
} ],
"message" : "Invalid Value"
}
Is that a generic error because of the invalid token or is it an authentication issue? If it an authentication issue, how do I solve it? If it is an invalid token issue, how am I supposed to know?
Some more information:
I get the same error when trying to make that call from the API Explorer as well (this time using a Client ID and API Key instead of Service Account).
I have not delegated domain-wide access to the service account. Do I have to for some reason?
I can successfully make other calls to the API such as inappproducts.list
From my experiences, if you have HTTP 400 error with Invalid Value then that purchase or subscription is FRAUD.
You can check out Order Id part of those purchases. Probably in the format of XXXXXXXXXXXX.XXXXXXXXXXXX which is wrong and should be GPA.XXXX.XXXXX.XXXXX.XXX
I don't really count the X char number. I just added to show the logic.
In my case the problem was that I was calling:
purchases.products.get
Instead of:
purchases.subscriptions.get
So, the reason that happened was just because the purchaseToken I was using was wrong.
I did not expect that to be the reason as I thought that in the case of an invalid token, I would receive a "token invalid" error (or something similar). As it turns out, the responses given by Google are pretty inconsistent (a 404 could also be given for an invalid token).
Scratched my head for a few hours, ALL my parameters were correct, and then well.. I realized that I was barking up the wrong tree (endpoint)
https://androidpublisher.googleapis.com/androidpublisher/v3/applications/{packageName}/purchases/subscriptions/{subscriptionId}/tokens/{token}
is not this
https://androidpublisher.googleapis.com/androidpublisher/v3/applications/{packageName}/purchases/products/{productId}/tokens/{token}
/purchases/subscriptions/.. vs /purchases/products/..
For all those who run into this problem, 99% of you need to publish the application for internal testers.
Follow this guide: https://support.google.com/googleplay/android-developer/answer/6062777?hl=en
I am referring to this project on Github. So this is supposed to be a RESTful API for managing a movie rental service. I mean it technically "works" right now, but one of the things it will do is deliver the error messages directly to the client from the internal methods.
Take this code for example:
/*
GET films
*/
get("/films", (req, res) -> {
try {
String json_output = get_film_list();
return json_output;
} catch (Exception e) {
return "{\"error\":\"There was an error: " + e.toString().replace("\"","") + "\"}";
}
});
And we have the get_film_list() method:
public static String get_film_list() throws SQLException, URISyntaxException{
Connection connection = ConnectionPool.getDBCP2Connection();
Statement stmt = connection.createStatement();
ResultSet rs = stmt.executeQuery("SELECT * FROM films");
String output = "{\"films\":[";
int got_result = 0;
while (rs.next()) {
output += "{\"id\":\""+rs.getInt(1)+"\",\"name\":\""+rs.getString(2)+"\",\"type\":\""+rs.getInt(3)+"\"},";
got_result = 1;
}
rs.close();
stmt.close();
output = output.substring(0, output.length()-1) + "]}";
if (got_result == 1){
return output;
}else{
throw new SQLException("No films.");
}
}
So the errors are delivered to the user via the API. I found this pretty convenient for development. I knew that if the server response contains the error property then there was an error, and it supplies the error message. I have heard through code review that this is not the way to do this at all. I also suspect that perhaps you're supposed to give formal HTTP errors or something. But at the same time I figured I would want my api to always return nice JSON formatted strings.
When a user hasn't authenticated, they will see this:
{"error":"Please Authenticate."}
I created an error in the DB connection class, and the user would see this:
{"error":"There was an error: java.sql.SQLException: Cannot load JDBC
driver class 'org.postgresql.Drive'"}
So, my question comes down to, what is the proper way to return error messages to the users with a RESTful API. One of this sort which uses returns JSON data.
Thanks!
RESTful services are based on 2 things, the response code and the actual response itself.
Well, basically it boils down to what error you want to handle. This particular scenario means no data being found and you would find different ways of handling this scenario. Any other error conditions would be handled differently
The 2 approaches to handling this error are
Scenario 1:
Response Code: 200 OK
Response: {}
which means that there was no data for the request specified(more so the parameters supplied with the request)
Scenario 2:
Response Code: 404 Not Found
Response: {"error":"Error Message"}
but this could potentially be confusing to indicate that the service was not found. But this depends on how you've defined your RESTful API.
From what I understand, the above scenario is a mix of both, where it sends out a 200 OK, but at the same time an error message too which is not the way to do it.
Its best to read through the rules of REST and then come up with your API.
Also it might be worth documenting your API through SWAGGER or RAML which makes it meaningful to someone using the service without going through tons of code to understand it.
Since you're using http you should use the http status codes properly, for example the SQL exception would probably result in a response code of 500 Internal Server Error, but you shouldn't expose the actual stack trace or exception at least for two reasons
The api-user has no use of that error message, he can't act upon it or take any reasonable actions to fix it.
You're exposing the applications internals, this could provide someone with malicious intent with valuable information.
When it comes to actually displaying an error. Hopefully something that the user can have some sort of use of. You can pretty much do it in any manner you feel fits your api. The important thing is that the api is consistent.
I'd say that the body of the response you're giving now is okay, except for the fact that the actual message probably doesn't mean anything to the intended user when you just call toString() on an Exception, that information is intended for the developers and should probably be logged.
What you need to do is, translate the exceptions to usable error messages and use http status codes.
When creating a REST API on the top of the HTTP protocol, the HTTP status codes are the proper way to indicate the result of the operation. Along with the status code, you can return a message with more details about the error.
Find below the most common status codes of errors for situations when the client seems to have erred:
400 Bad Request
401 Unauthorized
403 Forbidden
404 Not Found
409 Conflict
422 Unprocessable Entity
Don't define your own status codes. Stick to the standards.
When returning a message, your HTTP response can be like:
HTTP/1.1 404 Not Found
Content-Type: application/json
{ "error" : "Resource not found with the requested identifier" }
Trying to tidy up my code, but ran into an issue on a neat way to allow for pieces of business logic to report errors (at potentially multiple errors) to the user interface.
e.g. for the "simple" act of registering a user, I might have a non-ui method that looks like
public User register(String name, String email, String password);
Which has quite a long list of potential errors, e.g.
Invalid username / email / password. In theory this is checked by the UI, but the server also checks for security. Shouldn't really happen.
Failed to make a HTTP call to the server (IOException from Apache HTTPClient).
Non 200 OK server HTTP response or failed to parse the servers JSON response
Username already used
Email already used (might happen at the time time as username already used)
For the first 3 I was thinking of throwing some kind of exception the user interface understands, and can display in a dialogue box, e.g.
throw LocalisedException(Strings.serverCommunicationFailed);
But for the last 2 I am really not sure. My old code just checked the relevant part of the JSON directly and then updated a text label next to the user input fields directly. But now I am trying to separate things they can't see each other to do that anymore and creating an exception object for this doesn't feel very exceptional (especially in similar error cases, e.g. say on a shop a custom wants to add 50 of x to the basket, but the server says there is only 45).
I am sure there is a standard pattern for this, but seems I have been looking in the wrong places (e.g. http://www.google.com/search?q=Google+user+interface+error+reporting )
You could define a custom InvalidFieldException for:
Invalid username / email / password
Username already used
Email already used
which contains a Map describing all the errors where the key is the field identifier, and the value the associated error message.
For:
Failed to make a HTTP call to the server (IOException from Apache HTTPClient)
Non 200 OK server HTTP response or failed to parse the servers JSON response
You can just define one or two dedicated exceptions and print a message on the screen for the user.
It is also a bad practice to put validation only in your ui, it should at least append in your model.
After checking the database the incorrect password should be displayed on the same login page.
I have used servlet and forwarded that to the login page but i couldn't add the message "incorrect password".
RequestDispatcher rd = getServletContext().getRequestDispatcher("/register.jsp");
if(dbpwd.equals(null)) {
pw.println("Not a registered user!!! sign up......");
rd.forward(req,res);
}
In tha above snippet how to print the "Not a registered user sign up......" on the login page.
It's a very bad idea to tell a potentially malevolent user what he did wrong if he's attempting to gain access to your system with ill intent.
On the other hand, a legitimate user who receives a message stating, "The username or password you entered is incorrect" will, in most cases, be able to figure out what they did wrong, or contact support to resolve the issue. A hacker won't.
Don't go out of your way to help a hacker gain access by telling him which field he needs to correct to gain access.
As Bob Kaufman said, you need to change your error message to a more general one like : "incorrect username or password".
To display the message on the login page, get the response handler of your servlet, and write a tag with your message.
But for a more specific answer, please to specify your question.
As others have said, you don't want to help someone trying to attack your application by providing a detailed error message for login pages.
You might find it useful to read this thread: What should a developer know before building a public web site?