【问题标题】:ServiceStack authentication request failsServiceStack 认证请求失败
【发布时间】:2023-03-20 16:43:01
【问题描述】:

我正在尝试通过关注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

我不确定为什么 URL 不是 /json/auth/credentials 或者我可能做错了什么。有什么建议吗?


更新

跟踪堆栈中的事件链我发现了以下内容:

JsonDataContractSerializer.SerializeToStream 正确地将 Auth 请求序列化为 Json。但是,EndpointHandlerBase 传递给JsonDataContractDeserializerSystem.Net.HttpRequestStream 具有正确长度的流,其中填充了空值(零字节)。因此,传递给CredentialsAuthProvider.Authenticate 的请求对象的所有属性都为空。

HTTP 流如何去除其数据?

【问题讨论】:

    标签: asp.net-mvc authentication servicestack


    【解决方案1】:

    知道了!!!

    问题是我在TestAppHost.Configure 中添加了以下用于记录目的的预请求过滤器:

            PreRequestFilters.Add((httpReq, httpRes) =>
            {
                LastRequestBody = httpReq.GetRawBody();
            });
    

    here所见。

    GetRawBody() 方法读取请求 InputStream 时,会将其留在 EOS 状态,并且所有后续读取尝试均不返回任何内容。

    所以显然GetRawBody() 只能安全地用于缓冲流,但不幸的是它悄悄地导致了一个非常讨厌的错误,而不是在与非缓冲流一起使用时抛出异常。

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-26
    • 2017-11-22
    • 2020-06-20
    • 1970-01-01
    • 2013-09-30
    • 2022-09-27
    • 2014-07-26
    • 1970-01-01
    相关资源
    最近更新 更多