OpenAM v.13 – REST STS OpenAM Token Translation

A quick demo of OpenAM’s Token Translation Service

According to Wikipedia:

In a typical usage scenario, a client requests access to a secure software application, often called a relying party. Instead of the application authenticating the client, the client is redirected to an STS. The STS authenticates the client and issues a security token. Finally, the client is redirected back to the relying party where it presents the security token. The token is the data record in which claims are packed, and is protected from manipulation with strong cryptography. The software application verifies that the token originated from an STS trusted by it, and then makes authorization decisions accordingly. The token is creating a chain of trust between the STS and the software application consuming the claims. This process is illustrated in the Security Assertion Markup Language (SAML) use case, demonstrating how single sign-on can be used to access web services.

Here is a quick video (w/o audio) demonstrating how to create an STS instance in OpenAM v.13 and then using Postman (REST client) to translate the tokenid of an authenticated user.

Caveat: There are obviously more configuration requirements for an actual deployment, the ACS URL would be key, for example. Refer to the STS documentation linked below the video.

References:

  • OpenAM 13 Admin Guide – 17.2. Configuring the Security Token Service
  • OpenAM 13 Developer’s Guide – 2.1.7. RESTful Secure Token Service
  • REST Requests:

    Authenticate:
    POST /openam/json/authenticate HTTP/1.1
    Host: am.example.com:8080
    X-OpenAM-Username: username
    X-OpenAM-Password: password
    Content-Type: application/json
    Cache-Control: no-cache

    {}

    Translate:
    POST /openam/rest-sts/sts-test?_action=translate HTTP/1.1
    Host: am.example.com:8080
    Content-Type: application/json
    Cache-Control: no-cache

    {
    “input_token_state”: {
    “token_type”: “OPENAM”,
    “session_id”: “AQIC5wM2LY4SfczD8y5-kVgiXY7rxxxxxxxxx8k0o8.*AAJTSQACMDEAAlNLABQtNjY4MzQxNjkzMDg2ODI1MjIzOQACUzEAAA..*”
    },
    “output_token_state”: {
    “token_type”: “SAML2”,
    “subject_confirmation”: “BEARER”
    }
    }

    Next Steps?
    We implement solutions like this for our clients nearly every day. Are you looking for assistance on a current project? Maybe you have a future project and you just want to keep in touch. Awesome! Head on over to our contact page and drop us a line. We’re looking forward to hearing from you.

    ForgeRock upgrades entire stack today! #OpenAM #OpenIDM #OpenDJ #OpenIG

    ok guys … ForgeRock released updates across the board today:

  • Access Management – AM 13
  • Identity Management – IDM 4
  • Directory Services – DJ 3
  • Identity Gateway – IG 4
  • I have only had a chance to go through the OpenAM release notes … and this is a big release for OpenAM. Clearly a ton of effort was put into this version. Check out the release notes for a comprehensive list of new features. I have highlighted my favorites here:

  • Contextual Authorization
  • SAML 2 Authentication Module
  • OAuth 2.0 Device Flow
  • Additional UMA Support (you knew this was coming)
  • OAuth 2.0 Enhancements
  • Elasticity and Scaling Features (Stateless Sessions and Dynamic Configuration, Yay!!)
  • Soap STS is back … so, you have REST and SOAP STS services now
  • OpenIG to replace DAS (bye-bye DAS … you won’t be missed, along with your little friend JATO too)
  • One more – listed under “User Experience Enhancements” there is a new one “Recording Troubleshooting Information” – I don’t know much about this and need to find out some more but looks really useful
  • So, go download these new versions and check out this new stuff. Let me know if you find new stuff that I haven’t found yet.

    Implementing OAuth2 with OpenAM

    This post is going to be a “work in progress” but I am going to post it as I go along as opposed to waiting until it’s completed.(Continuous Delivery ya’ know! ).

    As you probably know OpenAM supports OAuth2 out of the box. Great but some people are still asking, “what is OAuth2?”. No problem. There are a ton of resources available online that provides an overview.

    Resources:

  • OAuth 2.0 Specification
  • OAuth 2 Site
  • OAuth2 – blog post by Anders Askasen
  • OpenAM OAuth 2.0 Authentication
  • Shoot Me a Token: OpenAM as an OAuth2 Provider
  • OAuth 2.0: Get Started with the Demo Client
  • OpenID Connect Examples
  • Google OAuth Playground
  • FR-OpenAM-DeliveryPartner-Badge

    Planning your #IDM architecture

    Planning and designing your Identity & Access Management architecture can be pretty complex, depending on your use cases. Even when using a set of tools like ForgeRock’s Open Identity Suite … which is pretty easy to install. You need to understand which products are right for your use cases and requirements.

    Should you use OpenAM or OpenIDM for creating users? This is a common question that customers ask us. (hint … you should probably use OpenIDM for provisioning users, even though OpenAM does provide the ability to create users.). What about the number of servers or instances you should be running? As a rule of thumb, a well tuned OpenAM instance can handle about 100,000 sessions concurrently … but that doesn’t mean you should only have one OpenAM instance configured if you only have 50,000 users.

    It’s highly advisable to engage with a ForgeRock partner that has the experience and know how to help you navigate these questions. Our team can help you determine which products you need to license, how to best configure your environment to provide rock-solid services to your customers and can even manage this environment for you after it’s all set up. We have provided these types of services to the Federal Government, Public School Systems and several commercial organizations. We have designed and implemented solutions for on-premise data centers, cloud-based deployments and hybrid deployments as well.

    We can advise your team before you buy, help you configure and setup the environments and then keep it running securely after it’s been deployed.

    Take a look at some of the solutions we offer here and then reach out to us here.

    maven-logo-black-on-white

    Building OpenAM with Maven (Quick Note)

    Just a quick note from my past self to my future self …

    Set up:
    Apple MacBook Pro (Late 2013)
    2.3 Ghz Intel Core i7
    16 GB 1600 Mhz

    java version “1.8.0_51”
    Java(TM) SE Runtime Environment (build 1.8.0_51-b16)
    Java HotSpot(TM) 64-Bit Server VM (build 25.51-b03, mixed mode)

    mvn -version
    Apache Maven 3.3.3

    Check out from the trunk:
    svn co https://svn.forgerock.org/openam/trunk/openam/

    Set the Maven Environment Variables:
    export MAVEN_OPTS=”-Xmx1024m -XX:MaxPermSize=512m”

    Note: On the ForgeRock website the recommendation was:
    export MAVEN_OPTS=-Xmx512m
    but this continuously throws an
    out of memory error.

    Maven Build:
    mvn -DskipTests=true clean install

    Everything gets built to:
    /openam/openam-server/target

    p.s.
    I have buried the DeLorean in the abandoned Delgado Mine, adjacent to the Old Boot Hill Cemetery

    OpenAM: Forcing users to reset password on next login.

    Overview

    A very common use case, when implementing ForgeRock’s OpenAM, is forcing a user to reset their password the next time they login. Seems easy enough right? … next time a particular user authenticates in they should be prompted to change their password before continuing on to the resource (web page) that they had originally requested.

    The documentation does mention a setting, in section 8.3, to enable this:

    Force Change Password on Next Login

    When enabled, the user must change her password next time she logs in after OpenAM resets her password.

     

    Unfortunately, this doesn’t seem to work. Doing a little “googling” you can find there is an open bug on this.

    There are several places online where ForgeRock’s Peter Major (aka @aldaris) recommends implementing this at the directory server layer instead. This is pretty easy to implement if you are using OpenDJ as your user identity repository.

    I am going to explain how to configure this here:

    OpenAM

    In OpenAM your authenication module needs to be set to LDAP instead of DataStore. The default ldapService authentication module uses the DataStore authentication module, which does not support forcing a user to reset their password. Instead you shoud create a new authentication chain which uses LDAP as the authentication module.

    Note
    : I am assuming that your LDAP authentication module is configured to use an OpenDJ instance.

    OpenDJ

    There are two settings in OpenDJ which need to be enabled.

    1. Modify the Password Policy to enforce Password Reset on Next Login
    2. Enable pwdReset attribute on the user’s record

    Modify the Password Policy:
    Using OpenDJ’s dsconfig command line tool you can edit the user’s password policy to enable the Password Reset settings. In this example the user’s password policy is the Default Password Policy. Change the setting force-change-on-reset from false to true. (Note: in production you probably would have created a different policy and wouldn’t be using the default policy)

    Enable pwdReset attribute on the user’s record:
    This setting can be changed either via an ldap browser, command line (ldapmodify) or even by using a provisioning tool like OpenIDM. Keep in mind that this is considered an operational attribute so you’ll need to ensure that you have permission to change the value.

    Note: The embedded OpenDJ instance that comes with OpenAM is configured to prevent a user from changing their password so you will likely run into errors unless you have modified the ACI. It’s actually not recommended to use the embedded OpenDJ instance as a user identity store, in production. So, use an external instance of OpenDJ and you’ll be fine.

    So, let’s see this in action:

    by the way … this works just fine using the XUI as well:

    Wrap up

    So, we’ve demonstrated how easy it is to implement the force password reset on next login functionality. We’ve validated that this approach works whether you are using the legacy UI or the new modern XUI.

    Don’t hesitate to reach out if you have any questions. If you need help implementing OpenAM or any other product’s in ForgeRock’s Open Identity Suite drop us a line through our contact page.

    #ForgeRock: Using #OpenIDM to sync Account Lockout Status #IDM

    Use Case:

    In an enterprise setup you would likely want to know when a user has locked their account (e.g. too many failed password attempts) and more than likely want to distribute that information to other systems in your environment. One solution would be to enable OpenIDM to monitor the user identity repository for changes to the user’s status.

    This post will demonstrate one possible configuration for this use case.

    Starting out with a typical ForgeRock set up … OpenIDM to provision and synchronize users, OpenAM to manage access and OpenDJ and the configuraton and user data store.


    Assumptions:

    • OpenDJ is already Installed ( or you plan to use the OpenAM’s embedded directory store )
    • OpenAM is already configured to use OpenDJ as it’s configuration store and user identity store
    • OpenIDM is already installed (and using OrientDB as the repo DB)
    • The OrientDB console has been installed (not part of the ForgeRock software stack)

    Steps to Configure:

    OpenDJ:

    • Modify the Default Password Policy (using OpenDJ’s dsconfig tool)
      • Set the # of Password Failures before Lockout

    • Enable Change Logs (by enabling replication)
      • Using OpenDJ’s ./dsconfig tool
        • Create a replication server
        • Create a replication domain

    OpenIDM

    • Create a connector to OpenDJ

    • Create an OpenIDM to OpenDJ Mapping

     

    • Create an OpenDJ to OpenIDM Mapping


    Testing

    First Lock the Account by failing the login. I am using the REST API but this can be done via the OpenAM UI as well.

     

    Once the account is locked, verify that the attribute (pwdAccountLockedTime) now has a date time stamp as a value.

     

    Now, verify that the OpenIDM repostitory has been updated with the same value.

     

    Unlocking the Account

    Unlocking the account is as simple as changing the password in OpenAM. Once you change the password you should be able to repeat the Testing steps to ensure that the pwdAccountLockedTime attribute has been returned to null.

    Next Steps

    Now that the pwdAccountLockedTime attribute is syncing between OpenDJ and OpenIDM you can take the next steps and have OpenIDM syncronize the changed value out to other systems as well.

    Give us a call if you need help implementing this use case or any other similar use cases.

    Disclaimers:

    • OrientDB is not supported by ForgeRock for production installs
    • Whether you use the embedded OpenDJ as part of your architecture would depend on your performance and scalability requirements.
    • This particular architecture is for demo purposes and may not be suitable for your specific requirements.  Give us a call if you need assistance in designing an appropriate architecture for your specific requirements.

    LDAP Command Line Cheat #OpenDJ

    I use the command line a lot when interfacing with OpenDJ. One of the issues with this is that I often run into an issue with the BindDN user’s password has an “!” (bang) in it. As this is a special character in Unix/Linux command line, it will typically cause unexpected results.

    With ldapsearch you can just leave the password paramater off and you will be prompted to provide the password. I have found that this is not the case with ldapmodify and ldapdelete. So, this can be problematic when trying to delete a user’s record.

    Another work-around is to set up a tools.properties file in your user’s home directory. So, if you typically run these commands as a user named “opendj” then you would create the following file, in the opendj user’s home directory:

    ~/.opendj/tools.properties
    hostname=directory.example.com
    port=1389
    bindDN=uid=kvaughn,ou=People,dc=example,dc=com
    ldapcompare.port=1389
    ldapdelete.port=1389
    ldapmodify.port=1389
    ldappasswordmodify.port=1389
    ldapsearch.port=1389

    So, then to delete a user:

    Create an ldif file containing the user’s DN and the change type:

    ex. vi deleuser.ldif
    dn: uid=newuser,ou=People,dc=example,dc=com
    changetype: delete

    Then run the ldapmodify command:

    $ldapmodify -p 1389 -f deluser.ldif

    You will be prompted for the password which you can type in and not worry about any conflicts with the OS command line.

    OpenIDM: Implementing a custom password policy

    OpenIDM 3.1 comes with several password policies enabled by default.  There are often times when you will need to implement additional policies or even modify or extend existing policies.  This is a quick guide that will walk you through the basics of implementing your own password policies.

    Let’s talk a little bit about what’s there by default.

    Policies are enabled in the openidm/conf/policy.json file.  This file is organized by resources (e.g. managed/user, internal/user, etc).  Each resource in turn has a properties section in which policies are defined for a specific attribute (e.g. userName, password, email, etc).

    Here is an example:

    The policies that are reference in policy.json are actually defined in:  openidm/bin/defaults/script/policy.js

    policy.js looks something like this:

     “policies” : [

            {   “policyId” : “required”,

                “policyExec” : “required”,

                “clientValidation”: true,

                “policyRequirements” : [“REQUIRED”]

            },

     policyFunctions.required = function(fullObject, value, params, propName) {

            if (value === undefined) {

                return [ { “policyRequirement” : “REQUIRED” } ];

            }

            return [];

        };

    I wouldn’t make changes directly to policy.js as these changes could get overwritten by an updated from ForgeRock.  

    So, now to implement your own policies … let’s add in a policy that will enforce a maximum length for passwords.

    • First make a copy of the policy.js file, rename it and save to: /openidm/script/custom-name-policy.js
    • Remove all of the policies, from the new file, that you don’t need
    • Add in your new custom policy 

    At the top of the file add in:

    var policy1 = {
    “policyId” : “maximum-length”,
    “policyExec” : “maxLength”,
    “clientValidation” : true,
    “validateOnlyIfPresent” : true,
    “policyRequirements” : [“MAX_LENGTH”]
    }

    addPolicy(policy1);

    function maxLength(fullObject, value, params, property) {
    var maxLength = params.maxLength;
    var val = “”;

    if (value != null) {
    val = value;
    }

    if (val.length > max.length) {
    return [ { “policyRequirement” : “ No more than “ + maxLength + characters”, “params” : {“maxLength”:maxLength} } ];
    }
    return []
    };

    A simple function that checks to make sure that the password length is not longer than the maxLength parameter.

    Great, so how do we enable that (and where do we set that maxLength parameter?)

    Let’s go back and modify the policy.json file.  Near the top of the file there is a parameter called “additionalFiles”.  Add the path and name of your custom file to that parameter.

    “additionalFiles” : [
    “script/custom-name-policy.js
    ],

    Next,

    find the password policy section (in the policy.json file).  Under the “managed/user” resource …

    “name” : “password”,
    “policies” : [
    {
    “policyId” : “notNull”
      },
    {
    “policyId” : “atLeastXCapLetters”,
    “params” : {
    “numCaps” : 1
            }
    },

    Now add in a reference to the new policy, that was created in the custom-name-policy.js file.  So policy.json would now look like this:

    “name” : “password”,
    “policies” : [
    {
    “policyId” : “notNull”
      },
    {
    “policyId” : “atLeastXCapLetters”,
    “params” : {
    “numCaps” : 1
            }
    },
    {
    “policyId” : “
    maximum-length”,
    “params” : {
    “maxLength” : 16
              }
    },

    Save this file and restart OpenIDM.  Your new new policy should now be enabled and when creating a password for a managed/user object (i.e. user) you will get a policy validation error if the password is longer than 16 characters.

    Custom Password Policy Validation in OpenIDM

    A customer needed to ensure that passwords contained at least one ‘special character’ when a new password was created in OpenIDM.

    I borrowed heavily from the provided samples but had to figure out the correct regexp formatting.

    Here is the function that I used to implement this:

    function atLeastXSpecialChars(fullObject, value, params, property) {
       isRequired = _.find(this.failedPolicyRequirements, function (fpr) {
           return fpr.policyRequirement === "REQUIRED";
       }),
       isNonEmptyString = (typeof(value) === "string" && value.length),
       valuePassesRegexp = (function (v) {
       var testResult = isNonEmptyString ? v.match(/\(|\)|\!|\$|\`|\~|\:|\.|\,|\<|\>|\=|\?|\^|\_|\{|\}/g) : false;
           return testResult;
       }(value));
       if ((isRequired || isNonEmptyString) && !valuePassesRegexp) {
           return [ {"policyRequirement" : "AT_LEAST_X_SPECIAL_CHARS"}];
       }
        return [];
    };