java對接SCOM微軟監控系統告警

来源:https://www.cnblogs.com/a1exlee/archive/2023/03/06/17184404.html
-Advertisement-
Play Games

背景 項目上需要對接scom微軟監控系統告警,能夠拿到手的資料十分有限,只有幾個官方文檔地址: Operations Manager REST API Reference - Operations Manager REST API | Microsoft Learn SCOM: Quick Star ...


背景

項目上需要對接scom微軟監控系統告警,能夠拿到手的資料十分有限,只有幾個官方文檔地址:

Operations Manager REST API Reference - Operations Manager REST API | Microsoft Learn

SCOM: Quick Start - REST API - TechNet Articles - United States (English) - TechNet Wiki (microsoft.com)

SCOM告警儀錶盤頁面展示:

註意事項

僅支持 System Center Operations Manager 1801 及以上版本有RESTAPI,千萬註意;

對接過程

官網正好有一個獲取告警的示例,但是是powershell版本的:

#Set Headers for the request
$userName ="domain\username";
$password ="Password";
$AuthenticationMode= "Network"
$scomHeaders = New-Object “System.Collections.Generic.Dictionary[[String],[String]]”
$scomHeaders.Add('Content-Type','application/json; charset=utf-8')
$bodyraw = "($AuthenticationMode):$($userName):$($password)” //官網這裡寫的還有問題,少了個$
$Bytes = [System.Text.Encoding]::UTF8.GetBytes($bodyraw)
$EncodedText =[Convert]::ToBase64String($Bytes)
$jsonbody = $EncodedText | ConvertTo-Json

$uriBase = 'http://<scomserver>/OperationsManager'

#Authenticate
$auth = Invoke-WebRequest -Method POST -Uri $uriBase/authenticate -Headers $scomheaders -body $jsonbody -UseDefaultCredentials -SessionVariable $websession 
#Include CSRF Token
$csrfTocken = $websession.Cookies.GetCookies($uriBase) | ? { $_.Name -eq 'SCOM-CSRF-TOKEN' }
$scomHeaders.Add('SCOM-CSRF-TOKEN', [System.Web.HttpUtility]::UrlDecode($csrfTocken.Value))

#Examples to Invoke the required SCOM API

#Data/alertDescription/{alertid}
$alertid="6A88FBC1-0EDC-4173-9BB1-30FFEC296672"
$uri = "$uriBase/data/alertDetails"
$Response = Invoke-WebRequest -Uri "$uriBase/data/alertDetails/$alertid" -Headers $scomheaders -Method Get -WebSession $websession
$Response.Content | Convertto-json



#Criteria: Enter the displayname of the SCOM object
$Criteria = "DisplayName LIKE '%SQL%'"
#Convert our criteria to JSON format
$JSONBody = $Criteria | ConvertTo-Json
$Response = Invoke-WebRequest -Uri "$uriBase/data/class/monitors" -Method Post -Body $JSONBody -WebSession $WebSession
$Response.Content | Convertto-json


#Data Request in JSON Format
$dashboardbody='
{
  "refreshing": false,
  "Name": "TestAPIDashboard",
  "path": "35b6eba3-6202-8738-a47f-16acf476230f"
}'
$response = Invoke-WebRequest -Uri "$uriBase/monitoring/dashboard" -Headers $scomheaders -Method POST -Body $dashboardbody -ContentType "application/json" -UseDefaultCredentials -WebSession $websession

流程就是:

  • 第一步: 拿到username(用戶名) password(賬密碼) AuthenticationMode(認證模式,示例中是Network) domain(域) 四個配置信息

  • 第二步: 將信息按照 AuthenticationMode:domain\username:password 拼接在一起然後通過base64加密:

    "TmV0d29yazphYmNcYWRtaW51c2VyOlBXRDEyMw=="

  • 第三步:調用認證介面 POST: http://<Servername>/OperationsManager/authenticate ,將上一步的字元串放到請求體,Content-Type設置為application/json

  • 第四步:將響應頭的Set-Cookie裡面的SCOM-CSRF-TOKEN 設置到請求頭中,發起查詢告警列表請求

    POST http://<Servername>/OperationsManager/data/alert

示例很美好,但是一試問題就來了,

  • 問題一: 認證介面訪問時一直401

剛開始以為是用戶名密碼或者許可權問題,聯繫確認了web頁面直接訪問 http://IP/OperationsManager/ 該賬號可以正常登錄查詢,有操作員許可權,百思不得其解,意外打開F12發現頁面上也是用的這個介面,於是決定抓包

打開fidder/wireshark,抓包認證介面發現居然發起了三次請求

查看response header

反應過來原來還有一層NTLM認證,於是調整java代碼,使用httpclient發起NTLM請求,核心代碼如下:

  public static final String AUTH_URL = "/authenticate";
