How to Authenticate to a asp.Net webservice from Flash Media Server - asp.net

I've searched all over and can't find this addressed anywhere.
I have a Flash Media Server script that writes data to an ASP.Net webservice when a user connects. It works great, but I want to lock down security if possible.
The best I could come up with was to add a token to the flashVars of the client flv, then pass it through FMS when making the web service call, but I would prefer another method if possible. Something using SOAP authentication, etc?
Here's the relevant portion of the FMS script
load("webservices/WebServices.asc");
application.onAppStart = function()
{
application.allowDebug = true;
webServiceObj = new WebService('http://webserviceURI.asmx?WSDL');
webServiceObj.onLoad = function(Wsdl){
trace("result string -- " + Wsdl);
}
webServiceObj.onFault = function(fault){
trace("web service fault --" + fault.faultstring);
}
}
application.onConnect = function(client, name, guid, role, sessID)
{
callWebMethod = webServiceObj.MyWebSErviceFunction(parameters...)
callWebMethod.onResult = function(returning){
trace("called back from WebService");
}
}

Just found the answer to this in the Adobe documentation for the WebService class:
Note: The WebService class is not able to retrieve complex data or an array returned by a web service. Also, the WebService class does not support security features.

Related

How to correlate two AppInsights resources that communicate through NServiceBus?

Currently, I have dozens of .NET services hosted on various machines that show up as Resources on my AppInsights Application Map, which also shows their dependencies with respect to each other, based on the HTTP requests they make.
However, the relationships between services that communicate through NServiceBus (RabbitMQ) are not shown. Now, I am able to show the messages that are either sent or handled by a service via calls to TelemetryClient.TrackXXX(), but not connect Resources on the map using this information.
I have even gone so far as to attach the parent operation ID from the NSB message sender to the message itself, and assign it to the telemetry object in the receiver, but there is still no line drawn between the services in the Application Map.
To reiterate, this is what I'm getting in the Application Map:
(NSB Message Sender) --> (Message sent/handled)
And this is what I want:
(NSB Sender) --> (Receiver)
The services in question are .NET Core 3.1.
I cannot provide the code, as this is for my work, but any help would be greatly appreciated. I've searched everywhere, and even sources that seemed like they would help, didn't.
(not signed in, posting from work)
Alright, I finally got it. My approach to correlate AppInsights resources using their NSB communication is to mimic HTTP telemetry correlation.
Below is an extension method I wrote for AppInsights' TelemetryClient. I made a subclass named RbmqMessage:NServiceBus.IMessage, given my applications use RBMQ, and gave it the following properties for the sake of correlation (all set in the service that sends the message) :
parentId: equal to DependencyTelemetry.Id
opId: value is the same in the sender's DependencyTelemetry and the receiver's RequestTelemetry. Equal to telemetry.context.operation.id
startTime: DateTime.Now was good enough for my purposes
The code in the service that sends the NSB message:
public static RbmqMessage TrackRbmq(this TelemetryClient client, RbmqMessage message)
{
var msg = message;
// I ran into some issues with Reflection
var classNameIdx = message.ToString().LastIndexOf('.') + 1;
var messageClassName = message.ToString().Substring(classNameIdx);
var telemetry = new DependencyTelemetry
{
Type = "RabbitMQ",
Data = "SEND "+messageClassName,
Name = "SEND "+messageClassName,
Timestamp = DateTime.Now,
Target = "RECEIVE "+messageClassName //matches name in the service receiving this message
};
client.TrackDependency(telemetry);
msg.parentId = telemetry.Id;
msg.opId = telemetry.Context.Operation.Id; //this wont have a value until TrackDependency is called
msg.startTime = telemetry.Timestamp;
return msg;
}
The code where you send the NSB message:
var msg = new MyMessage(); //make your existing messages inherit RbmqMessage
var correlatedMessage = _telemetryClient.TrackRbmq(msg);
MessageSession.Publish(correlatedMessage); //or however the NSB message goes out in your application
The extension method in the NServiceBus message-receiving service:
public static void TrackRbmq(this TelemetryClient client, RbmqMessage message)
{
var classnameIdx = message.ToString().LastIndexOf('.')+1;
var telemetry = new RequestTelemetry
{
Timestamp = DateTime.Now,
Name = "RECEIVE "+message.ToString().Substring(classNameIdx)
};
telemetry.Context.Operation.ParentId = message.parentId;
telemetry.Context.Operation.Id = message.opId;
telemetry.Duration = message.startTime - telemetry.Timestamp;
client.TrackRequest(telemetry);
}
And finally, just track and send the message:
var msg = new MyMessage();
_telemetryClient.TrackRbmq(msg);
MessagePipeline.Send(msg); //or however its sent in your app
I hope this saves someone the trouble I went through.

