**** Please note that the code in this post is not supported by ForgeRock. This is only an example. ****
Introduction
Support for impersonation is useful in the enterprise use cases where designated administrators are required to act on behalf of a user in certain scenarios. By impersonating another user an administrator, if authorized to do so, gains access to a restricted view of the user’s profile in the system. This is helpful in situations involving password reset, request-based access and profile updates. However, the design of such a system must call for controls that actively restrict access to the user’s entitlements at the outset. This can be achieved using step-up authentication for gaining access to private user data, and also by using the OpenAM policy engine for performing advanced resource-based decisioning.
Configuration
An OpenAM custom authentication module was written to enable impersonation support. The module requires input of the username of the end-user being impersonated and the administrator credentials. After submitting the username and password, the admin account is authenticated first and then it is also authorized to complete the impersonation request using REST calls to a specified OpenAM Policy endpoint. This policy can be either local or external as we shall examine further. The impersonated user is also validated for being in active status in the system. If all is okay, the administrator is permitted to impersonate and OpenAM creates a session for the impersonated user. The module can be configured using the following gauges to complete the described functions correctly:
- Setup the resource-set you want to check policy for. This resource set its nothing but a special URL that invokes policy evaluation for impersonation
- The authentication realm you want the administrator to authenticate in. The authentication module allows for realm-specific authentication
- The OpenAM server where the policy resides, the realm where the policy resides, and the policy-set name. The policy does not need to be local and can be on a remote policy host
- Check whether you want the administrator to be a member of a local group as well, in addition to the external policy authorization.
Installation
$ ./ssoadm create-svc –adminid amadmin –password-file pwdfile –xmlfile ~/amAuthImpersonationModule.xml
Service was added.
$ ./ssoadm register-auth-module –adminid amadmin –password-file pwdfile –authmodule org.forgerock.openam.authentication.modules.impersonation.ImpersonationModule
Authentication module was registered.
$ cp ~/impblocked.jsp /tomcat8/webapps/openam/config/auth/default
$ cp ~/ImpersonationModule.xml /tomcat8/webapps/openam/config/auth/default
$ cp ~/amAuthImpersonationModule.properties /tomcat8//webapps/openam/WEB-INF/classes
Development
Configuration read from Module Instance
options -> {iplanet-am-auth-check-group-membership=[True], iplanet-am-auth-impersonation-hash-enabled=[true], iplanet-am-auth-authentication-realm=[authn], iplanet-am-auth-impersonation-auth-level=[1], iplanet-am-auth-resource-set=[http://openam:8080/openam/index.html], moduleInstanceName=impersonate, iplanet-am-auth-impersonation-id=[Enter the user id to impersonate?], iplanet-am-auth-impersonation-group-name=[impersonation], iplanet-am-auth-openam-server=[http://openam:8080/openam], iplanet-am-auth-policy-realm=[impersonation], iplanet-am-auth-policy-set-name=[impersonation]}
Authorize the administrator locally
In our test scenario, the ‘user.0’ is really an administrative user that has been granted membership to the group named ‘impersonation’, as configured in the module (see above).
We build an AMIdentity object for the group and validate membership.
[AMIdentity object: id=impersonation,ou=group,o=impersonation,ou=services,dc=openam,dc=forgerock,dc=org]
value of attribute: uid=user.0,ou=People,dc=forgerock,dc=com
userName to check: user.0
match found! admin: user.0 allowed to impersonate user: user.1
Authorize the Administrator
Get the ssotoken for the admin who is trying to impersonate via a policy call, and authenticate the user to the realm specified in the config
json/authn/authenticate response-> {"tokenId":"AQIC5wM2LY4Sfcxokjvdayf3ig0oDuQITXRTWT9B_3hq72A.*AAJTSQACMDEAAlNLABI1ODk0Nzg1NTEyNDUzNzcxNDI.*","successUrl":"/openam/console"}
tokenId-> AQIC5wM2LY4Sfcxokjvdayf3ig0oDuQITXRTWT9B_3hq72A.*AAJTSQACMDEAAlNLABI1ODk0Nzg1NTEyNDUzNzcxNDI.*
Build the 2nd policy rest call, and use the resource set, openam server, policy set and policy container from the configuration passed to the module.
stringentity-> {"resources": ["http://openam:8080/openam/index.html"],"application":"impersonation", "subject": {"ssoToken":"AQIC5wM2LY4Sfcxokjvdayf3ig0oDuQITXRTWT9B_3hq72A.*AAJTSQACMDEAAlNLABI1ODk0Nzg1NTEyNDUzNzcxNDI.*"}}
json/impersonation/policies?_action=evaluate response-> [{"advices":{},"actions":{"POST":true,"PATCH":true,"GET":true,"DELETE":true,"OPTIONS":true,"PUT":true,"HEAD":true},"resource":"http://openam:8080/openam/index.html","attributes":{"uid":["user.0"],"cn":["Javed Shah"],"roleName":["timeBoundAdmin"]}}]
Custom response attributes can be passed back to the module for further evaluation if needed. For example, a statically defined roleName=timeBoundAdmin could be used to further restrict this impersonation request within the time window specified in the ‘timeBoundAdmin’ control. This example is only given to seed the imagination, the module currently does not restrict the impersonation session using a time window, but this is possible to do.
Parse the JSON response from Policy Evaluation
jsonarray-> {"resource":"http:\/\/openam:8080\/openam\/index.html","attributes":{"uid":["user.0"],"cn":["Javed Shah"],"roleName":["timeBoundAdmin"]},"advices":{},"actions":{"POST":true,"PATCH":true,"GET":true,"DELETE":true,"OPTIONS":true,"HEAD":true,"PUT":true}}
Demo



Comments are closed.
Hey Javed
Great job!!!
thanks,
Rogerio Rondini
Thanks.. if there is a specific custom authN module you would like to see, let me know. I’ll try to come up with something.