2014-10-17 5 views
2

기본 사용자 지정 인증을 사용하여 IIS에 게시해야하는 OData WCF 서비스의 작동 구현이 있습니다.IIS AuthenticateRequest에서 WCF 서비스를 인증 할 때 처음으로 만 호출되는 경우

구현은 Microsoft OData example을 기반으로하며 IIS Express에서 완벽하게 작동합니다. 기본 인증 만 사용하도록 IIS 7.5에 게시하면 AuthenticateRequest 처리기는 초기 요청시에만 호출되며 상태 코드 401을 반환하고 인증을 요청합니다.

AuthenticateRequest는 더 이상 후속 요청에서 호출되지 않습니다. IIS에서 서비스를 디버깅 할 때 BeginRequest가 확실히 호출됩니다. 단지 AuthenticateRequest가 파이프 라인에없는 것입니까? 둘 다 IIS Express에서 모든 요청이라고합니다.

IIS 인증 구성 :

IIS Authentication configuration

IHttpModule 코드 :

public class BasicAuthModule: IHttpModule 
{ 
    // based on http://msdn.microsoft.com/en-gb/data/gg192997.aspx 

    public void Init(HttpApplication app) 
    { 
     app.AuthenticateRequest += AuthenticateRequest; 
     app.BeginRequest += BeginRequest; 
    } 

    private void BeginRequest(object sender, EventArgs e) 
    { 
     var app = (HttpApplication)sender; 
     if(app.Context == null) 
     { 
      throw new Exception("Will not happen"); 
     } 
    } 

    private void AuthenticateRequest(object sender, EventArgs e) 
    { 
     var app = (HttpApplication)sender; 
     if(!app.Request.Headers.AllKeys.Contains("Authorization")) 
     { 
      CreateNotAuthorizedResponse(app, 401, 1, "Please provide Authorization headers with your request."); 
      app.CompleteRequest(); 
     } 
     else if(!BasicAuthProvider.Authenticate(app.Context)) 
     { 
      CreateNotAuthorizedResponse(app, 401, 1, "Logon failed."); 
      app.CompleteRequest(); 
     } 
    } 

    private static void CreateNotAuthorizedResponse(HttpApplication app, int code, int subCode, string description) 
    { 
     var response = app.Context.Response; 
//  response.Status = "401 Unauthorized"; 
     response.StatusCode = code; 
     response.SubStatusCode = subCode; 
     response.StatusDescription = description; 
//  response.AppendHeader("WWW-Authenticate", "Basic"); 
//  response.End(); 
    } 

    public void Dispose() 
    { 
    } 
} 

의 Web.config :

<?xml version="1.0"?> 
<configuration> 
    <appSettings> 
    <add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" /> 
    </appSettings> 
    <system.web> 
    <compilation debug="true" targetFramework="4.5" /> 
    <httpRuntime targetFramework="4.5"/> 
    </system.web> 
    <system.serviceModel> 
    <behaviors> 
     <serviceBehaviors> 
     <behavior> 
      <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/> 
      <serviceDebug includeExceptionDetailInFaults="false"/> 
     </behavior> 
     </serviceBehaviors> 
    </behaviors> 
    <protocolMapping> 
     <add binding="basicHttpsBinding" scheme="https" /> 
    </protocolMapping>  
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" /> 
    </system.serviceModel> 
    <system.webServer> 
     <modules runAllManagedModulesForAllRequests="true"> 
      <add name="BasicAuthModule" type="WcfTestService.BasicAuthModule"/> 
     </modules> 
    <directoryBrowse enabled="true"/> 
    </system.webServer> 
</configuration> 

그리고 질문 : 인증은 비주얼 스튜디오 2012 디버깅에서 작동하는 이유 서버에 있지만 IIS 7.5에는 없습니까? 전체 테스트 프로젝트는 here에서 다운로드 할 수 있습니다.

편집 : 나는 CreateNotAuthorizedResponse 기능과 예외를 (나는 마지막 순간 게시하기 전에 추가) 발생으로 Response.End()에 과도한 테스트 코드를 주석

.

요청을 검사 할 때 Cookie가 IIS가 어떤 이유로 인증을 건너 뛸 수 있다는 점을 제외하면 모든 것이 작동해야합니다. 제 2 원료 요청 아래 - 쌍을 올리 :

요청 1

GET http://localhost:8080/test/ HTTP/1.1 
Host: localhost:8080 
Connection: keep-alive 
Pragma: no-cache 
Cache-Control: no-cache 
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8 
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2062.124 Safari/537.36 
Accept-Encoding: gzip,deflate,sdch 
Accept-Language: en-US,en;q=0.8,pl;q=0.6 
Cookie: ASPSESSIONIDAQRDDBTR=BPCFKGDDCGJLPFKHEPOLPMFK; __RequestVerificationToken_L2RlbGl2ZXJ50=j0o-RDC12Z_E1o1nnXU_9iFaThUEPXRXDNKepqoX2fmgjg8gRB6Hi9fs3MSGxUvYQs6tJ0Jxsf6U20WKWpOrj4azgL_VpVzQHcNyJghUrKg1; __RequestVerificationToken=uOeCVgZDguOs3mRA7O4nhj88wJ_mFR6t1QN7vl7mOPGaNBoEnVFmIQVoUwxim8NbODJKMz5fBuAoPKo7Ek-4JeujsOIyIxjRB1xS_JaFF381; .ASPXAUTH=C2965A60E4BB162123A2CDDA8FD825C9DF3625116E5722C9B873BA64F041CCDCAB098EA3A208C2061D8D5746BC0832413105BA274C1B37DB8276471D49DE12562E4E93933289828427F559057519E75421493909E215EAA0DFB4C8DBE213EAC19AB6025EA715658A8D57CAFA308F7AC4A9051687777D2E82B7A2552917466E7C0BFA0C23EEE272F7E83C3718371375358B1199F155FB882EF8F5082CB28F6E030146DE365B5E4D8FE25E55EDD3F03788 

