Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Enabling SAML-Based SSO With Remote EJB Through Picketlink

DZone's Guide to

Enabling SAML-Based SSO With Remote EJB Through Picketlink

In this quick tutorial, you'll learn how to add single sign-on capabilities to your Enterprise JavaBeans application using SAML and XML.

· Security Zone ·
Free Resource

Download Microservices for Java Developers: A hands-on introduction to frameworks and containers. Brought to you in partnership with Red Hat.

Let's suppose that you have a remote Enterprise JavaBeans (EJB) application where the EJB client is a service pack (SP) application in a Security Assertion Markup Language (SAML) architecture. You would like your remote EJB to be authenticated use the same assertion which was used for the SP.

Before proceeding with this tutorial, you should have a basic understanding of EJB and Picketlink.

I have developed a POC based on Picketlink. Below are the things I have done to achieve it.

  • Set Picketlink to sign response and assertion in identity provider (IDP) application.

    •  Configure: `SAML2SignatureGenerationHandler` like the following in picketlink.xml of IDP application.

    <Handler class="org.picketlink.identity.federation.web.handlers.saml2.SAML2SignatureGenerationHandler">
         <Option Key="SIGN_RESPONSE_AND_ASSERTION" Value="true"/>
     </Handler>
  • Set Picketlink to store SAML assertions in the http-session in the SP application. 

    • Configure:`SAML2AuthenticationHandler` like the following in the picketlink.xml file of the SP application.

    <Handler class="org.picketlink.identity.federation.web.handlers.saml2.SAML2AuthenticationHandler">
         <Option Key="ASSERTION_SESSION_ATTRIBUTE_NAME" Value="org.picketlink.sp.assertion"/>
     </Handler>
  • Configure the sp security-domain to look something like the below code, setting the flag “sufficient” for both the login module and for the IDP application. You can configure your customized login module or you can use any login module available in picketbox.

      <security-domain name="sp" cache-type="default">
         <authentication>
            <login-module code="org.picketlink.identity.federation.bindings.jboss.auth.SAML2LoginModule" flag="sufficient" />
            <login-module code="org.picketlink.identity.federation.bindings.jboss.auth.SAML2STSLoginModule" flag="sufficient">
                 <module-option name="roleKey" value="Role"/>
                 <module-option name="localValidation" value="true"/>
                 <module-option name="localValidationSecurityDomain" value="sp"/>
            </login-module>
          </authentication>
       </security-domain>

In your servlet (EJB client/SP application) you need to get the signed assertion and send it along with the EJB invocation for verification, like the code below. Here, I have used a ejb-remote application which is available in quickstart [1].

//Getting Signed SAML Assertion
public String getSignedAssertion(HttpServletRequest httpRequest) throws Exception {
         HttpSession session = httpRequest.getSession();
         String cachedSignedAssertion = (String) session.getAttribute("org.picketlink.sp.assertion.signed");
         if (cachedSignedAssertion == null) {
             Document assertion = (Document) session.getAttribute("org.picketlink.sp.assertion");
             String stringSignedAssertion = DocumentUtil.asString(assertion);
             System.out.println(stringSignedAssertion);
             return stringSignedAssertion;
         } else {
             System.out.println("...cached assertion...");
             return cachedSignedAssertion;
         }
     }

//EJB invocation
public void getInitialContext(String assertion, String username) throws Exception, NamingException {

         Properties props = new Properties();
         props.put("remote.connectionprovider.create.options.org.xnio.Options.SSL_ENABLED", "false");
         props.put(Context.URL_PKG_PREFIXES, "org.jboss.ejb.client.naming");
         props.put("remote.connections", "default");
         props.put("remote.connection.default.port", "4447");
         props.put("remote.connection.default.host", "10.10.10.10");
         System.out.println("Connecting...");
         props.put("remote.connection.default.username", username);
         props.put("remote.connection.default.password", assertion);
         props.put("remote.connection.default.connect.options.org.xnio.Options.SASL_POLICY_NOPLAINTEXT","false");
         props.put("remote.connection.default.connect.options.org.xnio.Options.SASL_POLICY_NOANONYMOUS","false");
         Context context = new InitialContext(props);
         RemoteCounter aa = (RemoteCounter) context.lookup("ejb:/jboss-ejb-remote-server-side//CounterBean!org.jboss.as.quickstarts.ejb.remote.stateful.RemoteCounter?stateful");
         System.out.println(aa.getCount());
         aa.increment();
         System.out.println(aa.getCount());
         System.out.println("EJB Executed... using SAML assertion");
     }

You can get the IDP and SP sample of Picketlink at [2] below:

  1. https://github.com/jboss-developer/jboss-eap-quickstarts/tree/6.4.x/ejb-remote
  2. https://github.com/jboss-developer/jboss-picketlink-quickstarts

That's it for today!

Download Building Reactive Microservices in Java: Asynchronous and Event-Based Application Design. Brought to you in partnership with Red Hat

Topics:
security ,single sign on ,saml ,xml ,authentication

Published at DZone with permission of

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}