@John ve @Arpad bağlantısından ve @RobWinch bağlantısından yanıtları kullanarak çalışan bir çözüm aldım
Spring Security 3.2.9 ve jQuery 1.10.2 kullanıyorum.
Spring'in sınıfını yalnızca AJAX isteklerinden 4XX yanıtına neden olacak şekilde genişletin:
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>
JSP'lerimde, burada gösterildiği gibi genel bir AJAX hata işleyicisi ekleyin
$( document ).ajaxError(function( event, jqxhr, settings, thrownError ) {
if ( jqxhr.status === 403 ) {
window.location = "login.jsp";
} else {
if(thrownError != null) {
alert(thrownError);
} else {
alert("error");
}
}
});
Ayrıca, mevcut hata işleyicilerini JSP sayfalarındaki AJAX çağrılarından kaldırın:
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");
// }
});
Umarım başkalarına yardımcı olur.
Güncelleme1
Form-login yapılandırmasına seçeneği (her zaman use-default-target = "true") eklemem gerektiğini buldum. Bir AJAX isteği giriş sayfasına (süresi dolmuş oturum nedeniyle) yönlendirildikten sonra, Spring önceki AJAX isteğini hatırlar ve giriş yaptıktan sonra otomatik olarak yönlendirir. Bu, döndürülen JSON'un tarayıcı sayfasında görüntülenmesine neden olur. Tabii ki, istediğim gibi değil.
Güncelleme2always-use-default-target="true"
requstCache'den AJAX isteklerini engelleme @RobWinch örneğini kullanmak
yerine . Bu, normal bağlantıların giriş yaptıktan sonra orijinal hedeflerine yönlendirilmesine izin verir, ancak AJAX giriş yaptıktan sonra ana sayfaya gider.