我的问题改写为:
我有一台具有安全的api端点的Web服务器-必须在使用它们之前先通过Google认证。我为此实现了Challenge
和Callback
端点。
这在具有我的SPA Web前端的浏览器中效果很好。用户被重定向到Google网站以登录,然后被重定向回我的webapp;然后浏览器将具有经过身份验证的cookie,并且Webapp可以使用端点来更新其状态。
我还有一个WPF应用程序,它将与Web服务器通信。 我希望WPF应用程序执行与Web前端相同的操作:在通过Google身份验证后,使用Web api端点。 WPF应用程序和我的Web服务器之间的连接是通过HttpClient完成的。
我的问题是我不知道如何验证WPF应用程序和Web服务器之间的HttpClient连接。
我尝试使用相同的Challenge
端点,但是得到的响应当然是Google登录页面中的HTML,所以我想我不能将它与HttpClient一起使用...
我还尝试通过WPF应用使用GoogleApis进行身份验证,并使用经过身份验证的令牌在HttpClient
中设置cookie,但这显然不兼容。
如何通过外部提供商(例如Google)对与Web api的HttpClient连接进行身份验证?
原始问题:
在WPF应用程序中,用户使用以下代码向Google进行身份验证:
using Google.Apis.Auth.OAuth2;
...
public void Authenticate()
{
UserCredential credential = GoogleWebAuthorizationBroker.AuthorizeAsync(
new ClientSecrets
{
ClientId = "myClientId",
ClientSecret = "myClientSecret"
},
new[] { "email", "openid" },
"user",
CancellationToken.None).Result;
}
这有效,并且UserCredential
对象包含已验证的令牌:
如何将此令牌信息嵌入通过HttpClient
发出的Web请求中以调用我的webapi端点?
我认为该请求必须包含一些cookie才能通知服务器它已通过身份验证,但是我不知道确切地是哪个cookie。
服务器端的终结点通过IdentityServer验证用户的身份:
var result = await HttpContext.AuthenticateAsync(IdentityServer4.IdentityServerConstants.ExternalCookieAuthenticationScheme);
if (result?.Succeeded != true)
{
throw new Exception("External authentication error");
}
答案 0 :(得分:2)
如果我的问题正确,那么您只需设置Authorization
标头
var credentials = await GoogleWebAuthorizationBroker.AuthorizeAsync(
clientSecrets,
new[] { "email", "openid" },
"user",
CancellationToken.None);
_httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(
credentials.Token.TokenType,
credentials.Token.IdToken);
答案 1 :(得分:0)
也许您会在下面找到有用的提示,以更好地了解OpenID:)
混淆源于混合使用GoogleApis和IdentityServer框架。 认证/授权可以使用它们之一来实现。 Google.Apis.Auth.OAuth2和IdentityServer4命名空间中的对象并非旨在进行交互。 当然,不需要手动处理cookie。
问问自己,Google为用户提供了哪些信任。如果回拨到WPF,则信任WPF的webapi是一个单独的问题。
答案 2 :(得分:0)
您在问题中回答自己的问题:
然后,浏览器将具有经过身份验证的cookie,并且Webapp可以使用 端点更新其状态
HttpClient需要发送那些相同的cookie。 How do I set a cookie on HttpClient's HttpRequestMessage
答案 3 :(得分:0)
如果我正确理解了您的问题,那么不久前我也遇到了同样的问题。
我实现的方式是在后端,无论谁尝试访问端点,他们都必须发送Bearer X
授权令牌。
令牌包含要访问资源的客户端的身份,我检查了是否允许他访问。
无论哪种客户端想要访问端点,它都只需要在他发送的请求中具有该身份验证标头,后端便会对其进行相同处理。
在我的场景中,我使用了一种身份验证服务,该服务通过一个包含身份信息的特定JWT将cookie返回给客户端。 然后,从客户端,我将从身份验证服务收到的JWT作为授权标头发送到后端的每个请求。
我必须将从服务接收的JWT放在标头中的原因是,身份验证服务和后端服务不在同一域中,因此无法共享cookie。
这样的设计使得无论您如何验证客户端,最终结果都必须是后端可以接收和读取的某种令牌。
希望这会有所帮助。