Tuesday, November 24, 2015

OpenAM 12 - New Forget Password Self-Service

Most of my customers build their own User Self-Service module. That includes Change Password and Forget Password. And most of the times, they interact with the backend data source (e.g OpenDJ or Active Directory) directly.

I seldom have to worry about enabling the Forget Password feature in OpenAM. Well, good time is up for me. :) I have a customer that wants to utilize the Forget Password in OpenAM 12. 

Well, so based on my past exploration with OpenAM Password Reset feature, our discussion revolved around Challenge Questions & Answers and how the flow will be. Note that this customer only wanted the new XUI. No way to use legacy UI as discovery and customization times have been invested into rebranding the XUI.

Today, I had a shock when I started to read more about the Forget Password feature in OpenAM 12. The more I read, the more confused I become. The documentation keeps talking about Resetting Forgotten Passwords (legacy). 

OpenAM can provide self-service password reset for forgotten passwords when end user pages are served by the classic UI. To enable self-service password reset, you must configure the password reset service itself, which consists mainly of setting up secret questions, and configuring an SMTP mail server to send reset passwords to the users of the service.

But Mr Customer wants nothing, but the new XUI.

Now, during XUI rebranding, I did come across the following scripts in one of the template files.

There is definitely something to configure via the OpenAM Administration console to make the Forget Password hyperlink appears in XUI.

So I searched around and reached Configuration > Global > User Self Service. There you are! The Forgot Password for Users is disabled by default.

So I went ahead to enable the feature. Another great feature out there is the Forgot Password Token LifeTime (seconds). This expires the hyperlink which is sent to users. (Will talk about this in a while ...)

Nice, the Forgot password hyperlink finally appears!

The next screen is what you'll see when the Forgot password hyperlink is clicked.

When a correct username (default is to match with UID) is entered, an email will be sent.

The user will receive an email like the following:

This is where the Forgot Password Token LifeTime (seconds) kicks in. I suppose the hyperlink in the email will expires in the configured time. (I'll need to fully test this function. Still at high-level investigation now)

Once the hyperlink is clicked, the user will be redirected to the Change forgotten password page.

Pretty cool right? Initially I thought Mr Customer would reject it because the long-discussed Challenge Questions & Answers feature is no longer available in the new XUI. But, to my surprise, he prefers this new feature, especially the Forgot Password Token LifeTime.

And what surprised me more?

This new feature is not mentioned at all in OpenAM documentation, not in stable release. And I just searched the draft documentation for OpenAM 13, it's not mentioned as well. Maybe it's hidden somewhere, but it's really not obvious to customers and integrators like us.

The documentation is not catching up with development? Super strange! 


Monday, November 23, 2015

SLF4J: Class path contains multiple SLF4J bindings

Prior to OpenAM 12, we used to have our own logging framework using SLF4J and LogBack, instead of default logging framework that comes default with OpenAM. 

In OpenAM 12, multiple SLF4J bindings errors are thrown if both logging framework co-exist.

SLF4J: Class path contains multiple SLF4J bindings.
SLF4J: Found binding in [jar:file:/data/opt/apache-tomcat-8.0.26/webapps/auth/WEB-INF/lib/openam-slf4j-12.0.2.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: Found binding in [jar:file:/data/opt/apache-tomcat-8.0.26/webapps/auth/WEB-INF/lib/logback-classic-1.1.3.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings for an explanation.
SLF4J: Actual binding is of type [org.forgerock.openam.slf4j.AMLoggerFactory]

Need to handle carefully.


Friday, November 20, 2015

OpenAM - Mobile Access

The common topic from customers these days is how to integrate their mobile applications with OpenAM.

I will usually use the material from Shoot Me a Token: OpenAM as an OAuth2 Provider. Victor wrote this quite some time ago when I attended the 1st Open Identity Summit in the US. But it's still relevant.

So, there are a few ways to integrate mobile applications with OpenAM - OAuth2, OpenID Connect or REST. All methods are language independent, which is good.

The most common integration will be OAuth2. With OAuth2 in mind, one has to differentiate that there are in fact 2 types of tokens - Access Token & Refresh Token. The lifetime of a refresh token is long. So, a refresh token is used to exchange for a new access token (which is short-lived). This is important concept. Otherwise, users will need to keep logging in.

A real life example would be your Facebook application on your mobile phone. Are you prompted to log in every day? I don't even recall when did I last logged in. Technically, it's the "refresh token exchanging for an access token" in play.

In order for OpenAM to behave like Facebook (ok, this is very layman), the OAuth2 Provider feature in OpenAM has to be enabled. Once enabled, OpenAM can now provide the same functionalities as Facebook. It is now able to issue access and refresh token to mobile applications. It is now OAuth2-aware.

Some customers will then want to know more about what's going on behind the scene. Well, Victor's slides have it all. I just need to highlight a bit to make it complete.

The very 1st time a user access a mobile application (OAUTH2 Demo), he will be prompted with a consent page.

OpenAM will display the same to user. Depending on which OpenAM version you are using, you might get this:

Yes, so UI customization is required. :)  Or if you might get this:

I have not tested the latest UI yet. (Currently on a OpenAM 12 project, OAuth2 is in next phase)

So, after user has given his consent (highlighted in RED), an attribute in the user's LDAP entry is updated to "remember" user has in fact given his consent. This will prevent the Consent Page to be displayed again.

Once that's done, the mobile application will request for an Access Token and this will be stored in the Key Chain on the handphone (highlighted in BLUE). At the same time, the Refresh Token is stored.

The next time the user fires up the mobile application, it will retrieve the Access Token. If it has not expired, it will be used to request token information from OpenAM.

If the Access Token is expired, then the Refresh Token will be used to exchange for a new Access Token. The new Access Token will be stored in the Key Chain.

The extreme case will be the Refresh Token has also expired. Then users will be forced to re-login again.

That explains why some sites have their Refresh Token set to be months or even year. Just long enough for you to change handphone. :)

Futher readings:

[Concept] Working with Mobile Devices & Applications

[Sample] OpenAM OAuth 2.0 iOS Sample App

* I have not tested the sample codes yet. No comment there.


Tuesday, November 17, 2015

ssoadm CLI - when to encrypt password?

So my OpenAMM ssoadm CLI journey continues ... 

To create a datastore, the following command is used:

$ ./ssoadm create-datastore -u amadmin -f .pwd.txt -e / -m DS1 -t LDAPv3ForOpenDS -D /data/bin/patch/am-config/datastore-DS1.conf

The content of datastore will be as follows:

sun-idrepo-ldapv3-config-authid=uid=openam,ou=service accounts,o=XXX

Notice that password must be in clear and not encrypted using ampassword CLI. Once the create-datastore command is executed, the password will be stored in encrypted form in the OpenDJ.

But still remember this?

$ ./ssoadm set-svrcfg-xml -u amadmin -f .pwd.txt -s http://am0-test.XXXX.net:8080/auth -X /data/bin//am-config/dir-conf.xml

Notice that the passwords must be encrypted within this XML structure.

So when to encrypt password? I'm not too sure. It's not consistent.


Monday, November 16, 2015

ssoadm CLI - Directory Configuration Part II

So there is, in fact, a way to script the Directory Configuration as mentioned by Peter.

The easiest way is to export the configuration in XML format, then import again via the ssoadm CLI.

$ ./ssoadm get-svrcfg-xml -u amadmin -f .pwd.txt -s http://am0-test.XXXX.net:8080/auth

$ ./ssoadm set-svrcfg-xml -u amadmin -f .pwd.txt -s http://am0-test.XXXX.net:8080/auth -X /data/bin//am-config/dir-conf.xml

Do take note to:

1. only update the SMS Server Group.

2. encrypt password via ampassword CLI


Friday, November 13, 2015

ssoadm CLI - Directory Configuration

Using ssoadm CLI to list a server configuration, I found out that the Directory Configuration information is not returned.

If you reference the OpenAM documentation, you would also realize there is no property listed in Servers > Directory Configuration section.

1) Now, for best practice, we would definitely not want to use cn=Directory Manager to bind to OpenDJ. A better approach is to create a service account.  

