Tại sao WARs không thể chia sẻ thông tin phiên?


11

Tôi đã thấy một số nhà phát triển đang tìm giải pháp cho vấn đề này: truy cập thông tin phiên từ một WAR khác nhau (ngay cả khi trong cùng một EAR) - đây là một số mẫu: Có cách nào để chia sẻ trạng thái phiên giữa các ứng dụng khác nhau trong tomcat không? , Phiên truy cập của một ứng dụng web khác , các tệp WAR khác nhau, tài nguyên được chia sẻ , Tomcat: Làm thế nào để chia sẻ dữ liệu giữa hai ứng dụng? , Thuộc tính crossContext làm gì trong Tomcat? Nó có cho phép chia sẻ phiên không? và như thế...

Từ tất cả những gì tôi đã tìm kiếm, có một số giải pháp cụ thể tùy thuộc vào container, nhưng nó bằng cách nào đó ' trái với đặc điểm kỹ thuật '. Tôi cũng đã xem qua đặc tả Java EE mà không gặp may mắn trong việc tìm câu trả lời.

Một số nhà phát triển nói về việc ghép nối giữa các ứng dụng web, nhưng tôi có xu hướng không đồng ý. Lý do nào khiến người ta giữ WAR trong cùng một EAR nếu không khớp? Ví dụ, các EJB có thể được truy cập cục bộ (ngay cả khi bên trong một JAR EJB khác trong cùng EAR).

Cụ thể hơn, một trong những WAR của tôi xử lý xác thực và ủy quyền và tôi muốn chia sẻ thông tin này với các WAR khác (trong cùng EAR). Tôi đã xử lý các vấn đề tương tự trước đây bằng cách đóng gói các WAR dưới dạng JAR và đưa chúng vào một dự án WAR đơn lẻ (WEB-INF / lib). Tuy nhiên, tôi không thích giải pháp này (nó đòi hỏi một nỗ lực rất lớn trong việc đặt tên servlet, v.v.).

Và không có giải pháp nào trả lời được câu hỏi đầu tiên (và quan trọng nhất): Tại sao WARs không thể chia sẻ thông tin phiên?


1
Không chắc chắn tại sao điều này bị hạ cấp, ngoài việc nó có thể phù hợp hơn với SO.
NateDSaint

3
"Theo đặc tả API của servlet 2.3, trình quản lý phiên chỉ hỗ trợ phạm vi phiên bằng mô-đun Web. Chỉ các máy chủ trong cùng mô-đun Web mới có thể truy cập dữ liệu được liên kết với một phiên cụ thể." Điều này có thể được nhìn thấy một lần nữa trong HttpSession - "Thông tin phiên chỉ nằm trong phạm vi ứng dụng web hiện tại (ServletContext), vì vậy thông tin được lưu trữ trong một ngữ cảnh sẽ không được hiển thị trực tiếp trong một ngữ cảnh khác." - Làm như vậy là trái với đặc điểm kỹ thuật.

(tốt hơn, liên kết hiện tại cho HttpSession )

@MichaelT, cảm ơn bạn. Nhưng nó vẫn không trả lời tại sao.
rvcoutinho

@NateDSaint Mặc dù câu hỏi có liên quan đến các công nghệ cụ thể, tôi tin rằng nó có nhiều khả năng là một câu hỏi về khái niệm. Sau đó, tôi quyết định cho lập trình viên.
rvcoutinho

Câu trả lời:


7

Đối xử với một EAR như một máy ảo giả

EAR đơn giản là một tập hợp các tệp WAR chia sẻ cấu hình và thư viện chung, thường là từ các JAR. Điều này cho phép tập hợp các dịch vụ phụ thuộc lẫn nhau được quản lý dễ dàng hơn trong vùng chứa ứng dụng. Do đó, bạn có thể nghĩ về EAR như một dạng máy ảo đơn giản sau khi được triển khai vào thùng chứa của nó.

