2009-08-24 18 views
6

System.IdentityModel.Selectors.UserNamePasswordValidatorクラスのオーバーライドされたValidate()メソッドを使用してカスタムUserName検証を使用するようにWCFサービスを構成しました。WCF UserName認証とフォルトコントラクト

契約のすべてのメソッドはFaultContractAttributeで修飾され、カスタムSOAPフォールトを返すことができます。

FaultExceptionをスローするとき<T>(TはFaultContractAttributeで指定された型です)、すべて正常に動作し、応答XMLにカスタムフォールトが発生します。私がしようとすると、ユーザー名の認証クラスのオーバーライドされたvalidate()メソッドにFaultException <T>を投げる場合

しかし、私は次のような理由で、一般的なSOAPフォールトを取得:

「このフォールトの作成者がなかった

理由を指定しないでください。 "私は、コードを変更した場合

しかし、のような一般的なSOAPフォールトをスローします

throw new FaultException("Authentication failed.");

私は、少なくとも取得する「認証に失敗しました。」理由要素の中で。

私の質問は以下のとおりです。彼らは、サービス実装の範囲内にあると検証()でスローされている場合

  • はなぜFaultException <T>例外が同じように扱われていませんか?
  • Validate()メソッドでスローされる例外を、コントラクトメソッドで指定されたFaultContractAttributeに準拠させることはできますか?

大変助かりました。自分の推測では、メッセージが契約のどのメソッドにも関連付けられる前に認証が行われるため、FaultContractAttributeには関連付けられていませんが、これを確認し回避策を与える記事は非常に便利です。

タリ

+0

感謝。どんな解決策ですか?私はまだ2013年3月に答えを探しています。 –

答えて

0

それは少し迷惑なんだけど、私はこれを行うことによって、そのラウンド得た:メッセージを含む

 
SecurityTokenValidationException stve 
    = new SecurityTokenValidationException("Invalid username or password"); 
throw new FaultException<SecurityTokenValidationException>(stve, stve.Message); 

は、さらにあなたが愚かな「理由を指定しませんでした」というメッセージを取得しないことを意味し。

0

問題は、カスタム検証コードが特定のコンテキストOperationContractの外部で実行されているため、WCFが処理する場所がFaultContractではないことが問題です。したがって、短い答えはいいえです。FaultContractを尊重するためにカスタムバリデータから例外をスローすることはできません。

ここにはいくつかのオプションがあります。私が好むものは、非汎用のFaultExceptionを投げ、あらかじめ決められたFaultCodeを提供することです。このようにして、私のキャッチブロックは、契約上の障害と「配管」障害とを区別することができます。以下に示すように、カスタムバリデータから投げる例外は、MessageSecurityExceptionとして戻ってくる必要があることに注意してください:この質問を投稿するための

// Custom Validator: 
public override void Validate(string userName, string password) 
{ 
    throw new FaultException(
    "Invalid username or password.", 
    new FaultCode("AUTHENTICATION_FAILURE")); 
} 

// Client Code: 
try 
{ 
    client.DoSomething(); 
} 
catch (MessageSecurityException ex) 
{ 
    var inner = ex.InnerException as FaultException; 
    if (inner != null && inner.Code.Name.Equals("AUTHENTICATION_FAILURE")) 
    { 
    // Security failure. 
    } 
} 
catch (FaultException<SomethingFault> ex) 
{ 
    // Exception from the method itself. 
} 
+0

私は上記を試しましたが、FaultExceptionとしてex.innerExceptionをキャストしようとするとnull値を取得します。どんな助けもありがとう。 – vikasse

+0

まあ、内部の例外はどのようなタイプの例外ですか?障害ではない場合、問題はサービスに含まれていません。 –

+0

私はサーバーにフォールト例外タイプを投げますが、クライアントでは内部例外はsystem.net.webexceptionタイプで、私はサーバーから投げたmsgを持っていません。 – vikasse