11

自己ホスト型の WCF REST サービスを作成しました (WCF REST スターター キット プレビュー 2 の追加機能を使用)。これはすべて正常に機能しています。

現在、基本認証をサービスに追加しようとしています。しかし、私はこれを行うのを妨げている WCF スタックでいくつかのかなり大きな障害にぶつかっています。

HttpListener(自己ホスト型の WCF サービスが WCF スタックの低レベルで内部的に使用する) が、自己生成された応答にヘッダーを挿入しようとする試みをブロックしているようWWW-Authenticateです401 Unauthorized。なんで?

このヘッダーを忘れても、認証を機能させることができますWWW-Authenticate(Microsoft も同様に行ったようです)。しかし、それが問題です。ヘッダーを送り返さないWWW-Authenticateと、Web ブラウザーは標準の「ログオン」ダイアログを表示しません。ユーザーはエラー ページに直面するだけで、401 Unauthorized実際にログオンする方法はありません。

REST サービスは、コンピューターと人間の両方がアクセスできる必要があります (少なくとも GET 要求レベルでは)。したがって、WCF REST はここで REST の基本的な部分に準拠していないように感じます。誰かが私に同意しますか?

自己ホスト型の WCF REST サービスで動作する基本認証を取得した人はいますか? もしそうなら、どのようにしましたか?

PS:明らかに、セキュリティで保護されていない基本認証を使用するという私の意図は、私のサービスでも HTTPS/SSL が機能することを前提としています。しかし、それは別の問題です。

