現在、私は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.