Thursday, March 27, 2014

Open AM Adding DELETE and PUT Http Actions to Policies

I'm investigating Forge Rock's Open AM product again this morning. Version 11 out of the box only supports http actions of GET and POST when configuring access policies. With a little research on the internet and some digging through the LDAP configuration directory I found an attribute named sunServiceSchema in entry ou=1.0,ou=iPlanetAMWebAgentService,ou=services,dc=openam,dc=forgerock,dc=org. This contained the following XML document. Note the GET and POST http actions highlighted. That looked promising:


<?xml version="1.0" encoding="UTF-8"?>


<ServicesConfiguration><Service name="iPlanetAMWebAgentService" version="1.0"><Schema i18nFileName="amWebAgent"  i18nKey="iplanet-am-web-agent-service-description"  revisionNumber="10" 
<Global validate="yes" >
  <AttributeSchema cosQualifier="default"  i18nKey=""  isSearchable="no"  name="serviceObjectClasses"  syntax="string"  type="list" >
<DefaultValues>
      <Value>iplanet-am-web-agent-service</Value>
</DefaultValues>
</AttributeSchema>
</Global>

  <Policy>
<AttributeSchema cosQualifier="default"  i18nKey="GET"  isSearchable="no"  name="GET"  syntax="boolean"  type="single"  uitype="radio" >
<IsResourceNameAllowed></IsResourceNameAllowed>
<BooleanValues>
<BooleanTrueValue i18nKey="allow" >allow</BooleanTrueValue>
<BooleanFalseValue i18nKey="deny" >deny</BooleanFalseValue>
</BooleanValues>
</AttributeSchema>
<AttributeSchema cosQualifier="default"  i18nKey="POST"  isSearchable="no"  name="POST"  syntax="boolean"  type="single"  uitype="radio" >
<IsResourceNameAllowed></IsResourceNameAllowed>
<BooleanValues>
<BooleanTrueValue i18nKey="allow" >allow</BooleanTrueValue>
<BooleanFalseValue i18nKey="deny" >deny</BooleanFalseValue>
</BooleanValues>
</AttributeSchema>
</Policy>

</Schema></Service></ServicesConfiguration>

On a hunch I added the following two additional attribute schema elements by copying the existing ones and modifying their i18nKey and name as highlighted below:

<AttributeSchema cosQualifier="default"  i18nKey="PUT"  isSearchable="no"  name="PUT"  syntax="boolean"  type="single"  uitype="radio" >
 <IsResourceNameAllowed></IsResourceNameAllowed>
 <BooleanValues>
     <BooleanTrueValue i18nKey="allow" >allow</BooleanTrueValue>
     <BooleanFalseValue i18nKey="deny" >deny</BooleanFalseValue>
  </BooleanValues>
</AttributeSchema>
<AttributeSchema cosQualifier="default"  i18nKey="DELETE"  isSearchable="no"  name="DELETE"  syntax="boolean"  type="single"  uitype="radio" >
 <IsResourceNameAllowed></IsResourceNameAllowed>
 <BooleanValues>
    <BooleanTrueValue i18nKey="allow" >allow</BooleanTrueValue>
     <BooleanFalseValue i18nKey="deny" >deny</BooleanFalseValue>
 </BooleanValues>
</AttributeSchema>

I then bounced the Open AM server. Upon selecting a policy and editing its rule I then saw that DELETE and PUT were now showing in the UI. The question then was will they be honored and work with policy evaluation. Since I don't yet have an application behind an agent to verify that they work I turned to the /authorize restful endpoint. I first acquired a token via the /authenticate restful endpoint:

curl --request POST --header "X-OpenAM-Username: <my-user>" --header "X-OpenAM-Password: <my-password>" --header "Content-Type: application/json" --data "{}" https://signin-int.lds.org/openam/json/authenticate { "tokenId": "AQIC5wM2LY4SfcxzmBcakM-l7x_FXkMzkT21Ok9Bhgf2zQs.*AAJTSQACMDIAAlNLABQtNTIxNjI5NTA3ODMyMzM1OTQxMAACUzEAAjAx*", "successUrl": "/openam/console" }

Once I had a token I was ready to hit the /authorize restful endpoint. But first off my policy looked like the following:


Policy Name: test.lds.org
Rules:
 Name: /directory
 Resource Name: http://test.lds.org/directory/*
 Actions Checked: DELETE, GET, POST
Subjects:

 Name: Allow All Users
 Authentication Module: Authenticated Users

Conditions: none
Response Providers: none

One call to test access is shown below with the token from the /authenticate call above truncated for this post but included in its entirety in the real call. Note that the documentation as of this post did not indicate that an action parameter was supported but a quick google search turned up a blog that mentioned it. Good thing we have bloggers eh? :-)

curl "https://signin-int.lds.org/openam/identity/authorize?uri=http%3A%2F%2Ftest.lds.org%2Fdirectory%2Ftest&action=DELETE&subjectid=AQIC...*" boolean=true

I ran the the test specifying a different action each time in the query parameter. The results showed as follows for each action tested. Note that I also tested a lowercase version of the POST action and learned that the value of the action query parameter is case sensitive. That is nice to know and would make a good addition to the documentation:

DELETE: boolean=true
GET: boolean=true
POST: boolean=true
post: exception.name=com.sun.identity.idsvcs.GeneralFailure Invalid action name: post for service: iPlanetAMWebAgentService.
PUT: boolean=false

I then changed the actions in the policy as follows:

Actions Checked: DELETE, POST, PUT

And the results then showed these responses:

DELETE: boolean=true
GET: boolean=false
POST: boolean=true
PUT: boolean=true

So it appears that adding those sections to that XML document in the configuration directory did indeed add support for DELETE and PUT as desired. Once I get an agent and application combination set up I'll verify these changes there as well and cover that in another post. Enjoy.


Wednesday, March 12, 2014

Open AM: Authenticate Rest API

Looking into Open AM from ForgeRock this morning. Their Restful APIs are pretty impressive. They include policy management but also authentication and policy evaluation. For example, I can authenticate with a simple http post to their authentication endpoint like so of course with identifying information removed:

curl --request POST --header "X-OpenAM-Username: boydkr" --header "X-OpenAM-Password: <your-password>" --header "Content-Type: application/json" --data "{}" https://<your-server>/openam/json/authenticatee

This call returns the JSON object shown next that includes a tokenId that can be used with subsequent calls to the service:

{ "tokenId": "AQIC5wM2LY4SfcxYDQOWOowJjHU-DWfz6JtPEfDzbfFC-A8.*AAJTSQACMDEAAlNLABMxNDcyODc5MTQ2MTE3ODk4NDUw*", "successUrl": "/openam/console" }

If I were to specify the wrong password I get the following JSON response with suitable delay to discourage use of this endpoint for brute force attacks:

{ "errorMessage": "Invalid Password!!" }

If you use an incorrect username you get this JSON response:

{ "errorMessage": "Authentication Failed!!" }

For the successful authentication, I can see that a valid session has been created by looking in Open AM's Session console available in each realm. There is also an endpoint that verifies if a given token is still valid meaning the user's session is still active. You can hit that with the following request substituting in your token of course:

curl --request POST --data "tokenid=AQIC5wM2LY4SfcxYDQOWOowJjHU-DWfz6JtPEfDzbfFC-A8.*AAJTSQACMDEAAlNLABMxNDcyODc5MTQ2MTE3ODk4NDUw*" https://<your-server>/openam/identity/isTokenValid

That returns a text/plain response containing the answer:

boolean=true

If I return to the open AM Session console and terminate the boydkr session and then hit that endpoint again with that token I now see that the token is no longer valid:

boolean=false

And that check for token validity does not impact the session. In other words, the server does not treat that request as an indication of user activity and hence does not update the Time Idle shown in Open AM's Session console. As such, I envision this could be useful as a means for a client side javascript app to know if the session has timed out and take steps to prevent the user from losing data they may be engaged in creating like a blog post entry they are editing but haven't yet posted. 

That is all that I have time for today. Enjoy.