IT박스

iPhone UIWebView를 사용할 때 Asp.Net 양식 인증

itboxs 2020. 12. 1. 07:50
반응형

iPhone UIWebView를 사용할 때 Asp.Net 양식 인증


Forms Authentication을 사용하는 Asp.net MVC 2 애플리케이션을 작성 중이며 현재 웹을 통한 인증 / 로그인과 관련하여 iPhone 애플리케이션에 문제가 있습니다. UIWebView 컨트롤을 사용하는 간단한 iPhone 앱을 개발했습니다. 이 단계에서 앱은 Asp.Net 웹 사이트로 이동합니다. 간단 하죠? 문제는 사용자가 로그인 페이지를 통과 할 수 없다는 것입니다. 재현 단계는 다음과 같습니다.

  • iPhone 앱을 엽니 다.
  • 앱이 홈 페이지로 이동합니다.
  • 사용자가 인증되지 않았으므로 로그인 화면 / 페이지로 리디렉션됩니다.
  • 사용자는 올바른 사용자 이름과 암호를 입력합니다. 제출을 클릭합니다.
  • 서버 측에서는 사용자가 인증되고 쿠키가 생성되어 FormsAuthentication.GetAuthCookie를 사용하여 클라이언트로 전송됩니다.
  • 서버 전송은 사용자를 올바른 홈 페이지로 보내기 위해 리디렉션됩니다.

그러나 사용자는 리디렉션 BACK 로그인 화면을!

나는 이것에 대해 광범위한 디버깅을 수행했으며 내가 아는 것은 다음과 같습니다.

쿠키가 클라이언트로 전송되고 클라이언트가 쿠키를 저장하고 있습니다. iPhone 디버거에서 그리고 Javsascript를 사용하여 페이지에 쿠키 데이터를 표시하여이를 확인했습니다. 쿠키가 서버로 다시 전송됩니다. Visual Studio 디버거에서이를 확인했습니다. 올바른 쿠키입니다 (설정된 것과 동일한 쿠키). User.Identity.IsAuthenticated 속성은 인증 쿠키가 Request 개체에 포함되어 있어도 어떤 이유로 인해 false를 반환합니다. iPhone 앱이 쿠키를 허용하도록 설정되어 있고 쿠키가 클라이언트에 있음을 확인했습니다.

재미있는 점이 있습니다. iPhone에서 Safari 브라우저를 열고 저희 사이트로 직접 이동하면 정상적으로 작동합니다.

로그인 화면을 통과하지 않는다는 점에서 iPad에서도 동일한 동작을합니다. 이것은 에뮬레이터와 장치에서 재현됩니다.

이 웹 사이트는 IE 7-8, Safari (Windows 용), Blackberry, IEMobile 6.5, Phone 7에서 테스트를 거쳤으며 찾을 수 있습니다. 작동하지 않는 유일한 상황은 iPhone 앱의 UIWebView입니다.


나는 똑같은 문제가 있었지만 다른 장치 (NokiaN8)에서 문제를 다시 User-Agent로 추적했습니다.

IIS는 정규식을 사용하여 User-Agent 문자열과 일치시킵니다. 문제의 근본 원인은 특정 장치에 대해 일치하는 정규식이 없었고, Default 속성이 사용 된 가장 낮은 수준의 일치 항목 중 하나가되었다는 것입니다. 기본 속성은 브라우저가 쿠키를 지원하지 않는다고 말했습니다.

해결책:

  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.browser)을 만들고이 xml을 포함하여 "Mozilla"및 기본 브라우저 설정이 모두 쿠키를 지원해야한다고 웹 서버에 알리는 것입니다.

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

이 문제는 ASP.NET 4.5에서 수정되었으며 모든 브라우저는 쿠키를 지원하는 것으로 간주되므로 추가 .browser 파일이 필요하지 않습니다.


내가 한 연구에서 User-Agent를 설정할 수없는 이유는 UIWebView가 요청을 보내기 직전, 즉 코드에서 요청을 한 후에 User-Agent 값을 설정하기 때문입니다. .

이 문제를 해결하는 방법은 표준 방법을 제공하는 방법으로 바꾸는 고급적이고 잠재적으로 위험한 Objective-C 개념 인 "방법 전환"이라는 것을 사용하는 것입니다. 최종 결과는 요청이 전송되고 프레임 워크 코드가 User-Agent를 추가 할 때 제공 한 방법을 사용하여 속이게됩니다.

다음은 이것을 구현하기 위해 내가 한 일을 설명하지만 저는 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 하위 클래스 :

@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) And then used it like this. (The connection delegate saves the data in a mutable array and then manually sets the UIWebView using its loadData method when it finishes loading).

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

I had the same exact problem, researched & consolidated a complete solution (from above answers and other threads) here: http://www.bloggersworld.com/index.php/asp-net-forms-authentication-iphone-cookies/


  1. Have you specified a DestinationPageUrl in markup?

  2. Have you specified the defaultURL in web.config?

Example web.config

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

Example DestinationPageUrl

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

Lastly have you looked in the cookie jar and seen if your session cookie actually exists?

Where are an UIWebView's cookies stored?


The reason of this happening apparently has to do with the fact that if the user-agent is not known then the browser is assumed to not accept cookies (as others have answered), and instead IIS puts the ASPXAUTH value in the URL.

However the MVC routing system apparently missed that possibility, which is clearly a bug, and therefore it is getting messed up.

While adding the .browser with a custom user-agent solves the problem, it does not guarantee that other user-agents will also be solved, and in fact I have found the K9 Browser for the android also has this problem, and as such it is only a solution if one has a logging system such as elmeh to track down such errors.

On the other hand adding a default brings up the question if it is true that all browsers accept cookies, which is apparently the reason why IIS does not assume so.

However besides adding explictly the user-agents one can add in the global.asax RegiterRoutes() method an explicit handler to ignore it, as follows:

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

However in this case one will have to copy all route entries to match with the cookie-less situation, unless one is about to write a custom route handler.

Or we can use the above cookie-less route to send the user to an error page explaining that his browser is not supported on the moment, and send an alert to the web-master with the user-agent to handle it.

참고URL : https://stackoverflow.com/questions/4158550/asp-net-forms-authentication-when-using-iphone-uiwebview

반응형