Add Authorization to Your ASP.NET Core Web API Application

Auth0 allows you to add authentication and access user profile information in almost any application type quickly. This guide demonstrates how to integrate Auth0 with any new or existing ASP.NET Web API application using the Microsoft.AspNetCore.Authentication.JwtBearer package.

If you haven't created an API in your Auth0 dashboard yet, you can use the interactive selector to create a new Auth0 API or select an existing API that represents the project you want to integrate with.

Alternatively, you can read our getting started guide, which will help you set up your first API through the Auth0 Dashboard.

Note that every API in Auth0 is configured using an API Identifier; your application code will use the API Identifier as the Audience to validate the access token.

1

Define permissions

Permissions let you define how resources can be accessed on behalf of the user with a given access token. For example, you might choose to grant read access to the messages resource if users have the manager access level, and grant write access to that resource if they have the administrator access level.

You can define allowed permissions in the Permissions view of the Auth0 Dashboard's APIs section. The following example uses the read:messages scope.

Auth0 Dashboard> Applications > APIs > [Specific API] > Permissions tab

2

Install dependencies

To allow your application to validate access tokens, add a reference to the Microsoft.AspNetCore.Authentication.JwtBearer NuGet package:

Install-Package Microsoft.AspNetCore.Authentication.JwtBearer

feedbackSection.helpful

/

3

Configure the middleware

Set up the authentication middleware by configuring it in your application's Program.cs file:

  1. Register the authentication services by making a call to the AddAuthentication method. Configure JwtBearerDefaults.AuthenticationScheme as the default scheme.

  2. Register the JWT Bearer authentication scheme by making a call to the AddJwtBearer method. Configure your Auth0 domain as the authority and your Auth0 API Identifier as the audience, and be sure that your Auth0 domain and API Identifier are set in your application's appsettings.json file.

  3. Add the authentication and authorization middleware to the middleware pipeline by adding calls to the UseAuthentication and UseAuthorization methods under the var app = builder.Build(); method.

4

Validate scopes

To ensure that an access token contains the correct scopes, use Policy-Based Authorization in the ASP.NET Core:

  1. Create a new authorization requirement called HasScopeRequirement, which will check whether the scope claim issued by your Auth0 tenant is present, and if so, will check that the claim contains the requested scope.

  2. Under your Program.cs file's var builder = WebApplication.CreateBuilder(args); method, add a call to the app.AddAuthorization method.

  3. Add policies for scopes by calling AddPolicy for each scope.

  4. Register a singleton for the HasScopeHandler class.

5

Protect API endpoints

The JWT middleware integrates with the standard ASP.NET Core Authentication and Authorization mechanisms.

To secure an endpoint, add the [Authorize] attribute to your controller action (or the entire controller if you want to protect all of its actions).

When securing endpoints that require specific scopes, make sure that the correct scope is present in the access_token. To do so, add the Authorize attribute to the Scoped action and pass read:messages as the policy parameter.

6

Call your API

The way in which you call your API depends on the type of application you are developing and the framework you are using. To learn more, read the relevant application Quickstart:

Get an access token

Regardless of the type of application you are developing or the framework you are using, to call your API, you need an access token.

If you call your API from a Single-Page Application (SPA) or Native application, you will receive an access token after the authorization flow completes.

If you call the API from a command-line tool or other service where a user entering credentials does not exist, use the OAuth Client Credentials Flow. To do so, register a Machine-to-Machine Application and pass the following values in your request:

  • Client ID as the client_id parameter.

  • Client Secret as the client_secret parameter.

  • API Identifier (the same value used to configure the middleware earlier in this quickstart) as the audience parameter.

Example request

curl --request post \
--url 'https://{yourDomain}/oauth/token' \
--header 'content-type: application/x-www-form-urlencoded'

feedbackSection.helpful

/
var client = new RestClient("https://{yourDomain}/oauth/token");
var request = new RestRequest(Method.POST);
request.AddHeader("content-type", "application/x-www-form-urlencoded");
IRestResponse response = client.Execute(request);

