500 error when making API token request to cherwell - c#

I'm getting a 500 internal server error when trying to access cherwell REST api via Code trying to return a token to make other calls. I've verified that all the information (username, password, ClientID, and client secret) are all correct. I've also verified the server is up and accepting requests. Something must be wrong with my code. Any help would be great!
string token = "";
string responseBody;
string serverName = "ql1cwbeta1";
//initialize web client
using (WebClient webClient = new WebClient())
{
// pull down parameters for body
string grantType = ConfigurationManager.AppSettings["grant_type"];
string clientId = ConfigurationManager.AppSettings["client_id"];
string username = ConfigurationManager.AppSettings["username"];
string password = ConfigurationManager.AppSettings["password"];
string authMode = ConfigurationManager.AppSettings["auth_mode"];
//add parameters in headers
webClient.Headers.Add("Accept", "application/json");
// adding parameters in body
NameValueCollection values = new NameValueCollection
{
{"grant_type", grantType},
{"client_id", clientId},
{"username", username},
{"password", password},
{"auth_mode", authMode}
};
try
{
byte[] responseBytes = webClient.
UploadValues("http://" + serverName + "/CherwellAPI/token?auth_mode=" + authMode + "&api_key=" + clientId, "POST", values);
responseBody = Encoding.UTF8.GetString(responseBytes);
}
catch (Exception exception)
{
return exception;
}

Hope below code may help you.
public static string TokenRequest()
{
try
{
// Create HTTP Web Request for the token request
HttpWebRequest tokenRequest = (HttpWebRequest)WebRequest.Create(Values.TokenURL);
byte[] data = Encoding.ASCII.GetBytes("username=" + Username + "&password=" + Password + "&client_id=" + ClientId + "&grant_type=" + GrantType);
// Set request verb POST, content type and content length (length of data)
tokenRequest.Method = "POST";
tokenRequest.ContentType = "application/x-www-form-urlencoded";
tokenRequest.ContentLength = data.Length;
// Stream request data
using (Stream stream = tokenRequest.GetRequestStream())
{
stream.Write(data, 0, data.Length);
}
// Get the response and read stream to string
using (WebResponse response = tokenRequest.GetResponse())
{
using (Stream stream = response.GetResponseStream())
{
using (StreamReader sr = new StreamReader(stream))
{
// responseText = sr.ReadToEnd();
return sr.ReadToEnd();
}
}
}
}
catch (WebException ex)
{
// Catch error for bad URL (404) or bad request (400) resulting from bad input (username, password, client id, grant type in token request)
if (ex.Message.Contains("400"))
{
// do something for bad request
}
else if (ex.Message.Contains("404"))
{
// do something for not found
}
else
{
// unknown error, do something
}
return null;
}
catch (Exception ex)
{
// General Exception
return null;
}
}

For future reference - You can include the client ID as part of the querystring if all parameters are included in the querystring, but if you are also sending a payload, then authmode should be the only thing in the querystring.
It will accept all of these parameters as querystrings.
However, you should know that for Cherwell specifically, if you are using LDAP auth / user accounts, you may need to URL encode your username values.
There are certain special characters that will break the auth command. Specifically, including a backslash for a domain can cause issues if it's not escaped with %5C , which I believe can cause a 400 error.
Also a cause of an error can be if you've chosen an authmode that's not enabled for the browser apps in the Security Settings page of the admin console ;)

Related

Send post to Facebook page

