salesagility / SuiteCRM

SuiteCRM - Open source CRM for the world
https://www.suitecrm.com
GNU Affero General Public License v3.0
4.4k stars 2.06k forks source link

7.11.10: /Api/access_token not found (.htaccess) #8251

Closed sutidor closed 3 years ago

sutidor commented 4 years ago

Issue

When I want to work with Api v8 I got a strange error: /Api/access_token gives me "File not found." (which is a custom message, because if I use /Api/abcdef it gives me Server Error 404 Page Not Found - which is the standard server 404 error message)

My rewrite engine is on, I checked by changing the line RewriteRule ^Api/access_token$ Api/index.php/access_token [L] to google.com and it works.

Permissions should be fine, I set them with a script.

When I use Api/index.php/access_token though, everything works normally.

my .htaccess file looks like this:

RedirectMatch 403 .*\.log$
RedirectMatch 403 /+not_imported_.*\.txt
RedirectMatch 403 /+(soap|cache|xtemplate|data|examples|include|log4php|metadata|modules|vendor)/+.*\.(php|tpl)
RedirectMatch 403 /+emailmandelivery\.php
RedirectMatch 403 /+.git
RedirectMatch 403 /+.cache/
RedirectMatch 403 /+tests
RedirectMatch 403 /+RoboFile\.php
RedirectMatch 403 /+composer\.json
RedirectMatch 403 /+composer\.lock
RedirectMatch 403 /+upload
RedirectMatch 403 /+custom/+blowfish
RedirectMatch 403 /+cache/+diagnostic
RedirectMatch 403 /+files\.md5$

