15

I've written below C# code to login to JIRA Rest API:

var url = new Uri("http://localhost:8090/rest/auth/latest/session?os_username=tempusername&os_password=temppwd"); var request = WebRequest.Create(url) as HttpWebRequest; if (null == request) { return ""; } request.Method = "POST"; request.ContentType = "application/json"; request.ContentLength = 200; request.KeepAlive = false; using (var response = request.GetResponse() as HttpWebResponse) { } 

When I execute this, application just goes on running without returning any response. Please suggest if this is the right way of calling JIRA Login using REST API

2
  • Why do you have a ContentType and ContentLength specified? I don't see any actual content/body included in your code. Commented Aug 8, 2012 at 17:19
  • You say returning without any response, does your request.GetResponse() throw an exception? There should be at least some kind of response from the web server. Commented Aug 25, 2012 at 11:51

6 Answers 6

36

For basic authentication you need to send in the username and password in a base64-encoding. Guidelines can be found in the API examples on atlassians developer page: https://developer.atlassian.com/display/JIRADEV/JIRA+REST+API+Example+-+Basic+Authentication , if you are doing it in C# you need to send the encoded data in the header in the following format:

"Authorization: Basic [ENCODED CREDENTIALS]"

Here is a simple example:

public enum JiraResource { project } protected string RunQuery( JiraResource resource, string argument = null, string data = null, string method = "GET") { string url = string.Format("{0}{1}/", m_BaseUrl, resource.ToString()); 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; 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}", m_Username, m_Password); byte[] byteCredentials = UTF8Encoding.UTF8.GetBytes(mergedCredentials); return Convert.ToBase64String(byteCredentials); } 

(JiraResource is just an enum I use to decide which part of the API to use)

I hope this will help!

Sign up to request clarification or add additional context in comments.

2 Comments

This solution will not work if you are trying to connect using WCF service.
This post suggests that you should Add the Authorization Header before the write, which probably makes sense. Unfortunately, that solution did not resolve my 401 issue.
6

Here is a simpler solution which works as required:

var mergedCredentials = string.Format("{0}:{1}", username, password); var byteCredentials = Encoding.UTF8.GetBytes(mergedCredentials); var encodedCredentials = Convert.ToBase64String(byteCredentials); using (WebClient webClient = new WebClient()) { webClient.Headers.Set("Authorization", "Basic " + encodedCredentials); return webClient.DownloadString(url); } 

Comments

2

If you don't want to encode your credentials in every request here is how to do it using cookies.

When requesting the cookie you don't need to add any authorization on the headers. This method will accept a JSON string with the user name and password and the URL. It will return the cookie values.

public async Task<JiraCookie> GetCookieAsync(string myJsonUserNamePassword, string JiraCookieEndpointUrl) { using (var client = new HttpClient()) { var response = await client.PostAsync( JiraCookieEndpointUrl, new StringContent(myJsonUserNamePassword, Encoding.UTF8, "application/json")); var json = response.Content.ReadAsStringAsync().Result; var jiraCookie= JsonConvert.DeserializeObject<JiraCookie>(json); return jArr; } } public class JiraCookie { public Session session { get; set; } } public class Session { public string name { get; set; } public string value { get; set; } } 

When I call it using url: http://[baseJiraUrl]/rest/auth/1/session it returns the following JSON response:

{ "session" : -{ "name" : JSESSIONID, "value" : cookieValue } 

Keep in mind the URL above is valid in the version of JIRA I'm using and may vary depending on which version you're using. Read the JIRA API documentation for the correct URL for the version you are using. I'm using the following: https://docs.atlassian.com/software/jira/docs/api/REST/7.6.1/#auth/1/session

Remember you'll have to store your cookie and use it on every subsequent request. Check out this answer on how add cookies to your HttpClient request: How do I set a cookie on HttpClient's HttpRequestMessage.

Once you're done with the cookie (logging out) simply send a delete http request with the same URL as the post.

Comments

0

I tweaked the RunQuery code so that it will run today (Apr 2018). The encrypt/decrypt referenced below is from the following link (I converted it to an extension method and threw values into environment).

https://stackoverflow.com/questions/10168240/encrypting-decrypting-a-string-in-c-sharp

I successfully execute the code from LinqPad - thus the Dump() command after RunQuery

private string _baseUrl = "https://xxxxxx.atlassian.net"; private string _username = "YourLogin"; void Main() { RunQuery(JiraResource.project).JsonToXml().Dump(); } public enum JiraResource { project } private const string restApiVersion = "/rest/api/2/"; protected string RunQuery( JiraResource resource, string argument = null, string data = null, string method = "GET") { string url = $"{_baseUrl}{restApiVersion}{resource}"; if (argument != null) url = $"{url}{argument}/"; var 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); var response = request.GetResponse() as HttpWebResponse; string result = string.Empty; using (StreamReader reader = new StreamReader(response.GetResponseStream())) { result = reader.ReadToEnd(); } return result; } private string GetEncodedCredentials() { var encryptedPassword = Environment.GetEnvironmentVariable("PassEncrypted"); var encryptionSalt = Environment.GetEnvironmentVariable("PassSalt"); var password = encryptedPassword.Decrypt(encryptionSalt); var mergedCredentials = $"{_username}:{password}"; var byteCredentials = UTF8Encoding.UTF8.GetBytes(mergedCredentials); return Convert.ToBase64String(byteCredentials); } public static class MyExtensions { public static XElement JsonToXml(this string jsonData, bool isAddingHeader = true) { var data = isAddingHeader ? "{\"record\":" + jsonData + "}" : jsonData; data = data // Complains if xml element name starts numeric .Replace("16x16", "n16x16") .Replace("24x24", "n24x24") .Replace("32x32", "n32x32") .Replace("48x48", "n48x48"); var result = JsonConvert.DeserializeXmlNode(data, "data"); var xmlResult = XElement.Parse(result.OuterXml); return xmlResult; } } 

Comments

0

For posting multipart content in Rest I use Tiny.RestClient.

var client = new TinyRestClient(new HttpClient(), "http://localhost:8090"); var strResult = await client.PostRequest("rest/auth/latest/session). WithBasicAuthentication("username", "password") ExecuteAsStringAsync(); 

Comments

0
static void Main(string[] args) { using (WebClient wc = new WebClient()) { wc.Headers.Add("Authorization", "Basic " + GetEncodedCredentials()); string tasks = wc.DownloadString("yourjiraurl/search?jql=task=bug"); var taskdetails = JsonConvert.DeserializeObject<TaskDetails>(tasks); } } static string GetEncodedCredentials() { string mergedCredentials = string.Format("{0}:{1}", "UserName", "Password"); byte[] byteCredentials = UTF8Encoding.UTF8.GetBytes(mergedCredentials); return Convert.ToBase64String(byteCredentials); } 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.