【问题标题】:Wildfly 上的 Spring Security:执行过滤器链时出错
【发布时间】:2023-03-12 11:01:01
【问题描述】:

我正在尝试将 Spring Security SAML ExtensionSpring Boot 集成。

关于这件事,我确实开发了一个完整的示例应用程序。其源代码可在 GitHub 上获得:

通过将其作为 Spring Boot 应用程序运行(针对 SDK 内置应用程序服务器运行),WebApp 可以正常工作。

很遗憾,同样的 AuthN 过程在 Undertow/WildFly 上根本不起作用。

根据日志,IdP实际上执行了AuthN过程:我自定义的UserDetails实现的指令正确执行。尽管有执行流程,但 Spring 不会为当前用户设置和保留权限。

@Component
public class SAMLUserDetailsServiceImpl implements SAMLUserDetailsService {

    // Logger
    private static final Logger LOG = LoggerFactory.getLogger(SAMLUserDetailsServiceImpl.class);

    @Override
    public Object loadUserBySAML(SAMLCredential credential)
            throws UsernameNotFoundException, SSOUserAccountNotExistsException {
        String userID = credential.getNameID().getValue();
        if (userID.compareTo("jdoe@samplemail.com") != 0) {     // We're simulating the data access.
            LOG.warn("SSO User Account not found into the system");
            throw new SSOUserAccountNotExistsException("SSO User Account not found into the system", userID);
        }
        LOG.info(userID + " is logged in");
        List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
        GrantedAuthority authority = new SimpleGrantedAuthority("ROLE_USER");
        authorities.add(authority);
        ExtUser userDetails = new ExtUser(userID, "password", true, true, true,
                true, authorities, "John", "Doe");
        return userDetails;
    }
}

在调试时,我发现问题依赖于FilterChainProxy 类。在运行时,ServletRequest 的属性 FILTER_APPLIED 具有 null 值,因此 Spring 清除了 SecurityContextHolder

private final static String FILTER_APPLIED = FilterChainProxy.class.getName().concat(".APPLIED");

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
        throws IOException, ServletException {
    boolean clearContext = request.getAttribute(FILTER_APPLIED) == null;
    if (clearContext) {
        try {
            request.setAttribute(FILTER_APPLIED, Boolean.TRUE);
            doFilterInternal(request, response, chain);
        } finally {
            SecurityContextHolder.clearContext();
            request.removeAttribute(FILTER_APPLIED);
        }
    } else {
        doFilterInternal(request, response, chain);
    }
}

VMware vFabric tc SeverTomcat 上,一切正常。你对解决这个问题有什么想法吗?

【问题讨论】:

  • 在大多数情况下,SecurityContextHolder 应在请求后清除。该代码的唯一目的是在同一请求期间多次应用过滤器链(在这种情况下,只有原始链应该清除上下文)。所以我认为这不是问题。
  • 顺便说一句,这种行为每次都会使登录过程无效。有没有办法修复它,例如通过正确配置我的 AS 软件?
  • 不确定你的意思。什么行为,以及它如何使登录无效?当线程完成处理请求时清除上下文是正常行为 - 必须防止将线程本地数据泄漏回线程池。此时,上下文通常应该缓存在用户的会话中。所以它不应该使登录无效。
  • 如上所述,在SSO之后,Application Server会清除session数据和auth数据。这只发生在 Wildfly 上:相同的代码在 Tomcat 上也能正常工作。
  • SecurityContextHolder.clearContext() 不清除会话数据。在将线程释放回线程池之前,它会删除上下文的ThreadLocal 存储。我的观点是,这应该总是在请求结束时发生,所以你看到的是正常的,不太可能是你的问题的原因。

标签: spring spring-security wildfly spring-saml undertow


【解决方案1】:

调查问题我注意到身份验证请求中的 cookie 和引用者有些混乱。

如果您将 web 应用程序上下文更改为根上下文,目前 wildfly 身份验证将起作用:

 <server name="default-server" default-host="webapp">
     <http-listener name="default" socket-binding="http"/>
     <host name="default-host" alias="localhost" default-web-module="sso.war"/>
 </server>

重新启动 wildfly 并清除 cookie 后,一切都应该按预期工作

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-10-01
  • 2013-09-30
  • 2018-07-08
  • 2013-06-16
  • 2020-11-04
  • 2015-02-19
  • 2020-08-04
相关资源
最近更新 更多