응답 1 (CreateNotAuthorizedResponse 방법에 의해 생성 된)

HTTP/1.1 401 Please provide Authorization headers with your request. 
Cache-Control: private 
Content-Type: text/html; charset=utf-8 
Server: Microsoft-IIS/7.5 
WWW-Authenticate: Basic realm="localhost" 
X-Powered-By: ASP.NET 
Date: Mon, 20 Oct 2014 13:03:14 GMT 
Content-Length: 6607 

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml"> 
<head> 
<title>IIS 7.5 Detailed Error - 401.1 - Please provide Authorization headers with your request.</title> 

요청 2 (입력 테스트 : 테스트 - dGVzdDp0ZXN0) :

GET http://localhost:8080/test/ HTTP/1.1 
Host: localhost:8080 
Connection: keep-alive 
Pragma: no-cache 
Cache-Control: no-cache 
Authorization: Basic dGVzdDp0ZXN0 
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8 
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2062.124 Safari/537.36 
Accept-Encoding: gzip,deflate,sdch 
Accept-Language: en-US,en;q=0.8,pl;q=0.6 
Cookie: ASPSESSIONIDAQRDDBTR=BPCFKGDDCGJLPFKHEPOLPMFK; __RequestVerificationToken_L2RlbGl2ZXJ50=j0o-RDC12Z_E1o1nnXU_9iFaThUEPXRXDNKepqoX2fmgjg8gRB6Hi9fs3MSGxUvYQs6tJ0Jxsf6U20WKWpOrj4azgL_VpVzQHcNyJghUrKg1; __RequestVerificationToken=uOeCVgZDguOs3mRA7O4nhj88wJ_mFR6t1QN7vl7mOPGaNBoEnVFmIQVoUwxim8NbODJKMz5fBuAoPKo7Ek-4JeujsOIyIxjRB1xS_JaFF381; .ASPXAUTH=C2965A60E4BB162123A2CDDA8FD825C9DF3625116E5722C9B873BA64F041CCDCAB098EA3A208C2061D8D5746BC0832413105BA274C1B37DB8276471D49DE12562E4E93933289828427F559057519E75421493909E215EAA0DFB4C8DBE213EAC19AB6025EA715658A8D57CAFA308F7AC4A9051687777D2E82B7A2552917466E7C0BFA0C23EEE272F7E83C3718371375358B1199F155FB882EF8F5082CB28F6E030146DE365B5E4D8FE25E55EDD3F03788 

응답 2 (BeginRequest는 AuthenticateRequest가 아니라 호출 됨) :

HTTP/1.1 401 Unauthorized 
Cache-Control: private 
Content-Type: text/html; charset=utf-8 
Server: Microsoft-IIS/7.5 
WWW-Authenticate: Basic realm="localhost" 
X-Powered-By: ASP.NET 
Date: Mon, 20 Oct 2014 13:03:17 GMT 
Content-Length: 6531 

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml"> 
<head> 
<title>IIS 7.5 Detailed Error - 401.1 - Unauthorized</title> 

답변

1

IIS 기본 제공 인증을 사용자 지정 인증 모듈과 혼용하고 있다고 생각합니다. 간단한 대답은 IIS에서 기본 인증을 비활성화하고 익명을 활성화하는 것입니다. 이것은 asp.net에 모든 인증 작업을 전달합니다.

VS에서 테스트 중이라면 F5를 누르면 자동으로 실행되는 브라우저를 통해 수행 중이라고 가정합니다.

기본 인증을 사용하도록 설정하면 IIS는 브라우저가 로그인 양식을 표시하도록 401 초기에 응답합니다.

사용자가 입력 한 자격 증명은 유효한 Windows 자격 증명이어야하며 IIS는 Windows 계정에 대해 유효성을 검사합니다.IIS가 이러한 자격 증명을 확인하면 요청을 코드에 전달합니다.

유효한 Windows 자격 증명을 입력하면 이벤트가 발생하지만 코드는 자격 시험/검사하지 않기 때문에 그것을 거부하고 401.1

를 반환합니다 당신은 검사/시험 다음 IIS가 자격 증명을 거부를 입력하고 전송하면 이벤트가 호출되지 않도록 401을 다시 보냅니다.

마지막 단어 : http 클라이언트 (예 : System.Net.WebClient의 단위 테스트)를 사용하여 웹 서비스를 테스트하거나 http 플러그인에서 크롬 서비스 (postman/devhttp)를 사용하여 http 수준에서 테스트해야합니다. 당신이 이미 이것을하고 있다면 내 가정을 용서하십시오.

+0

좋은 설명에 감사드립니다. 사실 나는 이미 익명 성으로 전환했으며 귀하의 설명에 따라 더 합리적입니다. 나는 Fiddler를 사용하여 IIS와의 트래픽을 분석하고 단위 테스트는 설명 된대로 또는 주로 Credentials가 설정된 DataServiceContext를 사용하여 직접 연결합니다. 시간 내 주셔서 다시 한번 감사드립니다. – too

+0

오신 것을 환영합니다. 기쁘게 생각합니다. 당신이 세부적인 질문을 올렸고 볼 코드를 제공하는 데 많은 도움이됩니다. 건배 – Avner