Introduction
This document outlines the following requirement
At present in IBM security Verify Access, the JWKS public endpoint(/sps/jwks) doesn’t provided alg in the JSON response.
The reason for above is this, any certificate key which is presented in JSON can have possibility of different algorithm usage and when a public JWKS endpoint is accessed, its not known beforehand which algorithm to use .Different algorithm example could be RS256, HS256 etc which could be either for Signing use or for encryption use based on returned JSON response at JWKS endpoint.The OpenID provider may require to have alg defined in the JSON response .
The same infomap can be used to fulfill different requirements even at OIDC API definition jwks endpoint URI.
An Example:
The solution proposed in this document takes an approach where customer already knows what algorithm to use.
For example: alg -> RS256
This solution assumes that its known beforehand what algorithm is being used and that algorithm is added as part of the JSON response.
When the Algorithm is known and the endpoint is public JWKS then an infomap is created which will internally call public JWKS and will append alg into the structure.
The same code template is capable of doing different tasks for example(may require modification)
- Different alg based on different KID or some other criteria
- Different responses to different OP by different infomap
The Flow Diagram
Note: Infomap endpoint is protected through Verify Access Reverse Proxy.
High Level Steps used to create the Solution
- Create template files
- Create javascript mapping rule
- Create authentication mechanism
- Create authentication policy
- Make sure infomap uri has unauth acl
- Acls can be readjusted as per the requirement
Create Template Files
- goto LMI -> AAC -> Global Settings -> Template Files
- create a new directory under c->authsvc->authenticator . The name of the directory is addAlToJwt
- under addAlToJwt Directory create a success.json file and put its content as below
- The final structure will appear like this
- The final path of success.json is /authsvc/authenticator/addAlToJwt/success.json
- The path is used in infomap as well as in the mapping rule , Hence its important it should map exactly to same
page.setValue("/authsvc/authenticator/addAlToJwt/success.json");
Create a mapping rule
Rule mappingRuleToaddAlgToJwt is created
- LMI->AAC->Authentication->Advanced
- menu appears to select advanced tab
- upon clickin advanced window to create mapping rule appears and when clicked on Add it will bring up the screen to put javascript code
- save and deploy chances
-
/*
Purpose:The purpose of the code is to be used in Infomap to modify JWKS json response to add Alg example, alg:256 to it.
At present the jwsk public endpoint of verify access doesn't return alg at (/sps/jwks)
The full documentation is provided at the Blog
Blog -> https://community.ibm.com/community/user/security/blogs/tushar-prasad1/2022/05/21/
*/
importPackage(Packages.com.tivoli.am.fim.trustserver.sts.utilities);
importClass(Packages.com.tivoli.am.fim.trustserver.sts.utilities.IDMappingExtUtils);
importClass(Packages.com.ibm.security.access.httpclient.HttpClientV2);
const RUNTIME_HOST='http://localhost';
const URI_PUBLIC_JWKS="/sps/jwks";
let algToAdd="RS256";
let urlString=RUNTIME_HOST+URI_PUBLIC_JWKS;
try
{
let response=new HttpResponse();
response=HttpClientV2.httpGet(urlString);
var httpData=response.getBody();
var httpResponseCode=response.getCode();
}
catch(error)
{
IDMappingExtUtils.traceString("The error around httpcall"+error) ;
}
try
{
if(httpResponseCode == 200)
{
IDMappingExtUtils.traceString("Method addAlgtoJwtcalled"+httpData.toString());
let addforSig=true;
let addforEnc=true;
inputJwt=httpData.toString();
let parsedJson=JSON.parse(inputJwt);
for(keys in parsedJson)
{
for(let j=0; j<parsedJson.keys.length;j++)
{
let sigVal=parsedJson.keys[j].use;
if(sigVal.match('sig') && addforSig)
{
//add alg for sig
parsedJson.keys[j].alg=algToAdd;
}
if(sigVal.match('enc') && addforEnc)
{
//add alg for sig
parsedJson.keys[j].alg=algToAdd;
}
}
}
page.setValue("/authsvc/authenticator/addAlToJwt/success.json");
macros.put("@result@", JSON.stringify(parsedJson));
//success.setValue(false);
success.endPolicyWithoutCredential();
}
else
{
IDMappingExtUtils.traceString("The status code is not 200") ;
}
}
catch(error)
{
IDMappingExtUtils.traceString("The error around putting jwt"+error) ;
}
Create Infomap Authentication Mechanism
- Goto LMI->AAC->Authentication->mechanisms
- select Infomap Authentication
- This will start the flow to create new Infomap Authentication Mechanism
- After filling General properties , goto properties tab to select mapping rule, mappingRuleToaddAlgToJwt (created in earlier steps) and also give the full path of Tempalte Page which is /authsvc/authenticator/addAlToJwt/success.json
- save and deploy changes which will create the Infomap Mechanism by the name addAlgToJson
Create an Authentication Policy
- goto LMI->AAC->Policies
- click on + button to add
- In the above steps, you see policy is given an name -> policyToAddAlg(do note this will be used to call the infomap from browser or the OP) and its urn is -> urn:ibm:security:authentication:asf:policyToAddAlg and workflow steps points to infomap addAlgToJson which was created in earlier steps.
- Save and deploy changes
Miscellaneous settings
- Disable encoding of the Macro @result@ . @result@ macro is used to store the result passed back to client( OP or browser) Hence it needs to be made sure that this is not encoded
- Goto LMI-> Advanced Configuration
- find sps.page.notEscapedMacros and set macro @result@ into it
- save and deploy changes
Two ways now to invoke the infomap
- Goto LMI-> AAC->Advanced Configuration and check property of sps.authService.policyKickoffMethod
- when sps.authService.policyKickoffMethod -> Query then Infomap uril will be https://<reverserproxy/<junctionname/sps/apiauthsvc?PolicyId=urn:ibm:security:authentication:asf:policyToAddAlg
- when sps.authService.policyKickoffMethod -> Query then Infomap uril will be https://<reverserproxy/<junctionname/sps/apiauthsvc/policy/policyToAddAlg (do note instead or urn just the policyname is used)
- when sps.authService.policyKickoffMethod -> both ,you can use either of above method to invoke
Result
After successfully creating all the steps( The acl needs to be adjusted accordingly and then URL can be accessed which in turn will return a json response with Alg="256" and mapping rule can be readjusted to set other values)
curl --location --request GET 'https://192.1xx/mga/sps/apiauthsvc/policy/policyToAddAlg'
Summary
By following this document, you can create an infomap which will add alg into the json response.
Reference:The Infomap javascript can be found at :
https://github.com/IBM-Security/isam-support/tree/master/config-example/aac/info_map_js/infomap_addAlgorithm_to_jwks_endpoint.jsAuthor:Tushar Prasad - IBM
Nicholas Lloyd - IBM