2015-09-16 5 views
2

У меня есть приложение Java, которое подается Tomcat (то есть http://111.222.333.444:8080/myApp). Мой клиент хочет, чтобы это приложение отвечало на дружественный домен (то есть http://client.example.com). Я не очень хорошо с Apache или Tomcat, но я настроен Apache, как это сделать редирект:Apache перенаправляет приложение Tomcat с Spring Security

<VirtualHost 111.222.333.444:80> 
    ServerName client.example.com 
    ProxyRequests Off 
    ProxyPreserveHost On 
    <Proxy *> 
     Order deny,allow 
     Allow from all 
    </Proxy> 
    ProxyPass/http://111.222.333.444:8080/myApp/ 
    ProxyPassReverse/http://111.222.333.444:8080/myApp/ 
    ProxyPassReverseCookieDomain 111.222.333.444 client.example.com 

    ProxyPass /login.html http://111.222.333.444:8080/login.html 
    ProxyPassReverse /login.html http://111.222.333.444:8080/login.html 
</VirtualHost> 

Это прекрасно работает, чтобы обслуживать приложение под http://client.example.com. Однако у меня есть страница входа в систему, использующая Spring Security. Вход в систему отлично работает при доступе к нему с http://111.222.333.444:8080/myApp/login.html. Однако, когда я обращаюсь к нему с http://client.example.com/login.html и вводим правильное имя пользователя и пароль, он просто загружает страницу входа снова без ошибок.

My WebSecurityConfigurerAdapter выглядит так. Я не смог заставить его правильно загрузить страницу входа в систему, не передавая абсолютный URL-адрес в loginPage().

@Configuration 
@EnableWebMvcSecurity 
public class WebSecurityConfig extends WebSecurityConfigurerAdapter { 

    @Override 
    public void configure(WebSecurity web) throws Exception { 
     web.ignoring().antMatchers("/resources/**"); 
    } 

    @Override 
    protected void configure(HttpSecurity http) throws Exception { 
     http.csrf().disable(); 
     http.authorizeRequests() 
       .antMatchers("/admin/**") 
       .hasRole("ADMIN") 
       .and() 
       .formLogin() 
       .loginPage("http://client.example.com/login.html") 
       .and() 
       .logout() 
       .logoutSuccessUrl("/"); 
    } 

    @Autowired 
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { 
     auth.inMemoryAuthentication().withUser("admin").password("admin").roles("ADMIN"); 
    } 
} 

Моя страница Войти выглядит следующим образом:

<form name="f" method="post" action="/login.html">    
    <fieldset> 
     <legend>Please Login</legend>   
     <label for="username">User</label> 
     <select id="username" name="username"> 
      <option value="-1"></option> 
      <option value="admin">admin</option> 
     </select>   
     <label for="password">Password</label> 
     <input type="password" id="password" name="password"/> 
     <div> 
      <button type="submit" role="button"><span>Login</span></button> 
     </div> 
    </fieldset> 
</form> 

Так что, когда я посещаю http://client.example.com/admin/test.html, я правильно перенаправлены http://client.example.com/login.html. Но когда я пытаюсь войти в систему с «admin»/«admin», он просто загружает страницу входа снова на http://client.example.com/login.html без каких-либо ошибок. Журналы apache, журналы tomcat и журналы приложений не говорят мне ничего полезного.

Я думаю, что это связано с прокси-сервером Apache, который не играет хорошо с Spring Security, так как он работает, когда напрямую работает с приложением Tomcat, но я не уверен.

  1. Как я могу заставить Apache/Spring Security правильно обрабатывать логин? Я ожидаю, что приложение узнает, что я вошел в систему и направил меня на страницу администратора, к которой я пытался получить доступ.
  2. Есть ли способ заставить страницу входа работать без использования абсолютного URL-адреса в WebSecurityConfigurerAdapter?

Apache версии: Apache/2.2.31 версия (Unix)
Spring Security: 3.2.6.RELEASE
версия Tomcat: Apache Tomcat/7.0.42
Java Версия: Java 1.7

ответ

0

Я думаю, что ваша форма Войти действия не должны указывать на ваш Логин URL страницы, а

/j_spring_security_check 

UsernamePasswordAuthenticationFilter ищет что подражать а.е. тотализационный процесс. Если вы не хотите использовать/j_spring_security_check, вы можете сказать UsernamePasswordAuthenticationFilter искать другой URL, установив вызывающий метод loginProcessingUrl на вашем FormLoginConfigurer так:

formlogin() 
    .loginProcessingUrl('/custom_login_url') 
    .loginPage("http://client.domain.com/login.html") 
+0

Спасибо за рекомендации. Я действительно пробовал это раньше, не повезло. Когда я изменяю действие формы, чтобы быть/j_spring_security_check, форма отправляется в htt p: //client.domain.com/j_spring_security_check, и я получаю «405 Method Not Allowed». Я также попытался изменить поля на j_username и j_password, потому что это похоже на то, что ищет UserPasswordAuthenticationFilter, но это не помогло. – byrdley20

+0

У вас был отключен csrf в то время, когда у вас было установленное действие формы, равное «/ j_spring_security_check»? – fractonimbus

+0

Да, он был отключен.С тех пор я попытался включить его, который успешно отправляет токен csrf в POST, но затем я получаю «Запрещенный 403». Нужно ли настроить https для правильной настройки весны? – byrdley20

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