우리는 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>
이 따라 작동합니다 스프링 보안 문서 및 기타 온라인 리소스. 무엇이 잘못 될 수 있는지에 대한 아이디어가 있습니까?
SecurityContextHolder 기본 보유 정책은 ThreadLocal입니다. 모든 요청은 새 스레드에서 처리됩니다 (실제로 스레드 풀의 경우는 아니지만 문제가되지 않습니다). 스레드 로컬을 보유한 컨텍스트 사본을 소유해야합니다. 따라서 로그인 메소드에 설정된 인증은 다른 스레드에 있기 때문에 getProjects 메소드에서 액세스 할 수 없습니다. 인증 정보를 어떤 장소 (예 : http 세션)에 저장하고 새 요청이 서버에 도착할 때마다 인증 객체를 복원해야합니다 (아마도 서블릿 필터에 있음) –
Check http://stackoverflow.com/questions/3923296/user-granted -authorities-are-always-role-anonymous – axtavt
나는 axtavt로 링크 된 우수 답변을 사용하여이 정확한 기능을 구현했습니다. –