C# · 12月 29, 2021

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

我们开发了一套由授权服务器保护的Web API(REST).授权服务器已发出客户端ID和客户机密码.这些可用于获取访问令牌.对资源服务器(REST API)的后续调用可以使用有效的令牌.

我想编写一个将使用API​​的基于Web的(Asp.net MVC 5)客户端.是否有可以下载的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<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,notification.Request.CallCancelled);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