如何在Asp.net MVC中编写OAuth2 Web API客户端

我们开发了一组受授权服务器保护的Web API(REST)。 授权服务器已发出客户端ID和客户端密钥。 这些可用于获取访问令牌。 可以在后续调用资源服务器(REST API)时使用有效令牌。

我想编写一个基于Web的(Asp.net MVC 5)客户端,它将使用API​​。 我可以下载一个nuget包来帮助我实现客户端OAuth2流程吗? 任何人都可以指导我在OAuth2流的客户端实现(用asp.net MVC编写)中的一个很好的例子吗?

更新我能够使用下面的代码块获取访问令牌,但我想要的是“客户端凭据”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(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 { { 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(OpenIdConnectParameterNames.AccessToken))); } } } }); } } 

要支持客户端凭据授予类型,您最好的选择可能是直接使用HttpClient

 var request = new HttpRequestMessage(HttpMethod.Post, "http://server.com/token"); request.Content = new FormUrlEncodedContent(new Dictionary { { "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("access_token"); 

对于交互式流程(如授权代码流程),有两种更好的方法:

  • 如果您的授权服务器支持OpenID Connect(基于OAuth2),您只需使用Microsoft开发的OWIN / Katana 3的OpenID Connect中间件: https ://www.nuget.org/packages/Microsoft.Owin.Security 。 OpenIdConnect /

  • 如果授权服务器不支持OpenID Connect,则可以选择创建自己的OAuth2客户端中间件。 您可以查看此SO答案的最后一部分以获取更多信息: 使用OWIN标识从多个API客户端注册Web API 2外部登录