OAuth verification for JWT Payload

Hello @chrisp,

Take a look at this rule implemented for custom authentication on a Web Service source. You can use this as a connector rule in the beforeOperationRule on any operation where the custom authentication is needed.

<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE Rule PUBLIC "sailpoint.dtd" "sailpoint.dtd">
 <Rule language="beanshell" name="Custom Authentication" type="WebServiceBeforeOperationRule">
    <Description>
      This rule is used by the  Web Services connector before performing any operation like testconnection,
      aggregation etc.
    </Description>
    <Signature returnType="EndPoint">
      <Inputs>
        <Argument name="log">
          <Description>
            The log object associated with the SailPointContext.
          </Description>
        </Argument>
        <Argument name="context">
          <Description>
            A sailpoint.api.SailPointContext object that can be used to query the database if necessary.
          </Description>
        </Argument>
        <Argument name="application">
          <Description>The application whose data file is being processed.</Description>
        </Argument>
        <Argument name="requestEndPoint">
          <Description>The current request information contain header, body, context url, method type, response attribute map,
            successful response code
          </Description>
        </Argument>
        <Argument name="oldResponseMap">
          <Description>earlier response object </Description>
        </Argument>
        <Argument name="restClient">
          <Description>REST Client Object</Description>
        </Argument>
      </Inputs>
      <Returns>
        <Argument name="EndPoint">
          <Description>Updated EndPoint Object</Description>
        </Argument>
      </Returns>
    </Signature>
    <Source><![CDATA[
	  
		import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.util.io.pem.PemObject;
import org.bouncycastle.util.io.pem.PemReader;
import org.jose4j.jws.JsonWebSignature;
import org.jose4j.jwt.JwtClaims;
import org.jose4j.lang.JoseException;
import org.json.JSONException;
import org.json.JSONObject;
import com.squareup.okhttp.MediaType;
import com.squareup.okhttp.OkHttpClient;
import com.squareup.okhttp.Request;
import com.squareup.okhttp.RequestBody;
import com.squareup.okhttp.Response;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.StringReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.interfaces.RSAPrivateKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.time.Instant;
import java.time.temporal.ChronoUnit;
import java.util.Map;

		
		public String generateToken() throws NoSuchAlgorithmException, InvalidKeySpecException, IOException, JoseException {
        java.security.Security.addProvider(new BouncyCastleProvider());
		// Creating instance of PEM reader to get the Secret Key
		PemReader pemReader = new PemReader(new StringReader(SECRET_KEY));
		PemObject pemObject;
		pemObject = pemReader.readPemObject();

		//Getting the RSA instance for KeyFactory
		KeyFactory factory = KeyFactory.getInstance("RSA");
		byte[] content = pemObject.getContent();
		PKCS8EncodedKeySpec privKeySpec = new PKCS8EncodedKeySpec(content);
		RSAPrivateKey privateKey = (RSAPrivateKey) factory.generatePrivate(privKeySpec);

		//Getting the Unix time for UTC
		long unixTime = Instant.now().getEpochSecond();
		//Adding a minute to Unix time UTC

		long unixTime1 = Instant.now().plus(1, ChronoUnit.MINUTES).getEpochSecond();
	
			 JwtClaims claims = new JwtClaims();
			 claims.setClaim("iss","<issuer>");
			 claims.setClaim("aud","<aud_value>");
			 claims.setClaim("scope","<scopes>");
			 claims.setClaim("iat",unixTime);
			 claims.setClaim("exp",unixTime1);
			 
			 JsonWebSignature jws = new JsonWebSignature();
		        jws.setDoKeyValidation(false);
		        jws.setPayload(claims.toJson());
		        jws.setKey(privateKey);
		        jws.setAlgorithmHeaderValue("RS256");

		return jws.getCompactSerialization();
	}

	private  String jsonObjectCreator( String token) throws JSONException {
	log.error("Custom Auth Rule : Inside jsonObjectCreator()" );
		JSONObject obj=new JSONObject();
				obj.put("grant_type", "urn:ietf:params:oauth:grant-type:jwt-bearer");
				obj.put("assertion", token);
		String json = obj.toString();
		log.error("Custom Auth Rule : The json object is " +  json.toString() );
		return json;
	}
	
	
	
			 log.error("Custom Authentication : Rule Started");
	private static MediaType JSON= MediaType.parse("application/json; charset=utf-8");
	private static String SECRET_KEY = "<Secret Key>";

		String token= "";
        String jsonBody ="";
        String access_token="";
Map bodyMap = (Map) requestEndPoint.getBody();
		 try {
            token = generateToken();
            if(!token.isEmpty() || token !=null) {
					 log.error("Custom Authentication : JWT Assertion generated");
            	 jsonBody = jsonObjectCreator(token);
            }
            
            if(!jsonBody.isEmpty() || jsonBody !=null) {			
bodyMap.put("jsonBody", jsonBody);
            }
        }catch (JoseException e) {
			log.error("Custom Auth Rule : Exception occurred : " + e.toString());
		} catch (NoSuchAlgorithmException e) {
            log.error("Custom Auth Rule : Exception occurred : " + e.toString());
        } catch (InvalidKeySpecException e) {
            log.error("Custom Auth Rule : Exception occurred : " + e.toString());
        } catch (IOException e) {
            log.error("Custom Auth Rule : Exception occurred : " + e.toString());
        }catch (JSONException e) {
			 log.error("Custom Auth Rule : Exception occurred : " + e.toString());
		}finally {
           requestEndPoint.setBody(bodyMap);
			 log.error("Custom Authentication : In Finally block");
			return requestEndPoint;
        }
		
		 
		 ]]>
    </Source>
  </Rule>

1 Like