<IfModule mod_rewrite.c>
    Options +SymLinksIfOwnerMatch
    Options -Indexes
    Options -MultiViews
    RewriteEngine On
    RewriteBase /
    RewriteRule ^cache/jsLanguage/(.._..).js$ index.php?entryPoint=jslang&modulename=app_strings&lang=$1 [L,QSA]
    RewriteRule ^cache/jsLanguage/(\w*)/(.._..).js$ index.php?entryPoint=jslang&modulename=$1&lang=$2 [L,QSA]

    # --------- DEPRECATED --------
    RewriteRule ^api/(.*)$ - [env=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
    RewriteRule ^api/(.*?)$ lib/API/public/index.php/$1 [L]
    # -----------------------------

    RewriteRule ^Api/(.*)$ - [env=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
    RewriteRule ^Api/access_token$ Api/index.php/access_token [L]
    RewriteRule ^Api/V8/(.*?)$ Api/index.php/V8/$1 [L]
</IfModule>
<IfModule mod_headers.c>
    Header unset ETag
    FileETag None
</IfModule>
<IfModule mod_headers.c>
    Header unset X-Powered-By
    Header always unset X-Powered-By
</IfModule>
<IfModule mod_expires.c>
 ExpiresActive on
 ExpiresDefault "access plus 1 month"

 # CSS
 ExpiresByType text/css "access plus 1 year"

 # Data
 ExpiresByType application/atom+xml "access plus 1 hour"
 ExpiresByType application/rdf+xml "access plus 1 hour"
 ExpiresByType application/rss+xml "access plus 1 hour"
 ExpiresByType application/json "access plus 0 seconds"
 ExpiresByType application/ld+json "access plus 0 seconds"
 ExpiresByType application/schema+json "access plus 0 seconds"
 ExpiresByType application/geo+json "access plus 0 seconds"
 ExpiresByType application/xml "access plus 0 seconds"
 ExpiresByType text/calendar "access plus 0 seconds"
 ExpiresByType text/xml "access plus 0 seconds"

 # Favicon
 ExpiresByType image/x-icon "access plus 1 week"

 # HTML
 ExpiresByType text/html "access plus 0 seconds"

 # JavaScript
 ExpiresByType application/javascript "access plus 1 year"
 ExpiresByType application/x-javascript "access plus 1 year"
 ExpiresByType text/javascript "access plus 1 year"

 # Markdown
 ExpiresByType text/markdown "access plus 0 seconds"

 # Media files
 ExpiresByType audio/ogg "access plus 1 month"
 ExpiresByType image/bmp "access plus 1 month"
 ExpiresByType image/gif "access plus 1 month"
 ExpiresByType image/jpeg "access plus 1 month"
 ExpiresByType image/jpg "access plus 1 month"
 ExpiresByType image/png "access plus 1 month"
 ExpiresByType image/svg+xml "access plus 1 month"
 ExpiresByType image/webp "access plus 1 month"
 ExpiresByType video/mp4 "access plus 1 month"
 ExpiresByType video/ogg "access plus 1 month"
 ExpiresByType video/webm "access plus 1 month"

 # Fonts
 ExpiresByType font/eot "access plus 1 month"
 ExpiresByType font/opentype "access plus 1 month"
 ExpiresByType font/otf "access plus 1 month"
 ExpiresByType application/x-font-ttf "access plus 1 month"
 ExpiresByType font/ttf "access plus 1 month"
 ExpiresByType application/font-woff "access plus 1 month"
 ExpiresByType application/x-font-woff "access plus 1 month"
 ExpiresByType font/woff "access plus 1 month"
 ExpiresByType application/font-woff2 "access plus 1 month"
 ExpiresByType font/woff2 "access plus 1 month"

 # Other
 ExpiresByType text/x-cross-domain-policy "access plus 1 week"
</IfModule>
<IfModule mod_headers.c>
    Header set X-Content-Type-Options "nosniff"
</IfModule>
<IfModule mod_rewrite.c>
        RewriteEngine On
        RewriteCond %{REQUEST_FILENAME} !-d
        RewriteCond %{REQUEST_URI} (.+)/$
        RewriteRule ^ %1 [R=301,L]
</IfModule>
# END SUITECRM RESTRICTIONS

Expected Behavior

I expect /Api/access_token to work like Api/index.php/access_token

Actual Behavior

It gives me File not found. (which is not the standard Error message!)

Steps to Reproduce

Context

Medium priority, as the Api works but with the long link

Your Environment

Mac-Rae commented 4 years ago

Hi @sutidor,

I've removed the link you provided as it would not be of assistance while debugging :+1:

Thanks

pgorod commented 4 years ago

Did you run Admin / Repairs / Rebuild .htaccess ?

sutidor commented 4 years ago

I did the normal repair and the rebuild .htaccess. What would you expect the .htaccess to look like after this?

Mac-Rae commented 4 years ago

Hi @sutidor,

# --------- DEPRECATED --------
RewriteRule ^api/(.*)$ - [env=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
RewriteRule ^api/(.*?)$ lib/API/public/index.php/$1 [L]
# -----------------------------

RewriteRule ^Api/(.*)$ - [env=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
RewriteRule ^Api/access_token$ Api/index.php/access_token [L]
RewriteRule ^Api/V8/(.*?)$ Api/index.php/V8/$1 [L]

After rebuilding my .htaccess this section is present which appears to redirect correctly. (Didn't test via the API just via browser to see if .htaccess was blocking me and it seemed to be alright)

Just to confirm with @pgorod, did you run the repair command below? Screenshot from 2019-11-15 11-31-17

sutidor commented 4 years ago

Hi @Mac-Rae, yes I did run the command and your section looks exactly like mine, I double checked.

That's exactly what makes this error super weird: If I use the long path it does work and I see no error in my .htacces.

Mac-Rae commented 4 years ago

Hmm, strange.

@sutidor could you try, just in a browser navigating to /lib/API/public/index.php Should get something like;

{"error":"access_denied","message":"The resource owner or authorization server denied the request.","hint":"Missing \"Authorization\" header"}

Just so we know the .htaccess is working as expected.

sutidor commented 4 years ago

I did as you suggested and the exact same message appears: {"error":"access_denied","message":"The resource owner or authorization server denied the request.","hint":"Missing \"Authorization\" header"}

jt0in3e commented 4 years ago

I have similar problem but with NGINX. I've set up rewrite rules correctly (hope so ), checked path /lib/API/public/index.phpwhich gave

{"error":"access_denied","message":"The resource owner or authorization server denied the request.","hint":"Missing \"Authorization\" header"}.

However, either /Api/access_token or /Api/index.php/access_token gives server error 404 Page Not Found.

From nginx logs:

2020/01/12 20:50:01 [error] 27020#27020: *23 open() "/srv/http/example/www/crm/Api/index.php/access_token" failed (20: Not a directory), client: 71.124.78.10, server: example.com, request: "GET /crm/Api/access_token HTTP/2.0", host: "example.com"

theerapatkij commented 4 years ago

I try to use API v8 with nginx and convert the htaccess to nginx format and I'm still have a same similar problem. So I gave up and use apache then it's working.

Maybe you should try with apache to see it's working or not

In official document nginx is not there. https://docs.suitecrm.com/admin/compatibility-matrix/

Hopefully, It will support soon.

jt0in3e commented 4 years ago

@theerapatkij It doesn't work with Apache too. It works only for /Api/access_token (and I also successfully rewrote rules for nginx) , but for any other API path doesn't (say '/Api/V8/meta/swagger.json' displays custom 'Page Not Found', not apache server response as 404 Not Found.). Tried Quick Repair, Repair .httaccess with no luck (

Edit1: I've also checked this path '/lib/API/public/index.php' as recommended by @Mac-Rae and received the same error as @sutidor (on Apache server) ` {"error":"access_denied","message":"The resource owner or authorization server denied the request.","hint":"Missing \"Authorization\" header"}

Edit2: Please find some LOGS for GET method '/Api/V8/meta/swagger.json'. Hope this would help. `

theerapatkij commented 4 years ago

@jt0in3e Can you use Postman application to send POST request then compare the response. It should be 400 Bad request and result will be

{ "error": "unsupported_grant_type", "message": "The authorization grant type is not supported by the authorization server.", "hint": "Check thegrant_typeparameter" }

Don't forget to change your domain. Screen Shot 2020-01-17 at 12 19 55 AM

jt0in3e commented 4 years ago

@theerapatkij Here it is { "error": "unsupported_grant_type", "message": "The authorization grant type is not supported by the authorization server.", "hint": "Check thegrant_typeparameter" }

Screenshot at 2020-01-17 11-29-23

Made some reporting/logging/printing variable $_SERVER from index.php ('/Api/Index.php'). This should be interesting. Please see result

theerapatkij commented 4 years ago

@jt0in3e That result is prove of API is working. But you dont know how to use it. I think you misunderstand how to use API V8 in SuiteCRM. You should follow this instruction. This is my simple explain about using API.

  1. You need to create "Client Credentials". Go to SuiteCRM Admin panel > see in section "System" > OAuth2 Clients and Tokens You'll see "New Client Credentials Client"
  2. After you created. Remember your secret and ID which system generate for you.
  3. Back to POSTMAN same request that you test. Select "Body" section and fill key and value from what you create client like this Screen Shot 2020-01-18 at 12 11 36 PM
  4. If you get result of access token. So your API is working! which mean you need to learning about API more how to use the endpoints. I suggest you to read SuiteCRM documentation for more info.

https://docs.suitecrm.com/developer/api/developer-setup-guide/json-api/

jt0in3e commented 4 years ago

@theerapatkij So, in the case ‘/Api/V8/meta/swagger.json’ should work without token, shouldn’t it? As per docs But it doesn’t, and displays custom Page Not Found page not generated by Apache server. Or do I miss something?

theerapatkij commented 4 years ago

@jt0in3e I never use swagger before. I use only POSTMAN to test the API and they prepare Collection of API for import to POSTMAN location is in "Api/docs/postman". But you want to get swagger.json from right? Location is "Api/docs/swagger/swagger.json" You can change to from ‘/Api/V8/meta/swagger.json’ instead and no Authen required just basic request a file. or you can request from browser

Screen Shot 2020-01-18 at 6 44 21 PM (Sorry, My suitecrm.url is 'host/Api which means http://localhost/Api/docs/swagger/swagger.json) Maybe the documentation on that page is not update. Because the route of API in "Api/V8/Config/routes.php" is no swagger at all.

jt0in3e commented 4 years ago

Thank you, @theerapatkij . I do confirm that API works and the documentation re 'swagger' not updated. Previously I've tested requests to Api/docs/swagger/swagger.json as well and it worked. Thus thought the path 'Api/V8/meta/swagger.json' from docs just incorrectly redirects by either webserver or php script. Have stuck at this point, didn't test anything else. And now big move was made to test API's endpoints ))) (really don't need the swagger, just have been testing if API works).

(additions): Api didn't work with default install and setup of Apache&SuiteCRM on Debian 10 (setting up of keys, credentials, hash secret etc was made). This was because the mod_rewrite module was not activated by default, and AllowOverride directive was set to None, not to All. Maybe it should be mentioned in the docs somehow, e.g. in Before you start section

tsitle commented 4 years ago

The PR #8486 should also resolve this issue.

sutidor commented 4 years ago

I updated to 7.11.12 now, and the issue persists.

  1. I tested Api/docs/swagger/swagger.json and it works
  2. I tested /Api/index.php/access_token and it works as expected (Browser: Method not allowed Method not allowed. Must be one of: POST)
  3. I tested .htaccess by replacing the line RewriteRule ^Api/access_token$ Api/index.php/access_token [L] with RewriteRule ^Api/access_token$ https://google.com [R=301,L] and it works as expected
  4. I test /Api/access_token and it gives me the custom: File not found.
  5. I test /Api/access_tokenzz and it gives me the server-default: File not found (404)

see my htaccess (no modifications) attached htaccess-2020.txt

pgorod commented 4 years ago

@sutidor did you try with these changes? https://github.com/salesagility/SuiteCRM/pull/8486/files

Note that this is not merged yet...

sutidor commented 4 years ago

Note that this is not merged yet...

Thanks for your oversight, it indeed resolved the issue.

tsitle commented 4 years ago

Would be nice to see the PR merged one day ;-)

pgorod commented 4 years ago

@sutidor we re-opened because we normally only close the Issues after the PR is merged. Thanks.

Moriuks commented 3 years ago

So i been trying to use the suite API but i keep getting a 404 error..

What i've tried:

Set the rewrite rule

RewriteRule ^Api/(.*)$ - [env=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
RewriteRule ^Api/access_token$ Api/index.php/access_token [L]
RewriteRule ^Api/V8/(.*?)$ Api/index.php/V8/$1 [L]

Configure the OAuth client (password grant type) in the UI (Admin->Oauth Clients) and after all of this i still get an 4040 error. I'm not sure what else to try/check, i believe it has something to do with the bitnami installation.

I am stuck on this and not sure what else to try, any tip on how to solve this issue is greatly appreciate it

[1] https://docs.suitecrm.com/developer/api/developer-setup-guide/json-api/#_before_you_start_calling_endpoints

tsitle commented 3 years ago

@Moriuks The PR #8486 might resolve your issue. Your .htaccess seems to contain the original RewriteRules from an older SuiteCRM release (<7.11.16). After applying the PR #8486 and regenerating the .htaccess file you should be able to fetch an OAuth token e.g. via https://my.suite.crm/Api/access_token

Moriuks commented 3 years ago

thanks for the response @tsitle I tried what you mentioned but it still turns into an error, although i'm not sure if version 7.11.15 needs this change, i also notice that applying the PR #8486 and regenerating the .htaccess leads me back to the original .htaccess file (so it undos the changes).Also, after testing to https://my.suite.crm/Api/access_token i get a 505 errorPHP Fatal error: Uncaught Error: Call to undefined method League\\OAuth2\\Server\\AuthorizationServer::setEncryptionKey() so this error is not from this issue. Anyway , thanks for the help

tsitle commented 3 years ago

Hi @Moriuks , your .htaccess should now contain these lines:

    RewriteRule ^Api/(.*)$ - [env=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
    RewriteRule ^Api/access_token$ Api/index.php [L]
    RewriteRule ^Api/V8/(.*?)$ Api/index.php [L]

The PR I mentioned was merged into SuiteCRM version 7.11.16: Release Notes.

I just tested the current release 7.11.18 to see whether there are still problems with OAuth but it worked right out of the box (after creating the OpenSSL keypair of course):

SuiteCRM 7.11.18:

screen1-suitecrm

Postman:

screen2-postman

If your .htaccess is OK then perhaps you can fix the problem with OAuth by upgrading to the current SuiteCRM release...

Cheers!

Moriuks commented 3 years ago

Hi @tsitle , thank you for your detailed response.

I double check to make sure that i had what you mentioned and i did but kept getting the same result, so somewhere along the configuration with bitnami and the oauth2 was the error. So i decide to reinstall sugar with the following configuration:

After following the SuiteCRM API Docco and checking the .htaccess file (which by default it already has the changes you mentioned), enabling the mod rewrites in Apache and changing AllowOverride None to AllowOverride All i was good to go and started seeing the Oauth token.

Note: the endpoints i used for this to work are:

/Api/access_token. 
Api/V8/module/{Module}
sutidor commented 3 years ago

If you are using bitnami container change /opt/bitnami/apache2/conf/vhosts suitecrm-https-vhost.conf (if you are using https) suitecrm-vhost.conf (if you are using plain http) AllowOverride All

SuiteBot commented 2 years ago

This issue has been mentioned on SuiteCRM. There might be relevant details there:

https://community.suitecrm.com/t/404-for-v8-api-access-token/85498/1