Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit de5f0c7

Browse files
committed
MPDO:1015 code refactoring
1 parent f80a821 commit de5f0c7

File tree

7 files changed

+279
-146
lines changed

7 files changed

+279
-146
lines changed
Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
schema_version: 20180708
22
name: basicauth
3-
version: 0.0.6
3+
version: 0.0.21
44
runtime: java
55
build_image: fnproject/fn-java-fdk-build:jdk11-1.0.146
66
run_image: fnproject/fn-java-fdk:jre11-1.0.146
77
cmd: com.example.fn.BasicAuth::handleRequest
8+
memory: 512
9+
timeout: 120

‎samples/oci-apigw-idcs-auth-basic/pom.xml

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
<?xml version="1.0" encoding="UTF-8"?>
2-
<project xmlns="http://maven.apache.org/POM/4.0.0"
3-
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4-
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
2+
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
53
<modelVersion>4.0.0</modelVersion>
64
<properties>
75
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
86
<fdk.version>1.0.146</fdk.version>
7+
<jdk.version>11</jdk.version>
98
</properties>
9+
1010
<groupId>com.example.fn</groupId>
1111
<artifactId>basicAuth</artifactId>
12-
<version>1.0.0</version>
12+
<version>1.0.1</version>
1313

1414
<dependencies>
1515
<dependency>
@@ -49,18 +49,18 @@
4949
<artifactId>maven-compiler-plugin</artifactId>
5050
<version>3.3</version>
5151
<configuration>
52-
<source>11</source>
53-
<target>11</target>
52+
<source>${jdk.version}</source>
53+
<target>${jdk.version}</target>
5454
</configuration>
5555
</plugin>
5656
<plugin>
57-
<groupId>org.apache.maven.plugins</groupId>
58-
<artifactId>maven-surefire-plugin</artifactId>
59-
<version>2.22.1</version>
60-
<configuration>
61-
<useSystemClassLoader>false</useSystemClassLoader>
62-
</configuration>
57+
<groupId>org.apache.maven.plugins</groupId>
58+
<artifactId>maven-surefire-plugin</artifactId>
59+
<version>2.22.1</version>
60+
<configuration>
61+
<useSystemClassLoader>false</useSystemClassLoader>
62+
</configuration>
6363
</plugin>
6464
</plugins>
6565
</build>
66-
</project>
66+
</project>
Lines changed: 112 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -1,96 +1,153 @@
11
package com.example.fn;
22

3-
import java.net.http.HttpClient;
4-
import java.net.http.HttpRequest;
3+
import static com.example.fn.util.ResourceServerConfig.TOKEN_PREFIX;
4+
import static com.example.fn.util.ResourceServerConfig.CONFIG_KEY_IDCS_URL;
5+
import static com.example.fn.util.ResourceServerConfig.CONFIG_KEY_CLIENT_ID;
6+
import static com.example.fn.util.ResourceServerConfig.CONFIG_KEY_CLIENT_SECRET;
7+
import static com.example.fn.util.ResourceServerConfig.CONFIG_KEY_SCOPE_AUD;
8+
import static com.example.fn.util.ResourceServerConfig.DEFAULT_GRANT_TYPE;
9+
import static com.example.fn.util.ResourceServerConfig.TOKEN_CLAIM_KEY_EXPIRY;
10+
import static com.example.fn.util.ResourceServerConfig.TOKEN_CLAIM_KEY_SUBJECT;
11+
import static com.example.fn.util.ResourceServerConfig.TOKEN_CLAIM_KEY_SCOPE;
12+
513
import java.net.http.HttpResponse;
6-
import java.net.URI;
714

815
import java.io.IOException;
916
import java.io.UnsupportedEncodingException;
1017
import java.lang.InterruptedException;
1118
import org.json.JSONObject;
12-
import java.util.*;
1319

