使用ServiceStack和带有Windows身份验证的C#客户端进行服务调用会引发未经授权的异常

时间:2014-05-19 08:14:19

标签: c# rest servicestack windows-authentication

我有一个公开一组REST服务的服务器。我在WPF客户端中使用这些服务。所有这些都在Intranet中工作,最近我决定开启Windows身份验证(直到现在我使用的是不同形式的身份验证),因此我可以实现SSO。 当我启用IWA时,通过浏览器调用时,所有服务仍然可访问。问题是当我使用C#客户端(JsvServiceClient - ServiceStack类)调用它时,我得到了未经授权的异常。我正在使用Negotiate,因为我需要在服务器上使用Kerberos进行模拟/委派。

我自己的一些想法:

当我运行fiddler时,似乎在幕后,当浏览器发出第一个请求时它也会收到未经授权的许可,但在此之后它会发送另一个请求授权:Negotiate ygMDAuBgorBgEEAYI3AgIKB(这个令牌更长,我已经缩短了标题中的简单说明。这样做会导致再次未经授权。之后发送第三个请求,该请求再次具有授权:标头中的协商(但之后具有不同的令牌)。这次请求被授权并显示数据。

我知道身份验证,授权,缓存等在SS中是如何工作的,但问题是服务器上没有代码被调用(使用JsvServiceClient时)。我创建了一个HttpModule并将其添加到Web配置中仅用于调试目的。在引发Unathorized之后立即触发HttpApplication.AuthenticateRequest。显然,这个级别的调用被拒绝了,因为SS主要是HttpHandlers一起工作,所以没有触发任何服务器代码(根本没有到达处理程序)。

浏览器可能会自己执行一些处理WindowsAuth(某种握手或某种握手)的逻辑,而且这种逻辑不能使用SS中的C#客户端来处理。但由于我不确定,我决定在这里问所有的大师。

可能这是一个愚蠢的问题,但显然我无法自己解决这个问题,所以任何帮助都会受到赞赏。

1 个答案:

答案 0 :(得分:3)

通过向客户端添加RequestFilter,您可以将凭据设置为当前登录用户,就像浏览器为您所做的那样。

有关详细信息,请参阅CredentialCache.DefaultCredentials

JsvServiceClient client = new JsvServiceClient("https://host:port/");
...
client.RequestFilter = req => {
    req.Credentials = CredentialCache.DefaultCredentials;
};

解决您的具体问题:

  

浏览器可能会自己执行一些处理WindowsAuth(某种握手或某种握手)的逻辑,并且不会使用SS中的C#客户端处理此逻辑。

是的,从Intranet区域访问时,浏览器会自行处理Windows身份验证。但是,ServiceStack客户端HttpWebRequest中的基础JsvServiceClient将需要配置为发送凭据,如上所示

  

我知道身份验证,授权,缓存等在SS中是如何工作的,但问题是在服务器上没有代码被调用

IIS提供Windows身份验证层,而不是ServiceStack,因此在Windows身份验证成功之前,不会调用ServiceStack服务中的代码。只有这样,请求才会传递给ServiceStack处理程序。

希望这有帮助。