Spring Boot中Spring Security的XML配置

zea*_*eal 5 java spring spring-security spring-boot

我想将基于XML的配置用于Spring Security.第一个想法是使用SHA-256或任何其他散列函数用于用户密码.我找不到用普通java解决这个问题的好方法.所以我开始在xml中配置东西.当它开始变得有趣时,这就是重点.

我的配置:

  • spring-boot 1.1.8.RELEASE
  • spring-boot-starter-*1.1.8
  • Tomcat的嵌入,碧玉:8.0.8

弹簧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>
Run Code Online (Sandbox Code Playgroud)

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

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

但是我在任何pageload上都得到以下异常:

[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 
...
Run Code Online (Sandbox Code Playgroud)

所以看起来配置来自resources/WEB-INF/web.xml不加载,如果我从文档中有很好的理解,我应该在使用普通弹簧时使用它,而不需要启动.(应配置过滤器).我对吗?

为什么会发生这种错误?有没有更好的方法在spring-boot中使用基于xml的配置来实现spring-security?web.xml甚至可以通过tomcat加载吗?

zea*_*eal 0

根据Dave Syer在最新版本的 Spring Boot 中的说法,配置 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);
        }

    }

}
Run Code Online (Sandbox Code Playgroud)