使用 C# 以编程方式登录 Microsoft Online 网站 [英] Logging into Microsoft Online website programatically with C#

查看:42
本文介绍了使用 C# 以编程方式登录 Microsoft Online 网站的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试编写一个实用程序,该实用程序将尝试登录 Microsoft Online Admin 网站并报告是否可以访问.

I'm trying to write a utility which will attempt to login to the Microsoft Online Admin website and report back as to whether it is reachable.

使用代码主要来自本文,http://odetocode.com/articles/162.aspx 和一些屏幕抓取我拼凑了以下内容.不幸的是它不起作用,最终响应显示我仍在查看登录页面而不是目标页面.

Using code mainly from this article, http://odetocode.com/articles/162.aspx and some screen scraping I have pieced together the following. Unfortunately it doesn't work, the final response shows that I am still looking at the login page rather than the target page.

任何帮助都会很棒.提前致谢.

Any help would be terrific. Thanks in advance.

    private void LoginToSite()
    {
        const string LOGIN_URL = "https://admin.microsoftonline.com/Login.aspx";
        const string USERNAME = "<username>";
        const string PASSWORD = "<password>";
        const string TARGET_PAGE_URL = "https://admin.noam.microsoftonline.com/Home/Home.aspx";

        // first, request the login form to get the viewstate value
        HttpWebRequest webRequest = WebRequest.Create(LOGIN_URL) as HttpWebRequest;
        StreamReader responseReader = new StreamReader(
              webRequest.GetResponse().GetResponseStream()
           );
        string responseData = responseReader.ReadToEnd();
        responseReader.Close();

        // extract the viewstate value and build out POST data
        string viewState = ExtractViewState(responseData);
        string postData =
              String.Format(
                 "__VIEWSTATE={0}&AdminCenterLoginControl$UserNameTextBox={1}&AdminCenterLoginControl$PasswordTextbox={2}&__EVENTTARGET=AdminCenterLoginControl_ActionButton",
                 viewState, USERNAME, PASSWORD
              );

        // have a cookie container ready to receive the forms auth cookie
        CookieContainer cookies = new CookieContainer();

        // now post to the login form
        webRequest = WebRequest.Create(LOGIN_URL) as HttpWebRequest;
        webRequest.Method = "POST";
        webRequest.ContentType = "application/x-www-form-urlencoded";
        webRequest.CookieContainer = cookies;

        // write the form values into the request message
        StreamWriter requestWriter = new StreamWriter(webRequest.GetRequestStream());
        requestWriter.Write(postData);
        requestWriter.Close();

        // we don't need the contents of the response, just the cookie it issues
        webRequest.GetResponse().Close();

        // now we can send out cookie along with a request for the protected page
        webRequest = WebRequest.Create(TARGET_PAGE_URL) as HttpWebRequest;
        webRequest.CookieContainer = cookies;
        responseReader = new StreamReader(webRequest.GetResponse().GetResponseStream());

        // and read the response
        responseData = responseReader.ReadToEnd();
        responseReader.Close();

        MessageBox.Show(responseData);
    }

    private string ExtractViewState(string s)
    {
        string viewStateNameDelimiter = "__VIEWSTATE";
        string valueDelimiter = "value="";

        int viewStateNamePosition = s.IndexOf(viewStateNameDelimiter);
        int viewStateValuePosition = s.IndexOf(
              valueDelimiter, viewStateNamePosition
           );

        int viewStateStartPosition = viewStateValuePosition +
                                     valueDelimiter.Length;
        int viewStateEndPosition = s.IndexOf(""", viewStateStartPosition);

        return HttpUtility.UrlEncodeUnicode(
                 s.Substring(
                    viewStateStartPosition,
                    viewStateEndPosition - viewStateStartPosition
                 )
              );
    }

编辑

    private void LoginToSite()
    {
        const string LOGIN_URL = "https://admin.microsoftonline.com/login.aspx?ReturnUrl=%2fDefault.aspx";
        const string USERNAME = "<username>";
        const string PASSWORD = "<password>";

        // Request the login form to get the viewstate value
        HttpWebRequest webRequest = WebRequest.Create(LOGIN_URL) as HttpWebRequest;
        string response1 = new StreamReader(webRequest.GetResponse().GetResponseStream()).ReadToEnd();

        // Extract the viewstate value and build our POST data
        string viewState = ExtractViewState(response1);
        string postData = String.Format(
                 "__VIEWSTATE={0}&AdminCenterLoginControl$UserNameTextBox={1}&AdminCenterLoginControl$PasswordTextbox={2}&__EVENTTARGET=AdminCenterLoginControl_ActionButton",
                 viewState, USERNAME, PASSWORD);

        // Set up the Request properties
        webRequest = WebRequest.Create(LOGIN_URL) as HttpWebRequest;
        webRequest.Method = "POST";
        webRequest.ContentType = "application/x-www-form-urlencoded";
        CookieContainer cookies = new CookieContainer();
        webRequest.CookieContainer = cookies;

        // Post back to the form
        using (StreamWriter requestWriter = new StreamWriter(webRequest.GetRequestStream()))
        {
            requestWriter.Write(postData);
        }

        // Read response
        string response2 = new StreamReader(webRequest.GetResponse().GetResponseStream()).ReadToEnd();

        MessageBox.Show(response2);
    }

推荐答案

MicrosoftOnline.com 似乎不使用 Windows Live ID(又名 Passport)进行登录.这很遗憾,因为有一些可用的库可以让客户端应用程序非常简单地登录 LiveID.

It would appear that MicrosoftOnline.com does not use Windows Live IDs (aka Passport) for login. This is a shame, since there are libraries available that make logging into LiveID pretty simple for client apps.

您的代码首先访问登录页面,从响应中删除 cookie,然后尝试导航到目标页面.这不符合用户行为的正常流程.通常情况下,用户点击链接转到目标页面,如果用户未登录,网站会将请求重定向到登录页面.登录后,登录页面重定向回最初请求的目标页面.

Your code hits the login page first, scraps cookies from the response, then attempts to navigate to the target page. This doesn't match the normal flow of user behavior. Normally, the user clicks on a link to go to a target page and the web site redirects the request to the login page if the user is not logged in. After logging in, the login page redirects back to the originally requested target page.

您可以通过在浏览器中访问 admin.microsoftonline.com 时查看登录 URL 来看到这一点.您会立即重定向到登录页面,但登录页面上的完整 URL 是:https://admin.microsoftonline.com/login.aspx?ReturnUrl=%2fDefault.aspx

You can see this by looking at the login URL when you visit admin.microsoftonline.com in the browser. You are immediately redirected to the login page, but the full URL on the login page is: https://admin.microsoftonline.com/login.aspx?ReturnUrl=%2fDefault.aspx

注意最后的 ReturnUrl 查询参数.这会告诉登录页面在登录完成后重定向回哪个页面.

Note the ReturnUrl query param at the end. This tells the login page what page to redirect back to when the login is completed.

我不知道登录页面是否需要重定向,但由于这是实际最终用户交互(有效)的主要路径,而不是您的代码所采用的路径,因此需要考虑.其中,重定向到登录/重定向回目标技术将负责自动为目标域设置浏览器 cookie.

I don't know if redirect is required by the login page, but since this is the primary path for actual end user interaction (that works) and not the path your code is taking, it's something to consider. Among other things, the redirect to login/ redirect back to target technique will take care of setting the browser cookies for the target domain automatically.

附言我还注意到 Microsoft 在线服务的电子邮件管理部分使用了不同的登录 URL.从该页面 (http://www.microsoft.com/online/signin.aspx) 单击 Exchange 托管服务管理中心链接会将您带到 http:admin.messaging.microsoft.com,它会立即重定向到https://sts.messaging.microsoft.com/login.aspx?ReturnUrl=%2fDefault.aspx%3fwa%3dwsignin1.0%26wtrealm%3dhttps%253a%252f%252fadmin.messaging.microsoft.com%26wctx%3drm%253d0%2526id%253dpassive%2526ru%252601wctx%25250320000000%252000000000000-27T17%253a11%253a50Z&wa=wsignin1.0&wtrealm=https%3a%2f%2fadmin.messaging.microsoft.com&wctx=rm%3d0%26id%3dpassive%26ru%3d%252f&wct=2010-10-27T17%3a11%3a50Z

p.s. I notice also that the email administration portion of Microsoft Online services uses a different login URL. From this page (http://www.microsoft.com/online/signin.aspx) clicking on the Exchange Hosted Services Administrative Center link takes you to http:admin.messaging.microsoft.com, which immediately redirects to a login url of https://sts.messaging.microsoft.com/login.aspx?ReturnUrl=%2fDefault.aspx%3fwa%3dwsignin1.0%26wtrealm%3dhttps%253a%252f%252fadmin.messaging.microsoft.com%26wctx%3drm%253d0%2526id%253dpassive%2526ru%253d%25252f%26wct%3d2010-10-27T17%253a11%253a50Z&wa=wsignin1.0&wtrealm=https%3a%2f%2fadmin.messaging.microsoft.com&wctx=rm%3d0%26id%3dpassive%26ru%3d%252f&wct=2010-10-27T17%3a11%3a50Z

域名 sts.messaging.microsoft.com 表明 Microsoft Online Services 的 Exchange 托管服务部分正在使用安全令牌服务,这表明该登录系统能够进行联合单点登录在不同的服务之间.您可以使用类似 Windows Identity Foundation (WIF) 客户端组件.这是否适用于 Microsoft 在线服务的其余部分?我不知道.

The domain name sts.messaging.microsoft.com suggests that the Exchange Hosted Services portion of Microsoft Online Services is using a Security Token Service, which suggests that this login system is capable of federated single sign on between different services. You might be able to connect to this using something like the Windows Identity Foundation (WIF) client components. Will that work with the rest of Microsoft Online Services? I don't know.

这篇关于使用 C# 以编程方式登录 Microsoft Online 网站的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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