Login to yammer through axapta - authentication

I have an assignment to develop a functionality for the Microsoft Dynamics AX (2012) i.e. in the SalesTable form I need to open a browser with automatically authentication to Yammer.
By analyzing the http webRequests (with Fiddler tool ) I have discovered that for this purpose there several web request are sending (with specific parameters and cookies) in certain sequence, such as:
1. https://www.yammer.com/oauth2/authorize?client_id=VALUE&redirect_uri=https://www.yammer.com
2. https://www.yammer.com/dialog/authenticate?client_id=VALUE
3. https://www.yammer.com/images/public-site-spacer.gif
4. https://persona.yammer.com/login_provider.json?email=VALUE&state=VALUE
5. https://login.microsoftonline.com/common/oauth2/authorize?client_id=VALUE&domain_hint=VALUE&login_hint=&nonce=2VALUE&redirect_uri=VALUE&response_mode=query&response_type=id_token&scope=open_id&site_id=VALUE&state=VALUE
6. https://login.microsoftonline.com/common/userrealm/?user=VALUE&api-version=VALUE&stsRequest=VALUE&checkForMicrosoftAccount=VALUE
7. https://login.microsoftonline.com/common/login
All these request I sending programmatically and can catch the web Response object from such web request, except request #7. With Fiddler tool I can see than additional request has been send automatically to the:
1. https://persona.yammer.com/office_sessions?id_token=VALUE&state=&session_state=VALUE
and to the URI above just after #8
2. https://www.yammer.com/?persona_token=VALUE&state=
When I try to create requests #8 and #9 programmatically (let’s say #8My and #9My) I have an error.
My final goal is to get some mandatory parameters such as: ("browser_token", "oauth_token" and "code") from the webResponses on the #8 and #9 requests.
Can you please help me to define how to get them? Maybe I should skip some request listed above or add some additional requests (which one?)?
Thank you
Commented as of 16.06.2016
I will try to localize the problem (because there are quite a lot of gaps and for the sake of clarity I will ask questions one by one), thank you for understanding.
Below there is a screenshot of my requests
enter image description here
On the step #7 I’m sending the following request:
GET https://persona.yammer.com/login_provider.json?email=myEmail#myDomain.com&state=41a563bc24e263ed5b35fbe63e7c5c556a0477024d88b28fb012ed6de48b1d39 HTTP/1.1
Host: persona.yammer.com
Cookie: yamtrak_id=2b9ea0d1-55c4-4368-b893-d9b7e3b1da32
Fiddler shows me, that in response of this request (#7), there is parameter “_session_id=” (value is showed below and in red rectangular on the screenshot)
_session_id=Zlk2YjlkcFZPdTZlOHAwVHl4L0lodC85K1VvaUFkbWxNZU5LZzNLcWR6SU1JWEI4c0l1aFpjMmhGNlllcEFVQ1VtNVN6R1lwTGxoZFNIYW5zb3pKSlE9PS0tdWxIVXEzR3JIN0RQcUsvU2svOVY4QT09--6fc208ae3d6d939e3e2e7eecfffd1d23d3051f39;
This parameter (_session_id) will be used in request #12.
But when I grab (programmatically) the cookies in response of the request #7, the value of this parameter is absolutely different from mentioned above (and the name of the parameter is “_session=” (instead of “_session_id=”).
_session=BAh7CUkiD3Nlc3Npb25faWQGOgZFRkkiJTU0OGYyOTQ0YTAxNzYyNjUzZmJlMGI2ZmZjOTU3ZWI4BjsAVEkiC21vYmlsZQY7AEZGSSIQX2NzcmZfdG9rZW4GOwBGSSIxTlZRZkFJRTZHeHdJWUtxcUtVNHEzWXNKeDZ2Z2FiQUZ6NXJIalM0Nk0zTT0GOwBGSSIKZmxhc2gGOwBGbzolQWN0aW9uRGlzcGF0Y2g6OkZsYXNoOjpGbGFzaEhhc2gJOgxAY2xvc2VkRjoNQGZsYXNoZXN7CToKZXJyb3IwOgl0cmZlMDoLbm90aWNlMDoJdHJmbjA6CUBub3cwOgpAdXNlZG86CFNldAY6CkBoYXNoewk7CVQ7ClQ7C1Q7DFQ%3D--ea5007eba2efabc2627f2e5af66c4c57f22d53bb
Here is the code of how I’m getting the Cookies string from the HttpWebResponse
public string getStringCookies(System.Net.HttpWebResponse _response)
{
string cookies = string.Empty;
try
{
cookies = _response.Headers["Set-Cookie"];
}
catch (Exception ex)
{
Console.WriteLine("Error in SetCookies: " + ex.Message);
}
return cookies;
}
So the question is: what should I do in order to catch the _session_id parameter in the response of the request #7?

Related

What is the order of HTTP responses, data, and error, and are they guaranteed to be in that order?

I am debugging/testing the part of my app that sends an HTTP POST, with a file to upload, to a 3rd party server and need to be sure of the order of the info that server sends back.
Below is a very trimmed down sample of how I handle what is returned by the server.
At this moment, am debugging for files sent that exceed the LimitRequestBody size set in Apache. Yes, I do check file size in my app before sending, but am trying to debug for anything possible, i.e. malicious bot sending data outside of my app.
What I can't seem to find online is the lifecycle of what a server will send back in terms of the response, data, and error, and need to be sure I will get them back in this order:
Response
Data
and if there's an error:
Error (and then nothing else)
uploadSession.dataTask(with: upFile.toUrl!)
{ (data, response, error) in
if let response = response {
upLoadInvClass.upResp(resp: response)
}
if let error = error {
upLoadInvClass.upErr(error: error)
}
if let data = data {
upLoadInvClass.upData(data: data)
}
}.resume()

How to troubleshoot issues related to requests and responses from ws loaded in SM

I am working on an integration between Microfocus Service Manager and Remedy. In order to troubleshoot issues related to requests and responses from SM to Remedy is needed to print or send that information to a log. I have tried using a debug -RTM:3 flag in my testing port configuration, but unfortunately there is a lot of information in my log since it writes every step performed by the tool. After that, I set the -debughttp flag in my port, but it only writes inputs/outputs from external resources.
Here is what I have done:
Load Remedy customer's endpoint with WSDL2JS utility.
Invoke the endpoint with a SL.
Perform a request to the endpoint.
Get an undefined response.
Check logs written by -RTM and -debughttp without success.
Is there any way to check what’s happening with my requests or with my customer’s reponses?
You can get the content of your requests and responses using the sl created by WSDL2JS only adding a piece of code within it.
For your requests, look for this part of the code (about line 129):
this.resultXML = doSOAPRequest( this.location, soapOp.SOAPAction, result.xml,
this.user, this.password,
this.connectTimeOut, this.sendTimeOut, this.recvTimeOut,
this.attachments, this.acceptfastinfoset );
Add the following code below:
//Print your request
print(result.xml)
//Send your xml request to a internal log called integration_debug.log in your app server
writeFile("../logs/integration_debug.log","a","\n");
writeFile("../logs/integration_debug.log","a","######### REQUEST INFO XML######\n");
writeFile("../logs/integration_debug.log","a",system.functions.tod()
+ "\n"
+ result.xml
+ "\n"
+ "\n");
For your customer’s responses, look for this part of the code:
if ( soapOp.responseObj == "null" ) // one-way MEP ?
{
return null;
}
var resultObj = new Object();
resultObj.responseObj = soapOp.responseObj;
Add the following code below:
//Print your customer response
print(this.resultXML.getDocumentElement())
//Send your xml response to a internal log called integration_debug.log in your app server
writeFile("../logs/integration_debug.log","a","\n");
writeFile("../logs/integration_debug.log","a","######### RESPONSE INFO XML#######\n");
writeFile("../logs/integration_debug.log","a",system.functions.tod()
+ "\n"
+ this.resultXML.getDocumentElement()
+ "\n"
+ "\n");
As a reference you can check the following picture to identify where inserting your code:
Hopefully, that can be helpful for your troubleshooting.

intermittent error from rally 'Not authorized to perform action: Invalid key' for POST request in chrome extension

I developed a chrome extension using Rally's WSAPI v2.0, and it basically does the following things:
get user and project, and store them
get current iteration everytime
send a post request to create a workitem
For the THIRD step, I sometimes get error ["Not authorized to perform action: Invalid key"] since end of last month.
[updated]Error can be reproduced everytime if I log in Rally website via SSO before using the extension to send requests via apikey.
What's the best practice to send subsequent requests via apikey in my extension since I can't control end users' habits?
I did see some similar posts but none of them is helpful... and in case it helps:
I'm adding ZSESSIONID:apikey in my request header, instead of user /
password to authenticate, so I believe no security token is needed
(https://comm.support.ca.com/kb/api-key-and-oauth-client-faq/kb000011568)
url starts with https://rally1.rallydev.com/slm/webservice/v2.0/
issue is fixed after clearing cookies for
https://rally1.rallydev.com/, but somehow it appears again some time
later
I checked the cookie when the issue was reproduced, and found one with name of ZSESSIONID and its value became something else rather than the apikey. Not sure if that matters though...
code for request:
function initXHR(method, url, apikey, cbFunc) {
let httpRequest = new XMLHttpRequest();
...
httpRequest.open(method, url);
httpRequest.setRequestHeader('Content-Type', ' application\/json');
httpRequest.setRequestHeader('Accept', ' application\/json');
httpRequest.setRequestHeader('ZSESSIONID', apikey);
httpRequest.onreadystatechange = function() {
...
};
return httpRequest;
}
...
usReq = initXHR ('POST', baseURL+'hierarchicalrequirement/create', apikey, function(){...});
Anyone has any idea / suggestion? Thanks a million!
I've seen this error when the API key had both read-only and full-access grants configured. I would start by making sure your key only has the full-access grant.

ASP.NET Web API - Reading querystring/formdata before each request

For reasons outlined here I need to review a set values from they querystring or formdata before each request (so I can perform some authentication). The keys are the same each time and should be present in each request, however they will be located in the querystring for GET requests, and in the formdata for POST and others
As this is for authentication purposes, this needs to run before the request; At the moment I am using a MessageHandler.
I can work out whether I should be reading the querystring or formdata based on the method, and when it's a GET I can read the querystring OK using Request.GetQueryNameValuePairs(); however the problem is reading the formdata when it's a POST.
I can get the formdata using Request.Content.ReadAsFormDataAsync(), however formdata can only be read once, and when I read it here it is no longer available for the request (i.e. my controller actions get null models)
What is the most appropriate way to consistently and non-intrusively read querystring and/or formdata from a request before it gets to the request logic?
Regarding your question of which place would be better, in this case i believe the AuthorizationFilters to be better than a message handler, but either way i see that the problem is related to reading the body multiple times.
After doing "Request.Content.ReadAsFormDataAsync()" in your message handler, Can you try doing the following?
Stream requestBufferedStream = Request.Content.ReadAsStreamAsync().Result;
requestBufferedStream.Position = 0; //resetting to 0 as ReadAsFormDataAsync might have read the entire stream and position would be at the end of the stream causing no bytes to be read during parameter binding and you are seeing null values.
note: The ability of a request's content to be read single time only or multiple times depends on the host's buffer policy. By default, the host's buffer policy is set as always Buffered. In this case, you will be able to reset the position back to 0. However, if you explicitly make the policy to be Streamed, then you cannot reset back to 0.
What about using ActionFilterAtrributes?
this code worked well for me
public HttpResponseMessage AddEditCheck(Check check)
{
var request= ((System.Web.HttpContextWrapper)Request.Properties.ToList<KeyValuePair<string, object>>().First().Value).Request;
var i = request.Form["txtCheckDate"];
return Request.CreateResponse(HttpStatusCode.Ok);
}

Accessing the HTTP headers from a WCF Service

I need to access the HTTP response headers that are to be returned to the client from a WCF Service. Accessing the HTTPContext is easy(through HttpContext.Current.Response), but what is the event/extension/behavior that is executed lastly, when the StatusCode is already set (for ex. if the status is 500)?
EDIT: Message Inspectors don't seem to be a good solution here, because at the time they run, the status code isn't set yet. (At least in my trial that was the case)
You can access all headers on WebOperationContext.Current.IncomingRequest, like this:
IncomingWebRequestContext request = WebOperationContext.Current.IncomingRequest;
WebHeaderCollection headers = request.Headers;
Console.WriteLine("-------------------------------------------------------");
foreach (string headerName in headers.AllKeys)
{
Console.WriteLine(headerName + ": " + headers[headerName]);
}
Console.WriteLine("-------------------------------------------------------");
See here
Simplest way for having control on the Headers is to use Message contracts.
Use Message Inspectors to monitor the message right after receiving it at the Service end.
In an extreme case, where you are not satisfied with any other standard routes, you can go for POX (Plain Old XML) type operations where you would be dealing with raw XML message.