как я могу автоматизировать вызов URL-адреса на защищенном паролем сайте asp.net-mvc

у меня есть сайт asp.net-mvc с серверной частью sqlserver, и я использую memberprovider для входа в систему и т. д.

У меня есть несколько автоматизированных вещей, которые я хочу запускать ежедневно или еженедельно, так как я могу сделать это сегодня, если я:

  1. Авторизоваться
  2. URL-адрес вызова

так скажем, URL-адрес

www.mysite.com/MyController/RunCleanupScript

Я знаю, что некоторые люди предложат разбить код RunCleanupScript на отдельный скрипт за пределами веб-сайта, но я хотел посмотреть, есть ли решение для автоматизации эквивалента ручного входа в систему и последующего ввода этого URL-адреса для вызова этого скрипта?


person leora    schedule 14.10.2011    source источник
comment
Создайте фильтр, для которого требуется isAuthenticated || isLocal, и вызовите RunCleanupScript локально.   -  person Chase Florell    schedule 14.10.2011
comment
Одна вещь, которую я делал в прошлом, — это создание атрибута «AuthoriseBasic» вместо использования атрибута авторизации ASP.NET. Затем вы можете войти в систему с помощью .NET WebRequest, используя основные учетные данные для запроса на вход. Это намного проще, чем пытаться войти в сервисы членства. Будет ли это работать для вас?   -  person John McKim    schedule 20.10.2011


Ответы (7)


Фил У Хаака есть пост о решении, которое может сработать для вас — он также предупреждает о связанных с этим опасностях. Вы можете использовать этот метод, чтобы запланировать задачу очистки. Если вы переместите свой код очистки из контроллера, тогда логин не потребуется — его никогда нельзя будет вызвать извне. Если вам по-прежнему нужно иметь возможность войти в систему и принудительно выполнить очистку, то перенос кода очистки из вашего контроллера все еще является способом. Ваше защищенное действие и код планировщика будут вызывать код очистки.

Другим вариантом может быть создание службы Windows, которая выполняет действие и сохраняет необходимые учетные данные в своем файле конфигурации.

person s1mm0t    schedule 21.10.2011

Аутентификация с помощью форм вместе с некоторыми сценариями, вызывающими веб-страницы для получения файла cookie, может быть не самым стабильным и поддерживаемым подходом для ваших требований.

Вы можете поддерживать базовую аутентификацию, которая упрощает передачу имени пользователя и пароля из скрипта. Пример реализации базовой аутентификации в asp.net mvc см. в этот пост в блоге.

person saintedlama    schedule 20.10.2011

Вы можете написать консольное приложение, которое будет выполнять 2 HTTP-запроса: первый для входа в систему и второй для получения защищенного ресурса:

using System;
using System.Collections.Specialized;
using System.Net;

public class WebClientEx: WebClient
{
    private readonly CookieContainer _cookieContainer = new CookieContainer();

    protected override WebRequest GetWebRequest(Uri address)
    {
        var request = base.GetWebRequest(address);
        ((HttpWebRequest)request).CookieContainer = _cookieContainer;
        return request;
    }
}

class Program
{
    static void Main()
    {
        using (var client = new WebClientEx())
        {
            var values = new NameValueCollection
            {
                { "username", "user" },
                { "password", "pwd" },
            };
            // Login
            client.UploadValues("http://example.com/account/logon", values);

            // Fetch the protected resource
            var result = client.DownloadString("http://example.com/home/foo");
            Console.WriteLine(result);
        }
    }
}
person Darin Dimitrov    schedule 20.10.2011
comment
Предупреждение файла cookie WebClient позволяет очень легко сделать это на сайте как есть. - person Paul Tyng; 21.10.2011

Этот код будет входить на сайт FormsAuthentication, а затем использовать файл cookie AUTH для перехода к любому другому URL-адресу на сайте...

string appURL = "https://.../LogOn";

// UserName and Password should match the names of the inputs on your form
string strPostData = String.Format("UserName={0}&Password={1}", "login", "pass");

Cookie authCookie;
CookieContainer cookieJar = new CookieContainer();

// Prepare post to the login form
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(appURL);

req.Method = "POST";
req.ContentLength = strPostData.Length;
req.ContentType = "application/x-www-form-urlencoded";
req.CookieContainer = cookieJar;
req.AutomaticDecompression = DecompressionMethods.GZip
                             | DecompressionMethods.Deflate;

// Proxy - Optional
// req.Proxy.Credentials = CredentialCache.DefaultCredentials;

// Post to the login form.
StreamWriter swRequestWriter = new StreamWriter(req.GetRequestStream());
swRequestWriter.Write(strPostData);
swRequestWriter.Close();

// Get the response.
HttpWebResponse hwrWebResponse = (HttpWebResponse)req.GetResponse();


// Store the required AUTH cookie
authCookie = cookieJar.GetCookies(new Uri("... your cookie uri ..."))[".ASPXAUTH"];

Теперь вы можете получить доступ к любому другому URL-адресу сайта, используя файл cookie AUTH.

HttpWebRequest req = (HttpWebRequest)WebRequest.Create("... url ...");

req.CookieContainer.Add(new System.Net.Cookie(authCookie.Name,
                          authCookie.Value,
                          authCookie.Path, "localhost"));

HttpWebResponse resp = (HttpWebResponse) req.GetResponse();
person im_nullable    schedule 22.10.2011

PowerShell может быть хорошим вариантом для вас. Вот пример, который демонстрирует, как вы должны отправить значения формы на страницу входа, а затем использовать файл cookie ответа, чтобы сделать второй вызов на страницу администрирования.

Обратите внимание: большую часть этого примера я позаимствовал из этого сообщения.

