为什么我在使用ServiceStack客户端时从ServiceStack服务获得401响应

时间:2015-03-13 20:29:45

标签: servicestack

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

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

我注意到,在每次请求Web服务方法时,ith显示两个请求,第一个返回响应401,第二个返回200.

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

[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*);

请务必注意,我们只对网络服务方法进行一次调用,这两项请求都是此次调用的一部分

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

非常感谢提前

西蒙

1 个答案:

答案 0 :(得分:3)

第一个请求失败,因为它向受保护的服务发送了非经过身份验证的请求,因此服务正在使用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找到其他身份验证示例。