I have a c# asp.net web application.
I am using the facebook login through their javascript sdk and it does the login.
Now I have a Simple WYSIWYG Editor in which whatever is added should be posted on the facebook page of that logged in user.
Following is the code:
string FacebookApiId = "952214336368241";
string FacebookApiSecret = "fb2213d66523c8cb0bc99306f46ee457";
string accessToken = GetAccessToken(FacebookApiId, FacebookApiSecret);
PostMessage(accessToken, "My message");
private string GetAccessToken(string apiId, string apiSecret)
{
string AuthenticationUrlFormat = "https://graph.facebook.com/oauth/access_token?client_id={0}&client_secret={1}&grant_type=client_credentials&scope=manage_pages,offline_access,publish_stream";
string accessToken = string.Empty;
string url = string.Format(AuthenticationUrlFormat, apiId, apiSecret);
WebRequest request = WebRequest.Create(url);
WebResponse response = request.GetResponse();
using (Stream responseStream = response.GetResponseStream())
{
StreamReader reader = new StreamReader(responseStream, Encoding.UTF8);
String responseString = reader.ReadToEnd(); // this gives me {"access_token":"952214336368241|McqSGYIMU1eYBZ1zGydWj9hu6Bt","token_type":"bearer"}
NameValueCollection query = HttpUtility.ParseQueryString(responseString);
accessToken = query["access_token"]; // This line throws error
}
//if (accessToken.Trim().Length == 0)
//throw new Exception("There is no Access Token");
return "952214336368241|McqSGYIMU1eYBZ1zGydWj9hu6B"; // hard-coded to get it working;
}
private void PostMessage(string accessToken, string v)
{
try
{
FacebookClient facebookClient = new FacebookClient(accessToken);
dynamic messagePost = new ExpandoObject();
messagePost.access_token = accessToken;
messagePost.message = v;
var result = facebookClient.Post("/[user id]/feed", messagePost);
}
catch (FacebookOAuthException ex)
{
//handle something
}
catch (Exception ex)
{
//handle something else
}
}
This throws error:
{"(OAuthException - #803) (#803) Some of the aliases you requested do not exist: [user id]"}
I even wrote my facebook emailid instead of [user id] but it still does not work and gives me error:
Message: "(OAuthException - #2500) An active access token must be used to query information about the current user."
Can anyone please advise how can I remove this error.
The code is VERY old, offline_access and publish_stream do not exist anymore since many years.
You have to use a Page Token with the publish_pages permission in order to post to your Page with the API.
You can use "me/feed" or "page-id/feed", but not an Email.
Information about Tokens and how to generate them:
https://developers.facebook.com/docs/facebook-login/access-tokens/
https://www.devils-heaven.com/facebook-access-tokens/
Try stuff in the API Explorer before programming: https://developers.facebook.com/tools/explorer/

WNS push notification cannot be sent

