2017-02-14 22 views
0

Привет, Я строю проект с весенним ботинком & Весенняя безопасность. Теперь я хочу предоставить услугу login restfull для Jquery.ajax ({...}); И я хочу:Весенняя ботинок + безопасность + jquery ajax

  1. процесс запроса Войти с HTML-страницы (как и <form> представить).
  2. автоматический для проверки тайм-аута сеанса при запросе страницы HTML, переадресация таймаута на страницу входа.
  3. обрабатывает запрос на вход от Ajax.
  4. автоматический контроль состояния входа при запросе Ajax.

Я кодирования как этот

SecurityConfig

простирается от WebSecurityConfigurerAdapter

@Override 
protected void configure(HttpSecurity http) throws Exception { 
    http.csrf().disable(); 

    http.exceptionHandling().authenticationEntryPoint((request, response, authException) -> { 
     String requestType = request.getHeader("x-requested-with"); 
     if (!StringUtils.isEmpty(requestType)) { 
      response.setStatus(HttpServletResponse.SC_OK); 
      response.getWriter().print("{\"invalid_session\": true}"); 
      response.getWriter().flush(); 
     } else { 
      response.sendRedirect("/security/login"); 
     } 
    }); 

    http.authorizeRequests() 
      .antMatchers("/security/**").permitAll() 
      .antMatchers("/reader/**").hasRole("READER") 
      .anyRequest().authenticated() 

      // session time out 
      .and().sessionManagement().invalidSessionUrl("/security/session_timeout") 

      .and().cors() 

      // login 
      .and() 
      .formLogin() 
      .successHandler(successHandler) 
      .failureHandler(faildHandler) 
      .loginPage("/security/login") 
      .permitAll() 

      // logout 
      .and() 
      .logout().permitAll(); 
} 

@Override 
protected void configure(AuthenticationManagerBuilder auth) throws Exception { 
    auth.userDetailsService(readerRepository::findOne); 
} 

У меня есть два обработчика для обработки аутентификацииSuccess и AuthenticationFailure.

FailureHandler

простирается от SimpleUrlAuthenticationFailureHandler

@Override 
public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException { 
    System.out.println("Failed to auth."); 
    String requestType = request.getHeader("x-requested-with"); 
    if (!StringUtils.isEmpty(requestType)) { 
     response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); 
     response.getWriter().print("{\"success\": false}"); 
    } else { 
     setDefaultFailureUrl("/security/login?error=true"); 
     super.onAuthenticationFailure(request, response, exception); 
    } 
} 

SuccessHandler

простирается от SavedRequestAwareAuthenticationSuccessHandler

@Override 
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException { 
    System.out.println("Success to auth."); 
    String requestType = request.getHeader("x-requested-with"); 
    if (!StringUtils.isEmpty(requestType)) { 
     response.setStatus(HttpServletResponse.SC_OK); 
     response.getWriter().print("{\"success\": true}"); 
    } else { 
     setDefaultTargetUrl("/index/index"); 
     setAlwaysUseDefaultTargetUrl(true); 
     super.onAuthenticationSuccess(request, response, authentication); 
    } 
} 

Контроллер

база RequestMapping является '/ безопасность'

@RequestMapping(value = "/login") 
public String login(@RequestParam(value = "error", defaultValue = "false") boolean error, Model model) { 
    model.addAttribute("error", error); 
    return "login"; 
} 

@RequestMapping("/session_timeout") 
public void sessionTimeout(HttpServletRequest request, HttpServletResponse response) throws IOException { 
    System.out.println("session was timeout."); 
    if (request.getHeader("x-requested-with") != null) { 
     // handler for ajax 
     response.getWriter().print("{\"sessionTimeout\": true}"); 
     response.getWriter().close(); 
    } else { 
     response.sendRedirect("login"); 
    } 
} 

Когда я тестирую на странице (thymeleaf), все работало. но .. если используется JQuery Ajax. Issure:

Когда я Jquery.ajax ({}) API для отправки запроса, запрос не может быть добраться до сервера. Как написать ajax-запрос с jquery, я пробовал много методов Jquery, страница не имеет кода ответа в консоли. Является ли весенняя безопасность не поддерживать ajax?

+0

Можете ли вы предоставить свой javascript-код ajax, а также код статуса ответа сервера, пожалуйста? –

+0

Привет, вентилятор, см. Следующий ответ. – Tony

ответ

0

Спасибо, вентилятор, я исправил его.Я переписал аутентификации для входа:

UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(userDetails, userReq.getPassword(), userDetails.getAuthorities()); 
authenticationManager.authenticate(token); 
if (token.isAuthenticated()) { 
    SecurityContextHolder.getContext().setAuthentication(token); 
    return true; 
} 

Do аутентификации с AuthenticationManager и впрыскивается с весны.

Если у вас есть успех, я верну sessionid клиенту и клиенту, сохраненному в cookie, когда клиент выполнит запрос, клиент всегда ставит sessionid в конце URL-адреса, запрашиваемого ajax. Если не удалось выполнить авторизацию, я согласен с кодом согласованной ошибки.

например:

$.ajax({ 
    url: 'http://test:port/project/list;jsessionid=' + jessionid, 
    ... 
}) 

Но я не думаю, что так хорошо, как это работа. Это очень хлопотно. В клиенте мне нужно проверить каждый код ответа правильно или нет для каждого запроса. Есть ли лучшие способы решить эту проблему?

, кстати, клиент (браузер + Ajax) и сервер (Spring mvc) являются отдельными.

+0

Эй, Тони, я не думаю, что вам нужно поставить 'jsessionid' как часть запроса ajax. Файл cookie 'jsessionid' автоматически отправляется на сервер в качестве части заголовка запроса. У меня есть репозиторий github о загрузке весны и аутентификации JWT. Код может быть вам полезен. Вот URL-адрес репо: https://github.com/bfwg/springboot-jwt-starter –

Смежные вопросы