feedbackSection.helpful

/
package main
import (
"fmt"
"net/http"
"io/ioutil"
)
func main() {
url := "https://{yourDomain}/oauth/token"
req, _ := http.NewRequest("post", url, nil)
req.Header.Add("content-type", "application/x-www-form-urlencoded")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := ioutil.ReadAll(res.Body)
fmt.Println(res)
fmt.Println(string(body))
}

feedbackSection.helpful

/
HttpResponse<String> response = Unirest.post("https://{yourDomain}/oauth/token")
.header("content-type", "application/x-www-form-urlencoded")
.asString();

feedbackSection.helpful

/
var axios = require("axios").default;
var options = {
method: 'post',
url: 'https://{yourDomain}/oauth/token',
headers: {'content-type': 'application/x-www-form-urlencoded'}
};
axios.request(options).then(function (response) {
console.log(response.data);
}).catch(function (error) {
console.error(error);
});

feedbackSection.helpful

/
#import <Foundation/Foundation.h>
NSDictionary *headers = @{ @"content-type": @"application/x-www-form-urlencoded" };
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"https://{yourDomain}/oauth/token"]
                                                   cachePolicy:NSURLRequestUseProtocolCachePolicy

                                               timeoutInterval:10.0];

[request setHTTPMethod:@"post"];
[request setAllHTTPHeaderFields:headers];
NSURLSession *session = [NSURLSession sharedSession];
NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request
                                        completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {

                                            if (error) {

                                                NSLog(@&quot;%@&quot;, error);

                                            } else {

                                                NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *) response;

                                                NSLog(@&quot;%@&quot;, httpResponse);

                                            }

                                        }];

[dataTask resume];

feedbackSection.helpful

/
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://{yourDomain}/oauth/token",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "post",
CURLOPT_HTTPHEADER => [
&quot;content-type: application/x-www-form-urlencoded&quot;

],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}

feedbackSection.helpful

/
import http.client
conn = http.client.HTTPSConnection("")
headers = { 'content-type': "application/x-www-form-urlencoded" }
conn.request("post", "/{yourDomain}/oauth/token", headers=headers)
res = conn.getresponse()
data = res.read()
print(data.decode("utf-8"))

feedbackSection.helpful

/
require 'uri'
require 'net/http'
require 'openssl'
url = URI("https://{yourDomain}/oauth/token")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
request = Net::HTTP::Post.new(url)
request["content-type"] = 'application/x-www-form-urlencoded'
response = http.request(request)
puts response.read_body

feedbackSection.helpful

/
import Foundation
let headers = ["content-type": "application/x-www-form-urlencoded"]
let request = NSMutableURLRequest(url: NSURL(string: "https://{yourDomain}/oauth/token")! as URL,
                                    cachePolicy: .useProtocolCachePolicy,

                                timeoutInterval: 10.0)

request.httpMethod = "post"
request.allHTTPHeaderFields = headers
let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
if (error != nil) {
print(error)

} else {
let httpResponse = response as? HTTPURLResponse

print(httpResponse)

}
})
dataTask.resume()

feedbackSection.helpful

/

Call a secure endpoint

Now that you have an access token, you can use it to call secure API endpoints. When calling a secure endpoint, you must include the access token as a Bearer token in the Authorization header of the request. For example, you can make a request to the /api/private endpoint:

curl --request get \
--url http://localhost:3010/api/private \
--header 'authorization: Bearer YOUR_ACCESS_TOKEN'

feedbackSection.helpful

/
var client = new RestClient("http://localhost:3010/api/private");
var request = new RestRequest(Method.GET);
request.AddHeader("authorization", "Bearer YOUR_ACCESS_TOKEN");
IRestResponse response = client.Execute(request);

feedbackSection.helpful

