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

标签 c# asp.net asp.net-mvc oauth-2.0

我们开发了一组受授权服务器保护的 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");

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

关于c# - 如何在 Asp.net MVC 中编写 OAuth2 Web API 客户端,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31376484/

相关文章:

asp.net - Umbraco 有什么好的电子商务扩展/插件吗?

html <hr> 标签奇怪显示

c# - 为什么 Asp.Net Identity IdentityDbContext 是黑盒?

c# - 单元测试场景——如何测试?

c# - 通过 C# (Microsoft.AnalysisServices) 进行的 SSAS 处理比 SSMS 慢得多

C#、sp_executesql 和不正确的语法

c# - 导出到 Excel 在 SSL (https) 下的 IE 上不起作用

javascript - 完整日历无法识别 Chrome 中日期字段上的点击事件?

javascript - 对 ASP.NET MVC Controller 的 JQuery JSON POST 请求未到达端点,但手动使用路由工作正常

c# - MVC : Binding CKEditor textarea value to the model