You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@fineract.apache.org by aw...@apache.org on 2019/04/30 08:17:33 UTC
[fineract-cn-permitted-feign-client] 04/27: Minor changes to access
token acquisition so that it can be used in rhythm where we don't know in
advance which application we'll be needing a token for.
This is an automated email from the ASF dual-hosted git repository.
awasum pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/fineract-cn-permitted-feign-client.git
commit bc6b05877f368083d72f8a31899632e7f7b23d6a
Author: myrle-krantz <mk...@mifos.org>
AuthorDate: Sun May 21 17:12:19 2017 +0200
Minor changes to access token acquisition so that it can be used in rhythm where we don't know in advance which application we'll be needing a token for.
---
.../ApplicationTokenedTargetInterceptor.java | 3 +-
.../service/ApplicationAccessTokenService.java | 78 ++++++++--------------
.../service/TokenCacheKey.java | 72 ++++++++++++++++++++
.../service/ApplicationAccessTokenServiceTest.java | 23 ++++++-
4 files changed, 121 insertions(+), 55 deletions(-)
diff --git a/library/src/main/java/io/mifos/permittedfeignclient/security/ApplicationTokenedTargetInterceptor.java b/library/src/main/java/io/mifos/permittedfeignclient/security/ApplicationTokenedTargetInterceptor.java
index 4141d70..60a58ad 100644
--- a/library/src/main/java/io/mifos/permittedfeignclient/security/ApplicationTokenedTargetInterceptor.java
+++ b/library/src/main/java/io/mifos/permittedfeignclient/security/ApplicationTokenedTargetInterceptor.java
@@ -19,6 +19,7 @@ import feign.RequestInterceptor;
import feign.RequestTemplate;
import io.mifos.core.api.util.ApiConstants;
import io.mifos.core.api.util.UserContextHolder;
+import io.mifos.core.lang.TenantContextHolder;
import io.mifos.permittedfeignclient.annotation.EndpointSet;
import io.mifos.permittedfeignclient.service.ApplicationAccessTokenService;
import org.springframework.util.Assert;
@@ -48,7 +49,7 @@ public class ApplicationTokenedTargetInterceptor implements RequestInterceptor {
public void apply(final RequestTemplate template) {
UserContextHolder.getUserContext().ifPresent(userContext -> {
template.header(ApiConstants.USER_HEADER, userContext.getUser());
- template.header(ApiConstants.AUTHORIZATION_HEADER, applicationAccessTokenService.getAccessToken(userContext.getUser(), endpointSetIdentifier));
+ template.header(ApiConstants.AUTHORIZATION_HEADER, applicationAccessTokenService.getAccessToken(userContext.getUser(), TenantContextHolder.checkedGetIdentifier(), endpointSetIdentifier));
});
}
}
\ No newline at end of file
diff --git a/library/src/main/java/io/mifos/permittedfeignclient/service/ApplicationAccessTokenService.java b/library/src/main/java/io/mifos/permittedfeignclient/service/ApplicationAccessTokenService.java
index 082f5ec..c21752b 100644
--- a/library/src/main/java/io/mifos/permittedfeignclient/service/ApplicationAccessTokenService.java
+++ b/library/src/main/java/io/mifos/permittedfeignclient/service/ApplicationAccessTokenService.java
@@ -20,7 +20,7 @@ import io.mifos.anubis.security.AmitAuthenticationException;
import io.mifos.anubis.token.TenantRefreshTokenSerializer;
import io.mifos.anubis.token.TokenSerializationResult;
import io.mifos.core.lang.ApplicationName;
-import io.mifos.core.lang.TenantContextHolder;
+import io.mifos.core.lang.AutoTenantContext;
import io.mifos.core.lang.security.RsaKeyPairFactory;
import io.mifos.identity.api.v1.client.IdentityManager;
import io.mifos.identity.api.v1.domain.Authentication;
@@ -30,8 +30,8 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
import java.util.Map;
-import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.TimeUnit;
@@ -41,41 +41,6 @@ import java.util.concurrent.TimeUnit;
@Component
public class ApplicationAccessTokenService {
private static final long REFRESH_TOKEN_LIFESPAN = TimeUnit.SECONDS.convert(1, TimeUnit.MINUTES);
- private static class TokenCacheKey {
- final String user;
- final String tenant;
- final String endpointSet;
-
- private TokenCacheKey(final String user, final String tenant, final String endpointSet) {
- this.user = user;
- this.tenant = tenant;
- this.endpointSet = endpointSet;
- }
-
- @Override
- public boolean equals(Object o) {
- if (this == o) return true;
- if (o == null || getClass() != o.getClass()) return false;
- TokenCacheKey that = (TokenCacheKey) o;
- return Objects.equals(user, that.user) &&
- Objects.equals(tenant, that.tenant) &&
- Objects.equals(endpointSet, that.endpointSet);
- }
-
- @Override
- public int hashCode() {
- return Objects.hash(user, tenant, endpointSet);
- }
-
- @Override
- public String toString() {
- return "TokenCacheKey{" +
- "user='" + user + '\'' +
- ", tenant='" + tenant + '\'' +
- ", endpointSet='" + endpointSet + '\'' +
- '}';
- }
- }
private final String applicationName;
private final TenantSignatureRepository tenantSignatureRepository;
@@ -111,32 +76,41 @@ public class ApplicationAccessTokenService {
.build();
}
- public String getAccessToken(final String user, final String endpointSetIdentifier) {
- final TokenCacheKey tokenCacheKey
- = new TokenCacheKey(user, TenantContextHolder.checkedGetIdentifier(), endpointSetIdentifier);
+ @SuppressWarnings("WeakerAccess")
+ public String getAccessToken(final String user, final String tenant) {
+ return getAccessToken(user, tenant, null);
+ }
+
+ public String getAccessToken(final String user, final String tenant, final @Nullable String endpointSetIdentifier) {
+ final TokenCacheKey tokenCacheKey = new TokenCacheKey(user, tenant, endpointSetIdentifier);
final Authentication authentication = accessTokenCache.get(tokenCacheKey);
return authentication.getAccessToken();
}
private Authentication createAccessToken(final TokenCacheKey tokenCacheKey) {
final String refreshToken = refreshTokenCache.get(tokenCacheKey).getToken();
- return identityManager.refresh(refreshToken);
+ try (final AutoTenantContext ignored = new AutoTenantContext(tokenCacheKey.getTenant())) {
+ return identityManager.refresh(refreshToken);
+ }
}
private TokenSerializationResult createRefreshToken(final TokenCacheKey tokenCacheKey) {
- final Optional<RsaKeyPairFactory.KeyPairHolder> optionalSigningKeyPair
- = tenantSignatureRepository.getLatestApplicationSigningKeyPair();
+ try (final AutoTenantContext ignored = new AutoTenantContext(tokenCacheKey.getTenant())) {
+ final Optional<RsaKeyPairFactory.KeyPairHolder> optionalSigningKeyPair
+ = tenantSignatureRepository.getLatestApplicationSigningKeyPair();
+
+ final RsaKeyPairFactory.KeyPairHolder signingKeyPair = optionalSigningKeyPair.orElseThrow(AmitAuthenticationException::missingTenant);
- final RsaKeyPairFactory.KeyPairHolder signingKeyPair = optionalSigningKeyPair.orElseThrow(AmitAuthenticationException::missingTenant);
+ final TenantRefreshTokenSerializer.Specification specification = new TenantRefreshTokenSerializer.Specification()
+ .setSourceApplication(applicationName)
+ .setUser(tokenCacheKey.getUser())
+ .setSecondsToLive(REFRESH_TOKEN_LIFESPAN)
+ .setPrivateKey(signingKeyPair.privateKey())
+ .setKeyTimestamp(signingKeyPair.getTimestamp());
- final TenantRefreshTokenSerializer.Specification specification = new TenantRefreshTokenSerializer.Specification()
- .setSourceApplication(applicationName)
- .setUser(tokenCacheKey.user)
- .setSecondsToLive(REFRESH_TOKEN_LIFESPAN)
- .setPrivateKey(signingKeyPair.privateKey())
- .setKeyTimestamp(signingKeyPair.getTimestamp())
- .setEndpointSet(tokenCacheKey.endpointSet);
+ tokenCacheKey.getEndpointSet().ifPresent(specification::setEndpointSet);
- return tenantRefreshTokenSerializer.build(specification);
+ return tenantRefreshTokenSerializer.build(specification);
+ }
}
}
diff --git a/library/src/main/java/io/mifos/permittedfeignclient/service/TokenCacheKey.java b/library/src/main/java/io/mifos/permittedfeignclient/service/TokenCacheKey.java
new file mode 100644
index 0000000..1d203c6
--- /dev/null
+++ b/library/src/main/java/io/mifos/permittedfeignclient/service/TokenCacheKey.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright 2017 The Mifos Initiative.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package io.mifos.permittedfeignclient.service;
+
+import javax.annotation.Nullable;
+import java.util.Objects;
+import java.util.Optional;
+
+/**
+ * @author Myrle Krantz
+ */
+class TokenCacheKey {
+ private final String user;
+ private final String tenant;
+ @SuppressWarnings("OptionalUsedAsFieldOrParameterType")
+ private final Optional<String> endpointSet;
+
+ TokenCacheKey(final String user, final String tenant, final @Nullable String endpointSet) {
+ this.user = user;
+ this.tenant = tenant;
+ this.endpointSet = Optional.ofNullable(endpointSet);
+ }
+
+ String getUser() {
+ return user;
+ }
+
+ String getTenant() {
+ return tenant;
+ }
+
+ Optional<String> getEndpointSet() {
+ return endpointSet;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ TokenCacheKey that = (TokenCacheKey) o;
+ return Objects.equals(user, that.user) &&
+ Objects.equals(tenant, that.tenant) &&
+ Objects.equals(endpointSet, that.endpointSet);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(user, tenant, endpointSet);
+ }
+
+ @Override
+ public String toString() {
+ return "TokenCacheKey{" +
+ "user='" + user + '\'' +
+ ", tenant='" + tenant + '\'' +
+ ", endpointSet='" + endpointSet + '\'' +
+ '}';
+ }
+}
diff --git a/library/src/test/java/io/mifos/permittedfeignclient/service/ApplicationAccessTokenServiceTest.java b/library/src/test/java/io/mifos/permittedfeignclient/service/ApplicationAccessTokenServiceTest.java
index 51d3f63..29017b6 100644
--- a/library/src/test/java/io/mifos/permittedfeignclient/service/ApplicationAccessTokenServiceTest.java
+++ b/library/src/test/java/io/mifos/permittedfeignclient/service/ApplicationAccessTokenServiceTest.java
@@ -1,3 +1,18 @@
+/*
+ * Copyright 2017 The Mifos Initiative.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package io.mifos.permittedfeignclient.service;
import io.mifos.anubis.config.TenantSignatureRepository;
@@ -5,6 +20,7 @@ import io.mifos.anubis.token.TenantRefreshTokenSerializer;
import io.mifos.anubis.token.TokenSerializationResult;
import io.mifos.core.lang.ApplicationName;
import io.mifos.core.lang.AutoTenantContext;
+import io.mifos.core.lang.TenantContextHolder;
import io.mifos.core.lang.security.RsaKeyPairFactory;
import io.mifos.identity.api.v1.client.IdentityManager;
import io.mifos.identity.api.v1.domain.Authentication;
@@ -48,10 +64,13 @@ public class ApplicationAccessTokenServiceTest {
tenantRefreshTokenSerializerMock);
try (final AutoTenantContext ignored1 = new AutoTenantContext(TENANT_NAME)) {
- final String accessToken = testSubject.getAccessToken(USER_NAME, "blah");
+ final String accessTokenWithoutCallEndpointSet = testSubject.getAccessToken(USER_NAME, TenantContextHolder.checkedGetIdentifier());
+ Assert.assertEquals(BEARER_TOKEN_MOCK, accessTokenWithoutCallEndpointSet);
+
+ final String accessToken = testSubject.getAccessToken(USER_NAME, TenantContextHolder.checkedGetIdentifier(), "blah");
Assert.assertEquals(BEARER_TOKEN_MOCK, accessToken);
- final String accessTokenAgain = testSubject.getAccessToken(USER_NAME, "blah");
+ final String accessTokenAgain = testSubject.getAccessToken(USER_NAME, TenantContextHolder.checkedGetIdentifier(), "blah");
Assert.assertEquals(BEARER_TOKEN_MOCK, accessTokenAgain);
}
}