Ich habe eine funktionierende Lösung mit den Antworten von @John und @Arpad Link und @RobWinch Link
Ich verwende Spring Security 3.2.9 und jQuery 1.10.2.
Erweitern Sie die Klasse von Spring, um 4XX-Antworten nur von AJAX-Anfragen zu erhalten:
public class CustomLoginUrlAuthenticationEntryPoint extends LoginUrlAuthenticationEntryPoint {
public CustomLoginUrlAuthenticationEntryPoint(final String loginFormUrl) {
super(loginFormUrl);
}
// For AJAX requests for user that isn't logged in, need to return 403 status.
// For normal requests, Spring does a (302) redirect to login.jsp which the browser handles normally.
@Override
public void commence(final HttpServletRequest request,
final HttpServletResponse response,
final AuthenticationException authException)
throws IOException, ServletException {
if ("XMLHttpRequest".equals(request.getHeader("X-Requested-With"))) {
response.sendError(HttpServletResponse.SC_FORBIDDEN, "Access Denied");
} else {
super.commence(request, response, authException);
}
}
}
applicationContext-security.xml
<security:http auto-config="false" use-expressions="true" entry-point-ref="customAuthEntryPoint" >
<security:form-login login-page='/login.jsp' default-target-url='/index.jsp'
authentication-failure-url="/login.jsp?error=true"
/>
<security:access-denied-handler error-page="/errorPage.jsp"/>
<security:logout logout-success-url="/login.jsp?logout" />
...
<bean id="customAuthEntryPoint" class="com.myapp.utils.CustomLoginUrlAuthenticationEntryPoint" scope="singleton">
<constructor-arg value="/login.jsp" />
</bean>
...
<bean id="requestCache" class="org.springframework.security.web.savedrequest.HttpSessionRequestCache">
<property name="requestMatcher">
<bean class="org.springframework.security.web.util.matcher.NegatedRequestMatcher">
<constructor-arg>
<bean class="org.springframework.security.web.util.matcher.MediaTypeRequestMatcher">
<constructor-arg>
<bean class="org.springframework.web.accept.HeaderContentNegotiationStrategy"/>
</constructor-arg>
<constructor-arg value="#{T(org.springframework.http.MediaType).APPLICATION_JSON}"/>
<property name="useEquals" value="true"/>
</bean>
</constructor-arg>
</bean>
</property>
</bean>
Fügen Sie in meinen JSPs einen globalen AJAX-Fehler-Handler wie folgt hinzu aquí
$( document ).ajaxError(function( event, jqxhr, settings, thrownError ) {
if ( jqxhr.status === 403 ) {
window.location = "login.jsp";
} else {
if(thrownError != null) {
alert(thrownError);
} else {
alert("error");
}
}
});
Entfernen Sie außerdem vorhandene Fehlerbehandlungsprogramme aus AJAX-Aufrufen in JSP-Seiten:
var str = $("#viewForm").serialize();
$.ajax({
url: "get_mongoDB_doc_versions.do",
type: "post",
data: str,
cache: false,
async: false,
dataType: "json",
success: function(data) { ... },
// error: function (jqXHR, textStatus, errorStr) {
// if(textStatus != null)
// alert(textStatus);
// else if(errorStr != null)
// alert(errorStr);
// else
// alert("error");
// }
});
Ich hoffe, es hilft anderen.
Aktualisierung1 Ich fand heraus, dass ich die Option (always-use-default-target="true") in die form-login-Konfiguration aufnehmen musste. Dies war notwendig, da Spring, nachdem eine AJAX-Anfrage auf die Anmeldeseite umgeleitet wurde (aufgrund einer abgelaufenen Sitzung), sich die vorherige AJAX-Anfrage merkt und nach der Anmeldung automatisch dorthin umleitet. Dies führt dazu, dass das zurückgegebene JSON auf der Browserseite angezeigt wird. Das ist natürlich nicht das, was ich will.
Aktualisierung2 Anstelle der Verwendung von always-use-default-target="true"
Verwenden Sie @RobWinch Beispiel der Blockierung von AJAX-Anfragen aus dem requstCache. Dadurch können normale Links nach der Anmeldung zu ihrem ursprünglichen Ziel umgeleitet werden, aber AJAX-Anfragen gehen nach der Anmeldung auf die Startseite.
1 Stimmen
(nicht eine Antwort als solche) - Ich habe dies in der Vergangenheit durch Bearbeiten der Jquery-Bibliothek und Hinzufügen einer Prüfung für die Login-Seite auf jedem XHR abgeschlossen getan. Nicht die beste Lösung, weil es jedes Mal getan werden müsste, wenn Sie aktualisieren, aber es löst das Problem.
1 Stimmen
Siehe dazugehörige Frage: stackoverflow.com/questions/5941933/
0 Stimmen
El
HttpContext.Response.AddHeader
und prüfen Sie den Erfolg von ajaxsetup6 Stimmen
Warum kann der Server nicht 401 zurückgeben? In diesem Fall können Sie ein globales $.ajaxSetup haben und den Statuscode verwenden, um die Seite umzuleiten.
1 Stimmen
Dieser Link doanduyhai.wordpress.com/2012/04/21/ gibt mir die richtige Lösung
0 Stimmen
Schauen Sie sich bitte an diese Antwort .