I'm using the following code to send a push raw notification to my app. The code is taken from the examples given in the official documentation.
public string PostToWns(string secret, string sid, string uri, string xml, string notificationType, string contentType)
{
try
{
var accessToken = GetAccessToken(secret, sid);
byte[] contentInBytes = Encoding.UTF8.GetBytes(xml);
HttpWebRequest request = HttpWebRequest.Create(uri) as HttpWebRequest;
request.Method = "POST";
request.Headers.Add("X-WNS-Type", notificationType);
request.ContentType = contentType;
request.Headers.Add("Authorization", String.Format("Bearer {0}", accessToken.AccessToken));
using (Stream requestStream = request.GetRequestStream())
requestStream.Write(contentInBytes, 0, contentInBytes.Length);
using (HttpWebResponse webResponse = (HttpWebResponse)request.GetResponse())
// ^^^^^ This throws an exception ^^^^^
return webResponse.StatusCode.ToString();
}
catch (WebException webException)
{
HttpStatusCode status = ((HttpWebResponse)webException.Response).StatusCode;
if (status == HttpStatusCode.Unauthorized)
{
GetAccessToken(secret, sid);
return PostToWns(uri, xml, secret, sid, notificationType, contentType);
}
else if (status == HttpStatusCode.Gone || status == HttpStatusCode.NotFound)
{
return "";
}
else if (status == HttpStatusCode.NotAcceptable)
{
return "";
}
else
{
string[] debugOutput = {
status.ToString(),
webException.Response.Headers["X-WNS-Debug-Trace"],
webException.Response.Headers["X-WNS-Error-Description"],
webException.Response.Headers["X-WNS-Msg-ID"],
webException.Response.Headers["X-WNS-Status"]
};
return string.Join(" | ", debugOutput);
}
}
catch (Exception ex)
{
return "EXCEPTION: " + ex.Message;
}
}
// Authorization
[DataContract]
public class OAuthToken
{
[DataMember(Name = "access_token")]
public string AccessToken { get; set; }
[DataMember(Name = "token_type")]
public string TokenType { get; set; }
}
private OAuthToken GetOAuthTokenFromJson(string jsonString)
{
using (var ms = new MemoryStream(Encoding.Unicode.GetBytes(jsonString)))
{
var ser = new DataContractJsonSerializer(typeof(OAuthToken));
var oAuthToken = (OAuthToken)ser.ReadObject(ms);
return oAuthToken;
}
}
protected OAuthToken GetAccessToken(string secret, string sid)
{
var urlEncodedSecret = HttpUtility.UrlEncode(secret);
var urlEncodedSid = HttpUtility.UrlEncode(sid);
var body = String.Format("grant_type=client_credentials&client_id={0}&client_secret={1}&scope=notify.windows.com",
urlEncodedSid,
urlEncodedSecret);
string response;
using (var client = new WebClient())
{
client.Headers.Add("Content-Type", "application/x-www-form-urlencoded");
response = client.UploadString("https://login.live.com/accesstoken.srf", body);
}
return GetOAuthTokenFromJson(response);
}
The server always returns Unauthorized. However, I am able to obtain a token without problems and the channel URL used is obtained as in the official example.
The entire code executes at once, so I doubt the token expires every time.
I tried using online tools to check if push notifications are working and the same Unauthorized error happens there.
Do I have to register for WNS somewhere? My app is already in the Store and I have the ID and password from the Live Services website. I use these as credentials to get the token and the token is obtained every time. I described this as part of a related question: Proper WNS credentials.
Does anyone have any ideas or solutions?
I found an answer in a different question: Windows Notifications Service: 401 Invalid Token when trying to create a Toast notification in PHP.
The client_id must be the full SID (including the protocol prefix) and the client_secret the password.

Example code to send push notification from remote server to universal windows app?

