-
Notifications
You must be signed in to change notification settings - Fork 9
69 reuse saved jwt auth token until it expire 1 #70
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
lukasmatusiewicz
merged 37 commits into
master
from
69-reuse-saved-jwt-auth-token-until-it-expire-1
Mar 26, 2025
Merged
Changes from 19 commits
Commits
Show all changes
37 commits
Select commit
Hold shift + click to select a range
b95f47d
Update JSONParser.java
lukasmatusiewicz 6f5e7ef
Update JSONParser.java
lukasmatusiewicz 626a875
Update JSONParser.java
lukasmatusiewicz 12ab544
Update PIConstants.java
lukasmatusiewicz 2a90a4e
Update JSONParser.java
lukasmatusiewicz d581b23
Update JSONParser.java
lukasmatusiewicz 872db86
Update PIConstants.java
lukasmatusiewicz 0711b6e
Update PIResponse.java
lukasmatusiewicz 098706d
Update PrivacyIDEA.java
lukasmatusiewicz 072bf36
Update TestGetTokenInfo.java
lukasmatusiewicz c452b71
Update AsyncRequestCallable.java
lukasmatusiewicz 26a3e90
Update AsyncRequestCallable.java
lukasmatusiewicz 70bef18
Update PrivacyIDEA.java
lukasmatusiewicz f3bd138
Update PrivacyIDEA.java
lukasmatusiewicz f3736d0
Update JSONParser.java
lukasmatusiewicz 01eb016
Update PrivacyIDEA.java
lukasmatusiewicz 1e23c86
Update PrivacyIDEA.java
lukasmatusiewicz a6d491b
Update PrivacyIDEA.java
lukasmatusiewicz c09b902
update tests
lukasmatusiewicz faf235b
Update PrivacyIDEA.java
lukasmatusiewicz e6eb252
Update build.yml
lukasmatusiewicz 9f77a94
Update PrivacyIDEA.java
lukasmatusiewicz 3c5614f
Update JSONParser.java
lukasmatusiewicz 81b52af
Update PrivacyIDEA.java
lukasmatusiewicz 44cf2f8
Update pom.xml
lukasmatusiewicz 7d3554f
Create TestJWTAuthToken.java
lukasmatusiewicz a94cad4
Update TestJWTAuthToken.java
lukasmatusiewicz d75e8cb
Update TestJWTAuthToken.java
lukasmatusiewicz 479b918
Update TestValidateCheckSerial.java
lukasmatusiewicz b43e4f8
Update TestRollout.java
lukasmatusiewicz 2629d18
update test, change naming
nilsbehlen e55ee8b
Update TestJWT.java
nilsbehlen 5ba9e3e
Update TestJWT.java
lukasmatusiewicz f5e43c5
Update TestJWT.java
nilsbehlen 437700b
schedule again when response is empty
nilsbehlen 44a5fae
Merge branch 'master' into 69-reuse-saved-jwt-auth-token-until-it-exp…
lukasmatusiewicz 3d50f1f
cleanup
lukasmatusiewicz File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -33,9 +33,12 @@ public class PrivacyIDEA implements Closeable | |
| private final IPILogger log; | ||
| private final IPISimpleLogger simpleLog; | ||
| private final Endpoint endpoint; | ||
| private String authToken = null; | ||
| // Thread pool for connections | ||
| private final BlockingQueue<Runnable> queue = new ArrayBlockingQueue<>(1000); | ||
| private final ThreadPoolExecutor threadPool = new ThreadPoolExecutor(20, 20, 10, TimeUnit.SECONDS, queue); | ||
| private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1); | ||
| private final CountDownLatch authTokenLatch = new CountDownLatch(1); | ||
| final JSONParser parser; | ||
| // Responses from these endpoints will not be logged. The list can be overwritten. | ||
| private List<String> logExcludedEndpoints = Arrays.asList(PIConstants.ENDPOINT_AUTH, | ||
|
|
@@ -49,6 +52,10 @@ private PrivacyIDEA(PIConfig configuration, IPILogger logger, IPISimpleLogger si | |
| this.endpoint = new Endpoint(this); | ||
| this.parser = new JSONParser(this); | ||
| this.threadPool.allowCoreThreadTimeOut(true); | ||
| if (serviceAccountAvailable()) | ||
| { | ||
| retrieveAuthToken(); | ||
| } | ||
| } | ||
|
|
||
| /** | ||
|
|
@@ -150,6 +157,11 @@ private PIResponse getPIResponse(String type, String input, String pass, Map<Str | |
| params.put(TRANSACTION_ID, transactionID); | ||
| } | ||
| String response = runRequestAsync(ENDPOINT_VALIDATE_CHECK, params, headers, false, POST); | ||
| // Shutdown the scheduler if user successfully authenticated | ||
| if (this.parser.parsePIResponse(response) != null && this.parser.parsePIResponse(response).value) | ||
| { | ||
| this.scheduler.shutdownNow(); | ||
| } | ||
| return this.parser.parsePIResponse(response); | ||
| } | ||
|
|
||
|
|
@@ -243,21 +255,10 @@ public ChallengeStatus pollTransaction(String transactionID) | |
| } | ||
|
|
||
| /** | ||
| * Get the auth token from the /auth endpoint using the service account. | ||
| * Get the service account parameters. | ||
| * | ||
| * @return auth token or null. | ||
| * @return map with username and password. | ||
| */ | ||
| public String getAuthToken() | ||
| { | ||
| if (!serviceAccountAvailable()) | ||
| { | ||
| error("Cannot retrieve auth token without service account!"); | ||
| return null; | ||
| } | ||
| String response = runRequestAsync(ENDPOINT_AUTH, serviceAccountParam(), Collections.emptyMap(), false, POST); | ||
| return parser.extractAuthToken(response); | ||
| } | ||
|
|
||
| Map<String, String> serviceAccountParam() | ||
| { | ||
| Map<String, String> authTokenParams = new LinkedHashMap<>(); | ||
|
|
@@ -348,6 +349,11 @@ public RolloutInfo tokenInit(String username, String typeToEnroll, String otpKey | |
| return parser.parseRolloutInfo(response); | ||
| } | ||
|
|
||
| /** | ||
| * Append the realm to the parameters if it is set. | ||
| * | ||
| * @param params parameters | ||
| */ | ||
| private void appendRealm(Map<String, String> params) | ||
| { | ||
| if (configuration.realm != null && !configuration.realm.isEmpty()) | ||
|
|
@@ -356,6 +362,48 @@ private void appendRealm(Map<String, String> params) | |
| } | ||
| } | ||
|
|
||
| /** | ||
| * Retrieve the auth token from the /auth endpoint and schedule the next retrieval. | ||
| */ | ||
| private void retrieveAuthToken() | ||
| { | ||
| String response = runRequestAsync(ENDPOINT_AUTH, serviceAccountParam(), Collections.emptyMap(), false, POST); | ||
|
||
| LinkedHashMap<String, String> authTokenMap = parser.extractAuthToken(response); | ||
| this.authToken = authTokenMap.get(AUTH_TOKEN); | ||
| int authTokenExp = Integer.parseInt(authTokenMap.get(AUTH_TOKEN_EXP)); | ||
| log("Auth token expires in: " + (authTokenExp - System.currentTimeMillis() / 1000L) + " seconds."); | ||
|
|
||
| // Schedule the next token retrieval to 1 min before expiration | ||
| long delay = authTokenExp - 60 - System.currentTimeMillis() / 1000L; | ||
| scheduler.schedule(this::retrieveAuthToken, delay, TimeUnit.SECONDS); | ||
|
|
||
| // Count down the latch to indicate that the token is retrieved | ||
| authTokenLatch.countDown(); | ||
| } | ||
|
|
||
| /** | ||
| * Get the auth token from the /auth endpoint using the service account. | ||
| * | ||
| * @return auth token or null. | ||
| * @throws InterruptedException if the thread is interrupted while waiting for the auth token. | ||
| */ | ||
| public String getAuthToken() throws InterruptedException | ||
| { | ||
| // Wait for the auth token to be retrieved | ||
| authTokenLatch.await(); | ||
| return this.authToken; | ||
| } | ||
|
|
||
| /** | ||
| * @return true if a service account is available | ||
| */ | ||
| public boolean serviceAccountAvailable() | ||
| { | ||
| return configuration.serviceAccountName != null && !configuration.serviceAccountName.isEmpty() | ||
| && configuration.serviceAccountPass != null && | ||
| !configuration.serviceAccountPass.isEmpty(); | ||
| } | ||
|
|
||
| /** | ||
| * Run a request in a thread of the thread pool. Then join that thread to the one that was calling this method. | ||
| * If the server takes longer to answer a request, the other requests do not have to wait. | ||
|
|
@@ -388,6 +436,14 @@ private String runRequestAsync(String path, Map<String, String> params, Map<Stri | |
| return response; | ||
| } | ||
|
|
||
| /** | ||
| * @return the configuration of this instance | ||
| */ | ||
| PIConfig configuration() | ||
| { | ||
| return configuration; | ||
| } | ||
|
|
||
| /** | ||
| * @return list of endpoints for which the response is not printed | ||
| */ | ||
|
|
@@ -404,21 +460,6 @@ public void logExcludedEndpoints(List<String> list) | |
| this.logExcludedEndpoints = list; | ||
| } | ||
|
|
||
| /** | ||
| * @return true if a service account is available | ||
| */ | ||
| public boolean serviceAccountAvailable() | ||
| { | ||
| return configuration.serviceAccountName != null && !configuration.serviceAccountName.isEmpty() | ||
| && configuration.serviceAccountPass != null && | ||
| !configuration.serviceAccountPass.isEmpty(); | ||
| } | ||
|
|
||
| PIConfig configuration() | ||
| { | ||
| return configuration; | ||
| } | ||
|
|
||
| /** | ||
| * Pass the message to the appropriate logger implementation. | ||
| * | ||
|
|
@@ -519,6 +560,7 @@ else if (this.simpleLog != null) | |
| public void close() throws IOException | ||
| { | ||
| this.threadPool.shutdown(); | ||
| this.scheduler.shutdownNow(); | ||
| } | ||
|
|
||
| /** | ||
|
|
@@ -533,6 +575,9 @@ public static Builder newBuilder(String serverURL, String userAgent) | |
| return new Builder(serverURL, userAgent); | ||
| } | ||
|
|
||
| /** | ||
| * Builder class to create a PrivacyIDEA instance. | ||
| */ | ||
| public static class Builder | ||
| { | ||
| private final String serverURL; | ||
|
|
||
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
do not call
parsePIResponsetwiceThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
right
faf235b