Spring Security на Wildfly: ошибка при выполнении цепочки фильтров

194

Я пытаюсь интегрировать расширение Spring Security SAML с Spring 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класса. Во время выполнения, атрибут FILTER_APPLIEDиз ServletRequestимеет нулевое значение, таким образом 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 Sever и Tomcat все работает совершенно нормально. Есть ли у вас идеи по решению этой проблемы?

vdenotaris
источник
2
В большинстве ситуаций SecurityContextHolderпосле запроса следует очистить. Единственная цель этого кода в том случае, если цепочка фильтров применяется более одного раза во время одного и того же запроса (в этом случае только исходная цепочка должна очищать контекст). Так что я не думаю, что это проблема.
Шон Овца
2
Кстати, такое поведение отключает процесс входа в систему каждый раз. Есть ли способ исправить это, например, путем правильной настройки моего программного обеспечения AS?
vdenotaris
1
Не уверен, что вы подразумеваете под этим. Какое поведение и как оно делает недействительным логин? Очистка контекста, когда поток завершает обработку запроса, является нормальным поведением - важно предотвратить утечку локальных данных потока обратно в пул потоков. На этом этапе контекст обычно должен кэшироваться в сеансе пользователя. Так что это не должно делать недействительным логин.
Шон Овца
2
Как описано выше, после единого входа сервер приложений очищает данные сеанса и данные аутентификации. Это происходит только с Wildfly: тот же код отлично работает с Tomcat.
vdenotaris
11
SecurityContextHolder.clearContext()не очищает данные сеанса Он удаляет ThreadLocalхранилище контекста до освобождения потока обратно в пул потоков. Я хочу сказать, что это всегда должно происходить в конце запроса, поэтому то, что вы видите, является нормальным явлением и вряд ли станет причиной вашей проблемы.
Шон Овца

Ответы:

7

Исследуя проблему, я заметил, что в запросе аутентификации есть некоторый беспорядок с файлами cookie и ссылками.

В настоящее время аутентификация 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 и очистки куки все должно работать как положено

nesteant
источник
Хорошее решение, если вы знакомы с WildFly и JBOSS, можете ли вы взглянуть на этот вопрос stackoverflow.com/questions/59006162/…
ZINE Mahmoud