I'm trying to send a push notification from a small code write in c#, here is the code:
public void Launch()
{
string channelUri = "channel uri";
string sid = "sid package";
string secret = "client secret";
// toast notification
var toast = #"<toast><visual><binding template=""ToastText01""><text id=""1"">Hello!</text></binding></visual></toast>";
Console.WriteLine(this.PostToWns(secret, sid, channelUri, toast));
Console.ReadLine();
}
// Post to WNS
public string PostToWns(string secret, string sid, string uri, string xml, string type = "wns/toast")
{
try
{
// You should cache this access token
var accessToken = GetAccessToken(secret, sid);
byte[] contentInBytes = Encoding.UTF8.GetBytes(xml);
HttpWebRequest request = HttpWebRequest.Create(uri) as HttpWebRequest;
request.Method = "POST";
request.Headers.Add("X-WNS-Type", type);
request.Headers.Add("Authorization", String.Format("Bearer {0}", accessToken.AccessToken));
using (Stream requestStream = request.GetRequestStream())
requestStream.Write(contentInBytes, 0, contentInBytes.Length);
using (HttpWebResponse webResponse = (HttpWebResponse)request.GetResponse())
return webResponse.StatusCode.ToString();
}
catch (WebException webException)
{
string exceptionDetails = webException.Response.Headers["WWW-Authenticate"] ?? string.Empty;
if (exceptionDetails.Contains("Token expired"))
{
GetAccessToken(secret, sid);
// Implement a maximum retry policy
return PostToWns(uri, xml, secret, sid, type);
}
else
{
// Log the response
return "EXCEPTION: " + webException.Message;
}
}
catch (Exception ex)
{
return "EXCEPTION: " + ex.Message;
}
}
// Authorization
[DataContract]
public class OAuthToken
{
[DataMember(Name = "access_token")]
public string AccessToken { get; set; }
[DataMember(Name = "token_type")]
public string TokenType { get; set; }
}
private OAuthToken GetOAuthTokenFromJson(string jsonString)
{
using (var ms = new MemoryStream(Encoding.Unicode.GetBytes(jsonString)))
{
var ser = new DataContractJsonSerializer(typeof(OAuthToken));
var oAuthToken = (OAuthToken)ser.ReadObject(ms);
return oAuthToken;
}
}
protected OAuthToken GetAccessToken(string secret, string sid)
{
var urlEncodedSecret = HttpUtility.UrlEncode(secret);
var urlEncodedSid = HttpUtility.UrlEncode(sid);
var body = String.Format("grant_type=client_credentials&client_id={0}&client_secret={1}&scope=notify.windows.com",
urlEncodedSid,
urlEncodedSecret);
string response;
using (var client = new WebClient())
{
client.Headers.Add("Content-Type", "application/x-www-form-urlencoded");
response = client.UploadString("https://login.live.com/accesstoken.srf", body);
}
return GetOAuthTokenFromJson(response);
}
Where channelUri, sid and secret are fixed variables that I obtained earlier. The problem is that the remote server return the 400 error (Bad Request) but i dont't know why. The channel creation is successful, i followed this guide: https://msdn.microsoft.com/en-us/library/windows/apps/xaml/hh868221.aspx and sid and secret variables refer to the app previously created in the microsoft developer dashboard.
Someone can help me?
HTTP 400 error indicates Bad Request, it means the request could not be understood by the server due to malformed syntax. In the other word, the request sent by the client doesn't follow server's rules.
There are four required headers that must be included in all push notifications: X-WNS-Type, Content-Type, Content-Length, and Authorization.
While using HttpWebResponse, it should be able to set Content-Length for you automatically, but you still need to set the Content-Type manually. And for toast, tile, and badge notifications, this header must be set to "text/xml". For more info, please see Send notification request.
HttpWebRequest request = HttpWebRequest.Create(uri) as HttpWebRequest;
request.Method = "POST";
request.Headers.Add("X-WNS-Type", type);
request.ContentType = "text/xml";
request.Headers.Add("Authorization", String.Format("Bearer {0}", accessToken.AccessToken));

JIRA error: Remote server returned error 407 proxy authentication required

