2012-05-30 4 views
8

우리는 jQuery 모바일을 사용하여 모바일 앱을 개발 중이며 스프링 보안으로 올바르게 설정된 스프링 3.1.x 백엔드에서 프로그래밍 방식으로 사용자를 인증하려고합니다.스프링 보안 : 프로그래밍 방식으로 로그인

POST 요청이 사용자 이름과 암호가 포함 된 백엔드 (jQuery의 $ .post 사용)로 전송되면 서버는 자격 증명이 올바른지 확인하고 사용자로 로그인합니다.

서버가 SecurityContext에서 인증을 올바르게 설정 한 것으로 보이지만 서버에 두 번째 요청 (로그인이 필요한 페이지에 $ .get)하면 보안 세부 정보가 기억되지 않고 익명으로 보입니다 토큰이 컨텍스트에있는 것 같습니다.

은 로그인 (간결함을 제거 암호 확인)을 처리하는 컨트롤러의 방법입니다 :

@RequestMapping(value = "/login", method = RequestMethod.POST, produces = "application/json") 
@ResponseBody 
public Map<String, String> login(@RequestParam String username, @RequestParam String password, HttpServletRequest request) { 
    Map<String, String> response = new HashMap<String, String>(); 

    User u = userService.findByAccountName(username); 

    if (u != null && u.hasRole("inspector")) { 
     UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(username, password); 
     try { 
      Authentication auth = authenticationManager.authenticate(token); 
      SecurityContextHolder.getContext().setAuthentication(auth); 

      response.put("status", "true"); 
      return response; 
     } catch (BadCredentialsException ex) { 
      response.put("status", "false"); 
      response.put("error", "Bad credentials"); 
      return response; 
     } 
    } else { 
     response.put("status", "false"); 
     response.put("error", "Invalid role"); 
     return response; 
    } 
} 

이것은 우리가 문맥 밖으로 된 UserDetails를 얻을 수있는 다른 방법 :

@RequestMapping(value = "/project", method = RequestMethod.GET) 
@ResponseBody 
public String getProjects(HttpSession session) { 

    Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); 
    User u = userService.findByAccountName(((UserDetails) authentication.getPrincipal()).getUsername()); 
... 

봄 보안 구성은 :

<global-method-security pre-post-annotations="enabled"/> 
<http use-expressions="true" auto-config="true"> 

    <form-login login-processing-url="/static/j_spring_security_check" login-page="/" 
       authentication-failure-url="/?login_error=t"/> 

    ... 
    <intercept-url pattern="/api/**" access="permitAll"/> 
    ... 
    <remember-me key="biKey" token-validity-seconds="2419200"/> 
    <logout logout-url="/logout"/> 
</http> 

<authentication-manager alias="authenticationManager"> 
    <authentication-provider user-service-ref="udm"> 
     <password-encoder hash="md5"/> 
    </authentication-provider> 
</authentication-manager> 

이 따라 작동합니다 스프링 보안 문서 및 기타 온라인 리소스. 무엇이 잘못 될 수 있는지에 대한 아이디어가 있습니까?

+0

SecurityContextHolder 기본 보유 정책은 ThreadLocal입니다. 모든 요청은 새 스레드에서 처리됩니다 (실제로 스레드 풀의 경우는 아니지만 문제가되지 않습니다). 스레드 로컬을 보유한 컨텍스트 사본을 소유해야합니다. 따라서 로그인 메소드에 설정된 인증은 다른 스레드에 있기 때문에 getProjects 메소드에서 액세스 할 수 없습니다. 인증 정보를 어떤 장소 (예 : http 세션)에 저장하고 새 요청이 서버에 도착할 때마다 인증 객체를 복원해야합니다 (아마도 서블릿 필터에 있음) –

+1

Check http://stackoverflow.com/questions/3923296/user-granted -authorities-are-always-role-anonymous – axtavt

+0

나는 axtavt로 링크 된 우수 답변을 사용하여이 정확한 기능을 구현했습니다. –

답변

11

구성에 혼란 스럽습니다. 자신 만의 로그인 컨트롤러를 구현했지만, 스프링 보안의 form-login을 사용하고있는 것으로 보입니다. 나는 최근에 Spring Security + jquery로 ajax 로그인을 구현했다. 내 자신의 컨트롤러를 작성하는 대신 필자는 필자가 필요로하는 json 응답을 반환하기 위해 자신의 AuthenticationSuccessHandler 및 AuthenticationFailureHandler를 구현했습니다. 그냥 ...

public void onAuthenticationSuccess(HttpServletRequest request, 
     HttpServletResponse response, Authentication authentication) 
     throws IOException, ServletException { 
    response.getWriter().println("{\"success\": true}"); 
} 

public void onAuthenticationFailure(HttpServletRequest request, 
     HttpServletResponse response, AuthenticationException exception) 
     throws IOException, ServletException { 
    response.getWriter().println("{\"success\": false}"); 
} 

그런 다음 당신이 뭔가 등으로 형태-로그인 요소를 구성 할 수 있습니다 .... SimpleUrlAuthenticationSuccessHandler 및 SimpleUrlAuthenticationFailureHandler는만큼 간단 각 클래스, 뭔가에 onAuthenticationSuccess 및 onAuthenticationFailure 방법을 재정의 확장

<form-login login-processing-url="/static/j_spring_security_check" login-page="/" 
      authentication-success-handler-ref="ajaxAuthenticationSuccessHandler" 
      authentication-failure-handler-ref="ajaxAuthenticationFailureHandler" 
      authentication-failure-url="/?login_error=t"/> 
+0

이것은 완벽하게 ... 감사합니다. – HDave

+0

기꺼이 도와 주셨으면 합격으로 대답 해주세요 – hyness

+0

만약 내가 할 수만 있다면 ... – HDave

관련 문제