Các dịch vụ Web Java: Tìm hiểu về WS-Policy

Tìm hiểu các chi tiết về WS-Policy và xem những phần nào làm việc với ba ngăn xếp các dịch vụ web Java nguồn mở

WS-Policy (Chính sách các Dịch vụ Web) cung cấp một cấu trúc chung để cấu hình các tính năng và các tùy chọn áp dụng cho một dịch vụ web. Bạn đã thấy nó được sử dụng cho các cấu hình WS-Security (Bảo mật các Dịch vụ Web) trong loạt bài này và có lẽ ở nơi khác với các công nghệ mở rộng khác như WS-ReliableMessaging (Tạo thông báo tin cậy các Dịch vụ Web). Trong bài này, bạn sẽ tìm hiểu về cấu trúc của các tài liệu WS-Policy và các cách mà bạn có thể đính kèm các chính sách vào các dịch vụ trong WSDL (Web Service Description Language - Ngôn ngữ mô tả dịch vụ Web), với các ví dụ về cấu hình-bảo mật đã thực hiện trên Apache Axis2, Metro và Apache CXF.

Dennis Sosnoski, Nhà tư vấn, Sosnoski Software Solutions, Inc.

Dennis Sosnoski là một nhà tư vấn và nhà trợ giúp đào tạo chuyên về các dịch vụ Web và SOA dựa trên-Java. Kinh nghiệm phát triển phần mềm chuyên nghiệp của ông trải suốt hơn 30 năm qua, với một thập kỉ cuối tập trung vào các công nghệ XML và Java phía máy chủ. Dennis là nhà phát triển hàng đầu về dụng cụ liên kết dữ liệu XML JiBX mã nguồn mở, cũng là một người có duyên nợ với khung công tác của các dịch vụ Web Apache Axis2. Ông cũng là một trong những thành viên của nhóm chuyên gia đặc tả kỹ thuật của Jax-WS 2.0 và JAXB 2.0. Xem trang web của ông để có thông tin về các dịch vụ đào tạo và tư vấn của ông.



29 06 2012

Giới thiệu về loạt bài này

Các dịch vụ Web là một phần quan trọng về vai trò của công nghệ Java™ trong điện toán doanh nghiệp. Trong loạt bài này, nhà tư vấn các dịch vụ web và XML Dennis Sosnoski trình bày các khung công tác và các công nghệ chính rất quan trọng cho các nhà phát triển Java đang sử dụng các dịch vụ web. Hãy theo dõi loạt bài này để cập nhật những phát triển mới nhất trong lĩnh vực này và hiểu rõ cách bạn có thể sử dụng chúng để hỗ trợ cho các dự án lập trình của mình.

Bạn đã thấy nhiều ví dụ về WS-Policy và WS SecurityPolicy (Chính sách bảo mật các Dịch vụ Web) trong loạt bài Các dịch vụ web Java, nhưng cho đến nay không có bất kỳ cuộc thảo luận nào về cách WS-Policy thực sự hoạt động ra sao (hoặc ít nhất được dự kiến hoạt động). Trong bài này, trước hết tôi sẽ lấp đầy các khoảng trống đó bằng cách cung cấp cho bạn một nền tảng nhỏ hơn về WS-Policy. Sau đó, bạn sẽ thấy cách đính kèm các chính sách vào các dịch vụ trong các tài liệu WSDL. Cuối cùng, tôi sẽ thực hiện một số ví dụ về cấu hình WS-Policy cho Axis2, Metro và CXF và cho bạn biết chúng sẽ làm việc trong thực tế như thế nào. (Xem Tải về để nhận được đủ các mẫu mã).

Cơ bản về WS-Policy

WS-Policy định nghĩa một cấu trúc XML đơn giản có bốn phần tử khác nhau và một cặp các thuộc tính. Những phần tử và các thuộc tính này, như WS-Policy đã giải thích, cung cấp một cách để tổ chức và kết hợp các xác nhận chính sách trong bất kỳ mức độ phức tạp nào. Để định nghĩa các xác nhận thực tế tạo nên một chính sách, bạn sử dụng các phần mở rộng tên miền cụ thể ví dụ như WS-SecurityPolicy, chứ không thực chất là WS-Policy.

Các phiên bản WS-Policy

Các chi tiết về WS-Policy trong bài này đặc trưng cho phiên bản 1.5 "chính thức" của WS-Policy do W3C xuất bản, nhưng các quy tắc chung giống nhau áp dụng cho các phiên bản "trình lên" cũ vẫn còn đang được sử dụng rộng rãi. Như với các công nghệ các Dịch vụ Web (WS-*) khác, bạn có thể cho biết một tài liệu đang sử dụng phiên bản nào bằng cách kiểm tra vùng tên XML. Vùng tên cho WS-Policy 1.5 l http://www.w3.org/ns/ws-policy; vùng tên cho các phiên bản trình lên là http://schemas.xmlsoap.org/ws/2004/09/policy. Trong suốt bài này, tôi sử dụng vùng tên http://www.w3.org/ns/ws-policy, được biểu diễn bằng tiền tố wsp.

Để thuận tiện, WS-Policy định nghĩa cả một biểu thức dạng chuẩn của một chính sách và một bộ các quy tắc mà bạn có thể sử dụng để tạo ra các biểu thức chính sách rút gọn hơn. Dạng chuẩn có thể hơi dài dòng, vì vậy (mặc dù các khuyến cáo WS-Policy nói rằng "dạng chuẩn của một biểu thức chính sách NÊN được sử dụng khi thực hành") hầu hết các tác giả của các tài liệu chính sách đều có xu hướng sử dụng ít nhất một số phần của các quy tắc biểu thức rút gọn để làm cho các tài liệu thân thiện hơn với mọi người. Mặc dù cách giải thích các tài liệu chính sách đều dựa trên dạng chuẩn, vì vậy đây là điều tôi sẽ trình bày trước tiên.

Biểu thức dạng chuẩn

