我花了几天时间试图掌握ServiceStack,看起来很棒。唯一的问题是认证,这似乎是很多摩擦,努力工作和眼泪。
我希望MonoTouch注册用户,针对ServiceStack进行身份验证/针对OAuth进行身份验证,并且通常在进行身份验证时最大限度地减少对数据库的调用。
到目前为止,我已经得到了这个:
var client = new JsonServiceClient(newbaseUri);
// register a new user:
var registration = new Registration {
FirstName = "john"
UserName = "user" ,
Password = "pass",
Email = "john@john.com",
};
var registerResponse = client.Send<RegistrationResponse>(registration);
--------------------------------
// user registered...later on I authenticate:
var authResponse = client.Send<AuthResponse>(new Auth {
UserName = "user",
Password = "pass",
RememberMe = true
});
var authResponse = clientlogin.Send<AuthResponse>(auth);
--------------------------------
// somehow I need to store 'authresponse' for later calls, not sure how without a browser
// tried manually setting the cookies and credentials parameters later but no joy
// but now I need to call a secured ([Authenticate] decorated) service method:
var client = new JsonServiceClient(newbaseUri);
var response = client.Send<HelloResponse>(new Hello { Name = "World!" });
return response.Result;
-----------------------------------------
// heres the configuration
var appSettings = new AppSettings();
//Default route: /auth/{provider}
Plugins.Add(new AuthFeature(() => new CustomUserSession(),
new IAuthProvider[] {
new CredentialsAuthProvider(appSettings), // never seems to get called
//new FacebookAuthProvider(appSettings), // not sure how to get this to work on monotouch
//new TwitterAuthProvider(appSettings), // same issue as facebook
new BasicAuthProvider(appSettings) // works but what about caching/tokens/cookies?
}));
//Default route: /register
Plugins.Add(new RegistrationFeature()); // how do i send extra params to this as created in mongodb collection
var mongoClient = new MongoClient("mongodb://localhost");
var server = mongoClient.GetServer();
var db = server.GetDatabase("users");
container.Register<ICacheClient>(new MemoryCacheClient());
container.Register<IUserAuthRepository>(new MongoDBAuthRepository(db, true));
我的问题是:
1)如何启用额外字段以及注册(因为mongodb [Servicestack.Authentication.Mongodb]有很多空字段,例如生日,第一行,城市,时区等),这些字段不存在于ServiceStack.Common.ServiceClient.Web.Registration对象?
2)如何将'authresponse'中发送的cookie(甚至可能是令牌系统)传输到后续调用,以便允许ServiceStack与会话进行匹配以进行持续身份验证,而不是更多正在进行的数据库调用问题是'基本身份验证'方法(即在服务器端没有调用CredentialsAuthProvider)?
请帮助......我已经阅读了文档,运行测试,检查了社交引导程序,现在我正在认真地失去了几天的时间,并且考虑将SS与简单的成员集成,甚至完全抛弃ServiceStack用于旧的skool soap / wcf通过它的外观更容易实现:(
答案 0 :(得分:3)
1)如果您想使用注册插件,我不认为您可以添加其他字段,因为已经定义了注册请求/类。您可以创建自己的注册服务并调用RegistrationService / Plugin。此外,this post可能会有所帮助。
[Route("/myregistration")]
public class MyRegistration : Registration //Add Additional fields for registration
{
public DateTime? BirthDate { get; set; }
public string Gender { get; set; }
}
public class MyRegisterService : Service
{
public IUserAuthRepository UserAuthRepo { get; set; }
public object Post(MyRegistration request)
{
using (var registrationService = base.ResolveService<RegistrationService>())
{
//handle the registration
var response = registrationService.Post(request.TranslateTo<Registration>());
}
//save the additional data
var userAuth = request.TranslateTo<UserAuth>();
UserAuthRepo.SaveUserAuth(userAuth);
//can make your own response or grab response from RegistrationService above
return new MyRegistrationResponse();
}
}
2)您可以验证您的JsonServiceClient并重复使用它来发出多个请求。
var client = new JsonServiceClient(newbaseUri);
var authResponse = client.Send<AuthResponse>(new Auth {
UserName = "user",
Password = "pass",
RememberMe = true
}); //if successful your 'client' will have a populated CookieContainer with 'ss-id' and 'ss-pid' values
//reusing 'client' (after successful authentication) to make a request
//to a service requiring authentication
var response = client.Send<HelloResponse>(new Hello { Name = "World!" });
如果重复使用您的客户&#39;不是您可以尝试存储ss-id的选项。我不太了解MonoTouch以及它如何存储浏览器会话&#39;所以我不确定你会怎么做到这一点。在验证并存储ss-id之后,您可以使用请求过滤器将其添加到客户端
//Get ss-id value
foreach(Cookie cookie in previousAuthenticatedClient.GetCookies(new Uri(newbaseUri)))
{
if (cookie.Name == "ss-id")
{
//store ss-id
}
}
var newClient = new JsonServiceClient(newbaseUri)
{
LocalHttpWebRequestFilter = (req) =>
{
req.CookieContainer.Add(new Uri("http://localhost:56006"), new System.Net.Cookie("ss-id", ssId));
}
};