如何使用Service Stack AuthService的cookie / session在客户端上加载经过身份验证的用户?

时间:2012-06-18 16:16:24

标签: rest silverlight-5.0 servicestack

我正在使用Silverlight 5来使用JsonServiceClient使用ServiceStack REST服务,现在没问题。

此时,我可以在/ api路径的Asp.Net中登录/注销ServiceStack。

但是在我登录后,如果用户刷新浏览器托管Silverlight的当前页面,则会重新加载Silverlight应用程序并且会话/ cookie信息消失,从而迫使用户再次登录/密码。这是一种不受欢迎的行为。

在服务器端,我正在使用Default CredentialsProvider:

var appSettings = new AppSettings();
var credentialsProvuder = new CredentialsAuthProvider(appSettings);

//Default route: /auth/{provider}
Plugins.Add(new AuthFeature(() => new CustomUserSession(),
new IAuthProvider[] { credentialsProvuder }));

在客户端上,我设置了RememberMe = true:

    public static void TryLogin(string userName, string password, bool rememberMe, Action<AuthResponse, Exception> callBack)
    {
        AuthDto.UserName = userName;
        AuthDto.Password = password;
        AuthDto.RememberMe = rememberMe;
        Client.SendAsync<AuthResponse>(AuthDto, r => TryLoginResponse(callBack, r, null),
                         (r, e) => TryLoginResponse(callBack, r, e));
    }

要测试服务,我使用的是NuGet模板提供的默认Hello服务。此外,我在类上放置了[Authenticate]属性,它工作正常(该服务仅在我登录后才会自动化)。

检查JsonServiceClient的源代码,发现CookieContainer是在第一次请求之后创建的。

我试图对服务器进行虚拟调用,以便查看服务器是否将信息重新发送到浏览器,因此JsonServiceClient使用经过身份验证的用户信息填充cookiecontainer,但没有成功。

我的问题是:如何在客户端上再次进行身份验证,因为它之前已经过身份验证?当我调用某个方法(HTTP GET服务器/ api / auth / GetUser?)时,有没有办法让服务器重新发送cookie /会话?

修改

经过一段时间检查AsyncServiceClient类的源代码,我发现:

// Assembly ServiceStack.Common.3.8.3 \ lib \ sl5 \ ServiceStack.Common.dll

  HttpWebRequest webRequest = (HttpWebRequest) (this.UseBrowserHttpHandling ? WebRequestCreator.BrowserHttp : WebRequestCreator.ClientHttp).Create(new Uri(uriString));
  if (this.StoreCookies && !this.UseBrowserHttpHandling)
  {
    if (this.ShareCookiesWithBrowser)
    {
      if (this.CookieContainer == null)
        this.CookieContainer = new CookieContainer();
      this.CookieContainer.SetCookies(new Uri(this.BaseUri), HtmlPage.Document.Cookies);
    }
    webRequest.CookieContainer = this.CookieContainer;
  }    

如上面的代码中所示,AsyncServiceClient在每个请求之前检查CookieContainer,如果它为null,则将Cookies从Silverlight的WebClient设置为浏览器。

好的,现在我们可以使用cookies,因为我确信它们是从客户端发送到浏览器的。

那么,如何在不重新发送用户名和密码的情况下根据现有的X-UAId重新验证用户?

我想如果在客户端,我发送一个空的GET到AuthService和服务验证cookie,会话并自动向JsonServiceClient返回一个响应,指示用户已经过身份验证。

我想要的是类似于向服务器发出请求的WCF Ria Services“WebContext.Current.Authentication.LoadUser()”,如果服务器上的用户经过身份验证,则返回当前用户。

1 个答案:

答案 0 :(得分:3)

这可能有点晚了,但我遇到了同样的问题,问题出在AsyncServiceClient中。当身份验证失败时,客户端会发送另一个添加了BasicAuthentication头的请求。但是,当在此行中创建第二个请求时

https://github.com/ServiceStack/ServiceStack/blob/master/src/ServiceStack.Common/ServiceClient.Web/AsyncServiceClient.cs#L405

然后没有设置CookieStore,因此当服务器响应时不会存储cookie。在上面的一行之后,将其放入:

if (StoreCookies)
{
    requestState.WebRequest.CookieContainer = CookieContainer;
}