มาลองใช้ Spring Authorization Server กันดู

Phayao Boonon
3 min readNov 21, 2020

--

Photo by Oliver Hale on Unsplash

จากที่ Spring team ได้ ประกาศว่าจะทำโครงการ Spring Authorization Server เมื่อประมาณเมษาปีนี้ (2020) โดยจะแยก OAuth2 Authorization Server ออกจาก Spring Security ทำให้ version ใหม่ๆ ไม่สมารถสร้าง OAuth2 Authorization Server ได้แล้ว และใครที่ใช้อยู่อาจจะต้องยังไม่อัพเดต Spring Security version ใหม่ และรอว่าเมื่อไหร่โครงการนี้จะเสร็จ และแล้วโครงการนี้ก็คลอดมาให้เราลองใช้แต่ยังอยู่ในขั้นทดลองอยู่ และมั่นใจว่าจะออกมา version ที่ใช้งานจริงได้ในไม่ช้านี้

ในบทความนี้จะมาลองใช้งาน Spring Authorization Server ก็ออมาให้ทดลองใช้กัน โดยจะสร้าง OAuth2 Authorization Server ด้วย Spring Authorization Server และ Resource Server ที่จะต้อง authorize ด้วย OAuth2 JWT โดยอ้างอิงจากตัวอย่างที่ Spring Security team สร้างไว้

เท้าความกันหน่อย มาปกป้อง Microservice ด้วย OAuth2 ใน Spring Boot

Create Authorization Server Project

เราใช้ Spring Intializr สร้าง project เลือกเฉพาะ Spring Web และ Spring Security เท่านั้นในตอนสร้าง project เพราะเราจะไปเพิ่ม Spring Authorization Server ทีหลัง ในบทความนี้จะใช้ Gradle project

ใช้ IDE อย่าง IntellJ เปิด project ที่สร้างมา และเพิ่ม Spring Authorization Server dependency ในส่วน dependencies ของ build.gradle

implementation 'org.springframework.security.experimental:spring-security-oauth2-authorization-server:0.0.3'

Add Authorization Server Config

สำหรับการสร้าง Authorization Server ด้วย Spring Authorization Server เราจะต้องสร้าง config ให้กับ Spring Security (annotation สำหรับน่าจะยังไม่เสร็จ) ซึ่งจะสร้าง config ด้วย WebSecurityConfigurerAdapter เหมือน Spring Security ทั่วไป จะใช้ applyDefaultConfiguration เพื่อตั้งค่าต่างๆ ให้กับ Spring Security อย่างเช่น endpoint ต่างๆ ที่จำเป็นสำหรับ Authorization Server ที่ใช้ protocol OAuth2

สร้าง registeredClientRepository bean ที่มากับ Spring Authorization Server เพื่อใช้เป็นข้อมูลของ Client ที่จะอนุญาตให้ใช้งานระบบ จะเห็นได้ว่ามี fix ค่าของ Client ID เป็น messaging-client และ Client Secret เป็น secret ทำให้ตัวอย่างใช้งานได้แค่เพียง Client เดียวเท่านั้น และเก็บข้อมูลใว้ใน memory ของระบบเท่านั้น (ยังไม่ได้ลองว่าใช้ JDBC Repository ได้ไหม)

สร้าง keySource bean เพื่อจัดการ key ของระบบใน version นี้มี implementation เดียวคือ StaticKeyGeneratingKeyManager (จะถูกแทนที่ CryptoKey ในอนาคตก็น่าจะ secure มากขึ้น)

สุดท้ายเป็น UserDetailsService เหมือนกับ Spring Security ทั่วไปเลย (ซึ่งก็ใช้ Spring Security ทั่วไปนั้นหล่ะ 555) สำหรับเก็บข้อมูล User ที่ใช้งานระบบและก็เก็บไว้ใน memory เช่นเดียวกัน

เพียงเท่านี้เราก็สร้าง Authorization Server ได้แล้ว (แบบ In Memory ก่อน 555)

อาจจะเปลี่ยน port ของ Authorization Server หน่อยเพื่อไม่ให้ชนกับ Client App หรือ Resource Server โดยเพิ่ม server.port ในไฟล์ application.yaml

Run Authorization Server

หลังจากที่สร้าง Config แล้ว ก็ทดลอง run Authorization Server ขึ้นมาด้วยคำสั่ง gradle bootRun หรือจะ run Application จาก IntelliJ ก็ได้ จะเห็นได้ว่า Spring Boot Application ทำงานบน port 9000

ใน log จะแสดง Filter ที่ใช้โดยมี endpoint ที่ใช้สำหรับ OAuth2 protocol ดังนี้

POST /oauth2/token — เป็น Token endpoint

POST /oauth2/authorize — เป็น Authorization endpoint

GET /oauth2/authorize — เป็น Authorization endpoint เช่นกัน

POST /oauth2/revoke — เป็น Token revoke endpoint

GET /oauth2/jwks — เป็น JWT key endpoint

ซึ่ง Authorization endpoint จะใช้ HTTP method POST หรือ GET ก็ได้

Test Authorization Server

ลองใช้ Postman ทดลอง request token เพื่อเอา access token จาก Authorization Server กำหนดค่าของ Body grant_type เป็น client_credentials และ scope เป็น message.read ด้วย Basic Auth username เป็น client_id messaging-client และ password เป็น client_secret secret เหมือนกับที่เรากำหนดใน config ก็จะได้ assess token เป็น response กลับมา และเอาไปใช้ authentication กับ Resource Server ได้

ในบทความนี้ผมสร้าง Resource Server ไว้ แต่ขอไม่กล่าวถึงในรายละเอียด ด้วย dependency oauth2-resource-server โดยกำหนด jwk-set-uri เป็น JWT key endpoint ของ Authorization server

เมื่อลอง request ไปที่ endpoint /messages ของ Resource Server โดยที่ไม่ได้กำหนด Authorization จะได้ response HTTP code 401 เนื่องจากเราไม่มีสิทธิ์ใช้งาน Resource Server และเมื่อเราใช้ token ที่ได้รับมากำหนด Authorization เป็นแบบ Bare Token ก็จะได้ response body เป็นข้อมูลของ endpoint นั้น

สรุป

จากที่ทดลองใช้ Spring Authorization Server มาสร้าง OAuth2 Authentication Server ที่อยู่ในช่วงกำลังพัฒนา จะเห็นได้ว่าตัวอย่างที่ Spring team ให้มานั้นมันยังใช้ไม่ได้เลยเสียทีเดียวทำให้ต้องมาแก้เพื่อให้รันผ่าน แต่ตัว Spring Authorization Server เองทำมาได้ดีเลยทีเดียวทำให้ง่ายต่อการนำมาประยุกต์ใช้สร้าง OAuth2 Authorization Server เอง และบาง endpoint ที่ ถ้าเราใช้ OAuth2 Authorization Server ตัวเก่า อาจจะจำเป็นต้องพัฒนาบาง endpoint เองแต่ Spring Authorization Server มีมาให้พร้อมใช้งาน OAuth2 potocol แม้ว่าจะยังไม่สมบูรณ์ ซึ่งตอนนี้ก็ได้แต่รอว่าตัว Release จะออกมาเมื่อไหร่จะได้นำมาใช้จริงๆ กันเสียที

--

--

Phayao Boonon
Phayao Boonon

Written by Phayao Boonon

Software Engineer 👨🏻‍💻 Stay Hungry Stay Foolish

Responses (1)