Bekerja dengan cakupan OAuth2

Anda sedang melihat dokumentasi Apigee Edge.
Buka dokumentasi Apigee X.
info

Topik ini membahas cara menggunakan cakupan OAuth 2.0 di Apigee Edge.

Apa itu cakupan OAuth2?

Cakupan OAuth 2.0 menyediakan cara untuk membatasi jumlah akses yang diberikan ke token akses. Misalnya, token akses yang dikeluarkan untuk aplikasi klien dapat diberi akses BACA dan TULIS ke resource yang dilindungi, atau hanya akses BACA. Anda dapat mengimplementasikan API untuk menerapkan cakupan atau kombinasi cakupan apa pun yang Anda inginkan. Jadi, jika klien menerima token yang memiliki cakupan READ, dan mencoba memanggil endpoint API yang memerlukan akses TULIS, panggilan akan gagal.

Dalam topik ini, kita akan membahas cara menetapkan cakupan untuk mengakses token dan cara Apigee Edge menerapkan cakupan OAuth 2.0. Setelah membaca topik ini, Anda akan dapat menggunakan cakupan dengan percaya diri.

Bagaimana cakupan ditetapkan ke token akses?

Saat membuat token akses, Edge dapat menetapkan cakupan ke token tersebut. Untuk memahami bagaimana hal ini terjadi, Anda harus terlebih dahulu memahami entitas Apigee Edge berikut: produk API, developer, dan aplikasi developer. Untuk pendahuluan, lihat Pengantar publikasi. Sebaiknya Anda meninjau materi ini jika diperlukan sebelum melanjutkan.

Token akses adalah string panjang karakter yang terlihat acak yang memungkinkan Edge memverifikasi permintaan API yang masuk (anggap saja sebagai pengganti kredensial nama pengguna/sandi pada umumnya). Secara teknis, token adalah kunci yang mengacu pada kumpulan metadata yang terlihat seperti ini:

{
  "issued_at" : "1416962591727",
  "application_name" : "0d3e1d41-a59f-4d74-957e-d4e3275d4781",
  "scope" : "A",
  "status" : "approved",
  "api_product_list" : "[scopecheck1-bs0cSuqS9y]",
  "expires_in" : "1799", //--in seconds
  "developer.email" : "scopecheck1-AdBmANhsag@apigee.com",
  "organization_id" : "0",
  "token_type" : "BearerToken",
  "client_id" : "eTtB7w5lvk3DnOZNGReBlvGvIAeAywun",
  "access_token" : "ODm47ris5AlEty8TDc1itwYPe5MW",
  "organization_name" : "wwitman",
  "refresh_token_expires_in" : "0", //--in seconds
  "refresh_count" : "0"
}

Metadata token mencakup string token akses yang sebenarnya, informasi masa berlaku, identifikasi aplikasi developer, developer, dan produk yang terkait dengan token. Anda juga akan melihat bahwa metadata juga menyertakan "cakupan".

Bagaimana token mendapatkan cakupannya?

Kunci pertama untuk memahami cakupan adalah mengingat bahwa setiap produk di aplikasi developer dapat memiliki nol atau beberapa cakupan yang ditetapkan padanya. Cakupan ini dapat ditetapkan ketika produk dibuat, atau dapat ditambahkan nanti. Parameter ini terdapat sebagai daftar nama dan disertakan dalam "metadata" yang terkait dengan setiap produk.

Saat Anda membuat aplikasi developer dan menambahkan produk ke dalamnya, Edge akan melihat semua produk di aplikasi developer dan membuat daftar semua cakupan untuk produk tersebut (daftar cakupan global atau master aplikasi -- gabungan dari semua cakupan yang diakui).

Saat aplikasi klien meminta token akses dari Apigee Edge, aplikasi tersebut dapat secara opsional menentukan cakupan mana yang ingin dikaitkan dengan token tersebut. Misalnya, permintaan berikut meminta cakupan "A". Artinya, klien meminta server otorisasi (Edge) membuat token akses yang memiliki cakupan "A" (memberikan otorisasi pada aplikasi untuk memanggil API yang memiliki cakupan "A"). Aplikasi mengirimkan permintaan POST seperti ini:

