我们聘请了一名承包商,他正在为我们编写 iPhone 应用程序,我开始使用 ServiceStack 为其编写后端服务。
我在一般授权方面遇到了困难:使用什么样的授权以及如何实现它。
我对 ServiceStack、HTTP 和授权不太了解(还)..我读过this https://github.com/ServiceStack/ServiceStack/wiki/Authentication-and-authorization,但我可能仍然做错了什么。
我将使用现有旧数据库中的用户名和密码进行身份验证(但仅此 - 无需注册新用户,没有不同的权限。仅进行身份验证)。
所以我需要编写自己的提供者。
我已经成功地实现了一个工作CredentialsAuthProvider
在帮助下本教程 http://enehana.nohea.com/general/customizing-iauthprovider-for-servicestack-net-step-by-step/.
当我在浏览器中测试它时它有效:
- 致电我的服务并拨打 401
- POST to
auth/credentials
- 再次致电我的服务人员并得到正确的结果
然而,我注意到当我在 Fiddler 中尝试时,相同的工作流程不起作用。
邮寄至auth/credentials
作品。我发布这个:
POST http://localhost:52690/auth/credentials?format=json HTTP/1.1
User-Agent: Fiddler
Host: localhost:52690
Content-Length: 74
Content-Type: application/json; charset=utf-8
{
"UserName": "chspe",
"Password": "xyz",
"RememberMe": true
}
...并得到这个:
HTTP/1.1 200 OK
Server: ASP.NET Development Server/10.0.0.0
Date: Fri, 14 Jun 2013 13:07:35 GMT
X-AspNet-Version: 4.0.30319
X-Powered-By: ServiceStack/3,949 Win32NT/.NET
Set-Cookie: ss-id=3YUUgfwIeJd7PedFK5Th; path=/; HttpOnly
Set-Cookie: ss-pid=zQJ5Z4Vq7AY+BpVwbttj; expires=Tue, 14-Jun-2033 13:07:35 GMT; path=/; HttpOnly
Set-Cookie: ss-opt=perm; expires=Tue, 14-Jun-2033 13:07:35 GMT; path=/; HttpOnly
Set-Cookie: X-UAId=; expires=Tue, 14-Jun-2033 13:07:35 GMT; path=/; HttpOnly
Cache-Control: private
Content-Type: application/json; charset=utf-8
Content-Length: 75
Connection: Close
{"sessionId":"zQJ5Z4Vq7AY+BpVwbttj","userName":"chspe","responseStatus":{}}
在我看来很好。
但随后对我的实际服务的调用仍然返回 401:
GET http://localhost:52690/hello/world?format=json HTTP/1.1
User-Agent: Fiddler
Host: localhost:52690
Content-Length: 0
Content-Type: application/json; charset=utf-8
回复:
HTTP/1.1 401 Unauthorized
Server: ASP.NET Development Server/10.0.0.0
Date: Fri, 14 Jun 2013 13:07:44 GMT
X-AspNet-Version: 4.0.30319
WWW-Authenticate: credentials realm="/auth/credentials"
X-Powered-By: ServiceStack/3,949 Win32NT/.NET
Cache-Control: private
Content-Length: 0
Connection: Close
(这是HelloService
来自ServiceStack.Host.AspNet包 http://nuget.org/packages/ServiceStack.Host.AspNet/,我刚刚添加了[Authorize]
属性)
实际的请求是正确的,因为当我删除[Authorize]
属性。
我注意到CredentialsAuthProvider
似乎可以与cookie一起使用(有几个Set-Cookie: ...
第一个响应中的行)。
第一个问题:对于非浏览器的客户端来说,CredentialsAuthProvider 是否是正确的选择?
显然 Fiddler 无法识别 cookie,我怎么知道 iPhone 是否(或任何其他移动设备) would?
接下来,我尝试改用基本身份验证。
这是我的BasicAuthProvider
:
public class MyBasicAuthProvider : BasicAuthProvider
{
public override object Authenticate(IServiceBase authService, IAuthSession session, Auth request)
{
if (request.UserName == "MyUser")
{
return true;
}
}
}
但我很困惑 - 我什至无法从浏览器中使其正常工作。
当我在浏览器中加载服务的 URL 时,会弹出一个窗口,要求输入用户名和密码。
我输入正确的用户名并按 Enter,立即再次弹出相同的窗口。一次又一次……等等,无论我输入(正确的)数据的频率如何。
但是,我可以看到 ServiceStack 实际上使用了我的MyBasicAuthProvider
,因为当我在 Visual Studio 中设置断点时,我看到它识别用户名并返回True
.
第二个问题:我做错了什么?
我是否需要做更多的事情才能使用我自己的数据库进行基本身份验证?不是压倒一切的Authenticate
enough?