Theo cùng một cách mà một quá trình trên máy ảo có thể ảnh hưởng đến một quá trình khác, điều tương tự cũng đúng với EAR. Tất cả các WAR được cách ly để bảo vệ trạng thái bên trong của chúng.

Xác thực mở rộng

Trong các ứng dụng web nói chung cần phải không trạng thái để mở rộng quy mô. Có nhiều thông tin trong phiên là một mô hình chống ngăn chặn điều này. Điều này dẫn đến mâu thuẫn giữa bản chất không trạng thái của HTTP và nhu cầu duy trì trải nghiệm người dùng tùy chỉnh nhanh chóng. Xác thực là trường hợp sử dụng cổ điển và phổ biến trong các API trò chuyện yêu cầu nhiều yêu cầu xác thực để cung cấp chức năng của người dùng cuối.

Đăng nhập một lần và Đăng nhập một lần cần báo hiệu cẩn thận để hoạt động chính xác (xem xét Đăng xuất một phần), đặc biệt khi đặt tỷ lệ ngang. Đơn giản là chia sẻ trạng thái phiên gần như không bao giờ là một giải pháp tốt và cách tiếp cận tốt hơn là sử dụng một điểm tham chiếu duy nhất cho thông tin người dùng mà tất cả các nút trong cụm có quyền truy cập.

Tập trung vào truy cập nhanh vào bộ nhớ cache vào thông tin có liên quan sẽ mang lại kết quả có thể mở rộng hơn nhiều so với một số giải pháp chia sẻ phiên phức tạp, dễ vỡ.


Cảm ơn, @GaryRowe. Đây là câu trả lời tôi đang tìm kiếm. Dù sao, đó không phải là để nhà phát triển quyết định?
rvcoutinho

Một câu hỏi khác: Bạn có nghĩ JBoss Cache có thể là một giải pháp tốt không? Bạn đã nghe nói về Apache Shiro (và phân cụm phiên của nó) chưa? Còn nó thì sao?
rvcoutinho

@rvcoutinho Nhà phát triển ứng dụng có quyết định cách quản lý các quy trình trong nhân Linux không? Đó là một khung tương tự của một câu hỏi - vâng, bạn có thể làm điều đó nhưng nó sẽ cực kỳ khó khăn và có thể khiến bạn đau đớn hơn là đi theo con đường khác.
Gary Rowe

2
@rvcoutinho Tôi chưa sử dụng Apache Shiro (còn gọi là Bảo mật Apache) nhưng tôi tưởng tượng rằng đó sẽ là một giải pháp tốt cho vấn đề bảo mật được chia sẻ. Chắc chắn xem xét việc tích hợp với OpenID và OAuth2 thay vì triển khai giao thức của riêng bạn để đạt được điều tương tự. JBoss Cache bằng cách thừa nhận của riêng họ trong một ngõ cụt được thay thế bằng Infinispan trông khá phức tạp. Bạn có thể muốn xem trang web Ứng dụng Mười hai yếu tố để có cái nhìn tổng quát về một giải pháp có thể mở rộng đơn giản hơn.
Gary Rowe

2

Đó là điều mà tôi nghĩ là thiếu chức năng từ đặc tả JEE EAR - khả năng chia sẻ các phiên web trên nhiều kho lưu trữ web bị ràng buộc trong một EAR.

Các máy chủ ứng dụng như Weblogic không triển khai tiêu chuẩn cho chức năng này.


Đó là ý kiến ​​của tôi cho đến nay. Tôi đã cố gắng để hiểu tại sao sự lựa chọn được đề cập đã được thực hiện.
rvcoutinho

1

