Skip to content

Commit 193f16c

Browse files
authored
Merge pull request #13 from privacyidea/user_agent_service_realm
add realm parameter for service account, add user agent requirement
2 parents eda973e + 321f0c6 commit 193f16c

File tree

8 files changed

+65
-57
lines changed

8 files changed

+65
-57
lines changed

src/main/java/org/privacyidea/Configuration.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,13 @@ class Configuration {
1010
boolean doSSLVerify = true;
1111
String serviceAccountName = "";
1212
String serviceAccountPass = "";
13+
String serviceAccountRealm = "";
1314
List<Integer> pollingIntervals = new ArrayList<>();
1415
boolean disableLog = false;
16+
String userAgent = "";
1517

16-
public Configuration(String serverURL) {
18+
public Configuration(String serverURL, String userAgent) {
1719
this.serverURL = serverURL;
20+
this.userAgent = userAgent;
1821
}
1922
}

src/main/java/org/privacyidea/Endpoint.java

Lines changed: 34 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -18,27 +18,20 @@
1818
class Endpoint {
1919

2020
private final PrivacyIDEA privacyIDEA;
21-
private String authToken; // lazy init
2221
private List<String> logExcludedEndpointPrints = Collections.emptyList(); //Arrays.asList(org.privacyidea.Constants.ENDPOINT_AUTH, org.privacyidea.Constants.ENDPOINT_POLL_TRANSACTION);
23-
private boolean doSSLVerify = true;
24-
private final String hostname;
25-
private final String serviceAccountName;
26-
private final String serviceAccountPass;
27-
28-
Endpoint(PrivacyIDEA privacyIDEA, String hostname, boolean doSSLVerify, String serviceAccountName, String serviceAccountPass) {
29-
this.hostname = hostname;
30-
this.doSSLVerify = doSSLVerify;
31-
this.serviceAccountName = serviceAccountName;
32-
this.serviceAccountPass = serviceAccountPass;
22+
private final Configuration configuration;
23+
24+
Endpoint(PrivacyIDEA privacyIDEA, Configuration configuration) {
3325
this.privacyIDEA = privacyIDEA;
26+
this.configuration = configuration;
3427
}
3528

3629
/**
3730
* Make a https call to the specified path, the URL is taken from the config.
38-
* If SSL Verification is turned off in the config, the endpoints certificate will not be verified.
31+
* If SSL verification is set to false in the config, the endpoints certificate will not be verified.
3932
*
40-
* @param path Path to the API endpoint
41-
* @param params All necessary parameters for request
33+
* @param path path to the API endpoint
34+
* @param params all necessary parameters for the request
4235
* @param authTokenRequired whether the authorization header should be set
4336
* @param method "POST" or "GET"
4437
* @return String containing the whole response
@@ -67,7 +60,7 @@ String sendRequest(String path, Map<String, String> params, boolean authTokenReq
6760
HttpURLConnection con = null;
6861
String response = null;
6962
try {
70-
String strURL = hostname + path;
63+
String strURL = configuration.serverURL + path;
7164

7265
if (method.equals("GET")) {
7366
strURL += "?" + paramsSB.toString();
@@ -80,23 +73,25 @@ String sendRequest(String path, Map<String, String> params, boolean authTokenReq
8073
con = (HttpURLConnection) (url.openConnection());
8174
}
8275

83-
if (!doSSLVerify && (con instanceof HttpsURLConnection)) {
76+
if (!configuration.doSSLVerify && (con instanceof HttpsURLConnection)) {
8477
con = disableSSLVerification((HttpsURLConnection) con);
8578
}
8679

8780
if (method.equals("POST")) {
8881
con.setDoOutput(true);
8982
}
83+
9084
con.setRequestMethod(method);
85+
con.addRequestProperty("User-Agent", configuration.userAgent);
9186

92-
if (authToken == null && authTokenRequired) {
93-
getAuthTokenFromServer();
94-
}
87+
if (authTokenRequired) {
88+
String authToken = getAuthTokenFromServer();
89+
if (authToken.isEmpty()) {
90+
privacyIDEA.log("Failed to fetch authorization token from server!");
91+
return "";
92+
}
9593

96-
if (authToken != null && authTokenRequired) {
9794
con.setRequestProperty("Authorization", authToken);
98-
} else if (authTokenRequired) {
99-
throw new IllegalStateException("Authorization token could not be acquired, but it is needed!");
10095
}
10196

10297
con.connect();
@@ -132,10 +127,10 @@ String sendRequest(String path, Map<String, String> params, boolean authTokenReq
132127
response = br.lines().reduce("", (a, s) -> a += s);
133128
}
134129
}
135-
privacyIDEA.log("Reponse from error: " + response);
130+
privacyIDEA.log("Response from ErrorStream: " + response);
136131
}
137132
} catch (IOException ioe) {
138-
privacyIDEA.log("Exception while getting ErrorStream: " + e.getMessage());
133+
privacyIDEA.log("Exception getting ErrorStream: " + ioe.getMessage());
139134
}
140135

141136
}
@@ -178,35 +173,31 @@ public java.security.cert.X509Certificate[] getAcceptedIssuers() {
178173
return con;
179174
}
180175

181-
private void getAuthTokenFromServer() {
182-
if (authToken != null) {
183-
// The TTL of the AuthToken should be long enough for the usage (default is 60min)
184-
//log.info("Auth token already set.");
185-
return;
186-
}
187-
176+
String getAuthTokenFromServer() {
188177
if (!privacyIDEA.checkServiceAccountAvailable()) {
189178
privacyIDEA.log("Service account information not set, cannot retrieve auth token");
190-
return;
179+
return "";
191180
}
192181

193-
//log.info("Getting auth token from PI");
194182
Map<String, String> params = new LinkedHashMap<>();
195-
params.put(Constants.PARAM_KEY_USERNAME, serviceAccountName);
196-
params.put(Constants.PARAM_KEY_PASSWORD, serviceAccountPass);
183+
params.put(Constants.PARAM_KEY_USERNAME, configuration.serviceAccountName);
184+
params.put(Constants.PARAM_KEY_PASSWORD, configuration.serviceAccountPass);
185+
186+
if (configuration.serviceAccountRealm != null && !configuration.serviceAccountRealm.isEmpty()) {
187+
params.put(Constants.PARAM_KEY_REALM, configuration.serviceAccountRealm);
188+
} else if (configuration.realm != null && !configuration.realm.isEmpty()) {
189+
params.put(Constants.PARAM_KEY_REALM, configuration.realm);
190+
}
191+
197192
String response = sendRequest(Constants.ENDPOINT_AUTH, params, false, Constants.POST);
198193

199194
JsonObject obj = JsonParser.parseString(response).getAsJsonObject();
200195
if (obj != null) {
201-
authToken = obj.getAsJsonObject("result").getAsJsonObject("value").getAsJsonPrimitive("token").getAsString();
202-
}
203-
}
204-
205-
String getAuthToken() {
206-
if (authToken == null) {
207-
getAuthTokenFromServer();
196+
return obj.getAsJsonObject("result").getAsJsonObject("value").getAsJsonPrimitive("token").getAsString();
197+
} else {
198+
privacyIDEA.log("Response did not contain an authorization token: " + response);
199+
return "";
208200
}
209-
return authToken;
210201
}
211202

212203
public static String prettyPrintJson(String json) {
@@ -221,7 +212,6 @@ public static String prettyPrintJson(String json) {
221212
return json;
222213
}
223214

224-
//return sw.toString();
225215
return gson.toJson(obj);
226216
}
227217

src/main/java/org/privacyidea/PrivacyIDEA.java

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,7 @@ private PrivacyIDEA(Configuration configuration, PILoggerBridge logger, PISimple
2020
this.log = logger;
2121
this.simpleLog = simpleLog;
2222
this.configuration = configuration;
23-
this.endpoint = new Endpoint(this, configuration.serverURL, configuration.doSSLVerify,
24-
configuration.serviceAccountName, configuration.serviceAccountPass);
23+
this.endpoint = new Endpoint(this, configuration);
2524
}
2625

2726
/**
@@ -167,14 +166,14 @@ public void asyncPollTransaction(String transactionID, String username, PIPollTr
167166
/**
168167
* Get the Authorization token for the service account.
169168
*
170-
* @return the AuthToken or null if error
169+
* @return the AuthToken or empty string if error
171170
*/
172171
public String getAuthToken() {
173172
if (!checkServiceAccountAvailable()) {
174173
logError("Cannot retrieve auth token without service account!");
175174
return null;
176175
}
177-
return endpoint.getAuthToken();
176+
return endpoint.getAuthTokenFromServer();
178177
}
179178

180179
/*
@@ -317,15 +316,19 @@ public static class Builder {
317316
private boolean doSSLVerify = true;
318317
private String serviceAccountName = "";
319318
private String serviceAccountPass = "";
319+
private String serviceAccountRealm = "";
320+
private String userAgent = "";
320321
private List<Integer> pollingIntervals = Collections.singletonList(1);
321322
private PILoggerBridge logger = null;
322323
private boolean disableLog = false;
323324
private PISimpleLogBridge simpleLogBridge = null;
324325

325326
/**
326327
* @param serverURL the server URL is mandatory to communicate with privacyIDEA.
328+
* @param userAgent the user agent that should be used in the http requests. Should refer to the plugin, something like "privacyIDEA-Keycloak"
327329
*/
328-
public Builder(String serverURL) {
330+
public Builder(String serverURL, String userAgent) {
331+
this.userAgent = userAgent;
329332
this.serverURL = serverURL;
330333
}
331334

@@ -382,11 +385,22 @@ public Builder setServiceAccount(String serviceAccountName, String serviceAccoun
382385
return this;
383386
}
384387

388+
/**
389+
* Set the realm for the service account if the account is found in a separate realm from the realm set in {@link Builder#setRealm(String)}.
390+
*
391+
* @param serviceAccountRealm realm of the service account
392+
* @return Builder
393+
*/
394+
public Builder setServiceAccountRealm(String serviceAccountRealm) {
395+
this.serviceAccountRealm = serviceAccountRealm;
396+
return this;
397+
}
398+
385399
/**
386400
* Set the intervals at which the polling is done when using asyncPollTransaction.
387401
* The last number will be repeated if the end of the list is reached.
388402
*
389-
* @param intervals list of ints that represent seconds
403+
* @param intervals list of integers that represent seconds
390404
* @return Builder
391405
*/
392406
public Builder setPollingIntervals(List<Integer> intervals) {
@@ -400,11 +414,12 @@ public Builder disableLog() {
400414
}
401415

402416
public PrivacyIDEA build() {
403-
Configuration configuration = new Configuration(serverURL);
417+
Configuration configuration = new Configuration(serverURL, userAgent);
404418
configuration.realm = realm;
405419
configuration.doSSLVerify = doSSLVerify;
406420
configuration.serviceAccountName = serviceAccountName;
407421
configuration.serviceAccountPass = serviceAccountPass;
422+
configuration.serviceAccountRealm = serviceAccountRealm;
408423
configuration.pollingIntervals = pollingIntervals;
409424
configuration.disableLog = disableLog;
410425
return new PrivacyIDEA(configuration, logger, simpleLogBridge);

src/test/java/org/privacyidea/TestCRnoServiceAcc.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ public class TestCRnoServiceAcc implements PILoggerBridge {
2929
public void setup() {
3030
mockServer = ClientAndServer.startClientAndServer(1080);
3131

32-
privacyIDEA = new PrivacyIDEA.Builder("https://127.0.0.1:1080")
32+
privacyIDEA = new PrivacyIDEA.Builder("https://127.0.0.1:1080", "test")
3333
.setSSLVerify(false)
3434
.setLogger(this)
3535
.setSimpleLog(System.out::println)

src/test/java/org/privacyidea/TestOTP.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ public class TestOTP implements PILoggerBridge {
2828
public void setup() {
2929
mockServer = ClientAndServer.startClientAndServer(1080);
3030

31-
privacyIDEA = new PrivacyIDEA.Builder("https://127.0.0.1:1080")
31+
privacyIDEA = new PrivacyIDEA.Builder("https://127.0.0.1:1080", "test")
3232
.setSSLVerify(false)
3333
.setLogger(this)
3434
.build();

src/test/java/org/privacyidea/TestRollout.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ public class TestRollout {
1919
public void setup() {
2020
mockServer = ClientAndServer.startClientAndServer(1080);
2121

22-
privacyIDEA = new PrivacyIDEA.Builder("https://127.0.0.1:1080")
22+
privacyIDEA = new PrivacyIDEA.Builder("https://127.0.0.1:1080", "test")
2323
.setSSLVerify(false)
2424
.setServiceAccount("admin", "admin")
2525
.setLogger(new PILoggerBridge() {

src/test/java/org/privacyidea/TestSerialAuthentication.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ public class TestSerialAuthentication implements PILoggerBridge {
99

1010
@Test
1111
public void test() {
12-
PrivacyIDEA privacyIDEA = new PrivacyIDEA.Builder("https://127.0.0.1")
12+
PrivacyIDEA privacyIDEA = new PrivacyIDEA.Builder("https://127.0.0.1", "test")
1313
.setSSLVerify(false)
1414
.setServiceAccount("admin", "admin")
1515
.setLogger(this)

src/test/java/org/privacyidea/TestServiceAccount.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ public class TestServiceAccount implements PILoggerBridge {
2525
public void setup() {
2626
mockServer = ClientAndServer.startClientAndServer(1080);
2727

28-
privacyIDEA = new PrivacyIDEA.Builder("https://127.0.0.1:1080")
28+
privacyIDEA = new PrivacyIDEA.Builder("https://127.0.0.1:1080", "test")
2929
.setServiceAccount(serviceUser, servicePass)
3030
.setSSLVerify(false)
3131
.setLogger(this)

0 commit comments

Comments
 (0)