Biểu thức chính sách dạng chuẩn sử dụng tối đa ba phần tử, luôn phải được lồng nhau theo một thứ tự cụ thể. Phần tử ngoài cùng luôn là <wsp:Policy> và nó phải có một phần tử con duy nhất là <wsp:ExactlyOne>. Phần tử <wsp:ExactlyOne> lồng nhau lần lượt chứa bất kỳ số lượng (có thể là không) các phần tử con <wsp:All> nào. Vì vậy, biểu thức chính sách dạng chuẩn đơn giản có thể là <wsp:Policy><wsp:ExactlyOne/></wsp:Policy>.

Bất kỳ các xác nhận chính sách nào dưới dạng chuẩn phải được lồng trong một phần tử <wsp:All>. Chính các xác nhận chính sách này có thể chứa các biểu thức chính sách. Bạn đã thấy điều này trong các bài trước của loạt bài này, ở đó phần lớn các xác nhận WS-SecurityPolicy đều có chứa các biểu thức chính sách lồng nhau. Trong một biểu thức chính sách dạng chuẩn, bản thân tất cả các xác nhận chính sách lồng nhau này phải ở dạng chuẩn. (Trên thực tế, chúng phải ở trong một tập con hạn chế hơn của dạng chuẩn, nơi mà mỗi phần tử <wsp:ExactlyOne> có một và chỉ một phần tử con <wsp:All> ngoại trừ một phần tử trên cùng). Liệt kê 1 cho thấy một đoạn trích với một vài ví dụ về các biểu thức chính sách lồng nhau, được biểu diễn dưới dạng chuẩn:

Liệt kê 1. Đoạn trích WS-SecurityPolicy với các biểu thức chính sách lồng nhau
<wsp:Policy>
  <wsp:ExactlyOne>
    <wsp:All>
      <sp:AsymmetricBinding
          xmlns:sp="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702">
        <wsp:Policy>
          <wsp:ExactlyOne>
            <wsp:All>
              <sp:InitiatorToken>
                <wsp:Policy>
                  <wsp:ExactlyOne>
                    <wsp:All>
                      <sp:X509Token
                          sp:IncludeToken=".../IncludeToken/AlwaysToRecipient">
                        <wsp:Policy>
                          <wsp:ExactlyOne>
                            <wsp:All>
                              <sp:RequireThumbprintReference/>
                            </wsp:All>
                          </wsp:ExactlyOne>
                        </wsp:Policy>
                      </sp:X509Token>
                    </wsp:All>
                  </wsp:ExactlyOne>
                </wsp:Policy>
              </sp:InitiatorToken>
              ...

Mặc dù có nhiều tầng các phần tử lồng nhau, nhưng các ngữ nghĩa học của cấu trúc này đơn giản. Trong biểu thức dạng chuẩn của một chính sách, phần tử <wsp:Policy> chỉ là một trình bao (wrapper) cho biểu thức chính sách và trong trường hợp của các biểu thức chính sách mức cao nhất, một nơi để đính kèm một tên hay mã định danh cho chính sách. Phần tử <wsp:ExactlyOne> lồng nhau biểu diễn một tổ hợp or (hoặc) của các lựa chọn thay thế được các phần tử <wsp:All> lồng nhau biểu diễn (do đó, toàn bộ biểu thức chính sách được thỏa mãn nếu có bất kỳ một trong các lựa chọn thay thế lồng nhau nào được thỏa mãn). Mỗi phần tử <wsp:All> biểu diễn một tổ hợp and (và) của các xác nhận chính sách lồng nhau (sao cho việc lựa chọn thay thế đó được thỏa mãn chỉ khi tất cả các xác nhận được thỏa mãn).

Chính sách không chuẩn hóa

Biểu thức chính sách không cần ở dạng chuẩn. Các biểu thức chính sách không chuẩn có thể bao gồm các lựa chọn thay thế lồng nhau (nhiều phần tử con <wsp:All> của một phần tử <wsp:ExactlyOne> dưới mức cao nhất) và cũng có thể sử dụng các tùy chọn biểu thức chính sách rút gọn được thảo luận trong phần tiếp theo.

Nếu bạn đã nghiên cứu lý thuyết logic, bạn có thể nhận ra biểu diễn dạng chuẩn (không có các lựa chọn thay thế lồng nhau nào) là tương đương với dạng chuẩn phân biệt của một biểu thức logic. Thực sự các biểu thức chính sách đúng là biểu thức logic khi sử dụng một định dạng dấu móc nhọn, với các xác nhận làm các mệnh đề. Lý thuyết logic cho thấy bất kỳ biểu thức logic nào cũng có thể được chuyển đổi sang dạng chuẩn phân biệt và nguyên lý giống nhau áp dụng cho các biểu thức chính sách được viết với các lựa chọn thay thế lồng nhau — chúng có thể được mở rộng thành một biểu diễn dạng chuẩn với các lựa chọn thay thế chỉ ở mức cao nhất. Ưu điểm chính của biểu thức chính sách dạng chuẩn là nó làm cho dễ dàng kiểm tra tính tương thích cho cả hai chính sách bằng lập trình — nếu hai chính sách dạng chuẩn là tương thích, chúng sẽ có một hoặc nhiều hơn một phần tử <wsp:All> mức cao nhất có chứa các bộ các xác nhận như nhau.

Biểu thức chính sách rút gọn

Biểu thức dạng chuẩn của một chính sách có thể dài dòng, đặc biệt là khi nó liên quan đến các lựa chọn thay thế lồng nhau. WS-Policy định nghĩa các tùy chọn mà bạn có thể sử dụng để tạo ra các biểu thức chính sách rút gọn hơn so với các giấy phép dạng chuẩn, làm cho các chính sách dễ hiểu hơn với mọi người. Đôi khi tài liệu WS-Policy cũng khó hiểu khi đề cập đến các chính sách đang sử dụng các tùy chọn này dưới dạng rút gọn. Thực sự, nhiều biểu thức rút gọn của một chính sách có thể là tương đương với một biểu thức dạng chuẩn duy nhất. Trong bài này, tôi sẽ chỉ sử dụng biểu thức rút gọn để nói đến các chính sách khi sử dụng một hoặc nhiều tùy chọn này.

