我们开发了一组受授权服务器保护的 Web API (REST)。授权服务器已发布客户端 ID 和客户端密码。这些可用于获取访问 token 。有效 token 可用于对资源服务器(REST API)的后续调用。
我想编写一个基于 Web (Asp.net MVC 5) 的客户端来使用 API。我可以下载 nuget 包来帮助我实现客户端 OAuth2 流程吗?谁能给我一个关于 OAuth2 流程的客户端实现的好例子(用 asp.net MVC 编写)?
更新 我能够使用下面的代码块获取访问 token ,但我想要的是“客户端凭据”oauth 2 流程,我不必在其中输入登录名和密码。我现在的代码是:
public class Startup
{
public void Configuration(IAppBuilder app)
{
app.SetDefaultSignInAsAuthenticationType("ClientCookie");
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationMode = AuthenticationMode.Active,
AuthenticationType = "ClientCookie",
CookieName = CookieAuthenticationDefaults.CookiePrefix + "ClientCookie",
ExpireTimeSpan = TimeSpan.FromMinutes(5)
});
app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions
{
AuthenticationMode = AuthenticationMode.Active,
AuthenticationType = OpenIdConnectAuthenticationDefaults.AuthenticationType,
SignInAsAuthenticationType = app.GetDefaultSignInAsAuthenticationType(),
ClientId = ConfigurationManager.AppSettings["AuthServer:ClientId"],
ClientSecret = ConfigurationManager.AppSettings["AuthServer:ClientSecret"],
RedirectUri = ConfigurationManager.AppSettings["AuthServer:RedirectUrl"],
Configuration = new OpenIdConnectConfiguration
{
AuthorizationEndpoint = "https://identityserver.com/oauth2/authorize",
TokenEndpoint = "https://identityserver.com/oauth2/token"
},
//ResponseType = "client_credentials", // Doesn't work
ResponseType = "token",
Notifications = new OpenIdConnectAuthenticationNotifications
{
AuthenticationFailed = notification =>
{
if (string.Equals(notification.ProtocolMessage.Error, "access_denied", StringComparison.Ordinal))
{
notification.HandleResponse();
notification.Response.Redirect("/");
}
return Task.FromResult<object>(null);
},
AuthorizationCodeReceived = async notification =>
{
using (var client = new HttpClient())
{
//var configuration = await notification.Options.ConfigurationManager.GetConfigurationAsync(notification.Request.CallCancelled);
String tokenEndPoint = "https://identityserver.com/oauth2/token";
//var request = new HttpRequestMessage(HttpMethod.Post, configuration.TokenEndpoint);
var request = new HttpRequestMessage(HttpMethod.Post, tokenEndPoint);
request.Content = new FormUrlEncodedContent(new Dictionary<string, string> {
{ OpenIdConnectParameterNames.ClientId, notification.Options.ClientId },
{ OpenIdConnectParameterNames.ClientSecret, notification.Options.ClientSecret },
{ OpenIdConnectParameterNames.Code, notification.ProtocolMessage.Code },
{ OpenIdConnectParameterNames.GrantType, "authorization_code" },
{ OpenIdConnectParameterNames.RedirectUri, notification.Options.RedirectUri }
});
var response = await client.SendAsync(request, notification.Request.CallCancelled);
response.EnsureSuccessStatusCode();
var payload = JObject.Parse(await response.Content.ReadAsStringAsync());
// Add the access token to the returned ClaimsIdentity to make it easier to retrieve.
notification.AuthenticationTicket.Identity.AddClaim(new Claim(
type: OpenIdConnectParameterNames.AccessToken,
value: payload.Value<string>(OpenIdConnectParameterNames.AccessToken)));
}
}
}
});
}
}
最佳答案
要支持客户端凭据授权类型,您最好的选择可能是直接使用 HttpClient
:
var request = new HttpRequestMessage(HttpMethod.Post, "http://server.com/token");
request.Content = new FormUrlEncodedContent(new Dictionary<string, string> {
{ "client_id", "your client_id" },
{ "client_secret", "your client_secret" },
{ "grant_type", "client_credentials" }
});
var response = await client.SendAsync(request);
response.EnsureSuccessStatusCode();
var payload = JObject.Parse(await response.Content.ReadAsStringAsync());
var token = payload.Value<string>("access_token");
对于交互式流程(如授权代码流程),有两种更好的方法:
如果您的授权服务器支持 OpenID Connect(基于 OAuth2),您可以简单地使用 Microsoft 开发的用于 OWIN/Katana 3 的 OpenID Connect 中间件:https://www.nuget.org/packages/Microsoft.Owin.Security.OpenIdConnect/
如果您的授权服务器不支持 OpenID Connect,一种选择是创建您自己的 OAuth2 客户端中间件。您可以查看此 SO 答案的最后部分以获取更多信息:Registering Web API 2 external logins from multiple API clients with OWIN Identity
关于c# - 如何在 Asp.net MVC 中编写 OAuth2 Web API 客户端,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31376484/