OpenAM: New topic-based documentation

ForgeRock LogoOpenAM’s capabilities have grown significantly in the last few releases, with the result that even the product docs outgrew the old organization. Thanks to Chris Lee, Cristina Herraz, David Goldsmith, and Gene Hirayama, the draft docs are now arranged to make it easier to find just what you are looking for.

Instead of a guide-based doc set, what you see now are topic-oriented categories that bring you right to the features you want to use:

  • Try OpenAM (up and running quickly, ready for evaluation)
  • Access Management (authentication and single sign-on, authorization, RADIUS)
  • Federation (OAuth 2.0, OpenID Connect 1.0, SAML, STS)
  • User Services (self-registration, self-serve account and password management, self-serve sharing using UMA)
  • Installation and Maintenance (plan, install, set up, upgrade, and maintain access management services)
  • Extensibility (REST APIs, Java APIs and SPIs, C SDK)
  • Policy Agents (for enforcing policy on web sites and in Java web applications)

Each guide is written so that you find everything about a topic in one place. Are you focused on centralizing access policies for authorization? Read the Authorization Guide. Interested in granting access to account info for modern mobile and web applications using OpenID Connect? See the OpenID Connect 1.0 Guide. Participating in a federation of SAML 2 providers? Check out the SAML 2.0 Guide.

Those of you who knew the old layout intimately are probably going to wonder, “Where did you move my stuff?” In fact, there is a guide for that, too. Having Trouble Finding Something? indicates where your stuff went, with tables of correspondence from each section in the old layout to the topic in the new layout.

Great to see this leap forward towards a topic-based documentation set for OpenAM!


SiteMinder Policy conversion to OpenAM XACML

In this article I discuss migrating SiteMinder policies to OpenAM. I have laid out an approach and framework to make the conversion possible using XML parsing, XML codifying and custom metadata that is necessary to resolve embedded repository externalities in the SiteMinder policy definition. I have also written a Java-based program that uses the methodology discussed in this article to parse through the SiteMinder policy and resolve each policy construct to an OpenAM equivalent policy object. The program codifies the XACML output step-by-step and on completion, one is able to import the XACML policy set into OpenAM via the policy editor.

There are going to be some complications in your situation such as when converting whitelisted resource URI – that SiteMinder does not ‘trap’ in the policy definition- you will need to know which URI are not in your SM policy extract and allowed by default, and then go about creating or adding the same URI in a new or ‘converted’ OpenAM policy. You would then need to whitelist those URI by explicitly allowing access in OpenAM.

I begin by describing the general layout of an XPS domain export at a high level, and how different policy constructs in a SiteMinder policy map over to OpenAM.

Survey of SiteMinder Policy Objects

While there is not a one-to-one mapping for every policy construct, there is a logical mapping that is useful to achieve a first pass on the conversion. Some of the complications are elaborated on below.

CA.SM::Domain -> OpenAM Policy Set Definition

The CA.SM::Domain object is the parent object to several domain-specific properties such as Mode, Name and UserDirectoriesLink references. Nested directly under the Domain object are CA.SM::Realm,  CA.SM::Policy and CA.SM::Response objects.

CA.SM::Realm -> OpenAM Policy Resources

The Realm object includes properties that describe the AgentGroupLink and AuthScheme settings, session properties such as IdleTimeout, and among other things, the ResourceFilter that is the protected resource URI. Realm also contains a nested object, called the CA.SM::Rule with an associated XID that describes the Actions available for the ResourceFilter- such as GET, PUT and POST- and properties that describe regular expression matching, time restrictions, resource pattern and IsEnabled among other things.

CA.SM::Response -> OpenAM Response Attributes

Response object is a container for one or more name-value pairs, or ‘response attributes’ expected by the agent. These can be of type Web agent responses or RADIUS responses. This conversion article and the Java program are limited to handling only the Web agent responses currently.

The Response object has an associated XID, and includes properties that describe the authorization conditions when the response is applicable- such as AccessAccept and AccessChallenge- and properties for AgentTypeLink and Name.

CA.SM::ResponseAttr

Response also nests CA.SM::ResponseAttr objects, each with a unique XID, that each have properties for AgentTypeAttrLink- pointing to ReferenceObjects such as “WebAgent-HTTP-Header-Variable” indicating the means of transport for the response attributs- and also the Value of the response codified in the form of display-name=<%userattr=”profile-attribute-name”%>. Here it is assumed that the value is sourced from a user attribute, which is mostly the case, although several types of ResponseAttrs are possible, including user attribute as already mentioned, DN Attribute, Static values, Session Variable, etc.

