Skip to content

Commit d9d6ca2

Browse files
authored
Merge pull request #7 from oracle-devrel/basic-auth
added a basic-auth fuction for simple authentication processes
2 parents 4851cb0 + d8efea9 commit d9d6ca2

19 files changed

+1054
-0
lines changed

functionsbasicauth/.classpath

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<classpath>
3+
<classpathentry kind="src" output="target/classes" path="src/main/java">
4+
<attributes>
5+
<attribute name="optional" value="true"/>
6+
<attribute name="maven.pomderived" value="true"/>
7+
</attributes>
8+
</classpathentry>
9+
<classpathentry excluding="**" kind="src" output="target/classes" path="src/main/resources">
10+
<attributes>
11+
<attribute name="maven.pomderived" value="true"/>
12+
<attribute name="optional" value="true"/>
13+
</attributes>
14+
</classpathentry>
15+
<classpathentry kind="src" output="target/test-classes" path="src/test/java">
16+
<attributes>
17+
<attribute name="test" value="true"/>
18+
<attribute name="optional" value="true"/>
19+
<attribute name="maven.pomderived" value="true"/>
20+
</attributes>
21+
</classpathentry>
22+
<classpathentry excluding="**" kind="src" output="target/test-classes" path="src/test/resources">
23+
<attributes>
24+
<attribute name="test" value="true"/>
25+
<attribute name="maven.pomderived" value="true"/>
26+
<attribute name="optional" value="true"/>
27+
</attributes>
28+
</classpathentry>
29+
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-17">
30+
<attributes>
31+
<attribute name="maven.pomderived" value="true"/>
32+
</attributes>
33+
</classpathentry>
34+
<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
35+
<attributes>
36+
<attribute name="maven.pomderived" value="true"/>
37+
</attributes>
38+
</classpathentry>
39+
<classpathentry kind="src" path="target/generated-sources/annotations">
40+
<attributes>
41+
<attribute name="ignore_optional_problems" value="true"/>
42+
<attribute name="optional" value="true"/>
43+
<attribute name="maven.pomderived" value="true"/>
44+
<attribute name="m2e-apt" value="true"/>
45+
</attributes>
46+
</classpathentry>
47+
<classpathentry kind="src" output="target/test-classes" path="target/generated-test-sources/test-annotations">
48+
<attributes>
49+
<attribute name="optional" value="true"/>
50+
<attribute name="maven.pomderived" value="true"/>
51+
<attribute name="ignore_optional_problems" value="true"/>
52+
<attribute name="m2e-apt" value="true"/>
53+
<attribute name="test" value="true"/>
54+
</attributes>
55+
</classpathentry>
56+
<classpathentry kind="output" path="target/classes"/>
57+
</classpath>

