2009-12-10 3 views
6

폼 인증으로 보호되는 ASP.NET 앱이 있습니다. 앱은 MS AJAX를 사용하여 웹 서비스를 많이 호출합니다. AJAX의 폼 인증 및 POST 요청

아웃 폼 인증 시간 및 발생 - 요청 GET

- 모든 괜찮를 (사용자는 로그인 페이지로 리디렉션됩니다).

하지만 때 밖으로 폼 인증 시간과 일 - 요청 POST (아약스) - 더 리디렉션이 발생하지 않고 응용 프로그램 반환 "401 unathorized"브라우저는 사용자 이름과 암호 (안 로그인 폼에 대한 프롬프트 브라우저 내장 대화 상자). 물론 모든 사용자 이름/비밀번호를 입력하면 도움이되지 않습니다.

어떻게 처리합니까?

UPDATE : 불을 지르고 찾고 후, 나는 그냥은 "401 Unauthorizes"를 던져에만 웹 서비스 호출있어, 일반 POST 요청이 미세 로그인 리디렉션 것을 알아 냈다. 일반 요청과 웹 서비스의 차이점은 URL입니다. 어떤 정규 후 요청 및 웹 서비스에 대한 "Service.asmx를/methodName로"에 대한 "page.aspx"...

+1

FireBug를 사용하여 실제로 서버로 전송 된 내용과 응답 한 내용은 무엇입니까? 브라우저의 기본 제공 프롬프트는 일반적으로 액세스하려는 리소스가 기본 또는 NTLM 인증에 의해 보호된다는 것을 의미합니다. 사이트의 일부에 대해 이러한 인증을 사용할 수 있습니까? –

+0

예, IIS 설정에서 "익명 액세스"와 함께 "Windows 통합"인증을 받았습니다. 감사합니다, Firebug를 시도 할 것입니다 – Alex

답변

2

내 자신의 questin에 응답.

  • 가 있다면 :

    이 문제를 조사 및 더 많은 비트를 조사한 후 나는 웹 응용 프로그램이 폼 인증으로 보호하고 사용자가 인증되지 않은 경우에, 이런 것입니다 발견 GET 요청 - 사용자는 이며 로그인 페이지로 리디렉션됩니다.

  • 페이지에 대한 POST 요청 인 경우 사용자는 이며 로그인 페이지로 리디렉션됩니다.
  • 는 웹 서비스에 POST 요청 의 경우 - 사용자가 어떻게
  • (401) - 무단

그게 ASP를 가져가.NET 작동

그리고 웹 서비스가 AJAX (xmlHttpRequest 객체)에 의해 호출되고 401을 반환하면 물론 브라우저에 팝업 로그인 상자가 표시됩니다.

이제 웹 서비스에 대해 401을 던지지 않도록 Application_PostAuthenticateRequest에 코드를 추가해야합니다.

protected void Application_PostAuthenticateRequest(Object sender, EventArgs e) 
{ 
    if (Request.RequestType == "POST" //if its POST 
     && !User.Identity.IsAuthenticated //if user NOT authed 
     && !HasAnonymousAccess(Context) //if it's not the login page 
     ) 
    { 
     //lets get the auth type 
     Configuration config = WebConfigurationManager.OpenWebConfiguration("~"); 
     SystemWebSectionGroup grp = (SystemWebSectionGroup)config.GetSectionGroup("system.web"); 
     AuthenticationSection auth = grp.Authentication; 
     //if it FORMS auth 
     if(auth.Mode== AuthenticationMode.Forms) 
     { 

      //then redirect... this redirect won't work for AJAX cause xmlHttpRequest can't handle redirects, but anyway... 
      Response.Redirect(FormsAuthentication.LoginUrl, true); 
      Response.End(); 

     } 
    } 
} 
public static bool HasAnonymousAccess(HttpContext context) 
{ 
    return UrlAuthorizationModule.CheckUrlAccessForPrincipal(
     context.Request.Path, 
     new GenericPrincipal(new GenericIdentity(string.Empty), null), 
     context.Request.HttpMethod); 
} 
+0

@jazbit, 당신은 웹 서비스에 대한 401 상태 코드에 대해 이야기하는 일부 doucmentation을 가리킬 수 있습니까? 나는 세션을 확인 중이며 클라이언트에게 결과 401을 리다이렉션하고 있습니다. –

+0

Response.End는 일반적으로 할 나쁜 일. 보통 당신은'response.Redirect (url, False);를 원한다. HttpContext.Current.ApplicationInstance.CompleteRequest();' –

1

이다 나는 두 가지 솔루션을 참조하십시오

(1) "심장 박동"메커니즘을.

<script> 
    setInterval(ping, 60000); // based on comment by John 
    function ping() 
    { 
     $.get('/do/nothing'); 
    } 
</script> 

이 방법 세션이 한 브라우저 창은 열려있는 만료되지해야합니다 : 각 페이지에 "핑 (ping)"과 같은 몇 가지 더미 아약스 요청에 의해 서버,하는 스크립트를 포함한다.

(2) 각 ajax 요청에서 응답 상태를 확인하십시오. 응답에 "401 unauthorized"코드 (또는 200이 아닌 다른 코드)가 있으면 세션이 만료되었고 페이지의 일부 대화 상자에 응답을로드하는 대신 사용자를 로그인 페이지로 리디렉션합니다. 의견에 따라

결론 :

가장 좋은 방법은 위의 두 가지 메커니즘을 결합하는 것입니다. 하트 비트 메커니즘은 페이지가 브라우저에 표시되는 한 세션을 활성 상태로 유지하는 데 도움이됩니다. 그러나 있음을 보장하지는 않습니다. 세션이 만료되면 서버 연결이 끊어지고 다시 열릴 수 있습니다. 따라서 어쨌든 응답 상태를 확인해야합니다.

+0

setInterval (ping, 60000); 만 할 수 있습니다 setInterval에 문자열을 전달하는 것은 eval()과 동일하므로 권장하지 않습니다 –

+0

또한 ping() 내에서 setInterval을 다시 호출해야합니다. 두 번 이상 실행하려는 경우 –

+0

다른 모든 코드가 200 이상이면 세션이 만료되었음을 의미하지 않습니다. –