I'm trying to access JIRA data (get project) using JIRA REST API. Here is how I'm making it:
public enum JiraResource
{
project
}
public class JiraService : IJiraService
{
#region JiraService member functions
/* public void DoWork()
{
}*/
private const string str_baseURL = "https://jira.atlassian.com/rest/api/latest/issue/JRA-9";
private string str_Username;
private string str_Password;
public JiraService(string username,string password)
{
str_Username = username;
str_Password = password;
}
public string runQuery(
JiraResource resource,
string argument = null,
string data = null,
string method = "GET")
{
string url = string.Format("{0}{1}/",str_baseURL,resource.ToString());
// string url = string.Format("{0}{1}/", str_baseURL);
if(argument != null)
{
url = string.Format("{0}{1}/",url,argument);
}
HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest;
request.ContentType = "application/json";
request.Method = method;
if (data != null)
{
using (StreamWriter writer = new StreamWriter(request.GetRequestStream()))
{
writer.Write(data);
}
}
string base64Credentials = GetEncodedCredentials();
request.Headers.Add("Authorization", "Basic " + base64Credentials);
HttpWebResponse response = request.GetResponse() as HttpWebResponse; //Getting error here.
string result = string.Empty;
using (StreamReader reader = new StreamReader(response.GetResponseStream()))
{ result = reader.ReadToEnd(); }
return result;
}
private string GetEncodedCredentials()
{
string mergedCredentials = string.Format("{0}:{1}", str_Username, str_Password);
byte[] byteCredentials = UTF8Encoding.UTF8.GetBytes(mergedCredentials);
return Convert.ToBase64String(byteCredentials);
}
I'm using username and password as admin and admin (I think this is default). Please note that, this url ("https://jira.atlassian.com/rest/api/latest/issue/JRA-9") showing me json objects from the browser. However, from my code, I'm getting exception "Remote server returned error (407) proxy authentication required ".
As per this post(The remote server returned an error: (407) Proxy Authentication Required) I used useDefaultCredentials="true". But this is not working.
Is there anything that I'm missing? Please guide me.

400 bad request,Azure service management api config change

my problem is that i am getting a 400 bad request when i try to get a responce to my HTTP request.
Can anyone tell me why this is happening and possibly how i can fix it?
The exact error is :
BadRequestNo change in settings specified
I put in a breakpoint in my code before i pass in the configuration file, when i viewed it, it had changed what i wanted it to change and so the configuration file that already exists is definetly diffirent to the one i am trying to change it with.
Here is the api info for the configuration change : http://msdn.microsoft.com/en-us/library/windowsazure/ee460809.aspx
And Below is my code,Any help is greatly appreciated, thank you
public void changeConfiguration(string serviceName, string deploymentSlot, string config, string deploymentName)
{
//encoding the config file
byte[] encodedConfigbyte = new byte[config.Length];
encodedConfigbyte = System.Text.Encoding.UTF8.GetBytes(config);
string temp = Convert.ToBase64String(encodedConfigbyte);
//creating the URI with the subscriptionID,serviceName and deploymentSlot
Uri changeConfigRequestUri = new Uri("https://management.core.windows.net/" + subscriptionId + "/services/hostedservices/" + serviceName + "/deploymentslots/" + deploymentSlot + "/?comp=config");
//creating a request using the URI
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(changeConfigRequestUri);
//Adding a header to the request
request.Headers.Add("x-ms-version", "2010-10-28");
request.Method = "POST";
//Create a string to hold the request body, temp being the config file
string bodyText = "<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
"<ChangeConfiguration xmlns=\"http://schemas.microsoft.com/windowsazure\"" + ">"
+ "<Configuration>" + temp + "</Configuration></ChangeConfiguration>";
//encoding the body
byte[] buf = Encoding.ASCII.GetBytes(bodyText);
request.ContentType = "application/xml";
request.ContentLength = buf.Length;
//searches the cert store for a cert that has a matching thumbprint to the thumbprint supplied
X509Store certStore = new X509Store(StoreName.My, StoreLocation.CurrentUser);
try
{
certStore.Open(OpenFlags.ReadOnly);
}
catch (Exception e)
{
if (e is CryptographicException)
{
Console.WriteLine("Error: The store is unreadable.");
}
else if (e is SecurityException)
{
Console.WriteLine("Error: You don't have the required permission.");
}
else if (e is ArgumentException)
{
Console.WriteLine("Error: Invalid values in the store.");
}
else
{
throw;
}
}
X509Certificate2Collection certCollection = certStore.Certificates.Find(X509FindType.FindByThumbprint, thumbprint, false);
certStore.Close();
if (certCollection.Count == 0)
{
throw new Exception("Error: No certificate found containing thumbprint ");
}
X509Certificate2 certificate = certCollection[0];
//cert is added to the request
request.ClientCertificates.Add(certificate);
//the requestBody is written to the request
Stream dataStream = request.GetRequestStream();
dataStream.Write(buf, 0, buf.Length);
dataStream.Close();
try
{
//retrieving responce
WebResponse response = (HttpWebResponse)request.GetResponse();
}
catch (WebException e)
{
string test = new StreamReader(e.Response.GetResponseStream()).ReadToEnd();
}
}
}
BadRequest means a parameter was incorrect. My guess is that you are using a deploymentSlot of 0 instead of staging or production like it is mentioned here:
http://msdn.microsoft.com/en-us/library/ee460786.aspx
Other then that, it would be great if you could show us the parameters you are passing in and we can maybe tell from that what is wrong.

Categories

Resources