0

ASP.NETAjaxを使用してASP.NETページからWCFを呼び出しています。フォーム認証を使用してWebサイトを保護しています。

本番サーバーにデプロイされるまで、開発を通じてすべてが期待どおりに機能していました。その後、サービスが見つからなかったため、JavaScriptエラーが発生し始めました。本番サーバーはSSLを使用しているため、web.configに以下を追加しました。

<webHttpBinding>
    <binding name="webBinding">
    <security mode="Transport" />
    </binding>
</webHttpBinding>

これにより、JavaScriptエラーの発生は停止しましたが、WCFサービスは以前のように動作しなくなりました。

セキュリティを設定してASP.NETからWCFサービスへの呼び出しを転送する前に、AjaxはApplication_AuthenticateRequestGlobal.asaxでを実行します。IPrincipleこれにより、フォーム認証チケットにHttpContext.Current.User基づいてカスタムが設定されます。WCFサービスセットのコンストラクター。これにより、サービスはの間にセットにThread.CurrentPrinciple = HttpContext.Current.Userアクセスできます。IPrincipleApplication_AuthenticateRequest

セキュリティをトランスポートに変更した後、私のカスタムではないApplication_AuthenticateRequestため、セキュリティが実行されていないように見えます。Thread.CurrentPrincipleIPrinciple

トランスポートを使用する前と使用した後と同じ動作を得る方法を知っている人はいますか?

私のWebページは、WCFサービスを参照するために以下を使用しています。

<asp:ScriptManagerProxy ID="ScriptManagerProxy1" runat="
    <Services>
        <asp:ServiceReference Path="~/Services/MyService.svc" />
    </Services>
</asp:ScriptManagerProxy>

私ので使用されているコードApplication_AuthenticateRequest

protected void Application_AuthenticateRequest(object sender, EventArgs e)
{
    String cookieName = FormsAuthentication.FormsCookieName;
    HttpCookie authCookie = Context.Request.Cookies[cookieName];

    if (authCookie == null)
    {
        return;
    }

    FormsAuthenticationTicket authTicket = null;
    try
    {
        authTicket = FormsAuthentication.Decrypt(authCookie.Value);
    }
    catch
    {
        return;
    }

    if (authTicket == null)
    {
        return;
    }

    HttpContext.Current.User = new CustomPrinciple(authTicket.Name);
}
4

1 に答える 1

1

セキュリティを None から Transport に変更するだけでは、Authenticate_Request を介して実行されているアプリケーションには影響しません。おそらく、デバッガーをサービスの実装にアタッチして、HttpContext.Current.User が何であるかを確認する必要があります。カスタムプリンシパルですか、それとも設定されていませんか? そこにいくつかの Debug.Write メッセージを追加して、操作の順序を確認することもできます。Authenticate_Request イベントは予期した後に発生していますか?

構成でを使用している場合、MS Connect からこの問題が発生している可能性があります。<serviceAuthorization principalPermissionMode="UseAspNetRoles" />この設定は、セキュリティで保護されたトランスポートと互換性がなく、WCF がプリンシパルを上書きしているようです。プリンシパルを設定している場合は、principalPermissionMode="None"その上で使用する必要があるようです。

config ( ) またはサービスの属性( ) を使用して、サービスでASP.NET 互換モードが有効になっていることを確認します。それがなければ、サービスは HttpContext.Current にアクセスできません。<serviceHostingEnvironment aspNetCompatibilityEnabled="true" />[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Required)]

また、サービス実装コンストラクターで HttpContext.Current.User を取得するのではなく、サービスにアタッチする動作に移動してみてください。IDispatchMessageInspectorイベントを処理しAfterReceiveRequest、プリンシパルを Web コンテキストからスレッドに転送するを実装します。次のようになります。

public class HttpContextPrincipalInspector : IDispatchMessageInspector
{
  public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext)
  {
    if (HttpContext.Current != null)
    {
      IPrincipal principal = HttpContext.Current.User;
      Thread.CurrentPrincipal = principal;
    }
    return null;
  }

  public void BeforeSendReply(ref Message reply, object correlationState) { }
}

そしてもちろん、IEndpointBehaviorディスパッチャをアタッチするために を実装します...

public class HttpContextPrincipalBehavior : IEndpointBehavior
{
  public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
  {
    ChannelDispatcher channelDispatcher = endpointDispatcher.ChannelDispatcher;
    foreach (EndpointDispatcher endpointDispatch in channelDispatcher.Endpoints)
    {
      endpointDispatch.DispatchRuntime.MessageInspectors.Add(new HttpContextPrincipalInspector());
    }
  }

  // AddBindingParameters, ApplyClientBehavior, and Validate implementations
  // can be empty - they don't do anything.
}

...そしてカスタムBehaviorExtensionElementなので、WCF構成で使用できます:

public class HttpContextPrincipalElement : BehaviorExtensionElement
{
  public override Type BehaviorType
  {
    get { return typeof(HttpContextPrincipalBehavior); }
  }

  protected override object CreateBehavior()
  {
    return new HttpContextPrincipalBehavior();
  }
}

次に、これをエンドポイントの動作として使用するように任意のサービスを構成できるため、サービスの実装が Web コンテキストと直接やり取りすることはありません。テストが少し簡単になり、問題を完全に解決できる可能性があります。サービスにメッセージが届くたびに、サービスの構築に依存するのではなく、プリンシパルが自動的に転送されます。

于 2010-02-09T23:56:46.920 に答える