curl -i -X POST -H Authorization: Basic Mg12YTk2UkEIyIBCrtro1QpIG -H content-type:application/x-www-form-urlencoded http://myorg-test.apigee.net/oauth/token?grant_type=client_credentials&scope=A

Apa yang terjadi?

Saat Edge menerima permintaan ini, Edge mengetahui aplikasi mana yang membuat permintaan dan mengetahui aplikasi developer mana yang didaftarkan klien (client ID dan kunci rahasia klien dienkode dalam header autentikasi dasar). Karena parameter kueri scope disertakan, Edge perlu memutuskan apakah ada produk API yang terkait dengan aplikasi developer yang memiliki cakupan "A". Jika ya, token akses akan dibuat dengan cakupan "A". Cara lain untuk melihat hal ini adalah parameter kueri cakupan adalah sejenis filter. Jika aplikasi developer mengenali cakupan "A, B, X", dan parameter kueri menentukan "scope=X Y Z", hanya cakupan "X" yang akan ditetapkan ke token tersebut.

Bagaimana jika klien tidak melampirkan parameter cakupan? Dalam hal ini, Edge akan menghasilkan token yang menyertakan semua cakupan yang dikenali oleh aplikasi developer. Penting untuk dipahami bahwa perilaku default-nya adalah menampilkan token akses yang berisi gabungan semua cakupan untuk semua produk yang disertakan dalam aplikasi developer.

Jika tidak ada produk yang terkait dengan aplikasi developer yang menentukan cakupan, dan token memiliki cakupan, panggilan yang dilakukan dengan token tersebut akan gagal.

Misalnya, aplikasi developer mengenali cakupan berikut: A B C D. Ini adalah daftar master cakupan aplikasi. Bisa jadi satu produk dalam aplikasi memiliki cakupan A dan B, dan produk kedua memiliki cakupan C dan D, atau kombinasi apa pun. Jika klien tidak menentukan parameter scope (atau jika klien menentukan parameter cakupan tanpa nilai), keempat cakupannya akan diberikan: A, B, C, dan D. Sekali lagi, token menerima sekumpulan cakupan yang merupakan gabungan dari semua cakupan yang dikenali oleh aplikasi developer.

Ada satu kasus lagi saat perilaku default-nya adalah menampilkan token akses dengan semua cakupan yang dikenali, dan saat kebijakan GenerateAccessToken (kebijakan Apigee Edge yang menghasilkan token akses) tidak menentukan elemen <Scope>. Misalnya, berikut adalah kebijakan GenerateAccessToken tempat <Scope> ditentukan. Jika elemen <Scope> tidak ada (atau jika ada tetapi kosong), perilaku default akan dieksekusi.

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<OAuthV2 async="false" continueOnError="false" enabled="true" name="OAuthV2-GenerateAccessToken">
    <DisplayName>OAuthV2 - Generate Access Token</DisplayName>
    <Attributes>
      <Attribute name='hello' ref='system.time' display='false'>value1</Attribute>
    </Attributes>
    <Scope>request.queryparam.scope</Scope> 
    <GrantType>request.formparam.grant_type</GrantType>
    <ExternalAuthorization>false</ExternalAuthorization>
    <Operation>GenerateAccessToken</Operation>
    <SupportedGrantTypes>
      <GrantType>client_credentials</GrantType>
    </SupportedGrantTypes>
  <GenerateResponse enabled="true"/>
</OAuthV2>

Bagaimana cakupan diterapkan?

Pertama, ingat bahwa di Apigee Edge, token akses divalidasi dengan kebijakan OAuthV2 (biasanya ditempatkan di awal alur proxy). Kebijakan ini harus menentukan operasi VerifyAccessToken. Mari kita lihat kebijakan ini:

<OAuthV2 async="false" continueOnError="false" enabled="true" name="OAuthV2-VerifyAccessTokenA">
    <DisplayName>Verify OAuth v2.0 Access Token</DisplayName>
    <ExternalAuthorization>false</ExternalAuthorization>
    <Operation>VerifyAccessToken</Operation>
    <Scope>A</Scope> <!-- Optional: space-separated list of scope names. -->
    <GenerateResponse enabled="true"/>
</OAuthV2>

Perhatikan elemen <Scope>. Atribut ini digunakan untuk menentukan cakupan mana yang akan diterima oleh kebijakan.

