Spring Security บน Wildfly: เกิดข้อผิดพลาดขณะเรียกใช้เชนตัวกรอง


194

ฉันพยายามที่จะบูรณาการในฤดูใบไม้ผลิการรักษาความปลอดภัย SAML ขยายกับฤดูใบไม้ผลิ Boot

เกี่ยวกับเรื่องนี้ฉันได้พัฒนาแอปพลิเคชันตัวอย่างที่สมบูรณ์ ซอร์สโค้ดมันมีอยู่ใน GitHub:

ด้วยการเรียกใช้เป็นแอพพลิเคชั่น Spring Boot (ทำงานกับแอพพลิเคชั่นเซิร์ฟเวอร์ในตัว SDK) WebApp ทำงานได้ดี

แต่น่าเสียดายที่กระบวนการ AuthN เดียวกันไม่ได้ทำงานที่ทั้งหมดในสายน้ำ / WildFly

ตามบันทึกแล้ว IdP จะดำเนินการกระบวนการAuthNจริง: คำแนะนำในUserDetailsการปรับใช้แบบกำหนดเองของฉันนั้นดำเนินการอย่างถูกต้อง แม้จะมีโฟลว์การเรียกใช้งานสปริงไม่ได้ตั้งค่าและคงสิทธิพิเศษสำหรับผู้ใช้ปัจจุบันไว้

@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มีnullSecurityContextHolderค่าจึงล้างฤดูใบไม้ผลิ

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ทุกอย่างทำงานได้อย่างสมบูรณ์ คุณมีความคิดเกี่ยวกับการแก้ไขปัญหานี้หรือไม่?


2
ในสถานการณ์ส่วนใหญ่SecurityContextHolderควรล้างหลังจากการร้องขอ จุดประสงค์เดียวของรหัสนั้นคือในกรณีที่มีการใช้เชนตัวกรองมากกว่าหนึ่งครั้งในระหว่างคำขอเดียวกัน (ในกรณีนี้เฉพาะเชนดั้งเดิมเท่านั้นที่ควรล้างบริบท) ดังนั้นฉันไม่คิดว่าเป็นปัญหา
Shaun the Sheep

2
BTW พฤติกรรมนี้จะทำให้กระบวนการล็อกอินทุกครั้ง มีวิธีแก้ไขเช่นโดยการกำหนดค่าซอฟต์แวร์ของ AS อย่างถูกต้องหรือไม่
vdenotaris

1
ไม่แน่ใจว่าคุณหมายถึงอะไร พฤติกรรมอะไรและมันทำให้การเข้าสู่ระบบเป็นโมฆะได้อย่างไร การล้างบริบทเมื่อเธรดเสร็จสิ้นการจัดการคำร้องขอเป็นพฤติกรรมปกติ - เป็นสิ่งสำคัญเพื่อป้องกันการรั่วไหลของข้อมูลเธรดภายในกลับไปยังเธรดพูล ณ จุดนั้นบริบทมักจะถูกแคชไว้ในเซสชันของผู้ใช้ ดังนั้นจึงไม่ควรทำให้การเข้าสู่ระบบเป็นโมฆะ
Shaun the Sheep

2
ตามที่อธิบายไว้ข้างต้นหลังจาก SSO แล้ว Application Server จะล้างข้อมูลเซสชันและข้อมูลการตรวจสอบสิทธิ์ สิ่งนี้เกิดขึ้นกับ Wildfly เท่านั้น: รหัสเดียวกันใช้ได้ดีกับ Tomcat
vdenotaris

11
SecurityContextHolder.clearContext()ไม่ล้างข้อมูลเซสชัน มันลบที่ThreadLocalเก็บของบริบทก่อนที่จะปล่อยกระทู้กลับไปที่สระว่ายน้ำด้าย ประเด็นของฉันคือสิ่งนี้ควรเกิดขึ้นเมื่อมีการร้องขอดังนั้นสิ่งที่คุณเห็นเป็นเรื่องปกติและไม่น่าจะเป็นสาเหตุของปัญหาของคุณ
Shaun the Sheep

คำตอบ:


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.