1

GetColorsをパラメーターとして受け取り、GetColorIdsRQを返すメソッドがありますGetColorIdsRSGetColorIdsRQは SOAP リクエストで、GetColorIdsRSは SOAP レスポンスです。それぞれの実装の詳細は次のとおりです。

GetColorIdsRQ:

[DataContract]
public class GetColorIdsRQ
{
    [DataMember(Name="UserCredentials",Order=0,IsRequired=true)]
    public UserCredentials UserCredentials { get; set; }
}

ユーザー認証情報:

[DataContract(Name="UserCredentials")]
public class UserCredentials
{
    [DataMember(Name="Username",Order=0,IsRequired=true)]
    public string UserName { get; set; }
    [DataMember(Name="Password",Order=1,IsRequired=true)]
    public string Password { get; set; }
}

GetColorIdsRS:

[DataContract]
public class GetColorIdsRS
{
    [DataMember(Name = "ColorsIds", IsRequired = true, Order = 0)]
    public List<Color> ColorIds { get; set; }
}

色:

[DataContract(Name="Color")]
public class Color    
{
   [DataMember(Name="Code",IsRequired=true,Order=0)]
   public string Code { get; set; }
   [DataMember(Name="Name",IsRequired=true,Order=1)]
   public string Name { get; set; }  
}

これは、メソッドがインターフェイスで宣言される方法です。

[OperationContract(Name = "GetColorIds")]
GetColorIdsRS GetColorsIds(GetColorIdsRQ req);

これは GetColorIds の実装です。

public GetColorIdsRS GetColors(GetColorIdsRQ req)
{
    GetColorIdsRS getColorIdsRS = new GetColorIdsRS();
    List<Color> colorIds = new List<Color>();

    req.UserCredentials.UserName = "test";
    req.UserCredentials.Password = "test";

    //Validate Username and Password

    DataTable dtColorIds = Data.GetDataTable("GetColors");

    foreach (DataRow item in dtColorIds.Rows)
    {
        colorIds.Add(new Color { Name = item["Name"].ToString(), 
                                 Code = item["ColorId"].ToString() });
    }

    getColorIdsRS.ColorIds = colorIds;

    return getColorIdsRS;
}

WCF テスト クライアントから GetColors を呼び出すと、要求本文は次のようになります。

<s:Body>
    <GetColors xmlns="http://test.com/2011/05">
      <req xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
       <UserCredentials>
         <Username>test</Username>
         <Password>test2</Password>
       </UserCredentials>
     </req>
   </GetColors>
 </s:Body>

Username上記の問題は、とPasswordノードをに使用したいということですCustomUserNameValidator。それに対して検証できるように、ユーザー名とパスワードのノードCustomUserNameValidatorを認識させる方法がわかりません。メソッドでGetColorIdsRQ上記に気付いた場合は、次のように設定しています。GetColors

req.UserCredentials.UserName = "test";
req.UserCredentials.Password = "test";

しかし、これは明らかに検証されません。my の実装は次のCustomUserNamePasswordValidatorとおりです。

public class CustomUserNameValidator : UserNamePasswordValidator
{
    public override void Validate(string userName, string password)
    {
        // check if the user is not test
        if (userName != "test" || password != "test")
            throw new FaultException("Username and Password Failed");
    }
}

したがって、本質的に私が合格した場合:

req.UserCredentials.UserName = "test";
req.UserCredentials.Password = "test2";

CustomUserNameValidator は FaultException をスローする必要があります。

GetColors メソッドにも注意してください。「//Validate Username and Password」というコメントがあります。できることはわかっています。

CustomUserNameValidator val = new CustomUserNameValidator();
val.Validate(req.UserCredentials.UserName,req.UserCredentials.Password)

上記はValidateメソッドを呼び出しますが、自動である必要があることに気付き、すべてのメソッドでこれを行う必要があります。

CustomUserNameValidator を呼び出す唯一の方法は、次のようなプロキシ コードで ClientCredentials を設定することです。

proxy.ClientCredentials.UserName.UserName = "test;
proxy.ClientCredentials.UserName.Password = "test;

上記により Validate メソッドが呼び出されますが、上記を実行できず、Username と Password を Request オブジェクトのプロパティとして設定した場合、Validate は呼び出されないため、他のオプションは単にそれを必要とする各操作内の独自の Validate メソッド。ClientCredentials が失敗した場合、操作は呼び出されませんが、私の場合、操作を呼び出してから、スローの代わりに「無効なユーザー名および/またはパスワード」のようなエラー ノードを含む SOAP 応答を返す必要があります。 FaultException。

上記に基づいて、私の場合は CustomUserNamePasswordValidator の使用を避けるのが最善ですか?

ユーザー名とパスワードがプロキシのクライアント資格情報を介して設定できず、soap リクエストの本文を介して送信される場合、これを処理する方法は運用ベースで検証を処理することであると思われます。これはセキュリティ設定に影響します (たとえば、clientCredentialType="Username" にするポイントはありますか)

4

1 に答える 1

0

これは、WCF セキュリティ パイプラインを深く掘り下げてカスタム セキュリティ トークンを実装し (それでも不可能であることがわかります)、この実装に関連するすべてのものを実装しない限り、不可能です

標準の UserName 認証を使用しないのはなぜですか?

編集:

メッセージ本文のカスタム要素で資格情報を渡したい (そしてセキュリティ パイプラインを変更しない) 場合、検証はユーザー次第であり、ユーザー名バリデーターにはルーティングされません。操作中に行う必要があります。または、カスタム メッセージ インスペクターを構築し (実装IMessageInspector)、それをカスタム エンドポイント動作でラップして ( IEndpointBehavior)、検証を一元化することもできます。

于 2011-06-06T16:44:40.047 に答える