Một tính năng trong các tùy chọn của biểu thức-rút gọn là khả năng thể hiện các chính sách thông qua việc lồng các phần tử chính sách cơ bản (được gọi là các toán tử theo thuật ngữ chính sách, vì mỗi phần tử ngụ ý một cách giải thích cụ thể về các xác nhận lồng nhau) theo bất kỳ thứ tự nào. Các quy tắc lồng nhau cũng định nghĩa một cách giải thích về phần tử <wsp:Policy> được sử dụng trực tiếp (không đòi hỏi một phần tử con <wsp:ExactlyOne> riêng theo dạng chuẩn) là tương đương với <wsp:All>, có lẽ là tính năng biểu thức-rút gọn được sử dụng rộng rãi nhất.

Liệt kê 2 cho thấy một biểu thức rút gọn của một chính sách giống như được hiển thị trong Liệt kê 1, khi sử dụng biểu diễn <wsp:Policy> này. Phiên bản này có độ dài ngắn hơn một nửa so với phiên bản đầu tiên và thường dễ hiểu hơn nhiều với hầu hết mọi người.

Liệt kê 2. Chính sách đơn giản theo dạng rút gọn
<wsp:Policy>
  <sp:AsymmetricBinding
      xmlns:sp="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702">
    <wsp:Policy>
      <sp:InitiatorToken>
        <wsp:Policy>
          <sp:X509Token
              sp:IncludeToken=".../IncludeToken/AlwaysToRecipient">
            <wsp:Policy>
              <sp:RequireThumbprintReference/>
            </wsp:Policy>
          </sp:X509Token>

        </wsp:Policy>
      </sp:InitiatorToken>
      ...

WS-Policy định nghĩa một bộ các phép chuyển đổi mà bạn có thể áp dụng để chuyển đổi các biểu thức chính sách đang sử dụng các tùy chọn rút gọn sang dạng chuẩn, vì vậy có rất ít lý do để sử dụng trực tiếp dạng chuẩn. Để chuyển đổi các biểu thức rút gọn thành dạng chuẩn trên các máy tính dễ hơn nhiều so với để giải thích dạng chuẩn cho mọi người.

Phép lồng chính sách

