Безопасный веб-метод RESTful в Spring MVC - PullRequest
2 голосов
/ 08 февраля 2012

У меня есть какой-то контроллер:

    @Controller
    public class DefaultController {

    @RequestMapping(value="/index.html", method=RequestMethod.GET)
        public String indexView(){
            return "index";
        }

    @RequestMapping(value="/some.action", method=RequestMethod.POST)
    @ResponseBody
        public MyObject indexView(some parametrs.... ){
            MyObject o= daoService.getO(id);
                    return o; 
        }
}

Я использую Spring Security:

<security:global-method-security secured-annotations="enabled" />
<security:http  auto-config="true" access-denied-page="/accessDenied.jsp">
  <security:form-login login-page="/login.html" login-processing-url="/login" authentication-failure-url="/login.html?login_error=1" default-target-url="/"/> 
  <security:http-basic/>
    <security:intercept-url pattern='/**' access='ROLE_USER' />
  <security:logout logout-url="/logout" logout-success-url="/"/>
  <security:remember-me services-ref="rememberMeServices"/>
    </security:http>

Теперь моя проблема заключается в следующем:

когдадоступ к /some.action с использованием AJAX без аутентифицированного пользователя Spring Security возвращает команду 301 (перенаправить на страницу запрещенного доступа).

Что мне нужно, даже если пользователь не аутентифицирован, чтобы вернуть 200 OK и отправить сообщение об ошибке аутентификации клиенту или событию или, в худшем случае, вернуть 400 что-то с ошибкой.

Я понимаю, что мне нужно создать собственный обработчик успешной аутентификации, но могу ли я это сделать и как применить этот обработчик к * .action URI?

1 Ответ

2 голосов
/ 01 марта 2012

Для аутентификации AJAX я добавил пользовательскую точку входа безопасности, чтобы проверить, аутентифицирован ли пользователь. Если они не, я посылаю им код ошибки 4xx. Затем при вызове Ajax я проверяю, возвращена ли ошибка, и если да, то перенаправляю их на свою страницу входа.

Вот фрагмент моей конфигурации безопасности.

<security:http entry-point-ref="myAuthenticationEntryPoint" auto-config="true" use-expressions="true">
...
...
</security:http>
<bean id="myAuthenticationEntryPoint" class="com.security.AjaxAuthenticationEntryPoint" >
        <property name="loginFormUrl" value="/login"/>
</bean>

Вот моя точка входа:

public class AjaxAuthenticationEntryPoint extends LoginUrlAuthenticationEntryPoint
{   
    @Override
    /**
     * This method only gets call when the user logs out or when the session is invalid
     * 
     * It checks to see if the request is an ajax request
     * if so then return an error
     * else then do the natural check 
     */
    public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException)
            throws IOException, ServletException 
    {                       
        if ("XMLHttpRequest".equals(request.getHeader("X-Requested-With"))) 
        {
            if (request.getSession() != null)
            {
                Object targetUrl = request.getSession().getAttribute(WebAttributes.SAVED_REQUEST);
                if (targetUrl != null)
                {                   
                    response.sendError(HttpServletResponse.SC_EXPECTATION_FAILED);                                      
                }
            }   
        }
        else
        {
            super.commence(request, response, authException);
        }

    }
}

Вот фрагмент моего вызова JQuery, перезагрузка приводит к появлению страницы входа.

error: function (xhr, textStatus, errorThrown) 
               {    
                    // 417 is sent from the server to indicate that
                    // page needs to be reloaded
                    //
                    if (xhr.status == 417)
                    {
                        xhr = null;
                        window.location.reload();                       
                    }
               }
...