6

現在、私はServiceStackとその認証と承認のサポートで遊んでいます。

Use Cases プロジェクトCustomAuthenticationMvc(Web サービスHostアプリ)に取り組み、認証がどのように機能するかを理解しようとしているときに、次のことを行いました。

public class AppHost : AppHostBase
{
    public AppHost() : base("Basic Authentication Example",
                                                        typeof(AppHost).Assembly) { }

    public override void Configure(Container container)
    {
        // register storage for user sessions 
        container.Register<ICacheClient>(new MemoryCacheClient());
        container.Register<ISessionFactory>(c => new SessionFactory(
                                            c.Resolve<ICacheClient>()));

        //Register AuthFeature with custom user session and Basic auth provider
        Plugins.Add(new AuthFeature(
            () => new CustomUserSession(),
            new AuthProvider[] { new BasicAuthProvider() }
        ) );

        var userRep = new InMemoryAuthRepository();
        container.Register<IUserAuthRepository>(userRep);

        //Add a user for testing purposes
        string hash;
        string salt;
        new SaltedHash().GetHashAndSaltString("test", out hash, out salt);
        userRep.CreateUserAuth(new UserAuth
        {
            Id = 1,
            DisplayName = "DisplayName",
            Email = "as@if.com",
            UserName = "john",
            FirstName = "FirstName",
            LastName = "LastName",
            PasswordHash = hash,
            Salt = salt,
        }, "test");
    }
}

[Authenticate]サービスの実装は、Request DTO のすぐ上に属性が適用された有名な Hello World のものです...

[Authenticate]
[Route("/hello")]
[Route("/hello/{Name}")]
public class HelloRequest : IReturn<HelloResponse>
{
    public string Name { get; set; }
}

public class HelloResponse
{
    public string Result { get; set; }
}

public class HelloService : IService<HelloRequest>
{
    public object Execute(HelloRequest request)
    {
        return new HelloResponse
        {
            Result = "Hello, " + request.Name
        };
    }
}

コンソール アプリケーションを として使用するとClient、次のコードが得られます。

static void Main(string[] args)
{   
    // The host ASP.NET MVC is working OK! When I visit this URL I see the
    // metadata page.
    const string BaseUrl = "http://localhost:8088/api";

    var restClient = new JsonServiceClient(BaseUrl);

    restClient.SetCredentials("john", "test");

    HelloResponse response = restClient.Get<HelloResponse>("/hello/Leniel");

    Console.WriteLine(response.Result);
}

ここでの問題は、Web サービス呼び出しが例外をスローしているrestClient.SetCredentials("john", "test");ため、期待どおりに機能していないと思うことです。restClient.Get<HelloResponse>("/hello/Leniel");ログインページにリダイレクトされているのがわかります... 資格情報を設定して、Web サービスを呼び出しても問題ないと思いました。ここではそうではありません。

私は何を間違っていますか?ユーザーが単純なダイアログ ウィンドウにユーザー名とパスワードを入力する MonoTouch iOS アプリからこの Web サービスを呼び出す予定ですが、これを行う前に、この単純なコンソール アプリで動作させたいと考えています。

編集1

このコードを試して認証リクエストを送信しました(このスレッドで見られるように):

var authResponse = restClient.Send<AuthResponse>(new Auth
{
    UserName = "john", 
    Password = "test",
    RememberMe = true, 
});

ただし、例外がスローされます。

タイプ定義は「{」で始まる必要があります。シリアル化されたタイプ「AuthResponse」が必要です。取得した文字列は次で始まります:

<head>

デフォルトの ASP.NET MVCLoginページにリダイレクトされ続けるため、サービスの構成が間違っているようです (下の Fiddler のスクリーンショットを参照)。AuthFeatureまた、登録パスnullを に変更しましたHtmlRedirect

//Register AuthFeature with custom user session and Basic auth provider
Plugins.Add(new AuthFeature(
    () => new CustomUserSession(),
    new AuthProvider[] { new BasicAuthProvider() }
) {  HtmlRedirect = null });

編集2

ここで説明されているように、 Fiddlerで遊んで、Authorization リクエスト ヘッダーを追加しようとしました。

ここに画像の説明を入力

Fiddler の Auth インスペクタを見ると、次のことがわかります。

Authorization Header is present: Basic am9objp0ZXN0
Decoded Username:Password= john:test

では、なぜ 401 無許可ステータスになるのでしょうか? テスト目的でメモリ内にユーザーを設定した場合、それは機能するはずではありませんか?

サンプル コンソール アプリでリクエスト ヘッダーを渡すにはどうすればよいですか?

コンソール アプリで行う場合:

restClient.AlwaysSendBasicAuthHeader = true;

401 無許可の応答が返ってきました...

編集3

desunit の回答とコードの追加の助けを借りて、コンソール アプリの認証を次のコードで機能させることができました。

class Program
{
    const string BaseUrl = "http://localhost:8088/api";

    static void Main(string[] args)
    {
        var restClient = new JsonServiceClient(BaseUrl);

        restClient.SetCredentials("john", "test");

        restClient.AlwaysSendBasicAuthHeader = true;

        HelloResponse response = restClient.Get<HelloResponse>("/hello/Leniel");

        Console.WriteLine(response.Result);
    }
}

//Response DTO
//Follows naming convention
public class HelloResponse
{
    public string Result { get; set; }
}

次のことを知りたいです: コンソール アプリでは、常に Basic Auth ヘッダーを送信する必要がありますか? その行を削除すると、認証が失敗するだけで、HelloResponse.

4

1 に答える 1

4

この問題は、ServiceStack 自体には関連していませんが、ASP.NET Web が 401 エラー コードを処理する方法に関連しています。IHttpModuleログインフォームへのリダイレクトを抑制するカスタムで回避できます。この問題の詳細については、こちらを参照してください

これは非常に一般的な問題であるため、可能な解決策を示すためにプロジェクトを更新しました。 CustomAuthenticationMvc

于 2012-11-27T09:48:48.060 に答える