加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

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

发布时间:2020-12-15 06:57:40 所属栏目:百科 来源:网络整理
导读:我们开发了一套由授权服务器保护的Web API(REST).授权服务器已发出客户端ID和客户机密码.这些可用于获取访问令牌.对资源服务器(REST API)的后续调用可以使用有效的令牌. 我想编写一个将使用API??的基于Web的(Asp.net MVC 5)客户端.是否有可以下载的nuget软件
我们开发了一套由授权服务器保护的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

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读