수동

2

은 내가 웹 프로젝트를 빌드 할 스프링 security3 스프링 mvc3을 사용하여 인증 할 때 sessionRegistry와 사용자 로그인하기 것은 아닙니다. index.jsp라는 페이지가 있는데이 화면 상단에 에 로그인 사용자 이름과 온라인 사용자 수가 표시됩니다. 시스템에 로그인하는 2 가지 방법이 있습니다 :수동

'j_spring_security_check'수동으로 인증을
  • 아약스 로그인하여 로그인 페이지 사용 기본 구성 포스트에서

    나는 색인에 로그인 할 때 로그인 페이지를 사용하는 경우 페이지에서 온라인 정보와 사용자 이름 모두 올바르게 표시됩니다. 그러나 ajax login (수동으로 인증)을 사용하면 문제가 발생합니다. 온라인 사용자 수가 업데이트되지 않고 항상 사용자 이름을 표시 할 수 있지만 0이 표시됩니다. 컨트롤러의 부 :

    @Autowired 
    @Qualifier("authenticationManager") 
    AuthenticationManager authenticationManager; 
    @Autowired 
    SecurityContextRepository repository; 
    
    @RequestMapping(value="/ajaxLogin") 
    @ResponseBody 
    public String performLogin(
         @RequestParam("j_username") String username, 
         @RequestParam("j_password") String password, 
         HttpServletRequest request, HttpServletResponse response) { 
          UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(username, password); 
          try { 
           Authentication auth = authenticationManager.authenticate(token); 
           SecurityContextHolder.getContext().setAuthentication(auth); 
           repository.saveContext(SecurityContextHolder.getContext(), request, response); 
           logger.info("Authentication successfully! "); 
           return "{\"status\": true}"; 
          } catch (BadCredentialsException ex) { 
           return "{\"status\": false, \"error\": \"Bad Credentials\"}"; 
          } 
    } 
    

    스프링 security.xml 내가 가져 오는 데 사용

    <beans:beans xmlns="http://www.springframework.org/schema/security" 
    xmlns:beans="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://www.springframework.org/schema/beans 
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd 
    http://www.springframework.org/schema/security 
    http://www.springframework.org/schema/security/spring-security-3.0.3.xsd"> 
    
    <http auto-config="true" use-expressions="true">  
        <intercept-url pattern="/login" access="permitAll" /> 
        <intercept-url pattern="/index" access="permitAll" /> 
        <form-login login-page="/login" default-target-url="/index" 
         authentication-failure-url="/loginfailed" /> 
        <logout logout-success-url="/logout" /> 
    
        <session-management invalid-session-url="/index"> 
         <concurrency-control max-sessions="1" 
          error-if-maximum-exceeded="false" /> 
        </session-management> 
    </http> 
    
    <authentication-manager alias="authenticationManager"> 
        <authentication-provider> 
         <jdbc-user-service data-source-ref="dataSource" 
    
          users-by-username-query=" 
           select login_id,login_pwd, is_enabled 
           from t_user where login_id=?" 
    
          authorities-by-username-query=" 
           select u.login_id, r.authority from t_user u, t_roles r 
           where u.u_id = r.u_id and u.login_id =? " /> 
        </authentication-provider> 
    </authentication-manager> 
    

    방법은 온라인 로그인 사용자 수 :

    public class BaseController { 
        protected Logger logger = Logger.getLogger(this.getClass()); 
    
        @Autowired 
        SessionRegistry sessionRegistry; 
    
        @ModelAttribute("numUsers") 
        public int getNumberOfUsers() { 
         logger.info("in getNumberOfUsers() ..."); 
         return sessionRegistry.getAllPrincipals().size(); 
        } 
    } 
    

    코드 표시하는 데 사용 로그인 사용자 이름 :

    로그인 한 사용자의 수를 표시하는 데 사용
    <div> 
         <security:authorize ifAllGranted="ROLE_USER"> 
          <p><a href="#TODO">Welcome <security:authentication property="principal.username" />!</a> &nbsp;&nbsp;&nbsp; 
          <a href="<c:url value="/j_spring_security_logout" />">Logout</a></p> 
         </security:authorize> 
        </div> 
    

    코드 :

    <div style="color:#3CC457"> 
         ${numUsers} user(s) are logged in! 
        </div> 
    

    내가 수동으로 인증 할 때 때문에, 봄 보안 사용자에 대한 새로운 세션을 생성하지 않는 것이 같아요. 사용자 지정 SessionCounterListener를 작성하여 유효성을 검사합니다. -> 정상 로그 아웃 -> 아약스 로그인 -> 아약스 로그 아웃 정상적인 로그인 :

    public class SessionCounterListener implements HttpSessionListener { 
    private Logger logger = Logger.getLogger(this.getClass()); 
    private static int totalActiveSessions; 
    
    public static int getTotalActiveSession(){ 
         return totalActiveSessions; 
    } 
    
    @Override 
    public void sessionCreated(HttpSessionEvent event) { 
         totalActiveSessions++; 
         logger.info("sessionCreated - add one session into counter" + event.getSession().getId()); 
    } 
    
    @Override 
    public void sessionDestroyed(HttpSessionEvent event) { 
         totalActiveSessions--; 
         logger.info("sessionDestroyed - deduct one session from counter" + event.getSession().getId()); 
    } 
    

    }

    다음은 액션 시퀀스에 대한 로그 파일의 주요 내용이다.

    sessionDestroyed - deduct one session 1spueddcmdao019udc43k3uumw 
    sessionCreated - add one session 14nro6bzyjy0x1jtvnqjx31v1 
    sessionDestroyed - deduct one session 14nro6bzyjy0x1jtvnqjx31v1 
    sessionCreated - add one session e6jqz5qy6412118iph66xvaa1 
    

    사실, ajax login/logout은 출력을 제공하지 않습니다. 그래서 지금

    는 어떻게 올바른 로그인 사용자 카운트받을 수 있나요? 그리고 왜 다른 인증 방법은 세션을 다루는 다른 방법이 있습니까? 어떤 도움을 주시면 감사하겠습니다.

  • +0

    SessionUtils를 사용하십시오. 예를 들어보십시오 : http://stackoverflow.com/questions/1013032/programmatic-use-of-spring-security – Ritesh

    답변

    0

    스프링 spring-security.xml 파일에서 AJAX 인증 (/ajaxLogin)의 URL은 명시 적으로 허용되지 않습니다. 따라서 요청은 Spring에 의해 차단되어야합니다. 내가이 추가 제안 :

    <intercept-url pattern="/ajaxLogin" access="permitAll" /> 
    
    +0

    안녕하세요 @LaurentG, 귀하의 제안을 시도했지만 작동하지 않습니다./ajaxLogin을 사용하면 'Welcome [email protected]'이 이미 표시되었지만 사용자 수가 0 만 표시됩니다. 로그를 보면 시스템이 sessionCreated (HttpSessionEvent 이벤트)를 트리거하지 않습니다. 수동으로 인증 된 후 시스템은 동일한 세션 ID를 사용하지만 정상 로그인은 인증 후 새 세션 ID를 생성합니다. –

    3

    수동 SecurityContextPrincipal을 추가, 그것은 SessionRegistry에 사용자를 추가하지 않습니다. SessionRegistry에 사용자 세션을 수동으로 추가해야합니다.

    SecurityContextHolder.getContext().setAuthentication(auth); 
    sessionRegistry.registerNewSession(request.getSession().getId(), auth.getPrincipal()); 
    

    희망!