CA.SM::Policy -> OpenAM Policy Definition

Nested under the Domain object, and at peer level to the Realm and Response objects is the CA.SM::Policy object that serves to tie together protected resource URI to the corresponding user audience, rules including actions, response objects and optionally, IP address restrictions and time restrictions for those URI.

CA.SM::PolicyLink

The Policy object container has one or more CA.SM::PolicyLink objects that can be thought of as associations between the protected resources and the responses configured for each of them. The PolicyLink objects each have CA.SM::ResponseLink and CA.SM::RuleLink properties.

CA.SM::ResponseLink and CA.SM::RuleLink

The ResponseLink is a pointer to the Response object definition, and the RuleLink is a pointer to the Rule definition stored inside a CA.SM::Realm object. When invoked for a specific Realm, the policy enforces the Rule Actions as well as the Response attributes in case the policy evaluation is successful.

CA.SM::UserPolicy

The Policy object also contains one or more CA.SM::UserPolicy objects that can be thought of as audience restriction conditions. The UserPolicy object has properties defining the FilterPath, which is a SQL query but one that could be used to locate a set of users this policy applies to. Another property is the UserDirectoryLink that is a pointer to the external repository that contains the user profile data, and specifically stores the XID of the ReferenceObject by the name CA.SM::UserDirectory.

References

Besides Domain objects, there are also reference objects at a peer level to Domain. The Reference object tree encapsulates all external information that the policy references.

CA.SM::UserDirectory

The user repository information is stored under the CA.SM::UserDirectory ReferenceObject that includes a NameSpace attribute- such as “ODBC:”- and Server name. As mentioned previously the UserPolicy object stores a reference to the UserDirectory object using a UserDirectoryLink.

The program relies on these user directory references to be resolved using a metadata container in OpenDJ.

CA.SM::AgentGroup

The AgentGroup object refers to the SiteMinder agent configurations that all protect the same resources. The attribute AgentTypeLink contains a value that is referenced from CA.SM::Response objects using the AgentTypeLink property tying the web agent to that particular response object. There could be one or more Agent Groups.

CA.SM::AgentTypeAttr

One or more of these Reference objects define in what form the agent expects the response objects to be returned. Two currently supported, and commonly used, values include “WebAgent-HTTP-Header-Variable” and “WebAgent-HTTP-Cookie-Variable”. These are available for use in accept or reject responses only in SiteMinder.

Some other Reference objects include CA.SM::AgentType, which describes the SM agent- basically a Web Agent. Another is the CA.SM::AuthScheme which includes details about the form of authentication such as Forms-based, Basic auth or API.

Conversion to OpenAM

Converting CA.SM::Domain and CA.SM::Realm objects

Simply parse out these objects from the SiteMinder policy extract and create OpenAM policy set XACML definitions.

A code sample to establish the proper order and parity between the XACML elements is shown here:

        Element target = doc.createElementNS("ns2", "ns2:Target");
 	Element anyOf_subject = getAnyOfSubjectTree(doc, xmlMap);
 	target.appendChild(anyOf_subject);

 	Element anyOf_resource = getAnyOfResourceTree(doc, xmlMap, resourceUri);
 	target.appendChild(anyOf_resource);
 		
  	Element anyOf_application = getAnyOfApplicationTree(doc, xmlMap);
       	target.appendChild(anyOf_application);
       	
       	Element anyOf_action = getAnyOfActionTree(doc, xmlMap, actions);
       	target.appendChild(anyOf_action);

A code sample for creating the Resource URI in XACML format is shown below:

private static Element getAnyOfResourceTree(Document doc, Map<String, String> xmlMap, List resourceUri) {
// many AnyOf elements to define subject, resources, actions, etc
  	Element anyOf = doc.createElementNS("ns2", "ns2:AnyOf");
  	for(String url : resourceUri) {
		Element allOf = doc.createElementNS("ns2", "ns2:AllOf");
		Element Match = doc.createElementNS("ns2", "ns2:Match");
		Match.setAttribute("MatchId", "urn:sun:opensso:entitlement:resource-match:application:"+xmlMap.get("PolicyId"));
	       	Element AttributeValue = doc.createElementNS("ns2", "ns2:AttributeValue");
                AttributeValue.setAttribute("DataType", "http://www.w3.org/2001/XMLSchema#string");
                AttributeValue.setTextContent("*://*:*" + url);
   	        Match.appendChild(AttributeValue);
	       	Element AttributeDesignator = doc.createElementNS("ns2", "ns2:AttributeDesignator");
	       	AttributeDesignator.setAttribute("Category", "urn:oasis:names:tc:xacml:3.0:attribute-category:resource");
	       	AttributeDesignator.setAttribute("AttributeId", "urn:oasis:names:tc:xacml:1.0:resource:resource-id");
	       	AttributeDesignator.setAttribute("MustBePresent", "true");
	       	AttributeDesignator.setAttribute("DataType", "http://www.w3.org/2001/XMLSchema#string");
	       	Match.appendChild(AttributeDesignator);
	       	allOf.appendChild(Match);
	       	anyOf.appendChild(allOf);
  	}
	return anyOf;
}

