如何在 Asp.net MVC 中编写 OAuth2 Web API 客户端 [英] How to write OAuth2 Web API Client in Asp.net MVC

查看:13
本文介绍了如何在 Asp.net MVC 中编写 OAuth2 Web API 客户端的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

We have developed a set of Web APIs (REST) which are protected by an Authorization server. The Authorization server has issued the client id and client secret. These can be used to obtain an access token. A valid token can be used on subsequent calls to resource servers (REST APIs).

我想编写一个将使用 API 的基于 Web (Asp.net MVC 5) 的客户端.是否有我可以下载的 nuget 包可以帮助我实现客户端 OAuth2 流程?任何人都可以指导我找到一个关于 OAuth2 流(用 asp.net MVC 编写)的客户端实现的好例子吗?

I want to write an web based (Asp.net MVC 5) client that will consume the APIs. Is there a nuget package I can download that will help me to implement the client OAuth2 flow? Can anyone direct me to a good example on client implementation of OAuth2 flow (written in asp.net MVC)?

更新我能够使用下面的代码块获取访问令牌,但我想要的是客户端凭据"oauth 2 流,我不必输入登录名和密码.我现在的代码是:

Update I was able to get access token using the code block below, but what I want is a "client credentials" oauth 2 flow where I don't have to enter login and passwords. The code I have now is:

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:

To support the client credentials grant type, your best option is probably to directly use 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");

<小时>

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


For interactive flows (like the authorization code flow), there are two better approaches:

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

If OpenID Connect is not supported by your authorization server, one option is to create your own OAuth2 client middleware. You can take a look at the last part of this SO answer for more information: Registering Web API 2 external logins from multiple API clients with OWIN Identity

这篇关于如何在 Asp.net MVC 中编写 OAuth2 Web API 客户端的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