Spring Boot中Spring Security的XML配置

Posted

技术标签:

【中文标题】Spring Boot中Spring Security的XML配置【英文标题】:XML configuration of Spring Security in Spring Boot 【发布时间】:2014-12-07 13:11:08 【问题描述】:

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

我的配置:

spring-boot 1.1.8.RELEASE spring-boot-starter-* 在 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 的配置没有加载,如果我有一个好的understanding from the documentation,,我应该在只使用普通弹簧时使用它,而无需启动。 (应配置过滤器)。我说的对吗?

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

【问题讨论】:

【参考方案1】:

我没有尝试过这个(因为 Java 配置确实没有什么是你不能做的),但你必须消除 Spring Boot 提供的WebSecurityConfigurers(和@EnableWebSecurity)。我认为这样做可能比它需要的更复杂(但同样没有人需要使用 XML)。您必须在您的@EnableAutoConfiguration 中排除SecurityAutoConfiguration,然后在出现问题时处理它们(例如,您可能仍然需要SecurityProperties 类型的bean,并且您可能无法在没有更多混乱的情况下使用执行器)。

我不确定您所说的“来自resources/WEB-INF/web.xml 的配置”是什么意思,因为a)它是一个Spring Boot 应用程序,b)即使它不存在也不会有resources/WEB-INF/web.xml

【讨论】:

我想知道如何从 Java 配置密码编码(例如 sha256)。我在手册中没有找到任何关于它的内容。我只是试图用 xml 提供一个可能的解决方案。 关于web.xml:我在项目中使用tomcat。作为 Web 容器,可以使用 web.xml 进行配置。 spring 安全文档提到了这个 conf 的使用:docs.spring.io/autorepo/docs/spring-security/4.0.0.CI-SNAPSHOT/… 顺便说一句,感谢您的回答。我真的很想有一种编程方式来配置密码编码:)。如果有办法,应该在spring boot文档中提到。 安全配置不是 Spring Boot 特性。 Spring Security 已经支持所有 Java 配置需求。你试过看那里吗? 在 Spring Boot 中使用 web.xml 并不是一个很好的选择,而且你有一个 SpringBootServletInitializer 所以你不需要它。【参考方案2】:

根据 Dave Syer 在最新版本的 spring boot 中的说法,配置 spring 安全性的最佳方法是使用 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);
        

    


【讨论】:

【参考方案3】:

我遇到了同样的问题,然后我更改了 XML 文件的路径并将其保留在 src/main/resources/spring 中。它工作正常。

@SpringBootApplication

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

【讨论】:

同意这个答案。 spring boot 中的配置更加以 java-class 为中心。但是,配置的某些部分仍然可以基于 XML。请参阅@Configuration class-centric use of XML with @ImportResource。

以上是关于Spring Boot中Spring Security的XML配置的主要内容,如果未能解决你的问题,请参考以下文章

Spring security @secure 不适用于角色层次结构

Grails Spring Core 安全插件 - 无法解析类

如何从另一个新的 Spring Boot 项目调用一个 Spring Boot 项目中存在的 Spring Boot api

spring-boot实战12:Spring Boot中使用JavaMailSender发送邮件

Spring Security常用过滤器介绍

如何在 spring-boot 中禁用 spring-data-mongodb 自动配置