Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 57 additions & 0 deletions functionsbasicauth/.classpath
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" output="target/classes" path="src/main/java">
<attributes>
<attribute name="optional" value="true"/>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry excluding="**" kind="src" output="target/classes" path="src/main/resources">
<attributes>
<attribute name="maven.pomderived" value="true"/>
<attribute name="optional" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="src" output="target/test-classes" path="src/test/java">
<attributes>
<attribute name="test" value="true"/>
<attribute name="optional" value="true"/>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry excluding="**" kind="src" output="target/test-classes" path="src/test/resources">
<attributes>
<attribute name="test" value="true"/>
<attribute name="maven.pomderived" value="true"/>
<attribute name="optional" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-17">
<attributes>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
<attributes>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="src" path="target/generated-sources/annotations">
<attributes>
<attribute name="ignore_optional_problems" value="true"/>
<attribute name="optional" value="true"/>
<attribute name="maven.pomderived" value="true"/>
<attribute name="m2e-apt" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="src" output="target/test-classes" path="target/generated-test-sources/test-annotations">
<attributes>
<attribute name="optional" value="true"/>
<attribute name="maven.pomderived" value="true"/>
<attribute name="ignore_optional_problems" value="true"/>
<attribute name="m2e-apt" value="true"/>
<attribute name="test" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="output" path="target/classes"/>
</classpath>
47 changes: 47 additions & 0 deletions functionsbasicauth/.factorypath
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
<factorypath>
<factorypathentry kind="VARJAR" id="M2_REPO/com/fnproject/fn/api/1.0.193/api-1.0.193.jar" enabled="true" runInBatchMode="false"/>
<factorypathentry kind="VARJAR" id="M2_REPO/commons-codec/commons-codec/1.15/commons-codec-1.15.jar" enabled="true" runInBatchMode="false"/>
<factorypathentry kind="VARJAR" id="M2_REPO/commons-cli/commons-cli/1.5.0/commons-cli-1.5.0.jar" enabled="true" runInBatchMode="false"/>
<factorypathentry kind="VARJAR" id="M2_REPO/com/oracle/oci/sdk/oci-java-sdk-core/3.17.0/oci-java-sdk-core-3.17.0.jar" enabled="true" runInBatchMode="false"/>
<factorypathentry kind="VARJAR" id="M2_REPO/com/oracle/oci/sdk/oci-java-sdk-common/3.17.0/oci-java-sdk-common-3.17.0.jar" enabled="true" runInBatchMode="false"/>
<factorypathentry kind="VARJAR" id="M2_REPO/com/fasterxml/jackson/core/jackson-annotations/2.13.1/jackson-annotations-2.13.1.jar" enabled="true" runInBatchMode="false"/>
<factorypathentry kind="VARJAR" id="M2_REPO/org/bouncycastle/bcpkix-jdk15on/1.70/bcpkix-jdk15on-1.70.jar" enabled="true" runInBatchMode="false"/>
<factorypathentry kind="VARJAR" id="M2_REPO/org/bouncycastle/bcutil-jdk15on/1.70/bcutil-jdk15on-1.70.jar" enabled="true" runInBatchMode="false"/>
<factorypathentry kind="VARJAR" id="M2_REPO/org/bouncycastle/bcprov-jdk15on/1.70/bcprov-jdk15on-1.70.jar" enabled="true" runInBatchMode="false"/>
<factorypathentry kind="VARJAR" id="M2_REPO/com/oracle/oci/sdk/oci-java-sdk-circuitbreaker/3.17.0/oci-java-sdk-circuitbreaker-3.17.0.jar" enabled="true" runInBatchMode="false"/>
<factorypathentry kind="VARJAR" id="M2_REPO/io/github/resilience4j/resilience4j-circuitbreaker/1.7.1/resilience4j-circuitbreaker-1.7.1.jar" enabled="true" runInBatchMode="false"/>
<factorypathentry kind="VARJAR" id="M2_REPO/io/vavr/vavr/0.10.2/vavr-0.10.2.jar" enabled="true" runInBatchMode="false"/>
<factorypathentry kind="VARJAR" id="M2_REPO/io/vavr/vavr-match/0.10.2/vavr-match-0.10.2.jar" enabled="true" runInBatchMode="false"/>
<factorypathentry kind="VARJAR" id="M2_REPO/io/github/resilience4j/resilience4j-core/1.7.1/resilience4j-core-1.7.1.jar" enabled="true" runInBatchMode="false"/>
<factorypathentry kind="VARJAR" id="M2_REPO/com/oracle/oci/sdk/oci-java-sdk-workrequests/3.17.0/oci-java-sdk-workrequests-3.17.0.jar" enabled="true" runInBatchMode="false"/>
<factorypathentry kind="VARJAR" id="M2_REPO/com/oracle/oci/sdk/oci-java-sdk-secrets/3.17.0/oci-java-sdk-secrets-3.17.0.jar" enabled="true" runInBatchMode="false"/>
<factorypathentry kind="VARJAR" id="M2_REPO/com/oracle/oci/sdk/oci-java-sdk-common-httpclient-jersey3/3.17.0/oci-java-sdk-common-httpclient-jersey3-3.17.0.jar" enabled="true" runInBatchMode="false"/>
<factorypathentry kind="VARJAR" id="M2_REPO/com/oracle/oci/sdk/oci-java-sdk-common-httpclient/3.17.0/oci-java-sdk-common-httpclient-3.17.0.jar" enabled="true" runInBatchMode="false"/>
<factorypathentry kind="VARJAR" id="M2_REPO/jakarta/ws/rs/jakarta.ws.rs-api/3.0.0/jakarta.ws.rs-api-3.0.0.jar" enabled="true" runInBatchMode="false"/>
<factorypathentry kind="VARJAR" id="M2_REPO/jakarta/annotation/jakarta.annotation-api/2.1.1/jakarta.annotation-api-2.1.1.jar" enabled="true" runInBatchMode="false"/>
<factorypathentry kind="VARJAR" id="M2_REPO/com/fasterxml/jackson/core/jackson-core/2.13.1/jackson-core-2.13.1.jar" enabled="true" runInBatchMode="false"/>
<factorypathentry kind="VARJAR" id="M2_REPO/com/fasterxml/jackson/core/jackson-databind/2.13.4.2/jackson-databind-2.13.4.2.jar" enabled="true" runInBatchMode="false"/>
<factorypathentry kind="VARJAR" id="M2_REPO/org/glassfish/jersey/core/jersey-common/3.0.8/jersey-common-3.0.8.jar" enabled="true" runInBatchMode="false"/>
<factorypathentry kind="VARJAR" id="M2_REPO/jakarta/inject/jakarta.inject-api/2.0.1/jakarta.inject-api-2.0.1.jar" enabled="true" runInBatchMode="false"/>
<factorypathentry kind="VARJAR" id="M2_REPO/org/glassfish/hk2/osgi-resource-locator/1.0.3/osgi-resource-locator-1.0.3.jar" enabled="true" runInBatchMode="false"/>
<factorypathentry kind="VARJAR" id="M2_REPO/org/glassfish/jersey/core/jersey-client/3.0.8/jersey-client-3.0.8.jar" enabled="true" runInBatchMode="false"/>
<factorypathentry kind="VARJAR" id="M2_REPO/org/glassfish/jersey/media/jersey-media-json-jackson/3.0.8/jersey-media-json-jackson-3.0.8.jar" enabled="true" runInBatchMode="false"/>
<factorypathentry kind="VARJAR" id="M2_REPO/org/glassfish/jersey/ext/jersey-entity-filtering/3.0.8/jersey-entity-filtering-3.0.8.jar" enabled="true" runInBatchMode="false"/>
<factorypathentry kind="VARJAR" id="M2_REPO/com/fasterxml/jackson/module/jackson-module-jakarta-xmlbind-annotations/2.13.3/jackson-module-jakarta-xmlbind-annotations-2.13.3.jar" enabled="true" runInBatchMode="false"/>
<factorypathentry kind="VARJAR" id="M2_REPO/com/sun/activation/jakarta.activation/2.0.1/jakarta.activation-2.0.1.jar" enabled="true" runInBatchMode="false"/>
<factorypathentry kind="VARJAR" id="M2_REPO/jakarta/xml/bind/jakarta.xml.bind-api/3.0.1/jakarta.xml.bind-api-3.0.1.jar" enabled="true" runInBatchMode="false"/>
<factorypathentry kind="VARJAR" id="M2_REPO/org/glassfish/jersey/inject/jersey-hk2/3.0.8/jersey-hk2-3.0.8.jar" enabled="true" runInBatchMode="false"/>
<factorypathentry kind="VARJAR" id="M2_REPO/org/glassfish/hk2/hk2-locator/3.0.3/hk2-locator-3.0.3.jar" enabled="true" runInBatchMode="false"/>
<factorypathentry kind="VARJAR" id="M2_REPO/org/glassfish/hk2/external/aopalliance-repackaged/3.0.3/aopalliance-repackaged-3.0.3.jar" enabled="true" runInBatchMode="false"/>
<factorypathentry kind="VARJAR" id="M2_REPO/org/glassfish/hk2/hk2-api/3.0.3/hk2-api-3.0.3.jar" enabled="true" runInBatchMode="false"/>
<factorypathentry kind="VARJAR" id="M2_REPO/org/glassfish/hk2/hk2-utils/3.0.3/hk2-utils-3.0.3.jar" enabled="true" runInBatchMode="false"/>
<factorypathentry kind="VARJAR" id="M2_REPO/org/javassist/javassist/3.28.0-GA/javassist-3.28.0-GA.jar" enabled="true" runInBatchMode="false"/>
<factorypathentry kind="VARJAR" id="M2_REPO/org/glassfish/jersey/connectors/jersey-apache-connector/3.0.8/jersey-apache-connector-3.0.8.jar" enabled="true" runInBatchMode="false"/>
<factorypathentry kind="VARJAR" id="M2_REPO/org/apache/httpcomponents/httpclient/4.5.13/httpclient-4.5.13.jar" enabled="true" runInBatchMode="false"/>
<factorypathentry kind="VARJAR" id="M2_REPO/commons-logging/commons-logging/1.2/commons-logging-1.2.jar" enabled="true" runInBatchMode="false"/>
<factorypathentry kind="VARJAR" id="M2_REPO/org/apache/httpcomponents/httpcore/4.4.13/httpcore-4.4.13.jar" enabled="true" runInBatchMode="false"/>
<factorypathentry kind="VARJAR" id="M2_REPO/org/slf4j/slf4j-api/1.7.33/slf4j-api-1.7.33.jar" enabled="true" runInBatchMode="false"/>
<factorypathentry kind="VARJAR" id="M2_REPO/org/slf4j/slf4j-jdk14/1.7.33/slf4j-jdk14-1.7.33.jar" enabled="true" runInBatchMode="false"/>
<factorypathentry kind="VARJAR" id="M2_REPO/org/projectlombok/lombok/1.18.30/lombok-1.18.30.jar" enabled="true" runInBatchMode="false"/>
<factorypathentry kind="PLUGIN" id="org.eclipse.jst.ws.annotations.core" enabled="false" runInBatchMode="false"/>
</factorypath>
1 change: 1 addition & 0 deletions functionsbasicauth/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/target/
23 changes: 23 additions & 0 deletions functionsbasicauth/.project
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>functionsbasicauth</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.m2e.core.maven2Builder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.jdt.core.javanature</nature>
<nature>org.eclipse.m2e.core.maven2Nature</nature>
</natures>
</projectDescription>
6 changes: 6 additions & 0 deletions functionsbasicauth/.settings/org.eclipse.core.resources.prefs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
eclipse.preferences.version=1
encoding//src/main/java=UTF-8
encoding//src/main/resources=UTF-8
encoding//src/test/java=UTF-8
encoding//src/test/resources=UTF-8
encoding/<project>=UTF-8
4 changes: 4 additions & 0 deletions functionsbasicauth/.settings/org.eclipse.jdt.apt.core.prefs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
eclipse.preferences.version=1
org.eclipse.jdt.apt.aptEnabled=true
org.eclipse.jdt.apt.genSrcDir=target/generated-sources/annotations
org.eclipse.jdt.apt.genTestSrcDir=target/generated-test-sources/test-annotations
9 changes: 9 additions & 0 deletions functionsbasicauth/.settings/org.eclipse.jdt.core.prefs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.targetPlatform=17
org.eclipse.jdt.core.compiler.compliance=17
org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled
org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=ignore
org.eclipse.jdt.core.compiler.processAnnotations=enabled
org.eclipse.jdt.core.compiler.release=disabled
org.eclipse.jdt.core.compiler.source=17
4 changes: 4 additions & 0 deletions functionsbasicauth/.settings/org.eclipse.m2e.core.prefs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
activeProfiles=
eclipse.preferences.version=1
resolveWorkspaceProjects=true
version=1
93 changes: 93 additions & 0 deletions functionsbasicauth/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
# Basic Authentication function for API Gateway

