Как я могу автоматизировать вызов URL на защищенном паролем сайте asp.net-mvc - PullRequest
3 голосов
/ 14 октября 2011

У меня есть сайт asp.net-mvc с бэкэндом sqlserver, и я использую membershipprovider для входа в систему и т. Д.

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

  1. Войти
  2. URL звонка

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

www.mysite.com/MyController/RunCleanupScript

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

Ответы [ 7 ]

4 голосов
/ 21 октября 2011

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

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

2 голосов
/ 20 октября 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);
        }
    }
}
2 голосов
/ 20 октября 2011

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

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

1 голос
/ 22 октября 2011

Этот код будет входить на сайт FormsAuthentication, а затем использовать куки-файл 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();
0 голосов
/ 24 октября 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>
0 голосов
/ 20 октября 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
}
0 голосов
/ 20 октября 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. В любом случае их легко планировать с помощью планировщика заданий.

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

...