3

我正在使用 Silverlight 5 通过 JsonServiceClient 使用 ServiceStack REST 服务,现在可以了。

此时,我可以登录/注销托管在 Asp.Net 中路径 /api 的 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 server/api/auth/GetUser?)时,服务器是否可以重新发送 cookie/会话?

编辑

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

// 组装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 ,则将 Silverlight 的 WebClient 中的 Cookie 设置到浏览器。

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

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

我想如果在客户端,我向 AuthService 发送一个空的 GET 并且服务验证 cookie、会话并自动向 JsonServiceClient 返回一个响应,表明用户已通过身份验证。

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

4

1 回答 1

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;
}
于 2012-10-21T17:48:25.290 回答