I am trying to do openID connect Auth, successfully got AuthorizationResponse, but getting:
AuthorizationException: {"type":0,"code":3,"errorDescription":"Network error"}
caused by
java.io.FileNotFoundException: http://api.my_addr.com:8080/connect/token
on line #154 of AuthorizationService.class
is = conn.getInputStream();
I found answer on stackoverflow (http://stackoverflow.com/questions/9365829/filenotfoundexception-for-httpurlconnection-in-ice-cream-sandwich), but I cannot edit library code.
07-14 21:56:57.522 10037-10037/com.blacksea.plamobi E/ActivityThread: Activity com.blacksea.plamobi.LoginActivity has leaked ServiceConnection net.openid.appauth.BrowserHandler$1@7e81355 that was originally bound here
android.app.ServiceConnectionLeaked: Activity com.blacksea.plamobi.LoginActivity has leaked ServiceConnection net.openid.appauth.BrowserHandler$1@7e81355 that was originally bound here
at android.app.LoadedApk$ServiceDispatcher.<init>(LoadedApk.java:1092)
at android.app.LoadedApk.getServiceDispatcher(LoadedApk.java:986)
at android.app.ContextImpl.bindServiceCommon(ContextImpl.java:1303)
at android.app.ContextImpl.bindService(ContextImpl.java:1286)
at android.content.ContextWrapper.bindService(ContextWrapper.java:604)
at android.support.customtabs.CustomTabsClient.bindCustomTabsService(CustomTabsClient.java:64)
at net.openid.appauth.BrowserHandler.bindCustomTabsService(BrowserHandler.java:86)
at net.openid.appauth.BrowserHandler.<init>(BrowserHandler.java:61)
at net.openid.appauth.AuthorizationService.<init>(AuthorizationService.java:98)
at com.blacksea.plamobi.util.AuthService.<init>(AuthService.java:41)
at com.blacksea.plamobi.LoginActivity.checkAuthRedirect(LoginActivity.java:46)
at com.blacksea.plamobi.LoginActivity.onCreate(LoginActivity.java:27)
at android.app.Activity.performCreate(Activity.java:6237)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1107)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2369)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476)
at android.app.ActivityThread.-wrap11(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
07-14 21:57:11.529 10037-10037/com.blacksea.plamobi I/AppAuth: Unable to bind custom tabs service
This stack trace isn't related, can you send the stack trace for the FileNotFoundException if you have it? Also, check the URLs for the authentication endpoints you are using are actually reachable from your test device / emulator.
@iainmcgin
07-14 23:01:43.291 11754-11754/com.blacksea.plamobi W/System.err: AuthorizationException: {"type":0,"code":3,"errorDescription":"Network error"}
07-14 23:01:43.291 11754-11754/com.blacksea.plamobi W/System.err: at net.openid.appauth.AuthorizationService$TokenRequestTask.doInBackground(AuthorizationService.java:244)
07-14 23:01:43.291 11754-11754/com.blacksea.plamobi W/System.err: at net.openid.appauth.AuthorizationService$TokenRequestTask.doInBackground(AuthorizationService.java:206)
07-14 23:01:43.291 11754-11754/com.blacksea.plamobi W/System.err: at android.os.AsyncTask$2.call(AsyncTask.java:295)
07-14 23:01:43.291 11754-11754/com.blacksea.plamobi W/System.err: at java.util.concurrent.FutureTask.run(FutureTask.java:237)
07-14 23:01:43.291 11754-11754/com.blacksea.plamobi W/System.err: at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:234)
07-14 23:01:43.291 11754-11754/com.blacksea.plamobi W/System.err: at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
07-14 23:01:43.291 11754-11754/com.blacksea.plamobi W/System.err: at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
07-14 23:01:43.291 11754-11754/com.blacksea.plamobi W/System.err: at java.lang.Thread.run(Thread.java:818)
07-14 23:01:43.291 11754-11754/com.blacksea.plamobi W/System.err: Caused by: java.io.FileNotFoundException: http://api.plamobi.com:8080/connect/token
07-14 23:01:43.292 11754-11754/com.blacksea.plamobi W/System.err: at com.android.okhttp.internal.huc.HttpURLConnectionImpl.getInputStream(HttpURLConnectionImpl.java:238)
07-14 23:01:43.292 11754-11754/com.blacksea.plamobi W/System.err: at net.openid.appauth.AuthorizationService$TokenRequestTask.doInBackground(AuthorizationService.java:239)
07-14 23:01:43.292 11754-11754/com.blacksea.plamobi W/System.err: ... 7 more
@iainmcgin reason was server returned "400 Bad Request". It was my fault, but library need to return another error message.
His fault, but why the hell you do not check for an error response?
If response is error, you must not do conn.getInputStream(); but do conn.getErrorStream(); and hence throw a specific exception with that message and error code.
We could not figure out what is the problem for almost a week...
An oversight on my part, but you are of course welcome to submit pull requests to fix these issues rather than being rude, _especially_ when you purport to already know the solution. It's an open source library, and bugs will invariably exist.
I completely agree that you've done a lot of work to release this useful library.
However I am not a Java developer, but this check looks so obvious and essential so I wonder how it isn't implemented yet in v2.
Same error on Dropbox.
Any solutions?
@allek5 in debug mode, call "conn.getErrorStream", and know the real reason. It helped me
I figured it out already, but thanks anyway. It was a bad request error.
In my case, I was using the version 0.2.0 of the library, used in google codelabs lesson.
This version has a problem: don't set the media type in the post request. My custom authorization server needs that, and answer 400 bad request if media type is not present.
This problem is resolved in the actual version of the lib.
To me this IS an issue in the library.
According to Android HttpUrlConnection documentation:
Response Handling
…
If the HTTP response indicates that an error occurred, getInputStream() will throw an IOException. Use getErrorStream() to read the error response. The headers can be read in the normal way using getHeaderFields(),
I do have a case where Status Code 400 is returned very often: invalid_grant when the access or refresh token is expired or wrong credentials were provided in resource owner credentials flow.
Same here. I need to be able to tell when a refresh token operation is deliberately failed by the server, in which case a 400 is returned (and in the case of our server, an error body is returned with json: { "error":"invalid_grant" }
Either way, not checking the response code seems to be an oversight in my opinion.
Please see: https://github.com/openid/AppAuth-Android/pull/144
For a fix.
@iainmcgin There's two possible pull requests to address this issue. Any idea when you can get to choosing one and releasing? This is blocking part of my development.
Merged #144, so this issue should be resolved in the next release.
@iainmcgin Any idea when the next release will be?
Hopefully 2017-01-20 (tomorrow). I've got one last change I want to get in, some manual testing to do, then I'll cut the release.
Does not seem to be closed at all. There is no FileNotFound Exception anymore but an jSON deserialization exception in version 0.5.0
authMockServer.enqueue(new MockResponse()
.setResponseCode(400)
.setBody("{\"error\":\"invalid_grant\"}"));
service.performTokenRequest(refreshRequest, CLIENT_SECRET_BASIC,
(TokenResponse tokenResponse, AuthorizationException e ) -> response.onResult(
handleResponse(tokenResponse, e)
)
);
junit.framework.AssertionFailedError: noAccessToken_invalidRefreshToken failed with android.accounts.AuthenticatorException: JSON deserialization error
I think you need more fields. The body you have is missing stuff. If you fill that in it should work. Check the test case for this
Specifically error_description
Nope, it is not.
According to RFC6749 Section 5.2 only the parameter "error" is required, "error_description" and "error_uri" are optional.
The implementation I have to work with only supports the 'required' stuff of the RFC6749 and the provider does not want to add more than the required stuff.
In addition the example in the mentioned section defines a fully qualified error example as follows:
HTTP/1.1 400 Bad Request
Content-Type: application/json;charset=UTF-8
Cache-Control: no-store
Pragma: no-cache
{
"error":"invalid_request"
}
Ok. So the existing code which checks that should be relaxed. I noticed it making my test case and didn't think it was an issue as my server gives that back.
@iainmcgin We should probably make a fix for this in 0.5.1.
The code in question is here:
ex = AuthorizationException.fromOAuthTemplate(
TokenRequestErrors.byString(error),
error,
json.getString(AuthorizationException.PARAM_ERROR_DESCRIPTION),
UriUtil.parseUriIfAvailable(
json.optString(AuthorizationException.PARAM_ERROR_URI)));
It should probably use optString instead of getString.
Merged. I'll cut a 0.5.1 release with just this change.