自动化Microsoft FOPE(Forefront Online Protection for Exchange)搜索 [英] Automating Microsoft FOPE (Forefront Online Protection for Exchange) searches

查看:56
本文介绍了自动化Microsoft FOPE(Forefront Online Protection for Exchange)搜索的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

因此,我一直在研究一种自动在FOPE上进行搜索的方法.微软烦人的是,它没有提供API来访问它收集的数据,因此我必须模拟一个Web浏览器,其中包括登录,Cookie,抓取页面,然后使用该数据进一步抓取其中某些链接的所有怪癖.我应该可以获得最后的几部分,但是MS用于FOPE的设置让我感到困惑.我将发布我所知道的以及我所拥有的,因此希望其他管理员或编码员可以为您提供帮助.也许这里的信息会帮助其他管理员解决此问题,因为MS似乎实际上并不想使其变得用户友好.

So I have been working on a way to automate searches on FOPE. Microsoft annoyingly doesn't provide an API to access the data that it gathers so I have to emulate a webbrowser with all the quirks of logging in, cookies, scrapping pages and then using that data to further scrape certain links off of it. The last few parts I should be able to get, but the setup that MS uses for FOPE just perplexes me. I'll post what I know and what I have so hopefully some other admin or coder can help. Maybe the information in here will help other admins with this issue since it seems that MS doesn't actually feel like making it user friendly anyway.

https://sts.messaging.microsoft.com/login.asp

https://sts.messaging.microsoft.com/login.asp

<form name="signin" method="post" id="signin" action="">
<span class="normal">Sign in:</span>                 
<fieldset>
    <label for="email">User name:</label>
    <input type="text" id="email" name="email" maxlength="384" value="" /><br />
    <label for="Password">Password:</label>
    <input type="password" id="Password" name="Password" maxlength="256" /><br />
    <input type="submit" id="submit_signin" name="SignIn" value="Sign in" />
</fieldset>
</form>

登录后,我需要进入 https://admin.messaging.microsoft.com /Home.mvc/(经过几次自动重定向).在这里,我单击工具"按钮,将我带到搜索页面.

After logging in it takes me to https://admin.messaging.microsoft.com/Home.mvc/ (after a few automatic redirects). Here I click on the Tools button which takes me to the search page.

https://admin.messaging.microsoft.com/TraceMessage.mvc/Index/123456

https://admin.messaging.microsoft.com/TraceMessage.mvc/Index/123456

<fieldset>
    <div class="legend">
        <h3><span>Search Parameters</span></h3>
    </div>
    <ul class="fieldset">
        <li class="row large">
            <div class="field"><div class="shell">
    <label for="Sender">* Sender address:</label>
    <span class="input"><span><input type="text" id="Sender" name="Sender" value="" /></span></span>
            </div></div>
            <div class="field last"><div class="shell">
    <label for="Recipient">* Recipient address:</label>
    <span class="input"><span><input type="text" id="Recipient" name="Recipient" value="" /></span></span>
            </div></div>
        </li>
        <li class="row large">
            <div class="field"><div class="shell">
    <label for="Start">* Start date:</label>
    <span class="input"><span><input type="text" id="Start" name="Start" value="10/29/2012 1:19:20 PM"/></span></span>
            </div></div>
            <div class="field last"><div class="shell">
    <label for="End">* End date:</label>
    <span class="input"><span><input type="text" id="End" name="End" value="10/31/2012 1:19:20 PM"/></span></span>
            </div></div>
        </li>
        <li class="row large">
            <div class="field"><div class="shell">
    <label for="Adjust">Time zone:</label>
    <div class="input select">
        <select id="Adjust" name="Adjust">
            <option value="-5"  selected="selected"  >
                UTC-5</option>
        </select>
            </div></div></div>
            <div class="field last"><div class="shell">
    <label for="MessageId">Message ID:</label>
    <span class="input"><span><input type="text" id="MessageId" name="MessageId" value=""/></span></span>
            </div></div>
        </li>
    </ul>
    <br />* Fields marked with the star are required.
</fieldset>
<div>
    <span class="buttons">
        <input type="submit" id="submit" value="Search" />
    </span>
</div>

在此页面上,我需要插入发件人(user@exampleSender.com)和收件人域(exampleReceiver.com).在使用一些JS证明其正常工作之后,结果将填充到页面中.