Does the Facebook C# SDK depend on cookies on the server?

I'm using the Facebook C# SDK and am trying to figure out exactly how it works. I actually use an AJAX web method to lookup the Facebook account details based on the authenticated user ID, which looks something like this:
if (response.status === "connected")
{
KitchenPC.LogonFB(response.authResponse.userID, checkResult, facebookError);
}
On the server side, the LogonFB web method does something like:
Client = new FacebookClient(applicationId, applicationSecret);
var result = Client.Get(path) as IDictionary<string, object>;
UserId = Int64.Parse((String)result["id"]);
Name = result["name"] as String;
FirstName = result["first_name"] as String;
LastName = result["last_name"] as String;
Location = result.ContainsKey("location") ? result["location"] as String : "";
Gender = result.ContainsKey("gender") ? result["gender"] as String : "";
Email = result["email"] as String;
Where path is the user ID passed in from the client.
My Question:
I'm switching from ASP.NET Web Service to WCF, and WCF does not support cookies. In fact, HttpContext.Current will be null within the WCF pipeline. I was under the impression that the Facebook C# SDK depended on the fbm_ and fmsr_ cookies being passed in on the request, which would be used to validate the session with the Facebook server. However, much to my surprise, the .Get() call still works, and user information is returned. I also dug through the SDK source code and nowhere in it do I find references to HttpContext.Current.
Does the Facebook C# SDK work completely independently of cookies? Does this mean that all I need is the user's Facebook ID, and as long as they've previously approved my app ID, I can grab information about their account?
I just want to make sure I'm not doing anything wrong, and I'm not going to run into trouble in production.
When you pass the constructor with appId and appSecret, it will auto set the access token as app access token using string.Concat(appId, '|', appSecret). That constructor has been removed in newer version of the sdk. https://github.com/facebook-csharp-sdk/facebook-csharp-sdk/issues/103
Set it to null if you don't want the access token.
Client = new FacebookClient(applicationId, applicationSecret);
Client.AccessToken = null;
var result = Client.Get(path) as IDictionary<string, object>;

Microsoft Speech Recognition in webservices is not returning the result

Well i'm using Microsoft Speech Platform SDK 10.2.
I made a asp.Net WebService application and most of the WebServices works fine (HelloWorld(), etc...), but I have one service that uses the SpeechRecognitionEngine and when I deploy the application and try to run this webservice I get no result, i.e, I can see through the debug mode that it reaches the return line, but when I call it trought the browser the page keeps loading for ever, without any response.
Here's a sample of the code:
[WebMethod]
public bool voiceRecognition() {
SpeechRecognitionEngine sre = new SpeechRecognitionEngine(new System.Globalization.CultureInfo("pt-PT"));
Choices c = new Choices();
c.Add("test");
GrammarBuilder gb = new GrammarBuilder();
gb.Append(c);
Grammar g = new Grammar(gb);
sre.LoadGrammar(g);
sre.InitialSilenceTimeout = TimeSpan.FromSeconds(5);
//// just for Testing
RecognitionResult result = null;
if (result != null) {
return true;
} else {
return false;
}
}
Note: I'm using IIS to deploy the WebService Application.
If someone have some thoughts please let me know.
I don't know if you've found your answer or not. When trying to solve this myself a couple of days ago, I stumbled across your question and it matched our circumstances to a "T".
In order to fix it all we had to do was put...
sre.RecognizeAsyncStop();
sre.Dispose();
where "sre" is your SpeechRecognitionEngine variable. If you don't stop it and dispose of it at the end of your web service then the web service won't return.
Hope this helps. :)

Retrieving HTML pages from a 3rd party log in website with ASP.NET

