2012-03-28 27 views
22

Tôi đang thực hiện một ứng dụng có xác thực bởi OpenID bằng cách sử dụng Spring Security. Khi người dùng đăng nhập, một số quyền được tải trong phiên của anh ấy.Cách tải lại các cơ quan chức năng về cập nhật người dùng với Spring Security

Tôi có Người dùng có đầy đủ quyền có thể sửa đổi các cơ quan chức năng (thu hồi, thêm vai trò) của người dùng khác. Câu hỏi của tôi là, làm cách nào để thay đổi động cơ phiên của người dùng một cách linh hoạt? (không thể sử dụng SecurityContextHolder vì tôi muốn thay đổi một phiên Người dùng khác).

Cách đơn giản: phiên người dùng không hợp lệ, nhưng làm cách nào? Cách tốt hơn: làm mới phiên người dùng với chính quyền mới, nhưng làm cách nào?

Trả lời

6

Điểm mấu chốt - bạn sẽ có thể truy cập vào người dùng SecurityContext s.

Nếu bạn đang ở trong môi trường servlet và đang sử dụng HttpSession làm securityContextRepository trong securityContextPersistenceFilter của mình, thì có thể thực hiện với SessionRegistry của mùa xuân. Để buộc người dùng phải xác thực lại (nó phải tốt hơn thu hồi quyền đối với im lặng), hãy vô hiệu hóa HttpSession của anh ấy. Đừng quên để thêm HttpSessionEventPublisher để web.xml

<listener> 
    <listener-class> 
     org.springframework.security.web.session.HttpSessionEventPublisher 
    </listener-class> 
</listener> 

Nếu bạn đang sử dụng thread-địa phương securityContextRepository, sau đó bạn nên thêm bộ lọc tùy chỉnh để springSecurityFilterChain để quản lý SecurityContext s registry. Để thực hiện việc này, bạn phải sử dụng cấu hình springSecurityFilterChain đơn giản (không có các phím tắt không gian tên security). Với cấu hình đồng bằng với bộ lọc tùy chỉnh, bạn sẽ có toàn quyền kiểm soát xác thực và ủy quyền.

Một số liên kết, họ không giải quyết chính xác vấn đề của bạn (không OpenID), nhưng có thể hữu ích:

7

Cảm ơn, giúp tôi rất nhiều! Với SessionRegistry, tôi có thể sử dụng getAllPrincipals() để so sánh người dùng để sửa đổi với người dùng hiện hoạt đang hoạt động trong phiên. Nếu một phiên tồn tại, tôi có thể làm mất hiệu lực phiên của anh ta bằng cách sử dụng: expireNow() (từ SessionInformation) để buộc xác thực lại.

Nhưng tôi không hiểu tính hữu ích của securityContextPersistenceFilter?

EDIT:

// user object = User currently updated 
// invalidate user session 
List<Object> loggedUsers = sessionRegistry.getAllPrincipals(); 
for (Object principal : loggedUsers) { 
    if(principal instanceof User) { 
     final User loggedUser = (User) principal; 
     if(user.getUsername().equals(loggedUser.getUsername())) { 
      List<SessionInformation> sessionsInfo = sessionRegistry.getAllSessions(principal, false); 
      if(null != sessionsInfo && sessionsInfo.size() > 0) { 
       for (SessionInformation sessionInformation : sessionsInfo) { 
        LOGGER.info("Exprire now :" + sessionInformation.getSessionId()); 
        sessionInformation.expireNow(); 
        sessionRegistry.removeSessionInformation(sessionInformation.getSessionId()); 
        // User is not forced to re-logging 
       } 
      } 
     } 
    } 
} 
+0

'securityContextPersistenceFilter' theo mặc định sẽ đưa' SecurityContext' vào 'HttpSession' trong môi trường servlet. Vì bạn đã có sẵn mùa xuân 'SessionRegistry', bạn không cần phải tùy chỉnh bộ lọc này. – alexkasko

+0

Tôi đang ở trong môi trường servlet, tính hữu dụng của việc tùy chỉnh securityContextPersistenceFilter là gì? – Aure77

+0

các trường hợp khác nhau có thể, ví dụ: 'HttpSession's bị tắt và bạn không muốn lưu trữ luồng cục bộ. Vì vậy, bạn có thể sử dụng thực hiện của riêng bạn 'securityContextRepository'. Nếu 'HttpSession' lưu trữ phù hợp với nhu cầu của bạn, thì không có tính hữu ích. – alexkasko

22

Nếu bạn cần để tự động cập nhật một đăng nhập cơ quan chức năng của người dùng (khi này đã thay đổi, vì lý do gì), mà không cần phải đăng xuất và đăng nhập tất nhiên, bạn chỉ cần đặt lại đối tượng Authentication (mã thông báo bảo mật) trong Spring SecurityContextHolder.

Ví dụ:

Authentication auth = SecurityContextHolder.getContext().getAuthentication(); 

List<GrantedAuthority> updatedAuthorities = new ArrayList<>(auth.getAuthorities()); 
updatedAuthorities.add(...); //add your role here [e.g., new SimpleGrantedAuthority("ROLE_NEW_ROLE")] 

Authentication newAuth = new UsernamePasswordAuthenticationToken(auth.getPrincipal(), auth.getCredentials(), updatedAuthorities); 

SecurityContextHolder.getContext().setAuthentication(newAuth); 
+5

Vâng, nó gần như làm việc cho tôi. Biến "auth" này liên quan đến người dùng đã đăng nhập (tức là, tôi). Nếu tôi đăng nhập là "x" và tôi muốn thu hồi quyền "y", làm cách nào để nhận đối tượng của Xác thực từ người dùng cụ thể đó? – Paulo

Các vấn đề liên quan