// 獲取NTLM認證client
public CloseableHttpClient getBasicAuthHttpClient(String username, String password, String workStation, String domain) {
        CredentialsProvider provider = new BasicCredentialsProvider();
        NTCredentials ntCredentials = new NTCredentials(username, password, workStation, domain);
        provider.setCredentials(AuthScope.ANY, ntCredentials);
        return HttpClients.custom().setDefaultCredentialsProvider(provider).useSystemProperties().build();
}
// 認證介面,獲取token
public String askForToken() {
    String result = "";
    HttpPost httppost = new HttpPost(baseUrl + AUTH_URL);
    CloseableHttpClient basicAuthHttpClient;
    try {
        httppost.addHeader("Content-Type", "application/json;charset=UTF-8");
        BASE64Encoder base64Encoder = new BASE64Encoder();
        String encodedText = base64Encoder.encode((authMode + ":" + domain + "\\" + username + ":" + password).getBytes(StandardCharsets.UTF_8));
        httppost.setEntity(new StringEntity("\""+encodedText+"\"", DEFAULT_CHARSET));
        basicAuthHttpClient = getBasicAuthHttpClient(username, password, authMode, domain);
        HttpResponse response = basicAuthHttpClient.execute(httppost);
        Header[] headers = response.getHeaders("Set-Cookie");
        for (Header r : headers) {
            String value = r.getValue();
            if (value.startsWith("SCOM-CSRF-TOKEN")) {
                return  value.split(";")[0].split("=")[1] ;
            }
        }
        if (log.isDebugEnabled()) {
            log.debug("Request url:{},Request Parameter:{},Response:{}", baseUrl + AUTH_URL, encodedText, result);
        }
    } catch (Exception e) {
        throw new SystemException(e);
    }
    return result;
}

非常順利,成功拿到token,然後遭遇了新的問題

  • 問題二 :查詢告警介面依然401

    查詢告警http://ip/OperationsManager/data/alert,直接拿上一步獲取的token加入請求Header中,

    SCOM-CSRF-TOKEN: yjihbfEsRFLd9fMRgT_Rxf4MzDiact3jgvyXZBrMnQRA4MoKtaO8_si891ahn6Pm98SJltLoiQYQrEENBWhJXX5WkQbLa2hqI6gVG96Hj0Y1%3a5dV5XX9rOLp5850DHjRsJ93ioKTP_Fw2AakOi1QN35SI_Vr0nBYrw4n8bUzh_vbNLxKIek_7w9lHSlftqOA0TfKs6Rs0oU7O3w8GIegHvpPtYt_0fTgktvzq4nL7MTxF0
    

    過濾條件官網給的非常模糊沒有解釋,這裡直接跟scom控制台保持一致,請求體:

    {"classId":null,"objectIds":{},"criteria":"((Severity = '0') OR (Severity = '1') OR (Severity = '2')) AND ((Priority = '2') OR (Priority = '1') OR (Priority = '0')) AND ((ResolutionState != '255')) AND TimeRaised >= 'Sun, 30 Jan 2022 07:34:42 GMT'","displayColumns":["severity","monitoringobjectdisplayname","name","lastmodified","description","sitename","alertsource","netbiosdomainname"]}
    

    依然抓包頁面請求,發現依然發起三個


所以NTLM每個請求都要用上一步的getBasicAuthHttpClient()返回的client來發起請求

  • 問題三: 報錯 索引超出了數組界限

排查發現是header中的SCOM-CSRF-TOKEN需要先URLDecoder一下,不然會解析報錯。

SCOM-CSRF-TOKEN: yjihbfEsRFLd9fMRgT_Rxf4MzDiact3jgvyXZBrMnQRA4MoKtaO8_si891ahn6Pm98SJltLoiQYQrEENBWhJXX5WkQbLa2hqI6gVG96Hj0Y1:5dV5XX9rOLp5850DHjRsJ93ioKTP_Fw2AakOi1QN35SI_Vr0nBYrw4n8bUzh_vbNLxKIek_7w9lHSlftqOA0TfKs6Rs0oU7O3w8GIegHvpPtYt_0fTgktvzq4nL7MTxF0

  • 問題四:提示會話已過期

到這裡我們已經接近成功了,原因是因為光設置token到Header還不夠,還要請求的時候還需要攜帶Cookie,把第一步認證介面返回的Set-Cookie裡面的值設置到Cookie中,

httppost.addHeader("Content-Type", "application/json;charset=UTF-8");
httppost.addHeader("SCOM-CSRF-TOKEN", token);//這個token需要decode
httppost.addHeader("Cookie", "SCOM-CSRF-TOKEN="+originToken+";SCOMSessionId="+sessionId+";SCOMUserStatus=loggedIn"); //這個token不需要decode

響應格式:

{
  "tableColumns": [
    {
      "field": "ageinmilliseconds",
      "header": "",
      "type": null,
      "hidden": true
    },
    {
      "field": "severity",
      "header": "Severity",
      "type": null,
      "hidden": false
    },
    {
      "field": "monitoringobjectdisplayname",
      "header": "Source",
      "type": null,
      "hidden": false
    },
    {
      "field": "monitoringobjectpath",
      "header": "Path",
      "type": null,
      "hidden": false
    },
    {
      "field": "name",
      "header": "Name",
      "type": null,
      "hidden": false
    },
    {
      "field": "age",
      "header": "Age",
      "type": null,
      "hidden": false
    },
    {
      "field": "description",
      "header": "Description",
      "type": null,
      "hidden": false
    },
    {
      "field": "owner",
      "header": "Owner",
      "type": null,
      "hidden": false
    },
    {
      "field": "timeadded",
      "header": "Created",
      "type": null,
      "hidden": false
    },
    {
      "field": "id",
      "header": "Id",
      "type": null,
      "hidden": true
    }
  ],
  "rows": [
    {
      "id": "d3144ac9-4316-45ce-94b9-f50936219e24",
      "severity": "Error",
      "monitoringobjectdisplayname": "Test Service Group",
      "monitoringobjectpath": null,
      "name": null,
      "age": "6137 days, 6 hours",
      "ageinmilliseconds": 530260033217.2775,
      "description": "",
      "owner": "DXPSQYVCYBXGIUDZJZVWNLFDYEKA",
      "timeadded": "2022-05-17T03:29:36.7330000Z"
    },
    {
      "id": "d3144ac9-4316-45ce-94b9-f50936219e24",
      "severity": "Error",
      "monitoringobjectdisplayname": "Test Service Group",
      "monitoringobjectpath": null,
      "name": null,
      "age": "6137 days, 6 hours",
      "ageinmilliseconds": 530260149093.94025,
      "description": "",
      "owner": "DXPSQYVCYBXGIUDZJZVWNLFDYEKA",
      "timeadded": "2022-05-17T03:29:36.7330000Z"
    }
  ]
}

解析告警,做屬性轉換:

alarmId->告警唯一ID
netbioscomputername->電腦名(可能為空)
monitoringobjectdisplayname->源
description->告警描述
lastmodified->上次更新時間
principalname->站點
severity->告警級別

步驟總結

1.獲取認證信息,確認認證方式是否開啟NTLM

2.發起認證NTLM請求,從response header獲取SCOM-CSRF-TOKEN,以及SCOMSessionId

3.發起查詢告警請求,將上一步的token urldecode後設置到request header,將原始token和sessionId設置到Cookie


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 事情是這樣的,昨天去表弟家,用了下他的電腦,不小心點到了他硬碟里隱藏的秘密,本來我只需要用幾分鐘電腦的,害得我硬是在電腦旁坐了幾個小時~ 還好他爸媽不在家,不然表弟又要被毒打一頓! 為了防止表弟的秘密被髮現,從而被賞賜一頓男女混合雙打,於是我用Python把他所有的視頻都給打上了萬惡的馬賽克。 我想 ...
  • 前面我們介紹了組成程式的各種基本元素,看到瞭如何把基本過程和基本數據組合起來,構造出複合的實體。不過對於設計程式而言,這些手段還不夠,我們還需要一些能夠幫助我們構造起模塊化(modular)的大型系統的策略。所謂模塊化,也即使這些系統能夠“自然地”劃分為一些內聚(coherent)的部分,使這些部分... ...
  • Qt 學習筆記全系列傳送門: Qt 學習筆記 - 第一章 - 快速開始、信號與槽 【本章】Qt 學習筆記 - 第二章 - 添加圖片、佈局、界面切換 1、給 Qt 工程添加圖片 註意:不要隨意更改所需圖片的尾碼,否則可能導致無法正常使用,出現*Image format not supported*文件 ...
  • 字元串(str) 字元串的下標(索引) str_data = "python" p y t h o n 0 1 2 3 4 5 -6 -5 -4 -3 -2 -1 索引就是某數據在序列的位置 正索引:從左至右,從0開始 負索引:從右至左,從-1開始 其中:str_data[0] = str_data ...
  • 函數編程:強大的 Stream API 每博一文案 只要有人的地方,世界就不會是冰冷的,我們可以平凡,但絕對不可以平庸。 —————— 《平凡的世界》 人活著,就得隨時準備經受磨難。他已經看過一些書,知道不論是普通人還是了不起的人, 都要在自己的一生中經歷許多磨難。磨難使人堅強。 —————— 《平 ...
  • 眾所周知,request.getInputStream()只能調一次。如果希望在請求進入Controller之前統一列印請求參數(攔截器或過濾器),又不影響業務,我們只能將獲取到的輸入流緩存起來,後續都從緩存中獲取即可。 首先,自定義一個ServletInputStream package com. ...
  • 不建議使用JDBC直接將您的Cordova應用程式連接到MySQL資料庫,因為它會帶來安全風險.移動設備通常受到安全漏洞的約束,並且從移動應用程式連接到資料庫會增加暴露敏感信息的風險. 一種更好的方法是使用Back-最終服務(例如REST API)與資料庫進行交互.您的Cordova應用程式將與RE ...
  • 函數式編程:Lambda 表達式 每博一文案 曾經讀過的依然令我感動的句子,生活總是不如意,但往往是在無數痛苦中,但往往是在無數痛苦中,在重重矛盾 和艱難中才能成熟起來,堅強起來,愛情啊,它使荒蕪變成繁榮,平庸變得偉大,使死去的複活,活著的閃閃發光, 即使愛情是不盡的煎熬折磨,像冰霜般嚴厲,烈火般烤 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...