Bên cạnh việc đơn giản hóa việc lồng phần tử, biểu thức rút gọn cũng cung cấp một cách để tham khảo và sử dụng lại các biểu thức chính sách. Bạn làm điều này với phần tử WS-Policy thứ tư, <wsp:PolicyReference>. Một phần tử <wsp:PolicyReference> có thể xuất hiện bất cứ ở đâu mà một xác nhận chính sách có thể xuất hiện. Biểu thức chính sách tham khảo được thay thế có hiệu quả cho tài liệu tham khảo chính sách (về mặt kỹ thuật thay thế phần tử <wsp:All> tham khảo bằng một phần tử <wsp:Policy>. Cách tiếp cận thay thế này được gọi là phép lồng chính sách.

Liệt kê 3 minh họa việc sử dụng phép lồng chính sách, cho thấy biểu thức chính sách của Liệt kê 2 được cấu trúc lại theo một dạng mẫu bằng cách sử dụng một biểu thức chính sách và một tài liệu tham khảo riêng:

Liệt kê 3. Tài liệu tham khảo chính sách
<!-- Client X.509 token policy assertion. -->
<wsp:Policy wsu:Id="ClientX509"
    xmlns:wsu="http://.../oasis-200401-wss-wssecurity-utility-1.0.xsd">
  <sp:InitiatorToken>
    <wsp:Policy>
      <sp:X509Token
          sp:IncludeToken=".../IncludeToken/AlwaysToRecipient">
        <wsp:Policy>
          <sp:RequireThumbprintReference/>
        </wsp:Policy>
      </sp:X509Token>
    </wsp:Policy>
  </sp:InitiatorToken>
</wsp:Policy>

<wsp:Policy>
  <sp:AsymmetricBinding
      xmlns:sp="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702">
    <wsp:Policy>
      <wsp:PolicyReference URI="#ClientX509"/>
      ...

Có thể sử dụng các tài liệu tham khảo chính sách cho cả các biểu thức chính sách cục bộ, như trong Liệt kê 3, và các biểu thức chính sách bên ngoài. Đối với các biểu thức chính sách bên ngoài, thuộc tính URI của tài liệu tham khảo thường cung cấp URL thực tế của chính sách ngoài.

Như bạn sẽ thấy trong các ví dụ kiểm tra chính sách được cung cấp sau trong bài này, phép lồng chính sách hiện không được hỗ trợ phổ biến. Điều này hạn chế tiện ích của tính năng tốt đẹp khác này.

Các lựa chọn thay thế chính sách

Như bạn đã thấy ở trên, cấu trúc của WS-Policy hỗ trợ các lựa chọn giữa các lựa chọn thay thế như là một phần của một chính sách, thông qua phần tử <wsp:ExactlyOne>. Với biểu thức rút gọn, bạn cũng có thể (ít nhất theo lý thuyết) sử dụng các thuộc tính đặc biệt để tạo ra các lựa chọn. Theo khuyến cáo của WS-Policy, bạn có thể thêm thuộc tính wsp:Optional="true" vào bất kỳ xác nhận chính sách nào để làm cho xác nhận đó trở thành một tùy chọn chứ không phải là một yêu cầu, ngay cả khi xác nhận này là một phần tử con của phần tử <wsp:All> hoặc phần tử <wsp:Policy>.

Các lựa chọn chính sách có vẻ giống như một tính năng có ích có tiềm năng, nhưng thật khó để phát hiện ra một ví dụ làm việc quan trọng. Các trường hợp mà tính năng này được sử dụng trong thực tế thường dùng để tạo một thành phần đặc biệt về việc xử lý bảo mật, ví dụ như một UsernameToken tùy ý. Các lựa chọn thay thế phức tạp hơn, chẳng hạn như cho phép một máy khách cung cấp nhận dạng dưới dạng hoặc một UsernameToken hoặc một chứng nhận X.509, xem ra nằm ngoài khả năng của các công cụ WS-SecurityPolicy hiện tại.


Đính kèm chính sách

Trong WSDL 1.1 (hơi cũ một chút, nhưng vẫn còn là dạng mẫu định nghĩa dịch vụ được sử dụng rộng rãi nhất), các định nghĩa dịch vụ sử dụng một cấu trúc phân cấp. Tầng (dưới cùng) đầu tiên có chứa các phần tử <wsdl:message> định nghĩa cấu trúc XML của các thông báo đến và đi khỏi dịch vụ đó. Tầng thứ hai là các phần tử <wsdl:portType> định nghĩa các bộ các hoạt động, đầu vào, đầu ra hoặc các thông báo lỗi được quy định với mỗi hoạt động. Tầng thứ ba là các phần tử <wsdl:binding>, liên kết một giao thức thông báo cụ thể (chẳng hạn như SOAP) và phương thức truy cập với một <wsdl:portType>. Tầng thứ tư là các định nghĩa của các thiết bị đầu cuối-dịch vụ dưới dạng các phần tử <wsdl:port>, xác định địa chỉ mà ở đó có thể truy cập một phần tử <wsdl:binding>.

Các lược đồ WSDL

WSDL 1.1 đã có một lịch sử lâu dài và biến động khi nó thừa hưởng các định nghĩa lược đồ XML. Bản trình lên WSDL 1.1 ban đầu đã có cả mô tả văn bản về cách tài liệu XML WSDL đã được cấu trúc lẫn một định nghĩa lược đồ XML. Thật không may, lược đồ XML được cung cấp không phù hợp với văn bản. Người ta đã sửa chữa điều này trong một phiên bản sửa đổi lược đồ sau đó một chút, nhưng tài liệu WSDL 1.1 đã không được cập nhật để phản ánh sự thay đổi này. Sau đó, nhóm WS-I Basic Profile (Lược tả cơ bản WS-I) đã quyết định thực hiện thêm các thay đổi cho lược đồ WSDL, vì vậy nhóm đó đã tạo ra những gì dường như là phiên bản các hướng dẫn thực hành tốt nhất của lược đồ khó nắm giữ này. Các tài liệu được viết cho một phiên bản của lược đồ nói chung không tương thích với các phiên bản khác (mặc dù sử dụng vùng tên chính xác như nhau), nhưng may mắn thay, hầu hết các công cụ của các dịch vụ web về cơ bản bỏ qua lược đồ và chấp nhận bất cứ thứ gì tỏ ra hợp lý. Xem Tài nguyên để biết các liên kết đến nhiều lược đồ của WSDL.

WS-Policy cho phép bạn đính kèm các chính sách vào các định nghĩa dịch vụ WSDL ở một số điểm khác nhau không khớp chính xác với các tầng định nghĩa này. Trong khi các tầng biểu diễn một cơ cấu logic cho các định nghĩa dịch vụ, thì WS-Policy được quan tâm nhiều hơn với các thông báo và các nhóm thông báo. Bốn mức các nhóm thông báo mà WS-Policy sử dụng là:

  • Thông báo: Chính sách áp dụng cho một thông báo cụ thể (bất cứ ở đâu sử dụng thông báo đó nếu chính sách được đính kèm thông qua phần tử <wsdl:message> hoặc khi một hoạt động cụ thể sử dụng thông báo đó nếu được đính kèm thông qua các định nghĩa đầu vào/đầu ra/lỗi của hoạt động đó hoặc trong phần tử <wsdl:portType> hoặc trong phần tử <wsdl:binding>).
  • Hoạt động: Chính sách áp dụng cho tất cả các trao đổi thông báo cho một hoạt động cụ thể (chính sách được đính kèm thông qua phần tử <wsdl:operation>, trong hoặc phần tử <wsdl:binding> hoặc phần tử <wsdl:portType>).
  • Thiết bị đầu cuối: Chính sách áp dụng cho tất cả các trao đổi thông báo cho một liên kết dịch vụ cụ thể (chính sách được đính kèm thông qua phần tử <wsdl:port> hoặc phần tử <wsdl:binding>) hoặc cho tất cả các liên kết dịch vụ dựa trên một kiểu cổng đặc biệt (chính sách được đính kèm với phần tử <wsdl:portType> đó).
  • Dịch vụ: Chính sách áp dụng cho tất cả các thiết bị đầu cuối và tất cả các hoạt động gắn liền với một dịch vụ (chính sách được đính kèm với phần tử <wsdl:service>).

Cơ cấu đính kèm chính sách chính được sử dụng cho WSDL tương tự như cơ cấu được sử dụng để tham khảo một chính sách trong chính sách khác — phần tử <wsp:PolicyReference> đã thảo luận trong phần Phép lồng chính sách. Phần tử WS-Policy này có thể được thêm vào như là một phần tử con của bất kỳ các phần tử WSDL nào được liệt kê trước đó để xác định chính sách được áp dụng ở mức các nhóm thông báo đó. Bạn cũng có thể nhúng một chính sách trực tiếp như là một phần tử <wsp:Policy> với bất kỳ nội dung thích hợp nào, nhưng để sử dụng các tài liệu tham khảo thường tốt hơn sao cho cấu trúc WSDL vẫn sạch.

Chính sách được áp dụng ở một mức các nhóm thông báo được các tầng thấp hơn thừa kế, được kết hợp trong một phần tử <wsp:All>. Điều này làm cho chính sách thực tế (hoặc hiệu quả, theo thuật ngữ WS-Policy) được áp dụng cho mỗi thông báo có sự kết hợp của tất cả các chính sách được áp dụng ở các tầng thông báo, hoạt động, thiết bị đầu cuối và dịch vụ. Vì vậy, chính sách được xác định không chỉ bởi chính thông báo đó mà còn bởi ngữ cảnh sử dụng thông báo.

Liệt kê 4 minh họa cách chính sách này hoạt động, cho thấy một định nghĩa WSDL khung với các tham khảo chính sách:

Liệt kê 4. Ví dụ đính kèm chính sách
<wsdl:binding name="LibrarySoapBinding" type="wns:Library">

  <wsp:PolicyReference xmlns:wsp="http://www.w3.org/ns/ws-policy" URI="#UsernameToken"/>

  <wsdlsoap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
  
  <wsdl:operation name="addBook">
  
    <wsp:PolicyReference xmlns:wsp="http://www.w3.org/ns/ws-policy" URI="#AsymmEncr"/>


    ...

  </wsdl:operation>

</wsdl:binding>

Trong trường hợp này, một chính sách đòi hỏi một UsernameToken được đính kèm ở mức <wsdl:binding> và một chính sách bổ sung đòi hỏi mã hóa thông báo không đối xứng được đính kèm với hoạt động addBook được định nghĩa như là một phần liên kết đó. Khi cho rằng ví dụ này hiển thị bộ các tài liệu tham khảo chính sách đầy đủ cho WSDL, UsernameToken luôn cần thiết, nhưng chỉ sử dụng để ký thông báo cho hoạt động addBook.

Như là một cách sử dụng phần tử con <wsp:PolicyReference> khác để tham khảo trực tiếp các chính sách từ các phần tử WSDL, bạn có thể sử dụng thuộc tính wsp:PolicyURIs. Bạn có thể thêm thuộc tính này vào bất kỳ phần tử WSDL nào mà một chính sách có thể được đính kèm với nó. Về cơ bản nó hoạt động theo cách giống như khi sử dụng các phần tử con <wsp:PolicyReference>.

Đính kèm WS-SecurityPolicy

WS-SecurityPolicy quy định các mức nhóm-thông báo mà ở các mức đó người ta có thể đính kèm các kiểu xác nhận chính sách khác nhau vào một mô tả dịch vụ. Ví dụ, xác nhận <sp:TransportBinding> thường dùng để xác định bảo mật vận chuyển chỉ có thể được đính kèm ở mức thiết bị đầu cuối, trong sử dụng khi các xác nhận <sp:AsymmetricBinding><sp:SymmetricBinding> thường dùng để xác định mã hóa hoặc ký thông báo chỉ có thể được sử dụng ở mức thiết bị đầu cuối hoặc mức hoạt động.

Mặc dù không thể quy định xác nhận <sp:AsymmetricBinding> hay <sp:SymmetricBinding> ở mức thông báo, bạn có thể chỉ rõ các thành phần thông báo được mã hóa hoặc ký ở mức thông báo. Điều này có nghĩa là ít nhất về mặt lý thuyết. có thể quy định mã hóa hoặc ký trên cơ sở mỗi thông báo.


Các ví dụ chính sách

Khi bài này được công bố lần đầu, ví dụ Axis2 đã không làm việc. Ngay sau khi xuất bản, tôi đã có thể giải quyết vấn đề này bằng cách sử dụng một dạng mẫu cấu hình khác. Phần viết của bài báo đã sửa đổi và mã tải về đã sửa đổi để phản ánh các thay đổi này.

Vì bạn đã học được các nguyên tắc của WS-Policy và cách nó hoạt động với WSDL, đây là lúc dùng thử một số ví dụ chính sách bằng cách sử dụng những nguyên tắc này. Cũng như bài trước, tôi đã dùng thử đoạn mã này với ba trong số các ngăn xếp các dịch vụ web nguồn mở Java chính: Axis2, Metro và CXF.

Liệt kê 5 cho thấy một ví dụ (effective1.wsdl trong bản tải về mã mẫu) sử dụng ba mức đính kèm chính sách trong một định nghĩa dịch vụ WSDL. Ba chính sách được sử dụng là:

  • UsernameToken: Yêu cầu một UsernameToken với mật khẩu băm.
  • SymmEncr: Yêu cầu mã hóa đối xứng bằng cách sử dụng một khóa bí mật do máy khách tạo ra.
  • EncrBody: Yêu cầu mã hóa phần thân thông báo.
Liệt kê 5. Ví dụ chính sách-hiệu quả
<wsdl:definitions targetNamespace="http://ws.sosnoski.com/library/wsdl"...>
  

  <wsp:Policy wsu:Id="UsernameToken" xmlns:wsp="http://www.w3.org/ns/ws-policy"...>
    <sp:SupportingTokens>
      <wsp:Policy>
        <sp:UsernameToken sp:IncludeToken=".../IncludeToken/AlwaysToRecipient">
          <wsp:Policy>
            <sp:HashPassword/>
          </wsp:Policy>
        </sp:UsernameToken>
      </wsp:Policy>
    </sp:SupportingTokens>
  </wsp:Policy>
  
  <wsp:Policy wsu:Id="SymmEncr" xmlns:wsp="http://www.w3.org/ns/ws-policy"...>
    <sp:SymmetricBinding>
      <wsp:Policy>
        <sp:ProtectionToken>
          <wsp:Policy>
            <sp:X509Token sp:IncludeToken=".../IncludeToken/Never">
              ...
            </sp:X509Token>
          </wsp:Policy>
        </sp:ProtectionToken>
        ...
      </wsp:Policy>
    </sp:SymmetricBinding>
    ...
  </wsp:Policy>
  
  <wsp:Policy wsu:Id="EncrBody" xmlns:wsp="http://www.w3.org/ns/ws-policy"...>
    <sp:EncryptedParts>
      <sp:Body/>
    </sp:EncryptedParts>

  </wsp:Policy>
  ...
  <wsdl:binding name="LibrarySoapBinding" type="wns:Library">
    <wsp:PolicyReference xmlns:wsp="http://www.w3.org/ns/ws-policy"
        URI="#UsernameToken"/>
    ...
    <wsdl:operation name="getBook">
      <wsp:PolicyReference xmlns:wsp="http://www.w3.org/ns/ws-policy"
          URI="#SymmEncr"/>
      <wsdlsoap:operation soapAction="urn:getBook"/>
      <wsdl:input name="getBookRequest">
        <wsdlsoap:body use="literal"/>
      </wsdl:input>
      <wsdl:output name="getBookResponse">
        <wsp:PolicyReference xmlns:wsp="http://www.w3.org/ns/ws-policy"
            URI="#EncrBody"/>
        <wsdlsoap:body use="literal"/>

      </wsdl:output>
    </wsdl:operation>

    <wsdl:operation name="getBooksByType">
      <wsp:PolicyReference xmlns:wsp="http://www.w3.org/ns/ws-policy"
          URI="#SymmEncr"/>
      <wsdlsoap:operation soapAction="urn:getBooksByType"/>
      <wsdl:input name="getBooksByTypeRequest">
        <wsdlsoap:body use="literal"/>
      </wsdl:input>
      <wsdl:output name="getBooksByTypeResponse">
        <wsp:PolicyReference xmlns:wsp="http://www.w3.org/ns/ws-policy"
            URI="#EncrBody"/>
        <wsdlsoap:body use="literal"/>
      </wsdl:output>
    </wsdl:operation>

    <wsdl:operation name="getTypes">
    ...
    </wsdl:operation>

    <wsdl:operation name="addBook">
      <wsp:PolicyReference xmlns:wsp="http://www.w3.org/ns/ws-policy"
          URI="#SymmEncr"/>
      <wsdlsoap:operation soapAction="urn:addBook"/>
      <wsdl:input name="addBookRequest">
        <wsp:PolicyReference xmlns:wsp="http://www.w3.org/ns/ws-policy"
            URI="#EncrBody"/>
        <wsdlsoap:body use="literal"/>
      </wsdl:input>
      <wsdl:output name="addBookResponse">
        <wsdlsoap:body use="literal"/>
      </wsdl:output>
      <wsdl:fault name="addDuplicateFault">
        <wsp:PolicyReference xmlns:wsp="http://www.w3.org/ns/ws-policy"
            URI="#EncrBody"/>
        <wsdlsoap:fault name="addDuplicateFault" use="literal"/>
      </wsdl:fault>
    </wsdl:operation>
  </wsdl:binding>
  ...
</wsdl:definitions>

Các tài liệu tham khảo chính sách (được in đậm) trong tài liệu WSDL của Liệt kê 5 đính kèm chính sách UsernameToken vào phần tử <wsdl:binding>, sao cho UsernameToken là bắt buộc cho tất cả các hoạt động. Người ta đính kèm chính sách SymmEncr vào một phần tử <wsdl:operation> riêng lẻ cho tất cả các hoạt động trao đổi thông tin cuốn sách (book) và đính kèm chính sách EncrBody vào các thông báo có thông tin cuốn sách — để cho thông tin cuốn sách luôn được gửi đi ở dạng mã hóa.

Đây là một chính sách khó khăn, trong đó nó đòi hỏi máy khách tạo ra một khóa bí mật và gửi nó đến máy chủ với thông báo yêu cầu, mặc dù khóa bí mật chỉ được sử dụng để mã hóa trả lời. Axis2 1.5.1 (bản phân phối 1.5.2 đã được dùng thử, nhưng thiếu một tệp cần thiết để xử lý bảo mật) hoàn toàn đã bỏ qua chính sách đó trong cả hai mã được tạo ra và hoạt động của máy chủ, sẵn sàng chạy không có bất kỳ sự bảo mật nào. Khi tôi đã thay đổi các chính sách để sử dụng vùng tên trình lên cũ hơn, Axis2 đã nhận ra các chính sách và đã chạy đúng, ngoại trừ trong việc xử lý lỗi hoạt động trả lời addBook. Việc trả lời lỗi-ứng dụng trả về được hỗ trợ để sử dụng mã hóa, theo chính sách đó, nhưng Axis2 đã gửi nó trở lại không được mã hóa.

Metro đã tạo ra một thông báo yêu cầu với một UsernameToken, nhưng không có thông tin khóa-bí mật nào, một thất bại hoàn toàn dựa trên việc trao đổi thông báo lần đầu. CXF 2.3.0 đã làm tốt hơn nhiều so với Metro, xử lý chính sách đúng, ngoại trừ trong hai trường hợp. Khi hoạt động addBook thành công, thông báo trả lời không sử dụng mã hóa. Các máy chủ CXF đã xử lý điều này một cách chính xác, nhưng máy khách lại đưa ra một ngoại lệ khi xử lý trả lời. Lỗi CXF khác vẫn giống như Axis2, không sử dụng mã hóa để trả lời lỗi ứng dụng.

Chính sách của Liệt kê 5 chứng tỏ cách sử dụng mã hóa thông báo có chọn lọc, chỉ mã hóa những thông báo có thông tin cuốn sách. Tuy nhiên, chính sách này sử dụng mã hóa đối xứng. Thật là thú vị khi có khả năng thực hiện cùng một kiểu công việc bằng cách sử dụng mã hóa không đối xứng, ở nơi máy khách có chứng nhận riêng của mình (đặc biệt là khi bạn muốn ký thông báo để xác minh tính hợp lệ của người gửi). Liệt kê 6 cho thấy một ví dụ được thiết kế cho mục đích này (effective2.wsdl trong bản tải về). Ví dụ này chỉ sử dụng hai chính sách từ WSDL:

  • AsymmBinding: Yêu cầu mã hóa không đối xứng bằng cách sử dụng các chứng nhận kép.
  • SignBody: Yêu cầu ký phần thân thông báo.
Liệt kê 6. Ví dụ ký không đối xứng
<wsdl:definitions targetNamespace="http://ws.sosnoski.com/library/wsdl"...>

  <wsp:Policy wsu:Id="AsymmBinding" xmlns:wsp="http://www.w3.org/ns/ws-policy" ...>
    <sp:AsymmetricBinding>
      <wsp:Policy>
        <sp:InitiatorToken>
          <wsp:Policy>
            <sp:X509Token sp:IncludeToken=".../IncludeToken/AlwaysToRecipient">
              ...
            </sp:X509Token>
          </wsp:Policy>
        </sp:InitiatorToken>
        <sp:RecipientToken>
          <wsp:Policy>
            <sp:X509Token sp:IncludeToken=".../IncludeToken/Never">
              ...
            </sp:X509Token>
          </wsp:Policy>
        </sp:RecipientToken>
        ...
      </wsp:Policy>
    </sp:AsymmetricBinding>
  </wsp:Policy>
  
  <wsp:Policy wsu:Id="SignBody" xmlns:wsp="http://www.w3.org/ns/ws-policy" ...>
    <sp:SignedParts>
      <sp:Body/>
    </sp:SignedParts>
  </wsp:Policy>
  ...
  <wsdl:binding name="LibrarySoapBinding" type="wns:Library">
    ...
    <wsdl:operation name="getBook">
      <wsp:PolicyReference xmlns:wsp="http://www.w3.org/ns/ws-policy"
          URI="#AsymmBinding"/>
      <wsdlsoap:operation soapAction="urn:getBook"/>
      <wsdl:input name="getBookRequest">
        <wsdlsoap:body use="literal"/>
      </wsdl:input>
      <wsdl:output name="getBookResponse">
        <wsp:PolicyReference xmlns:wsp="http://www.w3.org/ns/ws-policy"
            URI="#SignBody"/>
        <wsdlsoap:body use="literal"/>
      </wsdl:output>
    </wsdl:operation>

    <wsdl:operation name="getBooksByType">
      <wsp:PolicyReference xmlns:wsp="http://www.w3.org/ns/ws-policy"
          URI="#AsymmBinding"/>
      <wsdlsoap:operation soapAction="urn:getBooksByType"/>
      <wsdl:input name="getBooksByTypeRequest">
        <wsdlsoap:body use="literal"/>
      </wsdl:input>

      <wsdl:output name="getBooksByTypeResponse">
        <wsp:PolicyReference xmlns:wsp="http://www.w3.org/ns/ws-policy"
            URI="#SignBody"/>
        <wsdlsoap:body use="literal"/>
      </wsdl:output>
    </wsdl:operation>

    <wsdl:operation name="getTypes">
      ...
    </wsdl:operation>

    <wsdl:operation name="addBook">
      <wsp:PolicyReference xmlns:wsp="http://www.w3.org/ns/ws-policy"
          URI="#AsymmBinding"/>
      <wsdlsoap:operation soapAction="urn:addBook"/>
      <wsdl:input name="addBookRequest">
        <wsp:PolicyReference xmlns:wsp="http://www.w3.org/ns/ws-policy"
            URI="#SignBody"/>
        <wsdlsoap:body use="literal"/>
      </wsdl:input>
      <wsdl:output name="addBookResponse">
        <wsdlsoap:body use="literal"/>
      </wsdl:output>
      <wsdl:fault name="addDuplicateFault">
        <wsdlsoap:fault name="addDuplicateFault" use="literal"/>
      </wsdl:fault>
    </wsdl:operation>
  </wsdl:binding>
  ...
</wsdl:definitions>

Ví dụ trong Liệt kê 6 sử dụng mã hóa không đối xứng để ký tất cả các thông báo cung cấp thông tin cuốn sách. Ví dụ này có nghĩa là các thông báo trả lời getBookgetBooksByType cần được máy chủ ký, trong khi các thông báo yêu cầu addBook cần máy khách ký. Vì ví dụ này đang sử dụng mã hóa không đối xứng, ở đây mỗi bên có chứng nhận riêng và khóa riêng của mình, nên nó cần xử lý đơn giản hơn một chút so với ví dụ mã hóa đối xứng trong Liệt kê 5.

Các tài liệu tham khảo chính sách bên ngoài

Các tài liệu tham khảo chính sách bên ngoài không thể thêm vào cấu trúc của các ví dụ được cung cấp, nhưng tôi đã kiểm tra chúng. Với bài kiểm tra của mình, tôi đã sử dụng cả hai tài liệu tham khảo có liên quan, của dạng mẫu <wsp:PolicyReference xmlns:wsp="http://www.w3.org/ns/ws-policy" URI="./asymm-binding-policy.xml"/> và các URL tuyệt đối được lưu trữ trên một máy chủ web. Cả Axis2 và Metro đã không thể giải quyết các tài liệu tham khảo chính sách về kiểu này. Chúng đã làm việc đúng trên CXF.

Axis2 đã không thành công theo cách giống như trong ví dụ trước, hoàn toàn bỏ qua các thành phần chính sách đang sử dụng các vùng tên chính sách của WS-Policy 1.5. Khi tôi đã thay đổi tới vùng tên trình lên, Axis2 đã có thể xử lý ví dụ này mà không có bất kỳ lỗi nào. Do những vấn đề này trong việc sử dụng vùng tên của WS-Policy 1.5 với Axis2, tất cả ví dụ Axis2 bản tải về mã này đều sử dụng vùng tên trình lên.

Metro không thể làm việc với cấu hình chính sách này như được cung cấp, đưa ra một ngoại lệ NullPointerException trên máy khách với chính yêu cầu đầu tiên. Sau một vài xem xét, tôi đã thấy rằng vấn đề sẽ hết giá như tôi đã đính kèm một chính sách ở mức thiết bị đầu cuối, chứ không chỉ ở mức hoạt động và mức thông báo. Ví dụ Metro bao gồm một effective3.wsdl với chính sách #AsymmBinding được tham khảo chỉ từ phần tử <wsdl:binding> và ví dụ này chạy không có vấn đề (mặc dù, giống như CXF trong trường hợp đối xứng, Metro không áp dụng bảo mật để trả lời lỗi-ứng dụng).

CXF cũng không thành công với cấu hình chính sách trong Liệt kê 6, nhưng không có bất kỳ cách giải quyết dễ dàng nào trong mã hiện tại. Mã máy khách CXF tạo sai một chữ ký khi gửi thông báo yêu cầu getBook và tiếp theo mã máy chủ thất bại trong việc xử lý thông báo yêu cầu. Vì vậy, nó trông giống như mã CXF hiện tại cố tạo ra một chữ ký khi AsymmetricBinding trong giới hạn, ngay cả khi không có gì sắp ký.


Tóm tắt về chính sách

WS-Policy định nghĩa một cấu trúc linh hoạt và mạnh mẽ để thể hiện các ràng buộc của bất kỳ dạng mẫu nào. Thật không may, các công cụ xử lý WS-Policy và WS-SecurityPolicy được các ngăn xếp các dịch vụ web sử dụng không triển khai thực hiện nhiều về tính linh hoạt. Do thiếu sự hỗ trợ thực hiện này, nên không thể sử dụng nhiều tính năng có ích khác của WS-Policy cho các dịch vụ web đã dự kiến để tương thích với toàn bộ dải các ngăn xếp dịch vụ web.

Việc xử lý chính sách-hiệu quả cơ bản, theo đó các chính sách được đính kèm tại các điểm khác nhau trong các định nghĩa dịch vụ WSDL, là một tính năng cốt lõi của chính sách và thiết kế WSDL và cần được sử dụng ở những nơi thích hợp cho các dịch vụ của bạn. Nhưng một trong những tính năng có ích tiềm năng của loại cấu hình này — khả năng để ký và mã hóa các thông báo có chọn lọc trên cơ sở cá nhân — không làm việc tin cậy (với Apache Axis2 chỉ xử lý các trường hợp kiểm tra đúng và tiếp theo chỉ sau khi thay đổi vùng tên chính sách) . Với quan điểm hạn chế này, khả năng tốt nhất là duy trì các bản đính kèm chính sách ở các mức <wsdl:binding><wsdl:operation> vào lúc này nếu bạn muốn có khả năng tương thích tốt nhất.

Các chính sách bên ngoài có thể đặc biệt có ích cho các môi trường kiểu-SOA, nơi một bộ các chính sách chung có thể được thiết lập để sử dụng trong toàn bộ tổ chức và mỗi dịch vụ có thể tham khảo các chính sách phù hợp với các nhu cầu của nó. Mặc dù tính năng này không được tất cả các ngăn xếp các dịch vụ web Java nguồn mở (với chỉ có Apache CXF xử lý nó đúng) hỗ trợ hiện nay, dù sao các tổ chức lớn hơn có thể muốn sử dụng tính năng này và hạn chế các công cụ dịch vụ web bằng cách sử dụng một trong các ngăn xếp (nguồn mở hay thương mại) hỗ trợ nó. Bạn cũng có thể có khả năng nhận được hiệu quả tương tự bằng các phương tiện khác, chẳng hạn như bằng cách sử dụng WSDL kèm theo.

Trong phần tiếp theo của loạt bài này, tôi sẽ tóm tắt các vấn đề hiệu năng và tính tương thích với ba ngăn xếp của các dịch vụ web Java và cung cấp một tổng quan về cách các ngăn xếp so sánh để sử dụng trong việc triển khai thực hiện các dịch vụ web bảo mật. Nếu bạn đang sử dụng các dịch vụ web bảo mật trong tổ chức của mình, bạn sẽ không muốn bỏ lỡ việc này.


Tải về

Mô tảTênKích thước
Sample code for this articlej-jws18.zip94KB

Tài nguyên

Học tập

Thảo luận

  • Hãy dành tâm trí cho cộng đồng My developerWorks. Kết nối với những người dùng developerWorks khác trong lúc khám phá các blog, các diễn đàn, các nhóm và các wiki hướng nhà phát triển.

Bình luận

developerWorks: Đăng nhập

Các trường được đánh dấu hoa thị là bắt buộc (*).


Bạn cần một ID của IBM?
Bạn quên định danh?


Bạn quên mật khẩu?
Đổi mật khẩu

Bằng việc nhấn Gửi, bạn đã đồng ý với các điều khoản sử dụng developerWorks Điều khoản sử dụng.

 


Ở lần bạn đăng nhập đầu tiên vào trang developerWorks, một hồ sơ cá nhân của bạn được tạo ra. Thông tin trong bản hồ sơ này (tên bạn, nước/vùng lãnh thổ, và tên cơ quan) sẽ được trưng ra cho mọi người và sẽ đi cùng các nội dung mà bạn đăng, trừ khi bạn chọn việc ẩn tên cơ quan của bạn. Bạn có thể cập nhật tài khoản trên trang IBM bất cứ khi nào.

Thông tin gửi đi được đảm bảo an toàn.

Chọn tên hiển thị của bạn



Lần đầu tiên bạn đăng nhập vào trang developerWorks, một bản trích ngang được tạo ra cho bạn, bạn cần phải chọn một tên để hiển thị. Tên hiển thị của bạn sẽ đi kèm theo các nội dung mà bạn đăng tải trên developerWorks.

Tên hiển thị cần có từ 3 đến 30 ký tự. Tên xuất hiện của bạn phải là duy nhất trên trang Cộng đồng developerWorks và vì lí do an ninh nó không phải là địa chỉ email của bạn.

Các trường được đánh dấu hoa thị là bắt buộc (*).

(Tên hiển thị cần có từ 3 đến 30 ký tự)

Bằng việc nhấn Gửi, bạn đã đồng ý với các điều khoản sử dụng developerWorks Điều khoản sử dụng.

 


Thông tin gửi đi được đảm bảo an toàn.


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=70
Zone=Công nghệ Java, SOA và dịch vụ Web, Nguồn mở
ArticleID=823427
ArticleTitle=Các dịch vụ Web Java: Tìm hiểu về WS-Policy
publish-date=06292012