How to write OAuth2 Web API Client in Asp.net MVC

54,660

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:

Share:
54,660
TejSoft
Author by

TejSoft

Updated on July 05, 2022

Comments

  • TejSoft
    TejSoft almost 2 years

    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).

    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)?

    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)));
                        }
                    }
                }
            });
    
    
        }
    }