Wednesday, April 12, 2017

Shibboleth Idp with External Authn Configuration

Shibboleth Idp comes with by default various flows like UsernamePassword, Mfa, X509, Kerberos, Spengo and various others flow but today I am going to discuss in details about one more flow which is also provided by Shibboleth Idp itself i.e External Flow

Use case:

Shibboleth Idp supports external Authn flow using which specific requirement can be fulfilled like your authentication database resides at some other location or some other servlet will do the authentication on the Idp’s behalf like authentication should be done at Facebook or Google side. All such scenario can be easily handled using External Authn flow.
Shibboleth team has already created document for the same which you can read it over here. I am writing this document to explain it in more details with example.

There are few predefined steps that we need to follow to add new custom flow in Shibboleth Idp as per Shibboleth guidelines. Let’s assume we have to create new flow named “Authn/Custom” in Shibboleth Idp. 

Here are the steps:

  • Copy opt\shibboleth-idp\conf\authn\ external-authn-config.xml and change it to custom-authn-config.xml and keep it under the same directory i.e. “opt\shibboleth-idp\conf\authn”.
  •  Replace all ‘External’ with ‘Custom’ in  custom-authn-config.xml file like 

<bean id="shibboleth.authn.External.externalAuthnPath" class="java.lang.String"
        c:_0="contextRelative:Authn/External" />                               
<bean id="shibboleth.authn.Custom.externalAuthnPath" class="java.lang.String"
        c:_0="contextRelative:Authn/Custom" />

  • Copy files from system to flow folder:

            cp system/flows/authn/external-authn-flow.xml flows/authn/Custom/Custom-flow.xml
            cp system/flows/authn/external-authn-beans.xml flows/authn/Custom/Custom-beans.xml

           Note: Make sure the name of the folder should be same as flow name. over here it is Custom  and Replace all ‘External’ with ‘Custom’ and edits the correct path too in both files.

  • Create a java project and create new Servlet CustomAuthnFlowServlet”. Servlet should contain final String key= ExternalAuthentication.startExternalAuthentication(httpRequest) and ExternalAuthentication.finishExternalAuthentication(key, httpRequest, httpResponse) and the authentication logic should be added between this statement and If you are doing any redirect then make sure you should persist the key as startExternalAuthentication & finishExternalAuthentication require the same key.
One more point principal should be set as httpRequest.setAttribute(ExternalAuthentication.PRINCIPAL_NAME_KEY, username) if you want to retrieve at Shibboleth SP side and in case of error mapped it with AUTHENTICATION_ERROR_KEY. httpRequest.setAttribute(ExternalAuthentication.AUTHENTICATION_ERROR_KEY, AUTHN_EXCEPTION);
  •  Add new Servlet mapping to web.xml file of Shibboleth Idp.

  •  Add your custom exception that we have created in our Servlet in  opt\shibboleth-idp\conf\authn\authn-events-flow.xml.
  •  Add below snippet to opt\shibboleth-idp\conf\errors.xml

<entry key="CustomException" value-ref="shibboleth.SAML2Status.AuthnFailed" />
        <entry key="AnotherException" value-ref="shibboleth.SAML2Status.AuthnFailed" />

Note: Map your Exception to correct value-ref as incase of error Idp will send this error Response to Shibboleth SP.
  • Register Custom Auth flow in conf/authn/external-authn-config.xml

  • Set idp.authn.flows as Custom (idp.authn.flows=Custom)
  • We can retrieve Principal at Shibboleth IdP side by adding below snipped in attribute-resolver.xml.
We are done here. Restart Shibboleth and hit target URL and you will see the SSO happening using your custom flow. Please feel free to comment or mail me for any queries.

Happy Coding!!!