cancel
Showing results for 
Search instead for 
Did you mean: 
cancel
1268
Views
0
Helpful
4
Replies

vb.Net/C# integration finesse 11.6 - simple login script

ahoff16
Level 1
Level 1

Hello,

I am wrapping in integration of our legacy system with Finesse. It is vb.net based and trying to get a simple login function to work. After all of the trials, I think I am close but I am getting a 401 Unauthorized error with the code below. I can log in via the web UI just fine and I am classed as a supervisor in the finesse system.

 

Please let me know what else I could try to get this simple script working. Is there a setting on the finesse server that I need to flip to allow api calls? I would assume that if I can plug in the <server>:8445 into the browser (which I can) then I should have access to the api via code.

 

Thanks for any help!!

 

 Public Function InitialSignIn(ByVal pUserID As String, ByVal pPass As String, ByVal pExtension As String) As String

        ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 Or SecurityProtocolType.Tls Or SecurityProtocolType.Tls11 Or SecurityProtocolType.Tls12

        Dim rsp As String = ""

        Dim Base_URL As String = "https://" & finserver & "/finesse/api/User/" & pUserID
        Dim request As HttpWebRequest = HttpWebRequest.Create(New Uri(Base_URL))
        request.Credentials = New NetworkCredential(System.Convert.ToBase64String(Encoding.UTF8.GetBytes(pUserID)),
                                                    System.Convert.ToBase64String(Encoding.UTF8.GetBytes(pPass)))
        request.Method = "PUT"
        request.ContentType = "application/xml"

        Dim requestxml As XElement = New XElement("User", New XElement("state", "LOGIN"), New XElement("extension", pExtension))

        Dim bytes As Byte() = Encoding.UTF8.GetBytes(requestxml.ToString())
        request.ContentLength = bytes.Length

        Using stream As IO.Stream = request.GetRequestStream
            stream.Write(bytes, 0, bytes.Length)
        End Using

        Using response As HttpWebResponse = request.GetResponse
            Using sread As New IO.StreamReader(response.GetResponseStream())
                rsp = sread.ReadToEnd
            End Using
        End Using

        Return rsp

    End Function
4 Replies 4

dekwan
Cisco Employee
Cisco Employee

Hi,

I am not an expert in .NET, so I am not sure my suggestion is accurate.

Since you are getting a HTTP status code of 401, it points me to the credentials. The Finesse REST APIs use basic auth for the authorization. In your code, I don't see anywhere that specifies that it is basic auth. I see that you are converting it to base64, but it usually needs to be Basic <auth string>.

Searching the web, I found this article: https://stickler.de/en/information/code-snippets/httpwebrequest-basic-authentication?filter_tag[0]=

 

NetworkCredential myNetworkCredential = new NetworkCredential(username, password);

CredentialCache myCredentialCache = new CredentialCache();
myCredentialCache.Add(myUri, "Basic", myNetworkCredential);

myHttpWebRequest.PreAuthenticate = true;
myHttpWebRequest.Credentials = myCredentialCache;

Maybe give this a shot?

 

Thanx,

Denise

 

ahoff16
Level 1
Level 1
I tried the credentials cache, but with the same resulting error of 401 Unauthorized.
I found out that the finesse server is attached to our Active Directory. I also tried using:
request.UseDefaultCredentials = True
so that it would pass the network credentials, but that didn't work either.

I am up for other suggestions to try

Hi,

You said that the Finesse server is attached to the Active Directory. So I am assuming that it is using SSO. If that is the case, the authentication is different. You have to use the SSO SDK. More information can be found here: https://developer.cisco.com/docs/finesse/#!single-sign-on

Thanx,
Denise

That helps. I am going down that path but have hit one, hopefully last, snag.

 

I am using the code below to attempt to get the token. However it returns a html file that has embedded javascript to "click". So when I save that html to a file, also below, and run it I get the actual token. I can't believe that this is the most efficient way to obtain a token through the api. 

 

Is there anyone that can give a little more direction? I think this is the last hurdle for getting this initial access laid out and I will share my final functions so it is easier for others using .NET or C#.

 

Initial function attempt for getting token:

 

Private sub getToken()
Dim baseurl As String = "https://" & finserver
        Dim client As New RestClient(baseurl)
        Dim request As New RestRequest("/desktop/sso/token")


        ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 Or SecurityProtocolType.Tls Or SecurityProtocolType.Tls11 Or SecurityProtocolType.Tls12

        With request
            .RequestFormat = DataFormat.Json
            .Method = Method.GET
            .AddHeader("Allow", "application/json")
            .Credentials = CredentialCache.DefaultCredentials

        End With

        Dim resp As RestResponse = client.Execute(request)
        Dim tmprsp as String = resp.Content
end Sub

Content of response:

 

 

<html><head><title>Working...</title></head><body><form method="POST" name="hiddenform" action="https://<server>:8553/ids/saml/response"><input 

type="hidden" name="SAMLResponse" 

value="giant block of gobbletygook" /><input type="hidden" name="RelayState" value="more gobblety" /><noscript><p>Script is 

disabled. Click Submit to continue.</p><input type="submit" value="Submit" /></noscript></form><script language="javascript">window.setTimeout('document.forms

[0].submit()', 0);</script></body></html>

I save all of that html into a text file, then use my browser to open the text file.

 

Result of opening saved text file:

{"token":"eyJhbGciOiJkaXIiLCJjdHkiOiJK...long token text","expires_in":3600}