Converting the CA.SM::Rule.Actions objects

Here the challenge is to convert the ResourceFilters into ResourceURI objects in the XACML definition, and then add the relevant actions to those resource URI as defined in the CA.SM::Realm object definition. A sample method that adds basic actions to a policy is shown here:

private static Element getAnyOfActionTree(Document doc, Map<String, String> xmlMap, List actions) {
	// many AnyOf elements to define subject, resources, actions, etc
  		Element anyOf = doc.createElementNS("ns2", "ns2:AnyOf");
  		for(String action : actions) {
      		Element allOf = doc.createElementNS("ns2", "ns2:AllOf");
  		Element Match = doc.createElementNS("ns2", "ns2:Match");
  		Match.setAttribute("MatchId", "urn:sun:opensso:entitlement:action-match:application:"+xmlMap.get("PolicyId"));
	       	Element AttributeValue = doc.createElementNS("ns2", "ns2:AttributeValue");
	       	AttributeValue.setAttribute("DataType", "http://www.w3.org/2001/XMLSchema#string");
	       	AttributeValue.setTextContent(action);
		   Match.appendChild(AttributeValue);
	       	Element AttributeDesignator = doc.createElementNS("ns2", "ns2:AttributeDesignator");
	       	AttributeDesignator.setAttribute("Category", "urn:oasis:names:tc:xacml:3.0:attribute-category:action");
	       	AttributeDesignator.setAttribute("AttributeId", "urn:oasis:names:tc:xacml:1.0:action:action-id");
	       	AttributeDesignator.setAttribute("MustBePresent", "true");
	       	AttributeDesignator.setAttribute("DataType", "http://www.w3.org/2001/XMLSchema#string");
	       	Match.appendChild(AttributeDesignator);
	       	allOf.appendChild(Match);       	
	       	anyOf.appendChild(allOf);
  	}
  	return anyOf;
   }

Converting Policy bindings for CA.SM::Real,  CA.SM::Response and CA.SM::UserPolicy objects

This portion is the most complex in the conversion because linkages have to be parsed out of the SiteMinder policy extract and rendered as separate OpenAM policies in XACML format. In order to convert a CA.SM::Policy object the program needs to follow the following algorithm at the very at least and in order:

  1. Establish the linkages between the CA.SM::Realm objects and the CA.SM::Response objects using the PolicyLink binder object
  2. Resolve the Response object, dynamic key-value pairs, by either directly reading the data from an external repository, or converting the references attributes to LDAP specific attributes
  3. Resolve the Subject Restrictions manifest in the PolicyLink.UserPolicy by converting the SQL Query to an LDAP search filter
  4. Create one OpenAM policy under the previously established Policy Set per Realm-Response-UserPolicy linkage

These steps are necessary in order to preserve the linkage of specific resource URI being accessible over the policy decision and returning specific response attributes.

Parsing out the bindings between CA.SM::Realm and CA.SM::Response objects

Since not all CA.SM::Realm objects in the SiteMinder policy extract refer to all the CA.SM::Response objects it becomes necessary to collect those objects that are bound together and dispatch them into one OpenAM policy. This is because OpenAM ties together a group of protected resource URI to a group of subject conditions, environment conditions and response attributes.

Resolving the Response object into static or dynamic OpenAM Response Attributes

A design decision here could be that the response attributes will be pulled from a user repository such as OpenDJ, making the CA.SM::ResponseAttr.Value definitions very easy to resolve. After parsing the definitions that usually are of the form:

CL_Header=<%userattr="<%userattr="CL_Cookie_Value"%>|UID=<%userattr="DEF_PROFILE_ID"%>|State=<%userattr="ST"%>|City=<%userattr="ADDR_CITY"%>|AddressLine1=<%userattr="ADDR1"%>|AddressLine2=<%userattr="ADDR2"%>|CompanyName=<%userattr="COMPANY"%>

One could construct the response objects one by one, with the display attribute (left of the “=” sign) as key and user profile attribute within quotes above, as the value. Simplistic string split and parsing techniques could be used to achieve this. The mapping of user profile attributes shown here could also be stored as key-value pairs in a metadata container in OpenDJ:

 

meta

Here, the connection information is stored as an LDAP url in description, admin username in sn and password (hidden) in givenName. The mapping of the user attributes is stored in cn. Using this information the program resolves the key-value pairs from the source repository to that of the target repository schema and the resulting key-value pairs are codified as OpenAM Response objects into XACML, as shown:

urn:sun:opensso:entitlement:json-resource-attribute:com.sun.identity.entitlement.UserAttributes:<attr-name>

Resolve the Subject Restrictions manifest in the PolicyLink.UserPolicy

Converting subject conditions derived from CA.SM::UserPolicy objects such as this one:

userpolicy

..would involve the same framework presented above, except this time we will create an LDAP search filter from the SQL Query- again assuming we are seeking data from an LDAP repository- to ensure the policy is only fired when the subject condition is satisfied.

The program can also provide support for directly retrieving user profile attributes – either for Subject Restrictions presented above in the form of LDAP filters, or for dynamically creating the Response key-value pairs in XACML. The metadata can have connection information stored as shown above that could be used to achieve this external lookup.

 

A Beginners Guide to OpenIDM Part 5 – User Registration

Last time we configured mappings to create user objects in OpenIDM from a CSV file. This is commonly something you might do when populating a new identity system for the first time with your existing users, but what about getting new users into the system?

 

This blog we will take a look at configuring OpenIDM’s user self registration functionality and how we can perform some post processing on new users.Note: As many of you will be aware OpenIDM 4.5 has recently been released, for now I am going to continue using OpenIDM 4 for this blog but everything we talk about here is still applicable to 4.5, albeit with minor differences. I will likely move to OpenIDM 4.5 (or 5 even) when the beginners series is concluded.

User Registration

To turn on User Registration in OpenIDM, first log in as an administrator. Then navigate to Configure, then User Registration.

 

 You will see the User Registration configuration screen:

 

 

Now before we turn it on, log out and take a look at the OpenIDM user login screen: http://localhost.localdomain.com:8080/#login/

 

 

Just try to remember what it looks like right now, as it will change in a moment.

 

By default, User Registration is disabled. Lets enable it now. Click the “Enable User Registration” slider.

 

You can see that we have a number of Registration Steps. These can be turned on and off as you require, they can also be re-ordered by dragging and dropping.

 

Lets briefly talk about what each of these steps involves:
  • reCAPTCHA for Registration: Google’s “I am not a robot” dialog. To prevent automated bots registering.
  • Email Validation: User is sent an email, they must click a link in the email to progress registration. Verifying that they do indeed have access to the email account.
  • User Details: Simply allows you to modify the attribute on the user object associated with email address. By default this is mail but you might want to change it based on your managed user schema if you have made changes.
  • KBA Stage: Whether or not to enforce the use of Knowledge Based Authentication i.e. challenge questions and answers.
  • Registration Form: Here you can change the Identity Service URL to another managed object.
Note that you cannot configure everything in the UI, but we will shortly take a close look at how you can do that for Email Validation and KBA Stage if required.

 

So lets make sure that we have turned everything on in the as in the image above, except for reCAPTCHA. There is no save button. Toggling the sliders is sufficient here.

 

Now log out again, and take another look at the user login screen:

 

 

You should see we now have a link to Register. You can take a look but this won’t really work yet as we need to configure the steps, mainly Email Validation. So lets do that now.

 

Configuring Email Validation

We need to configure Email Validation and for this we are going to need an email server. If you have an email server, great. If not I suggest downloading something like https://mailtrap.io

 

Navigate to Configure, then System Preferences.

 

Select the Email tab.

 

 

Toggle the Enable Email slider, then Use SMTP Authentication.

 

 

Enter the host, port and credentials for your email server.

 

 

Then press Save.

Testing Registration

Logout of OpenIDM, navigate to the user login page: http://localhost.localdomain.com:8080/#login/ and select the Register link again.

 

Enter a test email address and press SEND.

 

All being well you should receive an email:

 

 

If you click the link, you will continue the registration process in OpenIDM.

 

Press Save, then you can complete your KBA questions:

 

 

When that is done, press Save for the final time and you should see that…

 

 

Registration is complete, if you Return to Login Page you should be able to log in with your new user ( by default this is the username we set on the 2nd page, not the email address ).

 

 

Customising Registration

As with everything ForgeRock every step of the Registration process can be customised, and you can use our REST API’s if you want to build a completely customised experience.

 

However there are two customisations which are frequently performed, let’s take a quick look at them now.

Customising the Registration Email

This can be easily achieved through the UI, if you return to Configure, then User Registration and edit the Email Validation step.

 

 

If you prefer you can also edit this directly via <openidm>/conf/selfservice-registration.json

 

Customising KBA Challenge Questions

If you want to edit KBA questions you need to do this directly by editing <openidm>/conf/selfservice.kba.json

This blog post was first published @ http://identity-implementation.blogspot.no/, included here with permission from the author.

Identity Disorder Podcast, Episode 4: The Rodeo of Things

identity-disorder-speakers-ep004

In episode 4, Daniel and Chris are pleased to welcome one of ForgeRock’s founders, Victor Ake. Victor gives his insight into the Identity of Things, talking the differences between constrained and unconstrained devices, how IoT brokers work, securing IoT devices using identity standards, and how microservices fit in to the picture. Other topics include airport hotels, wrestling, and–wait for it–the rodeo.

Episode Links:

ForgeRock IoT Page:
https://www.forgerock.com/solutions/devices-things/

ForgeRock Identity Summit in London and Paris
https://summits.forgerock.com/

All upcoming ForgeRock events:
https://www.forgerock.com/about-us/events/

Debugging OpenAM and OpenIDM

My background is the what I call the world of legacy identity, as such it took me a little while to get used to the world of ForgeRock, REST API’s and the like.


If you come from that world you may find debugging implementation issues with ForgeRock is a little different so I wanted to write up a short guide to share what I have learned.

Have you checked the logs?

Some things never change and your first port of call to debug any issues should be the log files.

OpenAM

There are actually two places to check when debugging OpenAM:


Note: <openam_install_dir> is the directory in which OpenAM was installed, not the web container.


<openam_install_dir>openam/debug



This is where you find the debug logs. Generally very detailed logs for all the different components of OpenAM.


<openam_install_dir>openam/log


This is where you find access and error logs. Detailing access requests and the result of those requests.


For example, if we look at access.csv:



You can see the result of my last login as amadmin.

Configuring log levels

If you don’t see anything, you may need to change the logging configuration.


Navigate to: http://localhost.localdomain.com:18080/openam/Debug.jsp




This interface is fairly straight forward



In the above example I have set the policy component to Message level.


Just hit confirm and the change will be made immediately without a restart required.

OpenIDM

Again, there are actually two places to check when debugging OpenIDM:


<openidm_install_dir>openidm/logs


The main OpenIDM log files can be found here. OpenIDM used JDK logging and the configuration file can be found here if you need to make changes to logging levels:


<openidm_install_dir>openidm/conf/logging.properties


There is a helpful guide as to how do that here: http://www.javapractices.com/topic/TopicAction.do?Id=143


So far that is all fairly standard, however if you do not find anything in the logs then you may want to examine the REST services.

Debugging REST services

As I have said a few times on his blog, the ForgeRock platform is completely underpinned by REST services.


The User Interfaces for OpenAM and OpenIDM both make extensive use of REST service calls in their functioning.


When debugging issues, especially anything that results in an error visible in the UI. You should take a look at the requests and responses.


I use FireFox Developer Tools to do this but I know there are equivalents for other browsers.


It’s as simple as turning on Developer Tools and examining the network requests whilst using OpenAM and OpenIDM.



So lets try making a new authentication chain in OpenAM.



What we need to find is the POST request for the creation of the chain. If you browse up and down the list you should find it pretty quickly. On the right you can see the Headers in the request, the parameters and importantly the response code:




And the response:


So let’s see what that looks like when we have an error:



Generally you will see something like the above, and if you check the actual response, you should see a more detailed message that can help you debug the issue.

This blog post was first published @ http://identity-implementation.blogspot.no/, included here with permission from the author.

OpenDJ: Monitoring Unindexed Searches…

FR_plogo_org_FC_openDJ-300x86OpenDJ, the open source LDAP directory services, makes use of indexes to optimise search queries. When a search query doesn’t match any index, the server will cursor through the whole database to return the entries, if any, that match the search filter. These unindexed queries can require a lot of resources : I/Os, CPU… In order to reduce the resource consumption, OpenDJ rejects unindexed queries by default, except for the Root DNs (i.e. for cn=Directory Manager).

