Chi tiết cơ chế xác thực định danh OpenID được thể hiện qua các bước sau:
Bước 1: Người dùng (USER) yêu cầu xác thực lần đầu, yêu cầu được người sử dụng gửi tới ứng dụng bên thứ ba (APPS).
Bước 2: Tại APPS, USER sẽ được redirect tới nhà cung cấp dịch vụ OpenID (PROVIDER).
Bước 3: Tại đây, PROVIDER sẽ kiểm tra thông tin của APPS, nếu có hỗ trợ dịch vụ cho APPS, PROVIDER sẽ đưa USER tới một hộp thoại Login để USER xác thực tài khoản của mình.
Bước 4: Xác thực: USER gửi thông tin tài khoản của mình cho PROVIDER để kiểm tra thông tin đăng nhập.
Bước 5: Nếu thông tin tài khoản hợp lệ, PROVIDER sẽ redirect USER tới APPS kèm theo tham số kèm chữ ký từ PROVIDER.
Bước 6: APPS sẽ gửi 1 xác nhận chữ ký thông báo tới PROVIDER thông báo xác nhận định danh.
Bước 7: APPS đồng thời cũng gửi thông báo Login thành công kèm biến lưu session, cookie cho USER, kết thúc quá trình xác thực
Giải pháp OpenId đã được nhiều hãng công nghệ lớn trên thế giới sử dụng: Facebook, Yahoo, Amazon, vv… sử dụng trong việc xác thực định danh người dùng trên các trang web của bên thứ 3 có sử dụng dịch vụ của hãng. Tuy nhiên giải pháp này còn một số hạn chế trong việc chia sẻ sử dụng tài nguyên từ provider.
4.4.Dịch vụ xác thực ủy quyền chia sẻ tài nguyên Oauth
Oauth là một giao thức mở. Giao thức này cho phép người dùng xác thực tài khoản và ủy quyền chia sẻ nguồn tài nguyên từ Service Provider cho các bên ứng dụng thứ 3 (APPS) mà không phải cung cấp tên đăng nhập và mật khẩu cho các ứng dụng này.
Cũng tương tự như OpenID, giao thức xác thực của Oauth cũng bao gồm 3 thành phần: nhà cung cấp dịch vụ (Service Provider - SP), người sử dụng dịch vụ (Service User - SU) và bên ứng dụng thứ 3 khai thác tài nguyên (Service Consumer - SC).
Ở mô hình chuẩn mở, tổ chức sử dụng Oauth đề xuất quy trình xử lý xác thực, ủy quyền như sau:
Hình 21: Quy trình xử lý xác thực, ủy quyền khai thác tài nguyên dịch vụ (Nguồn: Oauth.net)
Ở quy trình này, Oauth đề ra 7 bước để hoàn thành xác thực tài khoản và ủy quyền truy xuất tài nguyên:
Bước 1 - Consumer request: phía SC gửi yêu cầu truy xuất tài nguyên tới SP thông qua Request Token trong request này bao gồm:
- Oauth_consumer_key: khóa xác thực consumer đăng ký với SP - Oath_signature_method: Phương thức ký xác thực oauth
- Oauth_signature: chữ ký
- Oauth_timestamp: thời hạn xác thực - Oauth_nonce:
- Oauth_version: phiên bản Oauth
- Oauth_callback: triệu gọi sau xác thực.
Bước 2 - Grant request token: SP cấp Request Token cho SC. Gói tin Request Token SP gửi cho SC bao gồm:
- Oauth_token: mã token xác thực (công khai) - Oauth_token_secret: mã token xác thực (bí mật) - Oauth_callback_confirmed: Xác nhận triệu hồi
Bước 3 – Direct user: SC chuyển hướng SU về hộp thoại xác thực của SP kèm theo oauth_token đã nhận được từ SP.
Bước 4 – Obtain User Authorization: Tại bước này SU tiến hành cung cấp thông tin xác thực tài khoản cho SP, SP tiến hành xác thực thông tin này, nếu đúng sẽ chuyển hướng SU trở về SC. Khi chuyển về SC, SP gửi kèm theo các thông tin:
- Oauth_token: mã token xác thực (công khai) - Oauth_verifier: Xác minh Oauth
Bước 5 – Request Access Token: SC sau khi nhận được các thông tin xác thực từ phía SP, lúc này SC gửi tiếp yêu cầu Access Token cho SP bao gồm các thông tin:
- Oauth_consumer_key - Oauth_token - Oath_signature_method - Oauth_signature - Oauth_timestamp - Oauth_nonce - Oauth_version - Oauth_verifier
Bước 6 – Grant Access Token: SP tiến hành kiểm tra các thông tin yêu cầu từ SC và cấp thông tin truy cập cho SC bao gồm:
- Oauth_token
- Oauth_token_secret
Bước 7 – Consumer Access Protected Resource: Kể từ bước này, Consumer có thể truy cập những tài nguyên được bảo vệ từ SP thông qua các thông tin mà SP đã cung cấp cho SC. Mỗi yêu cầu về tài nguyên của SC lúc này bao gồm:
- Oauth_consumer_key - Oauth_token - Oath_signature_method - Oauth_signature - Oauth_timestamp - Oauth_nonce - Oauth_version
Qua tìm hiểu, nghiên cứu và tiến hành thực nghiệm trên thực tế, phương thức xác thực, ủy quyền chuẩn Oauth cho thấy phù hợp với mô hình thương mại có quy mô lớn. Nếu áp dụng cho bài toán đã nêu trong luận văn tỏ ra không phù hợp vì có nhiều quy trình phức tạp, nhưng lại không thật cần thiết với đặc thù bài toán đặt ra. Do vậy, tôi xin đề xuất mô hình Oauth với cơ chế cải tiến để phù hợp với thực tiễn áp dụng.
4.5.Cơ chế xác thực Oauth đề xuất cho bài toán
Cơ chế đề xuất dựa trên những đặc điểm cơ bản từ cơ chế Oauth chuẩn, đơn giản hóa cấu trúc gói tin và lược bỏ bớt những thông tin không thật cần thiết mà vẫn đảm bảo các chính sách với bên phát triển ứng dụng thứ 3.
Hình 22: Quy trình xử lý xác thực, ủy quyền truy xuất tài nguyên đề xuất với bài toán hiện tại
Trong đề xuất này, cơ chế xác thực vẫn giữ lại những đặc điểm quan trọng từ mô hình chuẩn: token, secret_token, authorization của User tại Service Provider, access token, vv..
Cụ thể quy trình xử lý tuân theo các bước sau:
Bước 1: Khi SC muốn sử dụng tài nguyên tại SP, SU xác nhận yêu cầu của SC
Bước 2: SC gửi request token tới SP. Gói tin bao gồm: - Consumer_key
- Consumer_secret_key
Bước 3: SP kiểm tra thông tin SC đã đăng ký tại SP, nếu thỏa mãn, sẽ gửi trả lại lại SC yêu cầu redirect SU tới SP và kèm theo thông tin:
- Token_key
- Secret_token_key
Bước 4: SC tiến hành redirect SU tới trang xác thực của SP, thông tin gửi kèm bao gồm:
- Consumer_key - Token_key
Bước 5: Người dùng tiền hành xác thực tài khoản của mình tại SP, SP kiểm tra thông tin, nếu thỏa mãn SP sẽ chuyển tiếp SU về SC kèm theo trạng thái xác thực cho SC. Thông tin gửi về SC bao gồm:
- Token_key - Oauth_verifier - Oauth_permission
Bước 6: SC gửi yêu cầu access token cho SP cho phiên làm việc. Thông tin gửi đi bao gồm:
- Consumer_key - Token_key
Bước 7: SP kiểm tra thông tin SC gửi, nếu thỏa mãn SP gửi lại access token cho SC. Thông tin gửi đi bao gồm:
- Token_key - Access_token
Bước 8: Khi cần truy xuất tài nguyên, SC gửi yêu cầu kèm theo access token tới SP. Thông tin gửi bao gồm:
- Token_key - Access_token - Request_data
Bước 9: SP trả lại dữ liệu cho SC, thông tin bao gồm: - Token_key
- Data
4.6.Những vấn đề phát sinh của Oauth trên môi trường thiết bị di động
Cơ chế xác thực cải tiến từ Oauth đã được phát triển và sử dụng thí điểm cho 3 bài toán trong hệ thống phần mềm quản lý viễn thông. Tuy nhiên, trong tương lai, hệ thống mở rộng môi trường làm việc trên các thiết bị di động. Đây là một môi trường có đặc thù riêng, không giống môi trường ứng dụng trên desktop. Trong quá trình phát triển chúng tôi đã gặp phải một số vấn đề phức tạp cần giải quyết.
Có 3 vấn đề chính nổi lên khi ta bắt đầu phát triển ứng dụng với các thiết bị di động (ở đây ta xét tới các thiết bị di động sử dụng nền tảng hệ điều hành Android):
Vấn đề thứ nhất:
Các yêu cầu theo giao thức HTTP không được chứng thực, vậy bằng cách nào ta biết được những yêu cầu này được gửi từ một user nào đó?
Nếu đưa trực tiếp username và password trong HTTP request thì không an toàn. Để giải quyết vấn đề này, Twitter sử dụng OAuth để xác thực yêu cầu của người dùng tới dịch vụ. Tương tự như vậy Yahoo sử dụng OpenId cho cùng mục đích này.
Nhưng cả 3 giải pháp OAuth và OpenId đều không khả thi với bài toán hiện tại vì nó quá phức tạp.
Ví dụ như giải pháp OAuth, giải pháp này cần tới 2 bước để truy cập vào token Theo quy trình xử lý trên, User sẽ bị redirect từ ứng dụng hiện tại tới trình duyệt để cấp xác thực cho ứng dụng đó sau đó lại redirect lại. Nếu trường hợp là trên trình duyệt máy tính, điều này là hợp lý .Nhưng khi xử lý trên môi trường các thiết bị di động, nơi tốc độ truy cập mạng thường bị giới hạn điều nay sẽ ảnh hưởng rất lớn tới trải nghiệm của người dùng. Đây là vấn đề quan trọng yêu cầu phải giải quyết.
Vấn đề thứ hai:
Các URL của dịch vụ WCF thường không đủ tường minh cho các lập trình viên di động sử dụng. Chúng ta cần phải làm tất cả các dịch vụ WCF minh bạch hơn, từ đó các lập trình viên di động có thể sử dụng nó như các phương thức cục bộ. Điều này sẽ làm cho việc phối hợp nhóm thuận tiện hơn và đảm bảo duy trì các dịch vụ mở.
Vấn đề thứ ba:
Trong vấn đề xác thực User, mặc dù nền tảng .Net đã hỗ trợ các giải pháp xác thực như: Windows User Authentication, X509 certificate, Issued Token, vv.. Vẫn chưa có giải pháp nào phù hợp hoàn toàn với các ứng dụng mobile hoặc chưa mềm dẻo để mở rộng. Các phiên bản trước .WCF 4.0, RequestInterceptor là một giải pháp hoàn hảo tuy nhiên tới WCF 4.0 RequestInterceptor không còn được hỗ trợ.
4.7.Giải pháp XAuth và Service Authorization manager
Để giải quyết 3 vấn đề gặp phải, ta cần phải giải quyết từng vấn đề. Vấn đề đầu tiên, làm thế nào để ta có thể phân biệt các xác thực User?
OAuth quá nặng nề và thường được sử dụng trong môi trường thương mại vì OAuth hầu như phù hợp cho các API từ bên thứ ba.
XAuth kém an toàn hơn nếu sử dụng cho bên thứ ba, nhưng ở hoàn cảnh này, ta đang xây dựng các dịch vụ cho các ứng dụng riêng không có sự tham gia từ bên thứ ba, và trong tương lai cũng vậy. Do vậy, XAuth là sự lựa chọn tốt.
Hình 23: Xử lý xác thực theo cơ chế XAuth [4]
Vấn đề thứ hai, REST (Representational State Translate) là một lựa chọn tốt để xây dựng những dịch vụ thỏa mãn cả 2 tiêu chí tường mình và dễ sử dụng. REST là một kiểu kiến trúc để xây dựng những các ứng dụng phân tán lai trong đó bao gồm kiến trúc hướng dịch vụ bằng cách định nghĩa những bộ công cụ sử dụng chuẩn HTTP (GET, POST, PUT, DELETE) và có thể định vị bởi một URL. Và kể từ .Net 3.5, WCF đã hỗ trợ xây dựng kiểu dịch vụ REST.
Vấn đề thứ 3 là về việc Host cho dịch vụ XAuth. ServiceAuthorizationManager là công cụ thích hợp cho yêu cầu này. ServiceAuthorizationManager cung cấp một phương thức là CheckAccessCore, phương thức này hỗ trợ chúng ta can thiệp vào từng lời gọi tới dịch vụ WCF. Mặc dù ServiceAuthorizationManager không được thiết kế dành riêng cho những ứng dụng loại này. Sau khi thực hiện xác thực, chúng ta cần phải đăng ký nó với file cấu hình, sau đó xác thực này sẽ có hiệu lực với tất cả các lời gọi tới dịch vụ.
Hình 24:Cơ chế làm việc của AuthorizationManager [4]
Sau khi xác định được các vấn đề và tìm kiếm giải pháp ta tiến hành xây dựng demo giải pháp với hệ thống đã có.
Đầu tiên, ta xây dựng một dịch vụ RESTful WCF. Dịch vụ này sẽ kiểm tra header của yêu cầu để trả lại các thông tin mà User cần. Để làm các dịch vụ dễ sử dụng, các URL của WCF cần tuân theo dạng REST.
Ví dụ:
http://203.160.20.118/OAuthService/appService/notice/latest http://203.160.20.118/OAuthService/appService/more/{id}
Tiếp theo ta sẽ tạo Request Filter MyServiceAuthorizationManager được kế thừa từ lớp ServiceAuthorizationManager. Sau đó ghi đè lên phương thức CheckAccessCore.