Asp.Net проверка подлинности с помощью форм при использовании iPhone UIWebView


Я пишу a Asp.net приложение MVC 2, которое использует аутентификацию форм, и в настоящее время у меня возникла проблема с нашим приложением iPhone в отношении аутентификации/входа в систему через интернет. Мы разработали простое приложение для iPhone, которое использует элемент управления UIWebView. На этом этапе все, что приложение делает, это перейти к нашей Asp.Net сайт. Просто, правда? Проблема в том, что пользователь не может пройти на страницу входа. Шаги повторения:

  • открыть iPhone приложение.
  • приложение переходит на главную страницу.
  • пользователь не проходит проверку подлинности, поэтому они перенаправляются на экран входа / страницу
  • пользователь введет правильное имя пользователя и пароль. нажмите кнопку Отправить.
  • на стороне сервера пользователь проходит проверку подлинности, а файл cookie генерируется и отправляется клиенту с помощью FormsAuthentication.GetAuthCookie.
  • сервер отправляет перенаправление для отправки пользователя в правильный дом страница.

но затем пользователь перенаправляется назад на экран входа в систему!

Я сделал некоторые обширные отладки на этом и то, что я знаю, это:

файл cookie отправляется клиенту, и клиент сохраняет файл cookie. Проверено это в отладчике iPhone, а также с помощью Javsascript для отображения данных cookie на странице. Файл cookie отправляется обратно на сервер. Это было проверено в отладчике Visual Studio. Это правильно cookie (это тот же самый, который был установлен). Пользователь свойства.Тождественность.IsAuthenticated возвращает false по какой-то причине, даже если файл cookie auth содержится в объекте запроса. Я проверил, что приложение iPhone настроено для приема файлов cookie, и они находятся на клиенте.

вот забавная вещь: он отлично работает, если вы открываете браузер Safari на iPhone и заходите на наш сайт напрямую.

Он имеет такое же поведение, на iPad тоже в том, что он не прошел мимо экран входа. Это повторяется и на эмуляторах, и на устройствах.

этот же веб-сайт был протестирован с IE 7-8, Safari (для Windows), Blackberry, IEMobile 6.5, Phone 7, и он работает найти. Единственное обстоятельство, что он не работает, - это UIWebView в приложении iPhone.

7 61

7 ответов:

у меня была точно такая же проблема, но с другим устройством (NokiaN8), а также проследил проблему до User-Agent.

IIS использует регулярные выражения для сопоставления со строкой User-Agent. Корень проблемы заключался в том, что у него не было никаких совпадающих регулярных выражений для конкретного устройства, и он оказался на одном из самых низких уровней соответствия, где использовались свойства по умолчанию. Свойства по умолчанию сказали, что браузер не поддерживает cookies.

устранение:

  1. добавьте папку в свой веб-проект с именем App_Browsers (Правой Кнопкой Мыши проект, выберите: Add > Add ASP.NET Folder > App_Browsers).
  2. Добавить файл в эту папку (правой кнопкой мыши, выбираете: Add > New Item). Файл может иметь любое имя, но должен иметь .browser конец.
  3. добавить хорошее совпадающее выражение и правильные возможности (или добавить изменения в Default).

два примера:

<browsers>
  <browser id="NokiaN8" parentID="Mozilla">
    <identification>
      <userAgent match="NokiaN8" />
    </identification>
    <capabilities>
      <capability name="browser" value="NokiaN8" />
      <capability name="cookies" value="true" /> 
    </capabilities> 
  </browser> 
</browsers>

или измените значение по умолчанию:

<browsers>
  <browser refID="Default"> 
    <capabilities> 
      <capability name="cookies" value="true" /> 
    </capabilities>
  </browser>
</browsers>

Подробнее: Схема Файла Определения Браузера

решение, которое мы нашли, состояло в том, чтобы создать файл (generic.браузер) и включите этот xml, чтобы сообщить веб-серверу, что" Mozilla " и настройки браузера по умолчанию должны поддерживать файлы cookie.

<browser refID="Mozilla" >
    <capabilities>
        <capability name="cookies"  value="true" />
    </capabilities>
</browser>

это исправлено в ASP.NET 4.5 и все браузеры, как предполагается, поддерживают куки, так что дополнительные .файл-браузера не понадобится.

из исследования, которое я сделал, причина, по которой Вы не можете установить User-Agent, заключается в том, что UIWebView устанавливает значение User-Agent непосредственно перед отправкой запроса, то есть после того, как вы сделали запрос из своего кода.