This is an example of how to use a function to authenticate an API Gateway Basic auth header.

## Prequisites

To compile and install this function you will need to have followed the relevant [instructions to setup the functions environment](https://docs.oracle.com/en-us/iaas/Content/Functions/home.htm) (chose if it's going to be cloud shell, local development etc. Personally I think the cloud shell is the easiest to setup)

## Create the application and it's networking

Identify the VCN and subnet to put your function, I'd suggest using the see the information in the [Creating application](https://docs.oracle.com/en-us/iaas/Content/Functions/Tasks/functionscreatingapps.htm#top) Then use those instructions to create a functions application (this holds the functions) If you already have an existing setup or API GW you can use the private subnet behind the API GW.

I would also recommend that you create a log group (The "logs" section on the left side of the applications page) for the log information
Once the application is created you will need to update the NSG (if using them) to allow the API GW to talk to the function. Do this by going to the application page and wheere the NSG's are listed add the NSG being used by the API GET (look at the API GW page if needed to figure this out)

## Create the function and upload it

Assuming you've done the quick start instructions you can now upload your function. See the [Creating your function](https://docs.oracle.com/en-us/iaas/Content/Functions/Tasks/functionsuploading.htm) instructions, but as you have the functions code just make sure you are in this projects root directory and run compile and upload the function Remember to use the app name you just created.

```
fn -v deploy --app basic
```

## Setup the function configuration

Use the function configuration to define the way the function will behave. This function supports the following configuration options :

- `auth-source` Optional. The location of the actual values to check, if set to `vault` the code will assume the value in `auth-secret` is the OCID to be used to load the secret from the vault, any other value and it will try to load the contents from the `auth-secret` config property. The default is `config` (So loading from the function config)

- `auth-secret` Required, must contain either the OCID of the secrets to use (if `auth-source` is set to `vault`) OR value to check (for any onther value of the `auth-source` config) There is no default. The value can be in plain text or base 64 encoded (see the `auth-source-format` config setting)

- `auth-source-format` Indicates the format of the value to check, if set to `base64` then the retrieved value (from the config or the vault secret) will be decoded form base64 before being used for compartisson checks, if it's `plaintext` then it will be used cdirectly. The default is `plaintext`

- `result-cache-seconds` Indicates how long to ask the API GW to cache the results for, if not a valid number or provided does not specify a valid cache time on the returned data and will use the API GFW default (60 seconds at the time of writing) If below 60 or above 3600 will be wrapped to fit within that range as per the API GW max / min valid responses. Defaults ot no value provided and thus to the API GW default.

- `testing-mode` **MUST NOT BE SET ON PRODUCTION SYSTEMS.** If set to true will include the values for auth-secret and any provided values in the log data, this is of course a very bad thing for anything other than testing the function code and logic, and **MUST NOT BE SET ON PRODUCTION SYSTEMS.** Defaults to false.

## Vault setup

If you are storing the auth details in a vault (`auth-source`is set to `vault` above) then create a vault (if needed) then a master signing key (again if needed) then a secret containing either the plaintext auth details OR the base64 encoded version (if using the base 64 encoded feature in the create secret make sure you set the secret type to plaintext, if adding using the plain text feature AND you are pasting the base64 encoded version then you will need to ensure that the auth type is set to base 64)

Get the OCID of the secret and put it into the `auth-secret` in the config and then set the `auth-source` to vault.


## Functions dynamic group and policies to access vault secrets

To access the secrets in the vault (if you chose to store the password in the vault) Call the dynamic group `ExperientialFunctions` you will need to create a dynamic group to identify the function. The simplest version of this is

```
All {resource.type = 'fnfunc'}
```

This will match all functions, but you may want to restrict this further, for example adding a restriction for a specific compartment

```
All {resource.type = 'fnfunc', resource.compartment.id='compartment ocid'}
```
Would only match functions in the compartment with the specified OCID.

Once you have a dynamic group to identify the function then you need a policy that will let that group access the vault secret. This is a basic policy rule

```
allow dynamic-group ExperientialFunctions to manage secret-family in compartment experiential
```

Note that if the dynamic group was created using an identity someon (e.g. ) then the domain name needs ro be added to the DG name, for example

```
allow dynamic-group OracleIdentityCloudService/ExperientialFunctions to manage secret-family in compartment experiential
```

However you may want to restrict this further.


## Configure a policy for APIGW to call functions

The API Gateway needs to be able to call functions. create a policy rule to allow API Gateways in the specified compartment to access functions.

```
ALLOW any-user to use functions-family in compartment experiential where ALL {request.principal.type= 'ApiGateway', request.resource.compartment.id = 'ocid1.compartment.oc1......ocid'}
```

## Configuring the API Gateway to authenticate using the function

Follow the steps in the API Gateway [quick start documentation](https://docs.oracle.com/en-us/iaas/Content/APIGateway/Tasks/apigatewayquickstartsetupcreatedeploy.htm) to setup the appropriate networks and gateways

Create a deployment and [add the function you created as single authentication multi argument authorizer function](https://docs.oracle.com/en-us/iaas/Content/APIGateway/Tasks/apigatewayusingauthorizerfunction.htm) Note that you don't need to create the function itself, that's what this code does. You just need to configure the gateway to use it.

For the authorizer function setup the following function argument mapping

`request.headers.authorization` -> `authorization`

The argument name must be lower case
1 change: 1 addition & 0 deletions functionsbasicauth/body.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Life, the universe and everything
7 changes: 7 additions & 0 deletions functionsbasicauth/func.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
schema_version: 20180708
name: verify-basic-auth
version: 0.0.1
runtime: java
build_image: fnproject/fn-java-fdk-build:jdk17-1.0.193
run_image: fnproject/fn-java-fdk:jre17-1.0.193
cmd: com.oracle.timg.demos.functions.basicauth.BasicAuthFunction::handleAPIGWAuthenticationRequest
18 changes: 18 additions & 0 deletions functionsbasicauth/oictest.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"customerCode": "808080",
"customerName": "LOGIPE FINTECH PRIVATE LIMITED - DEMO through APIGW",
"productCode": "UPICOLL",
"productDescription": "Regular",
"poolingAccountNumber": "10089295611",
"transactionType": "Collections",
"dataKey": "751 10204 28-01-2023L00147700340000000001",
"batchAmt": "100.00",
"batchAmtCcd": "INR",
"vaNumber": "8080809837148839",
"utrNo": "302876436829",
"creditGenerationTime": "28-JAN-23 04.59.33.488870 AM",
"remitterName": "BALVANTSINGHSOMAKKHANSINGH",
"remitterAccountNumber": "15900100013792",
"remittingBankName": "BANK OF BARODA",
"ifscCode": "BARB0JASPUR"
}
Loading