magento-lts: Access denied when connecting via SOAP

A customer used before the update to openmage api calls for some marketing stuff. After the update to openmage, it is not possible to connect via soap.

For testing I created a new user with full permissions. I tried to connect with the following snippet

<?php 
try {
$client = new SoapClient('https://www.domain.com/api/v2_soap/?wsdl=1');
$session = $client->login('APIUSER', 'APIPASSWORD');

print '<pre>Works: '.print_r($session,1).'</pre>';
}
catch (Exception $e) {
print '<pre>Does not work: '.print_r($e,1).'</pre>';
}
?>

As result I get the faultstring “Access denied” with faultcode 2. I tested this with enabled and with disabled ws-i conformitiy. Even with enabled and disabled wsdl-cache. I always cleared the caches when I changed anything. Does anyone has an idea what could be wrong?

About this issue

  • Original URL
  • State: closed
  • Created 3 years ago
  • Comments: 32 (30 by maintainers)

Most upvoted comments

Can somebody create a PR for this? It’s starting to stagnate since it doesn’t have any answer since 2 months

The OP’s issue was already resolved. It was caused by the migration process.

Hi Guys,

Just thought I would add my fix for this issue.

I added -MultiViews to the .htaccess file and it seemed to resolve the issue.

Let me sum up common issues which occur when using SOAP:

  1. check if the server can connect to itself, e.g. run (curl -I https://myhostname/api/soap?wsdl) from ssh command line, this problem often results in the error “Error WSDL: SOAP-ERROR: Parsing WSDL: Couldn’t load from ‘http://Myhostname/api/soap?wsdl’ : failed to load external entity”
  2. check if curl i openssl PHP modules are installed
  3. is Magento cache enabled?
  4. is basic auth removed (htpasswd)
  5. isn’t default_socket_timeout not too low?
  6. check if the soap response body is not 1 char longer than Content-length header
  7. make sure API url’s are without index.php (/api/soap instead of index.php/api)
  8. make sure nginx/apache rewrites are correctly set apache:
RewriteRule ^api/([a-z][0-9a-z_]+)/?$ api.php?type=$1 [QSA,L]

nginx:

location /api {
        rewrite ^/api/rest /api.php?type=rest last;
        rewrite ^/api/v2_soap /api.php?type=v2_soap last;
        rewrite ^/api/soap /api.php?type=soap last;
    }
  1. check response from /api/v2_soap?wsdl=1 an make sure there are no url’s with index.php inside (if there are, try clearing cache)

  2. use the following scripts to debug connection using soap v1:

$mage_user = 'soap_user';
$mage_api_key = 'soap_passwd';
$mage_url = 'https://myshop.domain/api/soap/?wsdl';
$ini = ini_set("soap.wsdl_cache_enabled", 0);
$client = new SoapClient( $mage_url ,array('trace' => true));
try {
    print_r($client->__getFunctions());
    $session_id = $client->login($mage_user, $mage_api_key);
    $result = $client->call( $session_id, 'directory_country.list' );
    var_dump($result);
} catch (Exception $e) {
    var_dump($e->getMessage());
    echo "<br>Request Headers:<br>", htmlentities($client->__getLastRequestHeaders()), "<br>";
    echo "<br>Request :<br>", htmlentities($client->__getLastRequest()), "<br>";
    echo "<br>Response Headers:<br>", htmlentities($client->__getLastResponseHeaders()), "<br>";
    echo "<br>Response body:<br>", htmlentities($client->__getLastResponse()), "<br>";
}

or for SOAP 2

function debugSoap($proxy) {
echo "<br>Request Headers:<br><pre>", htmlentities($proxy->__getLastRequestHeaders()), "</pre><br>";
echo "<br>Request :<br><pre>", htmlentities($proxy->__getLastRequest()), "</pre><br>";
echo "<br>Response Headers:<br><pre>", htmlentities($proxy->__getLastResponseHeaders()), "</pre><br>";
echo "<br>Response body:<br><pre>", htmlentities($proxy->__getLastResponse()), "</pre><br>";
}

ini_set('display_errors', 1);
ini_set("soap.wsdl_cache_enabled", 0);
//ini_set("default_socket_timeout", 3);
  
$user = 'test';
$password = 'test';
$url = 'https://myshop.domain/api/v2_soap?wsdl=1';
$client = new SoapClient($url, array('trace' => true));
try {
    echo "trying to login\n";
    $sessionId = $client->login($user, $password);
    echo "logged in\n";
    $result = $client->customerCustomerList($sessionId);
    var_dump($result);
 
} catch (Exception $e) {
    var_dump($e->getMessage());
    debugSoap($client);
}