首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Spring安全中的链式认证

Spring安全中的链式认证
EN

Stack Overflow用户
提问于 2014-07-04 08:41:55
回答 1查看 1.4K关注 0票数 1

我能在SpringSecurity3.2.4中链接多个AuthenticationEntryPoint实例吗?

我试图创建以下场景:

  • 使用Spring安全性保护某个URL
  • 使用的AuthenticationEntryPointLoginUrlAuthenticationEntryPoint
  • 管理界面可以在此URL下生成服务
  • 管理员可以选择使用CLIENT-CERT保护这些服务。

当用户试图访问安全URL时:

  1. 如果路径已经使用CLIENT-CERT进行了安全保护,那么除非它们提供了一个与UserService中的用户相对应的有效证书,否则身份验证将失败。标准的Spring安全x509身份验证。
  2. 一旦用户按照第一点进行了身份验证,或者如果CLIENT-CERT没有保护该URL,他们就会被定向到基于FORM的身份验证页面。
  3. 一旦他们成功地使用用户名和密码进行身份验证,他们就会被定向到登陆页面。

我正在使用clientAuth="want"运行Tomcat 7.0.54。这在一个“简单的”Spring安全设置中工作得很好--即将一个WebSecurityConfigurerAdapter设置为x509(),另一个设置为formLogin() (按这个例子 )。

因此,我想要一个流程流,如下所示:

我在使用DelegatingAuthenticationEntryPoint动态更改所使用的身份验证方法方面取得了一些成功,但是:

  • 当使用AntPathRequestMatcher/form/**映射到LoginUrlAuthenticationEntryPoint时,身份验证servlet (/j_spring_security_check)会给出HTTP404错误。
  • 当使用AntPathRequestMatcher/cert/**映射到Http403ForbiddenEntryPoint时,用户的详细信息不会从提供的客户端证书中提取,因此会产生HTTP403错误。

我也看不出如何强制用户进行两次身份验证。

我使用的是java-config,而不是XML。

我的代码:

我有一个DelegatingAuthenticationEntryPoint

代码语言:javascript
复制
@Bean
public AuthenticationEntryPoint delegatingEntryPoint() {
    final LinkedHashMap<RequestMatcher, AuthenticationEntryPoint> map = Maps.newLinkedHashMap();
    map.put(new AntPathRequestMatcher("/basic/**"), new BasicAuthenticationEntryPoint());
    map.put(new AntPathRequestMatcher("/cert/**"), new Http403ForbiddenEntryPoint());

    final DelegatingAuthenticationEntryPoint entryPoint = new DelegatingAuthenticationEntryPoint(map);
    entryPoint.setDefaultEntryPoint(new LoginUrlAuthenticationEntryPoint("/login"));

    return entryPoint;
}

还有我的configure

代码语言:javascript
复制
@Override
protected void configure(final HttpSecurity http) throws Exception {
    defaultConfig(http)
            .headers()
            .contentTypeOptions()
            .xssProtection()
            .cacheControl()
            .httpStrictTransportSecurity()
            .addHeaderWriter(new XFrameOptionsHeaderWriter(SAMEORIGIN))
            .and()
            .authorizeRequests()
            .accessDecisionManager(decisionManager())
            .anyRequest()
            .authenticated()
            .and()
            .httpBasic()
            .authenticationEntryPoint(delegatingEntryPoint())
            .and()
            .sessionManagement()
            .maximumSessions(1)
            .sessionRegistry(sessionRegistry())
            .maxSessionsPreventsLogin(true);
}

其中decisionManager()返回一个UnanimousBased实例。sessionRegistry()返回一个SessionRegistryImpl实例。这两种方法都是@Bean

我使用以下方法添加自定义UserDetailsService

代码语言:javascript
复制
@Autowired
public void configureAuthManager(
        final AuthenticationManagerBuilder authBuilder,
        final InMemoryUserDetailsService authService) throws Exception {
    authBuilder.userDetailsService(authService);
}

我使用BeanPostProcessor映射了一个自定义BeanPostProcessor,就像这个例子中的那样。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-07-04 12:52:51

链接多个入口点并不能真正工作。

这里您的最佳选择可能是自定义表单登录过程,以便在需要时(在验证用户之前)检查证书。这可能会简化总体配置。这与普通的表单登录设置是一样的。

X509过滤器是很小的所做的工作。例如,您可以重写attemptAuthentication方法,调用super.attemptAuthentication(),然后检查证书信息是否与返回的用户身份验证信息匹配。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/24570108

复制
相关文章

相似问题

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