Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Silent authentication error is swallowed in OAuthManager #160

Closed
jeremybranecky-dat opened this issue May 4, 2018 · 6 comments
Closed

Comments

@jeremybranecky-dat
Copy link

jeremybranecky-dat commented May 4, 2018

We are attempting to perform silent authentication following the instructions here https://auth0.com/docs/api-auth/tutorials/silent-authentication, and are seeing an issue with how the error response is handled.

Some background: we have a custom hosted login page in Auth0 and are using the WebAuthProvider.init().start() call to present it from our Android client. We added the parameter "prompt" with value of "none" using the withParameters method provided by WebAuthProvider.Builder.

When the prompt=none parameter is used, and we are attempting to log in for the first time, we see an error response coming back from Auth0 with a value of "login_required" (which is what we expect). This error is handled by the OAuthManager class, and inside assertNoError (line 165 in OAuthManager), the error is swallowed and an AuthenticationException is thrown with a value of "a0.invalid_configuration". The a0.invalid_configuration error is what is passed back to our onFailure callback in the client.

Ideally we would like to get the "login_required" error value (and any other silent auth error responses https://auth0.com/docs/api-auth/tutorials/silent-authentication#error-response) in the onFailure callback, so we know to make the WebAuthProvider.init().start() call without prompt=none parameter.

If it helps, we are seeing the correct error response "Login required" when using the Auth swift library for iOS. Please advise.

@lbalmaceda
Copy link
Contributor

I don't think you should be using the silent auth flow from untrusted clients. If you need to renew the tokens you can always exchange refresh tokens for new access token once they expire. On mobile apps what it's recommended since it's more secure is to use a code exchange + PKCE flow. This is how this library works and how it was planned to be used. Check the guides at the auth0 site with more details on each flow.

@jeremybranecky-dat
Copy link
Author

I should have given you a better example of the code. I am using silent auth with a trusted client, via PKCE flow.

The following is how I am calling authorize via the WebAuthProvider, passing in prompt=none in params.

WebAuthProvider.init(auth0) .withScheme(getString(R.string.auth0_scheme)) .withScope("openid profile offline_access email") .withAudience(getString(R.string.auth0_audience)) .withResponseType(ResponseType.CODE) .withCustomTabsOptions(chromeTabOptions) .withParameters(params) .start(this, this)

I'm expecting the callback to be called with the "login_required" error, if I haven't already logged in. Instead I get the "a0.invalid_configuration" error, but see the "login_required" error in OAuthManager (see my comment above).

@lbalmaceda
Copy link
Contributor

lbalmaceda commented May 7, 2018

Ok I get it. I'll discuss this internally and see if we should expose that error. That would fix it right? Since you'll be handling the error yourself.
Anyway, I'm still convinced you shouldn't be using silent authentication at all. If you skip sending the prompt=none the browser would open and use SSO if available, or display the login box (can be forced with prompt=login). Like I said, if you need to check the validity of a session, that's what the expires_in value is used for. You could save time.now + expires_in somewhere and when that value is reached you could either prompt the user to log in again (launching the webauth) or renew the access token (by using the refresh token).

@jeremybranecky-dat
Copy link
Author

jeremybranecky-dat commented May 7, 2018

Yes, if the error was exposed, and returned back to the on onFailure callback, that would work for us.
I spoke with a co-worker and he said Shawn Meyer at Auth0 recommended we use prompt=none parameter to implement SSO, and FWIW we are following this blog post: https://auth0.com/blog/oauth-2-best-practices-for-native-app. Thanks!

@lbalmaceda
Copy link
Contributor

@jeremybranecky-dat There's an open PR ☝️if you'd like to try it out. The idea is that you capture that AuthenticationError instance and ask err.isLoginRequired() to see if it's an SSO error.

@jeremybranecky-dat
Copy link
Author

Thanks @lbalmaceda. I tried the PR locally and am getting the correct (expected) Error, and err.isLoginRequired() is true. I appreciate the help!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants