需要使用另一个IDP实现支持身份验证/授权的IDP

时间:2014-11-20 22:10:27

标签: java saml saml-2.0 picketlink

除了标准的用户名/密码表单身份验证之外,我们还要求使用其他外部IDP来实现支持身份验证/授权的IDP。 picketlink是否支持这种情况?

以下是必需的组件:

  1. 依赖于我们的IDP的多个SP(让我们称之为IDP-Internal)进行身份验证。
  2. IDP-Internal应支持使用LdapLoginModule的用户名/密码表单身份验证以及针对不同用户组的DatabaseLogingModule。它还应该支持使用另一个IDP进行身份验证(让我们称之为IDP-External)
  3. IDP-External来自具有SAML扩展名的外部提供商。
  4. 我们目前使用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这样做?

0 个答案:

没有答案