使用ServiceStack使用REST Web服务时的用户身份validation
ServiceStack文档中有很多关于如何使用服务器端实现用户身份validation的示例。 但是如何在客户端设置用户凭据?
我使用ServiceStack来使用这样的JSON REST
服务:
var restClient = new JsonServiceClient (baseUri); var response = restClient.Get ("/some/service");
如何在请求中添加任何forms的身份validation? 我想要使用的Web服务使用OAuth 1.0
,但我也有兴趣添加自定义身份validation。
在我的代码中,我之前已经成功执行了OAuth令牌交换,因此我已经拥有了一个有效的访问令牌,现在需要使用此访问令牌及其token_secret
对每个REST请求进行token_secret
。
ServiceStack的AuthTests在使用ServiceStack服务客户端时显示不同的身份validation方式。 默认情况下,BasicAuth和DigestAuth内置于客户端中,例如:
var client = new JsonServiceClient(baseUri) { UserName = UserName, Password = Password, }; var request = new Secured { Name = "test" }; var response = client.Send(request);
在幕后,ServiceStack将尝试正常发送请求,但当请求被拒绝并被服务器质询时,客户端将自动重试相同的请求,但这次使用Basic / Digest Auth标头。
要在知道您正在访问安全服务时跳过额外的跃点,您可以告诉客户端始终发送BasicAuth标头:
client.AlwaysSendBasicAuthHeader = true;
validation的另一种方法是对Auth
服务进行显式调用(这需要启用CredentialsAuthProvider),例如:
var authResponse = client.Send(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(request);
成功调用Auth
服务后,客户端将进行身份validation,如果设置了RememberMe ,客户端将保留服务器在后续请求中添加的会话Cookie,这将使得来自该客户端的未来请求得到身份validation。
回答我自己,因为我已经找到了一个很好的方法来使用LocalHttpWebRequestFilter
中的JsonServiceClient
:
为了使用OAuth 1.0a保护Web服务,每个http请求都必须发送一个特殊的Authorization:
标头。 在此标头字段中,必须发送散列(签名),该散列使用请求的某些特征作为输入数据,如主机名,请求URL和其他 。
现在看来,在LocalHttpWebRequestFilter
http请求之前,ServiceStack会调用LocalHttpWebRequestFilter
,并公开底层的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 ("/my/service");
请注意,我使用Devdefined.OAuth库来完成CalculateSignature()
。 在上述服务调用之前,创建请求令牌,获取用户授权以及根据OAuth的要求交换访问令牌的请求令牌是在ServiceStack之外完成的。