Apache 使用 Spring Security 重定向到 Tomcat 应用程序

Posted

技术标签:

【中文标题】Apache 使用 Spring Security 重定向到 Tomcat 应用程序【英文标题】:Apache redirect to Tomcat app with Spring Security 【发布时间】:2015-12-13 17:10:37 【问题描述】:

我有一个由 Tomcat 提供的 java 应用程序(即http://111.222.333.444:8080/myApp)。我的客户希望这个应用程序响应一个友好的域(即http://client.example.com)。我不太擅长 Apache 或 Tomcat,但我这样配置 Apache 来进行重定向:

<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 访问它并输入有效的用户名和密码时,它只是再次加载登录页面而没有错误。

我的 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 应用程序时有效,但我不确定。

    如何让 Apache/Spring Security 正确处理登录?我希望该应用能够识别我已登录并将我引导至我尝试访问的管理页面。 有没有办法在不使用 WebSecurityConfigurerAdapter 中的绝对 URL 的情况下让登录页面正常工作?

Apache 版本:Apache/2.2.31 (Unix) Spring Security 版本:3.2.6.RELEASE Tomcat 版本:Apache Tomcat/7.0.42 Java版本:Java 1.7

【问题讨论】:

【参考方案1】:

我认为您的登录表单操作不应该指向您的登录页面 URL,而是

/j_spring_security_check

UsernamePasswordAuthenticationFilter 正在寻找它来模仿身份验证过程。如果您不想使用 /j_spring_security_check,您可以通过在 FormLoginConfigurer 上设置调用 loginProcessingUrl 方法来告诉 UsernamePasswordAuthenticationFilter 查找另一个 URL,如下所示:

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

【讨论】:

感谢您的推荐。实际上,我以前曾尝试过,但没有运气。当我将表单操作更改为 /j_spring_security_check 时,表单将发布到 htt p://client.domain.com/j_spring_security_check 并且我得到“405 Method Not Allowed”。我还尝试将字段更改为 j_username 和 j_password,因为这看起来像是 UsernamePasswordAuthenticationFilter 正在寻找的,但这没有帮助。 在将表单发布操作设置为“/j_spring_security_check”时是否禁用了 csrf? 是的,它已被禁用。我已经尝试启用它,它成功地在 POST 中发送了 csrf 令牌,但是我得到一个“403 Forbidden”。我需要配置 https 才能正确使用 spring 安全性吗?

以上是关于Apache 使用 Spring Security 重定向到 Tomcat 应用程序的主要内容,如果未能解决你的问题,请参考以下文章

web应用安全框架选型:Spring Security与Apache Shiro

ABAC 对 Spring Security 或 Apache Shiro 的支持

何时从容器管理的安全性转移到 Apache Shiro、Spring Security 等替代方案?

何时从容器管理的安全性转移到 Apache Shiro、Spring Security 等替代方案?

何时从容器管理的安全性转移到 Apache Shiro、Spring Security 等替代方案?

何时从容器管理的安全性转移到 Apache Shiro、Spring Security 等替代方案?