【问题标题】:Cannot use spring-integration security with Spring Boot无法在 Spring Boot 中使用 spring-integration 安全性
【发布时间】:2015-09-11 02:49:37
【问题描述】:

我正在尝试通过以下方式在 Spring Boot 应用程序中使用 Spring Integration Security 配置:

<si-security:secured-channels access-decision-manager=
"accessDecisionManager">
    <si-security:access-policy pattern="requestChannel" receive-access="ROLE_USER"/>
</si-security:secured-channels>

此 XML 配置被插入到以下配置类中:

package demo.security.config;

import java.util.Arrays;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.integration.config.EnableIntegration;
import org.springframework.security.access.AccessDecisionManager;
import org.springframework.security.access.AccessDecisionVoter;
import org.springframework.security.access.vote.AffirmativeBased;
import org.springframework.security.access.vote.RoleVoter;

@Configuration
@EnableIntegration
// mentioned Spring Integration Security Config causing
// java.lang.IllegalArgumentException: A ServletContext is required to
// configure default servlet handling
@ImportResource({"classpath:springIntegrationSecurity.xml"})
public class SpringIntegrationSecurity {

@SuppressWarnings("rawtypes")
@Bean
public AccessDecisionManager accessDecisionManager() {
    RoleVoter roleVoter = new RoleVoter(); 
    roleVoter.setRolePrefix("");
    final AffirmativeBased acd = new AffirmativeBased(Arrays.<AccessDecisionVoter> 
        asList(roleVoter));
    return acd;
}

}

如果我在我的应用程序中包含提到的 Spring Integration Security XML 配置,它会崩溃:

Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'defaultServletHandlerMapping' defined in class path resource [org/springframework/boot/autoconfigure/web/WebMvcAutoConfiguration$EnableWebMvcConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.web.servlet.HandlerMapping]: Factory method 'defaultServletHandlerMapping' threw exception; nested exception is java.lang.IllegalArgumentException: A ServletContext is required to configure default servlet handling
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:599)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1119)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1014)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:504)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:303)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:299)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:755)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:757)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:480)
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:118)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:686)

似乎Spring Security Integration config是在ServletContext之前加载的,但我不知道如何克服这个问题...:(

我的 pom:

<?xml version="1.0" encoding="UTF-8"?>

http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0

<groupId>org.test</groupId>
<artifactId>spring-integration-security</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>

<name>spring-integration-security</name>
<description>Demo project for Spring Boot</description>

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.2.5.RELEASE</version>
    <relativePath/> <!-- lookup parent from repository -->
</parent>

<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <java.version>1.6</java.version>
</properties>

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-security</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-integration</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.security</groupId>
        <artifactId>spring-security-config</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.integration</groupId>
        <artifactId>spring-integration-security</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
</dependencies>

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
    </plugins>
</build>

有人可以帮忙吗?如果我省略 Spring Integration Security,我的应用程序可以正常工作...

【问题讨论】:

  • 为什么不使用没有xml的纯java配置?

标签: spring-integration


【解决方案1】:

问题可能与@ImportResource 解析的顺序有关。这就是为什么在大多数情况下 Spring Boot 都需要 Java Config。

例如,您的 Spring Integration Security 案例可以表示为:

@Bean
@SecuredChannel(interceptor = "channelSecurityInterceptor", receiveAccess = "ROLE_USER")
public MessageChannel requestChannel() {
    return new DirectChannel();
}

@Bean
public ChannelSecurityInterceptor channelSecurityInterceptor(AuthenticationManager authenticationManager,
                AccessDecisionManager accessDecisionManager) {
    ChannelSecurityInterceptor channelSecurityInterceptor = new ChannelSecurityInterceptor();
    channelSecurityInterceptor.setAuthenticationManager(authenticationManager);
    channelSecurityInterceptor.setAccessDecisionManager(accessDecisionManager);
    return channelSecurityInterceptor;
}

另一方面,请与您使用的 Spring Boot 和 Spring Integration 版本分享。

您介意用最新的 Spring Boot 1.3 M5 检查一下吗?

【讨论】:

  • 您好 Artem,我已经升级到 spring-boot 1.3 M5 并按照您的建议将 spring 集成安全 XML 配置重写为 Java 配置,它就像一个魅力!非常感谢...只是一个额外的问题,我仍然要配置 accessDecisionManager,为什么 spring-boot-starter-security 不将 accessDecisionManager 暴露为 SpringBean?
猜你喜欢
  • 2016-07-25
  • 1970-01-01
  • 1970-01-01
  • 2018-09-10
  • 1970-01-01
  • 2014-03-07
  • 2016-05-03
  • 2021-07-14
  • 2016-05-14
相关资源
最近更新 更多