ASP.NET Core Web APIアプリケーションに認可を追加する
Auth0を使用すると、アプリケーションに認証を追加して、アプリケーションの種類にかかわらず、ユーザープロファイル情報に手軽にアクセスすることができます。このガイドは、新規または既存のASP.NET Web APIアプリケーションにMicrosoft.AspNetCore.Authentication.JwtBearer
パッケージを使ってAuth0を統合する方法を説明します。
Auth0 DashboardでAPIをまだ作成していない場合は、対話型のセレクターを使ってAuth0 APIを新規作成します。そうでない場合は、統合したいプロジェクトを表す既存のAPIを選択することができます。
または、Auth0 Dashboardを使って初めてAPIをセットアップする方法を使用の開始ガイドで確認することもできます。
Auth0にあるAPIはそれぞれAPI識別子を使って構成され、アプリケーションのコードはAPI識別子をオーディエンスとしてアクセストークンを検証します。
アクセス許可は、ユーザーの代わりに、提供されたアクセストークンを使ってどのようにしてリソースにアクセスできるのかを定義できるようにします。たとえば、ユーザーがマネージャーアクセスレベルを持つ場合には、messages
リソースに対して読み取りアクセスを付与し、管理者アクセスレベルを持つ場合には、書き込みアクセスを付与することができます。
Auth0 Dashboardの[API]セクションにある[Permissions(権限)]ビューで使用可能なアクセス許可を定義することができます。以下の例ではread:messages
スコープを使用します。
![[Auth0 Dashboard]>[Applications(アプリケーション)]>[APIs]>[Specific API(特定のAPI]>[Permissions(権限)]タブ](http://images.ctfassets.net/cdy7uua7fh8z/1s3Yp5zqJiKiSWqbPSezNO/acef814282795bef6921535f044f96e9/Quickstarts_API.png)
アプリケーションがアクセストークンを検証できるようにするには、Microsoft.AspNetCore.Authentication.JwtBearer
NuGetパッケージへの参照を追加します。
Install-Package Microsoft.AspNetCore.Authentication.JwtBearer
Was this helpful?
アプリケーションのProgram.cs
ファイルを構成して、認証ミドルウェアをセットアップします:
AddAuthentication
メソッドを呼び出して、認証サービスを登録します。JwtBearerDefaults.AuthenticationScheme
をデフォルトのスキームとして構成します。AddJwtBearer
メソッドを呼び出して、JWTベアラー認証スキームを登録します。Auth0ドメインをオーソリティ、Auth0 API識別子をオーディエンスとして構成し、Auth0ドメインとAPI識別子がアプリケーションのappsettings.jsonファイル内で設定されていることを確認します。UseAuthentication
メソッドとUseAuthorization
メソッドの呼び出しをvar app = builder.Build();
メソッドの下に追加して、ミドルウェアパイプラインに認証ミドルウェアと認可ミドルウェアを追加します。
アクセストークンに正しいスコープが含まれていることを確認するには、ASP.NET Coreのポリシーベースの認可を使用します。
HasScopeRequirement
という名前の新しい認可要求を作成します。これは、Auth0テナント発行のscope
クレームが存在するかを確認し、存在する場合には、要求されたスコープがそのクレームに含まれているかを確認します。Program.cs
ファイルにあるvar builder = WebApplication.CreateBuilder(args);
メソッドの下に、app.AddAuthorization
メソッドへの呼び出しを追加します。スコープのポリシーを追加するには、各スコープに
AddPolicy
を呼び出します。HasScopeHandler
クラスのシングルトンを登録します。
JWTミドルウェアは、ASP.NET Coreの標準の認証および認可メカニズムと統合します。
エンドポイントのセキュリティを保護するには、[Authorize]
属性をコントローラーのアクション(すべてのアクションのセキュリティを保護するには、コントローラー)に追加します。
特定のスコープが必要なエンドポイントのセキュリティを保護するには、正しいスコープがaccess_token
に存在することを確認します。そのためには、Authorize
属性をScoped
アクションに追加し、read:messages
をpolicy
パラメーターとして渡します。
APIの呼び出し方は、開発しているアプリケーションの種類と使用しているフレームワークに依存します。詳細については、該当するアプリケーションのクイックスタートをお読みください。
アクセストークン取得する
開発しているアプリケーションの種類や使用しているフレームワークが何であったとしても、APIを呼び出すにはアクセストークンが必要です。
シングルページアプリケーション(SPA)またはネイティブアプリケーションからAPIを呼び出すと、認可フローの完了後にアクセストークンを受け取ります。
コマンドラインツールや他のサービスなど、ユーザーが資格情報を入力しないものからAPIを呼び出す際には、OAuthクライアントの資格情報フローを使用します。そのためには、マシンツーマシンアプリケーションを登録し、要求内で以下の値を渡します。
クライアントIDを
client_id
パラメーターとして渡す。クライアントシークレットを
client_secret
パラメーターとして渡す。API 識別子(このクイックスタートで以前にミドルウェアの構成に使用したのと同じ値)を
audience
パラメーターとして渡す。
要求例
curl --request post \
--url 'https://{yourDomain}/oauth/token' \
--header 'content-type: application/x-www-form-urlencoded'
Was this 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);
Was this 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))
}
Was this helpful?
HttpResponse<String> response = Unirest.post("https://{yourDomain}/oauth/token")
.header("content-type", "application/x-www-form-urlencoded")
.asString();
Was this 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);
});
Was this 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(@"%@", error);
} else {
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *) response;
NSLog(@"%@", httpResponse);
}
}];
[dataTask resume];
Was this 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 => [
"content-type: application/x-www-form-urlencoded"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}
Was this 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"))
Was this 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
Was this 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()
Was this helpful?
セキュリティ保護されたエンドポイントを呼び出す
取得したアクセストークン使用すると、セキュリティ保護されたAPIエンドポイントを呼び出すことができます。セキュリティ保護されたエンドポイントを呼び出す際には、アクセストークンをベアラートークンとして要求の認可ヘッダーに含める必要があります。たとえば、/api/private
エンドポイントに要求を送信することができます:
curl --request get \
--url http://localhost:3010/api/private \
--header 'authorization: Bearer YOUR_ACCESS_TOKEN'
Was this 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);
Was this 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))
}
Was this helpful?
HttpResponse<String> response = Unirest.get("http://localhost:3010/api/private")
.header("authorization", "Bearer YOUR_ACCESS_TOKEN")
.asString();
Was this 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);
});
Was this 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(@"%@", error);
} else {
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *) response;
NSLog(@"%@", httpResponse);
}
}];
[dataTask resume];
Was this 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 => [
"authorization: Bearer YOUR_ACCESS_TOKEN"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}
Was this 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"))
Was this 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
Was this 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()
Was this helpful?
/api/private-scoped
エンドポイントも同様の方法で呼び出しますが、APIのアクセス許可が正しく構成され、アクセストークンにread:messages
スコープがあることを確認してください。
checkpoint.header
/api/private
と/api/private-scoped
エンドポイントを呼び出すことができるはずです。
アプリケーションを実行して次の点を確認します:
GET /api/private
が認証された要求に使用できる。GET /api/private-scoped
がread:messages
スコープが付与されたアクセストークンを含む認証された要求に使用できる。
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
Sign up for an or to your existing account to integrate directly with your own tenant.