2013-02-12 23 views
6

Trong JSF, có vẻ như các phiên được tạo trước thông tin đăng nhập thành công. tức là chỉ cần yêu cầu trang đăng nhập sẽ tạo một phiên mới.Khi nào phiên được tạo trong khi đăng nhập JSF?

Có vẻ như rất lãng phí (và dễ bị tấn công DDoS) để tạo phiên cho mỗi yêu cầu nhận được, thay vì mỗi người dùng đăng nhập thành công.

Mã bên dưới khá chung chung, nhưng hiển thị loại kịch bản đơn giản mà tôi đang đề cập đến.

index.xhtml:

<html> 
    <body> 
     <h:form id="login"> 
      <h:outputLabel for="username">Username</h:outputLabel> 
      <p:inputText id="username" name="username" value="#{userController.username}"/> 
      <h:outputLabel for="password">Password</h:outputLabel> 
      <p:password id="password" name="password" value="#{userController.password}"/> 

      <p:commandButton id="loginButton" value="login" action="#{loginController.login}"/> 
     </h:form> 
    </body> 
</html> 

LoginController.java

@ViewScoped 
public class LoginController implements Serializable { 

    String username; 
    String password; 

    public void login(){ 
     HttpServletRequest request = (HttpServletRequest) FacesContext.getCurrentInstance().getExternalContext().getRequest(); 
     if (request.getSession(false) == null){ 
      System.out.println("No session."); 
     } else { 
      System.out.println("Session already exists."); 
     } 

     try { 
      request.login(username, password); 
     } catch (ServletException e) { 
      FacesContext.getCurrentInstance.addMessage(null, new FacesMessage("Login failure", e.getMessage())); 
     } 
    } 

    // username and password getters/setters 

} 

Chỉnh sửa: Mã hỗn loạn dụ cố định

Trả lời

8

Trước hết, phương pháp thử nghiệm của bạn là hoàn toàn sai.

if (request.getSession() == null){ 
    System.out.println("No session."); 
} else { 
    System.out.println("Session already exists."); 
} 

Hãy đọc kỹ phương pháp getSession(). Bạn sẽ nhận ra rằng nó không bao giờ trả lại null.

Quay lại vấn đề cụ thể, theo mặc định JSF thực sự sẽ tự động tạo phiên vì trạng thái xem JSF phải được lưu trữ ở đó. Nếu bạn đặt phương thức lưu trạng thái JSF thành client thay vì server, thì nó sẽ không được lưu trữ trong phiên và do đó không cần tạo phiên nào.

<context-param> 
    <param-name>javax.faces.STATE_SAVING_METHOD</param-name> 
    <param-value>client</param-value> 
</context-param> 

Trong JSF 2.2 sắp tới, bạn cũng có thể đặt đậu trong phạm vi yêu cầu và sử dụng <f:view transient="true"> để hoàn toàn không quốc tịch. Điều này là dành cho phiên bản JSF 2.1 hiện tại chỉ có sẵn từ Mojarra 2.1.19. Xem thêm ví dụ: this blog từ một trong những nhà phát triển Mojarra.

+0

Xưng tội - mã mẫu đã được điều chỉnh rất nhiều từ mã sản xuất của chúng tôi. Ban đầu tôi đã sử dụng getSession (sai). Nhưng điều đó sang một bên, cảm ơn bạn đã xác nhận những gì tôi nghĩ. Mặc dù săn bắn nhiều (sách, blog, tài liệu Oracle) Tôi đã không tìm thấy xác nhận rõ ràng rằng JSF tự động xử lý phiên. – MMeldrum

+0

Là một sang một bên, điều này thực sự làm cho nó dễ dàng hơn để lấy xuống một máy chủ bằng cách tràn nó với yêu cầu đăng nhập mới (mặc dù không có thông tin đăng nhập có sẵn)? – MMeldrum

+0

Phụ thuộc vào phần cứng và cấu hình máy chủ. Ví dụ. kết nối/yêu cầu tổng hợp, thời gian chờ của phiên, bộ nhớ có sẵn, băng thông mạng, vv Đo lường là biết. – BalusC