no veo parecen encontrar un buen ejemplo/respuesta sobre cómo volver a enviar algunos datos de una petición Ajax cuando una sesión ha expirado. Devuelve el HTML de la página de inicio de sesión y quiero enviar json o un código de estado que puedo interceptar.Detectar espera de sesión en el Ajax Solicitud de Spring MVC
Respuesta
La forma más sencilla de hacer esto es usar un filtro en URL de sus peticiones AJAX.
En el siguiente ejemplo sólo estoy enviando 500 código de respuesta HTTP con un cuerpo de respuesta que indica el tiempo de espera de la sesión, pero se puede ajustar fácilmente el código de respuesta y el cuerpo a lo que es más adecuado para su caso ..
package com.myapp.security.authentication;
import org.springframework.web.filter.GenericFilterBean;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class ExpiredSessionFilter extends GenericFilterBean {
static final String FILTER_APPLIED = "__spring_security_expired_session_filter_applied";
@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
if (request.getAttribute(FILTER_APPLIED) != null) {
chain.doFilter(request, response);
return;
}
request.setAttribute(FILTER_APPLIED, Boolean.TRUE);
if (request.getRequestedSessionId() != null && !request.isRequestedSessionIdValid()) {
response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "SESSION_TIMED_OUT");
return;
}
chain.doFilter(request, response);
}
}
Aquí hay un enfoque que creo que es bastante simple. Es una combinación de enfoques que he observado en este sitio. Escribí una publicación en el blog al respecto: http://yoyar.com/blog/2012/06/dealing-with-the-spring-security-ajax-session-timeout-problem/
La idea básica es usar un prefijo url api (es decir,/api/secured) como se sugiere arriba junto con un punto de entrada de autenticación. Es simple y funciona.
Aquí está el punto de entrada de autenticación:
package com.yoyar.yaya.config;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint;
import javax.servlet.ServletException;
import javax.servlet.http.*;
import java.io.IOException;
public class AjaxAwareAuthenticationEntryPoint
extends LoginUrlAuthenticationEntryPoint {
public AjaxAwareAuthenticationEntryPoint(String loginUrl) {
super(loginUrl);
}
@Override
public void commence(
HttpServletRequest request,
HttpServletResponse response,
AuthenticationException authException)
throws IOException, ServletException {
boolean isAjax
= request.getRequestURI().startsWith("/api/secured");
if (isAjax) {
response.sendError(403, "Forbidden");
} else {
super.commence(request, response, authException);
}
}
}
Y esto es lo que pasa en su contexto XML de Spring:
<bean id="authenticationEntryPoint"
class="com.yoyar.yaya.config.AjaxAwareAuthenticationEntryPoint">
<constructor-arg name="loginUrl" value="/login"/>
</bean>
<security:http auto-config="true"
use-expressions="true"
entry-point-ref="authenticationEntryPoint">
<security:intercept-url pattern="/api/secured/**" access="hasRole('ROLE_USER')"/>
<security:intercept-url pattern="/login" access="permitAll"/>
<security:intercept-url pattern="/logout" access="permitAll"/>
<security:intercept-url pattern="/denied" access="hasRole('ROLE_USER')"/>
<security:intercept-url pattern="/" access="permitAll"/>
<security:form-login login-page="/login"
authentication-failure-url="/loginfailed"
default-target-url="/login/success"/>
<security:access-denied-handler error-page="/denied"/>
<security:logout invalidate-session="true"
logout-success-url="/logout/success"
logout-url="/logout"/>
</security:http>
Puedo usar la misma solución por @ Matt en el back-end. Si está utilizando angularJs en el extremo frontal, agregue el interceptor siguiente en $ http angular para permitir que el navegador haga una redirección a la página de inicio de sesión.
var HttpInterceptorModule = angular.module('httpInterceptor', [])
.config(function ($httpProvider) {
$httpProvider.interceptors.push('myInterceptor');
$httpProvider.defaults.headers.common["X-Requested-With"] = 'XMLHttpRequest';
})
.factory('myInterceptor', function ($q) {
return {
'responseError': function(rejection) {
// do something on error
if(rejection.status == 403 || rejection.status == 401) window.location = "login";
return $q.reject(rejection);
}
};
});
Tenga en cuenta que por debajo de la línea que se necesita sólo si está utilizando AngularJS después de la versión 1.1.1 (AngularJS removidos cabecera "X-solicitada-Con" de esa versión en adelante)
$httpProvider.defaults.headers.common["X-Requested-With"] = 'XMLHttpRequest';
En vista de que la totalidad de la presentes respuestas son unos pocos años ahora, voy a compartir mi solución que tengo actualmente trabajando en una aplicación de primavera de arranque RESTO:
@Configuration
@EnableWebSecurity
public class UISecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
...
http.exceptionHandling.authenticationEntryPoint(authenticationEntryPoint());
...
}
private AuthenticationEntryPoint authenticationEntryPoint() {
// As a REST service there is no 'authentication entry point' like MVC which can redirect to a login page
// Instead just reply with 401 - Unauthorized
return (request, response, authException) -> response.sendError(HttpServletResponse.SC_UNAUTHORIZED, authException.getMessage());
}
}
la premisa básica aquí es que puedo reemplazar el punto de entrada de autenticación que por defecto se emitir un redireccionamiento a mi página de inicio de sesión inexistente mi. Ahora responde enviando un 401. Spring también crea implícitamente un objeto JSON de respuesta de error estándar que devuelve también.
- 1. detectar redireccionamientos de dominios cruzados en la solicitud de ajax
- 2. AJAX con Spring MVC
- 3. Solicitud JSON con JQuery/Ajax con Spring
- 4. configurando el tiempo de espera de la sesión en Spring MVC
- 5. asp.net mvc sesión de tiempo de espera
- 6. Solicitud Spring MVC sin visualización
- 7. MVC 3/Jquery AJAX/Session expires/C# - Manejo del tiempo de espera de la sesión durng ajax call
- 8. Respuesta de tiempo de espera de sesión en AJAX
- 9. Spring Security, Spring MVC y Sesiones de inicio de sesión
- 10. ¿Se restablece el tiempo de espera de la sesión en cada solicitud?
- 11. Detectar una solicitud cancelada en ASP.NET MVC
- 12. Cómo almacenar la sesión en Spring MVC
- 13. ¿Cómo se manejan las solicitudes de Ajax en Spring MVC?
- 14. JSF 2, Spring Security 3.xy Richfaces 4 redireccionan a la página de inicio de sesión en el tiempo de espera de la sesión para las solicitudes ajax
- 15. ¿Cómo ejecuto una solicitud autenticada de AJAX sin restablecer el tiempo de espera de sesión de Tomcat?
- 16. Spring MVC + Ajax. Cómo mostrar los errores?
- 17. Tiempo de espera de la sesión Error AJAX en la aplicación Tapestry
- 18. jQuery Ajax Solicitud dentro de Ajax Solicitud
- 19. ¿Cómo detectar el tiempo de espera en una llamada AJAX (XmlHttpRequest) en el navegador?
- 20. Acceda a "Solicitud de carga útil" en Spring MVC Controller?
- 21. Cómo usar Ajax JQuery en Spring Web MVC
- 22. Asegurar una solicitud de Ajax
- 23. Pantalla de inicio de sesión en el resultado de Ajax - Asp.net Mvc
- 24. ¿Es seguro mantener viva la sesión con la solicitud ajax?
- 25. Validación en Spring MVC
- 26. Cómo hacer una solicitud de Ajax para iniciar sesión
- 27. Tiempo de espera de sesión en ASP.NET
- 28. spring ajax request
- 29. ASP.NET: cómo detectar el tiempo de espera de autenticación
- 30. Detectar llamada ajax, ASP.net
¿Dónde puedo añadir esto en el fichero de configuración de frijol? Intenté esto antes y tuve problemas con eso. No estoy seguro si lo configuré bien la primera vez. Esto parece estar en el camino correcto. –
Suponiendo que ha Spring Security configurado correctamente, sólo tiene que añadir este filtro en la cadena de filtros de seguridad en su applicationContext-security.xml: definir el filtro como una _ _ y añadirlo a la cadena mediante _ _ –
En su opinión, ¿cuál es el mejor lugar para inyectar este filtro con los otros filtros? El atributo de filtro personalizado tiene un antes/después de que contiene construido en filtros, http://static.springsource.org/spring-security/site/docs/3.0.x/reference/ns-config.html#ns-custom-filters . No quiero que se ejecute en todas las páginas a través de ajax, sino solo en páginas seguras como una sección de administrador. Definitivamente tengo que pegarle al filtro ahora, solo necesito asegurarme de que solo se ejecute en esas páginas seguras. ¡Después de eso, recibiste una respuesta ANSWER! –