трюк, чтобы обойти эту проблему, заключается в использовании чего-то под названием "Метод swizzling", передовой и потенциально опасной концепции Objective-C, которая заменяет стандартный метод тем, который вы предоставляете. Конечным результатом является то, что когда ваш запрос отправляется и код фреймворка добавляет пользовательский агент, который будет обманут с помощью предоставленного вами метода.

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

1) Добавить категорию на NSObject, чтобы разрешить выпивка.

@interface NSObject (Swizzle)

+ (BOOL) swizzleMethod:(SEL)origSelector withMethod:(SEL)newSelector;

@end

@implementation NSObject (Swizzle)


+ (BOOL) swizzleMethod:(SEL) origSelector withMethod:(SEL)newSelector
{
    Method origMethod= class_getInstanceMethod(self, origSelector);
    Method newMethod= class_getInstanceMethod(self, newSelector);

    if (origMethod && newMethod)
    {
        if (class_addMethod(self, origSelector, method_getImplementation(newMethod), method_getTypeEncoding(newMethod)))
        {
            class_replaceMethod(self, newSelector, method_getImplementation(origMethod), method_getTypeEncoding(origMethod));
        }
        else {
            method_exchangeImplementations(origMethod, newMethod);
        }
        return YES;
    }
    return NO;
}
@end

2) подкласс NSMutableURLRequest, чтобы разрешить swizzle:

@interface NSMutableURLRequest (MyMutableURLRequest)

+ (void) setupUserAgentOverwrite;

@end
@implementation NSMutableURLRequest (MyMutableURLRequest)

- (void) newSetValue:(NSString*)value forHTTPHeaderField:(NSString*)field
{
    if ([field isEqualToString:@"User-Agent"])
    {
        value = USER_AGENT;  // ie, the value I want to use.
    }
    [self newSetValue:value forHTTPHeaderField:field];
}
+ (void) setupUserAgentOverwrite
{
    [self swizzleMethod:@selector(setValue:forHTTPHeaderField:) 
             withMethod:@selector(newSetValue:forHTTPHeaderField:)];

}

@end

3) вызовите статический метод для замены метода. Я сделал этот звонок в didFinishLaunchingWithOptions:

// Need to call this method so that User-Agent get updated correctly:
[NSMutableURLRequest setupUserAgentOverwrite];

4) и затем использовал его вот так. (Делегат соединения сохраняет данные в изменяемом массиве а затем вручную устанавливает UIWebView с помощью метода loadData, когда он завершает загрузку).

- (void)loadWithURLString:(NSString*)urlString
{
    NSURL *url = [NSURL URLWithString:urlString];
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
_connection = [NSURLConnection connectionWithRequest:request delegate:self];
[_connection start];
}

У меня была такая же точная проблема, исследованная и консолидированная полное решение (сверху ответы и другие темы) здесь: http://www.bloggersworld.com/index.php/asp-net-forms-authentication-iphone-cookies/

  1. вы указали a DestinationPageUrl в разметке?

  2. вы указали defaultURL в сеть.конфиг?

пример web.конфигурации

<authentication mode="Forms">
     <forms loginUrl="~/Login.aspx" defaultUrl="~/CustomerArea/Default.aspx"/>
</authentication>

Пример DestinationPageUrl

 <asp:Login ID="Login" runat="server" DestinationPageUrl="~/Secret/Default.aspx" />

наконец, вы смотрели в куки банку и видели, если ваш сеанс cookie на самом деле существует?

где хранятся файлы cookie UIWebView?

причина этого, по-видимому, связана с тем, что если пользовательский агент неизвестен, то браузер, как предполагается, не принимает куки (как ответили другие), и вместо этого IIS помещает значение ASPXAUTH в URL.

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

при добавлении .браузер с настраиваемым пользователем-агентом решает проблему, это не гарантирует что другие пользовательские агенты также будут решены, и на самом деле я нашел браузер K9 для android также имеет эту проблему, и как таковой это только решение, если у вас есть система регистрации, такая как elmeh, чтобы отслеживать такие ошибки.

С другой стороны, добавление значения по умолчанию вызывает вопрос, правда ли, что все браузеры принимают куки, что, по-видимому, является причиной того, что IIS не предполагает этого.

Однако помимо добавления явно пользовательских агентов можно добавить глобальный.Asax RegiterRoutes () метод явный обработчик, чтобы игнорировать его, следующим образом:

         routes.MapRoute(
            "CookieLess", // Route name
            "(F({Cookie}))/{controller}/{action}/{id}", // URL with parameters
            new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
        );

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

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