我正在尝试让集群 SSO 在 JBoss EAP 6.3.2(相当于 JBoss AS 7.4.x(中工作,我有会话复制工作正常,但是 SSO(用户主体复制(并非在所有情况下都有效。
当我使用在具有适当角色<auth-constraint>
的<security-contraint>
内保护的 servlet 时,它可以正常工作。
但是,对于不受保护的 servlet,SSO 在我第一次访问受保护的页面之前不起作用,这似乎启动了 SSO,然后 infinispan 在集群中找到用户主体。
这是一个问题,因为我有许多页面的行为与您是否登录都不同。
我有一个狡猾的解决方法,我在阀门内调用reauthenticateFromSSO
,但是直到后续请求才起作用(我认为我在链中为时已晚(。 我可能会做一个 servlet FORWARD 来解决这个问题,但它看起来很狡猾。
在独立内部.xml我尝试在<sso cache-container="web" cache-name="sso" reauthenticate="true"/>
行中设置reauthenticate=true
,但是每次我最终在群集中的不同服务器上结束时,这似乎都会导致它注销。
JBoss 内部是否有一些神奇的设置可以使其在不需要身份验证的页面上重新验证 SSO?
感谢@FedericoSierra的一些澄清,在super.invoke(request, response);
解决我的问题之前打电话给super.reauthenticateFromSSO
。我附上了下面的代码。
从理论上讲,检查request.getPrincipal() == null && ssoID != null
可能也足够了。
簇状SSOFailoverValve.java
package com.mycompany.valve;
import java.io.IOException;
import javax.servlet.ServletException;
import org.apache.catalina.authenticator.Constants;
import org.apache.catalina.connector.Request;
import org.apache.catalina.connector.Response;
import org.jboss.as.web.security.ExtendedFormAuthenticator;
import com.yourcompany.framework.Loggers;
/**
* Enables Clustered Single Sign On session failover for servlets that don't have any security defined in the web.xml
*/
public class ClusteredSSOFailoverValve extends ExtendedFormAuthenticator {
@Override
public void invoke(Request request, Response response) throws IOException, ServletException {
if (request.getSession(false) != null && request.getPrincipal() == null) {
// Try to find the session from Infinispan
// The REQ_SSOID_NOTE is set by org.jboss.as.web.sso.ClusteredSingleSignOn.invoke(Request, Response)
Object ssoID = request.getNote(Constants.REQ_SSOID_NOTE);
if (ssoID != null && ssoID instanceof String) {
if (Loggers.securityLogger.isDebugEnabled()) {
Loggers.securityLogger
.debug("Found SSO Session ID ["
+ ssoID
+ "] with a null principal, so will attempt a re-authenticate from SSO to try and retrieve the user principal from the cluster");
}
super.reauthenticateFromSSO((String) ssoID, request);
if (Loggers.securityLogger.isDebugEnabled()) {
Loggers.securityLogger.debug("After re-authenticate from SSO with ssoID [" + ssoID + "], principal is now ["
+ request.getPrincipal() + "]");
}
}
}
super.invoke(request, response);
}
}
WEB-INF/jboss-web.xml
<?xml version='1.0' encoding='UTF-8' ?>
<jboss-web>
<security-domain>sso</security-domain>
<valve>
<class-name>com.mycompany.valve.ClusteredSSOFailoverValve</class-name>
</valve>
</jboss-web>