我正在尝试通过this tutorial跟我的ServiceStack服务设置身份验证。
我的服务使用[Authenticate]
属性进行修饰。
我的AppHost看起来像这样:
public class TestAppHost : AppHostHttpListenerBase
{
public TestAppHost() : base("TestService", typeof(TestService).Assembly) { }
public static void ConfigureAppHost(IAppHost host, Container container)
{
try
{
// Set JSON web services to return idiomatic JSON camelCase properties.
ServiceStack.Text.JsConfig.EmitCamelCaseNames = true;
// Configure the IOC container
IoC.Configure(container);
// Configure ServiceStack authentication to use our custom authentication providers.
var appSettings = new AppSettings();
host.Plugins.Add(new AuthFeature(() =>
new AuthUserSession(), // use ServiceStack's session class but fill it with our own data using our own auth service provider
new IAuthProvider[] {
new UserCredentialsAuthProvider(appSettings)
}));
}
}
其中UserCredentialsAuthProvider
是我的自定义凭据提供程序:
public class UserCredentialsAuthProvider : CredentialsAuthProvider
{
public override bool TryAuthenticate(IServiceBase authService, string userName, string password)
{
try
{
// Authenticate the user.
var userRepo = authService.TryResolve<IUserRepository>();
var user = userRepo.Authenticate(userName, password);
// Populate session properties.
var session = authService.GetSession();
session.IsAuthenticated = true;
session.CreatedAt = DateTime.UtcNow;
session.DisplayName = user.FullName;
session.UserAuthName = session.UserName = user.Username;
session.UserAuthId = user.ID.ToString();
}
catch (Exception ex)
{
// ... Log exception ...
return false;
}
return true;
}
}
在我的用户测试中,我在http://127.0.0.1:8888
初始化并启动我的TestAppHost,然后使用JsonServiceClient对服务进行身份验证,如下所示:
var client = new JsonServiceClient("http://127.0.0.1:8888/")
var response = client.Send<AuthResponse>(new Auth
{
provider = UserCredentialsAuthProvider.Name,
UserName = username,
Password = password,
RememberMe = true
});
但是得到以下异常:
The remote server returned an error: (400) Bad Request.
at System.Net.HttpWebRequest.GetResponse()
at ServiceStack.ServiceClient.Web.ServiceClientBase.Send[TResponse](Object request)...
ServiceStack.ServiceInterface.Auth.Auth
请求包含正确的用户名和密码,请求发布到:
http://127.0.0.1:8888/json/syncreply/Auth
我不确定为什么网址不是/json/auth/credentials
或我可能做错了什么。有什么建议吗?
<小时/> 的更新
在堆栈中追踪事件链我发现了以下内容:
JsonDataContractSerializer.SerializeToStream
正确地将Auth请求序列化为Json。但是,通过System.Net.HttpRequestStream
传递给JsonDataContractDeserializer
的{{1}}具有正确长度的流,其中填充了空值(零字节)。因此,传递给EndpointHandlerBase
的请求对象在其所有属性中都为空。
如何删除HTTP流的数据?
答案 0 :(得分:1)
得到了!!!
问题是我在TestAppHost.Configure
中为日志记录添加了以下预请求过滤器:
PreRequestFilters.Add((httpReq, httpRes) =>
{
LastRequestBody = httpReq.GetRawBody();
});
见here。
当GetRawBody()
方法读取请求InputStream时,它将其保留为EOS状态,并且所有后续读取尝试都不返回任何内容。
所以很明显GetRawBody()
只能安全地与缓冲流一起使用,但不幸的是它会悄悄地导致一个非常讨厌的错误,而不是在与非缓冲流一起使用时抛出异常。