2

基本的なカスタム認証を使用して IIS で公開する必要がある OData WCF サービスの実用的な実装があります。

実装はMicrosoft OData の例に基づいており、IIS Express の下で完全に正常に動作します。基本認証のみを有効にして IIS 7.5 に発行すると、AuthenticateRequest ハンドラーは最初の要求でのみ呼び出され、ステータス コード 401 が返され、認証を求められます。

AuthenticateRequest は、後続のリクエストで呼び出されなくなりました。IIS でサービスをデバッグするとき、BeginRequest は確実に呼び出されます。パイプラインに AuthenticateRequest が存在しないだけですか? どちらも IIS Express のすべての要求と呼ばれます。

IIS 認証構成:

IIS 認証の構成

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>

質問: Visual Studio 2012 デバッグ サーバーでは認証が機能するのに、IIS 7.5 では機能しないのはなぜですか? 完全なテスト プロジェクトは、ここからダウンロードできます。

編集:

CreateNotAuthorizedResponse 関数と response.End() で過剰なテスト コードをコメントアウトしたため、例外が発生しました (投稿する直前に追加しました)。

リクエストを検査すると、Cookie が原因で IIS が何らかの理由で認証をスキップする可能性があることを除いて、すべてが機能しているように見えます。最初の 2 つの raw リクエストの下 - 応答のペア:

リクエスト 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 (test:test - 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> 
4

1 に答える 1

1

IIS 組み込みの基本認証と独自のカスタム認証モジュールを混同していると思います。簡単な答えは、IIS で基本認証を無効にし、匿名を有効にすることです。これにより、すべての認証作業が asp.net に渡されます。

VS でテストしている場合は、F5 キーを押すと自動的に起動するブラウザーを介してテストしていると想定しています。

基本認証をオンにすると、IIS は最初に 401 で応答し、ブラウザにログイン フォームを表示させます。

そこに入力する資格情報は、IIS が Windows アカウントに対して検証する有効な Windows 資格情報である必要があります。IIS がこれらの資格情報を検証すると、リクエストがコードに渡されます。

有効な Windows 資格情報を入力すると、イベントが発生しますが、資格情報がテスト/テストではなく、401.1 を返すため、コードはそれを拒否します。

test/test と入力すると、IIS は資格情報を拒否し、401 を返すため、イベントは呼び出されません。

最後に: HTTP クライアントを使用して Web サービスをテストするか (System.Net.WebClient を使用した単体テストなど)、Chrome プラグイン (postman/devhttp) を使用して http レベルでテストする必要があります。すでにこれを行っている場合は、私の仮定を許してください。

于 2014-10-22T17:18:20.737 に答える