我有一个公开一组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#客户端来处理。但由于我不确定,我决定在这里问所有的大师。
可能这是一个愚蠢的问题,但显然我无法自己解决这个问题,所以任何帮助都会受到赞赏。
答案 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处理程序。
希望这有帮助。