Dalam contoh ini, kebijakan hanya akan berhasil jika token akses menyertakan cakupan "A". Jika elemen <Scope> ini dihilangkan atau tidak memiliki nilai, kebijakan akan mengabaikan cakupan token akses.

Sekarang, dengan kemampuan untuk memvalidasi token akses berdasarkan cakupan, Anda dapat mendesain API untuk menerapkan cakupan tertentu. Anda melakukannya dengan merancang alur kustom beserta kebijakan VerifyAccessToken yang peka terhadap cakupan.

Misalnya, API Anda memiliki flow yang ditentukan untuk endpoint /resourceA:

<Flow name="resourceA">
            <Condition>(proxy.pathsuffix MatchesPath "/resourceA") and (request.verb = "GET")</Condition>
            <Description>Get a resource A</Description>
            <Request>
                <Step>
                    <Name>OAuthV2-VerifyAccessTokenA</Name>
                </Step>
            </Request>
            <Response>
                <Step>
                    <Name>AssignMessage-CreateResponse</Name>
                </Step>
            </Response>
        </Flow>

Saat alur ini dipicu (permintaan masuk dengan /resourceA di akhiran jalur), kebijakan OAuthV2-VerifyAccessTokenA akan segera dipanggil. Kebijakan ini memverifikasi bahwa token akses valid dan melihat cakupan apa yang didukung token. Jika kebijakan dikonfigurasi seperti contoh di bawah, dengan <Scope>A</Scope>, kebijakan hanya akan berhasil jika token akses memiliki cakupan "A". Jika tidak, {i>error <i}akan muncul.

<OAuthV2 async="false" continueOnError="false" enabled="true" name="OAuthV2-VerifyAccessTokenA">
    <DisplayName>Verify OAuth v2.0 Access Token</DisplayName>
    <ExternalAuthorization>false</ExternalAuthorization>
    <Operation>VerifyAccessToken</Operation>
    <Scope>A</Scope>
    <GenerateResponse enabled="true"/>
</OAuthV2>

Singkatnya, developer API bertanggung jawab untuk mendesain penerapan cakupan ke dalam API mereka. Mereka melakukannya dengan membuat alur kustom untuk menangani cakupan tertentu, dan menambahkan kebijakan VerifyAccessToken untuk menerapkan cakupan tersebut.

Contoh kode

Terakhir, mari kita lihat beberapa contoh panggilan API untuk membantu menggambarkan cara token menerima cakupan dan cara penerapan cakupan.

Huruf besar/kecil default

Misalnya Anda memiliki aplikasi developer dengan beberapa produk, dan gabungan dari cakupan produk tersebut adalah: A, B, dan C. Panggilan API ini meminta token akses, tetapi tidak menetapkan parameter kueri cakupan.

curl -X POST -H content-type:application/x-www-form-urlencoded http://wwitman-test.apigee.net/scopecheck1/token?grant_type=client_credentials

Dalam hal ini, token yang dihasilkan akan diberi cakupan A, B, dan C (perilaku default). Metadata token akan terlihat seperti ini:

{
  "issued_at" : "1417016208588",
  "application_name" : "eb1a0333-5775-4116-9eb2-c36075ddc360",
  "scope" : "A B C",
  "status" : "approved",
  "api_product_list" : "[scopecheck1-yEgQbQqjRR]",
  "expires_in" : "1799", //--in seconds
  "developer.email" : "scopecheck1-yxiuHuZcDW@apigee.com",
  "organization_id" : "0",
  "token_type" : "BearerToken",
  "client_id" : "atGFvl3jgA0pJd05rXKHeNAC69naDmpW",
  "access_token" : "MveXpj4UYXol38thNoJYIa8fBGlI",
  "organization_name" : "wwitman",
  "refresh_token_expires_in" : "0", //--in seconds
  "refresh_count" : "0"
}

Sekarang, misalkan Anda memiliki endpoint API yang memiliki cakupan "A" (artinya, VerifyAccessToken tersebut memerlukan cakupan "A"). Berikut adalah kebijakan VerifyAccessToken:

<OAuthV2 async="false" continueOnError="false" enabled="true" name="OAuthV2-VerifyAccessTokenA">
    <DisplayName>Verify OAuth v2.0 Access Token</DisplayName>
    <ExternalAuthorization>false</ExternalAuthorization>
    <Operation>VerifyAccessToken</Operation>
    <Scope>A</Scope>
    <GenerateResponse enabled="true"/>
</OAuthV2>

Berikut adalah contoh panggilan ke dan endpoint yang menerapkan cakupan A:

curl -X GET -H Authorization: Bearer MveXpj4UYXol38thNoJYIa8fBGlI http://wwitman-test.apigee.net/scopecheck1/resourceA 

Panggilan GET ini berhasil:

 {
   "hello" : "Tue, 25 Nov 2014 01:35:53 UTC"
 }

Hal ini berhasil karena kebijakan VerifyAccessToken yang dipicu saat endpoint dipanggil memerlukan cakupan A, dan token akses diberi cakupan A, B, dan C -- perilaku default.

Kasus pemfilteran

Misalnya Anda memiliki aplikasi developer dengan produk yang memiliki cakupan A, B, C, dan X. Anda meminta token akses dan menyertakan parameter kueri scope, seperti ini:

curl -i -X POST -H content-type:application/x-www-form-urlencoded 'http://myorg-test.apigee.net/oauth/token?grant_type=client_credentials&scope=A X'

Dalam kasus ini, token yang dihasilkan akan diberi cakupan A dan X, karena A dan X adalah cakupan yang valid. Ingat bahwa aplikasi developer mengenali cakupan A, B, C, dan X. Dalam hal ini, Anda memfilter daftar produk API berdasarkan cakupan tersebut. Jika suatu produk memiliki cakupan A atau X, Anda dapat mengonfigurasi endpoint API yang akan menerapkan cakupan ini. Jika suatu produk tidak memiliki cakupan A atau X (misalnya memiliki B,C, dan Z), API yang menerapkan cakupan A atau X tidak dapat dipanggil dengan token tersebut.

Saat Anda memanggil API dengan token baru:

curl -X GET -H Authorization: Bearer Rkmqo2UkEIyIBCrtro1QpIG http://wwitman-test.apigee.net/scopecheck1/resourceX

Token akses divalidasi oleh proxy API. Contoh:

<OAuthV2 async="false" continueOnError="false" enabled="true" name="OAuthV2-VerifyAccessTokenX">
    <DisplayName>Verify OAuth v2.0 Access Token</DisplayName>
    <ExternalAuthorization>false</ExternalAuthorization>
    <Operation>VerifyAccessToken</Operation>
    <Scope>A X</Scope>
    <GenerateResponse enabled="true"/>
</OAuthV2>

Pemicu panggilan GET berhasil dan menampilkan respons. Contoh:

 {
   "hello" : "Tue, 25 Nov 2014 01:35:53 UTC"
 }
 

Eksperimen berhasil karena kebijakan VerifyAccessToken memerlukan cakupan A atau X, dan token akses mencakup cakupan A dan X. Tentu saja, jika elemen <Scope> disetel ke "B", panggilan ini akan gagal.

Ringkasan

Penting untuk memahami cara Apigee Edge menangani cakupan OAuth 2.0. Berikut adalah poin-poin penting:

  • Aplikasi developer "mengenali" gabungan semua cakupan yang ditetapkan untuk semua produknya.
  • Saat meminta token akses, aplikasi memiliki kesempatan untuk menentukan cakupan mana yang ingin dimiliki. Apigee Edge (server otorisasi) dapat menentukan cakupan mana yang benar-benar akan ditetapkan ke token akses berdasarkan (a) cakupan yang diminta dan (b) cakupan yang dikenali oleh aplikasi developer.
  • Jika Apigee Edge tidak dikonfigurasi untuk memeriksa cakupan (elemen <Scope> tidak ada dalam kebijakan VerifyAccessToken atau kosong), panggilan API akan berhasil selama cakupan yang disematkan dalam token akses cocok dengan salah satu cakupan yang dikenali oleh aplikasi developer terdaftar (salah satu cakupan dalam daftar cakupan "master" aplikasi).
  • Jika token akses tidak memiliki cakupan yang terkait dengannya, token tersebut hanya akan berhasil jika Edge tidak mempertimbangkan cakupan (elemen <Scope> tidak ada dalam kebijakan VerifyAccessToken atau kosong).