On this page I would need to insert a sender (user@exampleSender.com) and the recipient domain (exampleReceiver.com). The results get populated in the page after using some JS to show that is working.

我已经查看了发布用户名和密码进行登录,以及通过C#登录网站 >两种解决方案似乎都不起作用.我希望那里的一些FOPE管理员可以帮助我弄清楚发生了什么以及如何使它工作.如果您需要我尝试一下或提供更多信息,请告诉我.

I've taken a look at Post Username and Password to login page programmatically as well as Login to website, via C# and neither solution seems to work at all. I'm hoping that some FOPE admin out there can help me figure out whats going on and how to make this work. If you need me to try something out or provide more information, please just let me know.

所以我在这方面取得了一些进展. XAML方面没有什么特别的(只是一个文本框,其中包含用于URL的空间,用于开始搜索的按钮以及WPF WebBrowser.

So I have made a little headway on this. The XAML side isn't anything special (just a textbox with space for a URL, a button to begin the search, and a WPF WebBrowser.

    private void executeButton_Click(object sender, RoutedEventArgs e)
    {
        DateTime timeNow = DateTime.Now;
        TimeZone zone = TimeZone.CurrentTimeZone;
        TimeSpan offset = zone.GetUtcOffset(DateTime.Now);

        this.wbControl.Navigate("https://admin.messaging.microsoft.com/TraceMessage.mvc/Trace/123456?s=" + Uri.EscapeUriString(this.inputTB.Text) + "&r=example.com&d=" + Uri.EscapeUriString(timeNow.AddDays(-29).ToString()) + "&e=" + Uri.EscapeUriString(timeNow.ToString()) + "&a=" + Uri.EscapeUriString(offset.Hours.ToString()));
   }

    private void wbControl_LoadCompleted_1(object sender, NavigationEventArgs e)
    {
        string email = "AUSERNAME";
        string password = "APASSWORD";

        dynamic doc = this.wbControl.Document;

        doc.GetElementById("email").SetAttribute("value", email);
        doc.GetElementById("Password").SetAttribute("value", password);
        doc.GetElementById("submit_signin").InvokeMember("click");
    }

由于当前正在测试功能,因此某些方面采用硬编码(用户名和密码),但最终不会采用这种方式.在这一点上,我陷入了代码的InvokeMember("click")部分.似乎有以下错误:

As this is currently for testing of the functionality certain aspects are hard-coded (usernames and passwords) that won't be that way in the end. At this point I am stuck when it comes to the InvokeMember("click") portion of the code. It seems to error out with the following:

>未知模块中发生类型'Microsoft.CSharp.RuntimeBinder.RuntimeBinderException'的异常.但未在用户代码中处理

An exception of type 'Microsoft.CSharp.RuntimeBinder.RuntimeBinderException' occurred in >Unknown Module. but was not handled in user code

其他信息:'System.MarshalByRefObject.InvokeMember(string,> System.Reflection.BindingFlags,System.Reflection.Binder,object [],> System.Reflection.ParameterModifier [],System.Globalization.CultureInfo,string [] )"由于其保护级别而无法访问

Additional information: 'System.MarshalByRefObject.InvokeMember(string, >System.Reflection.BindingFlags, System.Reflection.Binder, object[], >System.Reflection.ParameterModifier[], System.Globalization.CultureInfo, string[])' is >inaccessible due to its protection level

如果有用于此异常的处理程序,则可以安全地继续执行该程序.

If there is a handler for this exception, the program may be safely continued.

因此,我将其包装在空白的try/catch中,但从本质上讲,它仍然不提交表单.有人有建议吗?

So I've wrapped it in a blank try / catch but in essence it still doesn't submit the form. Does anyone have any suggestions?

似乎我一直坐在答案旁边,一直在提交表格.为什么应谨慎使用动态的另一个原因,因为您将无法获得任何IntelliSense帮助.我要提交的表格是:

Seems I was sitting on the answer to submit the form the whole time. Another reason of why dynamic should be used carefully as you will not get any IntelliSense help. All I did to submit the form was:

doc.GetElementById("submit_signin").Click();

现在,我只需要研究如何从搜索中获取结果(仅在JavaScript中),并确定提交表单后加载的页面何时完成加载.

Now I just need to work on how to get the results from the search (which is only in JavaScript) and determine when the page that loads after the form is submitted is finished loading.

推荐答案

好,所以经过很多战斗,我得到了一个解决方案.如果有人需要复制.cs代码或对其进行改进,我将发布.cs代码.到目前为止,它仍然运行良好:

Ok, so after much fighting I got a solution working. I'll post the .cs code if anyone needs to replicate it / improve on it. As of now it works pretty well though:

using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Collections;
using HtmlAgilityPack;
using System.Data;

namespace TestApp
{
public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
    }

    private void executeButton_Click(object sender, RoutedEventArgs e)
    {
        DateTime timeNow = DateTime.Now;
        TimeZone zone = TimeZone.CurrentTimeZone;
        TimeSpan offset = zone.GetUtcOffset(DateTime.Now);

        string email = "USERNAME";
        string password = "PASSWORD";

        List<string> URLList = new List<string>();

        foreach (string domain in Domains)
        {
            URLList.Add("https://admin.messaging.microsoft.com/TraceMessage.mvc/AsyncMessageList/123456?s=" + Uri.EscapeUriString(this.inputTB.Text) + "&r=" + domain + "&d=" + Uri.EscapeUriString(timeNow.AddDays(-29).ToString()) + "&e=" + Uri.EscapeUriString(timeNow.ToString()) + "&a=" + Uri.EscapeUriString(offset.Hours.ToString()));
        }

        var domainQueue = new Queue<string>(URLList);

        Action navigateQueue = () =>
        {
            if (domainQueue.Count != 0)
            {
                this.wbControl.Navigate(domainQueue.Dequeue());
            }
            else
            {
                MessageBox.Show("Completed");
            }
        };

        this.wbControl.LoadCompleted += (o, e0) =>
        {
            if (this.wbControl.IsLoaded == true)
            {
                dynamic doc = this.wbControl.Document;

                try
                {
                    doc.GetElementById("email").SetAttribute("value", email);
                    doc.GetElementById("Password").SetAttribute("value", password);
                    doc.GetElementById("submit_signin").Click();
                }
                catch
                {
                }

                if (e0.Uri.AbsolutePath.Contains("AsyncMessageList"))
                {
                    List<string> DetailsList = new List<string>();
                    DetailsList.AddRange(ExtractAllAHrefTags(doc));

                    foreach (string href in DetailsList)
                    {
                        domainQueue.Enqueue(href);
                    }
                    navigateQueue();
                }

                if (e0.Uri.AbsolutePath.Contains("Details"))
                {
                    resultsTB.Text += ParseEntries(doc);
                    navigateQueue();
                }

            }
        };

        navigateQueue();
    }

    private string ParseEntries(dynamic inputDoc)
    {
        HtmlAgilityPack.HtmlDocument docHAP = new HtmlAgilityPack.HtmlDocument();
        docHAP.LoadHtml(inputDoc.Body.InnerHtml.ToString());

        string csv = "";

        foreach (HtmlNode emNode in docHAP.DocumentNode.SelectNodes("//em"))
        {
            if (emNode.Attributes["class"] == null)
            {
                csv += "\"" + emNode.InnerText.ToString() + "\",";
            }
        }
        csv = csv.Remove(csv.Length - 1, 1) + "\"" + Environment.NewLine;
        return csv;
    }

    private List<string> ExtractAllAHrefTags(dynamic inputDoc)
    {
        HtmlAgilityPack.HtmlDocument docHAP = new HtmlAgilityPack.HtmlDocument();
        docHAP.LoadHtml(inputDoc.Body.InnerHtml.ToString());

        List<string> hrefTags = new List<string>();
        try
        {
            foreach (HtmlNode link in docHAP.DocumentNode.SelectNodes("//a[@href]"))
            {
                HtmlAttribute att = link.Attributes["href"];
                hrefTags.Add("https://" + this.wbControl.Source.Host.ToString() + System.Web.HttpUtility.HtmlDecode(att.Value));
            }
        }
        catch
        {
        }

        return hrefTags;
    }

    private List<string> Domains
    {
        get
        {
            List<string> currentDomains = new List<string>();
            currentDomains.Add("example.com");
            currentDomains.Add("sub.example.com");
            currentDomains.Add("it.example.com");
            return currentDomains;
        }
    }
}
}

这篇关于自动化Microsoft FOPE(Forefront Online Protection for Exchange)搜索的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