使用ServiceStack使用REST Web服务时的用户身份验证

Dyn*_*lon 9 c# authentication json web-services servicestack

ServiceStack文档都充满了关于如何使用示例服务器端实现用户的认证.但是如何在客户端设置用户凭据?

我使用ServiceStack来使用这样的JSON REST服务:

var restClient = new JsonServiceClient (baseUri);
var response = restClient.Get<MyResponse> ("/some/service");
Run Code Online (Sandbox Code Playgroud)

如何在请求中添加任何形式的身份验证?我想要使​​用的Web服务使用OAuth 1.0,但我也有兴趣添加自定义身份验证.

在我的代码中,我之前已经成功执行了OAuth令牌交换,因此我已经拥有了一个有效的访问令牌,并且现在需要使用此访问令牌及其来签署每个REST请求token_secret.

myt*_*thz 8

ServiceStack的AuthTests在使用ServiceStack服务客户端时显示不同的身份验证方式.默认情况下,BasicAuth和DigestAuth内置于客户端,例如:

var client = new JsonServiceClient(baseUri) {
    UserName = UserName,
    Password = Password,
};

var request = new Secured { Name = "test" };
var response = client.Send<SecureResponse>(request);    
Run Code Online (Sandbox Code Playgroud)

在幕后,ServiceStack将尝试正常发送请求,但当请求被拒绝并被服务器质询时,客户端将自动重试相同的请求,但这次使用Basic/Digest Auth标头.

要在知道您正在访问安全服务时跳过额外的跃点,您可以告诉客户端始终发送BasicAuth标头:

client.AlwaysSendBasicAuthHeader = true;
Run Code Online (Sandbox Code Playgroud)

验证的另一种方法是对服务进行显式调用Auth(这需要启用CredentialsAuthProvider),例如:

var authResponse = client.Send<AuthResponse>(new Auth {
    provider = CredentialsAuthProvider.Name,
    UserName = "user",
    Password = "p@55word",
    RememberMe = true,  //important tell client to retain permanent cookies
});

var request = new Secured { Name = "test" };
var response = client.Send<SecureResponse>(request);    
Run Code Online (Sandbox Code Playgroud)

成功调用Auth服务后,客户端将进行身份验证,如果设置了RememberMe,客户端将保留服务器在后续请求中添加的会话Cookie,这将使来自该客户端的未来请求得到身份验证.


Dyn*_*lon 7

回答我自己,因为我已经找到了一个很好的方法来使用LocalHttpWebRequestFilter钩子JsonServiceClient:

为了使用OAuth 1.0a保护Web服务,每个http请求都必须发送一个特殊的Authorization:标头.在此标头字段中,必须发送散列(签名),该散列使用请求的某些特征作为输入数据,如主机名,请求URL和其他.

现在似乎LocalHttpWebRequestFilter是在发出http请求之前由ServiceStack调用,并公开底层HttpWebRequest对象,其中可以添加额外的头并访问请求的必需字段.

所以我的解决方案基本上是:

var client = new JsonServiceClient (baseUri);

client.LocalHttpWebRequestFilter += (request) => {
    // compute signature using request and a previously obtained
    //  access token 
    string authorization_header = CalculateSignature (request, access_token);

    request.Headers.Add ("Authorization", authorization_header);
};
var response = client.Get<MySecuredResponse> ("/my/service");
Run Code Online (Sandbox Code Playgroud)

请注意,我使用Devdefined.OAuth库来完成所有繁重的工作CalculateSignature().在上述服务调用之前,创建请求令牌,获取用户授权以及根据OAuth的要求交换访问令牌的请求令牌是在ServiceStack之外完成的.