Я использовал Spring Security 3.0 для нашего механизма входа в систему, используя специальную веб-страницу входа в систему. Теперь мне нужна эта веб-страница для входа, чтобы вместо этого было окно lightbox/popup на каждой веб-странице нашего сайта, где при входе в систему я получаю результат AJAX, был ли он успешным или нет. Какой лучший способ сделать это с помощью Spring Безопасность и Spring webmvc 3.0?
Ajax с помощью spring webMVC и spring безопасности
Ответ 1
На стороне клиента вы можете имитировать нормальное представление формы для своего URL-адреса входа через ajax. Например, в jQuery:
$.ajax({
url: "${pageContext.request.contextPath}/j_spring_security_check",
type: "POST",
data: $("#loginFormName").serialize(),
beforeSend: function (xhr) {
xhr.setRequestHeader("X-Ajax-call", "true");
},
success: function(result) {
if (result == "ok") {
...
} else if (result == "error") {
...
}
}
});
На стороне сервера вы можете настроить AuthenticationSuccessHandler
и AuthenticationFailureHandler
, чтобы вернуть значение вместо перенаправления. Поскольку вам, вероятно, также нужна обычная страница входа в систему (для попытки получить доступ к защищенной странице с помощью прямого URL-адреса), вы должны указать ajax-вызовы от обычных вызовов, например, используя заголовок:
public class AjaxAuthenticationSuccessHandler implements AuthenticationSuccessHandler {
private AuthenticationSuccessHandler defaultHandler;
public AjaxAuthenticationSuccessHandler() {
}
public AjaxAuthenticationSuccessHandler(AuthenticationSuccessHandler defaultHandler) {
this.defaultHandler = defaultHandler;
}
public void onAuthenticationSuccess(HttpServletRequest request,
HttpServletResponse response, Authentication auth)
throws IOException, ServletException {
if ("true".equals(request.getHeader("X-Ajax-call"))) {
response.getWriter().print("ok");
response.getWriter().flush();
} else {
defaultHandler.onAuthenticationSuccess(request, response, auth);
}
}
}
Ответ 2
Я сделал что-то подобное (спасибо axtavt):
public class AjaxAuthenticationSuccessHandler extends
SimpleUrlAuthenticationSuccessHandler {
public void onAuthenticationSuccess(HttpServletRequest request,
HttpServletResponse response, Authentication auth)
throws IOException, ServletException {
if ("XMLHttpRequest".equals(request.getHeader("X-Requested-With"))) {
response.getWriter().print(
"{success:true, targetUrl : \'"
+ this.getTargetUrlParameter() + "\'}");
response.getWriter().flush();
} else {
super.onAuthenticationSuccess(request, response, auth);
}
}}
Я решил расширить простой обработчик успеха для поведения по умолчанию для запросов, отличных от Ajax. Здесь XML, чтобы заставить его работать:
<http auto-config="false" use-expressions="true" entry-point-ref="authenticationProcessingFilterEntryPoint">
<custom-filter position="FORM_LOGIN_FILTER" ref="authenticationFilter" />
...
...
</http>
<beans:bean id="authenticationProcessingFilterEntryPoint"
class="org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint">
<beans:property name="loginFormUrl" value="/index.do" />
<beans:property name="forceHttps" value="false" />
</beans:bean>
<beans:bean id="authenticationFilter" class=
"org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter">
<beans:property name="authenticationManager" ref="authenticationManager"/>
<beans:property name="filterProcessesUrl" value="/j_spring_security_check"/>
<beans:property name="sessionAuthenticationStrategy" ref="sas" />
<beans:property name="authenticationFailureHandler" ref="failureHandler"/>
<beans:property name="authenticationSuccessHandler" ref="successHandler"/>
</beans:bean>
<beans:bean id="successHandler" class="foo.AjaxAuthenticationSuccessHandler">
<beans:property name="defaultTargetUrl" value="/login.html"/>
</beans:bean>
<beans:bean id="failureHandler" class="foo.AjaxAuthenticationFailureHandler" />