Estamos desarrollando una aplicación móvil con jQuery móvil y quiere autenticar al usuario mediante programación en un backend 3.1.x primavera configurar correctamente con la seguridad de la primavera.primavera: programáticamente ingrese
Una solicitud POST se envía al backend (usando jQuery's $ .post) que contiene un nombre de usuario y contraseña, el servidor luego verifica si las credenciales son correctas e inicia sesión en el usuario.
El servidor parece configurar correctamente la autenticación en SecurityContext, sin embargo, cuando realizamos una segunda solicitud al servidor (un $ .get a una página que requiere inicio de sesión) los detalles de seguridad no parecen recordarse y es anónimo token parece estar en el contexto.
Este es el método en el controlador que maneja el (comprobación de la contraseña eliminado por razones de brevedad) entrada:
@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;
}
}
Este es el otro método en el que se obtienen los DetallesUsuario fuera del contexto:
@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());
...
configuración de seguridad
primavera:
<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>
Esto debería funcionar de acuerdo a la documentación de seguridad de primavera y otros recursos en línea. ¿Alguna idea sobre lo que podría estar mal?
La política de mantenimiento predeterminada de SecurityContextHolder es ThreadLocal. Cada solicitud se procesa en un nuevo hilo (en realidad no todos en el caso de grupos de hilos, pero esto no importa) y tiene su propia copia del contexto que contiene threadlocal. Por lo tanto, no se puede acceder a su Autenticación que está configurada en el método de inicio de sesión en el método getProjects (porque está en otro hilo). Debería guardar su información de autenticación en algún lugar (por ejemplo de sesión HTTP) y restaurar objetos de autenticación cada vez que la nueva solicitud llega al servidor (probablemente en filtro de servlet) –
Comprobar http://stackoverflow.com/questions/3923296/user-granted -autoridades-son-siempre-papel-anónima – axtavt
he implementado esta funcionalidad exacta utilizando la excelente respuesta unidos por axtavt. –