Chà, AFAIKS, không có lý do thực sự tại sao bạn muốn làm điều này. WAR là một ứng dụng web độc lập, với phạm vi riêng (cụ thể của ứng dụng web) (như phạm vi phiên). Nếu bạn cần chia sẻ chức năng (mã Java, trang JSP, tệp CSS), giữa nhiều WAR, bạn có tùy chọn hợp lý hơn nhiều để đóng gói chúng dưới dạng tệp JAR và triển khai chúng trong máy chủ ứng dụng của bạn. Gói WAR là một giải pháp đóng gói phức tạp hơn và được thiết kế để đóng gói một cái gì đó khác với "mã / chức năng chung" đơn giản. JAR là một định dạng đơn giản hơn VÀ được thiết kế để đóng gói và chia sẻ mã và chức năng. Tại sao bạn muốn sử dụng một bao bì phức tạp hơn và không đặc biệt được thiết kế cho bao bì đó để chia sẻ một cái gì đó, khi bạn đã có sẵn một định dạng gói đơn giản và phù hợp hơn với gói đó.


Tôi đồng ý với bạn. Nhưng chỉ khi nói đến tài nguyên chung. Nhưng, đối với một ứng dụng đăng nhập một lần, tôi sẽ cần chia sẻ thông tin cụ thể về phiên (về người dùng đã đăng nhập). Và tôi thấy không có lý do tại sao điều này sẽ chống lại thông số kỹ thuật.
rvcoutinho

2
Bởi vì phạm vi phiên không được thực hiện để chia sẻ dữ liệu người dùng hiện tại giữa các ứng dụng khác nhau. Và bởi vì SSO ngụ ý nhiều hơn là kiểm tra các thuộc tính phạm vi phiên. Bạn có thể tạo và đóng gói mã bên ngoài cuộc chiến của mình (và điều này không phụ thuộc vào cuộc chiến của bạn, mà là chiến tranh phụ thuộc vào nó) sẽ truy cập các thuộc tính phạm vi phiên nếu bạn muốn (như bộ lọc), nhưng giải pháp tốt hơn IMHO sẽ là để có một ứng dụng mặt tiền hoặc cấu hình máy chủ riêng biệt liên quan đến auth và cấp quyền truy cập cho các ứng dụng (triển khai chiến tranh) khác.
Shivan Dragon

Tôi sẽ lại đồng ý với bạn. Tuy nhiên, đặc tả JavaEE (sử dụng JAAS) lưu giữ thông tin người dùng như một phần của HttpSession, trái ngược với cách tiếp cận này. Một trong những lý do tôi đã cân nhắc sử dụng Shiro (nó duy trì một phiên trực giao) thay vào đó.
rvcoutinho

Dù sao, cảm ơn đã trả lời. Tôi vẫn chưa có câu trả lời dứt khoát cho câu hỏi của mình, nhưng tất cả những gì bạn nói là có liên quan. +1
rvcoutinho

@rvcoutinho tốt, đó là ý kiến ​​của tôi về vấn đề này, xin lỗi nó không hữu ích hơn cho bạn.
Shivan Dragon

0

Tôi nghĩ rằng điều này đã được thực hiện trên mục đích, để tránh các ứng dụng web khác nhau vô tình ghi đè lên thông tin phiên của nhau. Nó có thể có ích trong trường hợp của bạn, nhưng nói chung, bạn không muốn người dùng làm cho ứng dụng bị sập hoặc leo thang các đặc quyền của họ chỉ vì họ sử dụng hai ứng dụng web cùng một lúc. Chính xác là không khó để chia sẻ thông tin giữa các ứng dụng web; chỉ cần tạo một lớp với HashMap tĩnh, sử dụng GUID làm khóa và chuyển chúng như một phần của tham số URL hoặc HTTP.


Cảm ơn. Trên thực tế, tôi đã không nói về việc chia sẻ toàn bộ phiên giữa mọi ứng dụng, nhưng thông tin phiên cụ thể (dưới dạng thông tin người dùng) khi cần. Có lẽ tôi đã không rõ ràng. Bất kỳ đề xuất về làm cho nó rõ ràng hơn?
rvcoutinho
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.