2012-07-16 3 views
2

Java EE 6 (JSF CDI EJB)으로 동시 로그인 (동일한 사용자 및 패스)을 허용해서는 안되는 웹 응용 프로그램을 작성하고 있습니다.Java EE 6 동시 세션 및 공유

내가 좋아하는 것은 : 두 번 첫 번째 세션에서 사용자가 로그인 무효화해야하고 이전 세션 데이터 (포함 SessionScope 또는 Apache CODI에서 WindowScope 같은 다른 범위의 모든 CDI 콩이.) 전송됩니다

경우 새로운 세션.

그것은 당신이 지속적으로 같은 것을 전송할 것을 상상할 수 있듯이 자바 EE 6

이에 대한 고유의 메커니즘이 없습니다

+0

왜하지 이미 로그인 한 사용자의 로그인 페이지를 숨기고 * "이미 로그인했습니다. 로그 아웃을 원하시는 경우 로그 아웃하십시오. 다른 사용자로서의 ogin "* 또는 그와 같은 분별있는 것. – BalusC

+0

그게 그렇게 간단하지 않습니다. 사용자는 로그인을 신경 쓰지 않고 두 개의 다른 스테이션에서 작업하기를 원하기 때문입니다. 그는 그냥 같은 출력과 응용 프로그램의 동일한 상태를보고 싶어 – urbiwanus

+0

그럼 왜 첫 번째 세션을 무효화해야합니까? – BalusC

답변

0

내가 필터의 도움으로이 문제를 해결

공용 클래스 SessionReplicationFilter는 필터 {

를 구현

다음

}

관리자가 보인다는 공용 클래스 SessionReplicationManager {

private Map<String, HttpSession> map = new ConcurrentHashMap<String, HttpSession>(); 


public boolean checkExistingSession(String user, HttpSession session) { 
    if (map.keySet().contains(user)) { 
     if (!session.getId().equals(map.get(user).getId())) { 
      System.out.println("User already logged in "); 
      HttpSession oldSession = map.get(user); 
      // copies all attributes from the old session to the new session (replicate the session) 
      Enumeration<String> enumeration = oldSession.getAttributeNames(); 
      while (enumeration.hasMoreElements()) { 
       String name = enumeration.nextElement(); 
       System.out.println("Chaning attribut " + name); 
       session.setAttribute(name, oldSession.getAttribute(name)); 
      } 
      // invalidates the old user session (this keeps one session per user) 
      oldSession.invalidate(); 
      map.put(user, session); 
      return true; 
     } 
    } else { 
     System.out.println("Putting "+user+" into session cache"); 
     map.put(user, session); 
     return false; 
    } 
    return false; 
} 

}

그것은 코디와 아주 잘 작동

이 주석 ViewScoped 콩

하는 경우를 @ApplicationScoped 첫 번째 (AJAX) 요청마다 세션이 만료 된 예외가 발생하여 복원 세션 버튼을 사용하여 쉽게 처리 할 수있는 예외가 발생합니다.

viewscoped beans의 사소한 문제는 새 뷰 ID를 얻는 것입니다. 원점으로 다시 변경하면 모든 것이 잘 작동합니다.

것들 내가 추가해야합니다

  • 자동 로그 아웃 (아약스 폴링, WebSocket을 ...)
  • 모든 viewscoped-ID가이 댓글에 누락

를 저장하는 레지스트리의 일부 종류 :

  • web.xml을 구성

감사

+0

회신을 보는 사람은 이것이 미친 메모리 누수임을 알게되기를 바랍니다 (HttpSessions 맵은 결코 지워지지 않습니다). –

+0

당신 말이 맞아요. 여기에 sessionDestroyed 이벤트가있는 HttpSessionListener가 없습니다. 청취자는 맵에서 모든 유효하지 않은 세션을 제거합니다 (즉, 시간 초과, 로그 아웃 등) – urbiwanus

0

:-) 수배 세션 하이재킹 방식처럼 뭔가 하나의 세션에서 다른 세션으로의 유스 케이스 (예 : 체크 아웃 프로세스 열기)를 사용한다면 사용자의 GUI 상태를 으로 추적하면됩니다..

RESTful URL은 이상적인 방법입니다. 마지막 사용자 URL/사용자 작업 (예 : www.myapp.com/orders/new/12)을 유지하고 새 로그인시 다시 엽니 다.

DB에이를 유지하지 않으려면 응용 프로그램 범위 맵인 userid/url이 KISS 방식 일 수 있습니다.

+0

내 모든 사용 사례에서 이것이 작동하는지 잘 모르겠습니다. 그러나 나는 그것을 시도 할 것이다. – urbiwanus

+0

호기심에서 벗어나 - 당신은 어떤 시스템을 구축하고 있습니까? 상대적으로 짧은 시간 내에 다른 스테이션에 로그인하는 이유는 무엇입니까? –

+0

터미널이 다른 POS 시스템을 생각해보십시오. 나는 세부적으로 갈 수 없다. 죄송합니다. – urbiwanus

0

당신은 너무마다 하나

이 고려 (절차 로그의 시작 부분)에/다시 로그인, 현재의 세션이 무효화됩니다 로그온을 시도한다, 사용자에 대한 무 상태 빈을 사용할 수 있습니다 접근 방법의 종류 :

try {   
    session = request.getSession(); //the request is passed by another page or action 
    if(session.getAttribute("user") != null) { 

      //your code to forward or handle the existing user (re-log in/ do nothing etc.) 
}