在Spring Boot中使用XML配置Spring Security

6
我想使用基于XML的配置来实现Spring Security。首先考虑使用SHA-256或任何其他哈希函数来对用户密码进行加密。但是,我没有找到一个很好的方法来解决这个问题,所以我开始在xml中配置这些内容。这就是当它变得有趣的时候。
我的配置如下:
  • spring-boot 1.1.8.RELEASE
  • spring-boot-starter-* at 1.1.8
  • tomcat-embed-jasper:8.0.8
spring-security.xml:
<beans:beans xmlns="http://www.springframework.org/schema/security"
             xmlns:beans="http://www.springframework.org/schema/beans"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xmlns:jdbc="http://www.springframework.org/schema/jdbc"
             xsi:schemaLocation="http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
           http://www.springframework.org/schema/security
           http://www.springframework.org/schema/security/spring-security.xsd>

    <http pattern="/css/**" security="none"/>
    <http pattern="/login.html*" security="none"/>

    <http>
        <intercept-url pattern="/**" access="ROLE_USER" />
        <form-login login-page='/login.html'/>
    </http>

    <authentication-manager>

        <authentication-provider>
            <user-service>
                <user name="admin" password="admin"
                      authorities="ROLE_USER, ROLE_ADMIN"/>
                <user name="bob" password="bob"
                      authorities="ROLE_USER"/>
            </user-service>
        </authentication-provider>
    </authentication-manager>

</beans:beans>

我在类中加载XML文件,其中可以找到public static void main

@Configuration
@ComponentScan
@EnableAutoConfiguration
@Order(HIGHEST_PRECEDENCE)
@ImportResource({
        "/spring-security.xml"
})
public class PhrobeBootApplication extends SpringBootServletInitializer {
...
}

但是我在任何页面加载时都会遇到以下异常:

[ERROR] org.apache.catalina.core.ContainerBase.[Tomcat].[localhost].[/].[dispatcherServlet] - Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception
org.springframework.security.authentication.AuthenticationCredentialsNotFoundException: An Authentication object was not found in the SecurityContext 
...

看起来像是从resources/WEB-INF/web.xml的配置没有加载,如果我正确地理解了文档,我应该在仅使用普通的spring时使用它,而不是使用boot。(应该配置过滤器)。我是对的吗?
为什么会出现这个错误?有没有更好的方法在spring-boot中使用基于xml的spring-security配置?web.xml是否由tomcat加载?
3个回答

4

我之前也遇到了同样的问题,后来我将XML文件的路径更改为src/main/resources/spring,问题得到了解决。

@SpringBootApplication

@ImportResource("classpath:/spring/spring-security.xml")

同意这个答案。Spring Boot中的配置更加以Java类为中心。然而,一些配置仍然可以基于XML。请参见@Configuration class-centric use of XML with @ImportResource - Hong

1
我没有尝试过这个(因为使用Java配置你可以做任何事情),但是你需要消除Spring Boot提供的WebSecurityConfigurers(和@EnableWebSecurity)。我认为这样做可能比它需要的更复杂(但是没人需要使用XML)。你需要在@EnableAutoConfiguration中排除SecurityAutoConfiguration,然后处理随之出现的问题(例如,你可能仍然需要一个类型为SecurityProperties的bean,而且你可能不能使用Actuator,还需要进行一些深入的操作)。
关于“来自resources/WEB-INF/web.xml的配置”,我不确定你的意思,因为a)这是一个Spring Boot应用程序,b)即使不是,也不会有resources/WEB-INF/web.xml

我想知道如何从Java配置密码编码(例如sha256)。我在手册中没有找到任何相关信息。我只是尝试使用xml提供可能的解决方案。 - 4spir
关于web.xml:我在项目中使用tomcat。作为一个Web容器,它可以通过web.xml进行配置。Spring安全文档提到了这个配置的使用:http://docs.spring.io/autorepo/docs/spring-security/4.0.0.CI-SNAPSHOT/reference/htmlsingle/#ns-web-xml - 4spir
顺便说一下,谢谢你的回答。我真的很希望有一种编程方式来配置密码编码 :)。如果有方法的话,它应该在 Spring Boot 文档中提到。 - 4spir
安全配置不是Spring Boot的功能。Spring Security已经支持所有Java配置需求。你试过去那里看看吗? - Dave Syer
在Spring Boot中,使用web.xml并不是一个很好的选择,因为你有SpringBootServletInitializer,所以你不需要它。 - Dave Syer
我明白了。您能否提供一个在Spring Security文档中描述密码加密(如何配置)的链接?我认为这样问题就可以解决了,我会接受这个答案。 - 4spir

0
根据最近版本的Spring Boot中Dave Syer的声明,配置Spring Security的最佳方式是使用Java配置。
我需要一个SHA-256编码器,但我没有找到任何简单且好的实现方案。您只需要使用passwordEncoder配置jdbcAuthentication即可。这真的非常简单:
@EnableWebSecurity
public class SpringSecurityConfigurer extends WebMvcConfigurerAdapter {

    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        registry.addViewController("/login").setViewName("login");
    }

    @Bean
    public ApplicationSecurity applicationSecurity() {
        return new ApplicationSecurity();
    }

    @Order(SecurityProperties.ACCESS_OVERRIDE_ORDER)
    protected static class ApplicationSecurity extends WebSecurityConfigurerAdapter {

        @Autowired
        private SecurityProperties security;

        @Autowired
        private DataSource dataSource;

        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http.authorizeRequests().antMatchers("/css/**").permitAll().anyRequest().fullyAuthenticated()
                    .and().formLogin().loginPage("/login").failureUrl("/login?error").permitAll()
                    .and().logout().logoutRequestMatcher(new AntPathRequestMatcher("/logout")).logoutSuccessUrl("/login");
        }

        PasswordEncoder sha256PasswordEncoder = new PasswordEncoder() {
            @Override
            public String encode(CharSequence rawPassword) {
                return Hashing.sha256().hashString(rawPassword, Charsets.UTF_8).toString();
            }

            @Override
            public boolean matches(CharSequence rawPassword, String encodedPassword) {
                return encodedPassword.equals(Hashing.sha256().hashString(rawPassword, Charsets.UTF_8).toString());
            }
        };

        @Override
        public void configure(AuthenticationManagerBuilder auth) throws Exception {
            auth.jdbcAuthentication()
                    .dataSource(this.dataSource)
                    .passwordEncoder(sha256PasswordEncoder);
        }

    }

}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接