除了标准的用户名/密码表单身份验证之外,我们还要求使用其他外部IDP来实现支持身份验证/授权的IDP。 picketlink是否支持这种情况?
以下是必需的组件:
我们目前使用picketlink(在picketlink样本之后)实施了SP和IDP-Internal。但是,IDP-Internal到IDP-External集成目前是使用一些hacky借来的代码来实现的,这些代码手工/解析SAML请求/响应(这里没有picketlink)。 我已经设法通过扩展picketlink的IDPWebBrowserSSOValve将这个hacky代码集成到IDP-Internal中。此自定义阀门从IDP-External解析传入的SAMLResponse,并使用SAML2LoginModule进行本地容器身份验证,类似于在SP端执行的操作。
这是定制阀门:
public class IDPInternalAuthentiationValve extends IDPWebBrowserSSOValve {
@Override
public void invoke(Request request, Response response) throws IOException, ServletException {
String samlResponseXML = request.getParameter(GeneralConstants.SAML_RESPONSE_KEY);
if (isNotNull(samlResponseXML)) {
// This is a SAML Response from IDP-External
// Parse SAML and get subjectName and roles
// Lookup subject in an internal database and get local roles
ServiceProviderSAMLContext.push(subjectName, combinedRoles);
// Authenticate locally using SAML2LoginModule
Principal principal = container.getRealm().authenticate(subjectName, ServiceProviderSAMLContext.EMPTY_PASSWORD);
ServiceProviderSAMLContext.clear();
Session session = request.getSessionInternal(false);
// Save the authenticated Principal in our session
session.setNote(Constants.FORM_PRINCIPAL_NOTE, principal);
String samlRequestFromSession = (String)session.getNote(GeneralConstants.SAML_REQUEST_KEY);
// This is the request from SP
if (isNotNull(samlRequestFromSession)) {
// Send a response back to SP using the principal created above
processSAMLRequestMessage(request, response);
}
} else {
// Username/password form authentication flow
super.invoke(request, response);
}
}
}
这个解决方案虽然有效,但感觉有些笨拙。有没有更好的方法来使用picketlink这样做?