$LogonUrl = "http://yoursite.com/Account/LogOn"
$UserName = "AdminUser"
$Password = "pass@word1"
$AdminUrl = "http://yoursite.com/MyController/RunCleanupScript"

$cookies = New-Object System.Net.CookieContainer
$formData = "UserName=" + $UserName + "&Password=" + $Password

[net.httpWebRequest] $web1 = [net.webRequest]::create($LogonUrl)
$web1.method = "POST"
$web1.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"
$web1.Headers.Add("Accept-Language: en-US")
$web1.Headers.Add("Accept-Encoding: gzip,deflate")
$web1.Headers.Add("Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7")
$web1.AllowAutoRedirect = $false
$web1.ContentType = "application/x-www-form-urlencoded"
$buffer = [text.encoding]::ascii.getbytes($formData)
$web1.ContentLength = $buffer.length
$web1.TimeOut = 50000
$web1.KeepAlive = $true
$web1.Headers.Add("Keep-Alive: 300");
$web1.CookieContainer = $CookieContainer

$reqStrm = $web1.getRequestStream()
$reqStrm.write($buffer, 0, $buffer.length)
$reqStrm.flush()
$reqStrm.close()
[net.httpWebResponse] $response = $web1.getResponse()

$respStrm = $response.getResponseStream()
$reader = new-object IO.StreamReader($respStrm)
$result = $reader.ReadToEnd()
$response.close()

$web2 = new-object net.webclient
$web2.Headers.add("Cookie", $response.Headers["Set-Cookie"])
$result = $web2.DownloadString("$AdminUrl")

Write-Output $result

Его также можно легко превратить в консольное приложение Windows. В любом случае, их легко запланировать с помощью планировщика заданий.

Надеюсь это поможет.

person Greg Enslow    schedule 20.10.2011

Почему бы вам не дать WatiN или Selenium попробовать? Вы можете очень легко настроить шаг входа в систему, а затем проверить, правильно ли работает другая страница RunCleanupScript.

Пример главной страницы WatiN:

[Test] 
public void SearchForWatiNOnGoogle()
{
  using (var browser = new IE("http://www.google.com"))
  {
    browser.TextField(Find.ByName("q")).TypeText("WatiN");
    browser.Button(Find.ByName("btnG")).Click();

    Assert.IsTrue(browser.ContainsText("WatiN"));
  }
}

Затем вы можете иметь что-то вроде:

[Test] 
public void TestRunCleanupScript()
{
  using (var browser = new IE("www.mysite.com/MyController/RunCleanupScript"))
  {
    DoLogin(browser)
    //navigate to cleanupscript page      
    //your assert
  }
}

public void DoLogin(browser)
{
  //navigate to login
  //type username and password and hit button
}
person goenning    schedule 20.10.2011

В настоящее время я делаю это в производственной среде. В моем случае решение было несложным, так как MADAM уже был установлен, чтобы разрешить обычным RSS-ридерам безопасный доступ к RSS-каналам на сайте.

Хитрость в том, чтобы включить обычную аутентификацию для страниц, которые вы хотите вызывать автоматически, используя любые внешние процессы, что открывает вам огромное количество способов автоматического доступа к сайту; этот файл VBScript, например, вызывает URL-адрес обслуживания и проверяет, соответствует ли ответ сервера точно SUCCESS.

Option Explicit

Dim result
result = PerformMaintenance("http://www.mysite.com/MyController/RunCleanupScript")
WScript.Quit(result)

Function PerformMaintenance(URL)

  Dim objRequest

  Set objRequest = CreateObject("Microsoft.XmlHttp")

  'I use a POST request because strictly speaking a GET shouldn't change anything on the server.
  objRequest.open "POST", URL, false, "LimitedDaemonUser", "SecretDaemonPassword"
  objRequest.Send

  if (objRequest.ResponseText = "SUCCESS") Then
    PerformMaintenance = 0
  Else
    PerformMaintenance = 1
  End If

  set objRequest = Nothing

End Function

Базовая аутентификация достаточно проста, чтобы начать работать. Просто включите MADAM в свой проект и настройте его в своем файле Web.config. .

Добавление этих разделов/параметров Web.config (IIS6) должно заставить ваш пример запроса работать, если вы используете стандартный MembershipProvider. Вам просто нужно изменить MyNamespace.MembershipUserSecurityAuthority на ссылку на реальный класс. Исходный код для MembershipUserSecurityAuthority включен в MADAM в папке App_Code демонстрационного веб-приложения.

<configuration>
<configSections>
    <sectionGroup name="madam">
      <section name="userSecurityAuthority" type="System.Configuration.SingleTagSectionHandler, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
      <section name="formsAuthenticationDisposition" type="Madam.FormsAuthenticationDispositionSectionHandler, Madam" />
    </sectionGroup>
</configSections>
  <madam>
    <userSecurityAuthority realm="MyRealm" provider="MyNamespace.MembershipUserSecurityAuthority, MyNamespace" />
    <formsAuthenticationDisposition>
      <discriminators all="false">
        <discriminator inputExpression="Request.AppRelativeCurrentExecutionFilePath" pattern="~/MyController/RunCleanupScript$" type="Madam.RegexDiscriminator, Madam" />
        </discriminators>
    </formsAuthenticationDisposition>
  </madam>
  <system.web>
    <httpModules>
      <add name="FormsAuthenticationDisposition" type="Madam.FormsAuthenticationDispositionModule, Madam" />
      <add name="AuthenticationModule" type="Madam.BasicAuthenticationModule, Madam" />
    </httpModules>
  </system.web>
</configuration>
person Kevin Stricker    schedule 23.10.2011