1

我花了几天时间试图掌握 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 与 simplemembership 集成,甚至完全抛弃 ServiceStack 以获得旧的 skool soap/wcf,这要容易得多通过它的外观来实现:(

4

1 回答 1

3

1)如果您想使用注册插件,我认为您不能添加其他字段,因为注册请求/类已经定义。您可以制作自己的注册服务并调用 RegistrationService/Plugin。此外,这篇文章可能会有所帮助。

[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!" });

如果不能重用“客户端”,您可以尝试存储 ss-id。我不太了解 MonoTouch 以及它如何存储“浏览器会话”,因此我不确定您将如何完成此操作。验证并存储 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));
        }
};
于 2013-04-01T06:34:59.380 回答