In previous articles, I’ve talked about privileges for administratives accounts, and also about Analyzing Search Filters and Indexes.

Today, I’m going to show you how to monitor for unindexed searches by keeping a dedicated log file, using the traditional access logger and filtering criteria.

First, we’re going to create a new access logger, named “Searches” that will write its messages under “logs/search”.

dsconfig -D cn=directory manager -w secret12 -h localhost -p 4444 -n -X 
    create-log-publisher 
    --set enabled:true 
    --set log-file:logs/search 
    --set filtering-policy:inclusive 
    --set log-format:combined 
    --type file-based-access 
    --publisher-name Searches

Then we’re defining a Filtering Criteria, that will restrict what is being logged in that file: Let’s log only “search” operations, that are marked as “unindexed” and take more than “5000” milliseconds.

dsconfig -D cn=directory manager -w secret12 -h localhost -p 4444 -n -X 
    create-access-log-filtering-criteria 
    --publisher-name Searches 
    --set log-record-type:search 
    --set search-response-is-indexed:false 
    --set response-etime-greater-than:5000 
    --type generic 
    --criteria-name Expensive Searches

Voila! Now, whenever a search request is unindexed and take more than 5 seconds, the server will log the request to logs/search (in a single line) as below :

$ tail logs/search
[12/Sep/2016:14:25:31 +0200] SEARCH conn=10 op=1 msgID=2 base="dc=example,
dc=com" scope=sub filter="(objectclass=*)" attrs="+,*" result=0 nentries=
10003 unindexed etime=6542

This file can be monitored and used to trigger alerts to administrators, or simply used to collect and analyse the filters that result into unindexed requests, in order to better tune the OpenDJ indexes.

Note that sometimes, it is a good option to leave some requests unindexed (the cost of indexing them outweighs the benefits of the index). If these requests are unfrequent, run by specific administrators for reporting reasons, and if the results are expecting to contain a lot of entries. If so, a best practice is to have a dedicated replica for administration and run these expensive requests. Also, it is better if the client applications are tuned to expect these requests to take a long time.

Filed under: Directory Services Tagged: directory-server, ForgeRock, index, ldap, opendj, opensource, performance, search, Tips, tuning

This blog post was first published @ ludopoitou.com, included here with permission.

OpenDJ: Monitoring Unindexed Searches…

FR_plogo_org_FC_openDJ-300x86OpenDJ, the open source LDAP directory services, makes use of indexes to optimise search queries. When a search query doesn’t match any index, the server will cursor through the whole database to return the entries, if any, that match the search filter. These unindexed queries can require a lot of resources : I/Os, CPU… In order to reduce the resource consumption, OpenDJ rejects unindexed queries by default, except for the Root DNs (i.e. for cn=Directory Manager).

In previous articles, I’ve talked about privileges for administratives accounts, and also about Analyzing Search Filters and Indexes.

Today, I’m going to show you how to monitor for unindexed searches by keeping a dedicated log file, using the traditional access logger and filtering criteria.

First, we’re going to create a new access logger, named “Searches” that will write its messages under “logs/search”.

dsconfig -D cn=directory\ manager -w secret12 -h localhost -p 4444 -n -X \
    create-log-publisher \
    --set enabled:true \
    --set log-file:logs/search \
    --set filtering-policy:inclusive \
    --set log-format:combined \
    --type file-based-access \
    --publisher-name Searches

Then we’re defining a Filtering Criteria, that will restrict what is being logged in that file: Let’s log only “search” operations, that are marked as “unindexed” and take more than “5000” milliseconds.

dsconfig -D cn=directory\ manager -w secret12 -h localhost -p 4444 -n -X \
    create-access-log-filtering-criteria \
    --publisher-name Searches \
    --set log-record-type:search \
    --set search-response-is-indexed:false \
    --set response-etime-greater-than:5000 \
    --type generic \
    --criteria-name Expensive\ Searches

Voila! Now, whenever a search request is unindexed and take more than 5 seconds, the server will log the request to logs/search (in a single line) as below :

$ tail logs/search
[12/Sep/2016:14:25:31 +0200] SEARCH conn=10 op=1 msgID=2 base="dc=example,
dc=com" scope=sub filter="(objectclass=*)" attrs="+,*" result=0 nentries=
10003 unindexed etime=6542

This file can be monitored and used to trigger alerts to administrators, or simply used to collect and analyse the filters that result into unindexed requests, in order to better tune the OpenDJ indexes.