functionsbasicauth/.factorypath

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
<factorypath>
2+
<factorypathentry kind="VARJAR" id="M2_REPO/com/fnproject/fn/api/1.0.193/api-1.0.193.jar" enabled="true" runInBatchMode="false"/>
3+
<factorypathentry kind="VARJAR" id="M2_REPO/commons-codec/commons-codec/1.15/commons-codec-1.15.jar" enabled="true" runInBatchMode="false"/>
4+
<factorypathentry kind="VARJAR" id="M2_REPO/commons-cli/commons-cli/1.5.0/commons-cli-1.5.0.jar" enabled="true" runInBatchMode="false"/>
5+
<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"/>
6+
<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"/>
7+
<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"/>
8+
<factorypathentry kind="VARJAR" id="M2_REPO/org/bouncycastle/bcpkix-jdk15on/1.70/bcpkix-jdk15on-1.70.jar" enabled="true" runInBatchMode="false"/>
9+
<factorypathentry kind="VARJAR" id="M2_REPO/org/bouncycastle/bcutil-jdk15on/1.70/bcutil-jdk15on-1.70.jar" enabled="true" runInBatchMode="false"/>
10+
<factorypathentry kind="VARJAR" id="M2_REPO/org/bouncycastle/bcprov-jdk15on/1.70/bcprov-jdk15on-1.70.jar" enabled="true" runInBatchMode="false"/>
11+
<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"/>
12+
<factorypathentry kind="VARJAR" id="M2_REPO/io/github/resilience4j/resilience4j-circuitbreaker/1.7.1/resilience4j-circuitbreaker-1.7.1.jar" enabled="true" runInBatchMode="false"/>
13+
<factorypathentry kind="VARJAR" id="M2_REPO/io/vavr/vavr/0.10.2/vavr-0.10.2.jar" enabled="true" runInBatchMode="false"/>
14+
<factorypathentry kind="VARJAR" id="M2_REPO/io/vavr/vavr-match/0.10.2/vavr-match-0.10.2.jar" enabled="true" runInBatchMode="false"/>
15+
<factorypathentry kind="VARJAR" id="M2_REPO/io/github/resilience4j/resilience4j-core/1.7.1/resilience4j-core-1.7.1.jar" enabled="true" runInBatchMode="false"/>
16+
<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"/>
17+
<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"/>
18+
<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"/>
19+
<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"/>
20+
<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"/>
21+
<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"/>
22+
<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"/>
23+
<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"/>
24+
<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"/>
25+
<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"/>
26+
<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"/>
27+
<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"/>
28+
<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"/>
29+
<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"/>
30+
<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"/>
31+
<factorypathentry kind="VARJAR" id="M2_REPO/com/sun/activation/jakarta.activation/2.0.1/jakarta.activation-2.0.1.jar" enabled="true" runInBatchMode="false"/>
32+
<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"/>
33+
<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"/>
34+
<factorypathentry kind="VARJAR" id="M2_REPO/org/glassfish/hk2/hk2-locator/3.0.3/hk2-locator-3.0.3.jar" enabled="true" runInBatchMode="false"/>
35+
<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"/>
36+
<factorypathentry kind="VARJAR" id="M2_REPO/org/glassfish/hk2/hk2-api/3.0.3/hk2-api-3.0.3.jar" enabled="true" runInBatchMode="false"/>
37+
<factorypathentry kind="VARJAR" id="M2_REPO/org/glassfish/hk2/hk2-utils/3.0.3/hk2-utils-3.0.3.jar" enabled="true" runInBatchMode="false"/>
38+
<factorypathentry kind="VARJAR" id="M2_REPO/org/javassist/javassist/3.28.0-GA/javassist-3.28.0-GA.jar" enabled="true" runInBatchMode="false"/>
39+
<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"/>
40+
<factorypathentry kind="VARJAR" id="M2_REPO/org/apache/httpcomponents/httpclient/4.5.13/httpclient-4.5.13.jar" enabled="true" runInBatchMode="false"/>
41+
<factorypathentry kind="VARJAR" id="M2_REPO/commons-logging/commons-logging/1.2/commons-logging-1.2.jar" enabled="true" runInBatchMode="false"/>
42+
<factorypathentry kind="VARJAR" id="M2_REPO/org/apache/httpcomponents/httpcore/4.4.13/httpcore-4.4.13.jar" enabled="true" runInBatchMode="false"/>
43+
<factorypathentry kind="VARJAR" id="M2_REPO/org/slf4j/slf4j-api/1.7.33/slf4j-api-1.7.33.jar" enabled="true" runInBatchMode="false"/>
44+
<factorypathentry kind="VARJAR" id="M2_REPO/org/slf4j/slf4j-jdk14/1.7.33/slf4j-jdk14-1.7.33.jar" enabled="true" runInBatchMode="false"/>
45+
<factorypathentry kind="VARJAR" id="M2_REPO/org/projectlombok/lombok/1.18.30/lombok-1.18.30.jar" enabled="true" runInBatchMode="false"/>
46+
<factorypathentry kind="PLUGIN" id="org.eclipse.jst.ws.annotations.core" enabled="false" runInBatchMode="false"/>
47+
</factorypath>

functionsbasicauth/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
/target/

