Skip to content

Commit 633318e

Browse files
authored
Merge pull request #84 from Qualys/feature/QINT-21167
feature/QINT-21167: Added OIDC changes
2 parents c3f2211 + f558052 commit 633318e

7 files changed

Lines changed: 231 additions & 42 deletions

File tree

Lines changed: 45 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,36 @@
11
package com.example.GitHubActionsQWas.WASAuth;
22

3+
import com.example.GitHubActionsQWas.WASClient.QualysWASResponse;
4+
import com.example.GitHubActionsQWas.WASClient.WASBaseClient;
5+
import com.example.GitHubActionsQWas.WASClient.WASClient;
6+
import lombok.Getter;
7+
import org.apache.http.client.methods.CloseableHttpResponse;
8+
import org.apache.http.client.methods.HttpPost;
9+
import org.apache.http.impl.client.CloseableHttpClient;
10+
import org.apache.http.util.EntityUtils;
11+
import org.slf4j.Logger;
12+
import org.slf4j.LoggerFactory;
13+
14+
import java.io.IOException;
15+
import java.net.MalformedURLException;
16+
import java.net.URL;
17+
import java.security.KeyManagementException;
18+
import java.security.NoSuchAlgorithmException;
19+
20+
@Getter
321
public class WASAuth {
422
private String server;
523
private String username;
624
private String password;
25+
private String clientId;
26+
private String clientSecret;
727
private String authKey;
28+
private String authType;
829
private String proxyServer;
930
private String proxyUsername;
1031
private String proxyPassword;
1132
private int proxyPort;
33+
private final Logger logger = LoggerFactory.getLogger(WASClient.class);
1234

1335
public WASAuth() {
1436
}
@@ -17,41 +39,35 @@ public WASAuth(String oauthKey) {
1739
this.authKey = oauthKey;
1840
}
1941

20-
public String getServer() {
21-
return server;
22-
}
23-
24-
public String getUsername() {
25-
return username;
26-
}
27-
28-
public String getPassword() {
29-
return password;
30-
}
31-
32-
public String getAuthKey() {
33-
return authKey;
42+
public void setWasCredentials(String server, String username, String password, String authType) {
43+
this.server = server;
44+
this.username = username;
45+
this.password = password;
46+
this.authType = authType;
3447
}
3548

36-
public String getProxyServer() {
37-
return proxyServer;
49+
public void setWasOAuthCredentials(String server, String clientId, String clientSecret, String authType) {
50+
this.server = server;
51+
this.clientId = clientId;
52+
this.clientSecret = clientSecret;
53+
this.authType = authType;
3854
}
3955

40-
public String getProxyUsername() {
41-
return proxyUsername;
42-
}
56+
public void setOAuthKey() throws NoSuchAlgorithmException, KeyManagementException, IOException {
57+
WASClient client = new WASClient(this);
58+
CloseableHttpClient httpClient = client.getCloseableHttpClient();
4359

44-
public String getProxyPassword() {
45-
return proxyPassword;
46-
}
60+
URL url = new URL(server + "/auth/oidc");
61+
logger.info("Making Request: " + url);
4762

48-
public int getProxyPort() {
49-
return proxyPort;
50-
}
63+
HttpPost postRequest = new HttpPost(url.toString());
64+
postRequest.addHeader("Content-Type", "application/x-www-form-urlencoded");
65+
postRequest.addHeader("clientId", this.clientId);
66+
postRequest.addHeader("clientSecret", this.clientSecret);
5167

52-
public void setWasCredentials(String server, String username, String password) {
53-
this.server = server;
54-
this.username = username;
55-
this.password = password;
68+
CloseableHttpResponse httpResponse = httpClient.execute(postRequest);
69+
logger.info("Server returned with ResponseCode: " + httpResponse.getStatusLine().getStatusCode());
70+
this.authKey = EntityUtils.toString(httpResponse.getEntity(), "UTF-8");
71+
logger.warn("OAUTH Key is generated successfully...");
5672
}
5773
}

src/main/java/com/example/GitHubActionsQWas/WASClient/WASClient.java

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package com.example.GitHubActionsQWas.WASClient;
22

33
import com.example.GitHubActionsQWas.WASAuth.WASAuth;
4+
import com.example.GitHubActionsQWas.constants.Constants;
45
import com.example.GitHubActionsQWas.util.Helper;
56
import com.google.gson.*;
67
import org.apache.http.HttpEntity;
@@ -21,6 +22,8 @@
2122
import java.net.MalformedURLException;
2223
import java.net.URL;
2324
import java.nio.charset.StandardCharsets;
25+
import java.security.KeyManagementException;
26+
import java.security.NoSuchAlgorithmException;
2427
import java.util.Base64;
2528
import java.util.HashMap;
2629

@@ -77,6 +80,10 @@ public QualysWASResponse getReportStatus(String reportId) {
7780
return this.get(this.apiMap.get("getReportStatus") + reportId);
7881
}
7982

83+
public CloseableHttpClient getCloseableHttpClient() throws NoSuchAlgorithmException, KeyManagementException {
84+
return this.getHttpClient();
85+
}
86+
8087
private void download(String apiPath) {
8188
CloseableHttpClient httpClient = null;
8289

@@ -86,7 +93,11 @@ private void download(String apiPath) {
8693
httpClient = this.getHttpClient();
8794

8895
HttpGet getRequest = new HttpGet(url.toString());
89-
getRequest.addHeader("Authorization", "Basic " + this.getBasicAuthHeader());
96+
if (Constants.BASIC.equals(auth.getAuthType())) {
97+
getRequest.addHeader("Authorization", "Basic " + this.getBasicAuthHeader());
98+
} else if (Constants.OAUTH.equals(auth.getAuthType())) {
99+
getRequest.addHeader("Authorization", "Bearer " + auth.getAuthKey());
100+
}
90101
CloseableHttpResponse response = httpClient.execute(getRequest);
91102
logger.debug("Server returned with ResponseCode: {}", response.getStatusLine().getStatusCode());
92103

@@ -201,7 +212,11 @@ private QualysWASResponse get(String apiPath) {
201212

202213
HttpGet getRequest = new HttpGet(url.toString());
203214
getRequest.addHeader("accept", "application/json");
204-
getRequest.addHeader("Authorization", "Basic " + this.getBasicAuthHeader());
215+
if (Constants.BASIC.equals(auth.getAuthType())) {
216+
getRequest.addHeader("Authorization", "Basic " + this.getBasicAuthHeader());
217+
} else if (Constants.OAUTH.equals(auth.getAuthType())) {
218+
getRequest.addHeader("Authorization", "Bearer " + auth.getAuthKey());
219+
}
205220
CloseableHttpResponse response = httpClient.execute(getRequest);
206221
apiResponse.responseCode = response.getStatusLine().getStatusCode();
207222
logger.debug("Server returned with ResponseCode: " + apiResponse.responseCode);
@@ -245,7 +260,11 @@ private QualysWASResponse post(String apiPath, JsonObject requestData) {
245260

246261
HttpPost postRequest = new HttpPost(url.toString());
247262
postRequest.addHeader("accept", "application/json");
248-
postRequest.addHeader("Authorization", "Basic " + this.getBasicAuthHeader());
263+
if (Constants.BASIC.equals(auth.getAuthType())) {
264+
postRequest.addHeader("Authorization", "Basic " + this.getBasicAuthHeader());
265+
} else if (Constants.OAUTH.equals(auth.getAuthType())) {
266+
postRequest.addHeader("Authorization", "Bearer " + auth.getAuthKey());
267+
}
249268
Gson gson = new Gson();
250269
if (requestData != null) {
251270
postRequest.addHeader("Content-Type", "application/json");

src/main/java/com/example/GitHubActionsQWas/constants/Constants.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,5 +18,6 @@ public class Constants {
1818
public static final String COMPLETE = "COMPLETE";
1919
public static final String UNKNOWN = "UNKNOWN";
2020
public static final String PDF_FORMAT = "PDF";
21-
21+
public static final String BASIC = "BASIC";
22+
public static final String OAUTH = "OAUTH";
2223
}

src/main/java/com/example/GitHubActionsQWas/service/QualysWASScanBuilder.java

Lines changed: 48 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,14 @@
11
package com.example.GitHubActionsQWas.service;
22

3+
import ch.qos.logback.core.util.StringUtil;
34
import com.example.GitHubActionsQWas.WASAuth.WASAuth;
45
import com.example.GitHubActionsQWas.WASClient.QualysWASResponse;
56
import com.example.GitHubActionsQWas.WASClient.WASClient;
67
import com.example.GitHubActionsQWas.constants.Constants;
8+
import com.example.GitHubActionsQWas.util.ApiGatewayUrl;
9+
import com.example.GitHubActionsQWas.util.ApiServerUrl;
710
import com.example.GitHubActionsQWas.util.Helper;
11+
import com.example.GitHubActionsQWas.util.PortalUrl;
812
import com.fasterxml.jackson.core.JsonProcessingException;
913
import com.fasterxml.jackson.databind.JsonNode;
1014
import com.fasterxml.jackson.databind.ObjectMapper;
@@ -21,6 +25,10 @@
2125
import org.slf4j.LoggerFactory;
2226
import org.springframework.core.env.Environment;
2327

28+
import java.io.IOException;
29+
import java.net.MalformedURLException;
30+
import java.security.KeyManagementException;
31+
import java.security.NoSuchAlgorithmException;
2432
import java.util.ArrayList;
2533
import java.util.List;
2634
import java.util.concurrent.TimeUnit;
@@ -36,6 +44,8 @@ public class QualysWASScanBuilder {
3644
private Environment environment;
3745
private String apiServer;
3846
private String portalServer;
47+
private String gatewayServer;
48+
private String platform;
3949
private String qualysUsername;
4050
private String qualysPasssword;
4151
private boolean useProxy = false;
@@ -76,11 +86,14 @@ public class QualysWASScanBuilder {
7686
private boolean waitForResult;
7787
private WASClient client;
7888
private String fileType;
89+
private String authType;
90+
private String clientId;
91+
private String clientSecret;
92+
private String qualysIdentificationUrl;
7993

8094
public QualysWASScanBuilder(Environment environment) {
8195
try {
8296
this.environment = environment;
83-
this.apiServer = environment.getProperty("API_SERVER", "");
8497
this.qualysUsername = environment.getProperty("QUALYS_USERNAME", "");
8598
this.qualysPasssword = environment.getProperty("QUALYS_PASSWORD", "");
8699
this.useProxy = environment.getProperty("USE_PROXY", Boolean.class, false);
@@ -107,6 +120,21 @@ public QualysWASScanBuilder(Environment environment) {
107120
this.interval = environment.getProperty("INTERVAL", Integer.class, 1);
108121
this.timeout = environment.getProperty("TIMEOUT", Integer.class, (60 * 5) + 50);
109122
this.fileType = environment.getProperty("FILE_TYPE", "PDF");
123+
this.authType = environment.getProperty("AUTH_TYPE", "");
124+
this.clientId = environment.getProperty("CLIENT_ID", "");
125+
this.clientSecret = environment.getProperty("CLIENT_SECRET", "");
126+
this.platform = environment.getProperty("PLATFORM", "");
127+
this.qualysIdentificationUrl = "https://www.qualys.com/platform-identification";
128+
129+
if (StringUtil.notNullNorEmpty(platform)) {
130+
this.apiServer = ApiServerUrl.getByKey(platform).getUrl();
131+
this.portalServer = PortalUrl.getByKey(platform).getUrl();
132+
this.gatewayServer = ApiGatewayUrl.getByKey(platform).getUrl();
133+
} else {
134+
throw new Exception("PLATFORM not specified, Please configure it and try again. Please visit following url to identify correct platform: " +
135+
qualysIdentificationUrl);
136+
}
137+
110138
this.severity1Limit = 0;
111139
this.severity2Limit = 0;
112140
this.severity3Limit = 0;
@@ -120,7 +148,7 @@ public QualysWASScanBuilder(Environment environment) {
120148
assignSeverities();
121149
}
122150
} catch (Exception ex) {
123-
logger.error("Something went wrong. Reason: " + ex.getCause());
151+
logger.error("Something went wrong. Reason: " + ex.getMessage());
124152
System.exit(1);
125153
}
126154
}
@@ -173,10 +201,14 @@ protected void assignSeverities() {
173201
}
174202
}
175203

176-
protected void initWASClient() {
177-
WASAuth auth = new WASAuth();
178-
auth.setWasCredentials(apiServer, qualysUsername, qualysPasssword);
179-
204+
protected void initWASClient() throws NoSuchAlgorithmException, KeyManagementException, IOException {
205+
WASAuth auth = new WASAuth();;
206+
if (authType.equals(Constants.BASIC)) {
207+
auth.setWasCredentials(apiServer, qualysUsername, qualysPasssword, Constants.BASIC);
208+
} else {
209+
auth.setWasOAuthCredentials(gatewayServer, clientId, clientSecret, Constants.OAUTH);
210+
auth.setOAuthKey();
211+
}
180212
// if (useProxy) {
181213
// auth.setProxyCredentials(proxyServer, proxyPort, proxyUsername, proxyPassword);
182214
// }
@@ -226,8 +258,6 @@ protected JsonObject getCriteriaAsJsonObject() {
226258
*
227259
*/
228260
public void launchWebApplicationScan() {
229-
portalServer = apiServer.replace("api", "guard");
230-
231261
logger.info("Using Qualys API Server: " + apiServer);
232262

233263
try {
@@ -410,7 +440,16 @@ private JsonElement getEvaluationResult(JsonObject result) {
410440
}
411441

412442
public boolean isMandatoryParametersSet() {
413-
return !(this.apiServer == null || this.apiServer.isEmpty() || this.qualysUsername == null || this.qualysUsername.isEmpty() || this.qualysPasssword == null || this.qualysPasssword.isEmpty() || webAppId == null || webAppId.isEmpty() || scanName == null || scanName.isEmpty() || scanType == null || scanType.isEmpty());
443+
return !(this.apiServer == null || this.apiServer.isEmpty() ||
444+
this.qualysUsername == null || this.qualysUsername.isEmpty() ||
445+
this.qualysPasssword == null || this.qualysPasssword.isEmpty() ||
446+
this.webAppId == null || this.webAppId.isEmpty() ||
447+
this.scanName == null || this.scanName.isEmpty() ||
448+
this.scanType == null || this.scanType.isEmpty() ||
449+
this.platform == null || this.platform.isEmpty()) ||
450+
this.gatewayServer == null || this.gatewayServer.isEmpty() ||
451+
this.portalServer == null || this.portalServer.isEmpty() ||
452+
this.authType == null || this.authType.isEmpty();
414453
}
415454

416455
protected boolean testConnection() {
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
package com.example.GitHubActionsQWas.util;
2+
3+
import lombok.Getter;
4+
5+
@Getter
6+
public enum ApiGatewayUrl {
7+
US1 ("https://gateway.qualys.com"),
8+
US2 ("https://gateway.qg2.apps.qualys.com"),
9+
US3 ("https://gateway.qg3.apps.qualys.com"),
10+
US4 ("https://gateway.qg4.apps.qualys.com"),
11+
EU1 ("https://gateway.qualys.eu"),
12+
EU2 ("https://gateway.qg2.apps.qualys.eu"),
13+
EU3 ("https://gateway.qg3.apps.qualys.eu"),
14+
IN1 ("https://gateway.qg1.apps.qualys.in"),
15+
CA1 ("https://gateway.qg1.apps.qualys.ca"),
16+
AE1 ("https://gateway.qg1.apps.qualys.ae"),
17+
UK1 ("https://gateway.qg1.apps.qualys.co.uk"),
18+
AU1 ("https://gateway.qg1.apps.qualys.com.au"),
19+
KSA1 ("https://gateway.qg1.apps.qualysksa.com")
20+
;
21+
22+
private final String url;
23+
24+
ApiGatewayUrl(String url) {
25+
this.url = url;
26+
}
27+
28+
public static ApiGatewayUrl getByKey(String key) throws Exception {
29+
try {
30+
return valueOf(key.toUpperCase());
31+
} catch (Exception e) {
32+
String exception = String.format("Exception: You have entered invalid platform {%s}, Please visit following url to identify correct platform - %s",
33+
key.toUpperCase(),
34+
"https://www.qualys.com/platform-identification ");
35+
throw new Exception(exception);
36+
}
37+
}
38+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
package com.example.GitHubActionsQWas.util;
2+
3+
import lombok.Getter;
4+
5+
@Getter
6+
public enum ApiServerUrl {
7+
US1 ("https://qualysapi.qualys.com"),
8+
US2 ("https://qualysapi.qg2.apps.qualys.com"),
9+
US3 ("https://qualysapi.qg3.apps.qualys.com"),
10+
US4 ("https://qualysapi.qg4.apps.qualys.com"),
11+
EU1 ("https://qualysapi.qualys.eu"),
12+
EU2 ("https://qualysapi.qg2.apps.qualys.eu"),
13+
EU3 ("https://qualysapi.qg3.apps.qualys.eu"),
14+
IN1 ("https://qualysapi.qg1.apps.qualys.in"),
15+
CA1 ("https://qualysapi.qg1.apps.qualys.ca"),
16+
AE1 ("https://qualysapi.qg1.apps.qualys.ae"),
17+
UK1 ("https://qualysapi.qg1.apps.qualys.co.uk"),
18+
AU1 ("https://qualysapi.qg1.apps.qualys.com.au"),
19+
KSA1 ("https://qualysapi.qg1.apps.qualysksa.com")
20+
;
21+
22+
private final String url;
23+
24+
ApiServerUrl(String url) {
25+
this.url = url;
26+
}
27+
28+
public static ApiServerUrl getByKey(String key) throws Exception {
29+
try {
30+
return valueOf(key.toUpperCase());
31+
} catch (IllegalArgumentException e) {
32+
String exception = String.format("Exception: You have entered invalid platform {%s}, Please visit following url to identify correct platform - %s",
33+
key.toUpperCase(),
34+
"https://www.qualys.com/platform-identification ");
35+
throw new Exception(exception);
36+
}
37+
}
38+
}

0 commit comments

Comments
 (0)