Unauthorized Exception
Closed this issue · 6 comments
I'd like to retrieve an access token from the ERP service Odoo - their endpoints are:
Following the instructions of oauth2-essentials I initialize the client with the credientials and then I copy the whole URL I GET as response, which contains the authorization code to redirectUrl:
OAuth2AccessToken token = grant.withRedirect(redirectUrl).accessToken(executor);
I then get the following error message:
Exception in thread "main" org.dmfs.httpessentials.exceptions.UnauthorizedException: Authentication at my odoo domain'/restapi/1.0/common/oauth2/access_token'_ failed.
at org.dmfs.httpessentials.responsehandlers.FailResponseHandler.handleResponse(FailResponseHandler.java:74)
at org.dmfs.httpessentials.httpurlconnection.PlainHttpUrlConnectionExecutor.execute(PlainHttpUrlConnectionExecutor.java:81)
at org.dmfs.httpessentials.executors.common.decorators.BottomBranded.execute(BottomBranded.java:56)
at org.dmfs.httpessentials.executors.common.decorators.BottomBranded.execute(BottomBranded.java:56)
at org.dmfs.httpessentials.httpurlconnection.HttpUrlConnectionExecutor.execute(HttpUrlConnectionExecutor.java:69)
at org.dmfs.httpessentials.executors.useragent.Branded.execute(Branded.java:53)
at org.dmfs.oauth2.client.BasicOAuth2AuthorizationProvider.accessToken(BasicOAuth2AuthorizationProvider.java:55)
at org.dmfs.oauth2.client.BasicOAuth2Client.accessToken(BasicOAuth2Client.java:71)
at org.dmfs.oauth2.client.grants.AuthorizationCodeGrant$AuthorizedAuthorizationCodeGrant.accessToken(AuthorizationCodeGrant.java:165)
Any help? The credentials are correct and I even get an authorization code.
The response Url I put into redirectUrl looks for example something like this:
my odoo domain/?code=1npyDMbiCgGZnSgz1Tnvbc3lR060MD1m&state=RHpoZhuLaR8XW5Gd_O9D-5l5VZeXkTBNJVXgrZTgtxqdP23oGCqnTEFTcLEaWY_B
Thank youu!
the redirectUrl looks ok. UnauthorizedException
indicates that the server returned a 401 Unauthorized
error in response to the request. I've looked at https://apps.odoo.com/apps/modules/12.0/restapi/ but they don't really tell what they expect in the request.
RFC 6749 allows two ways of authenticating the client, the mandatory HTTP authentication method (that's what this library uses) and an optional request parameter method. Is it possible they don't support that HTTP authentication method?
Hi, thank you very much for your answer! 🙏
There is a more insightful documentation for Odoo's OAuth here:
https://odoo-restapi.readthedocs.io/en/latest/connection/logging_in/oauth2_authentication.html
In there they mention HTTP, so my guess is that it luckily is supported...
But maybe I just misinterpreted the instructions? In the last step it says:
// Open the URL in a WebView and wait for the redirect to the redirect URL
// After the redirect, feed the URL to the grant to retrieve the access token
OAuth2AccessToken token = grant.withRedirect(redirectUrl).accessToken(executor);
So I manually open it in Browser - maybe that's the problem? Do I have to instead use the HttpRequestExecutor, I initialize in the beginning to execute the GET-Request?
Here's the code with the Browser call:
Cheers
Thanks for the link. Looks like their implementation mixes OAuth2 and OAuth1.
This OAuth
Authorization
header scheme is used by OAuth1. (also see the Authentication Scheme Registry)
Authorization: OAuth client_id='uwCrAHAQbL7D9cvJLIztNaZ0bziEGMDh',
client_secret='FtHzOQVEs0aSEL9AXuIe9k7X6E2MekU7',
Whereas OAuth2 uses regular Basic
authentication to authenticate the client, see
RFC 6749, section 4.1.3
POST /token HTTP/1.1 Host: server.example.com Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW Content-Type: application/x-www-form-urlencoded grant_type=authorization_code&code=SplxlOBeZQQYbYS6WxSbIA&redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2Fcb
Sorry, unless they fix their OAuth2 implementation this library won't help you (nor will any other standards compliant implementation).
Thank you very much again for your response. I appreciate you've taken the time to investigate my problem. All you're saying is plausible to me and reading through the documentation chapters you've provided I see what the problem is. What puzzles me though, is that I am actually able to retrieve an access token using the URLs straight up my Google Chrome Browser.
For example - putting the GET
myOdooDomain/restapi/1.0/common/oauth2/authorize?client_id=myClientId&redirect_uri=myEncodedRedirect%&response_type=code
into the URL headline will return
myOdooDomain/?code=kkd0rfhQqOOtHq35ifdkYl3UQ9WTrfv1&state=None
Using this code in the POST request:
myOdooDmain/restapi/1.0/common/oauth2/access_token?client_id=myClientId&redirect_uri=myEncodedRedirect&code=kkd0rfhQqOOtHq35ifdkYl3UQ9WTrfv1&client_secret=myClientSecret&grant_type=authorization_code
will return me an access token in JSON format:
Would you reckon that there is no chance for me to reproduce this behavior in code?
Edit: I realized that the GET & POST above only work in browser if I'm logged into Odoo in the current browser session. Doing these without being logged in I get a 404 as well... which of course defeats the purpose of using OAuth in the first place. After all I want my client to fetch data w/o revealing my login data. So yes... as you stated - Odoo's implementation seems to be faulty.
But thank you again for all the help!
I guess your best option is to report this bug to them and hope they fix it quickly (or at least stop calling it OAuth2).
Closing this issue for now.