Programmatic authentication at icingaweb2

I want to request the eventhistory from icingaweb as json, to create some reporting.
As I understand, I can get this information only on icingaweb2, not from the api.

But I fail to authenticate successfull with a programm and I am not able to figure out, what’s wrong.

At first I do a GET-Request to obtain the Cookie “Icingaweb2” and the CSFR-Token out of the html-content.

Then I set up a POST-Request for authentication. But somehow I don’t manage to succeed.
I captured a successfull login with Fiddler 4 and tried to rebuild that as close as possible to what I can see there.
Something is missing, that I am not able to recognize.

Maybe someone, who knows this process, can help here.

I set up a github-repo for my complete code.

Regex patCSFRToken = new Regex("<input type=\"hidden\" name=\"CSRFToken\" value=\"(.*)\" id=\"CSRFToken\">");
string url = "https://icinga.tld/icingaweb2/authentication/login";
string content = string.Format(
    "username={0}&password={1}&redirect=&formUID=form_login&CSRFToken={2}&btn_submit=Anmelden",
    user, pass, csfr
);
HttpWebRequest request = HttpWebRequest.CreateHttp(url);
request.Method = "POST";
request.AllowAutoRedirect = false;
string sessionCookie = response.Headers.Get("Set-Cookie");
cContainer = new CookieContainer();
mat = patSessionCookie.Match(sessionCookie);
if(mat.Success) {
    cContainer.Add(new Cookie("_chc", "1", "/icingaweb2/", "icinga.tld"));
    cContainer.Add(new Cookie("Icingaweb2", mat.Groups[1].Value, "/icingaweb2/", "icinga.tld"));
    cContainer.Add(new Cookie("icingaweb2-tzo", "3600-0", "/icingaweb2/", "icinga.tld"));
    request.CookieContainer = cContainer;
    request.Accept = "*/*";
    request.ContentType = "application/x-www-form-urlencoded; charset=UTF-8";
    request.UserAgent = "Mozilla/5.0 (Windows NT 6.3; Win64; x64; rv:94.0) Gecko/20100101 Firefox/94.0";
    request.Headers.Add("Sec-Fetch-Dest", "empty");
    request.Headers.Add("Sec-Fetch-Mode", "cors");
    request.Headers.Add("Sec-Fetch-Site", "same-origin");
    request.Headers.Add("X-Icinga-Accept", "text/html");
    request.Headers.Add("X-Icinga-WindowId", "jtbiyolsakvh_nsbjgt");
    request.Headers.Add("X-Requested-With", "XMLHttpRequest");
    request.Headers.Add("Origin", "https://icinga.tld");
    request.Referer = "https://icinga.tld/icingaweb2/authentication/login";
    byte[] contentArray = Encoding.UTF8.GetBytes(content);
    request.ContentLength = contentArray.Length;
    Stream dataStream = request.GetRequestStream();
    dataStream.Write(contentArray, 0, contentArray.Length);
    dataStream.Close();
    HttpWebResponse responseAuth = (HttpWebResponse)request.GetResponse();
} else {
    Console.WriteLine("Unable to extract Session-Cookie.");
}

Enable external authentication and use a basic authentication in your script should be a better solution. If you are always coming from the same address, you can also automatically authenticate via a rewrite condition on the web server.

An example for this I have written can be found at GitHub - theforeman/smart_proxy_monitoring: Smart proxy plugin for monitoring system integration

1 Like