PPS: WCF REST Contrib ( http://wcfrestcontrib.codeplex.com/ ) を試しましたが、まったく同じ問題があります。このライブラリは、自己ホスト型のシナリオでテストされていないようです。

ありがとう。

4

3 に答える 3

13

残念ながら、(WCF 参照ソース コードと HTTP セッション スニッフィング用の Fiddler ツールの助けを借りて) これが WCF スタックのバグであると判断しました。

Fiddler を使用して、WCF サービスが基本認証を使用する他の Web サイトとは異なる動作をしていることに気付きました。

明確にするために、これは何が起こるべきかです:

  1. ブラウザGETは、パスワードが必要であることさえ知らずにリクエストを送信します。
  2. 401 UnauthorizedWeb サーバーは、ステータスとともに要求を拒否し、WWW-Authenticate受け入れ可能な認証方法に関する情報を含むヘッダーを含めます。
  3. ブラウザーはユーザーに資格情報の入力を求めます。
  4. ブラウザーGETは要求を再送信し、資格情報を含む適切なAuthenticationヘッダーを含めます。
  5. 200 OK資格情報が正しければ、Web サーバーはWeb ページで応答します。資格情報が間違っていた場合、Web サーバーは応答し、手順 2 で行ったもの401 Unauthorizedと同じWWW-Authenticateヘッダーを含めます。

私のWCFサービスで実際に起こっていたのはこれでした:

  1. ブラウザGETは、パスワードが必要であることさえ知らずにリクエストを送信します。
  2. WCF は、要求にヘッダーが含まれていないことを認識し、ステータスAuthenticationと共に要求をやみくもに拒否し、ヘッダーを含めます。これまでのところすべて正常です。401 UnauthorizedWWW-Authenticate
  3. ブラウザはユーザーに資格証明を要求します。まだ正常です。
  4. ブラウザーは、適切なヘッダーGETを含む要求を再送信します。Authentication
  5. 資格情報が正しかった場合、Web サーバーは で応答し200 OKます。すべて良好。ただし、資格情報が間違っていた場合、WCF は応答し403 ForbiddenWWW-Authenticate.

ブラウザが403 Forbiddenステータスを取得しても、これが認証試行の失敗であるとは認識されません。このステータス コードは、アクセスしようとした URL が立ち入り禁止であることをブラウザに通知することを目的としています。認証とはまったく関係ありません。これには、ユーザーがユーザー名/パスワードを間違って入力した場合 (そしてサーバーが 403 で拒否した場合) に、Web ブラウザーがユーザーに資格情報の再入力を求めるプロンプトを表示しないという恐ろしい副作用があります。実際、Web ブラウザは認証が成功したと認識し、セッションの残りの部分でそれらの資格情報を保存します!

これを念頭に置いて、私は明確化を求めました:

RFC 2617 ( http://www.faqs.org/rfcs/rfc2617.html#ixzz0eboUfnrl403 Forbidden ) は、ステータス コードの使用についてどこにも言及していません。実際、この問題について実際に言わなければならないことは次のとおりです。

オリジンサーバーがリクエストで送信されたクレデンシャルを受け入れたくない場合、401 (Unauthorized) レスポンスを返す必要があります。応答には、要求されたリソースに適用可能な少なくとも 1 つの (場合によっては新しい) チャレンジを含む WWW-Authenticate ヘッダー フィールドを含める必要があります。

WCF はこれらのどちらも行いません。401 Unauthorizedステータス コードも正しく送信されません。WWW-Authenticateまた、ヘッダーも含まれません。

次に、WCF ソース コード内で決定的な証拠を見つけます。

HttpRequestContextクラスに というメソッドがあり、次の内容が含まれていることがわかりProcessAuthenticationました (抜粋):

if (!authenticationSucceeded) 
{
   SendResponseAndClose(HttpStatusCode.Forbidden);
}

私は多くの点でマイクロソフトを擁護していますが、これは弁護の余地がありません。

幸いなことに、「許容できる」レベルまで機能しています。ユーザーが誤ってユーザー名/パスワードを誤って入力した場合、もう一度試行する唯一の方法は、Web ブラウザーを完全に閉じて再起動し、再試行することです。すべては、WCF が失敗した認証の試行に、仕様に従ってヘッダーとヘッダーで応答しないためです。401 UnauthorizedWWW-Authenticate

于 2010-02-04T22:40:23.473 に答える
6

このリンクこれに基づいて解決策を見つけました。

1 つ目は、 System.IdentityModel.Selectors.UserNamePasswordValidatorから継承するCustomUserNameValidatorというクラスのメソッド Validate をオーバーライドすることです。

Imports System.IdentityModel.Selectors
Imports System.ServiceModel
Imports System.Net

Public Class CustomUserNameValidator
    Inherits UserNamePasswordValidator

Public Overrides Sub Validate(userName As String, password As String)
    If Nothing = userName OrElse Nothing = password Then
        Throw New ArgumentNullException()
    End If

    If Not (userName = "user" AndAlso password = "password") Then
        Dim exep As New AddressAccessDeniedException("Incorrect user or password")
        exep.Data("HttpStatusCode") = HttpStatusCode.Unauthorized
        Throw exep
    End If
End Sub
End Class

トリックは、例外「HttpStatusCode」の属性を HttpStatusCode.Unauthorized に変更することでした

2 つ目は、次のように App.config でserviceBehaviorを作成することです。

<behaviors>
  <endpointBehaviors>
    <behavior name="HttpEnableBehavior">
      <webHttp />
    </behavior>
  </endpointBehaviors>
  <serviceBehaviors>
    <behavior name="SimpleServiceBehavior">
      <serviceMetadata httpGetEnabled="true"/>
      <serviceDebug includeExceptionDetailInFaults="false"/>
      <serviceCredentials>
        <userNameAuthentication userNamePasswordValidationMode="Custom" customUserNamePasswordValidatorType="Service.CustomUserNameValidator, Service"/>
      </serviceCredentials>
    </behavior>
  </serviceBehaviors>
</behaviors>

最後に、webHttpBinding の構成を指定し、それをエンドポイントに適用する必要があります。

<bindings>
  <webHttpBinding>
    <binding name="basicAuthBinding">
      <security mode="TransportCredentialOnly">
        <transport clientCredentialType="Basic" realm=""/>
      </security>
    </binding>
  </webHttpBinding>
</bindings>

<service behaviorConfiguration="SimpleServiceBehavior" name="Service.webService">
    <host>
      <baseAddresses>
        <add baseAddress="http://localhost:8000/webService" />
      </baseAddresses>
    </host>
    <endpoint address="http://localhost:8000/webService/restful" binding="webHttpBinding" bindingConfiguration="basicAuthBinding" contract="Service.IwebService" behaviorConfiguration="HttpEnableBehavior"/>
</service>
于 2011-06-13T21:08:48.473 に答える
1

はい、REST ベースの WCF サービスに基本認証を提供できます。ただし、完全で安全なソリューションを実現するために従わなければならないいくつかの手順があり、これまでのところ、ほとんどの応答は必要なすべての要素の断片です。

  1. WCF サービスをホストしているポートに SSL 証明書がバインドされるようにセルフホステッド サービスを構成します。これは、IIS などを介してマネージド ホスティングを使用する場合に SSL 証明書を適用する場合とは大きく異なります。コマンド ライン ユーティリティを使用して SSL 証明書を適用する必要があります。ヘッダーの認証情報が安全ではないため、SSL を使用せずに REST サービスで基本認証を使用しないでください。これを行う方法を正確に説明した (2) 詳細な投稿を次に示します。あなたの質問は大きすぎて、フォーラムの投稿にすべての詳細を載せることができません。そのため、包括的な詳細と段階的な手順を含むリンクを提供しています。

    セルフホステッド WCF サービスでの SSL 証明書の適用と使用

    WCF RESTful サービスを作成し、HTTPS over SSL を使用して保護する

  2. 基本認証を使用するようにサービスを構成します。これもマルチパートソリューションです。1 つ目は、基本認証を使用するようにサービスを構成することです。2 つ目は、「customUserNamePasswordValidatorType」を作成し、資格情報を検査してクライアントを認証することです。前回の投稿はこれに当てはまらなかったようですが、HTTPS を使用しておら、ソリューションのごく一部にすぎません。構成とセキュリティを含むエンド ツー エンドのソリューションを提供しないガイダンスには注意してください。最後の手順は、セキュリティ コンテキストを調べて、必要に応じてメソッド レベルで承認を提供することです。私が書いた次の投稿では、クライアントを構成、認証、承認する方法を順を追って説明しています。

    RESTful サービス: 基本認証を使用したクライアントの認証

これは、セルフホステッド WCF サービスで基本認証を使用するために必要なエンド ツー エンドのソリューションです。

于 2012-06-02T02:43:58.720 に答える