Note that sometimes, it is a good option to leave some requests unindexed (the cost of indexing them outweighs the benefits of the index). If these requests are unfrequent, run by specific administrators for reporting reasons, and if the results are expecting to contain a lot of entries. If so, a best practice is to have a dedicated replica for administration and run these expensive requests. Also, it is better if the client applications are tuned to expect these requests to take a long time.


Filed under: Directory Services Tagged: directory-server, ForgeRock, index, ldap, opendj, opensource, performance, search, Tips, tuning

OpenAM Text To Speech Authentication Module

For a recent POC I had a requirement to implement two factor authentication for users who may have impaired vision and would struggle to read an OTP or the code from a 2FA application.

To achieve this I cloned the existing OpenAM HOTP module and integrated it with The Twilio service: https://www.twilio.com/

I might do a bit more of a deep dive into how exactly this works later but for now the code is up in Github:

https://github.com/wayneblacklock/ttsAuthModule

And you can see a video of how it works below:

There is definitely room for improvement here, at the moment I am using the a Twimlet to encode the voice, in a production deployment you will want to generate TWIML (https://www.twilio.com/docs/api/twiml) in order to have more control over the voice i.e. introduce pauses etc.

This blog post was first published @ http://identity-implementation.blogspot.no/, included here with permission from the author.

OpenIG on Docker: The Perfect Couple

This blog post was first published @ http://identityrocks.blogspot.fr/, included here with permission.

“Docker containers wrap a piece of software in a complete filesystem that contains everything needed to run […]” [1]


OpenIG (Open Identity Gateway) provides an elegant yet flexible way to integrate your applications, devices, APIs with modern identity standards such as token types, authentication and authorization. The gateway as your integration component can be deployed and scaled along the applications and services it secures.

Whilst organizations adopt containerization as part of a “well-oiled” delivery pipeline, which includes the gateway, OpenIG in a container is also very beneficial for evaluation purposes. Here’s how you can evaluate in just a couple of minutes.

As prerequisites, you need docker and git on your system.

  1. Checkout the ForgeRock docker project to retrieve the Dockerfile and sample OpenIG configuration files
  • git clone https://stash.forgerock.org/scm/docker/docker.git
  • cd docker/openig
  • Build the docker image
  • docker build -t forgerock/openig:latest .
  • Run the docker image and mount the sample-config directory from your local git copy in the container
  • docker run –detach -p 8080:8080 –volume <LOCAL_PATH_TO_GIT>/docker/openig/sample-config:/var/openig –name openig -it forgerock/openig
To test the sample configuration, point your client (e.g. web browser, curl) to http://localhost:8080/simplethrottle for instance. The response is determined by the StaticResponseHandler setting in the 20-simplethrottle.json file.
A simplified version of this procedure however without the sample configuration but not necessitating usage of git and clone the full repo goes as follows. This is well suited to evaluate the upcoming user interface.
  1. Download the Dockerfile from https://stash.forgerock.org/projects/DOCKER/repos/docker/browse/openig/Dockerfile
  2. Build the docker image (as above)
  • docker build -t forgerock/openig:latest .
  • Run the docker image
  • docker run -d -p 8080:8080 –name openig -it forgerock/openig
Other useful commands:
  • Start container: docker stop openig
  • Stop container: docker start openig
  • Get shell prompt: docker exec -i -t openig /bin/bash
  • Remove container: docker rm openig

References

[1]Package your application into a standardized unit for software development”. Retrieved from https://www.docker.com/what-docker on Sep 6th, 2016.

 

A Beginners Guide to OpenIDM – Part 4 – Mappings

Overview

Last time we configured a connector to process data from a data source. In this blog we start to bring everything together and will define a mapping that creates objects using the connector.

Mappings define the relationships at the attribute level between data in connector data sources and objects. They also define rules to create attributes where they do not already exist and transform attributes if required.

Mappings

Architecture

In OpenIDM mappings consist of a number of logical components:
  • Properties: Defines attribute mappings between source attributes and target attributes, and scripts to create and transform attribute values. Also defines a link qualifier, required to link a single record in the source to multiple different records in the target. Which might be required in some situations e.g. event based HR data feeds where the same user record may appear multiple times.
  • Association: Queries, record validation scripts and association rules that work together define how a source account is linked to a target account. i.e. how OpenIDM knows that Anne’s account in the target system maps to Anne’s account in the source system, and not Bob’s account.
  • Behaviors: Defines the rules that tell OpenIDM what to do in different situations e.g. if an account doesn’t exist in the target system, then you might configure a behaviour to create it. This is incredibly powerful and we will explore it further.
  • Scheduling: Schedules for reconciliation operations e.g. run the mapping every hour, day, week etc. This is not the same as livesync (which we touched on last time) which will sync changes between systems as they occur.

Mappings Example

Creating the Mapping

As always with this blog, the best way to learn is to work through an example. We will build upon the existing work done in blogs 1-3 so you will need to complete those first.
Log in as administrator (openidm-admin), navigate to Configure then Mappings:
Then New Mapping:
You should see the following:
A mapping requires a source and a target and data will flow from the source to the target.
You can see there are a number of selectable options on this screen that you can assign as either a source or target:
  • Connectors: Any connectors you have configured, e.g. flat file, database, LDAP.
  • Managed Objects: The managed objects defined in OpenIDM.
So for this example, we want to use the CSV connector configured previously to create new managed users in OpenIDM. Effectively using the CSV data to create user identities.
Click Add to Mapping on the UserLoadCSV connector, this is going to be our source.
Similarly, now click Add to Mapping on the User managed object, this is our target.
You should see the following:
You have probably noticed that the CSV connector has a selectable drop down. There are some connectors where you might be interested in mapping more than one type of object e.g. accounts & groups in the case of LDAP. We have only configured the default _ACCOUNT_ object in this example.
 
Click Create Mapping.
 
 
Mapping Name: You can enter a more friendly mapping name if you like.
Linked Mapping: If you are creating two mappings in either direction, you should use this to link your second mapping to your first.
Click OK and the mapping should be created:

Configuring the Mapping

We have a mapping, now we need to configure it.
Navigate to the Properties tab and examine the Attribute Grid.
 
 
Start by clicking Add Missing Required Properties, this will automatically add those target properties which the connector definition or managed object specify must be populated. Make sure you press Save Properties after doing this.
You should see the required attributes for the managed user schema:
Now we need to configure the source attributes for each of the following target attributes.
Select the userName row:
You should see the following popup:
There are a few tabs here worth spending a moment on:
  • Property List: The source property to map from.
  • Transformation Script:  In line or file based scripts to transform attributes, a common use of this is to generate LDAP distinguished names.
  • Conditional Updates: Advanced logic that allows you to define rules for the conditional update of certain properties on sync. Useful if you want to ensure that a particular property is never over wrote.
  • Default Values: Simply set a fixed default value for the target, e.g. “true”, “active”, whatever.
Navigate to the Property List tab and select __NAME__. If you recall this corresponds to the connector we defined in the last blog. Now press Update.
Do the same with the rest of the mappings as below, then press Save Properties. You should end up with something like the below.
We can quickly check if this makes sense before we synchronize, look at Sample source, set the Link Qualifier to default and try entering one of the user ID’s in the CSV:
You should see a preview of the mapping result for whichever user you entered.
Next, we need to configure an Association Rule. Navigate to Association then look at Association Rules. Select Correlation Queries
Then Add Correlation Query:
Set the Link Qualifier to default, and look at Expression Builder.
 
 
Press + and select userName:
 
 
Then press Submit, and Save.
Select Save and Reconcile.
You should see the following:
Expand out In Progress, to see the results of reconciliation:
You can see there were 100 Absent results, you can examine the tooltip to see what this means but briefly it means that the source object has no matching target, i.e. there is no managed user record for all 100s lines in the CSV file. Which makes sense, as this is the first time we have run the reconciliation.
You might have expected that those managed users will now have been created, navigate to Manage, then User:
You should see No Data:
Which might not be what we expected, however lets navigate back to Configure, Mappings and look at the Behaviors tab of our mapping again. Look at Current Policy.
By default, new mapping are set up only to read data and not actually perform any operations, such as user creates.
Look at the policy table:
Now change the Current Policy to Default Actions, and note how the table changes:
Note that the actions have all changed, examine the tooltips to understand what is going on here. I plan to revisit Policies in a later blog because they are incredibly powerful.
For now note that Absent has now changed to Create. So for our situation earlier, we would now expect those 100 Absent users to result in Create operations.
Make sure you press Save before moving on.
Finally, press Reconcile Now to run another reconciliation:
You should see the same results as before, but lets check out our Users again under Manage, User.
 
If we have done everything correctly, you should now see all of the users from the CSV file created as OpenIDM managed users.
That’s all for this blog. Thanks.
 

This blog post was first published @ http://identity-implementation.blogspot.no/, included here with permission from the author.