functionsbasicauth/.project

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<projectDescription>
3+
<name>functionsbasicauth</name>
4+
<comment></comment>
5+
<projects>
6+
</projects>
7+
<buildSpec>
8+
<buildCommand>
9+
<name>org.eclipse.jdt.core.javabuilder</name>
10+
<arguments>
11+
</arguments>
12+
</buildCommand>
13+
<buildCommand>
14+
<name>org.eclipse.m2e.core.maven2Builder</name>
15+
<arguments>
16+
</arguments>
17+
</buildCommand>
18+
</buildSpec>
19+
<natures>
20+
<nature>org.eclipse.jdt.core.javanature</nature>
21+
<nature>org.eclipse.m2e.core.maven2Nature</nature>
22+
</natures>
23+
</projectDescription>
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
eclipse.preferences.version=1
2+
encoding//src/main/java=UTF-8
3+
encoding//src/main/resources=UTF-8
4+
encoding//src/test/java=UTF-8
5+
encoding//src/test/resources=UTF-8
6+
encoding/<project>=UTF-8
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
eclipse.preferences.version=1
2+
org.eclipse.jdt.apt.aptEnabled=true
3+
org.eclipse.jdt.apt.genSrcDir=target/generated-sources/annotations
4+
org.eclipse.jdt.apt.genTestSrcDir=target/generated-test-sources/test-annotations
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
eclipse.preferences.version=1
2+
org.eclipse.jdt.core.compiler.codegen.targetPlatform=17
3+
org.eclipse.jdt.core.compiler.compliance=17
4+
org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled
5+
org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
6+
org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=ignore
7+
org.eclipse.jdt.core.compiler.processAnnotations=enabled
8+
org.eclipse.jdt.core.compiler.release=disabled
9+
org.eclipse.jdt.core.compiler.source=17
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
activeProfiles=
2+
eclipse.preferences.version=1
3+
resolveWorkspaceProjects=true
4+
version=1

functionsbasicauth/README.md

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
# Basic Authentication function for API Gateway
2+
3+
This is an example of how to use a function to authenticate an API Gateway Basic auth header.
4+
5+
## Prequisites
6+
7+
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)
8+
9+
## Create the application and it's networking
10+
11+
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.
12+
13+
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
14+
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)
15+
16+
## Create the function and upload it
17+
18+
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.
19+
20+
```
21+
fn -v deploy --app basic
22+
```
23+
24+
## Setup the function configuration
25+
26+
Use the function configuration to define the way the function will behave. This function supports the following configuration options :
27+
28+
- `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)
29+
30+
- `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)
31+
32+
- `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`
33+
34+
- `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.
35+
36+
- `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.
37+
38+
## Vault setup
39+
40+
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)
41+
42+
Get the OCID of the secret and put it into the `auth-secret` in the config and then set the `auth-source` to vault.
43+
44+
45+
## Functions dynamic group and policies to access vault secrets
46+
47+
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
48+
49+
```
50+
All {resource.type = 'fnfunc'}
51+
```
52+
53+
This will match all functions, but you may want to restrict this further, for example adding a restriction for a specific compartment
54+
55+
```
56+
All {resource.type = 'fnfunc', resource.compartment.id='compartment ocid'}
57+
```
58+
Would only match functions in the compartment with the specified OCID.
59+
60+
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
61+
62+
```
63+
allow dynamic-group ExperientialFunctions to manage secret-family in compartment experiential
64+
```
65+
66+
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
67+
68+
```
69+
allow dynamic-group OracleIdentityCloudService/ExperientialFunctions to manage secret-family in compartment experiential
70+
```
71+
72+
However you may want to restrict this further.
73+
74+
75+
## Configure a policy for APIGW to call functions
76+
77+
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.
78+
79+
```
80+
ALLOW any-user to use functions-family in compartment experiential where ALL {request.principal.type= 'ApiGateway', request.resource.compartment.id = 'ocid1.compartment.oc1......ocid'}
81+
```
82+
83+
## Configuring the API Gateway to authenticate using the function
84+
85+
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
86+
87+
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.
88+
89+
For the authorizer function setup the following function argument mapping
90+
91+
`request.headers.authorization` -> `authorization`
92+
93+
The argument name must be lower case

functionsbasicauth/body.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Life, the universe and everything

0 commit comments

Comments
 (0)