7.10 v8 API Error: access_denied Hint: Missing "Authorization" header

My Environment
PHP 7.0
MySQL 5.6
CentOS 6.9
Apache 2.4
SuiteCRM 7.10.4

If anyone have a solution or having a similar experience, please let me know. I’ve listed all the relevant information below I that I have investigated trying to fix this issue. I don’t have any error messages in Apache Error Logs pertaining to this issue.


I’m receiving the following error message in the suitecrm.log when I try to invoke the version 8 of the APIs:
[-none-][FATAL] [ERROR] [ResourceServer] Code: 9 Message: The resource owner or authorization server denied the request. ErrorType: access_denied Hint: Missing “Authorization” header


This is the error message I get in the error.log:
[22-May-2018 12:23:14 America/New_York] PHP Fatal error: Uncaught RuntimeException: Unexpected data in output buffer. Maybe you have characters before an opening <?php tag? in //vendor/slim/slim/Slim/App.php:604
Stack trace:
#0 //vendor/slim/slim/Slim/App.php(316): Slim\App->finalize(Object(Slim\Http\Response))
#1 //lib/API/core/app.php(83): Slim\App->run()
#2 //lib/API/public/index.php(5): require_once(’/home/hhadmin/a…’)
#3 {main}
thrown in //vendor/slim/slim/Slim/App.php on line 604


I’m following the example code but have tweak it since it had some coding errors: This is the code:

<?php $ch = curl_init(); $header = array( 'Content-type: applicatoin/vnd.api+json', 'Accept: application/vnd.api+json', ); $postStr = json_encode(array( 'grant_type' => 'client_credentials', 'client_id' => 'removed-b9b9-ded8-c2e0-removed', 'client_secret' => '', 'scope' => 'standard:create standard:read standard:update standard:delete stand:relationship:create standard:relationship:read standard:relationship:update standard;relationship:delete' )); $url = 'https:///api/oauth/access_token'; curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST'); curl_setopt($ch, CURLOPT_POSTFIELDS, $postStr); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_HTTPHEADER, $header); $output = curl_exec($ch); echo "the response(output):\n"; print($output); $txt ="\ncompleted\n"; echo $txt; print($url); echo "\n"; print($postStr); print("\n\n") ?>

I’ve also checked my .htaccess file to ensure the api mods were correct. This is what I have:

BEGIN SUGARCRM RESTRICTIONS

RedirectMatch 403 (?i)..log$
RedirectMatch 403 (?i)/+not_imported_.
.txt
RedirectMatch 403 (?i)/+(soap|cache|xtemplate|data|examples|include|log4php|metadata|modules)/+..(php|tpl)
RedirectMatch 403 (?i)/+emailmandelivery.php
RedirectMatch 403 (?i)/+upload
RedirectMatch 403 (?i)/+cache/+diagnostic
RedirectMatch 403 (?i)/+files.md5$

Options +FollowSymLinks
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]
RewriteRule ^cache/jsLanguage/(…
…).js$ index.php?entryPoint=jslang&module=app_strings&lang=$1 [L,QSA]
RewriteRule ^cache/jsLanguage/(\w*)/(…_…).js$ index.php?entryPoint=jslang&module=$1&lang=$2 [L,QSA]
RewriteRule ^api/(.?)$ lib/API/public/index.php/$1 [L]
RewriteRule ^api/(.
)$ - [env=HTTP_AUTHORIZATION:%{HTTP:Authorization}]

END SUGARCRM RESTRICTIONS

RewriteEngine On
RewriteCond %{SERVER_PORT} 80
RewriteRule ^(.*)$ https://myurl-removed.com

Options +FollowSymLinks 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] RewriteRule ^api/(.*?)$ lib/SuiteCRM/API/public/index.php/$1 [L] RewriteRule ^api/(.*)$ - [env=HTTP_AUTHORIZATION:%{HTTP:Authorization}] Header set ETag "" Header set Cache-Control "max-age=2592000" Header set Expires "01 Jan 2112 00:00:00 GMT" ExpiresByType text/css "access plus 1 month" ExpiresByType text/javascript "access plus 1 month" ExpiresByType application/x-javascript "access plus 1 month" ExpiresByType image/gif "access plus 1 month" ExpiresByType image/jpg "access plus 1 month" ExpiresByType image/png "access plus 1 month"

Hello
Same issue here, but without the errors in the log (no errors at all for me), just a 401 in the access_log.
Trying both Postman and jMeter, no success.
Should you have found a solution, let us know!

I didn’t find a solution. I just used v4.1 version of the APIs

Hello
I did some research, and I managed to have the v8 API working.
There are several issues here and unfortunately I dont’ have the bandwidth to provide a quality report, I hope this may help anyway.

WRT the Authorization issue, I could solve it as described here, by adding the

 SetEnvIf

to .htaccess.
Note that the

 RewriteRule

