2016-10-14 2 views
-2

Мы создали приложение, которое имитирует учебник шаблонов Spring Security - API Gate Pattern (https://spring.io/guides/tutorials/spring-security-and-angular-js/#_the_api_gateway_pattern_angular_js_and_spring_security_part_iv). Единственное отличие заключается в том, что мы используем базу данных MySQL, а не Redis.Spring Security - шаблон шлюза api - ошибка?

Использование localhost: 8080 в качестве корня, у нас есть localhost: 8080/login (страница входа), localhost: 8080/ui (клиент jQuery) и localhost: 8080/api (успокаивающие веб-службы, бизнес-логика и т. Д.)

Мы находим обработку сеанса и переадресацию на различные объекты, как и следовало ожидать. Значение сеанса создается как ожидалось, пересылка происходит так, как ожидалось, и т. Д. Существует одно исключение. Если я вхожу в систему, а затем выйдите из системы, а затем перейдите прямо к localhost: 8080/ui переведет меня на страницу входа. Вы входите в систему, и он перенаправляет вас обратно на локальный хост: 8080/ui, но отобразит «ACCESS DENIED»!

После отслеживания сеансов в базе данных и клиенте я обнаружил, что в базе данных есть два сеанса. Один с разрешениями и один без. Клиент сохраняет один без!

Неужели кто-нибудь еще сталкивается с этой проблемой? Есть ли способ обойти это?

Вот список шагов, которые я прошел, отслеживание сеансов базы данных и проверка клиента.

 
    session_id        principal_name Client 
    ------------------------------------------------------------ 
1) go to localhost:8080      
    9229045c-27e0-410a-8711-45c56576d647 -    X 

2) login     
    2275db1c-fca4-4a2f-be73-e440599499d6 root    X 

3) logout     
    cc917e68-b1c0-46a4-bbe3-6705ccf7a5fa -    X 

4) go to localhost:8080/ui --> forwards to localhost:8080/login 
    cc917e68-b1c0-46a4-bbe3-6705ccf7a5fa -    X 

5) login -> forwards to localhost:8080/ui -> Access Denied      
    90d7931d-b265-42e2-a225-286bcf7d159c -    X
d2fae0ac-9cf9-4287-8e38-51f64b0ab28d root

ответ

1

Хорошо, через много часов мы нашли решение того, что казалось непоследовательным поведением. Смысл иногда заключается в том, что вы входите в систему, и он сохранит правильный сеанс, и вы можете перейти на страницу localhost: 8080/ui и не получить страницу Whitelabel Error ... иногда вы все равно получите ее.

На сервере шлюза ...
1) Добавлено RequestMethod.POST

@Controller 
public class HomeController { 
    @RequestMapping(method = { RequestMethod.GET, RequestMethod.POST }, path = "/") 
    public String home() { 
     return "redirect:" + RequestMappings.UI; 
    } 
} 

2) Изменена настроить файл, в частности
а) добавил .successForwardUrl («/»)
б) добавляемые .loginProcessingUrl («/ Войти»)
с) добавляют .logoutSuccessUrl ("/ входа? выход из системы")

@Override 
protected void configure(HttpSecurity http) throws Exception { 
    http.headers() 
     .frameOptions().sameOrigin() 
    .and().formLogin() 
     .loginPage(RequestMappings.LOGIN) 
     .failureHandler(failureHandler()) 
     .successForwardUrl("/") 
     .permitAll() 
     .loginProcessingUrl("/login") 
    .and().logout() 
     .logoutSuccessUrl("/login?logout") 
    .and().authorizeRequests() 
     .antMatchers("/login").permitAll() 
     .antMatchers(RequestMappings.CHANGE_PASSWORD).permitAll() 
     .anyRequest().authenticated() 
    .and().csrf() 
     .csrfTokenRepository(csrfTokenRepository()) 
    .and().addFilterAfter(csrfHeaderFilter(), SessionManagementFilter.class); 
} 

Теперь все еще есть способ получить ошибку whitepage. Если, прежде чем войти в систему, вы перейдете непосредственно на localhost: 8080/ui .... Он перешлет вас на страницу localhost: 8080/login. Вы входите в систему. Вы будете на localhost: 8080/ui/глядя на все, как ожидалось. Если вы удалите последнюю косую черту, вы получите ошибку whitepage. Тогда оттуда в кэше могут попасться. Но если вы вернетесь к корню, вы можете войти в систему как обычно, и все будет работать нормально.

Я думаю, что происходит то, что pre-login localhost: 8080/ui call кешируется и потому что индекс.html-страница никогда не была загружена после того, как вы вошли в систему и вернулись, вы проходите проверку авторизации, но она пытается загрузить ... ну, ничего, а затем выдает ошибку. По крайней мере, это мое лучшее предположение.

В любом случае, приветствия! Спасибо за помощь, которая начала нас на правильном пути!

+0

Прохладный, рад, что вы нашли проблему! Обязательно отметьте правильный ответ здесь –

0

Скорее всего, когда вы идете непосредственно обратно в приложение UI, он по-прежнему использует старый идентификатор сеанса и когда вы войти, он перенаправляет вас к UI снова со старым идентификатором сеанса.

Это может быть также, что до сих пор старая проблема на сервере Tomcat, проверьте эту нить, чтобы увидеть, как правильно очистить куки: https://straypixels.net/clearing-cookies-in-spring-tomcat/

Bascially, расширить SimpleUrlLogoutSuccessHandler так:

public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) 
throws IOException, ServletException { 
    //This search may or may not actually be necessary, you might be able to just 
    // create a new cookie with the right name 
    for(Cookie cookie : request.getCookies()) { 
     if(cookie.getName() == "JSESSIONID") { 
      //Clear one cookie 
      cookie.setName(""); 
      cookie.setMaxAge(0); 
      cookie.setPath(request.getContextPath()); 
      response.addCookie(cookie); 
      //Clear the other cookie 
      Cookie cookieWithSlash = cookie.clone(); 
      cookieWithSlash.setPath(request.getContextPath() + "/"); 
      response.addCookie(cookieWithSlash); 
     } 
    } 
    //This is actually a filter; continue along the chain 
    super.onLogoutSuccess(request, response, authentication); 
} 
Смежные вопросы