Our Situation:
Our team needs to retrieve log information from a 3rd party website (Specifically, this log
information is call logs -- our client rents an 866 number. When calls come in, they assist
people and need to make notes accordingly in our application that will correspond with the
current call). Our client has a web account with the 3rd party that allows them to view the
current call logs (date/time, phone number, amount of time on each call, etc).
I contacted the developer of their website and inquired about API or any other means of syncing
our database with their constantly updating database. They currently DO NOT support API. I
informed them of my situation and they are perfectly fine with any way we can retrieve the
information (bot/crawler). *The 3rd party said that they are working on API but could not give
us a general timeline as to when it will be up... and as with every client, they need to start
production ASAP.
I completely understand that if the 3rd party were to change their HTML layout, it may cause a
slight headache for us (sorting the data from the webpage). That being said, this is a temporary
solution to a long term issue. Once they implement their API, we will switch them over to it.
So my question is this:
What is the best way to log into the 3rd party website (see image: http://i903.photobucket.com/albums/ac239/jreedinc/customtf.jpg)
and retrieve certain HTML pages? We have reviewed source codes of webcrawlers, but none of them
have the capability of storing cookies and posting information back to the website (with log in information). We would prefer to do this in ASP.NET.
Is there another way to accomplish logging on to the website, then retrieving said information?
The classes you'll need to use are in the System.Net namespace. Below is some quick and dirty proof of concept code. To login in to a site that uses form login + cookies for security and then scrape the HTML output of a page.
In order to parse the HTML results you'll need to use an additional tool.
Possible HTML parsing tools.
SgmlReader, can convert HTML to XML. You then use .NET's XML features to extract data from the XML.
http://code.msdn.microsoft.com/SgmlReader
HTML Agility Pack, allows XPath queries against HTML documents.
http://htmlagilitypack.codeplex.com/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
class WebWorker {
/// <summary>
/// Cookies for use by web worker
/// </summary>
private System.Collections.Generic.List `<System.Net.Cookie` > cookies = new List < System.Net.Cookie > ();
public string GetWebPageContent(string url) {
System.Net.HttpWebRequest request = (System.Net.HttpWebRequest) System.Net.WebRequest.Create(url);
System.Net.CookieContainer cookieContainer = new System.Net.CookieContainer();
request.CookieContainer = cookieContainer;
request.Method = "GET";
//add cookies to maintain session state
foreach(System.Net.Cookie c in this.cookies) {
cookieContainer.Add(c);
}
System.Net.HttpWebResponse response = request.GetResponse() as System.Net.HttpWebResponse;
System.IO.Stream responseStream = response.GetResponseStream();
System.IO.StreamReader sReader = new System.IO.StreamReader(responseStream);
System.Diagnostics.Debug.WriteLine("Content:\n" + sReader.ReadToEnd());
return sReader.ReadToEnd();
}
public string Login(string url, string userIdFormFieldName, string userIdValue, string passwordFormFieldName, string passwordValue) {
System.Net.HttpWebRequest request = (System.Net.HttpWebRequest) System.Net.WebRequest.Create(url);
System.Net.CookieContainer cookieContainer = new System.Net.CookieContainer();
request.CookieContainer = cookieContainer;
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
string postData = System.Web.HttpUtility.UrlEncode(userIdFormFieldName) + "=" + System.Web.HttpUtility.UrlEncode(userIdValue) +
"&" + System.Web.HttpUtility.UrlEncode(passwordFormFieldName) + "=" + System.Web.HttpUtility.UrlEncode(passwordValue);
request.ContentLength = postData.Length;
request.AllowAutoRedirect = false; //allowing redirect seems to loose cookies
byte[] postDataBytes = System.Text.Encoding.UTF8.GetBytes(postData);
System.IO.Stream requestStream = request.GetRequestStream();
requestStream.Write(postDataBytes, 0, postDataBytes.Length);
System.Net.HttpWebResponse response = request.GetResponse() as System.Net.HttpWebResponse;
// System.Diagnostics.Debug.Write(WriteLine(new StreamReader(response.GetResponseStream()).ReadToEnd());
System.IO.Stream responseStream = response.GetResponseStream();
System.IO.StreamReader sReader = new System.IO.StreamReader(responseStream);
System.Diagnostics.Debug.WriteLine("Content:\n" + sReader.ReadToEnd());
this.cookies.Clear();
if (response.Cookies.Count > 0) {
for (int i = 0; i < response.Cookies.Count; i++) {
this.cookies.Add(response.Cookies[i]);
}
}
return "OK";
}
} //end class
//sample to use class
WebWorker worker = new WebWorker();
worker.Login("http://localhost/test/default.aspx", "uid", "bob", "pwd", "secret");
worker.GetWebPageContent("http://localhost/test/default.aspx");
I used a tool recently called WebQL (its a web scraper tool that lets the developer use SQL like syntax to scrape information from web pages.
WebQL on Wikipedia
This is actually a relatively simple operation. What you need to do is get the page that the screenshot posts back to (something like login.php, etc) and then construct a webrequest to that page with the login data you have. You will most likely get back a cookiecontainer that will have your login cookie to use on all subsequent requests.
You can look at this MSDN article for the basics of how to do it, but their write-up is kind of confusing. Look at the community comments at the end for an example of how to post back page variables (like the username and password). You will need to make sure you pass the cookiecontainer around on subsequent requests.
Unfortunately .NET does not natively have something like WWW::Mechanize, but the Webclient does have an "upload value" which might make it easier. You will still have to manually parse the page to figure out what fields you need to pass.

Facebook Connect and ASP.NET

I'm at step 8 of the authentication overview found here: http://wiki.developers.facebook.com/index.php/How_Connect_Authentication_Works
In particular, the user has logged into facebook via Facebook Connect and their web session has been created. How do I use the facebook developer toolkit v2.0 (from clarity) to retrieve information about the user. For example, I'd like to get the user's first name and last name.
Examples in the documentation are geared towards facebook applications, which this is not.
Update
Facebook recently released the Graph API. Unless you are maintaining an application that is using Facebook Connect, you should check out the latest API: http://developers.facebook.com/docs/
I had a lot of trouble figuring out how to make server side calls once a user logged in with Facebook Connect. The key is that the Facebook Connect javascript sets cookies on the client once there's a successful login. You use the values of these cookies to perform API calls on the server.
The confusing part was looking at the PHP sample they released. Their server side API automatically takes care of reading these cookie values and setting up an API object that's ready to make requests on behalf of the logged in user.
Here's an example using the Facebook Toolkit on the server after the user has logged in with Facebook Connect.
Server code:
API api = new API();
api.ApplicationKey = Utility.ApiKey();
api.SessionKey = Utility.SessionKey();
api.Secret = Utility.SecretKey();
api.uid = Utility.GetUserID();
facebook.Schema.user user = api.users.getInfo();
string fullName = user.first_name + " " + user.last_name;
foreach (facebook.Schema.user friend in api.friends.getUserObjects())
{
// do something with the friend
}
Utility.cs
public static class Utility
{
public static string ApiKey()
{
return ConfigurationManager.AppSettings["Facebook.API_Key"];
}
public static string SecretKey()
{
return ConfigurationManager.AppSettings["Facebook.Secret_Key"];
}
public static string SessionKey()
{
return GetFacebookCookie("session_key");
}
public static int GetUserID()
{
return int.Parse(GetFacebookCookie("user"));
}
private static string GetFacebookCookie(string name)
{
if (HttpContext.Current == null)
throw new ApplicationException("HttpContext cannot be null.");
string fullName = ApiKey() + "_" + name;
if (HttpContext.Current.Request.Cookies[fullName] == null)
throw new ApplicationException("Could not find facebook cookie named " + fullName);
return HttpContext.Current.Request.Cookies[fullName].Value;
}
}
I followed up on this concept and wrote a full fledged article that solves this problem in ASP.NET. Please see the following.
How to Retrieve User Data from Facebook Connect in ASP.NET - Devtacular
Thanks to Calebt for a good start on that helper class.
Enjoy.
Facebook Connect actually isn't too difficult, there's just a lack of documentation.
Put the necessary javascript from here: http://tinyurl.com/5527og
Validate the cookies match the signature provided by facebook to prevent hacking, see: http://tinyurl.com/57ry3s for an explanation on how to get started
Create an api object (Facebook.API.FacebookAPI)
On the api object, set the application key and secret Facebook provides you when you create your app.
Set api.SessionKey and api.UserId from the cookies created for you from facebook connect.
Once that is done, you can start making calls to facebook:
Facebook.Entity.User user = api.GetUserInfo(); //will get you started with the authenticated person
This is missing from the answers listed so far:
After login is successful, Facebook recommends that you validate the cookies are in fact legit and placed on the client machine by them.
Here is two methods that can be used together to solve this. You might want to add the IsValidFacebookSignature method to calebt's Utility class. Notice I have changed his GetFacebookCookie method slightly as well.
private bool IsValidFacebookSignature()
{
//keys must remain in alphabetical order
string[] keyArray = { "expires", "session_key", "ss", "user" };
string signature = "";
foreach (string key in keyArray)
signature += string.Format("{0}={1}", key, GetFacebookCookie(key));
signature += SecretKey; //your secret key issued by FB
MD5 md5 = MD5.Create();
byte[] hash = md5.ComputeHash(Encoding.UTF8.GetBytes(signature.Trim()));
StringBuilder sb = new StringBuilder();
foreach (byte hashByte in hash)
sb.Append(hashByte.ToString("x2", CultureInfo.InvariantCulture));
return (GetFacebookCookie("") == sb.ToString());
}
private string GetFacebookCookie(string cookieName)
{
//APIKey issued by FB
string fullCookie = string.IsNullOrEmpty(cookieName) ? ApiKey : ApiKey + "_" + cookieName;
return Request.Cookies[fullCookie].Value;
}
The SecretKey and ApiKey are values provided to you by Facebook. In this case these values need to be set, preferably coming from the .config file.
I followed up from Bill's great article, and made this little component. It takes care of identifying and validating the user from the Facebook Connect cookies.
Facebook Connect Authentication for ASP.NET
I hope that helps somebody!
Cheers,
Adam
You may also use SocialAuth.NET
It provides authentication, profiles and contacts with facebook, google, MSN and Yahoo with little development effort.
My two cents: a very simple project utilizing the "login with Facebook" feature - facebooklogin.codeplex.com
Not a library, but shows how it all works.

Resources