เรียนรู้เทคโนโลยี OAuth2

OAuth2 คืออะไร ทำไมต้องใช้

             OAuth2 คือมาตรฐานหนึ่งของระบบยืนยันตัวตน และจัดการสิทธิ์การเข้าใช้งานระบบต่าง ๆ เป็นมาตรฐาน rfc6747[1] ที่ใช้สำหรับ Client เชื่อมต่อกับ Server ที่ใช้ในการ Authen & Authorize เพื่อให้ได้รับสิ่งที่เรียกว่า Access Token เพื่อใช้แทน Username และ Password (สามารถใช้อย่างอื่นเพื่อขอ Token ก็ได้) เพื่อนำไปใช้กับบริการอื่น ๆ ทำให้มีความปลอดภัยมากขึ้น รวมถึงบอกว่าทำมีสิทธิ์ทำอะไรได้บ้างกับบริการนั้น ๆ (จริง ๆ แล้วถ้า Access Token หลุดก็เอาไปเข้าระบบอื่น ๆ ได้ อาจจะต่างตรงแค่ไม่เห็น Password) โดยแนะนำต้องใช้คู่กับ https อีกชั้นเพื่อความปลอดภัยสูงสุด โดยแสดงภาพคร่าว ๆ เป็น Protocol Flow ดังรูป[2]

              โดย Access Token จะมีเวลาจำกัดในการใช้งานเมื่อ Token หมดอายุ ก็ต้องไปขอใหม่ เมื่อเลิกใช้งานก็ขอยกเลิก Token รูปแบบการใช้งานมี 4 รูปแบบหรือเรียกว่า grant_type โดยแต่ละแบบมีรายละเอียดดังนี้[3]

  1. Authorization Codeใช้สำหรับ Web Server ที่ใช้ Code ด้านหลังในการเชื่อมต่อกับ OAuth Server โดยไม่ได้เปิดเผยให้สาธารณะเห็น อธิบายเป็นลักษณะการใช้งานคือ
    – ผู้ใช้งานเข้า Web Site
    – จะมีให้กด Login Facebook, Twitter, Google หรืออื่น ๆ 
    – เมื่อผู้ใช้กดก็จะเด้งให้ไป Login ที่ผู้ให้บริการนั้น ๆ ถ้าเคย Login ไว้แล้วก็จะข้ามขั้นตอนนี้ไป
    – ถ้าผู้ให้บริการนั้น ๆ เช่น Facebook จะให้กดยอมรับข้ออนุญาต ส่วนมากจะถามเรื่องสิทธิ์ในการเข้าถึงข้อมูลส่วนตัว
    – เมื่อผู้ใช้กดอนุญาต ก็จะกลับมายัง Web Site โดยในเบื้องหลัง WebSite จะได้ authorization code มาเรียกร้อยแล้วจากผู้ให้บริการ
    – จากนั้นทาง Web Site ก็สามารถเข้าถึงข้อมูลของผู้ให้บริการนั้น ๆ ได้ตามสิทธิที่อนุญาตไว้


    วิธีใช้ authorization code

    1. มีปุ่ม login ซึ่งมี link มี parameter คล้ายๆแบบนี้
      https://[oauth-server]/authorize?response_type=code&client_id=testclient&client_secret=testpass&redirect_uri=http%3A%2F%2F10.1.0.20%3A32778%2F%3Fauth%3Dsso
    2. เมื่อกดปุ่ม login ระบบจะต้องแจ้งว่า จะขอใช้สิทธิเรื่องใดบ้าง

    3. เมื่อผู้ใช้กดตกลงอนุญาต หน้าจอจะถูกพาไปยัง redirect_uri ที่ระบุไว้ พร้อมทั้งส่ง authorization code มาให้ด้วย
    4. ซึ่งจะมีหน้าตาประมาณนี้
       https://yoursite.com/oauth/callback?code=xxx 
    5. อ่าน code ออกมาเพื่อนำไปขอ access_token กับ API ของผู้ให้บริการ login ตัวนั้นๆ
       POST https://api.blah.com/oauth/token?grant_type=authorization_code&code=xxx&redirect_uri=xxx&client_id=xxx&client_secret=xxx 
      

      ค่า client_id, client_secret โดยมาก เจ้าของ login API (Identity provider) จะเป็นคนกำหนดมาให้

      หลังจากส่ง code ด้วย HTTP method POST และบอกว่าเป็น grant_type แบบ authorization_code ไปแล้ว client จะได้ access_token กลับมา เราจะเอา access_token นั้นในการเรียก API อื่น ๆ ต่อไป

  2. Implicit

    ใช้สำหรับ App ฝั่ง Client ซึ่งไม่จำเป็นต้องมี Web Server เป็นเหมือนการคุยระหว่าง Web Browser Client กับ OAuth Server ตรง ๆ เหมาะกับพวกที่ลงท้ายด้วย JS เช่น ReactJS, AngularJS ที่ต้องการดึงข้อมูลด้วย Browser เลย (เหมาะกับ Mobile เป็นพิเศษ) ลักษณะการทำงานคล้าย ๆ กับข้อ 1 แต่จะต่างกันตรงไม่ต้องส่ง Client_Secret เป็นวิธีที่เปิดเผยให้สาธารณะเห็น

    วิธีใช้ Implicit

    1. สร้างปุ่ม login ที่ส่ง action ไปยัง URL แบบนี้
       https://login.blah.com/oauth?response_type=token&client_id=xxx&redirect_uri=xxx&scope=email 
    2. เมื่อผู้ใช้กดปุ่ม จะแสดงหน้าต่างขอใช้สิทธิ หากตกลงข้อมูลจะ submit ไป server แล้วข้อมูล token จะถูกส่งกลับมาตาม redirect_uri ที่กำหนดเอา
    3. client_id ในข้อ 1 id provider เป็นคนกำหนดมาให้
    4. token ที่ได้มา เอาไปใช้ได้ดึงข้อมูลตามสิทธิ์ที่ได้มาได้เลย
  3. Password Credentials

    ใช้สำหรับ Application ที่มีการจัดการสิทธิเอง แต่ต้องการยืนยันตัวตนเท่านั้น ซึ่งวิธีนี้ไม่ต้อง Redirect ไปที่ผู้ให้บริการอื่น วิธีนี้เหมาะกับการใช้งานที่เป็นบริการของตัวเอง เพราะ username password จะปรากฎในเครื่องที่ส่งขอ token ถ้าไปรันวิธีนี้บน Server อื่นที่ไม่ได้เป็นเจ้าของ แสดงว่า เขาอาจจะดักเอา username password ไปใช้ก็ได้


    การใช้ Password Credentials

    1. มี form รับ username/password เมื่อกด submit แล้ว ส่ง form submit (POST method) ไปยัง server/service ของเรา
       POST https://login.blah.com/oauth/token?grant_type=password&username=xxx&password=xxx&client_id=xxx 
    2. จะได้ access_token มาใช้งานได้เลยหากใส่ข้อมูลถูกต้อง
  4. Client Credentials

    ในกรณีที่เป็นการคุยระหว่าง Application -> Service โดยจะไม่เกี่ยวข้องกับผู้ใช้ ยกตัวอย่างว่าเราอาจจะได้ข้อมูลสักอย่างแต่ต้องการความปลอดภัยว่าต้องเป็นเครื่องที่เราให้สิทธิ์ ก็สามารถส่ง id และ secret ที่ออกให้ Application ส่งมาขอ token เพื่อเข้าถึง Service นั้น ๆ ได้เลย

OAuth2 ปลอดภัยหรือไม่

      อยู่ที่การใช้งาน ว่าปลอดภัยหรือไม่ ถ้ารันบน http ธรรมดา ยังไงก็ไม่ปลอดภัย ถ้าใช้ php 4/5 หรือ windows 2003/2008/2008/2008 R2 ยังไงก็ไม่ปลอดภัย 

แล้วทำไมต้องใช้ OAuth2

– เนื่องจากเป็นมาตรฐานที่พัฒนาจาก OAuth1.0a ที่มีการใช้งานมาก ทำให้ Version 2 ซึ่งลดความซับซ้อนลง การใช้งานจึงเข้าใจง่ายขึ้น

– เร็วกว่า xml web service ใช้ json ในการสื่อสาร เพราะขนาดข้อมูลที่ส่งจะเล็กกว่ามาก

– มีผู้ให้บริการภายนอกหลากหลาย

– เหมาะกับใช้งานที่หลากหลาย เพราะรองรับหลากหลายภาษา (Java, Python, Go, .NET. Ruby, PHP, .NET, ฯลฯ)

– สามารถประยุกต์นำมาใช้งานเป็น Single Sign On ได้ (ต้องพัฒนาเพิ่มเอง ไม่มีมาให้ในมาตรฐาน)

=================================================

References :
[1] The OAuth 2.0 Authorization Framework : https://tools.ietf.org/html/rfc6749

[2] An Introduction to OAuth2 : https://www.digitalocean.com/community/tutorials/an-introduction-to-oauth-2

[3] OAuth 2.0 clients in Java programming, Part 1, The resource owner password credentials grant : https://www.ibm.com/developerworks/library/se-oauthjavapt1/index.html