2

私は非常に奇妙な問題を抱えています (SL5、WCF DataServices 5.0.1 を使用): ユーザーが存在するかどうかを確認する 2 つの文字列パラメーター (ユーザー名、パスワード) を持つ ServiceOperation があります。

public IQueryable<User> Login(string username, string password)
{...}

これを呼び出そうとすると、パスワードハッシュに「+」文字が含まれている場合を除いて、すべて正常に機能します。この場合、空白文字に置き換えられているようです。

var pwd = CRQWKrKzCcQVnlhk2zl0j5QM+c5ujQGMv0XXnh4genI=
this.Context.BeginExecute<User>(new Uri(string.Format("/Login?username='{0}'&password='{1}'", username, pwd), UriKind.Relative), (ar) => { .. }, null);

Fiddlerでそれを取得すると、Request-Headerは問題ないように思えます...

GET /Service.svc/Login?username='xyz'&password='CRQWKrKzCcQVnlhk2zl0j5QM+c5ujQGMv0XXnh4genI=' HTTP/1.1

しかし、WebForms-Tab では、Password-QueryString に「+」の代わりに空白が既に含まれています。サーバーでデバッグしても同じ結果です...

「+」が置き換えられた理由を知っている人はいますか? 他に無効な文字はありますか? どうすればそれを回避できますか?

更新/編集:

驚くべきことに、次のクエリは期待どおりに機能します。

var query = (DataServiceQuery<User>) from c in this.Context.Users
                                             where
                                                 c.Username.Equals(username.ToLower()) &&
                                                 c.Password.Equals(Cryptography.ComputeSha256Hash(password + username.ToLower())) 
                                             select c;

前もって感謝します!

4

2 に答える 2

1

ヒントをくれた Mark Stafford に感謝します。私は今、この問題の解決策を持っています:

var pwd = Uri.EscapeDataString(Cryptography.ComputeSha256Hash(password + username.ToLower()));

クエリは次のようになります。

/GET Service.svc/Login?username='xyz'&password='CRQWKrKzCcQVnlhk2zl0j5QM%252Bc5ujQGMv0XXnh4genI%253D'

サーバーでは、同等のセキュリティ解除を行います。

var pwd = Uri.UnescapeDataString(password);

http://www.codebadger.com/blog/post/2010/08/10/Use-EscapeUriString-instead-of-UrlEncode-for-Silverlight.aspxを参照してください。

于 2012-07-13T11:24:58.963 に答える
1

URL のクエリ文字列部分は、適切にエンコードする必要があります。WCF DS クライアント LINQ プロバイダー (例: context.Users.Where(...)) への呼び出しは、クライアント側のスタックによって自動的にエンコードされます。を呼び出すとcontext.Execute、この方法で URL が変更されないため、その値を他のコードでエンコードする必要があります。

違いを確認するには、Visual Studio でこれを試してください。

using System;
using System.Data.Services.Client;
using System.Linq;

namespace Scratch
{
    public class Program
    {
        public static void Main()
        {
            var context = new DataServiceContext(new Uri("http://services.odata.org/OData/OData.svc/"));
            var query1 = context.CreateQuery<Category>("Categories").Where(c => c.Name == "abcd+efgh=ijlk");
            var query2 = context.Execute<Category>(new Uri("http://services.odata.org/OData/OData.svc/Categories()?$filter=Name eq 'abcd+efgh=ijlk'"));
            Console.WriteLine("context.Categories.Where(...): {0}", query1.ToString());
            Console.WriteLine("context.Execute<Category>(...): {0}", ((QueryOperationResponse)query2).Query.ToString());
        }
    }

    public class Category
    {
        public int ID { get; set; }
        public string Name { get; set; }
    }
}
于 2012-07-12T17:35:09.510 に答える