2015-02-10 180 views
4

我试图在Spring Boot时装中使用Spring Security的Waffle身份验证。预期的结果是“如果协商失败,则阻止所有事情”。将Waffle Spring Security XML配置迁移到Spring Boot

华夫格项目为这种用例提供​​了一个configuration example(假如配置是通过web.xml完成的,则在此示例中,如果协商失败,则返回到简单HTTP认证)。但是,尽管做了很多尝试,但我不明白如何使用Boot和Java-only配置将Spring Waverle与Spring Security配合使用。我使用的是Spring Boot 1.2.1.RELEASE,具有入门网站和安全性,Waffle版本为1.7.3。

我意识到这不是一个具体的问题,但Spring论坛现在重定向到这里,华夫饼干家伙不知道Spring Boot。有人可以帮我将XML Spring Security配置转换为Spring Boot吗?

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

<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 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> 

这个

@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部分配置。声明一个入口点,并在BASIC认证过滤器之前放置过滤器。

例子:

<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> 

我的引导翻译:

@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工程就像一个魅力,这让我觉得我的引导配置有问题。

任何帮助表示赞赏!

+0

如果过滤器启动,我认为它必须工作。我真的不知道任何关于松饼的事情(但看起来很有趣)。我发现您的代码和XML示例的一个区别是,您只将自定义入口点安装到HTTP基本过滤器中(而不是整个链中的异常处理)。可能你需要这样做,但我不知道它是否能解决所有问题。 – 2015-03-12 08:08:37

+0

感谢您的反馈。它并没有解决'无效令牌'的问题(我会再次为华夫饼团队提供支持),但这只是一个开始。 – LeRiton 2015-03-13 12:19:19

+0

这有什么更新?我有同样的问题(我认为)。在春天起动的华夫饼。它似乎可以在Chrome和其他浏览器中正常工作,但在使用IE11时会失败。服务器记录一个Win32Exception“提供给该函数的令牌无效” – Mike 2016-05-02 16:41:14

回答

0

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

你必须创建一个FilterRegistrationBean重写此行为,禁用自动注册此特定的筛选:

@Bean 
public FilterRegistrationBean registration(NegotiateSecurityFilter filter) { 
    FilterRegistrationBean registration = new FilterRegistrationBean(filter); 
    registration.setEnabled(false); 
    return registration; 
} 

此外,戴维Syer提到的,您应该设置使用ExceptionHandlingConfigurer认证切入点豆。

@Override 
protected void configure(HttpSecurity http) throws Exception { 
    http.exceptionHandling() 
     .authenticationEntryPoint(authenticationEntryPoint); 
    // ... 
} 
+0

感谢您的澄清! 不幸的是,我不再使用Waffle的任何项目,所以我无法测试您的建议。 如果有人可以尝试并告诉我们,我会很高兴批准你的答案。 – LeRiton 2017-02-28 15:24:20

相关问题