使用显式网络凭据从 .Net Core API 调用 SSO-Enabled API
Calling SSO-Enabled API From .Net Core API Using Explicit Network Credentials
我正在将 WinForms 应用程序迁移到 .Net Core (3.1) API,我 运行 遇到了调用 SSO-protected 的功能的问题API 在我们的网络中。
在 WinForms 应用程序中,我有以下内容:
public async void Authenticate()
{
var wi = System.Security.Principal.WindowsIdentity.GetCurrent();
var wic = wi.Impersonate();
try
{
// Initial request to grab cookies and redirect endpoint
var apiEndPoint = $"https://{_host}{_apiPath}";
var cookieRedirectRequest = new HttpRequestMessage(HttpMethod.Get, apiEndPoint);
var response = await _httpClient.SendAsync(cookieRedirectRequest);
if (response != null)
{
var cookieContainer = new CookieContainer();
foreach (var cookie in response.Headers.GetValues("Set-Cookie"))
{
var parsedCookie = cookie.ToCookie();
parsedCookie.Domain = TARGET_DOMAIN;
cookieContainer.Add(parsedCookie);
}
var redirectURL = response.Headers.GetValues("Location").FirstOrDefault();
// Add the cookies to the client to continue the authentication
_httpClient = new HttpClient(new HttpClientHandler()
{
UseDefaultCredentials = true,
AllowAutoRedirect = true,
ClientCertificateOptions = ClientCertificateOption.Automatic,
UseCookies = true,
CookieContainer = cookieContainer
});
// Second request to grab code and state values
var codeAndStateRequest = new HttpRequestMessage(HttpMethod.Get, redirectURL);
response = await _httpClient.SendAsync(codeAndStateRequest);
...
对 API 的初始调用将我们重定向到 SSO-authentication 页面。我使用该初始响应中的 cookie 创建我自己的请求,以便我可以传递正确的凭据并取回适当的 SSO 令牌(在最后一行 returns 返回令牌的 SendSync 调用的响应),这然后,我用于对 API.
的未来请求进行身份验证
我正在尝试使用服务帐户在 .NET Core 中重新创建此功能,而不是进行 WindowsIdentity 模拟,我正在尝试显式设置我的 HttpClientHandler 的 NetworkCredentials 属性:
handler = new HttpClientHandler()
{
UseDefaultCredentials = false,
Credentials = new NetworkCredential("svc_acct_username", "svc_act_pass", "mydomain"),
AllowAutoRedirect = true,
ClientCertificateOptions = ClientCertificateOption.Automatic,
UseCookies = true,
CookieContainer = cookieContainer,
};
但是,我从第二个请求中得到的响应是 401。
这与我以前在原始应用程序中得到的结果一致——我最初会得到一个带有“WWW-Authenticate: Negotiate”header 的 401,但随后会有一个自动传入网络凭据的后续请求,我会得到 200。我没有收到带有 .Net Core 中的凭据的第二个请求。
我尝试了此处建议的凭据缓存解决方案:
https://github.com/dotnet/runtime/issues/24490
但这并没有奏效。
提前感谢你们能给我的任何帮助。我卡住了!
快速编辑:
通过简单地显式设置 HttpClientHandler 的 Credentials 属性 并设置 UseDefaultCredentials = false,我可以在我的 WinForms 应用程序中重新创建 .Net Core 行为。因此,通过设置 UseDefaultCredentials 会发生一些神奇的事情,在使用显式凭据时似乎无法重新创建。
我在 co-worker 的帮助下完成了这项工作!问题是,当您使用显式网络凭据时,您会丢失“协商”身份验证类型,这是我们的 SSO-endpoint 所要求的。通过使用 CredentialCache 对象并显式设置协商 auth-type,调用有效!
var credCache = new CredentialCache { { new Uri("https://example.com"), "Negotiate", new NetworkCredential("svc_acct_user", "svc_acct_password", "mydomain") } };
// Add the cookies to the client to continue the authentication
handler = new HttpClientHandler()
{
UseDefaultCredentials = false,
Credentials = credCache,
AllowAutoRedirect = true,
ClientCertificateOptions = ClientCertificateOption.Automatic,
UseCookies = true,
CookieContainer = cookieContainer,
};
我正在将 WinForms 应用程序迁移到 .Net Core (3.1) API,我 运行 遇到了调用 SSO-protected 的功能的问题API 在我们的网络中。
在 WinForms 应用程序中,我有以下内容:
public async void Authenticate()
{
var wi = System.Security.Principal.WindowsIdentity.GetCurrent();
var wic = wi.Impersonate();
try
{
// Initial request to grab cookies and redirect endpoint
var apiEndPoint = $"https://{_host}{_apiPath}";
var cookieRedirectRequest = new HttpRequestMessage(HttpMethod.Get, apiEndPoint);
var response = await _httpClient.SendAsync(cookieRedirectRequest);
if (response != null)
{
var cookieContainer = new CookieContainer();
foreach (var cookie in response.Headers.GetValues("Set-Cookie"))
{
var parsedCookie = cookie.ToCookie();
parsedCookie.Domain = TARGET_DOMAIN;
cookieContainer.Add(parsedCookie);
}
var redirectURL = response.Headers.GetValues("Location").FirstOrDefault();
// Add the cookies to the client to continue the authentication
_httpClient = new HttpClient(new HttpClientHandler()
{
UseDefaultCredentials = true,
AllowAutoRedirect = true,
ClientCertificateOptions = ClientCertificateOption.Automatic,
UseCookies = true,
CookieContainer = cookieContainer
});
// Second request to grab code and state values
var codeAndStateRequest = new HttpRequestMessage(HttpMethod.Get, redirectURL);
response = await _httpClient.SendAsync(codeAndStateRequest);
...
对 API 的初始调用将我们重定向到 SSO-authentication 页面。我使用该初始响应中的 cookie 创建我自己的请求,以便我可以传递正确的凭据并取回适当的 SSO 令牌(在最后一行 returns 返回令牌的 SendSync 调用的响应),这然后,我用于对 API.
的未来请求进行身份验证我正在尝试使用服务帐户在 .NET Core 中重新创建此功能,而不是进行 WindowsIdentity 模拟,我正在尝试显式设置我的 HttpClientHandler 的 NetworkCredentials 属性:
handler = new HttpClientHandler()
{
UseDefaultCredentials = false,
Credentials = new NetworkCredential("svc_acct_username", "svc_act_pass", "mydomain"),
AllowAutoRedirect = true,
ClientCertificateOptions = ClientCertificateOption.Automatic,
UseCookies = true,
CookieContainer = cookieContainer,
};
但是,我从第二个请求中得到的响应是 401。
这与我以前在原始应用程序中得到的结果一致——我最初会得到一个带有“WWW-Authenticate: Negotiate”header 的 401,但随后会有一个自动传入网络凭据的后续请求,我会得到 200。我没有收到带有 .Net Core 中的凭据的第二个请求。
我尝试了此处建议的凭据缓存解决方案: https://github.com/dotnet/runtime/issues/24490 但这并没有奏效。
提前感谢你们能给我的任何帮助。我卡住了!
快速编辑: 通过简单地显式设置 HttpClientHandler 的 Credentials 属性 并设置 UseDefaultCredentials = false,我可以在我的 WinForms 应用程序中重新创建 .Net Core 行为。因此,通过设置 UseDefaultCredentials 会发生一些神奇的事情,在使用显式凭据时似乎无法重新创建。
我在 co-worker 的帮助下完成了这项工作!问题是,当您使用显式网络凭据时,您会丢失“协商”身份验证类型,这是我们的 SSO-endpoint 所要求的。通过使用 CredentialCache 对象并显式设置协商 auth-type,调用有效!
var credCache = new CredentialCache { { new Uri("https://example.com"), "Negotiate", new NetworkCredential("svc_acct_user", "svc_acct_password", "mydomain") } };
// Add the cookies to the client to continue the authentication
handler = new HttpClientHandler()
{
UseDefaultCredentials = false,
Credentials = credCache,
AllowAutoRedirect = true,
ClientCertificateOptions = ClientCertificateOption.Automatic,
UseCookies = true,
CookieContainer = cookieContainer,
};