14-
public class BasicAuth {
15-
public static class Input {
16-
public String type;
17-
public String token;
18-
}
20+
import com.example.fn.util.Helper;
21+
import com.fnproject.fn.api.FnConfiguration;
22+
import com.fnproject.fn.api.RuntimeContext;
1923

20-
public static class Result {
21-
public boolean active = false;
22-
public String principal;
23-
public String[] scope;
24-
public String expiresAt;
25-
}
24+
import java.util.*;
2625

27-
private static final String TOKEN_PREFIX = "Basic ";
28-
private static final String IDCS_URL = ResourceServerConfig.IDCS_URL;
26+
/**
27+
* Main class implementing the {@code handleRequest} method, takes the user
28+
* credentials as input, authenticates the credentials against the identity
29+
* provider and if the authentication is successful then returns the following
30+
* claims from the access token <br/>
31+
* <ul>
32+
* <li>exp</li>
33+
* <li>sub</li>
34+
* <li>scope</li>
35+
* </ul>
36+
*/
37+
public class BasicAuth {
2938

30-
public String[] getUserDetailsFromToken(String token) {
31-
String data = token.substring(TOKEN_PREFIX.length());
32-
String[] user = new String(Base64.getDecoder().decode(data)).split(":", 2);
33-
return user;
39+
private static String IDCS_URL = null;
40+
private static String CLIENT_ID = null;
41+
private static String CLIENT_SECRET = null;
42+
private static String SCOPE_AUD = null;
43+
44+
/**
45+
* Reads the configuration parameters and sets the respective variables during
46+
* function initialization.
47+
*
48+
* @param {@link RuntimeContext} ctx
49+
*/
50+
@FnConfiguration
51+
public void config(final RuntimeContext ctx) {
52+
IDCS_URL = ctx.getConfigurationByKey(CONFIG_KEY_IDCS_URL).orElse(null);
53+
CLIENT_ID = ctx.getConfigurationByKey(CONFIG_KEY_CLIENT_ID).orElse(null);
54+
CLIENT_SECRET = ctx.getConfigurationByKey(CONFIG_KEY_CLIENT_SECRET).orElse(null);
55+
SCOPE_AUD = ctx.getConfigurationByKey(CONFIG_KEY_SCOPE_AUD).orElse(null);
3456
}
3557

36-
public Result handleRequest(Input input) throws UnsupportedEncodingException, InterruptedException {
37-
Result returnValue = new Result();
58+
/**
59+
* Entry point of the function
60+
*
61+
* @param {@link Input} input
62+
* @return {@link Result}
63+
* @throws UnsupportedEncodingException
64+
* @throws InterruptedException
65+
*/
66+
public Result handleRequest(final Input input) throws UnsupportedEncodingException, InterruptedException {
67+
final Result returnValue = new Result();
68+
69+
if (!isConfigValid()) {
70+
returnValue.active = false;
71+
System.out.println(
72+
"Function initialization error, all config parameters not set, please ensure that following config variables are set IDCS_URL, CLIENT_ID, CLIENT_SECRET");
73+
return returnValue;
74+
}
3875

3976
if (input.token == null || !input.token.startsWith(TOKEN_PREFIX)) {
4077
returnValue.active = false;
4178
System.out.println("Request error, missing credentials");
4279
return returnValue;
4380
}
4481

45-
String[] user = getUserDetailsFromToken(input.token);
82+
finalString[] user = getUserDetailsFromToken(input.token);
4683
if (user.length != 2 || user[0] == null || user[0].isEmpty() || user[1] == null || user[1].isEmpty()) {
84+
returnValue.active = false;
4785
System.out.println("Request error username or password missing");
4886
return returnValue;
4987
}
5088

51-
String username = user[0];
52-
String password = user[1];
53-
String clientId = ResourceServerConfig.CLIENT_ID;
54-
String clientSecret = ResourceServerConfig.CLIENT_SECRET;
55-
String authzHdrVal = clientId + ":" + clientSecret;
56-
String idcsScope = ResourceServerConfig.SCOPE_AUD;
57-
58-
String reqBody = "grant_type=password" +
59-
"&username=" + username +
60-
"&password=" + password +
61-
"&scope=" + idcsScope;
89+
final String authzHdrVal = CLIENT_ID + ":" + CLIENT_SECRET;
90+
final String reqBody = Helper.createRequestBody(user[0], user[1], SCOPE_AUD, DEFAULT_GRANT_TYPE);
6291

6392
try {
64-
HttpClient client = HttpClient.newHttpClient();
65-
66-
HttpRequest request = HttpRequest.newBuilder()
67-
.uri(URI.create(IDCS_URL))
68-
.header("Content-Type", "application/x-www-form-urlencoded")
69-
.header("Authorization", "Basic " + Base64.getEncoder().encodeToString(authzHdrVal.getBytes("UTF-8")))
70-
.POST(HttpRequest.BodyPublishers.ofString(reqBody))
71-
.build();
72-
73-
HttpResponse<String> response = client.send( request,
74-
HttpResponse.BodyHandlers.ofString() );
75-
93+
final HttpResponse<String> response = Helper.callIDCS(IDCS_URL, authzHdrVal, reqBody);
7694

7795
if (response.statusCode() == 200) {
96+
final String responseString = (String) response.body();
97+
final JSONObject payload = Helper.getTokenBody(responseString);
7898

79-
String responseString = (String) response.body();
80-
String[] chunks = responseString.split("\\.");
81-
String respjson = new String(Base64.getUrlDecoder().decode(chunks[1]));
82-
JSONObject payload = new JSONObject(respjson);
83-
Date expTime = new Date(payload.getLong("exp")*1000);
84-
85-
returnValue.principal = payload.getString("sub");
86-
returnValue.scope = payload.getString("scope").split(" ");
99+
final Date expTime = new Date(payload.getLong(TOKEN_CLAIM_KEY_EXPIRY) * 1000);
100+
returnValue.principal = payload.getString(TOKEN_CLAIM_KEY_SUBJECT);
101+
returnValue.scope = payload.getString(TOKEN_CLAIM_KEY_SCOPE).split(" ");
87102
returnValue.expiresAt = expTime.toString();
88103
returnValue.active = true;
104+
89105
System.out.println("Authentication successful");
90106
}
91107
} catch (IOException e) {
92108
e.printStackTrace();
93109
}
94110
return returnValue;
95111
}
112+
113+
/**
114+
* Returns true if all the configuration variables are set else returns false
115+
*
116+
* @return
117+
*/
118+
private boolean isConfigValid() {
119+
if (IDCS_URL != null && !IDCS_URL.trim().isEmpty()
120+
&& CLIENT_ID != null && !CLIENT_ID.trim().isEmpty()
121+
&& CLIENT_SECRET != null && !CLIENT_SECRET.isEmpty()
122+
&& SCOPE_AUD != null && !SCOPE_AUD.trim().isEmpty()) {
123+
return true;
124+
}
125+
return false;
126+
}
127+
128+
/**
129+
* The input contains the username and password in {@link Base64} encoded
130+
* format. The format of the token is Base64 encoded <username>:<password>. This
131+
* function decodes the token and returns the username and password.
132+
*
133+
* @param {@link String} token
134+
* @return {@link String} array with username and password
135+
*/
136+
private String[] getUserDetailsFromToken(final String token) {
137+
final String data = token.substring(TOKEN_PREFIX.length());
138+
final String[] user = new String(Base64.getDecoder().decode(data)).split(":", 2);
139+
return user;
140+
}
141+
142+
public static class Input {
143+
public String type;
144+
public String token;
145+
}
146+
147+
public static class Result {
148+
public boolean active = false;
149+
public String principal;
150+
public String[] scope;
151+
public String expiresAt;
152+
}
96153
}

‎samples/oci-apigw-idcs-auth-basic/src/main/java/com/example/fn/ResourceServerConfig.java

Lines changed: 0 additions & 21 deletions
This file was deleted.
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
package com.example.fn.util;
2+
3+
import static com.example.fn.util.ResourceServerConfig.TOKEN_PREFIX;
4+
import static com.example.fn.util.ResourceServerConfig.HEADER_NAME_CONTENT_TYPE;
5+
import static com.example.fn.util.ResourceServerConfig.HEADER_NAME_AUTHORIZATION;
6+
import static com.example.fn.util.ResourceServerConfig.HEADER_VALUE_CONTENT_TYPE;
7+
8+
import java.io.IOException;
9+
import java.net.URI;
10+
import java.net.http.HttpClient;
11+
import java.net.http.HttpRequest;
12+
import java.net.http.HttpResponse;
13+
import java.util.Base64;
14+
15+
import org.json.JSONObject;
16+
17+
/**
18+
* Util class that contains some common utility methods
19+
*/
20+
public final class Helper {
21+
22+
private Helper() {
23+
//
24+
}
25+
26+
/**
27+
* Creates the POST request body that will be sent to IDCS token endpoint
28+
*
29+
* @param {@link String} username
30+
* @param {@link String} password
31+
* @param {@link String} scope
32+
* @param {@link String} grantType
33+
* @return {@link String} request body
34+
*/
35+
public static String createRequestBody(final String username, final String password, final String scope,
36+
final String grantType) {
37+
return "grant_type=" + grantType +
38+
"&username=" + username +
39+
"&password=" + password +
40+
"&scope=" + scope;
41+
}
42+
43+
/**
44+
*
45+
* Calls IDCS token endpoint to validate the username and password and get the
46+
* access token.
47+
*
48+
* @param {@link String} url
49+
* @param {@link String} authHeader
50+
* @param {@link String} requestBody
51+
* @return {@link HttpResponse}
52+
* @throws InterruptedException
53+
* @throws IOException
54+
*/
55+
public static HttpResponse<String> callIDCS(final String url, final String authHeader, final String requestBody)
56+
throws IOException, InterruptedException {
57+
final HttpClient client = HttpClient.newHttpClient();
58+
59+
final HttpRequest request = HttpRequest.newBuilder()
60+
.uri(URI.create(url))
61+
.header(HEADER_NAME_CONTENT_TYPE, HEADER_VALUE_CONTENT_TYPE)
62+
.header(HEADER_NAME_AUTHORIZATION,
63+
TOKEN_PREFIX + Base64.getEncoder().encodeToString(authHeader.getBytes("UTF-8")))
64+
.POST(HttpRequest.BodyPublishers.ofString(requestBody))
65+
.build();
66+
67+
return client.send(request,
68+
HttpResponse.BodyHandlers.ofString());
69+
}
70+
71+
/**
72+
* Returns the body from the access token. The token is of the JWT format with 3
73+
* parts separated by "." First part is header, body is the second part and the
74+
* last part is signature
75+
*
76+
* @param response
77+
* @return
78+
*/
79+
public static JSONObject getTokenBody(final String response) {
80+
final String[] chunks = response.split("\\.");
81+
final String respjson = new String(Base64.getUrlDecoder().decode(chunks[1]));
82+
return new JSONObject(respjson);
83+
}
84+
}

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /