Dennis Sosnoski tiếp tục loạt bài Dịch vụ Web Java Java Web services của mình với việc xem xét việc sử dụng WS-Security và sử dụng WS-SecurityPolicy chính sách an ninh dịch vụ Web trong
Trang 1Các dịch vụ Web Java: Cơ sở về WS-Security của Axis2
Cài đặt Rampart trong Axis2 và thực hiện xử lý UserNameToken
Dennis Sosnoski, Nhà tư vấn, Sosnoski Software Solutions, Inc
Tóm tắt: Tìm hiểu cách bổ sung thêm mô đun an ninh Rampart cho Apache
Axis2 và bắt đầu sử dụng các tính năng WS-Security (an ninh dịch vụ Web) trong các dịch vụ Web của bạn Dennis Sosnoski tiếp tục loạt bài Dịch vụ Web Java
(Java Web services) của mình với việc xem xét việc sử dụng WS-Security và sử
dụng WS-SecurityPolicy (chính sách an ninh dịch vụ Web) trong Axis2, bắt đầu với UsernameToken (thẻ bài tên người dùng) như là một bước đầu tiên đơn giản Một số bài viết tiếp theo sẽ đưa bạn đi tiếp với WS-Security và WS-
SecurityPolicy, khi được Axis2 và Rampart thực hiện
An ninh là một yêu cầu chính của nhiều kiểu dịch vụ doanh nghiệp Nó cũng là một khu vực nguy hiểm mà tự thân bạn cần phải cố gắng thực hiện, vì thậm chí chỉ một sự lơ đễnh nhỏ và mơ hồ có thể dẫn đến lỗ hổng nghiêm trọng Những đặc điểm này làm cho việc tiêu chuẩn hóa xử lý an ninh luôn hấp dẫn, cho phép nhiều chuyên gia đóng góp vào một tiêu chuẩn và tránh bất kỳ sự lơ đễnh cá nhân nào Các dịch vụ Web dựa trên SOAP có thể sử dụng sự hỗ trợ WS-Security rộng rãi và các tiêu chuẩn có liên quan cho các nhu cầu an ninh của chúng, cho phép cấu hình
an ninh cho mỗi dịch vụ khi thích hợp
Axis2 của Apache hỗ trợ các tiêu chuẩn an ninh này thông qua mô đun Rampart (xem Tài nguyên) Trong bài này, bạn sẽ thấy cách cài đặt, cấu hình và sử dụng Rampart với Axis2 dành cho chức năng an ninh cơ bản về việc gửi một tên người dùng và mật khẩu của một yêu cầu dịch vụ Trong các bài viết tiếp theo của loạt bài này, bạn sẽ học cách sử dụng Rampart với nhiều hình thức an ninh tinh vi hơn
Về loạt bài này
Các dịch vụ Web là một phần chủ yếu của vai trò công nghệ Java™ trong điện toán doanh nghiệp Trong loạt bài viết này, nhà tư vấn XML và các dịch vụ Web Dennis Sosnoski trình bày các khung công tác và công nghệ chính rất quan trọng với các nhà phát triển Java khi sử dụng các dịch vụ Web Hãy theo dõi loạt bài này
để cập nhật những phát triển mới nhất trong lĩnh vực này và hiểu được bạn có thể
sử dụng chúng để hỗ trợ cho các dự án lập trình của bạn như thế nào
WS-Security
Trang 2WS-Security (an ninh dịch vụ Web) là một tiêu chuẩn để bổ sung thêm bảo đảm
an ninh cho các trao đổi thông điệp của dịch vụ Web SOAP (xem Tài nguyên) Nó
sử dụng một phần tử của phần đầu (header) thông điệp SOAP để đính kèm thông
tin an ninh theo các thông báo, dưới dạng các thẻ bài (tokens) chuyển tải các kiểu
lời tự khai khác nhau (các lời tự khai này có thể bao gồm tên, mã nhận diện, khóa, các nhóm, các đặc quyền, các khả năng, và v.v) cùng với thông tin mật mã hóa và chữ ký số WS-Security hỗ trợ nhiều định dạng cho các thẻ bài, nhiều miền tin cậy, nhiều định dạng chữ ký và nhiều công nghệ mã hóa, do đó, trong hầu hết trường hợp, thông tin trong phần đầu thông điệp cần phải chứa định dạng cụ thể và định danh thuật toán cho mỗi thành phần Các thông tin bổ sung này có thể dẫn đến một cấu trúc phức tạp cho các thông tin phần đầu của thông điệp, như được hiển thị trong (đã được biên tập lại nhiều) Liệt kê 1 — một ví dụ thông điệp với chữ ký và mật mã hóa:
Liệt kê 1 Thông báo ví dụ với chữ ký và mã hóa
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" > <soap:Header>
xmlns:wsu=" oasis-200401-wss-wssecurity-utility-1.0.xsd"
wsu:Id="SecurityToken-faa295 ">MIIEC56MQswCQY </wsse:BinarySecurityToken>
Trang 3<xenc:EncryptedKey xmlns:xenc="http://www.w3.org/2001/04/xmlenc#">
<xenc:EncryptionMethod 1_5" />
Trang 4/>
<Reference URI="#Id-c80f735c-62e9-4001-8094-702a4605e429">
<Transforms>
<Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" /> </Transforms>
<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" /> <DigestValue>lKjc5nyLQDZAIu/hZb4B6mLquow=</DigestValue>
</Reference>
</SignedInfo>
<SignatureValue>TiLmWvlz3mswinLVQn58BgYS0368 </SignatureValue> <KeyInfo>
Trang 5WS-số các tùy chọn được hỗ trợ, thật khó có thể sử dụng một mô tả văn bản cho mục đích này và cấu hình thủ công việc xử lý WS-Security có thể gây ra lỗi WS-Policy (Chính sách dịch vụ Web) là một cấu trúc mục đích chung để xác định các yêu cầu
mở rộng đối với các dịch vụ Web và WS-SecurityPolicy (Chính sách an ninh dịch
vụ Web) là một phần mở rộng của Policy đặc biệt dành cho sự hỗ trợ Security Hai tiêu chuẩn này đồng thời cùng với nhau hỗ trợ việc mô tả các yêu cầu WS-Security dưới dạng máy có thể đọc được Thông tin WS-Policy và WS-SecurityPolicy có thể được sử dụng độc lập hoặc được nhúng trực tiếp bên trong các tài liệu Web Services Description Language (WSDL- Ngôn ngữ mô tả dịch vụ Web), sao cho các khung công tác dịch vụ Web có thể tự động đặt cấu hình chính mình theo các yêu cầu dịch vụ
Trang 6
Giới thiệu Rampart
Rampart là mô-đun an ninh của Axis2, hỗ trợ WS-Security, WS-SecurityPolicy, WS-SecureConversation (đối thoại an ninh dịch vụ Web) và WS-Trust (Tin cậy dịch vụ Web) Trong bài này, bạn sẽ chỉ thấy các chức năng WS-Security và WS-SecurityPolicy của Rampart; các bài viết sau sẽ cho bạn xem xét các đặc tính khác
Vì Rampart được thực hiện như là một mô đun (trên thực tế là một cặp mô đun — rampart.mar và rahas.mar), nó được cắm vào khung công tác xử lý Axis2 và thực hiện công việc của mình bằng cách chặn các thông báo tại các điểm cụ thể trong việc xử lý đi vào và đi ra, kiểm tra hoặc thực hiện các thay đổi với các thông báo khi thích hợp
Cài đặt Rampart
Rampart được phân phối dưới dạng một số tệp jar (trong thư mục lib của bản phân phối), cùng với một cặp các tệp mô đun mar (trong thư mục dist) Bạn phải thêm các tệp jar vào đường dẫn lớp (classpath) của bạn để sử dụng Rampart với Axis2 và bạn phải thêm các tệp mar vào đường dẫn lớp của bạn hoặc vào cấu trúc kho lưu trữ Axis2
Cách dễ nhất để xử lý các tệp jar và mar của Rampart là thêm chúng vào bản cài đặt Axis2 của bạn Bạn có thể chỉ cần sao chép trực tiếp các tệp jar từ thư mục lib của Rampart vào thư mục lib của Axis2 của bạn và các tệp mar từ thư mục dist của Rampart vào thư mục repository/modules của Axis2 (Bạn cũng có thể sử dụng tệp build.xml của Ant trong thư mục samples của Rampart để sao chép các tệp này tới bản cài đặt Axis2 của bạn Chỉ cần đặt biến môi trường AXIS2_HOME tới thư mục cài đặt Axis2 của bạn và chạy ant từ cửa sổ dòng lệnh mở trong thư mục sample của Rampart)
Đối với nhiều đặc tính WS-Security (An ninh dịch vụ web), bạn cũng cần phải thêm trình cung cấp an ninh Bouncy Castle vào cấu hình an ninh của JVM và tệp jar của Bouncy Castle vào bản cài đặt Axis2 của bạn Bước này — không cần thiết đối với UsernameToken mà bạn sẽ tìm hiểu về nó trong bài viết này — là bắt buộc cho các tính năng an ninh khác được trình bày sau trong loạt bài này Vì lý
do bằng sáng chế của một số thuật toán an ninh, tệp jar của Bouncy là một phần tải riêng từ Rampart (xem Tài nguyên) Hãy tải về phiên bản jar thích hợp cho thời gian chạy Java của bạn và thêm tệp jar vào thư mục lib của Axis2 Sau đó bạn cần phải thay đổi các chính sách an ninh của bản cài đặt Java của bạn để sử dụng mã Bouncy Castle bằng cách thêm một dòng vào tệp java.security có trong
Trang 7thư mục lib/security của thời gian chạy Java của bạn Hãy tìm phần của tệp có một
số dòng security.provider khác nhau và thêm vào dòng sau đây:
Một ứng dụng mẫu
Ứng dụng được cung cấp trong mã ví dụ (xem Tải về) dựa trên một ví dụ mà tôi thường sử dụng trong Liên kết dữ liệu Axis2 ("Axis2 Data Binding") để giải thích các lựa chọn liên kết dữ liệu cho Axis2 Với bài viết này và các bài viết tiếp theo
về sự hỗ trợ WS-Security của Axis2, tôi đã cắt bớt đi, xuống chỉ còn ba hoạt động: getBook, addBook, và getBooksByType Để giữ cho đơn giản, chỉ có phiên bản
mã Axis Data Binding (ADB- Liên kết dữ liệu Axis) được cung cấp, nhưng đây không phải là một yêu cầu bắt buộc để làm việc với WS-Security trong Axis2 — Rampart thực hiện WS-Security ở một mức độ độc lập với các kỹ thuật liên kết dữ liệu mà mã của bạn sử dụng, do đó nó làm việc với tất cả các hình thức liên kết dữ liệu được Axis2 hỗ trợ
Thư mục gốc của mã ví dụ là jws04code Bên trong thư mục này, bạn sẽ tìm thấy các tệp build.xml và build.properties của Ant, tệp library.wsdl đưa ra định nghĩa dịch vụ cho ứng dụng ví dụ, một tệp log4j.properties được sử dụng để cấu hình đăng nhập phía khách và một số tệp XML định nghĩa thuộc tính (tất cả các tệp có tên dạng XXX-policy-client.xml hoặc XXX-policy-server.xml) Tệp
Trang 8build.properties cấu hình hoạt động của ứng dụng ví dụ Liệt kê 2 cho thấy phiên bản được cung cấp với tệp các thuộc tính này:
Liệt kê 2 Tệp build.properties được cung cấp
# set axis-home to your Axis2 installation directory
số hiệu cổng khác cho máy chủ của bạn, bạn cũng cần phải sửa đổi các giá trị name và host-port Tôi sẽ thảo luận về các giá trị còn lại ở phần sau trong bài viết này
Trang 9
Một thử nghiệm WS-Security
WS-Security xác định một số kiểu thẻ bài (tokens) (bao gồm các thẻ bài là một
phần của đặc tả cốt lõi và những thẻ bài được định nghĩa trong lược thảo như các
phần mở rộng trình cắm thêm (plug-in) cho đặc tả đó), với nhiều tùy chọn để xây dựng và sử dụng các thẻ bài như thế nào Mục đích của bài viết này là cấu hình và
sử dụng Rampart với Axis2, vì vậy tôi sẽ chỉ sử dụng thẻ bài có ích đơn giản nhất làm một ví dụ: thẻ bài UsernameToken, được định nghĩa bởi lược thảo
UsernameToken
WS-SecurityPolicy của UsernameToken
Mục đích của một UsernameToken chỉ là để chuyển tải thông tin về tên người dùng và mật khẩu như một phần của các tiêu đề WS-Security Dạng cơ bản nhất của UsernameToken gửi cả tên người dùng và mật khẩu dưới dạng văn bản tường minh Đây không phải là tối ưu, theo quan điểm an ninh (mặc dù không có gì sai với việc sử dụng cách tiếp cận này trên các kết nối an toàn), nhưng thật dễ dàng để nhìn thấy những gì đang gửi đi, tạo cho nó một điểm khởi đầu có ích
Cấu hình WS-SecurityPolicy cho một UsernameToken được gửi dưới dạng văn bản có thể đơn giản như hiển thị trong Liệt kê 3 Chính sách này (khi hiển thị ở đây, một dòng được phân tách thành hai dòng để vừa chiều rộng trang — không hợp lệ cho việc sử dụng thực tế) bao gồm một trình bao gói (wrapper) WS-Policy tiêu chuẩn (các phần tử có sử dụng tiền tố wsp) bọc bên ngoài một xác nhận
UsernameToken của WS-SecurityPolicy
Liệt kê 3 WS-SecurityPolicy của UsernameToken văn bản tường minh
<wsp:Policy wsu:Id="UsernameToken" xmlns:wsu=
1.0.xsd"
xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy">
<wsp:ExactlyOne>
Trang 10<wsp:All>
<sp:SupportingTokens
xmlns:sp="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702"> <wsp:Policy>
<sp:UsernameToken sp:IncludeToken="http://docs.oasis-open.org/
ws-sx/ws-securitypolicy/200702/IncludeToken/AlwaysToRecipient"/> </wsp:Policy>
Áp dụng chính sách
WS-Policy và WS-SecurityPolicy được thiết kế để hỗ trợ nhúng trong các định nghĩa dịch vụ WSDL Các tham chiếu được sử dụng để kết hợp một chính sách với một hoặc nhiều định nghĩa <wsdl:binding>,
<wsdl:binding>/<wsdl:operation>, hoặc <wsdl:message> Axis2 1.4.x thực hiện việc xử lý sơ bộ cho các chính sách nhúng trong WSDL, nhưng với Axis2 1.4.1 việc triển khai thực hiện chưa mạnh Thay vào đó bài viết này gắn các chính sách trực tiếp tới máy khách và máy chủ để tương thích với mã 1.4.1
Xử lý chính sách phía máy chủ
Trang 11Đối với phía máy chủ, bạn áp dụng một chính sách bằng cách thêm nó vào tệp cấu hình services.xml được bao gồm trong tệp lưu trữ dịch vụ aar của Axis2 Chính
sách này có thể được thêm trực tiếp như là phần tử con của một phần tử <service>
để áp dụng cho tất cả các hoạt động được dịch vụ đó định nghĩa Bạn cũng cần
phải thêm một phần tử <module> vào tệp services.xml để nói cho Axis2 rằng mô
đun Rampart phải được bao gồm vào trong cấu hình cho dịch vụ này Liệt kê 4 là
một phiên bản đã chỉnh sửa của services.xml được sử dụng bởi ứng dụng ví dụ, đã
in đậm tham chiếu mô-đun và thông tin chính sách được bổ sung thêm:
Liệt kê 4 services.xml với chính sách đã nhúng thêm
</messageReceivers>
<parameter
name="ServiceClass">com.sosnoski.ws.library.adb.LibraryUsernameImpl</parameter> <parameter name="useOriginalwsdl">true</parameter>
Trang 13<ramp:passwordCallbackClass> PWCBHandler</ramp:passwordCallbackClass> </ramp:RampartConfig>
Tái tạo Services.xml một cách dễ dàng
Khi bạn sử dụng công cụ Wsdl2Java của Axis2 để tạo các tệp triển khai phía máy
chủ nó tạo ra một tệp services.xml như một phần của các tạo phẩm được sinh ra
(trong thư mục resources, dưới thư mục đích tạo ra của bạn) Bất cứ lúc nào định
nghĩa dịch vụ WSDL của bạn thay đổi, bạn phải tạo lại tệp này, vì thế yêu cầu
nhúng tham chiếu mô đun và thông tin chính sách vào trong tệp này có thể khá vất
vả Mã ví dụ bao gồm một công cụ để tự động hóa các thay đổi này cho tệp được
tạo ra: lớp com.sosnoski.ws.MergeServerPolicy (Mã nguồn và mã nhị phân nằm
trong thư mục mergetool) Đích generate-server của tệp build.xml chạy công cụ
này để chèn tham chiếu mô đun và thông tin chính sách thích hợp vào tệp
services.xml được tạo ra mỗi khi mã máy chủ được tạo ra Bạn có thể sử dụng
công cụ này cho các dự án riêng của bạn nếu bạn muốn Nó lấy đường dẫn đến tệp services.xml làm tham số dòng lệnh đầu tiên, đường dẫn đến tệp chính sách làm
tham số thứ hai và tên của bất kỳ các mô đun nào được thêm vào như là các tham
số dòng lệnh còn lại
Nếu bạn so sánh các chính sách nhúng trong Liệt kê 4 với các chính sách cơ bản
trong Liệt kê 3, bạn sẽ thấy một phần tử được thêm vào — phần tử
<ramp:RampartConfig> Phần tử này cung cấp các phần mở rộng đặc thù của
Rampart cho thông tin chính sách, trong trường hợp này là đưa ra tên của một lớp
được sử dụng để xử lý các cuộc gọi lại mật khẩu Cuộc gọi lại là cách để mã máy
chủ của bạn có thể xác minh tổ hợp tên người dùng và mật khẩu được cung cấp
bởi máy khách khi có một yêu cầu
Trang 14Liệt kê 5 cho thấy việc thực hiện thực tế của lớp gọi lại, được áp dụng cho mật khẩu văn bản tường minh Trong trường hợp này, cả hai tên người dùng và mật khẩu được cung cấp cho cuộc gọi lại và tất cả những thứ mà các cuộc gọi lại cần làm là xác minh tổ hợp đó Nếu tên người dùng và mật khẩu khớp với giá trị dự kiến, chỉ đơn giản trả về; nếu không, nó đưa ra một lỗi ngoại lệ để báo hiệu có lỗi
Liệt kê 5 Mã gọi lại mật khẩu
import org.apache.ws.security.WSPasswordCallback;
public class PWCBHandler implements CallbackHandler
{
public void handle(Callback[] callbacks)
throws IOException, UnsupportedCallbackException {
for (int i = 0; i < callbacks.length; i++) {