2) In production, especially when a pair of external OpenDJ is deployed, we would want to add Server2 to point to the 2nd external OpenDJ.

For (1), this can be easily solved by:
a. Create the service account prior to installation & configuration of OpenAM
b. In the OpenAM configuration file,

DS_DIRMGRDN=cn=Directory Manager

Change DS_DIRMGRDN and  DS_DIRMGRPASSWD to the service account.

For (2), I have no idea how to script this. For now, I would have to manually add in via OpenAM Administration console.

Technically, I know this Directory Configuration is stored as XML in one of the LDAP attributes. Is this the challenge in not able to add/retrieve the information? I do not know.

Less than ideal.


Wednesday, November 11, 2015

ssoadm CLI for scaling and de-scaling of OpenAM nodes

So I am still in a project where OpenAM and OpenDJ are all deployed on AWS.  In a scenario when a spawned node is "de-scaled", it's good to clean up the server configuration.

For example, there are 2 nodes now (am0-test and am1-test). And am1-test is scheduled for "de-scale". 

In AWS terminology, the autoscaling group is performing a scaling in. 

When am1-test is finally terminated, we would like to clean up OpenAM Servers & Sites as follows:

That's easy using ssoadm CLI commands. 

$ ./ssoadm delete-server -u amadmin -f .pwd.txt -s http://am1-test.XXX.net:8080/auth

But how about the cleaning up of Realm/DNS Aliases?

That's where the ssoadm CLI command is lacking.

Listing of Realm/DNS Aliases is OK. Easy.

$ ./ssoadm get-realm -s sunIdentityRepositoryService -u amadmin -f .pwd.txt -e /

sunKeyValue: sunidentityrepositoryservice-sunOrganizationStatus=Active
sunxmlKeyValue: sunidentityrepositoryservice-sunOrganizationAliases=login-test.XXX.com.sg
sunxmlKeyValue: sunidentityrepositoryservice-sunOrganizationAliases=am1-test.XXX.net
sunxmlKeyValue: sunidentityrepositoryservice-sunOrganizationAliases=am0-test.XXX.net
sunxmlKeyValue: sunidentityrepositoryservice-sunOrganizationAliases=XXX

So, we only want to remove sunOrganizationAliases=am1-test.XXX.net right? I mean this is what we'll do via OpenAM Administration Console. Thus, we want the same for CLI isn't it?

There is a delete-realm-attr command that seems suitable.

$ ./ssoadm delete-realm-attr -s sunIdentityRepositoryService -u amadmin -f .pwd.txt -e / -a sunOrganizationAliases=am1-test.XXX.net

Attribute was removed.

Great! Attribute was removed. However, when get-realm command is executed again, nothing is being removed.

A look at the syntax indicates -a has to be the name of the attribute to be removed.

This means the CLI command has to be:

$ ./ssoadm delete-realm-attr -s sunIdentityRepositoryService -u amadmin -f .pwd.txt -e / -a sunOrganizationAliases

This is even worse. All the entries except the following are removed.

$ ./ssoadm get-realm -s sunIdentityRepositoryService -u amadmin -f .pwd.txt -e /
sunKeyValue: sunidentityrepositoryservice-sunOrganizationStatus=Active

And if one try to log in to OpenAM, the following error will occur:

The workaround is to use set-realm-svc-attrs command to add those sunOrganizationAliases back.

Notice that -a now accepts attribute values, instead of only attribute name.

$ ./ssoadm set-realm-attr -s sunIdentityRepositoryService -u amadmin -f .pwd.txt -e / -a sunOrganizationAliases -p -a sunOrganizationAliases=login-test.XXX.com.sg
$ ./ssoadm set-realm-attr -s sunIdentityRepositoryService -u amadmin -f .pwd.txt -e / -a sunOrganizationAliases -p -a sunOrganizationAliases=am0-test.XXX.net
$ ./ssoadm set-realm-attr -s sunIdentityRepositoryService -u amadmin -f .pwd.txt -e / -a sunOrganizationAliases -p -a sunOrganizationAliases=XXX

What a pain!