is already in place, I don’t know Apache/PHP enough to determine why this is required.

That fixed, I had an issue with the token being immediately revoked. This is a known issue, and was indeed fixed by modifying the timezone in php.ini.

Finally, I should say that I am using a bitnami image on AWS, updated to the latest stable release (7.10.7).

Hope this helps

Also faced with the same issue and now struggling against it. I am a .NET developer and not really familiar with LAMP stack. But liked suite CRM. Could you provide your .htaccess so I could compare it with mine?

The part of mine looks like and it is an image of Bitnami Suite CRM on Azure(surprise surprise)

Options +FollowSymLinks RewriteEngine On #RewriteBase /suitecrm 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] RewriteRule ^api/(.*?)$ lib/API/public/index.php/$1 [L] RewriteRule ^api/(.*)$ - [env=HTTP_AUTHORIZATION:%{HTTP:Authorization}]

But I didn’t really got on what should be [env=HTTP_AUTHORIZATION:%{HTTP:Authorization}] replaced.

Hello
sorry for the late reply

This is the relevant part of my .htaccess

<IfModule mod_rewrite.c>
    Options +FollowSymLinks
    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]
    RewriteRule ^cache/jsLanguage/(.._..).js$ index.php?entryPoint=jslang&module=app_strings&lang=$1 [L,QSA]
    RewriteRule ^cache/jsLanguage/(\w*)/(.._..).js$ index.php?entryPoint=jslang&module=$1&lang=$2 [L,QSA]
    RewriteRule ^api/(.*?)$ lib/API/public/index.php/$1 [L]
    RewriteRule ^api/(.*)$ - [env=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
</IfModule>
# END SUGARCRM RESTRICTIONS

SetEnvIf Authorization .+ HTTP_AUTHORIZATION=$0

but it took some try/error before I had it working so I wouldn’t recommend a plain copy/paste

Hi

Anyone else hitting this same problem still?. Im on 7.10.7 and I too have seen the errors in the example code - specifically the open backtick at the end of the second header array line and the reference to url rather than $url on the first curl_setopt line but with the code updated to the below


$ch = curl_init();
$header = array(
    'Content-type: application/vnd.api+json',
    'Accept: application/vnd.api+json',
 );
$postStr = json_encode(array(
    'grant_type' => 'client_credentials',
    'client_id' => 'my_created_client_id',
    'client_secret' => 'my_provided_secret',
    'scope' => 'standard:create standard:read standard:update standard:delete standard:delete standard:relationship:create standard:relationship:read standard:relationship:update standard:relationship:delete'
));
$url = 'https://mydomain.co.uk/api/oauth/access_token';
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
curl_setopt($ch, CURLOPT_POSTFIELDS, $postStr);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
$output = curl_exec($ch);
print_r($output);

I am getting the

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

Ive run through the rebuild htaccess code in the admin system and Ive added the SetEnvIf into my .htaccess just in case, but still getting the same

This is with Apache 2.4 , PHP 7.2 , Linux

Whats confusing me is that the $header is being set up with a Content-type and an Accept header but no Authorization - so Im not surprised its squawking with a missing authorization header

Im obviously doing something wrong

If anyone can point me in the right direction?

Thanks

Tony

I’m also facing same issue :frowning: any body find solution on this? My SuiteCRM version is 7.11.8

1 Like

The solution is the next version of SuiteCRM, or you can also apply this fix manually:

https://github.com/salesagility/SuiteCRM/pull/7762/files

At least i think that is causing this API problem. Tell me if it works.

1 Like

A few thoughts:

In order for the V8 API OAuth server to allow a token to be granted, you are required to communicate via https. (Port 443 ratherthan http over port 80)

Next issue is the :
[22-May-2018 12:23:14 America/New_York] PHP Fatal error: Uncaught RuntimeException: Unexpected data in output buffer. Maybe you have characters before an opening <?php tag? in //vendor/slim/slim/Slim/App.php:604

Which in the cases that I’ve debugged was due to a security conscious admin not allowing the web installer to write directly to the config.php file. As a result, they cut and pasted in the file and saved it. They left blank lines in the file after the ?> . Remove those blank lines. You’ll find that you can also remove the ?> at the end of the config.php, but I personally hate not having my tags closed!

With respect to the API endpoints, I now personally change them to be correct and not requiring the ‘rewrite rule’, as it requires another module to be functional, AND, in the web installer messes up the information that you get given to manually cut/paste into the .htaccess

e.g.
https://domain.com/suitecrm/Api/index.php/access_token
and
https://domain.com/suitecrm/Api/index.php/V8/module

Obviously, you’ve configured your public/private keys as detailed in

If that all fails, then time to up the logging level as detailed in:

I know that there some glitches in this interface that have been reported, but I can confirm that it can definitely be made to behave as expected in the latest 7.10.x and 7.11.x versions as at today.