Contoh kode program Spring Authorization Server yang baru.
Cara menjalankan aplikasi
mvn clean spring-boot:run
Perhatikan log aplikasi untuk mendapatkan JDBC URL database H2 seperti ini
H2 console available at '/h2-console'.
Database available at 'jdbc:h2:mem:b967a89c-dcf0-4752-b643-bc77419deaee'
Database H2 bisa diakses di http://localhost:9000/h2-console
-
Cari tahu dulu URL yang digunakan untuk prosedur OAuth 2.0
curl http://localhost:9000/.well-known/openid-configuration
Hasilnya seperti ini
{ "issuer": "http://127.0.0.1:9000", "authorization_endpoint": "http://127.0.0.1:9000/oauth2/authorize", "token_endpoint": "http://127.0.0.1:9000/oauth2/token", "token_endpoint_auth_methods_supported": [ "client_secret_basic", "client_secret_post" ], "jwks_uri": "http://127.0.0.1:9000/oauth2/jwks", "response_types_supported": [ "code" ], "grant_types_supported": [ "authorization_code", "client_credentials", "refresh_token" ], "subject_types_supported": [ "public" ], "id_token_signing_alg_values_supported": [ "RS256" ], "scopes_supported": [ "openid" ] }
-
Generate PKCE
- Code Verifier : 43 - 128 random string. Misal :
EmJ1jTS245HXMu5dDFc36XlEK02FCfT3BAvbvVfBiXSl
- Code Challenge : SHA256(code verifier). Misal :
ea3rEXbTCcvWGOL2m6J1lT2VWv-sLrnS2i-UeaNENbw
- Code Verifier : 43 - 128 random string. Misal :
-
Akses
authorization_endpoint
di http://auth-server/oauth2/authorize?client_id=mobileapp&redirect_uri=http://example.com&response_type=code&scope=openid&state=abcd1234&code_challenge_method=S256&code_challenge=ea3rEXbTCcvWGOL2m6J1lT2VWv-sLrnS2i-UeaNENbw.Login dengan username
user001
dan passwordteststaff
-
Approve consent page
-
Dapatkan
authorization_code
setelah berhasil login, misalnyaIE_yzrqdjYxgKbxr1vIjYSAbjB-lDP_zc_cf4fX7rf-ObFbzRuY8UrM_h-X-MzrO2jVDVWr9fYr-d0XGdTw-35kFo2_6K5CXF9oXWFm_YuUIgw_R2Q43TDHLUqWzcobm
-
Tukarkan
authorization_code
menjadiaccess_token
curl --location --request POST 'http://auth-server:9000/oauth2/token' \ --header 'Authorization: Basic bW9iaWxlYXBwOmFiY2Q=' \ --header 'Content-Type: application/x-www-form-urlencoded' \ --data-urlencode 'grant_type=authorization_code' \ --data-urlencode 'redirect_uri=http://example.com' \ --data-urlencode 'client_id=mobileapp' \ --data-urlencode 'code=s2QnpXbI7y2TB89HKK_s52Vm9d0r_XYd_OCPr7_sqvq4i0zApwDSK8g44JZaWoZjUiOAowaXHwknBah133cVmF9ng5noqibE45lAFo3ruKYTwxiDr32K81jzB6z3JyRr' \ --data-urlencode 'code_verifier=EmJ1jTS245HXMu5dDFc36XlEK02FCfT3BAvbvVfBiXSl'
Hasilnya seperti ini
{ "access_token": "eyJraWQiOiIzYTM5ZDdhNy0yMjc4LTQwZjYtOTgxNS03YWY5MzkwNmRkMzEiLCJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJzdWIiOiJ1c2VyMDAxIiwiYXVkIjoibW9iaWxlYXBwIiwibmJmIjoxNjI2OTA4NzEzLCJpc3MiOiJodHRwOlwvXC9hdXRoLXNlcnZlcjo5MDAwIiwiZXhwIjoxNjI2OTA5MDEzLCJpYXQiOjE2MjY5MDg3MTMsImp0aSI6ImZkYmNhMzQ0LTAxMDgtNDU2NC1iNWYxLWQ2Y2FjYjJjZDZkYSJ9.qlzoGCoUjrZcAhzPZGQKO4TT6JZrS7NABOvxh2pT_WWulj98HBYBz1sRhh9dbnJIovNu448aNAzT8othGP8ZHl-kzYrrHq4S58uS3oWfu3o5pjfF-k0CCYVSLyyYi0BdZWnUjJhn-p_CNOlh5779wt5H5Tck8b5Jz4hcZXeGgtpIiWmRNtsrOB-9W2yY5Tp1jn10J4FwxIJR5sxubtZqidNC_zvQ0GoE_ee8QkhgN1zdmtRGI3uunqr83dZrwkbmCFcEGJr03X9RJnMzEZRQMsHNqdhCDpXMsGohwpyz1b1iyFC-rqb5i-14zSIgQWJ1ce-M0DGa_Oyhni9GyMoHgQ", "refresh_token": "NV_HKGl3r0Wt1FQ8ao9DkIZsa9hMAFxYE6GN2F_R8tpix1O6crkw2k_FVz_4ZqFIroaoyS2j-nJqQmkgi9eAvVuJd_XghMJD7fY2rIRO1bUiml9HguAxoHypLjTgKWqv", "token_type": "Bearer", "expires_in": 299 }
-
Decode di JWT.io
-
Lakukan HTTP Request untuk mendapatkan access token
curl --location --request POST 'http://127.0.0.1:9000/oauth2/token' \ --header 'Authorization: Basic YmVsYWphcjpiZWxhamFyMTIz' \ --header 'Content-Type: application/x-www-form-urlencoded' \ --data-urlencode 'grant_type=password' \ --data-urlencode 'username=user001' \ --data-urlencode 'password=teststaff'
-
Responsenya seperti ini
{ "error_description": "OAuth 2.0 Parameter: grant_type", "error": "unsupported_grant_type", "error_uri": "https://tools.ietf.org/html/rfc6749#section-5.2" }
karena di versi
0.1.0
ini grant typepassword
belum disupport.Update : grant type password tidak akan disupport. Gunakan grant type authorization code dengan PKCE
-
Ambil informasi public key di
jwks_uri
curl http://127.0.0.1:9000/oauth2/jwks
Outputnya seperti ini
{ "keys": [ { "kty": "RSA", "e": "AQAB", "kid": "b631cb97-58f1-4cc2-b056-95f33686f1e7", "n": "j3sw-tGvAkDy-I5FSmUIiDl8bElvJrT71n5AMuzRTWGizgE729ImU2GwxzXvhrglLo0d4EFzKV3qHZFxgcAFh9dxAAOBCahFiIhUTcCZZx4cflcdwQ9kVgTisr4KSuA5A2RjIzFeuRSv3CPTtNVc4BQAAVX6bZJuDg_qVTyojfiblqdc03t1xNhDpfYMM_IYeFU-SUY300c5OjYpKVmTDxoh5C8WxplUrO70EYyq9nQFKprlvY3-258HWk9jrzztkUgODLoBLO60pSgyNjNplW5SKDVIVKJ7s0Z5niNpnbX00RB5GuUBMkv7oRxgBB7FtFeWd9MgeZfCTYHYXYHetw" } ] }
-
Dapatkan public key dari
JWKS
dengan menggunakan libraryjwk-to-pem
yang bisa dijalankan di https://npm.runkit.com.Paste kode program berikut di RunKit, jangan lupa ganti variabel
jwk
di baris 2 dengan output dari langkah sebelumnyavar jwkToPem = require("jwk-to-pem"); var jwk = {"kty":"RSA","e":"AQAB","kid":"b631cb97-58f1-4cc2-b056-95f33686f1e7","n":"j3sw-tGvAkDy-I5FSmUIiDl8bElvJrT71n5AMuzRTWGizgE729ImU2GwxzXvhrglLo0d4EFzKV3qHZFxgcAFh9dxAAOBCahFiIhUTcCZZx4cflcdwQ9kVgTisr4KSuA5A2RjIzFeuRSv3CPTtNVc4BQAAVX6bZJuDg_qVTyojfiblqdc03t1xNhDpfYMM_IYeFU-SUY300c5OjYpKVmTDxoh5C8WxplUrO70EYyq9nQFKprlvY3-258HWk9jrzztkUgODLoBLO60pSgyNjNplW5SKDVIVKJ7s0Z5niNpnbX00RB5GuUBMkv7oRxgBB7FtFeWd9MgeZfCTYHYXYHetw"}; var pem = jwkToPem(jwk); console.log(pem);
Hasilnya seperti ini
-
Copy public key yang didapatkan di RunKit
-----BEGIN PUBLIC KEY----- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAj3sw+tGvAkDy+I5FSmUI iDl8bElvJrT71n5AMuzRTWGizgE729ImU2GwxzXvhrglLo0d4EFzKV3qHZFxgcAF h9dxAAOBCahFiIhUTcCZZx4cflcdwQ9kVgTisr4KSuA5A2RjIzFeuRSv3CPTtNVc 4BQAAVX6bZJuDg/qVTyojfiblqdc03t1xNhDpfYMM/IYeFU+SUY300c5OjYpKVmT Dxoh5C8WxplUrO70EYyq9nQFKprlvY3+258HWk9jrzztkUgODLoBLO60pSgyNjNp lW5SKDVIVKJ7s0Z5niNpnbX00RB5GuUBMkv7oRxgBB7FtFeWd9MgeZfCTYHYXYHe twIDAQAB -----END PUBLIC KEY-----
-
Paste di
JWT.io
tadi untuk verifikasi signature. Seharusnya hasilnya verified.
-
Buat request ke endpoint
/oauth/token
dengangrant_type=refresh_token
dan menyertakanrefresh_token
curl --location --request POST 'http://auth-server:9000/oauth2/token' \ --header 'Authorization: Basic bW9iaWxlYXBwOmFiY2Q=' \ --header 'Content-Type: application/x-www-form-urlencoded' \ --data-urlencode 'grant_type=refresh_token' \ --data-urlencode 'client_id=mobileapp' \ --data-urlencode 'refresh_token=NV_HKGl3r0Wt1FQ8ao9DkIZsa9hMAFxYE6GN2F_R8tpix1O6crkw2k_FVz_4ZqFIroaoyS2j-nJqQmkgi9eAvVuJd_XghMJD7fY2rIRO1bUiml9HguAxoHypLjTgKWqv'
-
Hasilnya seperti ini
{ "access_token":"eyJraWQiOiI4NzNjN2MzMC1hZGZjLTQzZDgtYTE1OS05YzU1MTk5ZGM3OWQiLCJhbGciOiJSUzI1NiJ9.eyJzdWIiOiJ1c2VyMDAxIiwiYXVkIjoibW9iaWxlYXBwIiwibmJmIjoxNjMzMDE4ODY2LCJpc3MiOiJodHRwOlwvXC9hdXRoLXNlcnZlcjo5MDAwIiwiZXhwIjoxNjMzMDE5MTY2LCJpYXQiOjE2MzMwMTg4NjYsImF1dGhvcml0aWVzIjpbIlZJRVdfVFJBTlNBS1NJIl19.DaiGLylpDDX2_pelXScaPaiiZBQoUSNtwM8mpBc6R6MGzchKmN_KncUgmQ0ZYpAm_-gBJfSW8JB-yHcDeI5e4Hc3q0TvJYttiFrnOb9ar3b5PIQYVy1C8uXx_-wDohdVXn9EFrlKKnmL8wnSKuvn57Hl5h2AC5qAnKAnSM0Uqm-921hxjNi8JDaKlAygv2uwt0pgPg1Yn0kIyo6tStmQyVh2tUX-X1t-ISSfLCgfdNtSF90NwzuV0a08CFxxOxMyXlTKI_u7pn_FGH_tQq5VOSAZqXu_2qBI6f5oOAX4qISs2OKODOETsiJdHXMC-cZHOn9jECZ0-0TE4O1oLg2UWA", "refresh_token":"QhTGzH6ajcCeTGRgNDiEK_YSrQhlbP82WdeB57YoBz-9oRp2X2_n7eqo-y_0-4fas_mZPMRiVXUzfU5wC6fyAeW9hCygfzCwEWfZmjHWwmi2DV6BNitYNe_tkhdfy3sT", "token_type":"Bearer", "expires_in":299 }
git push heroku `git subtree split --prefix auth-server`:master --force