Wildfly의 Spring Security : 필터 체인 실행 중 오류


194

Spring Security SAML ExtensionSpring Boot 와 통합하려고합니다 .

문제에 관해, 나는 완전한 샘플 응용 프로그램을 개발했습니다. 소스 코드는 GitHub에서 사용할 수 있습니다 :

SDK 내장 응용 프로그램 서버에서 실행되는 Spring Boot 응용 프로그램으로 실행하면 웹 응용 프로그램이 제대로 작동합니다.

불행히도 Undertow / WildFly 에서는 동일한 AuthN 프로세스가 전혀 작동하지 않습니다 .

로그에 따르면 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 이렇게 봄이 지워, 값을 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);
    }
}

VM웨어 vFabric TC를 끊다톰캣 , 모든 것을 완전히 잘 작동합니다. 이 문제를 해결하는 데 대한 아이디어가 있습니까?


2
대부분의 상황에서 SecurityContextHolder요청 후 삭제해야합니다. 해당 코드의 유일한 목적은 동일한 요청 동안 필터 체인이 두 번 이상 적용되는 경우입니다 (이 경우 원본 체인 만 컨텍스트를 지워야 함). 그래서 나는 그것이 문제라고 생각하지 않습니다.
양 Shaun the

2
BTW,이 동작은 매번 로그인 프로세스를 무효화합니다. 예를 들어 AS 소프트웨어를 올바르게 구성하여 수정하는 방법이 있습니까?
vdenotaris

1
이것이 무엇을 의미하는지 잘 모르겠습니다. 어떤 행동을하며 로그인이 어떻게 무효화됩니까? 스레드가 요청 처리를 마치면 컨텍스트를 지우는 것은 정상적인 동작입니다. 스레드 로컬 데이터가 스레드 풀로 다시 누출되는 것을 방지하는 것이 중요합니다. 이 시점에서 컨텍스트는 일반적으로 사용자 세션에 캐시되어야합니다. 따라서 로그인을 무효화해서는 안됩니다.
양 Shaun

2
위에서 설명한 것처럼 SSO 후에 Application Server는 세션 데이터와 인증 데이터를 지 웁니다. 이것은 Wildfly에서만 발생합니다. Tomcat에서도 동일한 코드가 올바르게 작동합니다.
vdenotaris

11
SecurityContextHolder.clearContext()세션 데이터를 지우지 않습니다. ThreadLocal스레드를 스레드 풀로 다시 릴리스하기 전에 컨텍스트 의 스토리지를 제거합니다 . 내 요점은 이것이 요청의 끝에서 항상 발생해야한다는 것이므로, 당신이보고있는 것은 정상이며 문제의 원인이 아닐 것입니다.
양 Shaun

답변:


7

문제를 조사한 결과 인증 요청에 쿠키 및 참조자가 엉망인 것으로 나타났습니다.

웹 애플리케이션 컨텍스트를 루트 컨텍스트로 변경하면 현재 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를 다시 시작하고 쿠키를 지우면 모든 것이 예상대로 작동합니다.


WildFly 및 JBOSS로 유명한 경우 좋은 솔루션 stackoverflow.com/questions/59006162/…
ZINE Mahmoud
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.