2010-04-09 58 views
6

Tôi đang sử dụng Dịch vụ RememberMe của Spring Security để giữ cho người dùng được xác thực.Bảo mật mùa xuân Dịch vụ RememberMe với Cookie phiên

Tôi muốn tìm một cách đơn giản để đặt cookie RememberMe thành cookie phiên chứ không phải là thời gian hết hạn cố định. Đối với ứng dụng của tôi, cookie sẽ vẫn tồn tại cho đến khi người dùng đóng trình duyệt.

Bất kỳ đề xuất nào về cách triển khai tốt nhất điều này? Mọi lo ngại về vấn đề này có phải là vấn đề an ninh tiềm ẩn không?

Lý do chính để làm như vậy là với mã thông báo dựa trên cookie, bất kỳ máy chủ nào trong số các máy chủ của chúng tôi có thể bảo vệ yêu cầu được bảo vệ mà không dựa vào Xác thực của người dùng được lưu trữ trong HttpSession. Trong thực tế, tôi đã nói rõ ràng với Spring Security để không bao giờ tạo các session bằng cách sử dụng không gian tên. Hơn nữa, chúng tôi đang sử dụng Cân bằng tải đàn hồi của Amazon và các phiên cố định không được hỗ trợ.

NB: Mặc dù tôi biết rằng kể từ ngày 8 tháng 4, Amazon hiện hỗ trợ các phiên cố định, tôi vẫn không muốn sử dụng chúng vì một số lý do khác. Cụ thể là sự sụp đổ không kịp thời của một máy chủ sẽ vẫn gây ra việc mất các phiên cho tất cả người dùng được liên kết với nó. http://aws.amazon.com/about-aws/whats-new/2010/04/08/support-for-session-stickiness-in-elastic-load-balancing/

+0

Tại sao bạn không đơn giản triển khai thực hiện RememberMe của riêng bạn? Nó khá dễ. – lexicore

+0

Sao chép? http://stackoverflow.com/questions/2594960/best-practice-to-implement-secure-remember-me – rook

+0

@lexicore người thực hiện các phiên của riêng họ có thể mang lại sự tàn phá thực sự cho ứng dụng web của bạn. Đừng tái phát minh ra sự rên rỉ. Đọc bài đăng của tôi trên "trùng lặp?" câu hỏi trên. – rook

Trả lời

3

Để phiên làm việc đúng với cân bằng tải tôi sẽ lưu trữ dữ liệu phiên trong cơ sở dữ liệu sql.

Cookie phải luôn là giá trị ngẫu nhiên hết hạn. Có những trường hợp bạn có thể lưu trữ trạng thái dưới dạng giá trị cookie và không phải là mối đe dọa bí mật, chẳng hạn như ngôn ngữ ưa thích của người dùng, nhưng điều này nên tránh càng nhiều càng tốt. Bật HttpOnlyCookies, là một ý tưởng tuyệt vời.

Đọc A3: "Xác thực bị hỏng và Quản lý phiên" trong OWASP top 10 cho năm 2010. Một điểm quan trọng trong phần này là https phải được sử dụng cho toàn bộ phiên. Nếu phiên họp kéo dài trong một thời gian rất dài, thì điều này thậm chí còn quan trọng hơn.

Cũng nên nhớ rằng "Remember Me" tạo một cửa sổ lớn trong đó kẻ tấn công có thể "cưỡi" trên phiên. Điều này cho một kẻ tấn công một thời gian rất dài (tháng?), Trong đó ông có thể cung cấp một cuộc tấn công CSRF. Ngay cả khi bạn có bảo vệ CSRF, kẻ tấn công vẫn có thể đi trên một phiên với XSS và XmlHttpRequest (HttpOnlyCookies sẽ ngăn chặn một hijack đầy đủ). "Remember Me" tạo ra các mối đe dọa khác như xss, csrf, sniffing nghiêm trọng hơn. Miễn là các lỗ hổng này đã được giải quyết, thì bạn không nên có vấn đề với tin tặc thế giới thực.

Cách tiếp cận dễ nhất (và an toàn) để triển khai tính năng "nhớ tôi" là sửa đổi thời gian chờ của phiên để làm cho nó rất lớn (một vài tháng). Nếu hộp kiểm "nhớ tôi" được bỏ chọn thì lưu trữ biến phiên với thời gian chờ mới (1 ngày kể từ khi đăng nhập). Hãy nhớ rằng ngay cả khi cookie bị xóa bởi trình duyệt khi nó bị đóng, phiên vẫn hoạt động ở phía máy chủ. Nếu id phiên bị đánh cắp, thì nó vẫn có thể được sử dụng.

+0

Điều gì về một bộ lọc tùy chỉnh RememberMe hơn tạo ra một mã thông báo mới trên mỗi yêu cầu. Mã thông báo mới có thể có tuổi thọ ngắn, ví dụ: 20 phút. Nếu người dùng không làm gì, mã thông báo sẽ hết hạn. Nếu người dùng thực hiện một yêu cầu khác trong cửa sổ 20 phút, một cửa sổ 20 phút mới sẽ được tạo. Nếu phiên của người dùng bị đánh cắp bằng cách nào đó, việc thay đổi mật khẩu của người dùng sẽ vẫn làm mất hiệu lực bất kỳ mã thông báo hợp lệ nào trong tự nhiên ... suy nghĩ? –

+0

Tôi nhớ nơi tôi đã nghe ý tưởng này trước đây ... nó đòi hỏi sự tồn tại của mã thông báo cho một cơ sở dữ liệu, nhưng không phải là một HttpSession: http://jaspan.com/improved_persistent_login_cookie_best_practice Có lẽ tôi sẽ xem xét phân lớp PersistentTokenBasedRememberMeService trong Spring Bảo vệ. –

5

Bảo mật mùa xuân 3 không cung cấp cấu hình về cách tạo cookie.Bạn cần phải ghi đè lên hành vi mặc định:

import javax.servlet.http.Cookie; 
import javax.servlet.http.HttpServletRequest; 
import javax.servlet.http.HttpServletResponse; 
import org.springframework.security.web.authentication.rememberme.PersistentTokenBasedRememberMeServices; 

/** Cookie expires on session. */ 
public class PersistentTokenBasedRememberMeServicesCustom extends 
    PersistentTokenBasedRememberMeServices { 

    /** only needed because super throws exception. */ 
    public PersistentTokenBasedRememberMeServicesCustom() throws Exception { 
    super(); 
    } 

    /** Copy of code of inherited class + setting cookieExpiration, */ 
    @Override 
    protected void setCookie(String[] tokens, int maxAge, 
     HttpServletRequest request, HttpServletResponse response) { 
    String cookieValue = encodeCookie(tokens); 
    Cookie cookie = new Cookie(getCookieName(), cookieValue); 
    //cookie.setMaxAge(maxAge); 
    cookie.setPath("/"); 
    cookie.setSecure(false); // no getter available in super, so always false 

    response.addCookie(cookie); 
    } 
} 

Hãy chắc chắn rằng, bạn sử dụng này tùy PersistentTokenBasedRememberMeServices cho bạn rememberMeService bằng cách thêm tên lớp với nó là cấu hình đậu:

<beans:bean id="rememberMeServices" 
class="my.custom.spring.PersistentTokenBasedRememberMeServicesCustom"/> 
Các vấn đề liên quan