首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >将Waffle Spring Security XML配置迁移到Spring Boot

将Waffle Spring Security XML配置迁移到Spring Boot
EN

Stack Overflow用户
提问于 2015-02-10 21:03:46
回答 1查看 3.3K关注 0票数 4

我正在尝试以Spring Boot的方式将Waffle身份验证与Spring Security结合使用。预期结果是“如果协商失败,则阻止所有内容”。

Waffle项目为这种用例提供了一个configuration example (在本例中,如果协商失败,可以回退到简单的HTTP auth,这是我不需要的),假设配置是通过web.xml完成的。但是,尽管尝试了很多次,我还是不明白如何使用Boot和Java-only配置来将Waffle与Spring Security结合起来。我使用Spring Boot 1.2.1.RELEASE与starters web和安全性,Waffle版本是1.7.3。

我意识到这不是一个具体的问题,但是Spring论坛现在在这里重定向,而Waffle的人不知道Spring Boot。有人能帮我把XML Spring安全配置转换成Spring Boot吗?

第一步是声明过滤器链和上下文加载器侦听器。

代码语言:javascript
复制
<filter>
    <filter-name>springSecurityFilterChain</filter-name>
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
    <filter-name>springSecurityFilterChain</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>
<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>/WEB-INF/waffle-filter.xml</param-value> 
</context-param>
<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

我假设(我错了吗?)这已经由@EnableWebMvcSecurity处理了,所以这里没什么可做的。

下一步是声明几个提供者bean,因此我将其翻译为

代码语言:javascript
复制
<bean id="waffleWindowsAuthProvider" class="waffle.windows.auth.impl.WindowsAuthProviderImpl" />

<bean id="negotiateSecurityFilterProvider" class="waffle.servlet.spi.NegotiateSecurityFilterProvider">
    <constructor-arg ref="waffleWindowsAuthProvider" />
</bean>

<bean id="basicSecurityFilterProvider" class="waffle.servlet.spi.BasicSecurityFilterProvider">
    <constructor-arg ref="waffleWindowsAuthProvider" />
</bean>

<bean id="waffleSecurityFilterProviderCollection" class="waffle.servlet.spi.SecurityFilterProviderCollection">
    <constructor-arg>
        <list>
            <ref bean="negotiateSecurityFilterProvider" />               
            <ref bean="basicSecurityFilterProvider" />               
        </list>
    </constructor-arg>
</bean>

<bean id="waffleNegotiateSecurityFilter" class="waffle.spring.NegotiateSecurityFilter">
    <property name="Provider" ref="waffleSecurityFilterProviderCollection" />
</bean>

到这个

代码语言:javascript
复制
@Bean
public WindowsAuthProviderImpl waffleWindowsAuthProvider() {
    return new WindowsAuthProviderImpl();
}

@Bean
@Autowired
public NegotiateSecurityFilterProvider negotiateSecurityFilterProvider(final WindowsAuthProviderImpl windowsAuthProvider) {
    return new NegotiateSecurityFilterProvider(windowsAuthProvider);
}

@Bean
@Autowired
public BasicSecurityFilterProvider basicSecurityFilterProvider(final WindowsAuthProviderImpl windowsAuthProvider) {
    return new BasicSecurityFilterProvider(windowsAuthProvider);
}

@Bean
@Autowired
public SecurityFilterProviderCollection waffleSecurityFilterProviderCollection(final NegotiateSecurityFilterProvider negotiateSecurityFilterProvider, final BasicSecurityFilterProvider basicSecurityFilterProvider) {
    final SecurityFilterProvider[] securityFilterProviders = {
            negotiateSecurityFilterProvider,
            basicSecurityFilterProvider
    };
    return new SecurityFilterProviderCollection(securityFilterProviders);
}

@Bean
@Autowired
public NegotiateSecurityFilter waffleNegotiateSecurityFilter(final SecurityFilterProviderCollection securityFilterProviderCollection) {
    final NegotiateSecurityFilter negotiateSecurityFilter = new NegotiateSecurityFilter();
    negotiateSecurityFilter.setProvider(securityFilterProviderCollection);
    return negotiateSecurityFilter;
}

最后一步是配置sec:http部分。声明了一个入口点,并将filter放在BASIC auth filter之前。

示例:

代码语言:javascript
复制
<sec:http entry-point-ref="negotiateSecurityFilterEntryPoint">
    <sec:intercept-url pattern="/**" access="IS_AUTHENTICATED_FULLY" />
    <sec:custom-filter ref="waffleNegotiateSecurityFilter" position="BASIC_AUTH_FILTER" />
</sec:http>

<bean id="negotiateSecurityFilterEntryPoint" class="waffle.spring.NegotiateSecurityFilterEntryPoint">
    <property name="Provider" ref="waffleSecurityFilterProviderCollection" />
</bean>

我的引导翻译:

代码语言:javascript
复制
@Autowired
private NegotiateSecurityFilterEntryPoint authenticationEntryPoint;

@Autowired
private NegotiateSecurityFilter negotiateSecurityFilter;    

@Override
protected void configure(final HttpSecurity http) throws Exception {
    http
            .authorizeRequests().anyRequest().authenticated()
            .and()
            .addFilterBefore(this.negotiateSecurityFilter, BasicAuthenticationFilter.class)
            .httpBasic().authenticationEntryPoint(this.authenticationEntryPoint);
}

@Bean
@Autowired
public NegotiateSecurityFilterEntryPoint negotiateSecurityFilterEntryPoint(final SecurityFilterProviderCollection securityFilterProviderCollection) {
    final NegotiateSecurityFilterEntryPoint negotiateSecurityFilterEntryPoint = new NegotiateSecurityFilterEntryPoint();
    negotiateSecurityFilterEntryPoint.setProvider(securityFilterProviderCollection);
    return negotiateSecurityFilterEntryPoint;
}

运行此配置会导致奇怪的行为:有时NTLM被触发并成功,有时协商筛选器崩溃并显示“提供的令牌无效”错误(相同的凭据、用户、浏览器、配置)。

Provided example就像一个护身符,这让我觉得我的引导配置有问题。

感谢任何人的帮助!

EN

回答 1

Stack Overflow用户

发布于 2017-02-10 02:25:31

Spring Boot会自动注册所有的过滤bean,因此在这种情况下,NegotiateSecurityFilter最终会在过滤器链中出现两次。

您必须通过创建覆盖此行为的FilterRegistrationBean来禁用此特定筛选器的自动注册:

代码语言:javascript
复制
@Bean
public FilterRegistrationBean registration(NegotiateSecurityFilter filter) {
    FilterRegistrationBean registration = new FilterRegistrationBean(filter);
    registration.setEnabled(false);
    return registration;
}

此外,正如Dave Syer提到的,您应该使用ExceptionHandlingConfigurer设置身份验证入口点bean。

代码语言:javascript
复制
@Override
protected void configure(HttpSecurity http) throws Exception {
    http.exceptionHandling()
        .authenticationEntryPoint(authenticationEntryPoint);
    // ...
}
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/28432399

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档