text:
Trước khi bạn bắt đầu
Trong hướng dẫn này bạn sẽ tìm hiểu về An ninh của Các dịch vụ Web hoặc Các dịch vụ Web-An ninh (WS-Security). Hướng dẫn này dành cho các nhà phát triển muốn trưng ra các dịch vụ của mình trong một môi trường đòi hỏi phải bảo vệ các thông báo khỏi bị làm giả hoặc bị đọc trong lúc chuyển tiếp hoặc trong các tình huống trong đó phải nhận dạng rõ ràng người gửi. Thuật ngữ "Các dịch vụ Web-An ninh" (WS-Security) thường được dùng để chỉ một nhóm các đặc tả xử lý mã hóa và các chữ ký số, cho phép bạn tạo một ứng dụng an toàn.
Để làm theo cùng với hướng dẫn này, bạn nên có một sự hiểu biết cơ bản về SOAP, bạn có thể đạt được điều này bằng cách đọc Phần 1 của loạt bài hướng dẫn này và về phần mở rộng, bạn cần có một sự hiểu biết cơ bản về XML. SOAP là thuyết bất khả tri của ngôn ngữ lập trình, nhưng các ví dụ trong hướng dẫn này sử dụng các dự án Java ™ và Axis2 Apache. Tuy nhiên, các khái niệm này áp dụng cho môi trường và ngôn ngữ lập trình bất kỳ.
Về loạt bài này
Loạt bài hướng dẫn này dạy các khái niệm cơ bản về các dịch vụ Web bằng cách tiếp tục khai thác về tờ báo hư cấu, The Daily Moon (Mặt trăng hàng ngày), khi các nhân viên sử dụng các dịch vụ Web để tạo ra một hệ thống tiến trình công việc để tăng năng suất trong nhiều thay đổi.
Phần 1 đã giải thích các khái niệm cơ bản đằng sau các dịch vụ Web và đã dạy cách sử dụng SOAP, đặc tả này làm cơ sở cho hầu hết những cái sắp tới, kết nối phòng chuyên mục rao vặt với Hệ thống quản lý nội dung.
Phần 2, đưa mọi thứ tiến lên một bước xa hơn, khi giải thích cách sử dụng WSDL (Web Services Description Language - Ngôn ngữ mô tả các dịch vụ Web) để định nghĩa các thông báo được các dịch vụ Web tạo ra như mong đợi, cho phép nhóm làm việc tạo ra các dịch vụ và các ứng dụng khách để kết nối với chúng dễ dàng hơn.
Phần 3 tìm nhóm làm việc có một số dịch vụ tại chỗ và có một mong muốn định vị các dịch vụ dễ dàng. Đáp lại, UDDI (Universal Description, Discovery and Integration - Tích hợp, khám phá và mô tả đa năng) cung cấp một đăng ký có thể tìm kiếm được của các dịch vụ có sẵn theo cách đưa ra công khai các dịch vụ riêng của họ cho những người khác.
Bây giờ trong Phần 4, Rudy, chủ báo The Daily Moon, đã quyết định tờ báo này cần xây dựng các giao thức an ninh tốt hơn cho các dịch vụ Web để truy cập các hệ thống nội bộ của tờ báo.
Trong Phần 5, Các dịch vụ Web-Chính sách (WS-Policy), chúng ta sẽ xem xét các thay đổi mà các nhóm làm việc cần thực hiện để truy cập các dịch vụ mới được bảo vệ đó.
Tính tương thích là từ khóa trong phần 6, do các dịch vụ từ các cách hiện thực khác nhau phải được truy cập từ một hệ thống đơn. Phần 6 cũng sẽ trình bày các yêu cầu và các thử nghiệm liên quan đến việc cấp chứng chỉ Các dịch vụ Web-Tính tương thích (WS-I).
Cuối cùng, phần 7 dạy cách sử dụng WS-BPEL (Ngôn ngữ thực hiện qui trình kinh doanh) để tạo các ứng dụng phức tạp từ các dịch vụ riêng biệt.
Bây giờ hãy xem xét hướng dẫn này trình bày những gì cụ thể hơn một chút.
Về hướng dẫn này
Trong hướng dẫn này, bạn sẽ làm theo khi nhóm làm việc của tờ báo The Daily Moon sử dụng các đặc tả Các dịch vụ Web-An ninh để bảo vệ một trong các dịch vụ Web đã mô tả ở trên trong loạt bài này.
Theo tiến trình của hướng dẫn này, bạn sẽ học:
- Các dịch vụ Web-An ninh là gì.
- Sự khác biệt giữa mã hóa đối xứng và bất đối xứng.
- Sự khác biệt giữa các chữ ký và mã hóa.
- Hiệu quả của an ninh trên các thông báo SOAP.
- Làm thế nào để bảo vệ một dịch vụ web SOAP bằng cách sử dụng Axis2.
Trước khi chúng ta bắt đầu, bạn sẽ cần một vài công cụ.
Các điều kiện cần trước
Nhiều thứ trong hướng dẫn này thuộc về khái niệm, nhưng để làm theo cùng với các mã tạo các thông báo SOAP, bạn sẽ cần có sẵn phần mềm sau đây đã được cài đặt:
Chúng tôi sẽ giới thiệu cách cài đặt và sử dụng Apache Geronimo, đây cũng là cơ sở cho IBM Community Edition (Ấn bản cộng đồng của WebSphere của IBM). Ngoài ra bạn có thể sử dụng các máy chủ ứng dụng khác như là máy chủ ứng dụng WebSphere. Bạn có thể tải Apache Geronimo. Để biết thêm thông tin về cài đặt Geronimo, xem Phần 1 của loạt bài này.
Bạn sẽ sử dụng Apache Axis2, có chứa các thực hiện của các API có liên quan đến SOAP khác nhau để làm cho cuộc sống của bạn dễ dàng hơn. Bạn có thể tải Apache Axis2 từ Apache.org. Hướng dẫn này sử dụng phiên bản 0.94, nhưng các phiên bản mới hơn cũng sẽ hoạt động.
Mô đun Rampart của Apache Axis2 -- An ninh cho máy các dịch vụ Web Axis2 được cung cấp thông qua mô đun Rampart, nó không bao gồm trong bản cài đặt mặc định. Hãy tải về mô đun này từ Apache Download Mirrors.
Apache WSS4J -- Mặc dù chính Axis sẽ sử dụng Rampart, tại một số điểm mà bạn cần tham chiếu hướng dẫn các lớp WSS4J. Hãy tải về gói WSS4J package.
Ấn bản tiêu chuẩn Java 2 (Java 2 Standard Edition) phiên bản 1.4.2 hoặc cao hơn -- Tất cả các công cụ này dựa trên Java, chẳng hạn như các dịch vụ và ứng dụng khách mà bạn sẽ xây dựng trong hướng dẫn này. Hãy tải J2SE SDK.
TCPMon (tùy chọn) -- TCPMon là cách dễ dàng hơn để hiểu những gì đang diễn ra trong một ứng dụng dịch vụ web khi bạn thực sự có thể nhìn thấy các thông báo. Tải TCP Monitor để bạn có thể xem các thông báo đến và từ các dịch vụ Web.
GnuPG (tùy chọn) - Tất cả về việc ký thông báo mà chúng tôi sẽ làm được chính Axis2 và Java trình bày, nhưng nếu bạn muốn bàn đến việc ký các tài liệu riêng, như chúng tôi sẽ trình diễn ngắn gọn, hãy tải về GnuPG.
Bạn cũng sẽ cần một trình duyệt Web và một trình soạn thảo văn bản.
Tổng quan
Trước khi chúng ta nói về việc bảo vệ một dịch vụ, thật có ích để biết chính xác các phần nào tạo nên dịch vụ đó để biết những gì đã được thực hiện.
Câu chuyện tiếp tục cho đến nay
Loạt bài hướng dẫn này tiếp tục các hoạt động của các nhân viên của tờ báo Daily Moon (Mặt Trăng hàng ngày). Tờ báo này đã phát hiện ra cách làm việc mới dưới dạng các dịch vụ Web. Tất cả cách làm việc mới này đã bắt đầu trong phòng chuyên mục rao vặt. Phòng này đã quyết định cho phép những người khác truy cập vào hệ thống của mình thông qua việc sử dụng các thông báo SOAP -- các thông báo XML có thể được gửi qua HTTP.
Ví dụ, một yêu cầu cho một số trong các đoạn quảng cáo được phân loại thành thể loại con "để bán" có thể trông giống như Liệt kê 1.
Liệt kê 1. Một thông báo SOAP ví dụ
<?xml version='1.0' ?> <env:Envelope xmlns:env="http://www.w3.org/2003/05/SOAP-envelope"> <env:Header> </env:Header> <env:Body> <cms:getNumberOfArticles xmlns:cms="http://www.daily-moon.com/cms"> <cms:category>classifieds</cms:category> <cms:subcategory>forsale</cms:subcategory> </cms:getNumberOfArticles> </env:Body> </env:Envelope>
Thông báo tổng thể được gọi là Phong bì (Envelope), với các nội dung trong đó bao gồm phần Tiêu đề (Header) và phần Thân (Body). Tiêu đề chứa thông tin về chính thông báo đó, chẳng hạn như thông tin định tuyến, hoặc các thông tin dự kiến do "các phương tiện trung gian SOAP" xử lý hoặc dịch vụ giữa người gửi và người nhận cuối có thể xử lý thông báo. (Trong trường hợp này, hãy xem bất kỳ trong số các tiêu đề đó, nhưng đây là nơi thông tin an ninh của chúng ta sẽ gửi đi). Phần Thân của thông báo bao gồm "tải trọng" có các dữ liệu thực sự được chuyển tới dịch vụ Web.
Trong trường
hợp này, trọng tải là phần tử
getNumberOfArticles và nội
dung của nó.
Gene và Frances, từ bộ phận IT của tờ báo này, đã ráp một hệ thống vào với nhau để phục vụ các yêu cầu của các dịch vụ web, cũng như cơ sở hạ tầng để phát hiện và tự động tạo ra các ứng dụng khách cho các dịch vụ. Bây giờ chủ báo, Rudy, đang nhấn mạnh rằng họ tìm thấy cách để ngăn chặn truy cập trái phép vào các hệ thống này.
Nhu cầu an ninh
Đặc tả SOAP cơ bản không lo liệu cho việc bảo vệ các thông báo, mà để lại nhiệm vụ đó cho các đặc tả mở rộng. Vấn đề nằm ở tính chất của một ứng dụng của các dịch vụ Web. Trong hầu hết các trường hợp, chúng ta đang đề cập đến SOAP trên HTTP, có nghĩa là mỗi thông báo phải đi qua một hoặc nhiều nút trung gian, và bất kỳ một trong số các nút đó có thể đọc và/hoặc thay đổi một thông báo. Và điều đó thừa nhận rằng bản thân yêu cầu SOAP đã là một yêu cầu trực tiếp. Trong một số trường hợp, các thông báo SOAP được thiết kế đặc biệt để đi qua nhiều hơn một nút trước khi tới điểm đến cuối cùng của chúng.
Kết quả cuối cùng là chúng ta cần một cách để ngăn chặn một ai đó không phải là người nhận được dự kiến đọc các thông tin nhạy cảm, để ngăn chặn việc nghe trộm. Chúng ta cũng cần một cách để ngăn chặn một ai đó không phải là người gửi được dự kiến gửi đi các thông báo, để ngăn chặn truy cập trái phép.
Đặc tả SOAP cung cấp một phương tiện để bổ sung các thông tin an ninh -- chúng ta thêm thông tin vào một phần tử Tiêu đề của Phong bì -- nhưng không xác định các thông tin nên là gì. Để bảo vệ nó, chúng ta cần Các dịch vụ Web-An ninh (WS-Security).
Các phần về Các dịch vụ Web-An ninh
Có ba vấn đề chủ yếu cần có trong việc đảm bảo an ninh cho các trao đổi thông báo SOAP và Các dịch vụ Web-An ninh cung cấp các câu trả lời cho tất cả các vấn đề đó, nhưng không trực tiếp. Trong thực tế, Các dịch vụ Web-An ninh là một đặc tả không nói về cách bảo vệ thông báo, mà nói về cách giúp cho người nhận biết cách bạn đã bảo vệ thông báo. Để thực hiện việc bảo vệ trên thực tế, Các dịch vụ Web-An ninh tham chiếu các đặc tả bổ sung. Hãy xem Các dịch vụ Web-An ninh hoạt động như thế nào.
Vấn đề đầu tiên là nhận dạng và xác thực ứng dụng khách. Vì có rất nhiều cách khác nhau để tạo ra các thẻ an ninh, nên Các dịch vụ Web-An ninh không xác định bất kỳ phương tiện cụ thể nào, mà định nghĩa cách các thẻ an ninh khác nhau sẽ được chuyển giao trong các thông báo SOAP. Nói cách khác, nó cho phép người nhận biết cách trích xuất các thẻ an ninh khỏi thông báo để xử lý.
Vấn đề thứ hai là đảm bảo tính toàn vẹn của thông báo. Các dịch vụ Web-An ninh sử dụng các chữ ký số cho việc đó, sử dụng đặc tả Chữ ký XML hơn là phát minh ra một vài thứ mới. Chữ ký XML là một khuyến nghị của W3C cung cấp một cơ chế cho việc ký bằng số các tài liệu XML.
Vấn đề thứ ba là giữ cho thông báo khỏi bị nghe trộm trong khi nó chuyển tiếp. Một lần nữa, Các dịch vụ Web-An ninh sử dụng một tiêu chuẩn W3C khác, lần này là Mã hóa XML (XML Encryption), cung cấp một cơ chế để mã hóa các tài liệu XML.
Trong hướng dẫn này, chúng ta sẽ xem việc sử dụng các tiêu chuẩn này ảnh hưởng đến các thông báo SOAP thực tế thường dùng như thế nào, khi Frances và Gene thực hiện bảo vệ dịch vụ của chuyên mục Rao vặt hiện có.
Dịch vụ hiện tại
Trước khi chúng ta xem xét thực hiện các thay đổi, thật có ích để xem nơi Gene và Frances sẽ bắt đầu. Dịch vụ của của chuyên mục Rao vặt được triển khai thực hiện bằng cách sử dụng Axis2, có nghĩa là nó có chứa trong một tệp *.aar. Tệp CMSService.aar có ba tệp, như trong Liệt kê 2.
Liệt kê 2. Các nội dung của dịch vụ đầu tiên
CMSService.class meta-inf/Manifest.MF meta-inf/services.xml
Bản thân lớp này là đơn giản, nó nhận một thông báo SOAP liệt kê một thể loại và trả về một thông báo SOAP bao gồm một số các đoạn quảng cáo cho thể loại đó. Nó thực hiện chức năng này khi được tệp services.xml định nghĩa (xem Liệt kê 3).
Liệt kê 3. Tệp services.xml đầu tiên
<service name="CMSService"> <description> This is a sample Web Service for the newspaper's Content Managment System. </description> <parameter name="ServiceClass" locked="false">CMSService</parameter> <operation name="getNumberOfArticles"> <messageReceiver class= "org.apache.axis2.receivers.RawXMLINOutMessageReceiver"/> </operation> </service>
Việc bảo vệ dịch vụ đòi hỏi chỉ chạm vào tệp services.xml; Gene và Frances sẽ không hề phải chạm vào lớp Java thực tế.
Ứng dụng khách hiện tại
Bản thân ưng dụng khách là khá đơn giản và chỉ cần tạo và hiển thị yêu cầu, như trong Liệt kê 4:
Liệt kê 4. Lớp ứng dụng khách đầu tiên
import org.apache.axis2.Constants; import org.apache.axis2.addressing.EndpointReference; import org.apache.axis2.client.Options; import org.apache.axis2.client.ServiceClient; import org.apache.axiom.om.OMElement; import org.apache.axiom.om.OMAbstractFactory; import org.apache.axiom.soap.SOAPFactory; import org.apache.axiom.om.OMNamespace; import org.apache.axis2.context.ConfigurationContext; import org.apache.axis2.context.ConfigurationContextFactory; public class ClassifiedClient { private static EndpointReference targetEPR = new EndpointReference( "http://localhost:8888/axis2/services/CMSService"); public static OMElement getNumOfArticlesOMElement() { SOAPFactory fac = OMAbstractFactory.getSOAP12Factory(); OMNamespace omNs = fac.createOMNamespace( "http://daily-moon.com/cms", "cms"); OMElement method = fac.createOMElement("getNumberOfArticles", omNs); OMElement value = fac.createOMElement("category", omNs); value.addChild(fac.createOMText(value, "classifieds")); method.addChild(value); return method; } public static void main(String[] args) { try { OMElement payload = ClassifiedClient.getNumOfArticlesOMElement(); Options options = new Options(); options.setTo(targetEPR); options.setTransportInProtocol(Constants.TRANSPORT_HTTP); ServiceClient sender = new ServiceClient(); sender.setOptions(options); OMElement result = sender.sendReceive(payload); String response = result.getText(); System.out.println("There are "+response+ " classifieds at the moment."); } catch (Exception e) { System.out.println(e.toString()); } } }
Lưu ý rằng Gene đã thay đổi cổng điểm cuối thành 8888, thay cho 8080, cổng mà máy chủ Geronimo đang nghe. Gene làm điều đó để chèn một bước bổ sung sao cho anh ta có thể nhìn thấy các thông báo bay qua bay lại.
Xem các thông báo
Để xem các thông báo SOAP thực tế, hãy tải TCPMon từ http://ws.apache.org/commons/tcpmon/download.cgi. (Đúng, Axis2 đi kèm với SOAPMonitor, nhưng Gene đã phát hiện ra cách phức tạp nằm ngoài những rắc rối trong việc thiết lập những thứ đó, nó cho thấy SOAP nhưng không nhất thiết phải là các thông báo thô, mà chúng ta rõ ràng sẽ muốn xem).
Sau khi tải về, giải
nén ứng dụng đó và chạy tệp
tcpmon-1.0-bin\build\tcpmon.bat. Nhấn vào tab Admin và tạo một người nghe
mới, như trong Hình 1.
Hình 1. tab Admin của TCPMon
Chọn 8888 là một cổng nghe và xác định 8080 là cổng đích, để cho TCPMon nằm giữa ứng dụng khách và máy chủ. Nhấn Add và sau đó nhấn vào thẻ Port 8888. Nhấn vào hộp chọn XML Format. Bây giờ khi Frances thực hiện ứng dụng khách, Gene có thể thấy yêu cầu và đáp ứng, như trong Hình 2.
Hình 2. Yêu cầu và đáp ứng đầu tiên
Trước khi đi tiếp, chúng ta hãy xem xét nhanh các thông báo thực tế, để chúng ta có thể biết những gì thay đổi.
Các thông báo
Bản thân các thông báo rất đơn giản. Yêu cầu, như đã thấy trong Liệt kê 5, chỉ yêu cầu số lượng các đoạn quảng cáo được phân loại trong hệ thống:
Liệt kê 5. Yêu cầu đầu tiên
<?xml version='1.0' encoding='UTF-8'?> <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"> <soapenv:Header /> <soapenv:Body> <cms:getNumberOfArticles xmlns:cms="http://daily-moon.com/cms"> <cms:category>classifieds</cms:category> </cms:getNumberOfArticles> </soapenv:Body> </soapenv:Envelope>
Đáp ứng cũng không kém phần đơn giản, như bạn có thể thấy trong Liệt kê 6:
Liệt kê 6: Đáp ứng đầu tiên
<?xml version='1.0' encoding='UTF-8'?> <soapenv:Envelope xmlns:soapenv= "http://schemas.xmlsoap.org/soap/envelope/"> <soapenv:Header /> <soapenv:Body> <resp:numberOfArcticles xmlns:resp="http://daily-moon.com/cms/" xmlns:tns="http://ws.apache.org/axis2" >42</resp:numberOfArcticles> </soapenv:Body> </soapenv:Envelope>
Trong cả hai thông báo này, Frances sẽ đặt thông tin bổ sung trong phần tử Tiêu đề (Header) cho máy chủ (hoặc ứng dụng khách) xử lý.
Vào lúc này, bất cứ ai có thể gửi một yêu cầu đến dịch vụ và nhận được một đáp ứng và đó là điều làm cho Rudy không an tâm. Rudy muốn dịch vụ đó được thiết lập sao cho chỉ có những người dùng được ủy quyền mới có thể nhận được thông tin và sao cho các đối thủ cạnh tranh không thể thu chặn các thông tin. Rudy suy nghĩ rằng đây là một hệ thống bằng chứng-theo- khái niệm tốt. Rudy thực sự càng lo ngại hơn về các hệ thống phức tạp hơn, chẳng hạn như những hệ thống thêm nội dung hoặc truy cập vào hệ thống kế toán. Nhưng các khái niệm cũng như nhau thôi.
Để cung cấp an ninh, Gene và Frances cần sử dụng mã hóa và công nghệ liên quan của nó, các chữ ký.
Mã hóa và các chữ ký
Đa số các biện pháp an ninh đòi hỏi một hình thức mã hóa hay cách khác hoặc mã hóa đã hoạt động trong một chữ ký số, vì vậy trước khi Frances cho phép Gene bắt đầu lựa chọn cấu hình an ninh của dịch vụ, cô ấy muốn chắc chắn rằng họ hiểu những gì họ đang bàn đến.
Các kiểu mã hóa
Mã hóa là một quá trình che dấu thông tin để làm cho không thể đọc thông tin đó mà không có kiến thức đặc biệt. Lịch sử đã biết nhiều loại mã hóa khác nhau. Mã hóa hiện đại thường là một chuỗi các phép biến đổi rõ ràng được áp dụng cho một thông báo và một số dạng "khóa". Kết quả là các câu không thể đọc được. Giải mã là một quá trình ngược lại và cũng bao gồm một khóa, do đó bằng cách giữ bí mật khóa người ta có thể có cơ sở chắc chắn rằng không ai khác có thể đọc được thông báo đã mã hóa.
Các phương thức mã hóa hiện đại có thể được phân loại theo cách chúng sử dụng một hoặc hai khóa. Trong một thuật toán khóa đối xứng (ví dụ, DES), người gửi và người nhận phải có một khóa dùng chung được thiết lập trước và giữ bí mật với tất cả các bên khác; người gửi sử dụng khóa này để mã hóa còn người nhận sử dụng một khóa giống như vậy để giải mã. Trong trường hợp này, bản thân khóa là không quan trọng, trừ ra nó cần được cả hai bên liên quan biết đến và chỉ có hai bên đó mà thôi.
Trong một thuật toán khóa không đối xứng (như RSA), có hai khóa riêng biệt: một khoá công khai (public key) được công bố và được nhiều người biết đến thuộc về một cá nhân (hoặc tổ chức) cụ thể, trong khi một khóa riêng (private key) tương ứng được giữ bí mật. Một thông báo được mã hoá bằng khoá công khai chỉ có thể được giải mã bằng khoá riêng, do đó bất cứ ai cũng có thể gửi thông báo riêng cho một cá nhân cụ thể. Và điều ngược lại cũng đúng, do đó một thông báo có thể được giải mã bằng khoá chung của một cá nhân phải được cá nhân đó gửi đi. Chúng ta sẽ xem điều này bắt đầu có hiệu lực như thế nào trong việc mã hoá và việc ký các thông báo SOAP.
.
Mã hóa một tệp
Gene quyết định bắt đầu bằng cách xem mã hóa tác động đến văn bản thông báo thực tế như thế nào. Gene bắt đầu với một tệp văn bản, msg.txt, chứa một dòng duy nhất, như bạn có thể thấy trong Liệt kê 7.
Liệt kê 7. Văn bản đích
Hello, world!
Để làm cho mọi thứ đơn giản, Gene đã sử dụng chương trình GnuPG miễn phí, thực hiện lệnh được hiển thị trong Liệt kê 8.
Liệt kê 8. Lệnh mã hóa
gpg.exe -c -a --cipher-algo 3DES msg.txt
Lệnh này làm cho chương trình sử dụng thuật toán khóa đối xứng 3DES với nó để mã hóa tệp. Chương trình gọi cụm từ mật khẩu, mà Gene nhập vào là "mật khẩu" và sau đó tạo tệp msg.txt.asc. Bạn có thể xem các nội dung của tệp này trong Liệt kê 9.
Liệt kê 9. Tệp được mã hóa
-----BEGIN PGP MESSAGE----- Version: GnuPG v1.4.2.2 (MingW32) jA0EAgMCqFjZXeujyOJgySoKQ2qhpCpGERKpFn0iKms4kwjpI51BLcoTyH4p61YJ kDAiRMbC6PfCBmg= =G4EN -----END PGP MESSAGE-----
Chắc chắn không ai sẽ nghĩ rằng văn bản đầu tiên từ tệp đó! Được cổ vũ, Gene tiến lên xem xét vấn đề về các chữ ký số.
Các chữ ký hoạt động như thế nào
Các chữ ký số sử dụng các kỹ thuật mã hóa, nhưng mục đích của việc ký là khác nhau. Thay vì che giấu thông báo, một chữ ký tạo lòng tin cho người nhận theo hai mẩu thông tin: người gửi thông báo và bản thân thông báo.
Nó hoạt động như thế này. Người gửi mã hóa thông báo bằng khóa riêng của mình. Sau đó "chữ ký" này được gửi đến người nhận, cùng với thông báo gốc. Người nhận sẽ cố gắng kiểm tra chữ ký, có nghĩa là giải mã chữ ký bằng khóa chung của người gửi và so sánh các kết quả với thông báo gốc. Nếu quá trình này là thành công, người nhận có thể chắc chắn chỉ người gửi có thể là người tạo thông báo, bởi vì không ai trừ người gửi có khóa riêng của mình. Hơn nữa, nếu thông báo gốc đã thay đổi trong quá trình chuyển tiếp, thì chữ ký được giải mã sẽ không khớp với nó, vì thế việc kiểm tra chữ ký thành công cũng có nghĩa là thông báo không bị làm giả.
Thông thường, thay vì ký toàn bộ thông báo, người gửi sẽ tính toán một "tài liệu" của thông báo (bằng cách sử dụng một hàm băm mật mã), ký tài liệu đó và chuyển nó cùng với thông báo chưa mã hóa. Người nhận tính toán tài liệu của thông báo đã nhận và so sánh nó với tài liệu đã giải mã của chữ ký đó. Điều này cung cấp cùng một hiệu quả mà về cơ bản không cần tăng gấp đôi kích thước của mỗi thông báo. (Nó cũng giảm thời gian xử lý để tạo và kiểm tra chữ ký).
Việc ký một tệp
Được khuyến khích, Gene quyết định xem điều này đang hoạt động. Ý định của ông là ký bằng số tệp msg.txt mà Gene đã mã hóa trước đó. Vì nó làm cho việc ký một tệp đơn giản, nên Gene sẽ sử dụng cùng phần mềm GnuPG, mặc dù sau này Gene sẽ sử dụng một kỹ thuật khác để tạo khóa thường được ứng dụng thực tế sử dụng.
Bước đầu tiên là tạo cặp khoá bằng cách sử dụng lệnh trong Liệt kê 10.
Liệt kê 10. Tạo một cặp khóa
gpg.exe --gen-key
Chương trình hỏi nhiều câu hỏi về khóa, như tên, email của Gene và v.v. Gene chọn các tham số khóa mặc định (thuật toán DSA và chiều dài khóa 2048 bit) và cung cấp tên là "Jon Dow". Hoạt động này lưu trữ các khóa trong một tệp kho khóa (keystore) trong thư mục nhà của Gene.
Bây giờ Gene có thể ký thông báo. Ông sử dụng lệnh được hiển thị trong Liệt kê 11.
Liệt kê 11. Ký tài liệu
gpg.exe --clearsign -u "Jon Dow" msg.txt
Lúc này, chương trình yêu cầu mật khẩu kết hợp với khóa riêng của "Jon Dow", sau đó tạo tệp msg.txt.asc, như trong Liệt kê 12.
Liệt kê 12. Tài liệu đã ký
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Hello, world! -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.2.2 (MingW32) iD8DBQFEhftF06oTl3UESDQRArHsAJ0bE2qUEeVb5IDz4gQuRCgOes6v7gCfQhbJ l356yO+YTkJUJZx4KoTTzok= =ld3Y -----END PGP SIGNATURE-----
Một người đang nhận thông báo này sẽ biết giải mã chữ ký bằng cách sử dụng khóa chung của "Jon Dow", áp dụng thuật toán băm cho thông báo chưa mã hóa (sử dụng SHA1) và so sánh cả hai thông báo.
Bây giờ họ hiểu cách mã hóa và chữ ký hoạt động, Gene và Frances sẵn sàng chuyển sang bảo vệ dịch vụ thực tế.
Bảo vệ dịch vụ
Việc bảo vệ dịch vụ liên quan đến một số các bước phải diễn ra trước khi thông báo an ninh đầu tiên có thể được gửi đi và trong khi không có bước nào trong số các bước đó dành riêng cho đặc tả Các dịch vụ Web-An ninh thực tế (chứ không phải phần mềm mà nhóm làm việc đang sử dụng để tạo ra các thông báo), những bước này rất quan trọng và, dưới dạng này hay dạng khác, sẽ diễn ra đối với bất kỳ bản cài đặt Các dịch vụ Web-An ninh nào.
Tạo kho khóa
Bây giờ Gene đã thấy các chữ ký và mã hóa đang hoạt động, Gene cần bắt đầu chuẩn bị bản cài đặt riêng của nhóm làm việc. Gene cần bắt đầu bằng cách tạo kho khóa. Kho khóa sẽ bao gồm tất cả các cặp khóa chung-khóa riêng có thể cần dùng. Để làm điều đó, Gene sẽ sử dụng một ứng dụng công cụ khóa (keytool) đi kèm với JDK.
Để tạo một khoá mới và tạo một kho khóa (keystore), Gene thực hiện các lệnh sau đây, như đã thấy trong Liệt kê 13.
Liệt kê 13. Tạo một cặp khóa và kho khóa
>cd %JAVA_HOME%\bin >keytool -genkey -keystore mykeys.jks -alias gene Enter keystore password: mykeystorepassword What is your first and last name? [Unknown]: Gene Telluride What is the name of your organizational unit? [Unknown]: Information Technologies What is the name of your organization? [Unknown]: The Daily Moon What is the name of your City or Locality? [Unknown]: New York What is the name of your State or Province? [Unknown]: NY What is the two-letter country code for this unit? [Unknown]: US Is CN=Gene Telluride, OU=Information Technologies, O=The Daily Moon, L=New York, ST=NY, C=U S correct? [no]: yes Enter key password for <gene> (RETURN if same as keystore password): mypassword
Dòng lệnh báo cho công cụ này biết để tạo một cặp khóa và lưu nó trong tệp mykeys.jks. Cặp khóa có một bí danh của Gene, cho phép chúng ta dễ dàng tham chiếu nó. Frances có thể tạo khóa của mình và lưu nó trong cùng một tệp, mykeys.jks.
Bây giờ họ sẵn sàng bắt đầu thực hiện công việc bảo vệ dịch vụ riêng của mình.
Kích hoạt an ninh
Bước đầu tiên trong việc thêm Các dịch vụ Web-An ninh cho dịch vụ này là kích hoạt nó trên máy chủ. Apache Axis2, máy các dịch vụ Web mà nhóm làm việc đang chạy dịch vụ của mình, được xây dựng theo mô đun và mô đun Các dịch vụ Web-An ninh được gọi là Rampart (xem Các điều kiện cần trước với các thông tin tải về). Một khi bạn đã tải về Rampart, đặt tệp rampart-1.0.mar trong thư mục modules (các mô đun) của bản cài đặt Axis của bạn. Ví dụ, bản cài đặt của Gene có thư mục modules ở C:\SW\geronimo-1.0\config-store\32\war\WEB-INF\modules.
Tiếp theo, Gene cần tạo cho mô đun này hoàn toàn có sẵn, vì trong "chuỗi của trình xử lý" hoạt động sau hậu trường của Axis2, nó cần kích hoạt trước khi thông báo có thể được hướng đến một dịch vụ cụ thể. Khởi động lại Geronimo và đăng nhập vào trang quản trị Axis2 tại http://localhost:8080/axis2/axis2-admin/login. (Tên người dùng là admin và mật khẩu là axis2) Nhấn Engage Module/For all services (Kích hoạt Mô đun/Cho tất cả các dịch vụ) và chọn rampart-1.0. Nhấn Engage, như bạn có thể thấy trong Hình 3.
Hình 3. Kích hoạt mô đun Rampart
Bạn cũng có thể kích hoạt mô đun Rampart bằng cách thêm nó vào tệp axis2.xml, như bạn sẽ thấy khi chúng ta xem xét việc bảo vệ ứng dụng khách.
Thiết lập an ninh cho dịch vụ
Bây giờ cơ sở hạ tầng đã ở đúng chỗ, Frances có thể bắt đầu bảo vệ dịch vụ thực tế. Trước tiên, Frances tắt Geronimo, vì Frances muốn cập nhật tệp services.xml nằm trong kho lưu trữ CMSService.aar. (Frances có tùy chọn cập nhật và tải lên lại dịch vụ, nhưng cô ấy chọn thay đổi kho lưu trữ trực tiếp). Bản cài đặt của tờ báo có tệp *.aar tại vị trí C:\SW\geronimo-1.0\config-store\32\war\WEB-INF\services\CMSService.aar. Frances cập nhật tệp services.xml để yêu cầu một dấu thời gian (timestamp), như đã thấy trong Liệt kê 14.
Liệt kê 14. Thêm một dấu thời gian tới dịch vụ
<service name="CMSService"> <description> This is a sample Web Service for the newspaper's Content Managment System. </description> <parameter name="ServiceClass" locked="false">CMSService</parameter> <parameter name="InflowSecurity"> <action> <items>Timestamp</items> </action> </parameter> <parameter name="OutflowSecurity"> <action> <items>Timestamp</items> </action> </parameter> <operation name="getNumberOfArticles"> <messageReceiver class= "org.apache.axis2.receivers.RawXMLINOutMessageReceiver"/> </operation> </service>
Axis2 cho phép Frances kiểm soát cụ thể các thông báo chảy vào và chảy ra khỏi dịch vụ. Trong trường hợp này, Frances đã lệnh cho máy các dịch vụ Web yêu cầu các thông báo gửi đến bao gồm một Dấu thời gian và bao gồm một Dấu thời gian trong thông báo gửi ra được trả về cho ứng dụng khách.
Ngay đây, chúng ta sẽ thấy kết quả mà sự thay đổi này có trên các thông báo được chuyển qua giữa máy chủ và ứng dụng khách, nhưng khi Frances cố gắng để chạy một bài kiểm tra, TCPMon cho thấy máy chủ trả về một lỗi chứ không phải là các thông tin dự kiến, như bạn có thể thấy trong Liệt kê 15.
Liệt kê 15. Thiếu các tiêu đề an ninh
<?xml version='1.0' encoding='UTF-8'?> <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:wsa="http://www.w3.org/2005/08/addressing"> <soapenv:Header> <wsa:ReplyTo> <wsa:Address> http://www.w3.org/2005/08/addressing/anonymous </wsa:Address> </wsa:ReplyTo> <wsa:MessageID> urn:uuid:1CA9E94A9C7FE9D5B311507328796251 </wsa:MessageID> <wsa:Action> http://www.w3.org/2005/08/addressing/fault </wsa:Action> </soapenv:Header> <soapenv:Body> <soapenv:Fault> <faultcode>soapenv:Client</faultcode> <faultstring> WSDoAllReceiver: Request does not contain required Security header </faultstring> <detail> <Exception>org.apache.axis2.AxisFault: WSDoAllReceiver: Request does not contain required Security header at ... </Exception> </detail> </soapenv:Fault> </soapenv:Body> </soapenv:Envelope>
Điều quan trọng ở đây là bây giờ Frances biết nó đang hoạt động; máy này sẽ không chấp nhận các thông báo trừ khi chúng tuân theo an ninh mà cô ấy đã cấu hình cho dịch vụ.
Bây giờ Frances có thể chuyển tới ứng dụng khách.
Bảo vệ ứng dụng khách
Theo nhiều cách, ứng dụng khách cũng là một máy chủ giả, trong đó nó cũng gửi và nhận các thông báo SOAP, lẽ ra nó phải diễn ra như bình thường để cho bước đầu tiên của Frances trong việc bảo vệ ứng dụng khách là thêm tệp rampart-1.0.mar vào bản cài đặt của ứng dụng khách. Để làm điều đó, đầu tiên Frances tạo một thư mục mới là, <CLIENT_HOME>\axis-repo\modules, ở đây <CLIENT_HOME> là thư mục trong đó có đặt tệp ClassifiedClient.class. Rồi Frances thêm tệp rampart-1.0.mar vào thư mục đó. Frances cũng tạo một thư mục thứ hai là, <CLIENT_HOME>\axis-repo\conf, trong đó cô tạo một tệp mới tên là axis2.xml. Tệp này có chứa mã như thấy trong Liệt kê 16.
Liệt kê 16. Tệp axis2.xml đầu tiên
<axisconfig name="AxisJava2.0"> <!-- Engage the security module --> <module ref="ramart"/> <parameter name="OutflowSecurity"> <action> <items>Timestamp</items> </action> </parameter> <!-- <parameter name="InflowSecurity"> <action> <items>Timestamp</items> </action> </parameter> --> <!-- ================================================= --> <!-- Parameters --> <!-- ================================================= --> <parameter name="hotdeployment" locked="false">true</parameter> <parameter name="hotupdate" locked="false">false</parameter> <parameter name="enableMTOM" locked="false">true</parameter> <!-- Uncomment this to enable REST support --> <!-- <parameter name="enableREST" locked="false">true</parameter>--> <parameter name="userName" locked="false">admin</parameter> <parameter name="password" locked="false">axis2</parameter> <!-- ================================================= --> <!-- Message Receivers --> <!-- ================================================= --> <!--This is the Deafult Message Receiver for the system , if you want to have MessageReceivers for --> <!--all the other MEP implement it and add the correct entry to here, so that you can refer from--> <!--any operation --> <!--Note : You can ovride this for particular service by adding the same element with your requirement--> <messageReceivers> <messageReceiver mep="http://www.w3.org/2004/08/wsdl/in-only" class="org.apache.axis2.receivers.RawXMLINOnlyMessageReceiver"/> <messageReceiver mep="http://www.w3.org/2004/08/wsdl/in-out" class="org.apache.axis2.receivers.RawXMLINOutMessageReceiver"/> </messageReceivers> <!-- ================================================= --> <!-- Transport Ins --> <!-- ================================================= --> <transportReceiver name="http" class="org.apache.axis2.transport.http.SimpleHTTPServer"> <parameter name="port" locked="false">6060</parameter> <!--If you want to give your own host address for EPR generation--> <!--uncommet following paramter , and set as you required.--> <!--<parameter name="hostname" locked="false">http://myApp.com/ws</parameter>--> </transportReceiver> <transportReceiver name="tcp" class="org.apache.axis2.transport.tcp.TCPServer"> <parameter name="port" locked="false">6061</parameter> <!--If you want to give your own host address for EPR generation--> <!--uncommet following paramter , and set as you required.--> <!--<parameter name="hostname" locked="false">tcp://myApp.com/ws</parameter>--> </transportReceiver> <!-- ================================================= --> <!-- Transport Outs --> <!-- ================================================= --> <transportSender name="tcp" class="org.apache.axis2.transport.tcp.TCPTransportSender"/> <transportSender name="local" class="org.apache.axis2.transport.local.LocalTransportSender"/> <transportSender name="jms" class="org.apache.axis2.transport.jms.JMSSender"/> <transportSender name="http" class="org.apache.axis2.transport.http.CommonsHTTPTransportSender"> <parameter name="PROTOCOL" locked="false">HTTP/1.1</parameter> <parameter name="Transfer-Encoding" locked="false">chunked</parameter> </transportSender> <transportSender name="https" class="org.apache.axis2.transport.http.CommonsHTTPTransportSender"> <parameter name="PROTOCOL" locked="false">HTTP/1.1</parameter> <parameter name="Transfer-Encoding" locked="false">chunked</parameter> </transportSender> <!-- ================================================= --> <!-- Phases --> <!-- ================================================= --> <phaseOrder type="inflow"> <!-- System pre defined phases --> <phase name="Transport"> <handler name="RequestURIBasedDispatcher" class="org.apache.axis2.engine.RequestURIBasedDispatcher"> <order phase="Dispatch"/> </handler> <handler name="SOAPActionBasedDispatcher" class="org.apache.axis2.engine.SOAPActionBasedDispatcher"> <order phase="Dispatch"/> </handler> </phase> <phase name="Security"/> <phase name="PreDispatch"/> <phase name="Dispatch" class="org.apache.axis2.engine.DispatchPhase"> <handler name="AddressingBasedDispatcher" class="org.apache.axis2.engine.AddressingBasedDispatcher"> <order phase="Dispatch"/> </handler> <handler name="SOAPMessageBodyBasedDispatcher" class="org.apache.axis2.engine.SOAPMessageBodyBasedDispatcher"> <order phase="Dispatch"/> </handler> <handler name="InstanceDispatcher" class="org.apache.axis2.engine.InstanceDispatcher"> <order phase="PostDispatch"/> </handler> </phase> <!-- System pre defined phases --> <!-- After Postdispatch phase module author or or service author can add any phase he want --> <phase name="OperationInPhase"/> </phaseOrder> <phaseOrder type="outflow"> <!-- user can add his own phases to this area --> <phase name="OperationOutPhase"/> <!--system predefined phase--> <!--these phase will run irrespective of the service--> <phase name="PolicyDetermination"/> <phase name="MessageOut"/> </phaseOrder> <phaseOrder type="INfaultflow"> <phase name="PreDispatch"/> <phase name="Dispatch" class="org.apache.axis2.engine.DispatchPhase"> <handler name="RequestURIBasedDispatcher" class="org.apache.axis2.engine.RequestURIBasedDispatcher"> <order phase="Dispatch"/> </handler> <handler name="SOAPActionBasedDispatcher" class="org.apache.axis2.engine.SOAPActionBasedDispatcher"> <order phase="Dispatch"/> </handler> <handler name="AddressingBasedDispatcher" class="org.apache.axis2.engine.AddressingBasedDispatcher"> <order phase="Dispatch"/> </handler> <handler name="SOAPMessageBodyBasedDispatcher" class="org.apache.axis2.engine.SOAPMessageBodyBasedDispatcher"> <order phase="Dispatch"/> </handler> <handler name="InstanceDispatcher" class="org.apache.axis2.engine.InstanceDispatcher"> <order phase="PostDispatch"/> </handler> </phase> <!-- user can add his own phases to this area --> <phase name="OperationInFaultPhase"/> </phaseOrder> <phaseOrder type="Outfaultflow"> <!-- user can add his own phases to this area --> <phase name="OperationOutFaultPhase"/> <phase name="PolicyDetermination"/> <phase name="MessageOut"/> </phaseOrder> </axisconfig>
Hầu hết các mã này là mẫu soạn sẵn, vay mượn từ các ví dụ Axis2 khác. Tuy nhiên, trong phần in đậm ở trên đầu, Frances thêm vào để báo cho ứng dụng khách thêm một Dấu thời gian vào thông báo mà nó gửi đến máy chủ. Frances quyết định không bàn đến Dấu thời gian được máy chủ trả về, ít nhất là vào lúc này. Tuy nhiên, không giống như dịch vụ, ứng dụng khách sẽ không tự động tuân theo các hướng dẫn này. Frances đã thực hiện các thay đổi cho lớp thực tế.
Các thay đổi cho lớp ứng dụng khách
Để cho lớp ứng dụng
khách thực hiện các thay đổi được quy định trong tệp axis2.xml, nó phải biết về
chúng. Để kết thúc, Frances thêm cấu hình vào quá trình tạo
ServiceClient, như đã thấy trong Liệt kê
17.
Liệt kê 17. Gọi cấu hình mới từ ClassifiedClient.java
... public static void main(String[] args) { try { OMElement payload = ClassifiedClient.getNumOfArticlesOMElement(); ConfigurationContext configContext = ConfigurationContextFactory .createConfigurationContextFromFileSystem ( "axis-repo", null); Options options = new Options(); options.setTo(targetEPR); options.setTransportInProtocol(Constants.TRANSPORT_HTTP); ServiceClient sender = new ServiceClient(configContext, null); sender.setOptions(options); OMElement result = sender.sendReceive(payload); String response = result.getText(); System.out.println("There are "+response+ " classifieds at the moment."); } catch (Exception e) { System.out.println(e.toString()); } } }
Trước
tiên, Frances tạo một
ConfigurationContext mới, cho phép
ServiceClient tìm kiếm một cấu hình mới. Nhưng để làm
cho nó xảy ra, cô ấy sẽ cần thay đổi cách mà cô gọi là lớp ứng dụng khách thực
tế.
Kéo tất cả chúng lại với nhau
Để cho ứng dụng khách gọi đúng mô đun Rampart, nó cần biết nơi tìm tệp cấu hình và nơi tìm các mục kho lưu trữ bất kỳ khác, chẳng hạn như tệp *.mar của chính nó. Để làm điều đó, Frances thêm nhiều chi tiết hơn vào kịch bản thiết lập đường dẫn lớp (classpath) của mình và chạy lớp ứng dụng khách, như đã thấy trong Liệt kê 18.
Liệt kê 18. Gọi lớp
echo off SET CLASSPATH=C:/SW/axis2/lib/XmlSchema-1.0.2.jar SET CLASSPATH=%CLASSPATH%;C:/SW/axis2/lib/axiom-api-1.0.jar SET CLASSPATH=%CLASSPATH%;C:/SW/axis2/lib/axiom-impl-1.0.jar SET CLASSPATH=%CLASSPATH%;C:/SW/axis2/lib/axis2-kernel-1.0.jar SET CLASSPATH=%CLASSPATH%;C:/SW/axis2/lib/commons-codec-1.3.jar SET CLASSPATH=%CLASSPATH%;C:/SW/axis2/lib/commons-httpclient-3.0.jar SET CLASSPATH=%CLASSPATH%;C:/SW/axis2/lib/commons-logging-1.0.4.jar SET CLASSPATH=%CLASSPATH%;C:/SW/axis2/lib/ geronimo-spec-activation-1.0.2-rc4.jar SET CLASSPATH=%CLASSPATH%;C:/SW/axis2/lib/ geronimo-spec-javamail-1.3.1-rc5.jar SET CLASSPATH=%CLASSPATH%;C:/SW/axis2/lib/jaxen-1.1-beta-8.jar SET CLASSPATH=%CLASSPATH%;C:/SW/axis2/lib/log4j-1.2.13.jar SET CLASSPATH=%CLASSPATH%;C:/SW/axis2/lib/neethi-1.0.1.jar SET CLASSPATH=%CLASSPATH%;C:/SW/axis2/lib/stax-api-1.0.jar SET CLASSPATH=%CLASSPATH%;C:/SW/axis2/lib/wsdl4j-1.5.2.jar SET CLASSPATH=%CLASSPATH%;C:/SW/axis2/lib/wstx-asl-2.9.3.jar SET CLASSPATH=%CLASSPATH%; C:/sw/ClassifiedClient/lib/wss4j-1.5.0.jar SET CLASSPATH=%CLASSPATH%; C:/sw/ClassifiedClient/lib/xmlsec-1.3.0.jar SET CLASSPATH=%CLASSPATH%; C:/sw/ClassifiedClient/lib/ commons-discovery-0.2.jar SET CLASSPATH=%CLASSPATH%; C:/sw/ClassifiedClient/lib/ bcprov-jdk13-132.jar SET CLASSPATH=%CLASSPATH%; C:/sw/ClassifiedClient/lib/xalan.jar SET CLASSPATH=%CLASSPATH%;. java.exe -Daxis2.xml=axis-repo/conf/axis2.xml -Daxis2.repo=axis-repo ClassifiedClient
Lưu ý rằng Frances cũng thêm một số tệp *.jar từ bản phân phối WSS4J (xem Các điều kiện cần trước với các thông tin tải về).
Bây giờ cô ấy đã sẵn sàng để thử yêu cầu một lần nữa.
Yêu cầu
Việc chạy yêu cầu này cho thấy một thông báo SOAP bình thường, với một ngoại lệ, như đã thấy trong Liệt kê 19.
Liệt kê 19. Một thông báo SOAP có đánh dấu thời gian
<?xml version='1.0' encoding='UTF-8'?> <soapenv:Envelope xmlns:soapenv= "http://schemas.xmlsoap.org/soap/envelope/"> <soapenv:Header> <wsse:Security xmlns:wsse="http://docs.oasis- open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext- 1.0.xsd" soapenv:mustUnderstand="1"> <wsu:Timestamp xmlns:wsu="http://docs.oasis- open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility- 1.0.xsd" wsu:Id="Timestamp-29987161"> <wsu:Created>2006-06-19T16:22:28.578Z</wsu:Created> <wsu:Expires>2006-06-19T16:27:28.578Z</wsu:Expires> </wsu:Timestamp> </wsse:Security> </soapenv:Header> <soapenv:Body> <cms:getNumberOfArticles xmlns:cms="http://daily-moon.com/cms"> <cms:category>classifieds</cms:category> </cms:getNumberOfArticles> </soapenv:Body> </soapenv:Envelope>
Bây giờ, lần đầu tiên, Frances thấy một tiêu đề an ninh trong các thông báo của mình. Trong trường hợp này, nó chỉ là một Dấu thời gian, hiển thị khi cô đã tạo thông báo đó. Thuộc tính mustUnderstand có nghĩa là nếu máy chủ không biết phải làm gì với phần tử Timestamp (Dấu thời gian) này, thì nó phải loại bỏ thông báo đó.
Các Timestamp có lẽ là phần tử đơn giản nhất của Các dịch vụ Web-An ninh. Chúng cung cấp một cách để hạn chế tuổi thọ của các thông báo, ngăn chặn những kẻ xấu khỏi thu chặn các thông báo, thay đổi chúng lúc rảnh rỗi và gửi chúng đi. Trong trường hợp này, Dấu thời gian (Timestamp) quá hạn năm giây sau khi tạo thông báo đó, vì vậy nếu thông báo cũ hơn dấu thời gian đó, thì thông báo phải được loại bỏ. (Đúng, một kẻ xấu vẫn có thể thay đổi các giá trị của Dấu thời gian, nhưng chúng ta sẽ đối phó với điều đó khi chúng ta nhận được các chữ ký).
Đáp ứng
Theo quy định trong dịch vụ, đáp ứng cũng có một Dấu thời gian, như đã thấy trong Liệt kê 20.
Liệt kê 20. Đáp ứng
<?xml version='1.0' encoding='UTF-8'?> <soapenv:Envelope xmlns:soapenv= "http://schemas.xmlsoap.org/soap/envelope/"> <soapenv:Header> <wsse:Security xmlns:wsse="http://docs.oasis- open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext- 1.0.xsd" soapenv:mustUnderstand="1"> <wsu:Timestamp xmlns:wsu="http://docs.oasis- open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility- 1.0.xsd" wsu:Id="Timestamp-22347273"> <wsu:Created>2006-06-19T16:22:29.281Z</wsu:Created> <wsu:Expires>2006-06-19T16:27:29.281Z</wsu:Expires> </wsu:Timestamp> <wsse11:SignatureConfirmation xmlns:wsse11= "http://docs.oasis-open.org/wss/2005/xx/oasis-2005xx-wss-wssecurity- secext-1.1.xsd" xmlns:wsu="http://docs.oasis- open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility- 1.0.xsd" wsu:Id="SigConf-5759024" /> </wsse:Security> </soapenv:Header> <soapenv:Body> <resp:numberOfArcticles xmlns:resp="http://daily-moon.com/cms/" xmlns:tns="http://ws.apache.org/axis2" >42</resp:numberOfArcticles> </soapenv:Body> </soapenv:Envelope>
Đáp ứng bao gồm Dấu thời gian, theo quy định, nhưng cũng cho thấy rằng các thông tin an ninh đã được xử lý và được kiểm tra, mặc dù Frances đã không cấu hình ứng dụng khách để kiểm tra cái này hoặc cái khác trong những thực tế này.
Chú ý rằng trong cả hai trường hợp, thông báo thực tế vẫn còn nguyên vẹn.
Việc ký các thông báo
Bây giờ, vào lúc này, Frances đã thêm một Dấu thời gian cho cả các thông báo gửi đi và gửi đến, nhưng không có gì để ngăn chặn người khác khỏi việc chỉ thay đổi giá trị của nó và phát lại nó. Để giải quyết vấn đề đó (và bất kỳ vấn đề khác phát sinh từ các thông tin có thể đã bị thay đổi) Frances cần xem xét việc ký các thông báo của mình.
Việc ký thông báo hoạt động như thế nào
Như chúng ta đã được thấy ở trên, việc ký một thông báo liên quan đến việc tạo ra một phiên bản dữ liệu được mã hóa theo một cách đã biết, để cho việc giải mã nó cung cấp một giá trị mà bạn có thể so sánh với giá trị ban đầu. Ví dụ, giả sử Frances muốn ký bằng số phần tử Dấu thời gian trong các thông báo của mình sao cho máy chủ có thể kiểm tra xem các thông báo vẫn chưa bị làm giả hoặc chưa bị lấy ra theo một cách nào đó.
Để làm điều đó, Frances sẽ xây dựng một quá trình có một vài bước.
Trước tiên, Frances sẽ ký thông báo này (hoặc một phần của thông báo). Để làm điều đó, Frances sẽ sử dụng tệp axis2.xml để chỉ định một người sử dụng làm người ký. Axis2 sẽ nhận thông tin đó và làm hai việc với nó. Trước tiên, Axis2 sẽ cung cấp cho người sử dụng một bí danh cho một lớp "gọi lại". Lớp này sẽ trả về mật khẩu cho người dùng đó. Được trang bị mật khẩu đó, sau đó Axis2 sẽ lấy khóa riêng của người dùng đó từ kho khóa (keystore) mà chúng ta đã tạo ra ở trên.
Khi sử dụng khóa riêng này, Axis2 mã hóa hoặc ký, phần có liên quan của thông báo và thêm chữ ký vào thông báo đó. Sau đó Axis2 sẽ gửi thông báo. Khi dịch vụ nhận được thông báo đó, nó gần như thực hiện một cách tương tự, nó sẽ truy cập kho khóa để có được khóa chung cho người dùng đó và sau đó nó xác minh chữ ký.
Lưu ý rằng nếu dịch vụ sắp gửi trở lại nội dung đã được ký, các vai trò này sẽ được đảo ngược lại cho chuyến trả về.
Hãy xem xét việc thiết lập này.
Lớp
callback
Bước đầu tiên là tạo một lớp
callback (gọi lại). Trong một
tình huống thực, lớp này có thể truy cập vào một thư mục LDAP hoặc sử dụng các phương
thức khác để liên kết một tên người dùng với một mật khẩu, nhưng Frances sẽ bắt đầu
với một bằng chứng-theo-khái niệm, vì vậy cô sẽ tạo ra một lớp
callback đơn giản trả về các giá trị tùy ý, như bạn có thể thấy trong Liệt
kê 21.
Liệt kê 21. PWCallback.java, lớp
callback
import org.apache.ws.security.WSPasswordCallback; import javax.security.auth.callback.Callback; import javax.security.auth.callback.CallbackHandler; import javax.security.auth.callback.UnsupportedCallbackException; import java.io.IOException; public class PWCallback implements CallbackHandler { public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException { for (int i = 0; i < callbacks.length; i++) { if (callbacks[i] instanceof WSPasswordCallback) { WSPasswordCallback pc=(WSPasswordCallback)callbacks[i]; if (pc.getIdentifer().equals("gene")) { pc.setPassword("mypassword"); } else if (pc.getIdentifer().equals("frances")) { pc.setPassword("francespassword"); } else { throw new UnsupportedCallbackException( callbacks[i], "Unknown user"); } } else { throw new UnsupportedCallbackException(callbacks[i], "Unrecognized Callback"); } } } }
Những gì mà lớp đó thực hiện trong phương thức
handle()
không quan trọng; tất cả những thứ quan trọng là hoặc nó thiết lập mật khẩu cho đối
tượng
WSPasswordCallback hoặc nó ném ra một ngoại lệ.
Tệp các đặc tính
Tiếp theo Frances phải tìm một cách để báo cho Axis2 biết nơi tìm kho khóa và lớp nào sẽ thực sự thực hiện tất cả về thủ thuật mã hóa này. Để làm điều đó, Frances tạo ra một tệp các đặc tính là security.properties, như đã thấy trong Liệt kê 22:
Liệt kê 22. Tệp security.properties
org.apache.ws.security.crypto.provider=org.apache.ws.security.compo nents.crypto.Merlin org.apache.ws.security.crypto.merlin.keystore.type=jks org.apache.ws.security.crypto.merlin.keystore.password=mykeystorepa ssword org.apache.ws.security.crypto.merlin.file=mykeys.jks
Sau khi xác định nhà cung cấp, tệp các thuộc tính định nghĩa kiểu kho khóa -- trong trường hợp này là jks, định dạng độc quyền đi kèm với Java -- mật khẩu cho kho khóa và tên của tệp kho khóa thực tế, để đơn giản Frances đặt trong cùng thư mục với tệp lớp ứng dụng khách.
Tệp axis2.xml
Bây giờ Frances cần cho phép tệp axis2.xml những gì cô ấy đã suy nghĩ với các thông báo gửi ra, như bạn có thể thấy trong Liệt kê 23.
Liệt kê 23. Tệp axis2.xml, có chữ ký
<axisconfig name="AxisJava2.0"> <!-- Engage the security module --> <module ref="rampart"/> <parameter name="OutflowSecurity"> <action> <items>Signature</items> <user>gene</user><passwordCallbackClass>PWCallback</passwordCallbackClass> <signaturePropFile>security.properties</signaturePropFile> <signatureKeyIdentifier>SKIKeyIdentifier</signatureK eyIdentifier> <signatureParts>{Element}{http://schemas.xmlsoap.org /soap/envelope/}Body </signatureParts> </action> </parameter> <!-- <parameter name="InflowSecurity"> <action> <items>Timestamp</items> </action> </parameter> --> ...
Trong trường hợp này, thay vì ra lệnh cho ứng dụng khách thêm một Dấu thời gian, cô
ấy ra lệnh cho nó thêm một chữ ký. Xét thấy, ứng dụng khách xem xét tệp quy định
trong
signaturePropFile và sử dụng các thông tin tìm thấy
ở đó -- cùng với
passwordCallbackClass -- để nhận mật khẩu
cho người sử dụng Gene. Từ đó, nó kéo khóa riêng của Gene và ký chỉ một phần của
thông báo được quy định trong phần tử
signatureParts.
Trong trường hợp này, điều đó có nghĩa là phần tử đó được biểu thị bằng phần Thân
(Body) (trái ngược với chính nội dung của phần tử đó), là một phần của
http://schemas.xmlsoap.org/soap/envelope/ namespace.
Bạn có thể ký bất cứ phần nào của thông báo. Ví dụ, người ta thường ký Dấu thời gian, nếu có.
Yêu cầu
Vậy tất cả những thay đổi này muốn nói gì với các thông báo được ứng dụng khách tạo ra? Bạn có thể xem yêu cầu kết quả trong Liệt kê 24.
Liệt kê 24. Yêu cầu đã ký
<?xml version='1.0' encoding='UTF-8'?> <soapenv:Envelope xmlns:soapenv= "http://schemas.xmlsoap.org/soap/envelope/"> <soapenv:Header> <wsse:Security xmlns:wsse="..." soapenv:mustUnderstand="1"> <ds:Signature xmlns:ds="..." Id="Signature-8789796"> <ds:SignedInfo> <ds:CanonicalizationMethod Algorithm= "http://www.w3.org/2001/10/xml-exc-c14n#" /> <ds:SignatureMethod Algorithm= "http://www.w3.org/2000/09/xmldsig#rsa-sha1" /> <ds:Reference URI="#id-17764792"> <ds:Transforms> <ds:Transform Algorithm= "http://www.w3.org/2001/10/xml-exc-c14n#" /> </ds:Transforms> <ds:DigestMethod Algorithm= "http://www.w3.org/2000/09/xmldsig#sha1" /> <ds:DigestValue >wg+9KsR6BVBiO/hakJJwMdtU7+I=</ds:DigestValue> </ds:Reference> </ds:SignedInfo> <ds:SignatureValue>hom9Enzu3yHBuaF...</ds:SignatureValue> <ds:KeyInfo Id="KeyId-19475750"> <wsse:SecurityTokenReference xmlns:wsu=".." wsu:Id="STRId-31156635"> <wsse:KeyIdentifier EncodingType="http://docs.oasis -open.org/wss/2004/01/oasis-200401-wss-soap-message-security- 1.0#Base64Binary" ValueType="http://docs.oasis-open.org/wss/2004/01/o asis-200401-wss-x509-token-profile-1.0#X509SubjectKeyIdentifier" >CuJdE1B2dUFd1dkLZSzQ5vj6MYg=</wsse:KeyIdentifier> </wsse:SecurityTokenReference> </ds:KeyInfo> </ds:Signature> </wsse:Security> </soapenv:Header> <soapenv:Body xmlns:wsu="..." wsu:Id="id-17764792"> <cms:getNumberOfArticles xmlns:cms="http://daily-moon.com/cms"> <cms:category>classifieds</cms:category> </cms:getNumberOfArticles> </soapenv:Body> </soapenv:Envelope>
Tôi đã chia nhỏ các giá trị vùng tên ra để làm cho phần này dễ đọc hơn một chút,
nhưng hãy đi qua nó từ từ. Phần tử
Security (an ninh) có
chứa tất cả các thông tin an ninh, tất nhiên, bắt đầu với Signature (Chữ ký). Chữ ký
bắt đầu với các thông tin về những gì đã thực sự được ký. Nhảy về phía trước chỉ một
chút ít thôi, phần tử
Reference (tham chiếu) bao gồm một
thuộc tính
URI. URL tham chiếu ngược tới thuộc tính
id cho phần Thân (Body), hãy nhớ, đó là những gì mà Frances
nói cho ứng dụng khách biết để ký. Vì vậy chữ ký đó nói cho dịch vụ biết những thông
tin nào thực sự được ký.
Quay trở lại, bước đầu tiên trong nội dung ký là làm cho nó hợp với quy tắc tiêu
chuẩn -- loại bỏ các nút văn bản không liên quan và v.v -- nhưng thực sự có hai cách
để làm điều đó, bao hàm và loại trừ, sự khác biệt có trong cách mỗi phương thức xử lý
các khai báo vùng tên . Vì vậy, phần tử
CanonicalizationMethod quy định chữ ký sử dụng phương thức nào.
Sau đó chúng ta chuyển đến
SignatureMethod, (Phương thức
chữ ký), như tên cho thấy, xác định phương thức được sử dụng để ký dữ liệu có liên
quan.
Phần tử
Reference bao gồm các thông tin về tất cả các bước
đã được dùng để đạt tới nội dung cuối cùng để ký, theo thứ tự, sao cho quá trình kiểm
tra có thể nhận cùng một số bước và (hy vọng) đạt tới
SignatureValue (Giá trị chữ ký) giống nhau.
KeyInfo (Thông tin khóa) cung cấp hoặc là khóa thực tế
được sử dụng để ký dữ liệu hoặc một tham chiếu đến khóa.
Thực hiện các thay đổi cho dịch vụ
Bây giờ ứng dụng khách sẽ tạo chữ ký, nhưng dịch vụ không biết phải làm gì với nó. Frances sắp thay đổi điều đó.
Về bản chất, dịch vụ cần thực hiện rất nhiều các bước giống nhau mà ứng dụng khách đã thực hiện; nó cần có khả năng tìm các mật khẩu và các khóa trong kho khóa, do đó Frances bắt đầu bằng cách thêm các tệp mykeys.jks, PWCallback.class và security.properties vào tệp CMSService.aar. Bạn không cần sử dụng lớp và kho khóa giống như bạn đã sử dụng cho ứng dụng khách, nhưng trong trường hợp này, để cho thuận tiện Frances thực hiện nó.
Frances cũng thêm các tệp bcprov-jdk13-132.jar, wss4j-1.5.0.jar và -1.3.0.jar xmlsec vào thư mục lib của ứng dụng Axis2. (Những tệp này có trong bản phân phối WSS4J).
Sau đó Frances cần thiết lập định nghĩa dịch vụ (trong tệp services.xml) để công nhận rằng dữ liệu đã ký sẽ đến theo cách của nó. Cô ấy làm điều đó bằng cách thực hiện các thay đổi được hiển thị trong Liệt kê 25.
Liệt kê 25. Báo cho dịch vụ biết để yêu cầu dữ liệu đã ký
<service name="CMSService"> <description> This is a sample Web Service for the newspaper's Content Managment System. </description> <parameter name="ServiceClass" locked="false">CMSService</parameter> <parameter name="InflowSecurity"> <action> <items>Signature</items> <passwordCallbackClass>PWCallback</passwordCallbackClass> <signaturePropFile>security.properties</signaturePropFile> </action> </parameter> <parameter name="OutflowSecurity"> <action> <items>Timestamp</items> </action> </parameter> <operation name="getNumberOfArticles"> <messageReceiver class="org.apache.axis2.receivers.RawXMLINOutMessageReceiver"/> </operation> </service>
Những thay đổi này là đủ để cho các dịch vụ biết những gì để mong đợi và những gì để thực hiện với dữ liệu đã ký.
Đáp ứng
Đáp ứng này là một tài liệu bao gồm một Dấu thời gian, theo quy định trong tham số
OutFlowSecurity, nhưng cũng bao gồm thông tin về việc
xác minh chữ ký, như đã thấy trong Liệt kê26.
Liệt kê 26. Đáp ứng
<?xml version='1.0' encoding='UTF-8'?> <soapenv:Envelope xmlns:soapenv= "http://schemas.xmlsoap.org/soap/envelope/"> <soapenv:Header> <wsse:Security xmlns:wsse="..." soapenv:mustUnderstand="1"> <wsu:Timestamp xmlns:wsu="..." wsu:Id="Timestamp-27995990"> <wsu:Created>2006-06-19T23:56:55.214Z</wsu:Created> <wsu:Expires>2006-06-20T00:01:55.214Z</wsu:Expires> </wsu:Timestamp> <wsse11:SignatureConfirmation xmlns:wsse11="..." xmlns:wsu="..." Value="hom9Enzu3yHBuaigFl26b6A+5hy..." wsu:Id="SigConf-25877728" /> </wsse:Security> </soapenv:Header> <soapenv:Body> <resp:numberOfArcticles xmlns:resp="http://daily-moon.com/cms/" xmlns:tns="http://ws.apache.org/axis2">42</resp:numberOfArcticles> </soapenv:Body> </soapenv:Envelope>
Bây giờ hãy xem xét cách thêm mã hóa vào hình ảnh.
Thêm mã hóa
Frances hài lòng với quá trình kiểm tra một phần của thông báo khi sử dụng các chữ ký, nhưng vẫn không có cách nào để che dấu thông tin sao cho các đối thủ cạnh tranh và kẻ xấu khác không thể đọc nó. Chú ý đến vấn đề đó, Frances sẽ phải thêm mã hóa cho ứng dụng.
Thay đổi dịch vụ
Lúc này, cô bắt đầu với dịch vụ. Cô đã thêm vào tất cả các lớp bổ sung mà ứng dụng cần, vì thế tất cả những thứ mà cô cần thay đổi là tệp services.xml, như bạn có thể thấy trong Liệt kê 27.
Liệt kê 27. Thêm mã hóa vào dịch vụ
<service name="CMSService"> <description> This is a sample Web Service for the newspaper's Content Managment System. </description> <parameter name="ServiceClass" locked="false">CMSService</parameter> <parameter name="InflowSecurity"> <action> <items>Timestamp Signature Encrypt</items> <passwordCallbackClass>PWCallback</passwordCallbackClass> <signaturePropFile>security.properties</signaturePropFile> </action> </parameter> <operation name="getNumberOfArticles"> <messageReceiver class= "org.apache.axis2.receivers.RawXMLINOutMessageReceiver"/> </operation> </service>
Ở đây Frances đã nói cho dịch vụ biết rằng thông báo đưa vào sẽ phải có thêm Dấu thời gian và rồi chúng sẽ được ký và sau đó chúng sẽ được mã hóa -- theo thứ tự đó.
Bây giờ Frances chỉ cần báo cho ứng dụng khách biết để thực hiện nó.
Thay đổi ứng dụng khách
Vì Frances đã đặt nền tảng rồi, nên việc thêm mã hóa cho ứng dụng khách cũng là dễ hiểu và đòi hỏi đúng một sự thay đổi đơn giản cho tệp axis2.xml, như bạn có thể thấy trong Liệt kê 28.
Liệt kê 28. Thêm mã hóa cho ứng dụng khách
<axisconfig name="AxisJava2.0"> <!-- Engage the security module --> <module ref="rampart"/> <parameter name="OutflowSecurity"> <action> <items>Timestamp Signature Encrypt</items> <user>gene</user> <passwordCallbackClass>PWCallback</passwordCallbackClass> <signaturePropFile>security.properties</signaturePropFile> <signatureKeyIdentifier >SKIKeyIdentifier</signatureKeyIdentifier> <encryptionKeyIdentifier >SKIKeyIdentifier</encryptionKeyIdentifier> <encryptionUser>frances</encryptionUser> <signatureParts>{Element}{http://schemas.xmlsoap.org/soap/env elope/}Body</signatureParts> <optimizeParts>//xenc:EncryptedData/xenc:CipherData/xenc:Ciph erValue</optimizeParts> </action> </parameter> <!-- ================================================= --> <!-- Parameters --> <!-- ================================================= --> <parameter name="hotdeployment" locked="false">true</parameter> ...
Lưu ý là Francis sẽ xác định một người dùng khác để mã hóa hơn là cô đã sử dụng cho
chữ ký số. Đây không phải là một yêu cầu, nhưng nó có thể. Ngoài ra lưu ý việc bổ
sung phần tử
optimizeParts, xác định cách Axis2 cần biểu
thị dữ liệu đã mã hóa trong thông báo.
Chúng ta hãy xem tất cả kết thúc như thế nào.
Yêu cầu
Với tất cả mọi thứ ở đúng chỗ, thông báo đang trở nên hơi phức tạp một chút, như bạn có thể thấy trong Liệt kê 29.
Liệt kê 29. Yêu cầu được mã hóa, được ký và được đóng dấu
<?xml version='1.0' encoding='UTF-8'?> <soapenv:Envelope xmlns:soapenv= "http://schemas.xmlsoap.org/soap/envelope/" xmlns:xenc="http://www.w3.org/2001/04/xmlenc#"> <soapenv:Header> <wsse:Security xmlns:wsse="..." soapenv:mustUnderstand="1"> <xenc:EncryptedKey Id="EncKeyId-229902"> <xenc:EncryptionMethod Algorithm= "http://www.w3.org/2001/04/xmlenc#rsa-1_5" /> <ds:KeyInfo xmlns:ds="..."> <wsse:SecurityTokenReference> <wsse:KeyIdentifier EncodingType="http://docs.oasis -open.org/wss/2004/01/oasis-200401-wss-soap-message-security- 1.0#Base64Binary" ValueType="http://docs.oasis-open.org/wss/2004/01/o asis-200401-wss-x509-token-profile-1.0#X509SubjectKeyIdentifier" > Xeg55vRyK3ZhAEhEf+YT0z986L0= </wsse:KeyIdentifier> </wsse:SecurityTokenReference> </ds:KeyInfo> <xenc:CipherData> <xenc:CipherValue>PpAOXj5P0W8ukm...</xenc:CipherValue> </xenc:CipherData> <xenc:ReferenceList> <xenc:DataReference URI="#EncDataId-30957433" /> </xenc:ReferenceList> </xenc:EncryptedKey> <ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#" Id="Signature-17764792"> <ds:SignedInfo> <ds:CanonicalizationMethod Algorithm= "http://www.w3.org/2001/10/xml-exc-c14n#" /> <ds:SignatureMethod Algorithm= "http://www.w3.org/2000/09/xmldsig#rsa-sha1" /> <ds:Reference URI="#id-30957433"> <ds:Transforms> <ds:Transform Algorithm= "http://www.w3.org/2001/10/xml-exc-c14n#" /> </ds:Transforms> <ds:DigestMethod Algorithm= "http://www.w3.org/2000/09/xmldsig#sha1" /> <ds:DigestValue>+ECkM6R4GQ7AQ=...</ds:DigestValue> </ds:Reference> </ds:SignedInfo> <SignatureValue>DIeP5AxVmfw...</ds:SignatureValue> <ds:KeyInfo Id="KeyId-16675983"> <wsse:SecurityTokenReference xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401- wss-wssecurity-utility-1.0.xsd" wsu:Id="STRId-21866740"> <wsse:KeyIdentifier EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401- wss-soap-message-security-1.0#Base64Binary" ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401- wss-x509-token-profile-1.0#X509SubjectKeyIdentifier"> CuJdE1B2dUFd1dkLZSzQ5vj6MYg=</wsse:KeyIdentifier> </wsse:SecurityTokenReference> </ds:KeyInfo> </ds:Signature> <wsu:Timestamp xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401- wss-wssecurity-utility-1.0.xsd" wsu:Id="Timestamp-13665843"> <wsu:Created>2006-06-20T00:46:58.263Z</wsu:Created> <wsu:Expires>2006-06-20T00:51:58.263Z</wsu:Expires> </wsu:Timestamp> </wsse:Security> </soapenv:Header> <soapenv:Body xmlns:wsu="..." wsu:Id="id-30957433"> <xenc:EncryptedData Id="EncDataId-30957433" Type= "http://www.w3.org/2001/04/xmlenc#Content"> <xenc:EncryptionMethod Algorithm= "http://www.w3.org/2001/04/xmlenc#aes128-cbc" /> <xenc:CipherData> <xenc:CipherValue> DZ3vWPtabb5vBpZMlEYLPjFc8r2DMJ... fSjXpBFa7gybNA== </xenc:CipherValue> </xenc:CipherData> </xenc:EncryptedData> </soapenv:Body> </soapenv:Envelope>
Bắt đầu ở dưới cùng, lưu ý rằng thiếu yêu cầu thực tế hay đúng hơn là Axis2 đã thay
thế nó bằng một phần tử
EncryptedData bao gồm thông tin về
cách dữ liệu được mã hóa, cũng như các phần tử dữ liệu đã mã hóa thực tế (trong
CypherData và
CypherValue).
Dữ liệu đã được mã hóa bằng khóa dùng chung, có nghĩa là thông báo cần bao gồm khóa
đó sao cho nó có thể được giải mã. Khóa dùng chung đã được mã hóa với khóa chung của
người nhận và được nhúng vào phần Tiêu đề (Header), trong phần tử
EncryptedKey. Khóa này cũng bao gồm một
ReferenceList, có một
DataReference chỉ trở lại
tới dữ liệu mà khóa này đã được sử dụng để mã hóa.
Vì vậy, để đảo ngược hướng, người nhận (trong trường hợp này, máy chủ) nhận được thông báo, sử dụng khóa riêng của riêng mình để giải mã khóa dùng chung và sau đó sử dụng khóa dùng chung để giải mã phần thân của thông báo.
Và sau tất cả các việc đó, đáp ứng trông như thế nào?
Đáp ứng
Trên thực tế, đáp ứng khá đơn giản, vì Frances đã không thiết lập bất kỳ
OutFlowSecurity nào trên máy chủ, như bạn có thể nhìn thấy
trong Liệt kê 30.
Liệt kê 30. Đáp ứng
<?xml version='1.0' encoding='UTF-8'?> <soapenv:Envelope xmlns:soapenv= "http://schemas.xmlsoap.org/soap/envelope/"> <soapenv:Header /> <soapenv:Body> <resp:numberOfArcticles xmlns:resp= "http://daily-moon.com/cms/" xmlns:tns= "http://ws.apache.org/axis2" >42</resp:numberOfArcticles> </soapenv:Body> </soapenv:Envelope>
Đây là một đáp ứng SOAP hoàn toàn hợp lệ, trừ một điều. Bạn có thể nhớ rằng Frances
đã thiết lập ứng dụng khách như mong đợi, ít nhất là, một Dấu thời gian trong
InFlowSecurity riêng của mình. Vì vậy sau tất cả điều đó, yêu
cầu này sẽ vẫn còn thiếu trừ khi cả hai máy chủ và ứng dụng khách đang tạo ra và mong
chờ các phương thức an ninh giống nhau.
Đưa tất cả lại với nhau
Vào lúc này, Frances và Gene có một vài ví dụ rời rạc, vì vậy họ quyết định đặt tất cả mọi thứ với nhau thành một sự thực hiện duy nhất để hiển thị cho Rudy.
Đặc tả dịch vụ cuối cùng
Rudy muốn dịch vụ này chỉ chấp nhận các yêu cầu từ các cá nhân (hoặc các thực thể) được ủy quyền và Rudy không muốn các đáp ứng có thể bị các đối thủ cạnh tranh đọc được. Để làm điều đó, Gene và Frances thiết lập những thứ như sau:
- Các ứng dụng khách sẽ thêm một Dấu thời gian, mà nó sẽ cần ký bằng khóa riêng của một người sử dụng đã được phê duyệt. Điều này chú ý đến vấn đề truy cập được ủy quyền và ngăn các thông báo khỏi bị thu chặn và phát lại.
- Máy chủ sẽ thêm một Dấu thời gian, nhưng nó cũng sẽ mã hóa phần thân của đáp ứng để cho những người nghe trộm không thể xem dữ liệu gửi trở lại.
Hãy xem tất cả kết hợp với nhau như thế nào.
Dịch vụ
Về mặt dịch vụ, Gene thiết lập tệp services.xml như đã thấy trong Liệt kê 31.
Liệt kê 31. Tệp services.xml cuối cùng
<service name="CMSService"> <description> This is a sample Web Service for the newspaper's Content Managment System. </description> <parameter name="ServiceClass" locked="false">CMSService</parameter> <parameter name="InflowSecurity"> <action> <items>Timestamp Signature</items> <passwordCallbackClass>PWCallback</passwordCallbackClass> <signaturePropFile>security.properties</signaturePropFile> </action> </parameter> <parameter name="OutflowSecurity"> <action> <items>Timestamp Signature Encrypt</items> <user>gene</user> <passwordCallbackClass>PWCallback</passwordCallbackClass> <signaturePropFile>security.properties</signaturePropFile> <signatureKeyIdentifier >SKIKeyIdentifier</signatureKeyIdentifier> <encryptionKeyIdentifier >SKIKeyIdentifier</encryptionKeyIdentifier> <encryptionUser>frances</encryptionUser> <signatureParts> {Element}{http://schemas.xmlsoap.org/soap/envelope/}Body </signatureParts> <optimizeParts> //xenc:EncryptedData/xenc:CipherValue/xenc:CipherData </optimizeParts> </action> </parameter> <operation name="getNumberOfArticles"> <messageReceiver class= "org.apache.axis2.receivers.RawXMLINOutMessageReceiver"/> </operation> </service>
InflowSecurity là điều mà máy chủ trông đợi -- một thông
báo đã có một Dấu thời gian được thêm vào và sau đó được ký -- và
OutflowSecurity là điều mà nó sẽ gửi lại tới ứng dụng khách -- một thông
báo đã được đánh dấu thời gian và được ký, với các dữ liệu được mã hóa.
Ứng dụng khách
Về phía ứng dụng khách, Frances thiết lập ngược lại, như bạn có thể thấy trong Liệt kê 32.
Liệt kê 32. Tệp axis2.xml cuối cùng
<axisconfig name="AxisJava2.0"> <!-- Engage the security module --> <module ref="rampart"/> <parameter name="OutflowSecurity"> <action> <items>Timestamp Signature</items> <user>gene</user> <passwordCallbackClass>PWCallback</ passwordCallbackClass> <signaturePropFile>security.properties</signaturePropFile> <signatureKeyIdentifier >SKIKeyIdentifier</signatureKeyIdentifier> <signatureParts> {Element}{http://docs.oasis-open.org/wss/2004/01/oasis -200401-wss-wssecurity-utility-1.0.xsd}Timestamp</signatureParts> </action> </parameter> <parameter name="InflowSecurity"> <action> <items>Timestamp Signature Encrypt</items> <user>gene</user> <passwordCallbackClass>PWCallback</passwordCallbackClass> <signaturePropFile>security.properties</signaturePropFile> <signatureKeyIdentifier >SKIKeyIdentifier</signatureKeyIdentifier> <encryptionKeyIdentifier >SKIKeyIdentifier</encryptionKeyIdentifier> <encryptionUser>frances</encryptionUser> <signatureParts> {Element}{http://schemas.xmlsoap.org/soap/envelope/}Body </signatureParts> <optimizeParts> //xenc:EncryptedData/xenc:CipherValue/xenc:CipherData </optimizeParts> </action> </parameter> <!-- ================================================= --> <!-- Parameters --> <!-- ================================================= --> <parameter name="hotdeployment" locked="false">true</parameter> ...
Bây giờ ứng dụng khách sẽ gửi thông báo được đánh dấu thời gian và được ký và nhấn mạnh rằng các đáp ứng bất kỳ phải được đánh dấu thời gian, được ký và được mã hóa.
Chúng ta hãy xem điều đó có nghĩa thế nào đối với các thông báo thực tế.
Yêu cầu
Liệt kê 33 cho thấy yêu cầu cuối cùng.
Liệt kê 33. Yêu cầu cuối cùng
<?xml version='1.0' encoding='UTF-8'?> <soapenv:Envelope xmlns:soapenv= "http://schemas.xmlsoap.org/soap/envelope/"> <soapenv:Header> <wsse:Security xmlns:wsse="http://docs.oasis- open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" soapenv:mustUnderstand="1"> <ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#" Id="Signature-5525185"> <ds:SignedInfo> <ds:CanonicalizationMethod Algorithm= "http://www.w3.org/2001/10/xml-exc-c14n#" /> <ds:SignatureMethod Algorithm= "http://www.w3.org/2000/09/xmldsig#rsa-sha1" /> <ds:Reference URI="#Timestamp-1741620"> <ds:Transforms> <ds:Transform Algorithm= "http://www.w3.org/2001/10/xml-exc-c14n#" /> </ds:Transforms> <ds:DigestMethod Algorithm= "http://www.w3.org/2000/09/xmldsig#sha1" /> <ds:DigestValue> TQSR9wUuJ7rJi582TsbNjiAUqZI= </ds:DigestValue> </ds:Reference> </ds:SignedInfo> <ds:SignatureValue>aRI5mvvvXZusAB/5cKCx/fOcW+CDjdk1F3Icl lObVcEOWws9/mV4X2kWEX3hhwK7koX5jMPpl7AtLSbEh8UQGCa8yBua++yveprFl020To VtePVOcWsBLM+9VHu9bJbhvaaps43RiUkym6xvVU/yL3eKTbhdhB/RQDI3kylXdas= </ds:SignatureValue> <ds:KeyInfo Id="KeyId-26644003"> <wsse:SecurityTokenReference xmlns:wsu= "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity- utility-1.0.xsd" wsu:Id="STRId-26174005"> <wsse:KeyIdentifier EncodingType="http://docs.oasi s-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Bas e64Binary" ValueType="http://docs.oasis-open.org/wss/2004/01/oasis- 200401-wss-x509-token-profile-1.0#X509SubjectKeyIdentifier" >CuJdE1B2dUFd1dkLZSzQ5vj6MYg=</wsse:KeyIdentifier> </wsse:SecurityTokenReference> </ds:KeyInfo> </ds:Signature> <wsu:Timestamp xmlns:wsu="http://docs.oasis-open.org/wss/20 04/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="Timestamp-1741620"> <wsu:Created>2006-06-22T11:34:02.453Z</wsu:Created> <wsu:Expires>2006-06-22T11:39:02.453Z</wsu:Expires> </wsu:Timestamp> </wsse:Security> </soapenv:Header> <soapenv:Body> <cms:getNumberOfArticles xmlns:cms="http://daily-moon.com/cms"> <cms:category>classifieds</cms:category> </cms:getNumberOfArticles> </soapenv:Body> </soapenv:Envelope>
Đáp ứng
Liệt kê 34 cho thấy đáp ứng cuối cùng.
Liệt kê 34. Đáp ứng cuối cùng
<?xml version='1.0' encoding='UTF-8'?> <soapenv:Envelope xmlns:soapenv= "http://schemas.xmlsoap.org/soap/envelope/" xmlns:xenc="http://www.w3.org/2001/04/xmlenc#"> <soapenv:Header> <wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004 /01/oasis-200401-wss-wssecurity-secext-1.0.xsd" soapenv:mustUnderstand="1"> <xenc:EncryptedKey Id="EncKeyId-28585008"> <xenc:EncryptionMethod Algorithm= "http://www.w3.org/2001/04/xmlenc#rsa-1_5" /> <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#"> <wsse:SecurityTokenReference> <wsse:KeyIdentifier EncodingType="http://docs.oasis- open.org/wss/2004/01/oasis-200401-wss-soap-message-security- 1.0#Base64Binary" ValueType="http://docs.oasis-open.org/wss/2 004/01/oasis-200401-wss-x509-token-profile-1.0#X509SubjectKey Identifier">Xeg55vRyK3ZhAEhEf+YT0z986L0=</wsse:KeyIdentifier> </wsse:SecurityTokenReference> </ds:KeyInfo> <xenc:CipherData> <xenc:CipherValue>NSkylkASezzHSp37izSN3xnxf6v/zwN3C70uU2n UTNk4a9xYxhNcgiVQuS2/Tm3/x3Jm1d9rj2V8x1uqlKmi89MFifN34SDxaDTMBFzhfRv4 CmQSITEFjY1ySVDvMb7WZszGDhVIGYkjcDkoK+SfWdxyuaUdNUbPgEihSnFVRXs=</xen c:CipherValue> </xenc:CipherData> <xenc:ReferenceList> <xenc:DataReference URI="#EncDataId-19400027" /> </xenc:ReferenceList> </xenc:EncryptedKey> <ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#" Id="Signature-17174249"> <ds:SignedInfo> <ds:CanonicalizationMethod Algorithm= "http://www.w3.org/2001/10/xml-exc-c14n#" /> <ds:SignatureMethod Algorithm= "http://www.w3.org/2000/09/xmldsig#rsa-sha1" /> <ds:Reference URI="#id-19400027"> <ds:Transforms> <ds:Transform Algorithm= "http://www.w3.org/2001/10/xml-exc-c14n#" /> </ds:Transforms> <ds:DigestMethod Algorithm= "http://www.w3.org/2000/09/xmldsig#sha1" /> <ds:DigestValue>HfdufYEGpvPpfz2+HWKui4npV9s=</ds:Di gestValue> </ds:Reference> <ds:Reference URI="#SigConf-17122634"> <ds:Transforms> <ds:Transform Algorithm= "http://www.w3.org/2001/10/xml-exc-c14n#" /> </ds:Transforms> <ds:DigestMethod Algorithm= "http://www.w3.org/2000/09/xmldsig#sha1" /> <ds:DigestValue>e88WWqudpvW69wN23fgZjQ9ZAio=</ds:Di gestValue> </ds:Reference> </ds:SignedInfo> <ds:SignatureValue>aZLon//vwkw2G2Jxcligxod/CgxMjwtlefZiho yUz5FpgSY6RUoI5vuHX2unrWV+EVA2vWdtz/Iyq+RS7j4QtE2XTYovxdyiZPbKXNdFKHy AkpDr0aDLG9rSjyFVcTrUKgAY06t10zi13Daq95nDMH+wAJCYUO0Vor/u0V9Iv7I=</ds :SignatureValue> <ds:KeyInfo Id="KeyId-22768665"> <wsse:SecurityTokenReference xmlns:wsu="http://docs.oa sis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="STRId-18220809"> <wsse:KeyIdentifier EncodingType="http://docs.oasis- open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Bas e64Binary" ValueType="http://docs.oasis-open.org/wss/2004/01/oasis- 200401-wss-x509-token-profile-1.0#X509SubjectKeyIdentifier" >CuJdE1B2dUFd1dkLZSzQ5vj6MYg=</wsse:KeyIdentifier> </wsse:SecurityTokenReference> </ds:KeyInfo> </ds:Signature> <wsu:Timestamp xmlns:wsu="http://docs.oasis-open.org/wss/20 04/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="Timestamp-6400133"> <wsu:Created>2006-06-22T11:34:04.062Z</wsu:Created> <wsu:Expires>2006-06-22T11:39:04.062Z</wsu:Expires> </wsu:Timestamp> <wsse11:SignatureConfirmation xmlns:wsse11="http://docs.oasi s-open.org/wss/2005/xx/oasis-2005xx-wss-wssecurity-secext-1.1.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss- wssecurity-utility-1.0.xsd" Value="aRI5mvvvXZusAB/5cKCx/fOcW+CDjdk1F3 IcllObVcEOWws9/mV4X2kWEX3hhwK7koX5jMPpl7AtLSbEh8UQGCa8yBua++yveprFl02 0ToVtePVOcWsBLM+9VHu9bJbhvaaps43RiUkym6xvVU/yL3eKTbhdhB/RQDI3kylXda s=" wsu:Id="SigConf-17122634" /> </wsse:Security> </soapenv:Header> <soapenv:Body xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/o asis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="id-19400027"> <xenc:EncryptedData Id="EncDataId-19400027" Type= "http://www.w3.org/2001/04/xmlenc#Content"> <xenc:EncryptionMethod Algorithm= "http://www.w3.org/2001/04/xmlenc#aes128-cbc" /> <xenc:CipherData> <xenc:CipherValue>f6uWHGsYmGwHuno2j4H7a4qCMhPLTlCIg40p KLciESBzeCT8rvyl+qHXsFkZJq2m4uj9TEFtRX6efQ5MHBEJozMgI03LSVanh6MmHgt5o ilIJClWcQifEx0Azeo3KWnQKSc9lg0ywhKJH+JVBsPSP7E19jZAsR77wUEBBIprxs5W59 7C/mJh38iXSncwWccE7OCckf1x34FCfKHSqn46MCohZWiPZRjSmAI5dGFMKwttzpmsmXr LHLVrsjm4w9onis+Xr5gbi3Gcx6P0F2ZJGLBb9bkGh/IvjYutgzRD7zhyRZxUmM/oZTVs JJ7dA9YOED5l1C64f4yuqR6TtuVw3gIiuspxWafKwlJuuD0/9m6Ri4AvQuOVEioz45MM 5FBCQU+0LFceSlEFFKhN9yLUI9hgLsCYRzc8eedPAhZDjJEDHec5M9LZ0C07sKu7Cvnr jiino53xZmk5uQHs4JlNoA==</xenc:CipherValue> </xenc:CipherData> </xenc:EncryptedData> </soapenv:Body> </soapenv:Envelope>
Tóm tắt
Để cho các dịch vụ Web thực sự có ích trong môi trường doanh nghiệp, nó cần có các khả năng an ninh thích hợp. Bằng cách kết hợp với các công nghệ như Chữ ký XML và Mã hóa XML và cung cấp một cách tiêu chuẩn để biểu thị thông tin đó, Các dịch vụ Web-An ninh làm cho nó có khả năng bảo vệ cả hai thông báo SOAP đến và ra khỏi một số các mối đe dọa an ninh khác.
Bằng cách yêu cầu các chữ ký số, bạn có thể hạn chế việc truy cập đến các cá nhân hay các tổ chức có ủy quyền, cũng như kiểm tra các thông tin đó không bị thay đổi trong quá trình chuyển tiếp. Bằng cách kèm thêm cả mã hóa, bạn có thể ngăn dữ liệu khỏi bị những người nhận không dự tính trước đọc (hoặc ít nhất là hiểu). Và bằng cách thêm một Dấu thời gian (và ký nó), bạn có thể ngăn các thông báo khỏi bị bắt giữ và phát lại.
Trong hướng dẫn này, các nhân viên ở tờ báo Daily Moon đã bảo vệ các dịch vụ Web mà họ đã tạo ra trong phần trước của loạt bài này. Tiếp theo, trong phần 5, họ sẽ xem xét áp dụng các chính sách an ninh cho dịch vụ đó.
Tải về
Tài nguyên
Học tập
- Đọc Đặc tả Các dịch vụ Web-An ninh.
- Đọc Hiện trạng thẻ tên người dùng (PDF).
- Đọc về Hiện trạng thẻ X.509 (PDF).
- Đọc Đặc tả chữ ký XML.
- Đọc đặc tả Mã hóa XML tại http://www.w3.org/Encryption/2001/.
- Để có một nền tảng tốt về XML, hãy đọc Giới thiệu về hướng dẫn XML (developerWorks, 08.2002).
- Để có một hiểu biết tốt hơn về xử lý XML như một đối tượng, hãy đọc Hiểu biết DOM (developerWorks, 07.2003).
- Bạn có thể tìm nhiều thông tin về SOA và vùng các dịch vụ Web của developerWorks.
- Xem một ví dụ về Axis2 đang hoạt động bằng cách đọc Tạo tài khoản trực tuyến với loạt bài hướng dẫn Apache Geronimo và Axis2.
- Để tìm hiểu thêm về lập trình trong Java, hãy xem Vùng XML của developerWorks.
- Tìm hiểu tất cả về XML tại Vùng XML của developerWorks.
Lấy sản phẩm và công nghệ
- Tải Apache Geronimo. Để biết thêm thông tin về cài đặt Geronimo, hãy xem Phần 1 của loạt bài này.
- Tải phiên bản 1.0 của Apache Axis2 hoặc cao hơn.
- Tải mô đun Rampart của Apache Axis2.
- Tải Apache WSS4J.
- Tải phiên bản 1.4.2 hoặc cao hơn của Ấn bản tiêu chuẩn của Java 2.
- Tải TCPMon.
- Tải GnuPG.
Bình luận
-
Vùng dữ liệu trên developerWorks
Khám phá các bài viết xoay quanh lĩnh vực dữ liệu, Quản lý hệ thống thông tin
-
Vùng mã nguồn mở trên developerWorks
Xem các bài viết về HTML, CSS, JavaScript,...
-
Điện toán đám mây
Tìm hiểu về điện toán đám mây

markdown:
## Trước khi bạn bắt đầu
Trong hướng dẫn này bạn sẽ tìm hiểu về An ninh của Các dịch vụ Web hoặc Các dịch vụ Web-An ninh (WS-Security). Hướng dẫn này dành cho các nhà phát triển muốn trưng ra các dịch vụ của mình trong một môi trường đòi hỏi phải bảo vệ các thông báo khỏi bị làm giả hoặc bị đọc trong lúc chuyển tiếp hoặc trong các tình huống trong đó phải nhận dạng rõ ràng người gửi. Thuật ngữ "Các dịch vụ Web-An ninh" (WS-Security) thường được dùng để chỉ một nhóm các đặc tả xử lý mã hóa và các chữ ký số, cho phép bạn tạo một ứng dụng an toàn.
Để làm theo cùng với hướng dẫn này, bạn nên có một sự hiểu biết cơ bản về SOAP, bạn
có thể đạt được điều này bằng cách đọc
[Phần 1](http://www.ibm.com/developerworks/vn/edu/ws-understand-web-services1/index.html)
của loạt bài hướng dẫn này và về phần mở rộng, bạn cần có một sự hiểu
biết cơ bản về XML. SOAP là thuyết bất khả tri của ngôn ngữ lập trình, nhưng các ví
dụ trong hướng dẫn này sử dụng các dự án Java ™ và Axis2 Apache. Tuy nhiên,
các khái niệm này áp dụng cho môi trường và ngôn ngữ lập trình bất kỳ.
### Về loạt bài này
Loạt bài hướng dẫn này dạy các khái niệm cơ bản về các dịch vụ Web bằng cách tiếp tục
khai thác về tờ báo hư cấu,
*The Daily Moon* (Mặt trăng hàng ngày), khi các nhân
viên sử dụng các dịch vụ Web để tạo ra một hệ thống tiến trình công việc để tăng năng
suất trong nhiều thay đổi.
Phần 1 đã giải thích các khái niệm cơ bản đằng sau các dịch vụ Web và đã dạy cách sử dụng SOAP, đặc tả này làm cơ sở cho hầu hết những cái sắp tới, kết nối phòng chuyên mục rao vặt với Hệ thống quản lý nội dung.
Phần 2, đưa mọi thứ tiến lên một bước xa hơn, khi giải thích cách sử dụng WSDL (Web Services Description Language - Ngôn ngữ mô tả các dịch vụ Web) để định nghĩa các thông báo được các dịch vụ Web tạo ra như mong đợi, cho phép nhóm làm việc tạo ra các dịch vụ và các ứng dụng khách để kết nối với chúng dễ dàng hơn.
Phần 3 tìm nhóm làm việc có một số dịch vụ tại chỗ và có một mong muốn định vị các dịch vụ dễ dàng. Đáp lại, UDDI (Universal Description, Discovery and Integration - Tích hợp, khám phá và mô tả đa năng) cung cấp một đăng ký có thể tìm kiếm được của các dịch vụ có sẵn theo cách đưa ra công khai các dịch vụ riêng của họ cho những người khác.
Bây giờ trong Phần 4, Rudy, chủ báo
*The Daily Moon*, đã quyết định tờ báo này
cần xây dựng các giao thức an ninh tốt hơn cho các dịch vụ Web để truy cập các hệ
thống nội bộ của tờ báo.
Trong Phần 5, Các dịch vụ Web-Chính sách (WS-Policy), chúng ta sẽ xem xét các thay đổi mà các nhóm làm việc cần thực hiện để truy cập các dịch vụ mới được bảo vệ đó.
Tính tương thích là từ khóa trong phần 6, do các dịch vụ từ các cách hiện thực khác nhau phải được truy cập từ một hệ thống đơn. Phần 6 cũng sẽ trình bày các yêu cầu và các thử nghiệm liên quan đến việc cấp chứng chỉ Các dịch vụ Web-Tính tương thích (WS-I).
Cuối cùng, phần 7 dạy cách sử dụng WS-BPEL (Ngôn ngữ thực hiện qui trình kinh doanh) để tạo các ứng dụng phức tạp từ các dịch vụ riêng biệt.
Bây giờ hãy xem xét hướng dẫn này trình bày những gì cụ thể hơn một chút.
### Về hướng dẫn này
Trong hướng dẫn này, bạn sẽ làm theo khi nhóm làm việc của tờ báo
*The Daily
Moon* sử dụng các đặc tả Các dịch vụ Web-An ninh để bảo vệ một trong các dịch
vụ Web đã mô tả ở trên trong loạt bài này.
Theo tiến trình của hướng dẫn này, bạn sẽ học:
- Các dịch vụ Web-An ninh là gì.
- Sự khác biệt giữa mã hóa đối xứng và bất đối xứng.
- Sự khác biệt giữa các chữ ký và mã hóa.
- Hiệu quả của an ninh trên các thông báo SOAP.
- Làm thế nào để bảo vệ một dịch vụ web SOAP bằng cách sử dụng Axis2.
Trước khi chúng ta bắt đầu, bạn sẽ cần một vài công cụ.
### Các điều kiện cần trước
Nhiều thứ trong hướng dẫn này thuộc về khái niệm, nhưng để làm theo cùng với các mã tạo các thông báo SOAP, bạn sẽ cần có sẵn phần mềm sau đây đã được cài đặt:
Chúng tôi sẽ giới thiệu cách cài đặt và sử dụng Apache Geronimo, đây cũng là cơ sở
cho IBM Community Edition (Ấn bản cộng đồng của WebSphere của IBM). Ngoài ra bạn có
thể sử dụng các máy chủ ứng dụng khác như là máy chủ ứng dụng WebSphere. Bạn có thể
tải
[Apache Geronimo](http://geronimo.apache.org/downloads.html). Để biết
thêm thông tin về cài đặt Geronimo, xem [Phần 1](http://www.ibm.com/developerworks/vn/edu/ws-understand-web-services1/index.html) của loạt bài này.
Bạn sẽ sử dụng Apache Axis2, có chứa các thực hiện của các API có liên quan đến SOAP
khác nhau để làm cho cuộc sống của bạn dễ dàng hơn. Bạn có thể tải
[Apache Axis2](http://ws.apache.org/axis2/download.cgi) từ Apache.org.
Hướng dẫn này sử dụng phiên bản 0.94, nhưng các phiên bản mới hơn cũng sẽ hoạt
động.
Mô đun Rampart của Apache Axis2 -- An ninh cho máy các dịch vụ Web Axis2 được cung
cấp thông qua mô đun Rampart, nó không bao gồm trong bản cài đặt mặc định. Hãy tải về
mô đun này từ
[Apache Download Mirrors](http://www.apache.org/dyn/mirrors/mirrors.cgi/ws/axis2/modules/rampart/1_0/rampart-1.0.mar).
Apache WSS4J -- Mặc dù chính Axis sẽ sử dụng Rampart, tại một số điểm mà bạn cần tham
chiếu hướng dẫn các lớp WSS4J. Hãy tải về gói
[ WSS4J package](http://www.apache.org/dyn/closer.cgi/ws/wss4j/).
Ấn bản tiêu chuẩn Java 2 (Java 2 Standard Edition) phiên bản 1.4.2 hoặc cao hơn --
Tất cả các công cụ này dựa trên Java, chẳng hạn như các dịch vụ và ứng dụng khách mà
bạn sẽ xây dựng trong hướng dẫn này. Hãy tải
[J2SE SDK](http://java.sun.com/j2se/1.5.0/download.jsp).
TCPMon (tùy chọn) -- TCPMon là cách dễ dàng hơn để hiểu những gì đang diễn ra trong
một ứng dụng dịch vụ web khi bạn thực sự có thể nhìn thấy các thông báo. Tải
[TCP Monitor](http://ws.apache.org/commons/tcpmon) để bạn có thể xem các
thông báo đến và từ các dịch vụ Web.
GnuPG (tùy chọn) - Tất cả về việc ký thông báo mà chúng tôi sẽ làm được chính Axis2
và Java trình bày, nhưng nếu bạn muốn bàn đến việc ký các tài liệu riêng, như chúng
tôi sẽ trình diễn ngắn gọn, hãy tải về
[GnuPG](http://www.gnupg.org/(en)/download/index.html).
Bạn cũng sẽ cần một trình duyệt Web và một trình soạn thảo văn bản.
## Tổng quan
Trước khi chúng ta nói về việc bảo vệ một dịch vụ, thật có ích để biết chính xác các phần nào tạo nên dịch vụ đó để biết những gì đã được thực hiện.
### Câu chuyện tiếp tục cho đến nay
Loạt bài hướng dẫn này tiếp tục các hoạt động của các nhân viên của tờ báo Daily Moon (Mặt Trăng hàng ngày). Tờ báo này đã phát hiện ra cách làm việc mới dưới dạng các dịch vụ Web. Tất cả cách làm việc mới này đã bắt đầu trong phòng chuyên mục rao vặt. Phòng này đã quyết định cho phép những người khác truy cập vào hệ thống của mình thông qua việc sử dụng các thông báo SOAP -- các thông báo XML có thể được gửi qua HTTP.
Ví dụ, một yêu cầu cho một số trong các đoạn quảng cáo được phân loại thành thể loại con "để bán" có thể trông giống như Liệt kê 1.
##### Liệt kê 1. Một thông báo SOAP ví dụ
<?xml version='1.0' ?> <env:Envelope xmlns:env="http://www.w3.org/2003/05/SOAP-envelope"> <env:Header> </env:Header> <env:Body> <cms:getNumberOfArticles xmlns:cms="http://www.daily-moon.com/cms"> <cms:category>classifieds</cms:category> <cms:subcategory>forsale</cms:subcategory> </cms:getNumberOfArticles> </env:Body> </env:Envelope>
Thông báo tổng thể được gọi là Phong bì (Envelope), với các nội dung trong đó bao gồm phần Tiêu đề (Header) và phần Thân (Body). Tiêu đề chứa thông tin về chính thông báo đó, chẳng hạn như thông tin định tuyến, hoặc các thông tin dự kiến do "các phương tiện trung gian SOAP" xử lý hoặc dịch vụ giữa người gửi và người nhận cuối có thể xử lý thông báo. (Trong trường hợp này, hãy xem bất kỳ trong số các tiêu đề đó, nhưng đây là nơi thông tin an ninh của chúng ta sẽ gửi đi). Phần Thân của thông báo bao gồm "tải trọng" có các dữ liệu thực sự được chuyển tới dịch vụ Web.
Trong trường
hợp này, trọng tải là phần tử
getNumberOfArticles và nội
dung của nó.
Gene và Frances, từ bộ phận IT của tờ báo này, đã ráp một hệ thống vào với nhau để phục vụ các yêu cầu của các dịch vụ web, cũng như cơ sở hạ tầng để phát hiện và tự động tạo ra các ứng dụng khách cho các dịch vụ. Bây giờ chủ báo, Rudy, đang nhấn mạnh rằng họ tìm thấy cách để ngăn chặn truy cập trái phép vào các hệ thống này.
### Nhu cầu an ninh
Đặc tả SOAP cơ bản không lo liệu cho việc bảo vệ các thông báo, mà để lại nhiệm vụ đó cho các đặc tả mở rộng. Vấn đề nằm ở tính chất của một ứng dụng của các dịch vụ Web. Trong hầu hết các trường hợp, chúng ta đang đề cập đến SOAP trên HTTP, có nghĩa là mỗi thông báo phải đi qua một hoặc nhiều nút trung gian, và bất kỳ một trong số các nút đó có thể đọc và/hoặc thay đổi một thông báo. Và điều đó thừa nhận rằng bản thân yêu cầu SOAP đã là một yêu cầu trực tiếp. Trong một số trường hợp, các thông báo SOAP được thiết kế đặc biệt để đi qua nhiều hơn một nút trước khi tới điểm đến cuối cùng của chúng.
Kết quả cuối cùng là chúng ta cần một cách để ngăn chặn một ai đó không phải là người nhận được dự kiến đọc các thông tin nhạy cảm, để ngăn chặn việc nghe trộm. Chúng ta cũng cần một cách để ngăn chặn một ai đó không phải là người gửi được dự kiến gửi đi các thông báo, để ngăn chặn truy cập trái phép.
Đặc tả SOAP cung cấp một phương tiện để bổ sung các thông tin an ninh -- chúng ta thêm thông tin vào một phần tử Tiêu đề của Phong bì -- nhưng không xác định các thông tin nên là gì. Để bảo vệ nó, chúng ta cần Các dịch vụ Web-An ninh (WS-Security).
### Các phần về Các dịch vụ Web-An ninh
Có ba vấn đề chủ yếu cần có trong việc đảm bảo an ninh cho các trao đổi thông báo SOAP và Các dịch vụ Web-An ninh cung cấp các câu trả lời cho tất cả các vấn đề đó, nhưng không trực tiếp. Trong thực tế, Các dịch vụ Web-An ninh là một đặc tả không nói về cách bảo vệ thông báo, mà nói về cách giúp cho người nhận biết cách bạn đã bảo vệ thông báo. Để thực hiện việc bảo vệ trên thực tế, Các dịch vụ Web-An ninh tham chiếu các đặc tả bổ sung. Hãy xem Các dịch vụ Web-An ninh hoạt động như thế nào.
Vấn đề đầu tiên là nhận dạng và xác thực ứng dụng khách. Vì có rất nhiều cách khác nhau để tạo ra các thẻ an ninh, nên Các dịch vụ Web-An ninh không xác định bất kỳ phương tiện cụ thể nào, mà định nghĩa cách các thẻ an ninh khác nhau sẽ được chuyển giao trong các thông báo SOAP. Nói cách khác, nó cho phép người nhận biết cách trích xuất các thẻ an ninh khỏi thông báo để xử lý.
Vấn đề thứ hai là đảm bảo tính toàn vẹn của thông báo. Các dịch vụ Web-An ninh sử dụng các chữ ký số cho việc đó, sử dụng đặc tả Chữ ký XML hơn là phát minh ra một vài thứ mới. Chữ ký XML là một khuyến nghị của W3C cung cấp một cơ chế cho việc ký bằng số các tài liệu XML.
Vấn đề thứ ba là giữ cho thông báo khỏi bị nghe trộm trong khi nó chuyển tiếp. Một lần nữa, Các dịch vụ Web-An ninh sử dụng một tiêu chuẩn W3C khác, lần này là Mã hóa XML (XML Encryption), cung cấp một cơ chế để mã hóa các tài liệu XML.
Trong hướng dẫn này, chúng ta sẽ xem việc sử dụng các tiêu chuẩn này ảnh hưởng đến các thông báo SOAP thực tế thường dùng như thế nào, khi Frances và Gene thực hiện bảo vệ dịch vụ của chuyên mục Rao vặt hiện có.
### Dịch vụ hiện tại
Trước khi chúng ta xem xét thực hiện các thay đổi, thật có ích để xem nơi Gene và Frances sẽ bắt đầu. Dịch vụ của của chuyên mục Rao vặt được triển khai thực hiện bằng cách sử dụng Axis2, có nghĩa là nó có chứa trong một tệp *.aar. Tệp CMSService.aar có ba tệp, như trong Liệt kê 2.
##### Liệt kê 2. Các nội dung của dịch vụ đầu tiên
CMSService.class meta-inf/Manifest.MF meta-inf/services.xml
Bản thân lớp này là đơn giản, nó nhận một thông báo SOAP liệt kê một thể loại và trả về một thông báo SOAP bao gồm một số các đoạn quảng cáo cho thể loại đó. Nó thực hiện chức năng này khi được tệp services.xml định nghĩa (xem Liệt kê 3).
##### Liệt kê 3. Tệp services.xml đầu tiên
<service name="CMSService"> <description> This is a sample Web Service for the newspaper's Content Managment System. </description> <parameter name="ServiceClass" locked="false">CMSService</parameter> <operation name="getNumberOfArticles"> <messageReceiver class= "org.apache.axis2.receivers.RawXMLINOutMessageReceiver"/> </operation> </service>
Việc bảo vệ dịch vụ đòi hỏi chỉ chạm vào tệp services.xml; Gene và Frances sẽ không hề phải chạm vào lớp Java thực tế.
### Ứng dụng khách hiện tại
Bản thân ưng dụng khách là khá đơn giản và chỉ cần tạo và hiển thị yêu cầu, như trong Liệt kê 4:
##### Liệt kê 4. Lớp ứng dụng khách đầu tiên
import org.apache.axis2.Constants; import org.apache.axis2.addressing.EndpointReference; import org.apache.axis2.client.Options; import org.apache.axis2.client.ServiceClient; import org.apache.axiom.om.OMElement; import org.apache.axiom.om.OMAbstractFactory; import org.apache.axiom.soap.SOAPFactory; import org.apache.axiom.om.OMNamespace; import org.apache.axis2.context.ConfigurationContext; import org.apache.axis2.context.ConfigurationContextFactory; public class ClassifiedClient { private static EndpointReference targetEPR = new EndpointReference( "http://localhost:
8888/axis2/services/CMSService"); public static OMElement getNumOfArticlesOMElement() { SOAPFactory fac = OMAbstractFactory.getSOAP12Factory(); OMNamespace omNs = fac.createOMNamespace( "http://daily-moon.com/cms", "cms"); OMElement method = fac.createOMElement("getNumberOfArticles", omNs); OMElement value = fac.createOMElement("category", omNs); value.addChild(fac.createOMText(value, "classifieds")); method.addChild(value); return method; } public static void main(String[] args) { try { OMElement payload = ClassifiedClient.getNumOfArticlesOMElement(); Options options = new Options(); options.setTo(targetEPR); options.setTransportInProtocol(Constants.TRANSPORT_HTTP); ServiceClient sender = new ServiceClient(); sender.setOptions(options); OMElement result = sender.sendReceive(payload); String response = result.getText(); System.out.println("There are "+response+ " classifieds at the moment."); } catch (Exception e) { System.out.println(e.toString()); } } }
Lưu ý rằng Gene đã thay đổi cổng điểm cuối thành 8888, thay cho 8080, cổng mà máy chủ Geronimo đang nghe. Gene làm điều đó để chèn một bước bổ sung sao cho anh ta có thể nhìn thấy các thông báo bay qua bay lại.
### Xem các thông báo
Để xem các thông báo SOAP thực tế, hãy tải TCPMon từ http://ws.apache.org/commons/tcpmon/download.cgi. (Đúng, Axis2 đi kèm với SOAPMonitor, nhưng Gene đã phát hiện ra cách phức tạp nằm ngoài những rắc rối trong việc thiết lập những thứ đó, nó cho thấy SOAP nhưng không nhất thiết phải là các thông báo thô, mà chúng ta rõ ràng sẽ muốn xem).
Sau khi tải về, giải
nén ứng dụng đó và chạy tệp
tcpmon-1.0-bin\build\tcpmon.bat. Nhấn vào tab Admin và tạo một người nghe
mới, như trong Hình 1.
##### Hình 1. tab Admin của TCPMon
![ tab Admin của TCPMon](fig01.jpg)
Chọn 8888 là một cổng nghe và xác định 8080 là cổng đích, để cho TCPMon nằm giữa ứng dụng khách và máy chủ. Nhấn Add và sau đó nhấn vào thẻ Port 8888. Nhấn vào hộp chọn XML Format. Bây giờ khi Frances thực hiện ứng dụng khách, Gene có thể thấy yêu cầu và đáp ứng, như trong Hình 2.
##### Hình 2. Yêu cầu và đáp ứng đầu tiên
![ Yêu cầu và đáp ứng đầu tiên](fig02.jpg)
Trước khi đi tiếp, chúng ta hãy xem xét nhanh các thông báo thực tế, để chúng ta có thể biết những gì thay đổi.
### Các thông báo
Bản thân các thông báo rất đơn giản. Yêu cầu, như đã thấy trong Liệt kê 5, chỉ yêu cầu số lượng các đoạn quảng cáo được phân loại trong hệ thống:
##### Liệt kê 5. Yêu cầu đầu tiên
<?xml version='1.0' encoding='UTF-8'?> <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"> <soapenv:Header /> <soapenv:Body> <cms:getNumberOfArticles xmlns:cms="http://daily-moon.com/cms"> <cms:category>classifieds</cms:category> </cms:getNumberOfArticles> </soapenv:Body> </soapenv:Envelope>
Đáp ứng cũng không kém phần đơn giản, như bạn có thể thấy trong Liệt kê 6:
##### Liệt kê 6: Đáp ứng đầu tiên
<?xml version='1.0' encoding='UTF-8'?> <soapenv:Envelope xmlns:soapenv= "http://schemas.xmlsoap.org/soap/envelope/"> <soapenv:Header /> <soapenv:Body> <resp:numberOfArcticles xmlns:resp="http://daily-moon.com/cms/" xmlns:tns="http://ws.apache.org/axis2" >42</resp:numberOfArcticles> </soapenv:Body> </soapenv:Envelope>
Trong cả hai thông báo này, Frances sẽ đặt thông tin bổ sung trong phần tử Tiêu đề (Header) cho máy chủ (hoặc ứng dụng khách) xử lý.
Vào lúc này, bất cứ ai có thể gửi một yêu cầu đến dịch vụ và nhận được một đáp ứng và đó là điều làm cho Rudy không an tâm. Rudy muốn dịch vụ đó được thiết lập sao cho chỉ có những người dùng được ủy quyền mới có thể nhận được thông tin và sao cho các đối thủ cạnh tranh không thể thu chặn các thông tin. Rudy suy nghĩ rằng đây là một hệ thống bằng chứng-theo- khái niệm tốt. Rudy thực sự càng lo ngại hơn về các hệ thống phức tạp hơn, chẳng hạn như những hệ thống thêm nội dung hoặc truy cập vào hệ thống kế toán. Nhưng các khái niệm cũng như nhau thôi.
Để cung cấp an ninh, Gene và Frances cần sử dụng mã hóa và công nghệ liên quan của nó, các chữ ký.
## Mã hóa và các chữ ký
Đa số các biện pháp an ninh đòi hỏi một hình thức mã hóa hay cách khác hoặc mã hóa đã hoạt động trong một chữ ký số, vì vậy trước khi Frances cho phép Gene bắt đầu lựa chọn cấu hình an ninh của dịch vụ, cô ấy muốn chắc chắn rằng họ hiểu những gì họ đang bàn đến.
### Các kiểu mã hóa
Mã hóa là một quá trình che dấu thông tin để làm cho không thể đọc thông tin đó mà không có kiến thức đặc biệt. Lịch sử đã biết nhiều loại mã hóa khác nhau. Mã hóa hiện đại thường là một chuỗi các phép biến đổi rõ ràng được áp dụng cho một thông báo và một số dạng "khóa". Kết quả là các câu không thể đọc được. Giải mã là một quá trình ngược lại và cũng bao gồm một khóa, do đó bằng cách giữ bí mật khóa người ta có thể có cơ sở chắc chắn rằng không ai khác có thể đọc được thông báo đã mã hóa.
Các phương thức mã hóa hiện đại có thể được phân loại theo cách chúng sử dụng một hoặc hai khóa. Trong một thuật toán khóa đối xứng (ví dụ, DES), người gửi và người nhận phải có một khóa dùng chung được thiết lập trước và giữ bí mật với tất cả các bên khác; người gửi sử dụng khóa này để mã hóa còn người nhận sử dụng một khóa giống như vậy để giải mã. Trong trường hợp này, bản thân khóa là không quan trọng, trừ ra nó cần được cả hai bên liên quan biết đến và chỉ có hai bên đó mà thôi.
Trong một thuật toán khóa không đối xứng (như RSA), có hai khóa riêng biệt: một khoá công khai (public key) được công bố và được nhiều người biết đến thuộc về một cá nhân (hoặc tổ chức) cụ thể, trong khi một khóa riêng (private key) tương ứng được giữ bí mật. Một thông báo được mã hoá bằng khoá công khai chỉ có thể được giải mã bằng khoá riêng, do đó bất cứ ai cũng có thể gửi thông báo riêng cho một cá nhân cụ thể. Và điều ngược lại cũng đúng, do đó một thông báo có thể được giải mã bằng khoá chung của một cá nhân phải được cá nhân đó gửi đi. Chúng ta sẽ xem điều này bắt đầu có hiệu lực như thế nào trong việc mã hoá và việc ký các thông báo SOAP.
.
### Mã hóa một tệp
Gene quyết định bắt đầu bằng cách xem mã hóa tác động đến văn bản thông báo thực tế như thế nào. Gene bắt đầu với một tệp văn bản, msg.txt, chứa một dòng duy nhất, như bạn có thể thấy trong Liệt kê 7.
##### Liệt kê 7. Văn bản đích
Hello, world!
Để làm cho mọi thứ đơn giản, Gene đã sử dụng chương trình GnuPG miễn phí, thực hiện lệnh được hiển thị trong Liệt kê 8.
##### Liệt kê 8. Lệnh mã hóa
gpg.exe -c -a --cipher-algo 3DES msg.txt
Lệnh này làm cho chương trình sử dụng thuật toán khóa đối xứng 3DES với nó để mã hóa tệp. Chương trình gọi cụm từ mật khẩu, mà Gene nhập vào là "mật khẩu" và sau đó tạo tệp msg.txt.asc. Bạn có thể xem các nội dung của tệp này trong Liệt kê 9.
##### Liệt kê 9. Tệp được mã hóa
-----BEGIN PGP MESSAGE----- Version: GnuPG v1.4.2.2 (MingW32) jA0EAgMCqFjZXeujyOJgySoKQ2qhpCpGERKpFn0iKms4kwjpI51BLcoTyH4p61YJ kDAiRMbC6PfCBmg= =G4EN -----END PGP MESSAGE-----
Chắc chắn không ai sẽ nghĩ rằng văn bản đầu tiên từ tệp đó! Được cổ vũ, Gene tiến lên xem xét vấn đề về các chữ ký số.
### Các chữ ký hoạt động như thế nào
Các chữ ký số sử dụng các kỹ thuật mã hóa, nhưng mục đích của việc ký là khác nhau. Thay vì che giấu thông báo, một chữ ký tạo lòng tin cho người nhận theo hai mẩu thông tin: người gửi thông báo và bản thân thông báo.
Nó hoạt động như thế này. Người gửi mã hóa thông báo bằng khóa riêng của mình. Sau đó "chữ ký" này được gửi đến người nhận, cùng với thông báo gốc. Người nhận sẽ cố gắng kiểm tra chữ ký, có nghĩa là giải mã chữ ký bằng khóa chung của người gửi và so sánh các kết quả với thông báo gốc. Nếu quá trình này là thành công, người nhận có thể chắc chắn chỉ người gửi có thể là người tạo thông báo, bởi vì không ai trừ người gửi có khóa riêng của mình. Hơn nữa, nếu thông báo gốc đã thay đổi trong quá trình chuyển tiếp, thì chữ ký được giải mã sẽ không khớp với nó, vì thế việc kiểm tra chữ ký thành công cũng có nghĩa là thông báo không bị làm giả.
Thông thường, thay vì ký toàn bộ thông báo, người gửi sẽ tính toán một "tài liệu" của thông báo (bằng cách sử dụng một hàm băm mật mã), ký tài liệu đó và chuyển nó cùng với thông báo chưa mã hóa. Người nhận tính toán tài liệu của thông báo đã nhận và so sánh nó với tài liệu đã giải mã của chữ ký đó. Điều này cung cấp cùng một hiệu quả mà về cơ bản không cần tăng gấp đôi kích thước của mỗi thông báo. (Nó cũng giảm thời gian xử lý để tạo và kiểm tra chữ ký).
### Việc ký một tệp
Được khuyến khích, Gene quyết định xem điều này đang hoạt động. Ý định của ông là ký bằng số tệp msg.txt mà Gene đã mã hóa trước đó. Vì nó làm cho việc ký một tệp đơn giản, nên Gene sẽ sử dụng cùng phần mềm GnuPG, mặc dù sau này Gene sẽ sử dụng một kỹ thuật khác để tạo khóa thường được ứng dụng thực tế sử dụng.
Bước đầu tiên là tạo cặp khoá bằng cách sử dụng lệnh trong Liệt kê 10.
##### Liệt kê 10. Tạo một cặp khóa
gpg.exe --gen-key
Chương trình hỏi nhiều câu hỏi về khóa, như tên, email của Gene và v.v. Gene chọn các tham số khóa mặc định (thuật toán DSA và chiều dài khóa 2048 bit) và cung cấp tên là "Jon Dow". Hoạt động này lưu trữ các khóa trong một tệp kho khóa (keystore) trong thư mục nhà của Gene.
Bây giờ Gene có thể ký thông báo. Ông sử dụng lệnh được hiển thị trong Liệt kê 11.
##### Liệt kê 11. Ký tài liệu
gpg.exe --clearsign -u "Jon Dow" msg.txt
Lúc này, chương trình yêu cầu mật khẩu kết hợp với khóa riêng của "Jon Dow", sau đó tạo tệp msg.txt.asc, như trong Liệt kê 12.
##### Liệt kê 12. Tài liệu đã ký
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Hello, world! -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.2.2 (MingW32) iD8DBQFEhftF06oTl3UESDQRArHsAJ0bE2qUEeVb5IDz4gQuRCgOes6v7gCfQhbJ l356yO+YTkJUJZx4KoTTzok= =ld3Y -----END PGP SIGNATURE-----
Một người đang nhận thông báo này sẽ biết giải mã chữ ký bằng cách sử dụng khóa chung của "Jon Dow", áp dụng thuật toán băm cho thông báo chưa mã hóa (sử dụng SHA1) và so sánh cả hai thông báo.
Bây giờ họ hiểu cách mã hóa và chữ ký hoạt động, Gene và Frances sẵn sàng chuyển sang bảo vệ dịch vụ thực tế.
## Bảo vệ dịch vụ
Việc bảo vệ dịch vụ liên quan đến một số các bước phải diễn ra trước khi thông báo an ninh đầu tiên có thể được gửi đi và trong khi không có bước nào trong số các bước đó dành riêng cho đặc tả Các dịch vụ Web-An ninh thực tế (chứ không phải phần mềm mà nhóm làm việc đang sử dụng để tạo ra các thông báo), những bước này rất quan trọng và, dưới dạng này hay dạng khác, sẽ diễn ra đối với bất kỳ bản cài đặt Các dịch vụ Web-An ninh nào.
### Tạo kho khóa
Bây giờ Gene đã thấy các chữ ký và mã hóa đang hoạt động, Gene cần bắt đầu chuẩn bị bản cài đặt riêng của nhóm làm việc. Gene cần bắt đầu bằng cách tạo kho khóa. Kho khóa sẽ bao gồm tất cả các cặp khóa chung-khóa riêng có thể cần dùng. Để làm điều đó, Gene sẽ sử dụng một ứng dụng công cụ khóa (keytool) đi kèm với JDK.
Để tạo một khoá mới và tạo một kho khóa (keystore), Gene thực hiện các lệnh sau đây, như đã thấy trong Liệt kê 13.
##### Liệt kê 13. Tạo một cặp khóa và kho khóa
>
cd %JAVA_HOME%\bin> keytool -genkey -keystore mykeys.jks -alias geneEnter keystore password: mykeystorepasswordWhat is your first and last name? [Unknown]: Gene TellurideWhat is the name of your organizational unit? [Unknown]: Information TechnologiesWhat is the name of your organization? [Unknown]: The Daily MoonWhat is the name of your City or Locality? [Unknown]: New YorkWhat is the name of your State or Province? [Unknown]: NYWhat is the two-letter country code for this unit? [Unknown]: USIs CN=Gene Telluride, OU=Information Technologies, O=The Daily Moon, L=New York, ST=NY, C=U S correct? [no]: yesEnter key password for <gene> (RETURN if same as keystore password): mypassword
Dòng lệnh báo cho công cụ này biết để tạo một cặp khóa và lưu nó trong tệp mykeys.jks. Cặp khóa có một bí danh của Gene, cho phép chúng ta dễ dàng tham chiếu nó. Frances có thể tạo khóa của mình và lưu nó trong cùng một tệp, mykeys.jks.
Bây giờ họ sẵn sàng bắt đầu thực hiện công việc bảo vệ dịch vụ riêng của mình.
### Kích hoạt an ninh
Bước đầu tiên
trong việc thêm Các dịch vụ Web-An ninh cho dịch vụ này là kích hoạt nó trên máy chủ.
Apache Axis2, máy các dịch vụ Web mà nhóm làm việc đang chạy dịch vụ của mình, được
xây dựng theo mô đun và mô đun Các dịch vụ Web-An ninh được gọi là Rampart (xem
[Các điều kiện cần trước](prerequisites.html) với các thông tin tải về).
Một khi bạn đã tải về Rampart, đặt tệp rampart-1.0.mar trong thư mục modules (các mô
đun) của bản cài đặt Axis của bạn. Ví dụ, bản cài đặt của Gene có thư mục modules ở
C:\SW\geronimo-1.0\config-store\32\war\WEB-INF\modules.
Tiếp theo, Gene cần tạo cho mô đun này hoàn toàn có sẵn, vì trong "chuỗi của trình xử lý" hoạt động sau hậu trường của Axis2, nó cần kích hoạt trước khi thông báo có thể được hướng đến một dịch vụ cụ thể. Khởi động lại Geronimo và đăng nhập vào trang quản trị Axis2 tại http://localhost:8080/axis2/axis2-admin/login. (Tên người dùng là admin và mật khẩu là axis2) Nhấn Engage Module/For all services (Kích hoạt Mô đun/Cho tất cả các dịch vụ) và chọn rampart-1.0. Nhấn Engage, như bạn có thể thấy trong Hình 3.
##### Hình 3. Kích hoạt mô đun Rampart
![ kích hoạt mô đun Rampart](fig03.jpg)
Bạn cũng có thể kích hoạt mô đun Rampart bằng cách thêm nó vào tệp axis2.xml, như bạn sẽ thấy khi chúng ta xem xét việc bảo vệ ứng dụng khách.
### Thiết lập an ninh cho dịch vụ
Bây giờ cơ sở hạ tầng đã ở đúng chỗ, Frances có thể bắt đầu bảo vệ dịch vụ thực tế. Trước tiên, Frances tắt Geronimo, vì Frances muốn cập nhật tệp services.xml nằm trong kho lưu trữ CMSService.aar. (Frances có tùy chọn cập nhật và tải lên lại dịch vụ, nhưng cô ấy chọn thay đổi kho lưu trữ trực tiếp). Bản cài đặt của tờ báo có tệp *.aar tại vị trí C:\SW\geronimo-1.0\config-store\32\war\WEB-INF\services\CMSService.aar. Frances cập nhật tệp services.xml để yêu cầu một dấu thời gian (timestamp), như đã thấy trong Liệt kê 14.
##### Liệt kê 14. Thêm một dấu thời gian tới dịch vụ
<service name="CMSService"> <description> This is a sample Web Service for the newspaper's Content Managment System. </description> <parameter name="ServiceClass" locked="false">CMSService</parameter>
<parameter name="InflowSecurity"> <action> <items>Timestamp</items> </action> </parameter> <parameter name="OutflowSecurity"> <action> <items>Timestamp</items> </action> </parameter><operation name="getNumberOfArticles"> <messageReceiver class= "org.apache.axis2.receivers.RawXMLINOutMessageReceiver"/> </operation> </service>
Axis2 cho phép Frances kiểm soát cụ thể các thông báo chảy vào và chảy ra khỏi dịch vụ. Trong trường hợp này, Frances đã lệnh cho máy các dịch vụ Web yêu cầu các thông báo gửi đến bao gồm một Dấu thời gian và bao gồm một Dấu thời gian trong thông báo gửi ra được trả về cho ứng dụng khách.
Ngay đây, chúng ta sẽ thấy kết quả mà sự thay đổi này có trên các thông báo được chuyển qua giữa máy chủ và ứng dụng khách, nhưng khi Frances cố gắng để chạy một bài kiểm tra, TCPMon cho thấy máy chủ trả về một lỗi chứ không phải là các thông tin dự kiến, như bạn có thể thấy trong Liệt kê 15.
##### Liệt kê 15. Thiếu các tiêu đề an ninh
<?xml version='1.0' encoding='UTF-8'?> <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:wsa="http://www.w3.org/2005/08/addressing"> <soapenv:Header> <wsa:ReplyTo> <wsa:Address> http://www.w3.org/2005/08/addressing/anonymous </wsa:Address> </wsa:ReplyTo> <wsa:MessageID> urn:uuid:1CA9E94A9C7FE9D5B311507328796251 </wsa:MessageID> <wsa:Action> http://www.w3.org/2005/08/addressing/fault </wsa:Action> </soapenv:Header> <soapenv:Body> <soapenv:Fault> <faultcode>soapenv:Client</faultcode>
<faultstring> WSDoAllReceiver: Request does not contain required Security header </faultstring><detail> <Exception>org.apache.axis2.AxisFault: WSDoAllReceiver: Request does not contain required Security header at ... </Exception> </detail> </soapenv:Fault> </soapenv:Body> </soapenv:Envelope>
Điều quan trọng ở đây là bây giờ Frances biết nó đang hoạt động; máy này sẽ không chấp nhận các thông báo trừ khi chúng tuân theo an ninh mà cô ấy đã cấu hình cho dịch vụ.
Bây giờ Frances có thể chuyển tới ứng dụng khách.
### Bảo vệ ứng dụng khách
Theo nhiều cách, ứng dụng khách cũng là một máy chủ giả, trong đó nó cũng gửi và nhận các thông báo SOAP, lẽ ra nó phải diễn ra như bình thường để cho bước đầu tiên của Frances trong việc bảo vệ ứng dụng khách là thêm tệp rampart-1.0.mar vào bản cài đặt của ứng dụng khách. Để làm điều đó, đầu tiên Frances tạo một thư mục mới là, <CLIENT_HOME>\axis-repo\modules, ở đây <CLIENT_HOME> là thư mục trong đó có đặt tệp ClassifiedClient.class. Rồi Frances thêm tệp rampart-1.0.mar vào thư mục đó. Frances cũng tạo một thư mục thứ hai là, <CLIENT_HOME>\axis-repo\conf, trong đó cô tạo một tệp mới tên là axis2.xml. Tệp này có chứa mã như thấy trong Liệt kê 16.
##### Liệt kê 16. Tệp axis2.xml đầu tiên
<axisconfig name="AxisJava2.0">
<!-- Engage the security module --> <module ref="ramart"/> <parameter name="OutflowSecurity"> <action> <items>Timestamp</items> </action> </parameter> <!-- <parameter name="InflowSecurity"> <action> <items>Timestamp</items> </action> </parameter> --><!-- ================================================= --> <!-- Parameters --> <!-- ================================================= --> <parameter name="hotdeployment" locked="false">true</parameter> <parameter name="hotupdate" locked="false">false</parameter> <parameter name="enableMTOM" locked="false">true</parameter> <!-- Uncomment this to enable REST support --> <!-- <parameter name="enableREST" locked="false">true</parameter>--> <parameter name="userName" locked="false">admin</parameter> <parameter name="password" locked="false">axis2</parameter> <!-- ================================================= --> <!-- Message Receivers --> <!-- ================================================= --> <!--This is the Deafult Message Receiver for the system , if you want to have MessageReceivers for --> <!--all the other MEP implement it and add the correct entry to here, so that you can refer from--> <!--any operation --> <!--Note : You can ovride this for particular service by adding the same element with your requirement--> <messageReceivers> <messageReceiver mep="http://www.w3.org/2004/08/wsdl/in-only" class="org.apache.axis2.receivers.RawXMLINOnlyMessageReceiver"/> <messageReceiver mep="http://www.w3.org/2004/08/wsdl/in-out" class="org.apache.axis2.receivers.RawXMLINOutMessageReceiver"/> </messageReceivers> <!-- ================================================= --> <!-- Transport Ins --> <!-- ================================================= --> <transportReceiver name="http" class="org.apache.axis2.transport.http.SimpleHTTPServer"> <parameter name="port" locked="false">6060</parameter> <!--If you want to give your own host address for EPR generation--> <!--uncommet following paramter , and set as you required.--> <!--<parameter name="hostname" locked="false">http://myApp.com/ws</parameter>--> </transportReceiver> <transportReceiver name="tcp" class="org.apache.axis2.transport.tcp.TCPServer"> <parameter name="port" locked="false">6061</parameter> <!--If you want to give your own host address for EPR generation--> <!--uncommet following paramter , and set as you required.--> <!--<parameter name="hostname" locked="false">tcp://myApp.com/ws</parameter>--> </transportReceiver> <!-- ================================================= --> <!-- Transport Outs --> <!-- ================================================= --> <transportSender name="tcp" class="org.apache.axis2.transport.tcp.TCPTransportSender"/> <transportSender name="local" class="org.apache.axis2.transport.local.LocalTransportSender"/> <transportSender name="jms" class="org.apache.axis2.transport.jms.JMSSender"/> <transportSender name="http" class="org.apache.axis2.transport.http.CommonsHTTPTransportSender"> <parameter name="PROTOCOL" locked="false">HTTP/1.1</parameter> <parameter name="Transfer-Encoding" locked="false">chunked</parameter> </transportSender> <transportSender name="https" class="org.apache.axis2.transport.http.CommonsHTTPTransportSender"> <parameter name="PROTOCOL" locked="false">HTTP/1.1</parameter> <parameter name="Transfer-Encoding" locked="false">chunked</parameter> </transportSender> <!-- ================================================= --> <!-- Phases --> <!-- ================================================= --> <phaseOrder type="inflow"> <!-- System pre defined phases --> <phase name="Transport"> <handler name="RequestURIBasedDispatcher" class="org.apache.axis2.engine.RequestURIBasedDispatcher"> <order phase="Dispatch"/> </handler> <handler name="SOAPActionBasedDispatcher" class="org.apache.axis2.engine.SOAPActionBasedDispatcher"> <order phase="Dispatch"/> </handler> </phase> <phase name="Security"/> <phase name="PreDispatch"/> <phase name="Dispatch" class="org.apache.axis2.engine.DispatchPhase"> <handler name="AddressingBasedDispatcher" class="org.apache.axis2.engine.AddressingBasedDispatcher"> <order phase="Dispatch"/> </handler> <handler name="SOAPMessageBodyBasedDispatcher" class="org.apache.axis2.engine.SOAPMessageBodyBasedDispatcher"> <order phase="Dispatch"/> </handler> <handler name="InstanceDispatcher" class="org.apache.axis2.engine.InstanceDispatcher"> <order phase="PostDispatch"/> </handler> </phase> <!-- System pre defined phases --> <!-- After Postdispatch phase module author or or service author can add any phase he want --> <phase name="OperationInPhase"/> </phaseOrder> <phaseOrder type="outflow"> <!-- user can add his own phases to this area --> <phase name="OperationOutPhase"/> <!--system predefined phase--> <!--these phase will run irrespective of the service--> <phase name="PolicyDetermination"/> <phase name="MessageOut"/> </phaseOrder> <phaseOrder type="INfaultflow"> <phase name="PreDispatch"/> <phase name="Dispatch" class="org.apache.axis2.engine.DispatchPhase"> <handler name="RequestURIBasedDispatcher" class="org.apache.axis2.engine.RequestURIBasedDispatcher"> <order phase="Dispatch"/> </handler> <handler name="SOAPActionBasedDispatcher" class="org.apache.axis2.engine.SOAPActionBasedDispatcher"> <order phase="Dispatch"/> </handler> <handler name="AddressingBasedDispatcher" class="org.apache.axis2.engine.AddressingBasedDispatcher"> <order phase="Dispatch"/> </handler> <handler name="SOAPMessageBodyBasedDispatcher" class="org.apache.axis2.engine.SOAPMessageBodyBasedDispatcher"> <order phase="Dispatch"/> </handler> <handler name="InstanceDispatcher" class="org.apache.axis2.engine.InstanceDispatcher"> <order phase="PostDispatch"/> </handler> </phase> <!-- user can add his own phases to this area --> <phase name="OperationInFaultPhase"/> </phaseOrder> <phaseOrder type="Outfaultflow"> <!-- user can add his own phases to this area --> <phase name="OperationOutFaultPhase"/> <phase name="PolicyDetermination"/> <phase name="MessageOut"/> </phaseOrder> </axisconfig>
Hầu hết các mã này là mẫu soạn sẵn, vay mượn từ các ví dụ Axis2 khác. Tuy nhiên, trong phần in đậm ở trên đầu, Frances thêm vào để báo cho ứng dụng khách thêm một Dấu thời gian vào thông báo mà nó gửi đến máy chủ. Frances quyết định không bàn đến Dấu thời gian được máy chủ trả về, ít nhất là vào lúc này. Tuy nhiên, không giống như dịch vụ, ứng dụng khách sẽ không tự động tuân theo các hướng dẫn này. Frances đã thực hiện các thay đổi cho lớp thực tế.
### Các thay đổi cho lớp ứng dụng khách
Để cho lớp ứng dụng
khách thực hiện các thay đổi được quy định trong tệp axis2.xml, nó phải biết về
chúng. Để kết thúc, Frances thêm cấu hình vào quá trình tạo
ServiceClient, như đã thấy trong Liệt kê
17.
##### Liệt kê 17. Gọi cấu hình mới từ ClassifiedClient.java
... public static void main(String[] args) { try { OMElement payload = ClassifiedClient.getNumOfArticlesOMElement();
ConfigurationContext configContext = ConfigurationContextFactory .createConfigurationContextFromFileSystem ( "axis-repo", null);Options options = new Options(); options.setTo(targetEPR); options.setTransportInProtocol(Constants.TRANSPORT_HTTP); ServiceClient sender = new ServiceClient( configContext, null); sender.setOptions(options); OMElement result = sender.sendReceive(payload); String response = result.getText(); System.out.println("There are "+response+ " classifieds at the moment."); } catch (Exception e) { System.out.println(e.toString()); } } }
Trước
tiên, Frances tạo một
ConfigurationContext mới, cho phép
ServiceClient tìm kiếm một cấu hình mới. Nhưng để làm
cho nó xảy ra, cô ấy sẽ cần thay đổi cách mà cô gọi là lớp ứng dụng khách thực
tế.
### Kéo tất cả chúng lại với nhau
Để cho ứng dụng khách gọi đúng mô đun Rampart, nó cần biết nơi tìm tệp cấu hình và nơi tìm các mục kho lưu trữ bất kỳ khác, chẳng hạn như tệp *.mar của chính nó. Để làm điều đó, Frances thêm nhiều chi tiết hơn vào kịch bản thiết lập đường dẫn lớp (classpath) của mình và chạy lớp ứng dụng khách, như đã thấy trong Liệt kê 18.
##### Liệt kê 18. Gọi lớp
echo off SET CLASSPATH=C:/SW/axis2/lib/XmlSchema-1.0.2.jar SET CLASSPATH=%CLASSPATH%;C:/SW/axis2/lib/axiom-api-1.0.jar SET CLASSPATH=%CLASSPATH%;C:/SW/axis2/lib/axiom-impl-1.0.jar SET CLASSPATH=%CLASSPATH%;C:/SW/axis2/lib/axis2-kernel-1.0.jar SET CLASSPATH=%CLASSPATH%;C:/SW/axis2/lib/commons-codec-1.3.jar SET CLASSPATH=%CLASSPATH%;C:/SW/axis2/lib/commons-httpclient-3.0.jar SET CLASSPATH=%CLASSPATH%;C:/SW/axis2/lib/commons-logging-1.0.4.jar SET CLASSPATH=%CLASSPATH%;C:/SW/axis2/lib/ geronimo-spec-activation-1.0.2-rc4.jar SET CLASSPATH=%CLASSPATH%;C:/SW/axis2/lib/ geronimo-spec-javamail-1.3.1-rc5.jar SET CLASSPATH=%CLASSPATH%;C:/SW/axis2/lib/jaxen-1.1-beta-8.jar SET CLASSPATH=%CLASSPATH%;C:/SW/axis2/lib/log4j-1.2.13.jar SET CLASSPATH=%CLASSPATH%;C:/SW/axis2/lib/neethi-1.0.1.jar SET CLASSPATH=%CLASSPATH%;C:/SW/axis2/lib/stax-api-1.0.jar SET CLASSPATH=%CLASSPATH%;C:/SW/axis2/lib/wsdl4j-1.5.2.jar SET CLASSPATH=%CLASSPATH%;C:/SW/axis2/lib/wstx-asl-2.9.3.jar
SET CLASSPATH=%CLASSPATH%; C:/sw/ClassifiedClient/lib/wss4j-1.5.0.jar SET CLASSPATH=%CLASSPATH%; C:/sw/ClassifiedClient/lib/xmlsec-1.3.0.jar SET CLASSPATH=%CLASSPATH%; C:/sw/ClassifiedClient/lib/ commons-discovery-0.2.jar SET CLASSPATH=%CLASSPATH%; C:/sw/ClassifiedClient/lib/ bcprov-jdk13-132.jar SET CLASSPATH=%CLASSPATH%; C:/sw/ClassifiedClient/lib/xalan.jarSET CLASSPATH=%CLASSPATH%;. java.exe -Daxis2.xml=axis-repo/conf/axis2.xml -Daxis2.repo=axis-repoClassifiedClient
Lưu
ý rằng Frances cũng thêm một số tệp *.jar từ bản phân phối WSS4J (xem
[Các điều kiện cần trước](prerequisites.html) với các thông tin tải
về).
Bây giờ cô ấy đã sẵn sàng để thử yêu cầu một lần nữa.
### Yêu cầu
Việc chạy yêu cầu này cho thấy một thông báo SOAP bình thường, với một ngoại lệ, như đã thấy trong Liệt kê 19.
##### Liệt kê 19. Một thông báo SOAP có đánh dấu thời gian
<?xml version='1.0' encoding='UTF-8'?> <soapenv:Envelope xmlns:soapenv= "http://schemas.xmlsoap.org/soap/envelope/"> <soapenv:Header>
<wsse:Security xmlns:wsse="http://docs.oasis- open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext- 1.0.xsd" soapenv:mustUnderstand="1"> <wsu:Timestamp xmlns:wsu="http://docs.oasis- open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility- 1.0.xsd" wsu:Id="Timestamp-29987161"> <wsu:Created>2006-06-19T16:22:28.578Z</wsu:Created> <wsu:Expires>2006-06-19T16:27:28.578Z</wsu:Expires> </wsu:Timestamp> </wsse:Security></soapenv:Header> <soapenv:Body> <cms:getNumberOfArticles xmlns:cms="http://daily-moon.com/cms"> <cms:category>classifieds</cms:category> </cms:getNumberOfArticles> </soapenv:Body> </soapenv:Envelope>
Bây giờ, lần đầu tiên, Frances thấy một tiêu đề an ninh trong các thông báo của mình. Trong trường hợp này, nó chỉ là một Dấu thời gian, hiển thị khi cô đã tạo thông báo đó. Thuộc tính mustUnderstand có nghĩa là nếu máy chủ không biết phải làm gì với phần tử Timestamp (Dấu thời gian) này, thì nó phải loại bỏ thông báo đó.
Các Timestamp có lẽ là phần tử đơn giản nhất của Các dịch vụ Web-An ninh. Chúng cung cấp một cách để hạn chế tuổi thọ của các thông báo, ngăn chặn những kẻ xấu khỏi thu chặn các thông báo, thay đổi chúng lúc rảnh rỗi và gửi chúng đi. Trong trường hợp này, Dấu thời gian (Timestamp) quá hạn năm giây sau khi tạo thông báo đó, vì vậy nếu thông báo cũ hơn dấu thời gian đó, thì thông báo phải được loại bỏ. (Đúng, một kẻ xấu vẫn có thể thay đổi các giá trị của Dấu thời gian, nhưng chúng ta sẽ đối phó với điều đó khi chúng ta nhận được các chữ ký).
### Đáp ứng
Theo quy định trong dịch vụ, đáp ứng cũng có một Dấu thời gian, như đã thấy trong Liệt kê 20.
##### Liệt kê 20. Đáp ứng
<?xml version='1.0' encoding='UTF-8'?> <soapenv:Envelope xmlns:soapenv= "http://schemas.xmlsoap.org/soap/envelope/"> <soapenv:Header>
<wsse:Security xmlns:wsse="http://docs.oasis- open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext- 1.0.xsd" soapenv:mustUnderstand="1"> <wsu:Timestamp xmlns:wsu="http://docs.oasis- open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility- 1.0.xsd" wsu:Id="Timestamp-22347273"> <wsu:Created>2006-06-19T16:22:29.281Z</wsu:Created> <wsu:Expires>2006-06-19T16:27:29.281Z</wsu:Expires> </wsu:Timestamp> <wsse11:SignatureConfirmation xmlns:wsse11= "http://docs.oasis-open.org/wss/2005/xx/oasis-2005xx-wss-wssecurity- secext-1.1.xsd" xmlns:wsu="http://docs.oasis- open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility- 1.0.xsd" wsu:Id="SigConf-5759024" /> </wsse:Security></soapenv:Header> <soapenv:Body> <resp:numberOfArcticles xmlns:resp="http://daily-moon.com/cms/" xmlns:tns="http://ws.apache.org/axis2" >42</resp:numberOfArcticles> </soapenv:Body> </soapenv:Envelope>
Đáp ứng bao gồm Dấu thời gian, theo quy định, nhưng cũng cho thấy rằng các thông tin an ninh đã được xử lý và được kiểm tra, mặc dù Frances đã không cấu hình ứng dụng khách để kiểm tra cái này hoặc cái khác trong những thực tế này.
Chú ý rằng trong cả hai trường hợp, thông báo thực tế vẫn còn nguyên vẹn.
## Việc ký các thông báo
Bây giờ, vào lúc này, Frances đã thêm một Dấu thời gian cho cả các thông báo gửi đi và gửi đến, nhưng không có gì để ngăn chặn người khác khỏi việc chỉ thay đổi giá trị của nó và phát lại nó. Để giải quyết vấn đề đó (và bất kỳ vấn đề khác phát sinh từ các thông tin có thể đã bị thay đổi) Frances cần xem xét việc ký các thông báo của mình.
### Việc ký thông báo hoạt động như thế nào
Như chúng ta đã được thấy ở trên, việc ký một thông báo liên quan đến việc tạo ra một phiên bản dữ liệu được mã hóa theo một cách đã biết, để cho việc giải mã nó cung cấp một giá trị mà bạn có thể so sánh với giá trị ban đầu. Ví dụ, giả sử Frances muốn ký bằng số phần tử Dấu thời gian trong các thông báo của mình sao cho máy chủ có thể kiểm tra xem các thông báo vẫn chưa bị làm giả hoặc chưa bị lấy ra theo một cách nào đó.
Để làm điều đó, Frances sẽ xây dựng một quá trình có một vài bước.
Trước tiên, Frances sẽ ký thông báo này (hoặc một phần của thông báo). Để làm điều đó, Frances sẽ sử dụng tệp axis2.xml để chỉ định một người sử dụng làm người ký. Axis2 sẽ nhận thông tin đó và làm hai việc với nó. Trước tiên, Axis2 sẽ cung cấp cho người sử dụng một bí danh cho một lớp "gọi lại". Lớp này sẽ trả về mật khẩu cho người dùng đó. Được trang bị mật khẩu đó, sau đó Axis2 sẽ lấy khóa riêng của người dùng đó từ kho khóa (keystore) mà chúng ta đã tạo ra ở trên.
Khi sử dụng khóa riêng này, Axis2 mã hóa hoặc ký, phần có liên quan của thông báo và thêm chữ ký vào thông báo đó. Sau đó Axis2 sẽ gửi thông báo. Khi dịch vụ nhận được thông báo đó, nó gần như thực hiện một cách tương tự, nó sẽ truy cập kho khóa để có được khóa chung cho người dùng đó và sau đó nó xác minh chữ ký.
Lưu ý rằng nếu dịch vụ sắp gửi trở lại nội dung đã được ký, các vai trò này sẽ được đảo ngược lại cho chuyến trả về.
Hãy xem xét việc thiết lập này.
### Lớp
callback
Bước đầu tiên là tạo một lớp
callback (gọi lại). Trong một
tình huống thực, lớp này có thể truy cập vào một thư mục LDAP hoặc sử dụng các phương
thức khác để liên kết một tên người dùng với một mật khẩu, nhưng Frances sẽ bắt đầu
với một bằng chứng-theo-khái niệm, vì vậy cô sẽ tạo ra một lớp
callback đơn giản trả về các giá trị tùy ý, như bạn có thể thấy trong Liệt
kê 21.
##### Liệt kê 21. PWCallback.java, lớp
callback
import org.apache.ws.security.WSPasswordCallback; import javax.security.auth.callback.Callback; import javax.security.auth.callback.CallbackHandler; import javax.security.auth.callback.UnsupportedCallbackException; import java.io.IOException; public class PWCallback implements CallbackHandler { public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException { for (int i = 0; i < callbacks.length; i++) { if (callbacks[i] instanceof WSPasswordCallback) { WSPasswordCallback pc=(WSPasswordCallback)callbacks[i]; if (pc.getIdentifer().equals("gene")) { pc.setPassword("mypassword"); } else if (pc.getIdentifer().equals("frances")) { pc.setPassword("francespassword"); } else { throw new UnsupportedCallbackException( callbacks[i], "Unknown user"); } } else { throw new UnsupportedCallbackException(callbacks[i], "Unrecognized Callback"); } } } }
Những gì mà lớp đó thực hiện trong phương thức
handle()
không quan trọng; tất cả những thứ quan trọng là hoặc nó thiết lập mật khẩu cho đối
tượng
WSPasswordCallback hoặc nó ném ra một ngoại lệ.
### Tệp các đặc tính
Tiếp theo Frances phải tìm một cách để báo cho Axis2 biết nơi tìm kho khóa và lớp nào sẽ thực sự thực hiện tất cả về thủ thuật mã hóa này. Để làm điều đó, Frances tạo ra một tệp các đặc tính là security.properties, như đã thấy trong Liệt kê 22:
##### Liệt kê 22. Tệp security.properties
org.apache.ws.security.crypto.provider=org.apache.ws.security.compo nents.crypto.Merlin org.apache.ws.security.crypto.merlin.keystore.type=jks org.apache.ws.security.crypto.merlin.keystore.password=mykeystorepa ssword org.apache.ws.security.crypto.merlin.file=mykeys.jks
Sau khi xác định nhà cung cấp, tệp các thuộc tính định nghĩa kiểu kho khóa -- trong trường hợp này là jks, định dạng độc quyền đi kèm với Java -- mật khẩu cho kho khóa và tên của tệp kho khóa thực tế, để đơn giản Frances đặt trong cùng thư mục với tệp lớp ứng dụng khách.
### Tệp axis2.xml
Bây giờ Frances cần cho phép tệp axis2.xml những gì cô ấy đã suy nghĩ với các thông báo gửi ra, như bạn có thể thấy trong Liệt kê 23.
##### Liệt kê 23. Tệp axis2.xml, có chữ ký
<axisconfig name="AxisJava2.0"> <!-- Engage the security module --> <module ref="rampart"/> <parameter name="OutflowSecurity"> <action> <items>
Signature</items> <user>gene</user> <passwordCallbackClass>PWCallback</passwordCallbackClass> <signaturePropFile>security.properties</signaturePropFile> <signatureKeyIdentifier>SKIKeyIdentifier</signatureK eyIdentifier> <signatureParts>{Element}{http://schemas.xmlsoap.org /soap/envelope/}Body </signatureParts></action> </parameter> <!-- <parameter name="InflowSecurity"> <action> <items>Timestamp</items> </action> </parameter> --> ...
Trong trường hợp này, thay vì ra lệnh cho ứng dụng khách thêm một Dấu thời gian, cô
ấy ra lệnh cho nó thêm một chữ ký. Xét thấy, ứng dụng khách xem xét tệp quy định
trong
signaturePropFile và sử dụng các thông tin tìm thấy
ở đó -- cùng với
passwordCallbackClass -- để nhận mật khẩu
cho người sử dụng Gene. Từ đó, nó kéo khóa riêng của Gene và ký chỉ một phần của
thông báo được quy định trong phần tử
signatureParts.
Trong trường hợp này, điều đó có nghĩa là phần tử đó được biểu thị bằng phần Thân
(Body) (trái ngược với chính nội dung của phần tử đó), là một phần của
http://schemas.xmlsoap.org/soap/envelope/ namespace.
Bạn có thể ký bất cứ phần nào của thông báo. Ví dụ, người ta thường ký Dấu thời gian, nếu có.
### Yêu cầu
Vậy tất cả những thay đổi này muốn nói gì với các thông báo được ứng dụng khách tạo ra? Bạn có thể xem yêu cầu kết quả trong Liệt kê 24.
##### Liệt kê 24. Yêu cầu đã ký
<?xml version='1.0' encoding='UTF-8'?> <soapenv:Envelope xmlns:soapenv= "http://schemas.xmlsoap.org/soap/envelope/"> <soapenv:Header> <wsse:Security xmlns:wsse="..." soapenv:mustUnderstand="1"> <ds:Signature xmlns:ds="..." Id="Signature-8789796"> <ds:SignedInfo> <ds:CanonicalizationMethod Algorithm= "http://www.w3.org/2001/10/xml-exc-c14n#" /> <ds:SignatureMethod Algorithm= "http://www.w3.org/2000/09/xmldsig#rsa-sha1" /> <ds:Reference URI="#id-17764792"> <ds:Transforms> <ds:Transform Algorithm= "http://www.w3.org/2001/10/xml-exc-c14n#" /> </ds:Transforms> <ds:DigestMethod Algorithm= "http://www.w3.org/2000/09/xmldsig#sha1" /> <ds:DigestValue >wg+9KsR6BVBiO/hakJJwMdtU7+I=</ds:DigestValue> </ds:Reference> </ds:SignedInfo> <ds:SignatureValue>hom9Enzu3yHBuaF...</ds:SignatureValue> <ds:KeyInfo Id="KeyId-19475750"> <wsse:SecurityTokenReference xmlns:wsu=".." wsu:Id="STRId-31156635"> <wsse:KeyIdentifier EncodingType="http://docs.oasis -open.org/wss/2004/01/oasis-200401-wss-soap-message-security- 1.0#Base64Binary" ValueType="http://docs.oasis-open.org/wss/2004/01/o asis-200401-wss-x509-token-profile-1.0#X509SubjectKeyIdentifier" >CuJdE1B2dUFd1dkLZSzQ5vj6MYg=</wsse:KeyIdentifier> </wsse:SecurityTokenReference> </ds:KeyInfo> </ds:Signature> </wsse:Security> </soapenv:Header> <soapenv:Body xmlns:wsu="..." wsu:Id="id-17764792"> <cms:getNumberOfArticles xmlns:cms="http://daily-moon.com/cms"> <cms:category>classifieds</cms:category> </cms:getNumberOfArticles> </soapenv:Body> </soapenv:Envelope>
Tôi đã chia nhỏ các giá trị vùng tên ra để làm cho phần này dễ đọc hơn một chút,
nhưng hãy đi qua nó từ từ. Phần tử
Security (an ninh) có
chứa tất cả các thông tin an ninh, tất nhiên, bắt đầu với Signature (Chữ ký). Chữ ký
bắt đầu với các thông tin về những gì đã thực sự được ký. Nhảy về phía trước chỉ một
chút ít thôi, phần tử
Reference (tham chiếu) bao gồm một
thuộc tính
URI. URL tham chiếu ngược tới thuộc tính
id cho phần Thân (Body), hãy nhớ, đó là những gì mà Frances
nói cho ứng dụng khách biết để ký. Vì vậy chữ ký đó nói cho dịch vụ biết những thông
tin nào thực sự được ký.
Quay trở lại, bước đầu tiên trong nội dung ký là làm cho nó hợp với quy tắc tiêu
chuẩn -- loại bỏ các nút văn bản không liên quan và v.v -- nhưng thực sự có hai cách
để làm điều đó, bao hàm và loại trừ, sự khác biệt có trong cách mỗi phương thức xử lý
các khai báo vùng tên . Vì vậy, phần tử
CanonicalizationMethod quy định chữ ký sử dụng phương thức nào.
Sau đó chúng ta chuyển đến
SignatureMethod, (Phương thức
chữ ký), như tên cho thấy, xác định phương thức được sử dụng để ký dữ liệu có liên
quan.
Phần tử
Reference bao gồm các thông tin về tất cả các bước
đã được dùng để đạt tới nội dung cuối cùng để ký, theo thứ tự, sao cho quá trình kiểm
tra có thể nhận cùng một số bước và (hy vọng) đạt tới
SignatureValue (Giá trị chữ ký) giống nhau.
KeyInfo (Thông tin khóa) cung cấp hoặc là khóa thực tế
được sử dụng để ký dữ liệu hoặc một tham chiếu đến khóa.
### Thực hiện các thay đổi cho dịch vụ
Bây giờ ứng dụng khách sẽ tạo chữ ký, nhưng dịch vụ không biết phải làm gì với nó. Frances sắp thay đổi điều đó.
Về bản chất, dịch vụ cần thực hiện rất nhiều các bước giống nhau mà ứng dụng khách đã thực hiện; nó cần có khả năng tìm các mật khẩu và các khóa trong kho khóa, do đó Frances bắt đầu bằng cách thêm các tệp mykeys.jks, PWCallback.class và security.properties vào tệp CMSService.aar. Bạn không cần sử dụng lớp và kho khóa giống như bạn đã sử dụng cho ứng dụng khách, nhưng trong trường hợp này, để cho thuận tiện Frances thực hiện nó.
Frances cũng thêm các tệp bcprov-jdk13-132.jar, wss4j-1.5.0.jar và -1.3.0.jar xmlsec vào thư mục lib của ứng dụng Axis2. (Những tệp này có trong bản phân phối WSS4J).
Sau đó Frances cần thiết lập định nghĩa dịch vụ (trong tệp services.xml) để công nhận rằng dữ liệu đã ký sẽ đến theo cách của nó. Cô ấy làm điều đó bằng cách thực hiện các thay đổi được hiển thị trong Liệt kê 25.
##### Liệt kê 25. Báo cho dịch vụ biết để yêu cầu dữ liệu đã ký
<service name="CMSService"> <description> This is a sample Web Service for the newspaper's Content Managment System. </description> <parameter name="ServiceClass" locked="false">CMSService</parameter> <parameter name="InflowSecurity"> <action>
<items>Signature</items> <passwordCallbackClass>PWCallback</passwordCallbackClass> <signaturePropFile>security.properties</signaturePropFile></action> </parameter> <parameter name="OutflowSecurity"> <action> <items>Timestamp</items> </action> </parameter> <operation name="getNumberOfArticles"> <messageReceiver class="org.apache.axis2.receivers.RawXMLINOutMessageReceiver"/> </operation> </service>
Những thay đổi này là đủ để cho các dịch vụ biết những gì để mong đợi và những gì để thực hiện với dữ liệu đã ký.
### Đáp ứng
Đáp ứng này là một tài liệu bao gồm một Dấu thời gian, theo quy định trong tham số
OutFlowSecurity, nhưng cũng bao gồm thông tin về việc
xác minh chữ ký, như đã thấy trong Liệt kê26.
##### Liệt kê 26. Đáp ứng
<?xml version='1.0' encoding='UTF-8'?> <soapenv:Envelope xmlns:soapenv= "http://schemas.xmlsoap.org/soap/envelope/"> <soapenv:Header> <wsse:Security xmlns:wsse="..." soapenv:mustUnderstand="1"> <wsu:Timestamp xmlns:wsu="..." wsu:Id="Timestamp-27995990"> <wsu:Created>2006-06-19T23:56:55.214Z</wsu:Created> <wsu:Expires>2006-06-20T00:01:55.214Z</wsu:Expires> </wsu:Timestamp> <wsse11:SignatureConfirmation xmlns:wsse11="..." xmlns:wsu="..." Value="hom9Enzu3yHBuaigFl26b6A+5hy..." wsu:Id="SigConf-25877728" /> </wsse:Security> </soapenv:Header> <soapenv:Body> <resp:numberOfArcticles xmlns:resp="http://daily-moon.com/cms/" xmlns:tns="http://ws.apache.org/axis2">42</resp:numberOfArcticles> </soapenv:Body> </soapenv:Envelope>
Bây giờ hãy xem xét cách thêm mã hóa vào hình ảnh.
## Thêm mã hóa
Frances hài lòng với quá trình kiểm tra một phần của thông báo khi sử dụng các chữ ký, nhưng vẫn không có cách nào để che dấu thông tin sao cho các đối thủ cạnh tranh và kẻ xấu khác không thể đọc nó. Chú ý đến vấn đề đó, Frances sẽ phải thêm mã hóa cho ứng dụng.
### Thay đổi dịch vụ
Lúc này, cô bắt đầu với dịch vụ. Cô đã thêm vào tất cả các lớp bổ sung mà ứng dụng cần, vì thế tất cả những thứ mà cô cần thay đổi là tệp services.xml, như bạn có thể thấy trong Liệt kê 27.
##### Liệt kê 27. Thêm mã hóa vào dịch vụ
<service name="CMSService"> <description> This is a sample Web Service for the newspaper's Content Managment System. </description> <parameter name="ServiceClass" locked="false">CMSService</parameter> <parameter name="InflowSecurity"> <action> <items>
TimestampSignature Encrypt</items> <passwordCallbackClass>PWCallback</passwordCallbackClass> <signaturePropFile>security.properties</signaturePropFile> </action> </parameter> <operation name="getNumberOfArticles"> <messageReceiver class= "org.apache.axis2.receivers.RawXMLINOutMessageReceiver"/> </operation> </service>
Ở đây Frances đã nói cho dịch vụ biết rằng thông báo đưa vào sẽ phải có thêm Dấu thời gian và rồi chúng sẽ được ký và sau đó chúng sẽ được mã hóa -- theo thứ tự đó.
Bây giờ Frances chỉ cần báo cho ứng dụng khách biết để thực hiện nó.
### Thay đổi ứng dụng khách
Vì Frances đã đặt nền tảng rồi, nên việc thêm mã hóa cho ứng dụng khách cũng là dễ hiểu và đòi hỏi đúng một sự thay đổi đơn giản cho tệp axis2.xml, như bạn có thể thấy trong Liệt kê 28.
##### Liệt kê 28. Thêm mã hóa cho ứng dụng khách
<axisconfig name="AxisJava2.0"> <!-- Engage the security module --> <module ref="rampart"/> <parameter name="OutflowSecurity"> <action> <items>Timestamp Signature Encrypt</items> <user>gene</user> <passwordCallbackClass>PWCallback</passwordCallbackClass> <signaturePropFile>security.properties</signaturePropFile> <signatureKeyIdentifier >SKIKeyIdentifier</signatureKeyIdentifier>
<encryptionKeyIdentifier >SKIKeyIdentifier</encryptionKeyIdentifier> <encryptionUser>frances</encryptionUser><signatureParts>{Element}{http://schemas.xmlsoap.org/soap/env elope/}Body</signatureParts> <optimizeParts>//xenc:EncryptedData/xenc:CipherData/xenc:Ciph erValue</optimizeParts></action> </parameter> <!-- ================================================= --> <!-- Parameters --> <!-- ================================================= --> <parameter name="hotdeployment" locked="false">true</parameter> ...
Lưu ý là Francis sẽ xác định một người dùng khác để mã hóa hơn là cô đã sử dụng cho
chữ ký số. Đây không phải là một yêu cầu, nhưng nó có thể. Ngoài ra lưu ý việc bổ
sung phần tử
optimizeParts, xác định cách Axis2 cần biểu
thị dữ liệu đã mã hóa trong thông báo.
Chúng ta hãy xem tất cả kết thúc như thế nào.
### Yêu cầu
Với tất cả mọi thứ ở đúng chỗ, thông báo đang trở nên hơi phức tạp một chút, như bạn có thể thấy trong Liệt kê 29.
##### Liệt kê 29. Yêu cầu được mã hóa, được ký và được đóng dấu
<?xml version='1.0' encoding='UTF-8'?> <soapenv:Envelope xmlns:soapenv= "http://schemas.xmlsoap.org/soap/envelope/" xmlns:xenc="http://www.w3.org/2001/04/xmlenc#"> <soapenv:Header> <wsse:Security xmlns:wsse="..." soapenv:mustUnderstand="1">
<xenc:EncryptedKey Id="EncKeyId-229902"> <xenc:EncryptionMethod Algorithm= "http://www.w3.org/2001/04/xmlenc#rsa-1_5" /> <ds:KeyInfo xmlns:ds="..."> <wsse:SecurityTokenReference> <wsse:KeyIdentifier EncodingType="http://docs.oasis -open.org/wss/2004/01/oasis-200401-wss-soap-message-security- 1.0#Base64Binary" ValueType="http://docs.oasis-open.org/wss/2004/01/o asis-200401-wss-x509-token-profile-1.0#X509SubjectKeyIdentifier" > Xeg55vRyK3ZhAEhEf+YT0z986L0= </wsse:KeyIdentifier> </wsse:SecurityTokenReference> </ds:KeyInfo> <xenc:CipherData> <xenc:CipherValue>PpAOXj5P0W8ukm...</xenc:CipherValue> </xenc:CipherData> <xenc:ReferenceList> <xenc:DataReference URI="#EncDataId-30957433" /> </xenc:ReferenceList> </xenc:EncryptedKey><ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#" Id="Signature-17764792"> <ds:SignedInfo> <ds:CanonicalizationMethod Algorithm= "http://www.w3.org/2001/10/xml-exc-c14n#" /> <ds:SignatureMethod Algorithm= "http://www.w3.org/2000/09/xmldsig#rsa-sha1" /> <ds:Reference URI="#id-30957433"> <ds:Transforms> <ds:Transform Algorithm= "http://www.w3.org/2001/10/xml-exc-c14n#" /> </ds:Transforms> <ds:DigestMethod Algorithm= "http://www.w3.org/2000/09/xmldsig#sha1" /> <ds:DigestValue>+ECkM6R4GQ7AQ=...</ds:DigestValue> </ds:Reference> </ds:SignedInfo> <SignatureValue>DIeP5AxVmfw...</ds:SignatureValue> <ds:KeyInfo Id="KeyId-16675983"> <wsse:SecurityTokenReference xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401- wss-wssecurity-utility-1.0.xsd" wsu:Id="STRId-21866740"> <wsse:KeyIdentifier EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401- wss-soap-message-security-1.0#Base64Binary" ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401- wss-x509-token-profile-1.0#X509SubjectKeyIdentifier"> CuJdE1B2dUFd1dkLZSzQ5vj6MYg=</wsse:KeyIdentifier> </wsse:SecurityTokenReference> </ds:KeyInfo> </ds:Signature> <wsu:Timestamp xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401- wss-wssecurity-utility-1.0.xsd" wsu:Id="Timestamp-13665843"> <wsu:Created>2006-06-20T00:46:58.263Z</wsu:Created> <wsu:Expires>2006-06-20T00:51:58.263Z</wsu:Expires> </wsu:Timestamp> </wsse:Security> </soapenv:Header> <soapenv:Body xmlns:wsu="..." wsu:Id="id-30957433"> <xenc:EncryptedData Id="EncDataId-30957433" Type= "http://www.w3.org/2001/04/xmlenc#Content"> <xenc:EncryptionMethod Algorithm= "http://www.w3.org/2001/04/xmlenc#aes128-cbc" /> <xenc:CipherData> <xenc:CipherValue> DZ3vWPtabb5vBpZMlEYLPjFc8r2DMJ... fSjXpBFa7gybNA== </xenc:CipherValue> </xenc:CipherData> </xenc:EncryptedData></soapenv:Body> </soapenv:Envelope>
Bắt đầu ở dưới cùng, lưu ý rằng thiếu yêu cầu thực tế hay đúng hơn là Axis2 đã thay
thế nó bằng một phần tử
EncryptedData bao gồm thông tin về
cách dữ liệu được mã hóa, cũng như các phần tử dữ liệu đã mã hóa thực tế (trong
CypherData và
CypherValue).
Dữ liệu đã được mã hóa bằng khóa dùng chung, có nghĩa là thông báo cần bao gồm khóa
đó sao cho nó có thể được giải mã. Khóa dùng chung đã được mã hóa với khóa chung của
người nhận và được nhúng vào phần Tiêu đề (Header), trong phần tử
EncryptedKey. Khóa này cũng bao gồm một
ReferenceList, có một
DataReference chỉ trở lại
tới dữ liệu mà khóa này đã được sử dụng để mã hóa.
Vì vậy, để đảo ngược hướng, người nhận (trong trường hợp này, máy chủ) nhận được thông báo, sử dụng khóa riêng của riêng mình để giải mã khóa dùng chung và sau đó sử dụng khóa dùng chung để giải mã phần thân của thông báo.
Và sau tất cả các việc đó, đáp ứng trông như thế nào?
### Đáp ứng
Trên thực tế, đáp ứng khá đơn giản, vì Frances đã không thiết lập bất kỳ
OutFlowSecurity nào trên máy chủ, như bạn có thể nhìn thấy
trong Liệt kê 30.
##### Liệt kê 30. Đáp ứng
<?xml version='1.0' encoding='UTF-8'?> <soapenv:Envelope xmlns:soapenv= "http://schemas.xmlsoap.org/soap/envelope/"> <soapenv:Header /> <soapenv:Body> <resp:numberOfArcticles xmlns:resp= "http://daily-moon.com/cms/" xmlns:tns= "http://ws.apache.org/axis2" >42</resp:numberOfArcticles> </soapenv:Body> </soapenv:Envelope>
Đây là một đáp ứng SOAP hoàn toàn hợp lệ, trừ một điều. Bạn có thể nhớ rằng Frances
đã thiết lập ứng dụng khách như mong đợi, ít nhất là, một Dấu thời gian trong
InFlowSecurity riêng của mình. Vì vậy sau tất cả điều đó, yêu
cầu này sẽ vẫn còn thiếu trừ khi cả hai máy chủ và ứng dụng khách đang tạo ra và mong
chờ các phương thức an ninh giống nhau.
## Đưa tất cả lại với nhau
Vào lúc này, Frances và Gene có một vài ví dụ rời rạc, vì vậy họ quyết định đặt tất cả mọi thứ với nhau thành một sự thực hiện duy nhất để hiển thị cho Rudy.
### Đặc tả dịch vụ cuối cùng
Rudy muốn dịch vụ này chỉ chấp nhận các yêu cầu từ các cá nhân (hoặc các thực thể) được ủy quyền và Rudy không muốn các đáp ứng có thể bị các đối thủ cạnh tranh đọc được. Để làm điều đó, Gene và Frances thiết lập những thứ như sau:
- Các ứng dụng khách sẽ thêm một Dấu thời gian, mà nó sẽ cần ký bằng khóa riêng của một người sử dụng đã được phê duyệt. Điều này chú ý đến vấn đề truy cập được ủy quyền và ngăn các thông báo khỏi bị thu chặn và phát lại.
- Máy chủ sẽ thêm một Dấu thời gian, nhưng nó cũng sẽ mã hóa phần thân của đáp ứng để cho những người nghe trộm không thể xem dữ liệu gửi trở lại.
Hãy xem tất cả kết hợp với nhau như thế nào.
### Dịch vụ
Về mặt dịch vụ, Gene thiết lập tệp services.xml như đã thấy trong Liệt kê 31.
##### Liệt kê 31. Tệp services.xml cuối cùng
<service name="CMSService"> <description> This is a sample Web Service for the newspaper's Content Managment System. </description> <parameter name="ServiceClass" locked="false">CMSService</parameter> <parameter name="InflowSecurity"> <action> <items>Timestamp Signature</items> <passwordCallbackClass>PWCallback</passwordCallbackClass> <signaturePropFile>security.properties</signaturePropFile> </action> </parameter> <parameter name="OutflowSecurity"> <action> <items>Timestamp Signature Encrypt</items> <user>gene</user> <passwordCallbackClass>PWCallback</passwordCallbackClass> <signaturePropFile>security.properties</signaturePropFile> <signatureKeyIdentifier >SKIKeyIdentifier</signatureKeyIdentifier> <encryptionKeyIdentifier >SKIKeyIdentifier</encryptionKeyIdentifier> <encryptionUser>frances</encryptionUser> <signatureParts> {Element}{http://schemas.xmlsoap.org/soap/envelope/}Body </signatureParts> <optimizeParts> //xenc:EncryptedData/xenc:CipherValue/xenc:CipherData </optimizeParts> </action> </parameter> <operation name="getNumberOfArticles"> <messageReceiver class= "org.apache.axis2.receivers.RawXMLINOutMessageReceiver"/> </operation> </service>
InflowSecurity là điều mà máy chủ trông đợi -- một thông
báo đã có một Dấu thời gian được thêm vào và sau đó được ký -- và
OutflowSecurity là điều mà nó sẽ gửi lại tới ứng dụng khách -- một thông
báo đã được đánh dấu thời gian và được ký, với các dữ liệu được mã hóa.
### Ứng dụng khách
Về phía ứng dụng khách, Frances thiết lập ngược lại, như bạn có thể thấy trong Liệt kê 32.
##### Liệt kê 32. Tệp axis2.xml cuối cùng
<axisconfig name="AxisJava2.0"> <!-- Engage the security module --> <module ref="rampart"/> <parameter name="OutflowSecurity"> <action> <items>Timestamp Signature</items> <user>gene</user> <passwordCallbackClass>PWCallback</ passwordCallbackClass> <signaturePropFile>security.properties</signaturePropFile> <signatureKeyIdentifier >SKIKeyIdentifier</signatureKeyIdentifier> <signatureParts> {Element}{http://docs.oasis-open.org/wss/2004/01/oasis -200401-wss-wssecurity-utility-1.0.xsd}Timestamp</signatureParts> </action> </parameter> <parameter name="InflowSecurity"> <action> <items>Timestamp Signature Encrypt</items> <user>gene</user> <passwordCallbackClass>PWCallback</passwordCallbackClass> <signaturePropFile>security.properties</signaturePropFile> <signatureKeyIdentifier >SKIKeyIdentifier</signatureKeyIdentifier> <encryptionKeyIdentifier >SKIKeyIdentifier</encryptionKeyIdentifier> <encryptionUser>frances</encryptionUser> <signatureParts> {Element}{http://schemas.xmlsoap.org/soap/envelope/}Body </signatureParts> <optimizeParts> //xenc:EncryptedData/xenc:CipherValue/xenc:CipherData </optimizeParts> </action> </parameter> <!-- ================================================= --> <!-- Parameters --> <!-- ================================================= --> <parameter name="hotdeployment" locked="false">true</parameter> ...
Bây giờ ứng dụng khách sẽ gửi thông báo được đánh dấu thời gian và được ký và nhấn mạnh rằng các đáp ứng bất kỳ phải được đánh dấu thời gian, được ký và được mã hóa.
Chúng ta hãy xem điều đó có nghĩa thế nào đối với các thông báo thực tế.
### Yêu cầu
Liệt kê 33 cho thấy yêu cầu cuối cùng.
##### Liệt kê 33. Yêu cầu cuối cùng
<?xml version='1.0' encoding='UTF-8'?> <soapenv:Envelope xmlns:soapenv= "http://schemas.xmlsoap.org/soap/envelope/"> <soapenv:Header> <wsse:Security xmlns:wsse="http://docs.oasis- open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" soapenv:mustUnderstand="1"> <ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#" Id="Signature-5525185"> <ds:SignedInfo> <ds:CanonicalizationMethod Algorithm= "http://www.w3.org/2001/10/xml-exc-c14n#" /> <ds:SignatureMethod Algorithm= "http://www.w3.org/2000/09/xmldsig#rsa-sha1" /> <ds:Reference URI="#Timestamp-1741620"> <ds:Transforms> <ds:Transform Algorithm= "http://www.w3.org/2001/10/xml-exc-c14n#" /> </ds:Transforms> <ds:DigestMethod Algorithm= "http://www.w3.org/2000/09/xmldsig#sha1" /> <ds:DigestValue> TQSR9wUuJ7rJi582TsbNjiAUqZI= </ds:DigestValue> </ds:Reference> </ds:SignedInfo> <ds:SignatureValue>aRI5mvvvXZusAB/5cKCx/fOcW+CDjdk1F3Icl lObVcEOWws9/mV4X2kWEX3hhwK7koX5jMPpl7AtLSbEh8UQGCa8yBua++yveprFl020To VtePVOcWsBLM+9VHu9bJbhvaaps43RiUkym6xvVU/yL3eKTbhdhB/RQDI3kylXdas= </ds:SignatureValue> <ds:KeyInfo Id="KeyId-26644003"> <wsse:SecurityTokenReference xmlns:wsu= "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity- utility-1.0.xsd" wsu:Id="STRId-26174005"> <wsse:KeyIdentifier EncodingType="http://docs.oasi s-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Bas e64Binary" ValueType="http://docs.oasis-open.org/wss/2004/01/oasis- 200401-wss-x509-token-profile-1.0#X509SubjectKeyIdentifier" >CuJdE1B2dUFd1dkLZSzQ5vj6MYg=</wsse:KeyIdentifier> </wsse:SecurityTokenReference> </ds:KeyInfo> </ds:Signature> <wsu:Timestamp xmlns:wsu="http://docs.oasis-open.org/wss/20 04/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="Timestamp-1741620"> <wsu:Created>2006-06-22T11:34:02.453Z</wsu:Created> <wsu:Expires>2006-06-22T11:39:02.453Z</wsu:Expires> </wsu:Timestamp> </wsse:Security> </soapenv:Header> <soapenv:Body> <cms:getNumberOfArticles xmlns:cms="http://daily-moon.com/cms"> <cms:category>classifieds</cms:category> </cms:getNumberOfArticles> </soapenv:Body> </soapenv:Envelope>
### Đáp ứng
Liệt kê 34 cho thấy đáp ứng cuối cùng.
##### Liệt kê 34. Đáp ứng cuối cùng
<?xml version='1.0' encoding='UTF-8'?> <soapenv:Envelope xmlns:soapenv= "http://schemas.xmlsoap.org/soap/envelope/" xmlns:xenc="http://www.w3.org/2001/04/xmlenc#"> <soapenv:Header> <wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004 /01/oasis-200401-wss-wssecurity-secext-1.0.xsd" soapenv:mustUnderstand="1"> <xenc:EncryptedKey Id="EncKeyId-28585008"> <xenc:EncryptionMethod Algorithm= "http://www.w3.org/2001/04/xmlenc#rsa-1_5" /> <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#"> <wsse:SecurityTokenReference> <wsse:KeyIdentifier EncodingType="http://docs.oasis- open.org/wss/2004/01/oasis-200401-wss-soap-message-security- 1.0#Base64Binary" ValueType="http://docs.oasis-open.org/wss/2 004/01/oasis-200401-wss-x509-token-profile-1.0#X509SubjectKey Identifier">Xeg55vRyK3ZhAEhEf+YT0z986L0=</wsse:KeyIdentifier> </wsse:SecurityTokenReference> </ds:KeyInfo> <xenc:CipherData> <xenc:CipherValue>NSkylkASezzHSp37izSN3xnxf6v/zwN3C70uU2n UTNk4a9xYxhNcgiVQuS2/Tm3/x3Jm1d9rj2V8x1uqlKmi89MFifN34SDxaDTMBFzhfRv4 CmQSITEFjY1ySVDvMb7WZszGDhVIGYkjcDkoK+SfWdxyuaUdNUbPgEihSnFVRXs=</xen c:CipherValue> </xenc:CipherData> <xenc:ReferenceList> <xenc:DataReference URI="#EncDataId-19400027" /> </xenc:ReferenceList> </xenc:EncryptedKey> <ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#" Id="Signature-17174249"> <ds:SignedInfo> <ds:CanonicalizationMethod Algorithm= "http://www.w3.org/2001/10/xml-exc-c14n#" /> <ds:SignatureMethod Algorithm= "http://www.w3.org/2000/09/xmldsig#rsa-sha1" /> <ds:Reference URI="#id-19400027"> <ds:Transforms> <ds:Transform Algorithm= "http://www.w3.org/2001/10/xml-exc-c14n#" /> </ds:Transforms> <ds:DigestMethod Algorithm= "http://www.w3.org/2000/09/xmldsig#sha1" /> <ds:DigestValue>HfdufYEGpvPpfz2+HWKui4npV9s=</ds:Di gestValue> </ds:Reference> <ds:Reference URI="#SigConf-17122634"> <ds:Transforms> <ds:Transform Algorithm= "http://www.w3.org/2001/10/xml-exc-c14n#" /> </ds:Transforms> <ds:DigestMethod Algorithm= "http://www.w3.org/2000/09/xmldsig#sha1" /> <ds:DigestValue>e88WWqudpvW69wN23fgZjQ9ZAio=</ds:Di gestValue> </ds:Reference> </ds:SignedInfo> <ds:SignatureValue>aZLon//vwkw2G2Jxcligxod/CgxMjwtlefZiho yUz5FpgSY6RUoI5vuHX2unrWV+EVA2vWdtz/Iyq+RS7j4QtE2XTYovxdyiZPbKXNdFKHy AkpDr0aDLG9rSjyFVcTrUKgAY06t10zi13Daq95nDMH+wAJCYUO0Vor/u0V9Iv7I=</ds :SignatureValue> <ds:KeyInfo Id="KeyId-22768665"> <wsse:SecurityTokenReference xmlns:wsu="http://docs.oa sis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="STRId-18220809"> <wsse:KeyIdentifier EncodingType="http://docs.oasis- open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Bas e64Binary" ValueType="http://docs.oasis-open.org/wss/2004/01/oasis- 200401-wss-x509-token-profile-1.0#X509SubjectKeyIdentifier" >CuJdE1B2dUFd1dkLZSzQ5vj6MYg=</wsse:KeyIdentifier> </wsse:SecurityTokenReference> </ds:KeyInfo> </ds:Signature> <wsu:Timestamp xmlns:wsu="http://docs.oasis-open.org/wss/20 04/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="Timestamp-6400133"> <wsu:Created>2006-06-22T11:34:04.062Z</wsu:Created> <wsu:Expires>2006-06-22T11:39:04.062Z</wsu:Expires> </wsu:Timestamp> <wsse11:SignatureConfirmation xmlns:wsse11="http://docs.oasi s-open.org/wss/2005/xx/oasis-2005xx-wss-wssecurity-secext-1.1.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss- wssecurity-utility-1.0.xsd" Value="aRI5mvvvXZusAB/5cKCx/fOcW+CDjdk1F3 IcllObVcEOWws9/mV4X2kWEX3hhwK7koX5jMPpl7AtLSbEh8UQGCa8yBua++yveprFl02 0ToVtePVOcWsBLM+9VHu9bJbhvaaps43RiUkym6xvVU/yL3eKTbhdhB/RQDI3kylXda s=" wsu:Id="SigConf-17122634" /> </wsse:Security> </soapenv:Header> <soapenv:Body xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/o asis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="id-19400027"> <xenc:EncryptedData Id="EncDataId-19400027" Type= "http://www.w3.org/2001/04/xmlenc#Content"> <xenc:EncryptionMethod Algorithm= "http://www.w3.org/2001/04/xmlenc#aes128-cbc" /> <xenc:CipherData> <xenc:CipherValue>f6uWHGsYmGwHuno2j4H7a4qCMhPLTlCIg40p KLciESBzeCT8rvyl+qHXsFkZJq2m4uj9TEFtRX6efQ5MHBEJozMgI03LSVanh6MmHgt5o ilIJClWcQifEx0Azeo3KWnQKSc9lg0ywhKJH+JVBsPSP7E19jZAsR77wUEBBIprxs5W59 7C/mJh38iXSncwWccE7OCckf1x34FCfKHSqn46MCohZWiPZRjSmAI5dGFMKwttzpmsmXr LHLVrsjm4w9onis+Xr5gbi3Gcx6P0F2ZJGLBb9bkGh/IvjYutgzRD7zhyRZxUmM/oZTVs JJ7dA9YOED5l1C64f4yuqR6TtuVw3gIiuspxWafKwlJuuD0/9m6Ri4AvQuOVEioz45MM 5FBCQU+0LFceSlEFFKhN9yLUI9hgLsCYRzc8eedPAhZDjJEDHec5M9LZ0C07sKu7Cvnr jiino53xZmk5uQHs4JlNoA==</xenc:CipherValue> </xenc:CipherData> </xenc:EncryptedData> </soapenv:Body> </soapenv:Envelope>
## Tóm tắt
Để cho các dịch vụ Web thực sự có ích trong môi trường doanh nghiệp, nó cần có các khả năng an ninh thích hợp. Bằng cách kết hợp với các công nghệ như Chữ ký XML và Mã hóa XML và cung cấp một cách tiêu chuẩn để biểu thị thông tin đó, Các dịch vụ Web-An ninh làm cho nó có khả năng bảo vệ cả hai thông báo SOAP đến và ra khỏi một số các mối đe dọa an ninh khác.
Bằng cách yêu cầu các chữ ký số, bạn có thể hạn chế việc truy cập đến các cá nhân hay các tổ chức có ủy quyền, cũng như kiểm tra các thông tin đó không bị thay đổi trong quá trình chuyển tiếp. Bằng cách kèm thêm cả mã hóa, bạn có thể ngăn dữ liệu khỏi bị những người nhận không dự tính trước đọc (hoặc ít nhất là hiểu). Và bằng cách thêm một Dấu thời gian (và ký nó), bạn có thể ngăn các thông báo khỏi bị bắt giữ và phát lại.
Trong hướng dẫn này, các nhân viên ở tờ báo Daily Moon đã bảo vệ các dịch vụ Web mà họ đã tạo ra trong phần trước của loạt bài này. Tiếp theo, trong phần 5, họ sẽ xem xét áp dụng các chính sách an ninh cho dịch vụ đó.
## Tải về
|Mô tả||Tên||Kích thước|
|Source code|
## Tài nguyên
### Học tập
- Đọc
[Đặc tả Các dịch vụ Web-An ninh](http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0.pdf).
- Đọc
[Hiện trạng thẻ tên người dùng](http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0.pdf)(PDF).
- Đọc về
[Hiện trạng thẻ X.509](http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0.pdf)(PDF).
- Đọc
[Đặc tả chữ ký XML](http://www.w3.org/Signature/).
- Đọc đặc tả Mã hóa XML tại
[http://www.w3.org/Encryption/2001/](http://www.w3.org/Encryption/2001/).
- Để có một nền tảng tốt về XML, hãy đọc
[Giới thiệu về hướng dẫn XML](http://www.ibm.com/developerworks/vn/edu/xmlintro/index.html)(developerWorks, 08.2002).
- Để có một hiểu biết tốt hơn về xử lý XML như một đối
tượng, hãy đọc
[Hiểu biết DOM](http://www.ibm.com/developerworks/edu/x-dw-xudom-i.html?S_TACT=105AGY75)(developerWorks, 07.2003).
- Bạn có thể tìm nhiều thông tin về
[SOA và vùng các dịch vụ Web của developerWorks](http://www.ibm.com/developerworks/webservices?S_TACT=105AGY75).
- Xem một ví dụ về Axis2 đang hoạt động bằng cách đọc
[Tạo tài khoản trực tuyến với loạt bài hướng dẫn Apache Geronimo và Axis2](https://www6.software.ibm.com/developerworks/education/ws-understand-web-services1/resources.html).
- Để tìm hiểu thêm về lập trình trong Java, hãy xem
[Vùng XML của developerWorks](http://www.ibm.com/developerworks/java?S_TACT=105AGY75).
- Tìm hiểu tất cả về XML tại
[Vùng XML của developerWorks](http://www.ibm.com/developerworks/xml?S_TACT=105AGY75).
### Lấy sản phẩm và công nghệ
- Tải
[Apache Geronimo](http://geronimo.apache.org/downloads.html). Để biết thêm thông tin về cài đặt Geronimo, hãy xem [Phần 1](http://www.ibm.com/developerworks/vn/edu/ws-understand-web-services1/index.html)của loạt bài này.
- Tải
[phiên bản 1.0 của Apache Axis2](http://ws.apache.org/axis2/download.cgi)hoặc cao hơn.
- Tải
[mô đun Rampart của Apache Axis2](http://www.apache.org/dyn/mirrors/mirrors.cgi/ws/axis2/modules/rampart/1_0/rampart-1.0.mar).
- Tải
[Apache WSS4J](http://www.apache.org/dyn/closer.cgi/ws/wss4j/).
- Tải
[phiên bản 1.4.2 hoặc cao hơn của Ấn bản tiêu chuẩn của Java 2](http://java.sun.com/j2se/1.5.0/download.jsp).
- Tải
[TCPMon](http://ws.apache.org/commons/tcpmon).
- Tải
[GnuPG](http://www.gnupg.org/(en)/download/index.html).
## Bình luận
[Vùng dữ liệu trên developerWorks](http://www.ibm.com/developerworks/vn/views/data/libraryview.jsp)
Khám phá các bài viết xoay quanh lĩnh vực dữ liệu, Quản lý hệ thống thông tin
[Vùng mã nguồn mở trên developerWorks](http://www.ibm.com/developerworks/vn/views/opensource/libraryview.jsp)
Xem các bài viết về HTML, CSS, JavaScript,...
[Điện toán đám mây](http://www.ibm.com/developerworks/vn/views/cloud/libraryview.jsp)
Tìm hiểu về điện toán đám mây

Content-Encoding: gzip

Content-Language: en-US