Custom admin flows
There may be situations in which you need to create a custom admin flow. Uses cases for this my vary, but for my organization’s purpose, we wanted to be able to see all the current lockouts and fetch additional details about each. The current admin flow for this doesn’t provide a listing of all the lockouts, only basic details about a specific one (and the ability to increment the lock counter or clear the lock). So we copied a lot of the code to develop our own custom version.
For purposes of this article, we will list the requirements for creating a basic admin flow called “mycustomflow”. The purpose of the flow is arbitrary and not detailed in this article. We will also be packaging the necessary files into an extension jar file that is added to the idp.war via placing it in edit-webapp/WEB-INF/lib. All of this could also be done by defining a plugin, but for simplicity’s sake, this article will ignore that concept.
The following wiki pages discuss some of the specifics of what is required knowledge prior to implementing a custom admin flow:
This article discusses how to create IdP extensions.
ExtensionsConceptsThis article discusses the basics of how to create a custom web flow. It’s fairly general and it applies to both profile/login flows as well as admin flows.
SpringConfiguration | Spring Web FlowThis article briefly discusses admin flows but does not go into detail regarding how one would go about creating one, hence the need for this How-to.
Administration | Programming Guide to Administrative Flows
Instructions
The steps in this How-to are targeted for version 4.1+ of the IdP. They are simplified and do not show the entire content of the necessary files because they assume that you have a good understanding of how to create custom web flows and what the content of the typical custom flow config file(s) need to contain. Refer to the Spring Web Flow article mentioned above for details.
Create the XML files required for the flow (mycustomflow-flow.xml, mycustomflow-beans.xml) which will get packaged in your extension jar into META-INF/net/shibboleth/idp/flows/admin/mycustomflow. Its worth noting that these files don’t need to be packaged in the extension jar - they can also exist in main IdP flow configuration directory: conf/flows. You don’t even need both of these files, you can define your beans in the –flow.xml file if you want. The content of these files will vary depending on your use case, but there are a few important things you need:
Give an organization-unique profile ID to your admin flow in the –beans.xml file with an XML bean definition. The bean id must be called “shibboleth.AdminProfileId”:
<bean id="shibboleth.AdminProfileId" class="java.lang.String" c:_0="http://my.organization.org/flows/mycustomflow"/>
The exact name doesn’t matter very much (its just a string), but it’s a good idea to make it a URI. Just don’t try to make it something that the IdP predefines.
Ensure that your flow’s “parent” is defined in the –flow.xml file and is set to “admin.abstract”
<flow xmlns="http://www.springframework.org/schema/webflow" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=http://www.springframework.org/schema/webflow http://www.springframework.org/schema/webflow/spring-webflow.xsd" parent="admin.abstract">
Register the flow as an admin flow by adding a bean definition to your extension’s existing META-INF/net.shibboleth.idp/postconfig.xml file (create if needed). This file gets loaded after the IdP configuration is loaded.
<bean parent="shibboleth.AdminFlow" c:id="http://my.organization.org/flows/mycustomflow" p:loggingId="MyFlow" p:policyName="AccessByIPAddress" p:nonBrowserSupported="false" p:authenticated="false" p:resolveAttributes="false"/>
This bean could also be defined in conf/global.xml. The “id” MUST match the ID you gave to your “shibboleth.AdminProfileId” bean definition in step 1.
If you want, you can define the values for these bean properties in conf\admin\admin.properties and reference them via Velocity macro syntax:
p:loggingId="%{idp.myflow.logging:MyFlow}"
In order to register your flow as being a REST-ful resource, you need to define a "shibboleth.RESTFlows" bean as well. This is not 100% necessary if you want to fetch parameters from the normal HttpServletRequest query params (GET/POST), but if your flow wants to pull variables from the path (like a REST-resource would), it is required.
Create a postconfig.xml file that will get packaged in your extension jar into META-INF/net/shibboleth/idp/mvc with the following content. The “mycustomflow” text in the <value> element below needs to match your admin flow name.This could also be defined in conf/mvc-beans.xml if you have that file from a previous version of the IdP.
Its worth noting that along with these XML files, you will likely have a number of Java classes. You will almost certainly need one which actually performs most of the work of your flow related to reading the HTTP request and writing the HTTP response. This would need to extend net.shibboleth.idp.profile.AbstractProfileAction.