Created
June 7, 2016 18:11
-
-
Save omniscient/b99a38f6d8f7f39a739e4ccf99c7b9b0 to your computer and use it in GitHub Desktop.
C# Citrix StoreFront WebAPI sample (Authentication, Application List, ICA File)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.IO; | |
using System.Linq; | |
using System.Text; | |
using System.Xml; | |
using Newtonsoft.Json.Linq; | |
using RestSharp; | |
namespace ConsoleApplication3 | |
{ | |
public class ApplicationInfo | |
{ | |
public string ID { get; set; } | |
public string AppTitle { get; set; } | |
public string AppLaunchURL { get; set; } | |
public string AppIcon { get; set; } | |
public string AppDesc { get; set; } | |
} | |
public class AuthCredential | |
{ | |
public string AuthToken { get; set; } | |
public string SessionID { get; set; } | |
public string CSRFToken { get; set; } | |
} | |
public class Proxy | |
{ | |
public static AuthCredential Authenticate(string storeFrontUrl, string username, string password, string domain) | |
{ | |
var isSsl = storeFrontUrl.ToLower().IndexOf("https:", StringComparison.Ordinal) != -1; | |
var csrfToken = Guid.NewGuid().ToString(); | |
var aspnetSessionId = Guid.NewGuid().ToString(); | |
var request = new RestRequest("/PostCredentialsAuth/Login", Method.POST); | |
request.AddHeader("X-Citrix-IsUsingHTTPS", isSsl ? "Yes" : "No"); | |
request.AddHeader("Content-Type", "application/x-www-form-urlencoded"); | |
request.AddHeader("Csrf-Token", csrfToken); | |
request.AddCookie("csrtoken", csrfToken); | |
request.AddCookie("asp.net_sessionid", aspnetSessionId); | |
var authenticationBody = string.Format("username={0}\\{1}&password={2}", domain, username, password); | |
request.AddParameter("application/x-www-form-urlencoded", authenticationBody, ParameterType.RequestBody); | |
var client = new RestClient(storeFrontUrl); | |
//set the cookie container | |
client.CookieContainer = new System.Net.CookieContainer(); | |
var response = client.Execute(request); | |
if (response.ResponseStatus == ResponseStatus.Error) | |
{ | |
throw new Exception(string.Format("Error: {0}", response.ErrorMessage)); | |
} | |
//parse cookie values | |
var returnedContent = response.Content; | |
var doc = new XmlDocument(); | |
doc.LoadXml(returnedContent); | |
var statusNodeList = doc.GetElementsByTagName("Result"); | |
if (statusNodeList.Count != 1) return null; | |
if (statusNodeList[0].InnerText.ToLower() != "success") return null; | |
//Restsharp is not returning the headers correctly. So let's parse them manually through the header property | |
var returnedValues = new Dictionary<string, string>(); | |
foreach (var header in response.Headers.Where(i => i.Name == "Set-Cookie")) | |
{ | |
var cookieValues = header.Value.ToString().Split(','); | |
foreach (string cookieValue in cookieValues) | |
{ | |
var cookieElements = cookieValue.Split(';'); | |
var keyValueElements = cookieElements[0].Split('='); | |
returnedValues.Add(keyValueElements[0], keyValueElements[1]); | |
} | |
} | |
var credentials = new AuthCredential | |
{ | |
AuthToken = returnedValues["CtxsAuthId"], | |
CSRFToken = returnedValues["CsrfToken"], | |
SessionID = returnedValues["ASP.NET_SessionId"] | |
}; | |
return credentials; | |
} | |
public static List<ApplicationInfo> GetResources(string storeFrontUrl, AuthCredential credentials) | |
{ | |
var isSsl = storeFrontUrl.ToLower().IndexOf("https:", StringComparison.Ordinal) != -1; | |
var request = new RestRequest(@"Resources/List", Method.POST); | |
request.AddHeader("X-Citrix-IsUsingHTTPS", isSsl ? "Yes" : "No"); | |
request.AddHeader("Accept", "application/json"); | |
request.AddHeader("Csrf-Token", credentials.CSRFToken); | |
request.AddCookie("csrftoken", credentials.CSRFToken); | |
request.AddCookie("asp.net_sessionid", credentials.SessionID); | |
request.AddCookie("CtxsAuthId", credentials.AuthToken); | |
var client = new RestClient(storeFrontUrl); | |
var resourceList = client.Execute(request); | |
var json = resourceList.Content; | |
var jsonObject = JObject.Parse(json); | |
var resources = (JArray)jsonObject["resources"]; | |
var applicationList = new List<ApplicationInfo>(); | |
foreach (var resource in resources) | |
{ | |
var appInfo = new ApplicationInfo(); | |
appInfo.AppTitle = resource["name"].ToString(); | |
try | |
{ | |
appInfo.AppDesc = resource["description"].ToString(); | |
} | |
catch (Exception) | |
{ | |
appInfo.AppDesc = ""; | |
} | |
appInfo.AppIcon = resource["iconurl"].ToString(); | |
appInfo.AppLaunchURL = resource["launchurl"].ToString(); | |
appInfo.ID = resource["id"].ToString(); | |
applicationList.Add(appInfo); | |
} | |
return applicationList; | |
} | |
public static string GetIca(string storeFrontUrl, AuthCredential credentials, ApplicationInfo appInfo) | |
{ | |
var isSsl = storeFrontUrl.ToLower().IndexOf("https:", StringComparison.Ordinal) != -1; | |
var request = new RestRequest(Method.GET); | |
request.AddHeader("X-Citrix-IsUsingHTTPS", isSsl ? "Yes" : "No"); | |
request.AddHeader("Accept", "application/octet-stream"); | |
request.AddHeader("Csrf-Token", credentials.CSRFToken); | |
request.AddCookie("csrftoken", credentials.CSRFToken); | |
request.AddCookie("asp.net_sessionid", credentials.SessionID); | |
request.AddCookie("CtxsAuthId", credentials.AuthToken); | |
var applicationUrl = string.Format("{0}/{1}", storeFrontUrl, appInfo.AppLaunchURL); | |
var client = new RestClient(applicationUrl); | |
var icaResponse = client.Execute(request); | |
var icaFile = icaResponse.Content; | |
return icaFile; | |
} | |
} | |
class Program | |
{ | |
static void Main(string[] args) | |
{ | |
var storeFrontUrl = @"http://YourStoreFrontServerURL/Citrix/StoreWeb"; | |
var username = "YourUserName"; | |
var password = "YourPassword"; | |
var domain = "YourDomain"; | |
// Logs in to Citrix store front | |
var credentials = Proxy.Authenticate(storeFrontUrl, username, password, domain); | |
// Gets the list of resources for the user | |
var _applications = Proxy.GetResources(storeFrontUrl, credentials); | |
// Pick the first application in the list | |
var app = _applications.First(); | |
// Generate the ICA File | |
var _ica = Proxy.GetIca(storeFrontUrl, credentials, app); | |
// Save the ICA file to disk | |
var path = @"D:\temp"; | |
string _icaFile = string.Format(@"{0}/{1}.ica", path, app.AppTitle); | |
if (File.Exists(_icaFile)) | |
{ | |
File.Delete(_icaFile); | |
} | |
File.WriteAllText(_icaFile, _ica, Encoding.UTF8); | |
} | |
} | |
} |
Exact flow I needed to recreate it in Java. Great work!
Thanks a lot Francois. It worked well for me.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Hi,
the application give me an error on line "doc.LoadXml(returnedContent);"
ERROR "Additional information: "noindex" is unexpected token. The token expected """ or "'". Line 8, position15."
We have 2 version of StoreFront 2.6 and 3.9, both give me this error.