I'm using SSRS SDK for PHP
PHP Version 5.4
webserver: Centos 6.4
MSSQL Server 2008 R2
define("UID", "*****\*****");
define("PASWD", "*****");
define("SERVICE_URL", "http://192.168.0.1/ReportServerURL/");
try {
$ssrs_report = new SSRSReport(new Credentials(UID, PASWD), SERVICE_URL);
} catch (SSRSReportException $serviceException) {
echo $serviceException->GetErrorMessage() . "<br>";
}
When I try to connect SSRS report, it is throughing the following error:
Failed to connect to Reporting Service
Make sure that the url (http://192.168.0.1/ReportServerURL/) and credentials are correct!
The same credentials & link are accessible through browser without problem. But, through SSRS SDK it is not working.
I was looking for a solution in the net and I find that using the file TestSSRSConnection.php I could get more details but I dont know how to use it, and I cant find any documentation about it.
$testSSRSConnection = new TestSSRSConnection("/192.168.0.1/TESTREPORT/ReportServerURL/*****\*****/*****");
$testSSRSConnection->Parse();
$testSSRSConnection->TestConnection();
Testing it I get the following error:
Usage:TestSSRSConnection.php /server: /report: /uid: /pwd: [/datasource: /uid: /pwd:]
Some idea how to go forward in this topic?
Update
Doing a var_export($http_response_header))
I got
array (
0 => 'HTTP/1.1 401 Unauthorized',
1 => 'Content-Length: 0',
2 => 'WWW-Authenticate: Negotiate',
3 => 'WWW-Authenticate: NTLM',
4 => 'Date: Tue, 04 Mar 2014 22:13:58 GMT',
5 => 'Connection: close',
)
The problem was with the Authentication Type.
By default, Reporting Services accepts requests that specify Negotiate and NTLM authentication. If your deployment includes client applications or browsers that use Basic authentication, you must add Basic authentication to the list of supported types.
To get the header response I added in the SSRSReport.php in the line 193
if ($content === FALSE) {
throw new SSRSReportException("", "<br>Failed to connect to Reporting Service <br/> Make sure " .
"that the url ($this->_BaseUrl) and credentials are correct!<br>" .
var_export($http_response_header));//Line added by me to get the http header response
}
Output:
array (
0 => 'HTTP/1.1 401 Unauthorized',
1 => 'Content-Length: 0',
2 => 'WWW-Authenticate: Negotiate',
3 => 'WWW-Authenticate: NTLM',
4 => 'Date: Tue, 04 Mar 2014 22:13:58 GMT',
5 => 'Connection: close',
)
Failed to connect to Reporting Service
Make sure that the url (http://192.168.0.1/ReportServerURL/) and credentials are correct!
Adding Basic authentication to the SSRS solve the problem.
To configure a report server to use Basic authentication
1- Open RSReportServer.config in a text editor.
2- Find Authentication.
3- Copy one of the following XML structures that best fits your needs. The first XML structure provides placeholders for specifying all of the elements, which are described in the next section:
<Authentication>
<AuthenticationTypes>
<RSWindowsBasic>
<LogonMethod>3</LogonMethod>
<Realm></Realm>
<DefaultDomain></DefaultDomain>
</RSWindowsBasic>
</AuthenticationTypes>
<EnableAuthPersistence>true</EnableAuthPersistence>
</Authentication>
If you are using default values, you can copy the minimum element structure:
<AuthenticationTypes>
<RSWindowsBasic/>
</AuthenticationTypes>
4- Paste it over the existing entries for .
If you are using multiple authentication types, add just the RSWindowsBasic element but do not delete the entries for RSWindowsNegotiate, RSWindowsNTLM, or RSWindowsKerberos.
To support the Safari browser, you cannot configure the report server to use multiple authentication types. You must specify only RSWindowsBasic and delete the other entries.
Note that you cannot use Custom with other authentication types.
5- Replace empty values for or with values that are valid for your environment.
6- Save the file.
7- If you configured a scale-out deployment, repeat these steps for other report servers in the deployment.
8- Restart the report server to clear any sessions that are currently open.
Assuming there's no actual bug in the SDK, I would venture a guess at saying the problem lies with the constants you have defined:
define("UID", "*****\*****");
The backslash separates domain from user name in Windows, but it has a special meaning in a string value, e.g.:
define("UID", "domain\nick");
echo UID;
Output
domain
nick
The \n was transformed into a newline; so what you want is escape the backslash:
define("UID", "domain\\nick"); // backslash is escaped
echo UID; // output: domain\nick
Update
Inside SSRSReport.php (line 168) there's this:
$stream_conext_params = array('http' => array(
'header' => array($credentials->getBase64Auth())
));
However, the header context option takes a string, not an array:
$stream_conext_params = array('http' => array(
'header' => $credentials->getBase64Auth(),
));
Related
I am connecting to dynamics 365. It used to work perfectly, i curl to get the token then i use it as an authorization header along with php soapclient and it works, i connect i create a client and i can call my methods.
All of a sudden it decided not to work, and where it used to connect as SOAP 1.1 now it enforced SOAP 1.2
After changing from SOAP 1.1 to SOAP 1.2 ( because I got the error of binding mismatch where it said expecting application/soap+xml and text/xml was found ) So I changed versions and that error disappeared and got replaced with ERROR Fetching HTTP Headers.
That error got stuck for the longest time, people suggested to increase timeout but i put it as high as 500 800 5000 all the same.
Then all of a sudden, it started giving me SOAP ERROR Parsing schema element already defined. I did not change my code, i played for awhile with the headers but to no avail, I even removed the authorization header just to see what is going on and that did nothing i kept getting the same error.
SOAP-ERROR: Parsing Schema: element 'http://schemas.datacontract.org/2004/07/Microsoft.Dynamics.Ax.Xpp:XppObjectBase' already defined [string:Exception:private]
everytime I try to connect I get different kind of parsing schema error even though i am not changing anything in my code:
SOAP-ERROR: Parsing Schema: element 'http://schemas.microsoft.com/2003/10/Serialization/:anyType' already defined [string:Exception:private]
and another
SOAP-ERROR: Parsing Schema: element 'http://schemas.datacontract.org/2004/07/Microsoft.Dynamics.AX.KernelInterop:ProxyBase' already defined [string:Exception:private]
and then sometimes it does get through for a second but with fetching http header error again..
so i can not create a client instance anymore now..
where before i was able to create a client instance but i get an error when I call the method of "Error Fetching HTTP Headers"
something is definitely not stable because my errors are not one.
now some stated the wsdl could be faulty, but this is microsoft and the person i am in contact keeps saying he can not doing anything about it.
Help is this a PHP problem or a dynamics problem or wsdl custom made problem .
And how to solve this.
Thank you.
UPDATE
I'm sorry I mentioned earlier it is Dynamics AX , it turns out it is Dynamics 365 D365. I will keep dynamics ax tag in case it helps someone who needs the solutions provided.
UPDATE
Following is the connection code I am using:
function getAuthenticationHeader()
{
//Each variable has the values for our server
//resource
$appResource = urlencode($appADResource);
//clientID
$appClientID = urlencode($appADClientId);
//appSecret
$appSecret = urlencode($appADSecret);
//username
$appUserID = urlencode($appUserID);
// Password
$appUserPassword = urlencode($password);
// Construct the body for the STS request
$authenticationRequestBody = 'resource='.$appResource.'&client_id='.$appClientID.'&client_secret='.$appSecret.'&grant_type=password&username='.$appUserID.'&password='.$appUserPassword.'&scope=openid';
//Using curl to post the information to STS and get back the authentication response
$ch = curl_init();
// set url
$stsUrl = 'https://login.microsoftonline.com/'.$appTenantId.'/oauth2/token';
curl_setopt($ch, CURLOPT_URL, $stsUrl);
// Get the response back as a string
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
// Set the parameters for the request
curl_setopt($ch, CURLOPT_POSTFIELDS, $authenticationRequestBody);
// By default, HTTPS does not work with curl.
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
// read the output from the post request
$output = curl_exec($ch);
// close curl resource to free up system resources
curl_close($ch);
// decode the response from sts using json decoder
$tokenOutput = json_decode($output);
return $tokenOutput->{'token_type'}.' '.$tokenOutput->{'access_token'};
}
try
{
//WSDL Link
$url = "https://urlToOurServer/services/webservice?wsdl";
$authorizationToken = getAuthenticationHeader();
$context = stream_context_create(array(
'ssl' => array(
'verify_peer' => false,
'verify_peer_name' => false,
'allow_self_signed' => true
),
'https' => array(
'curl_verify_ssl_peer' => false,
'curl_verify_ssl_host' => false
),
'http' => array(
'header' =>'Authorization: '.$authorizationToken
)
));
//Create array of Soap Options
$arrOpt = array(
"soap_version" => SOAP_1_2,
"cache_wsdl" => WSDL_CACHE_NONE,
"exceptions" => true,
'trace' => true,
'encoding' => 'UTF-8',
'stream_context' => $context
);
}catch(Exception $e)
{
print_r($e);
}
I also found this in my wsdl
<sp:IssuedToken sp:IncludeToken="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702/IncludeToken/AlwaysToRecipient">
<sp:RequestSecurityTokenTemplate>
<trust:TokenType xmlns:trust="http://docs.oasis-open.org/ws-sx/ws-trust/200512">
http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV2.0
</trust:TokenType>
<trust:KeyType xmlns:trust="http://docs.oasis-open.org/ws-sx/ws-trust/200512">
http://docs.oasis-open.org/ws-sx/ws-trust/200512/Bearer
</trust:KeyType>
</sp:RequestSecurityTokenTemplate>
<wsp:Policy>
<sp:RequireInternalReference/>
How can I connect to SAML for Token ?
If everything is pretty much the same, but it's not working, the first thing to do is rule out the most basic AX issues. These may not solve your issue but will be a good first step.
now some stated the wsdl could be faulty, but this is microsoft and the person i am in contact keeps saying he can not doing anything about it.
Whomever that person is, you need to confirm they've done the following:
Confirm the environment and specifically the CIL is fully compiled. Do a full AXBuild and a full CIL to be sure during non-business hours and ensure the output is good. It's basically saying "recompile everything".
Refresh the WCF configuration in the client configuration you are using to connect to AX. This client configuration may be a *.axc file or it may just be the active one. Also refresh the business connector WCF. This is separate and may be what you are using to connect to AX. This is what most people are talking about.
Here's a little article that talks about creating a configuration, but I'll discuss below.
An AX client configuration ultimately is a bunch of text. It's either stored in an .axc file or stored in the registry in a few locations. The Business Connector client config may be the one that is getting missed in your scenario.
If you follow the link above and create a new .axc configuration file and ensure you've clicked "Refresh Configuration" before exporting, when you open the file up in Notepad, you'll see wcfconfig and a bunch of XML following it. That XML is what you're trying to get updated. Creating a new AXC here is just an exercise to help you understand what it is. You can delete the file after you're done looking.
Now, you've basically created a specific configuration file, but that doesn't mean anything is using it. If you call AX32.exe it will default to the one that is loaded in that config screen. Using a file is a way to very specifically choose one. Your code is probably using a specific AXC somewhere that needs either replaced or refreshed OR it's using one that's saved in this window:
It is very likely it is using one of the two that are saved in that configuration window. When you refresh in that window, it ultimately saves the WCF XML in the windows registry on the machine that is hosting the client and/or the AOS in subfolders in HKLM\SOFTWARE\Microsoft\Dynamics\6.0\Configuration. The key(s) is wcfconfig paired with wcfconfigversionid, which just stores a GUID to see if it's up-to-date.
When I say two, I mean most people don't even bother to look at the Business Connector AXC. It's what is highlighted in yellow in my image, and you need to specifically choose and refresh it. This could be important for you. In my image, I do not have it chosen. You need to drop the menu down and choose it.
On a dev machine, you can just clear both of those keys and refresh and you should see whatever configuration you're working on update.
This is a long post, but it's important to rule this part out first. If you have someone who's reasonably experienced administering AX they should know how to ensure these are refreshed.
Since you're saying this is not Dynamics AX, but one of the Dynamics 365 versions. The AX version used to be called Dynamics 365 for Finance and Operations Enterprise Edition but they've changed the licensing/naming again, so I don't even know what it's technically called. Most people call it Dynamics 365 for Operations or some variant.
Either way, you should test the service following the below method. We would need to see more information about the service details and call, so following the below is most likely best.
https://learn.microsoft.com/en-us/dynamics365/fin-ops-core/dev-itpro/data-entities/third-party-service-test
Documentation of the service, says I need to use WS-Security.
From they support, i got a p12 file, which I should be using.
What I did so far
I ran up SoapUI application, configured it, added wsdl etc, and got message
<faultstring>These policy alternatives can not be satisfied: (...)</faultstring>
So I found I need to add basic Auth to the request. And i got my proper answer.
What I need now
I need to use this to SOAP requests, on my PHP application.
First, i changed p12 file into pem, and tried :
$soapClient = new SoapClient('https://int.pz.gov.pl/pz-services/tpSigning?wsdl',
array('location' => 'https://int.pz.gov.pl/pz-services/tpSigning?wsdl',
'trace' => 1,"exceptions" => 1,
'local_cert'=>'path/cert_file.pem',
'passphrase'=>'cert_password'
));
But I am still getting same fail message about policies not being satisfied:
These policy alternatives can not be satisfied:
{http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702}AsymmetricBinding: Received Timestamp does not match the requirements
{http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702}X509Token: The received token does not match the token inclusion requirement
{http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702}SignedParts: Soap Body is not SIGNED in (...)
Help?
Is it even possible with just PHP? I tried several solutions, found some class extending SoapClient (using user/password, not p12/pem file), found even solution in c# (which I am too ready to use if that's what I need to do - sending xml to c# with WebSocket, and sending it back to browser), but non of those worked.
Changing the cert into pem format is the right way. The native PHP soap client class can not handle p12 certs. Have you tried the following?
try {
$oClient = new SoapClient(
'https://int.pz.gov.pl/pz-services/tpSigning?wsdl',
[
'authentication' => SOAP_AUTHENTICATION_DIGEST,
'exceptions' => true,
'local_cert' => dirname(__FILE__) . 'mycert.pem',
'passphrase' => 'my_passphrase',
'trace' => true,
]
);
} catch (SoapFault $oSoapFault) {
echo "<pre>";
var_dump($oSoapFault);
echo "</pre>";
}
The PHP soap client class uses SOAP_AUTHENTICATION_BASIC by default. Perhaps the DIGEST auth is the right way? Normally the cert includes all the data.
You don 't need the location option. The location option is just required, when using non-wsdl conversation with target namespace as uri option without a direct wsdl file.
And always keep in mind: What works with SoapUI isn 't supposed to run with the native PHP client. ;)
I am following the example at https://getstream.io/get_started/?language=php to understand how getstream io works. I ran into an error that got me confused.
require_once './vendor/autoload.php';
$client = new GetStream\Stream\Client('YOUR_API_KEY', 'API_KEY_SECRET');
$chris = $client->feed('user', 'chris');
// I replaced Your api key and api key secret with the one in my dashboard
// Add an activity; message is a custom field - tip: add unlimited custom fields!
$data = array(
"actor" => "chris",
"verb" => "add",
"object" => "picture:10",
"foreign_id" => "picture:10",
"message" => "Beautiful bird. Absolutely beautiful. Phenomenal bird."
);
$chris->addActivity($data);
// jack's 'timeline' feed follows chris' 'user' feed:
$jack = $client->feed('timeline', 'jack');
$jack->followFeed('user', 'chris');
// Read the 'timeline' feed for jack, chris' post will now show up:
$activities = $jack->getActivities(10);
var_dump($activities);
In my composer.json file I did this
"require": {
"get-stream/stream": "2.2.8"
}
I tried the above code on my localhost machine on windows but got this error
Fatal error: Uncaught exception 'GuzzleHttp\ExceptionConnectException' with message 'cURL error 28: Operation timed out after 0 milliseconds with 0 out of 0 bytes received (see http://curl.haxx.se/libcurl/c/libcurl-errors.html)' in C:\xampp\htdocs\CorpersMate\vendor\guzzlehttp\guzzle\src\Handler\CurlFactory.php on line 186
GuzzleHttp\Exception\ConnectException: cURL error 28: Operation timed out after 0 milliseconds with 0 out of 0 bytes received (see http://curl.haxx.se/libcurl/c/libcurl-errors.html) in C:\xampp\htdocs\CorpersMate\vendor\guzzlehttp\guzzle\src\Handler\CurlFactory.php on line 186
any ideas guys?
You should provide guide - we have to register first to get it, it can't happen.
Change second line to
$client = new GetStream\Stream\Client(KEY, SECRET);
I later found a tweak to the problem. The problem is with the guzzle library which is trying to verify my certificate. Because I needed a way to test it on local server before moving to production server, I had to modify the client constructor in the guzzle library and that solved the problem for me.
// file name is Client.php
public function __construct(array $config = ['verify' => false]) {
if (!isset($config['handler'])) {
$config['handler'] = HandlerStack::create();
}
// Convert the base_uri to a UriInterface
if (isset($config['base_uri'])) {
$config['base_uri'] = Psr7\uri_for($config['base_uri']);
}
$this->configureDefaults($config);
}
I'll dig into why this doesn't work on Xampp for you. Can you send us your cURL options, library version, etc.?
In the meantime, based on the workflow you've built:
build a feed for Chris
build an activity and put it on Chris' feed
build a feed for Jack
Jack follows Chris' feed
read Jack's feed and expect to see Chris' activity
... Jack will need to specify a number of activities to copy when following Chris' feed, otherwise Jack will only see updates from that point on; Jack will never see "picture:10" from Chris. There's a third optional parameter you can send through followFeed() that specifies how many items to copy to Jack's feed when you start following:
$jack->followFeed('user', 'chris', 100);
Or you can move step 4 between step 1 and 2. If Jack follows Chris before Chris adds a photo, it should show up on Jack's feed.
I am trying to perform a Bing Search by using the Windows Azure Marketplace API, I have downloaded their guide and sample code. The code prepares a HTTPS request with basic authentication, however I am constantly getting the following error:
Warning: file_get_contents(https://api.datamarket.azure.com/Data.ashx/Bing/SearchWeb/Web?Query=%27washburn%27&Adult=%27Off%27&$top=50&$format=Atom): failed to open stream: Connection refused
The php code (from Microsoft's document):
$context = stream_context_create(array(
'http' => array(
'proxy' => 'tcp://127.0.0.1:8888',
'request_fulluri' => true,
'header' => "Authorization: Basic " . base64_encode($accountKey.":".$accountKey)
)
));
Does anyone know what is causing the error please? I have correctly set the $accountKey and I tested it in a browser. What puzzles me a little is 127.0.0.1:8888 and also base64_encode($accountKey.":".$accountKey) , how come you need the $accountKey both before and after the : while when using a browser you are supposed to leave the username blank and just input the account key into the password field?
I have solved it and here is what I have found for future people that would be doing the same thing:
I commented out the line where it says:
'proxy' => 'tcp://127.0.0.1:8888',
'request_fulluri' => true,
and also set base64_encode("ignored:".$accountKey) instead
Base on what I read on MSDN, the username part is said to be ignored, so it shouldn't matter what value it is. I was thinking perhaps the length or the special characters in the key screwed things up so I replaces it with ignored (or anything really).
That did the trick and I can parse the returned JSON data. Good luck!
I've tried using Matt Harris' Twitter OAUTH library (https://github.com/themattharris/tmhOAuth) replacing default data with my keys and tokens, but for some reason I can't get a valid response code.
The url I'm testing with ends with a port (8888), but I'm not sure if that is to do with it. I'm tailing the PHP log and there are no errors.
$tweet_text = 'Hello world!';
print "Posting...\n";
$result = post_tweet($tweet_text);
print "Response code: " . $result . "\n";
function post_tweet($tweet_text) {
require_once('tmhOAuth.php');
$connection = new tmhOAuth(array(
'consumer_key' => '(hidden)',
'consumer_secret' => '(hidden)',
'user_token' => '(hidden)',
'user_secret' => '(hidden)',
));
$connection->request('POST',
$connection->url('1/statuses/update'),
array('status' => $tweet_text));
return $connection->response['code'];
}
Does anybody have any ideas?
Many thanks.
I had this problem and it's due to this recent change in December 2011:
"defaulted CURLOPT_SSL_VERIFYPEER to true"
If you dump $connection->response as Darren advises, you may see an error such as this one which I had:
string(165) "error setting certificate verify locations:"
Either make sure that the certificate file cacert.pem is in place, or disable SSL_VERIFYPEER.
I'm willing to bet that this will fix your issue (although it may not be the most secure solution):
$connection = new tmhOAuth(array(
'consumer_key' => '(hidden)',
'consumer_secret' => '(hidden)',
'user_token' => '(hidden)',
'user_secret' => '(hidden)',
'curl_ssl_verifypeer' => false
));
Update February 2015
Looking back on this answer today, I realise that advising people to set curl_ssl_verifypeer to false is not a very good answer (at this point you can no longer be sure you're talking to Twitter, so in fact it's a terrible answer). Instead, take the other advice I gave and ensure the appropriate Root CA Certificate file (cacert.pem) is in place.
If you compare with https://github.com/themattharris/tmhOAuth/blob/master/examples/tweet.php your code might need to change to look like:
$code=$connection->request('POST', ...);
return $code;
However, looking at the source code, reveals two things. First your code should be just as good as that, because $this->response['code'] is set to the value that gets returned. Second that that function (actually curlit()) can also return void. When it does that response['code'] is undefined. (This was looking like a promising twitter library until I saw that design mistake.)
Probing even further, it would only return void when $this->config['prevent_request'] exists and is true. You're not doing that, and we've gone full circle to not being able to explain the behaviour you see.
So, my next troubleshooting step would be to put error_reporting(E_ALL|E_NOTICE) at the top, and then check the error logs for more clues. Also do a print_r($connection->response) after your call to request() to see what else you have in there.
Looks like you need to make sure you have a current cert.
According to TMH's git repo:
Version 0.60 hardened the security of the library and defaulted curl_ssl_verifypeer to true. As some hosting providers do not provide the most current certificate root file it is now included in TMH's repository. If the version is out of date OR you prefer to download the certificate roots yourself, you can get them from: http://curl.haxx.se/ca/cacert.pem
Before upgrading the version of tmhOAuth that you use, be sure to verify the SSL handling works on your server by running the examples/verify_ssl.php script.