【问题标题】:Why am I getting 401 responses from my ServiceStack Services when using ServiceStack client为什么在使用 ServiceStack 客户端时,我的 ServiceStack 服务会收到 401 响应
【发布时间】:2015-03-14 19:34:45
【问题描述】:

我已经开发了一组 ServiceStack Web 服务,这些服务已经运行了几个月,主要来自使用 ServiceStack 客户端库的 WPF 应用程序。

由于与其他开发人员的服务出现了一些其他问题,我决定查看现有 WPF 应用程序与使用 Fiddler 的服务之间的请求和响应。

我注意到在对 Web 服务方法的每个请求上,都会显示两个请求,第一个返回响应 401,第二个返回 200。

我们所有的 Web 服务方法都设置为使用“任何”功能,允许来自客户端的任何动词 - 即 -

[Authenticate]
public object Any(DriverQuery request)
{
    var driver = DriverRepository.GetDriver<DriverEntity>(request.DriverUserId);
    return new DriverResponse { Driver = driver };
}

客户端只使用 JsonServiceClient.Send 方法 - 即

var response = client.Send(new DriverQuery { DriverUserId = driverUserId });

我们正在使用基本身份验证。

我担心为什么会发生这种情况,这是否正常,如果不正常,我做错了什么?

根据要求提供其他信息

返回 401 响应的请求:-

POST http://www.*******.uk/Api/jsv/reply/ClientsQuery HTTP/1.1
Accept: application/jsv
LoggedOnUserNameHeader: ******
User-Agent: ServiceStack .NET Client 4.038
Accept-Encoding: gzip,deflate
Content-Type: application/jsv
Host: dev.carbenefitsolutionstest.uk
Content-Length: 2
Expect: 100-continue

{}

401 响应

HTTP/1.1 401 Unauthorized
Cache-Control: private
Vary: Accept
Server: Microsoft-IIS/8.5
WWW-Authenticate: basic realm="/auth/basic"
X-Powered-By: ServiceStack/4.038 Win32NT/.NET
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS
Access-Control-Allow-Headers: Access-Control-Allow-Origin, Authorization, Content-Type
X-AspNet-Version: 4.0.30319
Set-Cookie: ss-id=5JfAHCT3axaUqDA9eQTA; path=/; HttpOnly
Set-Cookie: ss-pid=yEGg9GfCSbwLZKL4RYsi; expires=Wed, 14-Mar-2035 08:47:48 GMT; path=/; HttpOnly
X-Powered-By: ASP.NET
Date: Sat, 14 Mar 2015 08:47:48 GMT
Content-Length: 0

返回 200 响应的请求:-

POST http://www.*******.uk/Api/jsv/reply/ClientsQuery HTTP/1.1
Accept: application/jsv
LoggedOnUserNameHeader: *******
User-Agent: ServiceStack .NET Client 4.038
Accept-Encoding: gzip,deflate
Content-Type: application/jsv
Host: dev.carbenefitsolutionstest.uk
Cookie: ss-id=5JfAHCT3axaUqDA9eQTA; ss-pid=yEGg9GfCSbwLZKL4RYsi
Authorization: Basic d2Vic2VydmljZTpzdDNybDFuZw==
Content-Length: 2
Expect: 100-continue

{}

200 响应

HTTP/1.1 200 OK
Cache-Control: private
Content-Type: application/jsv
Vary: Accept
Server: Microsoft-IIS/8.5
X-Powered-By: ServiceStack/4.038 Win32NT/.NET
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS
Access-Control-Allow-Headers: Access-Control-Allow-Origin, Authorization, Content-Type
X-AspNet-Version: 4.0.30319
Set-Cookie: X-UAId=1; expires=Wed, 14-Mar-2035 08:47:48 GMT; path=/; HttpOnly
X-Powered-By: ASP.NET
Date: Sat, 14 Mar 2015 08:47:48 GMT
Content-Length: 78618

我创建了一个派生自 ServiceStack JsvServiceClient 的基类,它负责提供身份验证信息。代码如下所示。

public abstract class BaseServiceClient : JsvServiceClient
{
    protected BaseServiceClient(string baseUri, TimeSpan serviceTimeout, string currentUserName)
        : base(baseUri)
    {
        Headers.Add(CustomHeaders.LoggedOnUserNameHeader, currentUserName);
        UserName = WebServiceSecurity.GetMasterUsername();
        Password = WebServiceSecurity.GetMasterPassword();
        Timeout = serviceTimeout;
    }
}

服务认证配置代码

Plugins.Add(new AuthFeature(() => new AuthUserSession(), new IAuthProvider[] {new BasicAuthProvider()}));
    var userRepository = new InMemoryAuthRepository();
    container.Register<IUserAuthRepository>(userRepository);

    string hash;
    string salt;

    new SaltedHash().GetHashAndSaltString(WebServiceSecurity.GetMasterPassword(), out hash, out salt);
userRepository.CreateUserAuth(new UserAuth
{
    Id = 1,
    UserName = *UserName*,
    PasswordHash = ******,
    Salt = ******,
    Roles = new List<string> { *Role* },
}, *Password*);

请务必注意,我们只对 Web 服务方法进行一次调用,并且这两个请求都作为该单一调用的一部分产生

如果有人可以协助或确认这是正常行为,将不胜感激。

在此先感谢

西蒙

【问题讨论】:

  • 请更新您的问题以包括来自 Fiddler 的原始 HTTP 请求/响应以及您的 AuthFeature 注册,以显示您如何注册 BasicAuth。还有用于配置JsonServiceClient 的代码(省略任何密码)。
  • 嗨 - 道歉 - 根据要求提供更多信息。非常感谢。西蒙

标签: servicestack


【解决方案1】:

第一个请求失败,因为它正在向受保护的服务发送未经身份验证的请求,因此服务正确响应 401 UnAuthenticated 来表明这一点。错误响应还表明该服务支持带有WWW-Authenticate: basic realm="/auth/basic" 响应标头的HTTP Basic Auth

当发出后续请求时,它包含基本身份验证信息,可以在 HTTP 标头Authorization: Basic d2Vic2VydmljZTpzdDNybDFuZw== 中看到,因为它包含有效的用户名/密码,然后成功。

您可以通过始终随每个请求发送基本身份验证信息来跳过初始未经身份验证的请求和身份验证挑战响应。

您可以设置AlwaysSendBasicAuthHeader 属性以指示ServiceStack's ServiceClients 始终随每个请求发送基本身份验证信息,例如:

client.AlwaysSendBasicAuthHeader = true;

您可以在 ServiceClients AuthTests.cs 中找到使用 ServiceStack ServiceClients 的其他身份验证示例。

【讨论】:

  • 您好,很抱歉回复延迟 - 我只是有时间测试此更改。它工作得很好。非常感谢您的帮助。非常感谢。西蒙
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-09-23
相关资源
最近更新 更多