Using OAuth with Rira REST Calls in .NET / F #

I am trying to create a .NET application in F # that calls the Jira REST API to read / create problems.

I generated .puband .pemusing OpenSSL and applications created in Jira link with the public key.

Here is the signing function I put together (based on some C # code that I found in the blog post) that gets me the initial token response:

let rsasha1 (signingKey : string) str =
    let rsa = new RSACryptoServiceProvider()
    rsa.FromXmlString(signingKey)
    let shaHashObject = new SHA1Managed()
    let data = Encoding.ASCII.GetBytes(str : string)
    let hash = shaHashObject.ComputeHash(data)
    let signedValue = rsa.SignHash(hash, CryptoConfig.MapNameToOID("SHA1"))
    Convert.ToBase64String(signedValue, Base64FormattingOptions.None)

And this is the function I use to make the call (also found from the snippet online)

/// Request a token and return:
///  oauth_token, oauth_token_secret, oauth_callback_confirmed
let requestToken() = 

    let queryParameters = 
        ["oauth_callback", "oob"
         "oauth_consumer_key", consumerKey
         "oauth_nonce", System.Guid.NewGuid().ToString().Substring(24)
         "oauth_signature_method", "RSA-SHA1"
         "oauth_timestamp", currentUnixTime().ToString()
         "oauth_version", "1.0"]

    let signingString = baseString "POST" requestTokenURI queryParameters

    let rsaSignature = rsasha1 consumerSecretXML signingString

    let realQueryParameters = ("oauth_signature", rsaSignature)::queryParameters

    let req = WebRequest.Create(requestTokenURI, Method="POST")
    let headerValue = createAuthorizeHeader realQueryParameters
    req.Headers.Add(HttpRequestHeader.Authorization, headerValue)

    let resp = req.GetResponse()
    let stream = resp.GetResponseStream()
    let txt = (new StreamReader(stream)).ReadToEnd()

    let parts = txt.Split('&')
    (parts.[0].Split('=').[1],
     parts.[1].Split('=').[1],
     parts.[2].Split('=').[1] = "true")

This successfully returns token information, but I'm not sure what to do next when I have a token. The original C # code on which I based this used HMACSHA1 instead of RSASHA1 and simply associated the user's secret with the secret of the token, and then again called the signature function.

. .pem XML, RSACryptoServiceProvider. , .

, REST Jira?

+4
2

OAuth , , @Helge, , .

#r "System.Net.Http"

open System
open System.Collections.Generic
open System.Net
open System.Net.Http
open System.Net.Http.Headers

let toKVPairSeq l =
    Seq.map (fun (k, v) -> KeyValuePair(k, v)) l

let handler = new HttpClientHandler()
let client = new HttpClient(handler)
client.BaseAddress <- Uri "http://jira/"
let authRequestContent = new FormUrlEncodedContent([
                                                        "os_username", "jira-user"
                                                        "os_password", "jira-password"
                                                        "os_cookie", "true"
                                                        "os_destination", ""
                                                        "user_role", ""
                                                        "atl_token", ""
                                                        "login", "Log+In"
                                                    ] |> toKVPairSeq)
let request = new HttpRequestMessage()
let result1 = client.PostAsync("login.jsp", authRequestContent).Result
result1.EnsureSuccessStatusCode()
printf "%A %s" result1.StatusCode <| result1.Content.ReadAsStringAsync().Result
let result2 = (client.GetAsync "rest/api/latest/issue/ISSUE-1").Result
printf "%A %s" result2.StatusCode <| result2.Content.ReadAsStringAsync().Result
+1

, , , , - , . , "" ( JSON), Session JSESSIONID (cookie), .

( , JSESSIONID, ), ( ).

, FSharp.Data <package id="FSharp.Data" version="2.3.1" targetFramework="net46" /> , , "" ( ) .

, JSON , , JSON- - , JSON, .

, .

, , , F #; -)

#r "System.Servicemodel"
#r "System.Xml"
#r @"..\packages\FSharp.Data.2.3.1\lib\net40\fsharp.data.dll"

open FSharp.Data
[<Literal>]
let baseUrl = "https://jira"

[<Literal>]
let jiraUrlQuery = baseUrl + "/rest/api/2/search?jql=text%20~%20%22some text%22%20ORDER%20BY%20created%20DESC"

[<Literal>]
let loginUrl = "/rest/auth/1/session"

//[<Literal>]
let creds = sprintf "{\"username\": \"%s\", \"password\": \"%s\" }"

[<Literal>]
let loginInfoExample = "{\"session\":{\"name\":\"JSESSIONID\",\"value\":\"Γ₯æø8F95074F7398C68961708066EC6342A8\"},\"loginInfo\":{\"failedLoginCount\":7,\"loginCount\":434,\"lastFailedLoginTime\":\"2016-08-02T13:15:27.392+0200\",\"previousLoginTime\":\"2016-08-05T08:46:45.168+0200\"}}"

type LoginInfo = JsonProvider< loginInfoExample >

let login = Http.Request(baseUrl+loginUrl, httpMethod="POST", body=HttpRequestBody.TextRequest( creds "SomeUserName" "SomePassword" ), headers= [ "Content-Type", "application/json" ])
//let login = JsonValue.Request(baseUrl+loginUrl, httpMethod="POST",  headers= [ "Content-Type", "application/json" ])

let getText =
    function
    | Text s -> s
    | _ -> "" 

let loggedIn = LoginInfo.Parse(getText login.Body).Session.Value.ToString()

type JiraIssues = JsonProvider< ".\JIRA\query.json" > //jiraUrlQuery>

let listOfCases = JiraIssues.Parse(Http.Request(jiraUrlQuery, cookies=["JSESSIONID", loggedIn] ).Body |> getText)

listOfCases.Issues |> Seq.map (fun x -> x.Fields.Summary, x.Fields.Created) |> Seq.sortByDescending (fun (s,c) -> c) |> Seq.iter (fun (s,c) -> printfn "%A: %s" c s)  
+2

Source: https://habr.com/ru/post/1658029/


All Articles