/
package main
import (
"fmt"
"net/http"
"io/ioutil"
)
func main() {
url := "http://localhost:3010/api/private"
req, _ := http.NewRequest("get", url, nil)
req.Header.Add("authorization", "Bearer YOUR_ACCESS_TOKEN")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := ioutil.ReadAll(res.Body)
fmt.Println(res)
fmt.Println(string(body))
}

feedbackSection.helpful

/
HttpResponse<String> response = Unirest.get("http://localhost:3010/api/private")
.header("authorization", "Bearer YOUR_ACCESS_TOKEN")
.asString();

feedbackSection.helpful

/
var axios = require("axios").default;
var options = {
method: 'get',
url: 'http://localhost:3010/api/private',
headers: {authorization: 'Bearer YOUR_ACCESS_TOKEN'}
};
axios.request(options).then(function (response) {
console.log(response.data);
}).catch(function (error) {
console.error(error);
});

feedbackSection.helpful

/
#import <Foundation/Foundation.h>
NSDictionary *headers = @{ @"authorization": @"Bearer YOUR_ACCESS_TOKEN" };
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"http://localhost:3010/api/private"]
                                                   cachePolicy:NSURLRequestUseProtocolCachePolicy

                                               timeoutInterval:10.0];

[request setHTTPMethod:@"get"];
[request setAllHTTPHeaderFields:headers];
NSURLSession *session = [NSURLSession sharedSession];
NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request
                                        completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {

                                            if (error) {

                                                NSLog(@&quot;%@&quot;, error);

                                            } else {

                                                NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *) response;

                                                NSLog(@&quot;%@&quot;, httpResponse);

                                            }

                                        }];

[dataTask resume];

feedbackSection.helpful

/
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_PORT => "3010",
CURLOPT_URL => "http://localhost:3010/api/private",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "get",
CURLOPT_HTTPHEADER => [
&quot;authorization: Bearer YOUR_ACCESS_TOKEN&quot;

],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}

feedbackSection.helpful

/
import http.client
conn = http.client.HTTPConnection("localhost:3010")
headers = { 'authorization': "Bearer YOUR_ACCESS_TOKEN" }
conn.request("get", "/api/private", headers=headers)
res = conn.getresponse()
data = res.read()
print(data.decode("utf-8"))

feedbackSection.helpful

/
require 'uri'
require 'net/http'
url = URI("http://localhost:3010/api/private")
http = Net::HTTP.new(url.host, url.port)
request = Net::HTTP::Get.new(url)
request["authorization"] = 'Bearer YOUR_ACCESS_TOKEN'
response = http.request(request)
puts response.read_body

feedbackSection.helpful

/
import Foundation
let headers = ["authorization": "Bearer YOUR_ACCESS_TOKEN"]
let request = NSMutableURLRequest(url: NSURL(string: "http://localhost:3010/api/private")! as URL,
                                    cachePolicy: .useProtocolCachePolicy,

                                timeoutInterval: 10.0)

request.httpMethod = "get"
request.allHTTPHeaderFields = headers
let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
if (error != nil) {
print(error)

} else {
let httpResponse = response as? HTTPURLResponse

print(httpResponse)

}
})
dataTask.resume()

feedbackSection.helpful

/

Call the /api/private-scoped endpoint in a similar way, but ensure that the API permissions are configured correctly and that the access token includes the read:messages scope.

checkpoint.header

You should now be able to call the /api/private and /api/private-scoped endpoints.

Run your application and verify that:

  • GET /api/private is available for authenticated requests.

  • GET /api/private-scoped is available for authenticated requests containing an access token with the read:messages scope.

Next Steps

Excellent work! If you made it this far, you should now have login, logout, and user profile information running in your application.

This concludes our quickstart tutorial, but there is so much more to explore. To learn more about what you can do with Auth0, check out:

  • Auth0 Dashboard - Learn how to configure and manage your Auth0 tenant and applications
  • Auth0 Marketplace - Discover integrations you can enable to extend Auth0’s functionality

Did it work?

Any suggestion or typo?

Edit on GitHub
Sign Up

Sign up for an or to your existing account to integrate directly with your own tenant.