aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDan Timoney <dtimoney@att.com>2022-02-03 16:26:35 +0000
committerGerrit Code Review <gerrit@onap.org>2022-02-03 16:26:35 +0000
commit25518a58b9a3fdce91a9ed17c7ae6c32b57dc562 (patch)
tree599acfd43851d1492d911d65faffb0ed2402ae20
parentf01064b548d479d2f98abb7d30429b4a410a209e (diff)
parentc2f7f6d2e1775cc0b51ab6b8af7b9e84fc1f3535 (diff)
Merge "add async auth method support"
-rw-r--r--sdnr/wt/oauth-provider/provider-jar/pom.xml12
-rw-r--r--sdnr/wt/oauth-provider/provider-jar/src/main/java/org/onap/ccsdk/features/sdnr/wt/oauthprovider/OAuth2Realm.java5
-rw-r--r--sdnr/wt/oauth-provider/provider-jar/src/main/java/org/onap/ccsdk/features/sdnr/wt/oauthprovider/data/Config.java152
-rw-r--r--sdnr/wt/oauth-provider/provider-jar/src/main/java/org/onap/ccsdk/features/sdnr/wt/oauthprovider/data/InvalidConfigurationException.java32
-rw-r--r--sdnr/wt/oauth-provider/provider-jar/src/main/java/org/onap/ccsdk/features/sdnr/wt/oauthprovider/data/OAuthToken.java6
-rw-r--r--sdnr/wt/oauth-provider/provider-jar/src/main/java/org/onap/ccsdk/features/sdnr/wt/oauthprovider/data/UserTokenPayload.java10
-rw-r--r--sdnr/wt/oauth-provider/provider-jar/src/main/java/org/onap/ccsdk/features/sdnr/wt/oauthprovider/filters/AnyRoleHttpAuthenticationFilter.java2
-rw-r--r--sdnr/wt/oauth-provider/provider-jar/src/main/java/org/onap/ccsdk/features/sdnr/wt/oauthprovider/http/AuthHttpServlet.java10
-rw-r--r--sdnr/wt/oauth-provider/provider-jar/src/main/java/org/onap/ccsdk/features/sdnr/wt/oauthprovider/providers/AuthService.java7
-rw-r--r--sdnr/wt/oauth-provider/provider-jar/src/main/java/org/onap/ccsdk/features/sdnr/wt/oauthprovider/providers/GitlabProviderService.java3
-rw-r--r--sdnr/wt/oauth-provider/provider-jar/src/main/java/org/onap/ccsdk/features/sdnr/wt/oauthprovider/providers/KeycloakProviderService.java3
-rw-r--r--sdnr/wt/oauth-provider/provider-jar/src/main/java/org/onap/ccsdk/features/sdnr/wt/oauthprovider/providers/MdSalAuthorizationStore.java4
-rw-r--r--sdnr/wt/oauth-provider/provider-jar/src/main/java/org/onap/ccsdk/features/sdnr/wt/oauthprovider/providers/NextcloudProviderService.java2
-rw-r--r--sdnr/wt/oauth-provider/provider-jar/src/main/java/org/onap/ccsdk/features/sdnr/wt/oauthprovider/providers/PemUtils.java106
-rw-r--r--sdnr/wt/oauth-provider/provider-jar/src/main/java/org/onap/ccsdk/features/sdnr/wt/oauthprovider/providers/RSAKeyReader.java47
-rw-r--r--sdnr/wt/oauth-provider/provider-jar/src/main/java/org/onap/ccsdk/features/sdnr/wt/oauthprovider/providers/TokenCreator.java78
-rw-r--r--sdnr/wt/oauth-provider/provider-jar/src/test/java/org/onap/ccsdk/features/sdnr/wt/oauthprovider/test/TestAuthHttpServlet.java12
-rw-r--r--sdnr/wt/oauth-provider/provider-jar/src/test/java/org/onap/ccsdk/features/sdnr/wt/oauthprovider/test/TestConfig.java39
-rw-r--r--sdnr/wt/oauth-provider/provider-jar/src/test/java/org/onap/ccsdk/features/sdnr/wt/oauthprovider/test/TestDeserializer.java2
-rw-r--r--sdnr/wt/oauth-provider/provider-jar/src/test/java/org/onap/ccsdk/features/sdnr/wt/oauthprovider/test/TestGitlabAuthService.java6
-rw-r--r--sdnr/wt/oauth-provider/provider-jar/src/test/java/org/onap/ccsdk/features/sdnr/wt/oauthprovider/test/TestKeycloakAuthService.java5
-rw-r--r--sdnr/wt/oauth-provider/provider-jar/src/test/java/org/onap/ccsdk/features/sdnr/wt/oauthprovider/test/TestRSAAlgorithms.java108
-rw-r--r--sdnr/wt/oauth-provider/provider-jar/src/test/java/org/onap/ccsdk/features/sdnr/wt/oauthprovider/test/TestRealm.java7
-rw-r--r--sdnr/wt/oauth-provider/provider-jar/src/test/resources/jwtRS256.key27
-rw-r--r--sdnr/wt/oauth-provider/provider-jar/src/test/resources/jwtRS256.key.pub9
-rw-r--r--sdnr/wt/oauth-provider/provider-jar/src/test/resources/jwtRS512.key51
-rw-r--r--sdnr/wt/oauth-provider/provider-jar/src/test/resources/jwtRS512.key.pub14
-rw-r--r--sdnr/wt/oauth-provider/provider-jar/src/test/resources/test.config.json1
-rw-r--r--sdnr/wt/oauth-provider/provider-jar/src/test/resources/test.configRS256-invalid.json24
-rw-r--r--sdnr/wt/oauth-provider/provider-jar/src/test/resources/test.configRS256.json22
-rw-r--r--sdnr/wt/oauth-provider/provider-jar/src/test/resources/test.configRS512.json22
31 files changed, 743 insertions, 85 deletions
diff --git a/sdnr/wt/oauth-provider/provider-jar/pom.xml b/sdnr/wt/oauth-provider/provider-jar/pom.xml
index d4e3113d6..24b07bb8e 100644
--- a/sdnr/wt/oauth-provider/provider-jar/pom.xml
+++ b/sdnr/wt/oauth-provider/provider-jar/pom.xml
@@ -65,13 +65,13 @@
<artifactId>java-jwt</artifactId>
</dependency>
<dependency>
+ <groupId>org.bouncycastle</groupId>
+ <artifactId>bcprov-jdk15on</artifactId>
+ </dependency>
+ <dependency>
<groupId>org.opendaylight.aaa</groupId>
<artifactId>aaa-shiro</artifactId>
<exclusions>
-<!-- <exclusion> -->
-<!-- <groupId>org.opendaylight.aaa</groupId> -->
-<!-- <artifactId>aaa-shiro-api</artifactId> -->
-<!-- </exclusion> -->
<exclusion>
<groupId>org.opendaylight.aaa</groupId>
<artifactId>aaa-cert</artifactId>
@@ -120,10 +120,6 @@
<groupId>ehcache-root</groupId>
<artifactId>ehcache</artifactId>
</exclusion>
-<!-- <exclusion> -->
-<!-- <groupId>org.jolokia</groupId> -->
-<!-- <artifactId>jolokia-osgi</artifactId> -->
-<!-- </exclusion> -->
</exclusions>
</dependency>
<dependency>
diff --git a/sdnr/wt/oauth-provider/provider-jar/src/main/java/org/onap/ccsdk/features/sdnr/wt/oauthprovider/OAuth2Realm.java b/sdnr/wt/oauth-provider/provider-jar/src/main/java/org/onap/ccsdk/features/sdnr/wt/oauthprovider/OAuth2Realm.java
index 6dbed1f85..908b91dcf 100644
--- a/sdnr/wt/oauth-provider/provider-jar/src/main/java/org/onap/ccsdk/features/sdnr/wt/oauthprovider/OAuth2Realm.java
+++ b/sdnr/wt/oauth-provider/provider-jar/src/main/java/org/onap/ccsdk/features/sdnr/wt/oauthprovider/OAuth2Realm.java
@@ -26,15 +26,16 @@ import java.io.IOException;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
+import org.apache.shiro.authc.BearerToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.subject.PrincipalCollection;
import org.onap.ccsdk.features.sdnr.wt.oauthprovider.data.Config;
+import org.onap.ccsdk.features.sdnr.wt.oauthprovider.data.InvalidConfigurationException;
import org.onap.ccsdk.features.sdnr.wt.oauthprovider.providers.TokenCreator;
import org.opendaylight.aaa.api.shiro.principal.ODLPrincipal;
-import org.apache.shiro.authc.BearerToken;
import org.opendaylight.aaa.shiro.realm.TokenAuthRealm;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -46,7 +47,7 @@ public class OAuth2Realm extends TokenAuthRealm {
private final TokenCreator tokenCreator;
private final Config config;
- public OAuth2Realm() throws IOException {
+ public OAuth2Realm() throws IllegalArgumentException, IOException, InvalidConfigurationException {
super();
super.setName(REALM_NAME);
this.config = Config.getInstance();
diff --git a/sdnr/wt/oauth-provider/provider-jar/src/main/java/org/onap/ccsdk/features/sdnr/wt/oauthprovider/data/Config.java b/sdnr/wt/oauth-provider/provider-jar/src/main/java/org/onap/ccsdk/features/sdnr/wt/oauthprovider/data/Config.java
index 3ebc144d3..6798026f3 100644
--- a/sdnr/wt/oauth-provider/provider-jar/src/main/java/org/onap/ccsdk/features/sdnr/wt/oauthprovider/data/Config.java
+++ b/sdnr/wt/oauth-provider/provider-jar/src/main/java/org/onap/ccsdk/features/sdnr/wt/oauthprovider/data/Config.java
@@ -21,13 +21,16 @@
*/
package org.onap.ccsdk.features.sdnr.wt.oauthprovider.data;
+import com.fasterxml.jackson.annotation.JsonGetter;
import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonSetter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.nio.file.Files;
+import java.security.SecureRandom;
+import java.util.Arrays;
import java.util.List;
-import java.util.Random;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.slf4j.Logger;
@@ -44,25 +47,40 @@ public class Config {
private static final String DEFAULT_TOKENSECRET = generateSecret();
private static final String DEFAULT_REDIRECTURI = "/odlux/index.html#/oauth?token=";
private static final String DEFAULT_SUPPORTODLUSERS = "true";
- private static Random random;
+ public static final String TOKENALG_HS256 = "HS256";
+ public static final String TOKENALG_RS256 = "RS256";
+ public static final String TOKENALG_RS512 = "RS512";
+ private static final String CLIENTALG_PRE = "Client";
+ public static final String TOKENALG_CLIENT_RS256 = CLIENTALG_PRE + TOKENALG_RS256;
+ public static final String TOKENALG_CLIENT_RS512 = CLIENTALG_PRE + TOKENALG_RS512;
+ private static final String DEFAULT_TOKEN_ALGORITHM = TOKENALG_HS256;
+
+ private static final long DEFAULT_TOKEN_LIFETIME = 30 * 60;
+ private static final List<String> VALID_ALGORITHMS =
+ Arrays.asList(TOKENALG_HS256, TOKENALG_RS256, TOKENALG_RS512, TOKENALG_CLIENT_RS256, TOKENALG_CLIENT_RS512);
+ private static final List<String> VALID_ALGORITHMS_FOR_INTERNAL_LOGIN =
+ Arrays.asList(TOKENALG_HS256, TOKENALG_RS256, TOKENALG_RS512);
+ private static SecureRandom random;
private static Config _instance;
private List<OAuthProviderConfig> providers;
private String redirectUri;
private String supportOdlUsers;
private String tokenSecret;
+ private String tokenPubKey;
+ private String algorithm;
private String tokenIssuer;
private String publicUrl;
-
+ private long tokenLifetime;
@Override
public String toString() {
return "Config [providers=" + providers + ", redirectUri=" + redirectUri + ", supportOdlUsers="
- + supportOdlUsers + ", tokenSecret=" + tokenSecret + ", tokenIssuer=" + tokenIssuer + "]";
+ + supportOdlUsers + ", tokenSecret=***, tokenPubKey=" + tokenPubKey + ", algorithm=" + algorithm
+ + ", tokenIssuer=" + tokenIssuer + ", publicUrl=" + publicUrl + ", tokenLifetime=" + tokenLifetime
+ + "]";
}
-
-
public List<OAuthProviderConfig> getProviders() {
return providers;
}
@@ -95,6 +113,24 @@ public class Config {
this.tokenSecret = tokenSecret;
}
+ public String getAlgorithm() {
+ return this.algorithm;
+ }
+
+ public void setAlgorithm(String alg) {
+ this.algorithm = alg;
+ }
+
+ @JsonGetter("tokenPubKey")
+ public String getPublicKey() {
+ return this.tokenPubKey;
+ }
+
+ @JsonSetter("tokenPubKey")
+ public void setPublicKey(String pubKey) {
+ this.tokenPubKey = pubKey;
+ }
+
public String getTokenIssuer() {
return tokenIssuer;
}
@@ -103,7 +139,6 @@ public class Config {
this.tokenIssuer = tokenIssuer;
}
-
public String getPublicUrl() {
return publicUrl;
}
@@ -112,25 +147,39 @@ public class Config {
this.publicUrl = publicUrl;
}
+ public long getTokenLifetime() {
+ return this.tokenLifetime;
+ }
+
+ public void setTokenLifetime(long lifetime) {
+ this.tokenLifetime = lifetime;
+ }
+
@JsonIgnore
private void handleEnvironmentVars() {
- if (isEnvExpression(tokenIssuer)) {
- this.tokenIssuer = getProperty(tokenIssuer, null);
+ if (isEnvExpression(this.tokenIssuer)) {
+ this.tokenIssuer = getProperty(this.tokenIssuer, null);
+ }
+ if (isEnvExpression(this.tokenSecret)) {
+ this.tokenSecret = getProperty(this.tokenSecret, null);
}
- if (isEnvExpression(tokenSecret)) {
- this.tokenSecret = getProperty(tokenSecret, null);
+ if (isEnvExpression(this.tokenPubKey)) {
+ this.tokenPubKey = getProperty(this.tokenPubKey, null);
}
- if (isEnvExpression(publicUrl)) {
- this.publicUrl = getProperty(publicUrl, null);
+ if (isEnvExpression(this.algorithm)) {
+ this.algorithm = getProperty(this.algorithm, null);
}
- if (isEnvExpression(redirectUri)) {
- this.redirectUri = getProperty(redirectUri, null);
+ if (isEnvExpression(this.publicUrl)) {
+ this.publicUrl = getProperty(this.publicUrl, null);
}
- if (isEnvExpression(supportOdlUsers)) {
- this.supportOdlUsers = getProperty(supportOdlUsers, null);
+ if (isEnvExpression(this.redirectUri)) {
+ this.redirectUri = getProperty(this.redirectUri, null);
+ }
+ if (isEnvExpression(this.supportOdlUsers)) {
+ this.supportOdlUsers = getProperty(this.supportOdlUsers, null);
}
if (this.providers != null && !this.providers.isEmpty()) {
- for(OAuthProviderConfig cfg : this.providers) {
+ for (OAuthProviderConfig cfg : this.providers) {
cfg.handleEnvironmentVars();
}
}
@@ -138,21 +187,27 @@ public class Config {
@JsonIgnore
private void handleDefaultValues() {
- if (tokenIssuer == null || tokenIssuer.isEmpty()) {
+ if (this.tokenIssuer == null || this.tokenIssuer.isEmpty()) {
this.tokenIssuer = DEFAULT_TOKENISSUER;
}
- if (tokenSecret == null || tokenSecret.isEmpty()) {
+ if (this.algorithm == null || this.algorithm.isEmpty()) {
+ this.algorithm = DEFAULT_TOKEN_ALGORITHM;
+ }
+ if (TOKENALG_HS256.equals(this.algorithm) && (this.tokenSecret == null || this.tokenSecret.isEmpty())) {
this.tokenSecret = DEFAULT_TOKENSECRET;
}
- if (redirectUri == null || redirectUri.isEmpty() || "null".equals(redirectUri)) {
+ if (this.redirectUri == null || this.redirectUri.isEmpty() || "null".equals(this.redirectUri)) {
this.redirectUri = DEFAULT_REDIRECTURI;
}
- if (publicUrl != null && (publicUrl.isEmpty() || "null".equals(publicUrl))) {
+ if (this.publicUrl != null && (this.publicUrl.isEmpty() || "null".equals(this.publicUrl))) {
this.publicUrl = null;
}
- if (supportOdlUsers == null || supportOdlUsers.isEmpty()) {
+ if (this.supportOdlUsers == null || this.supportOdlUsers.isEmpty()) {
this.supportOdlUsers = DEFAULT_SUPPORTODLUSERS;
}
+ if (this.tokenLifetime <= 0) {
+ this.tokenLifetime = DEFAULT_TOKEN_LIFETIME;
+ }
}
static boolean isEnvExpression(String key) {
@@ -166,8 +221,8 @@ public class Config {
public static String generateSecret(int targetStringLength) {
int leftLimit = 48; // numeral '0'
int rightLimit = 122; // letter 'z'
- if(random==null) {
- random = new Random();
+ if (random == null) {
+ random = new SecureRandom();
}
String generatedString = random.ints(leftLimit, rightLimit + 1)
.filter(i -> (i <= 57 || i >= 65) && (i <= 90 || i >= 97)).limit(targetStringLength)
@@ -198,7 +253,7 @@ public class Config {
String envvar = mkey.substring(2, mkey.length() - 1);
String env = System.getenv(envvar);
tmp = tmp.replace(mkey, env == null ? "" : env);
- if (env != null && env.isEmpty()) {
+ if (env != null && !env.isEmpty()) {
found = true;
}
} catch (SecurityException e) {
@@ -218,7 +273,7 @@ public class Config {
return value.equals("true");
}
- public static Config load(String filename) throws IOException {
+ public static Config load(String filename) throws IOException, InvalidConfigurationException {
CustomObjectMapper mapper = new CustomObjectMapper();
File file = new File(filename);
if (!file.exists()) {
@@ -228,26 +283,65 @@ public class Config {
Config cfg = mapper.readValue(content, Config.class);
cfg.handleEnvironmentVars();
cfg.handleDefaultValues();
+ cfg.validate();
return cfg;
}
@JsonIgnore
+ private void validate() throws InvalidConfigurationException {
+ //verify that algorithm is supported
+ if (!VALID_ALGORITHMS.contains(this.algorithm)) {
+ throw new InvalidConfigurationException(String.format("Algorithm '%s' is not supported ", this.algorithm));
+ }
+ //verify that set values are matching the algorithm
+ //if hs256 check if secret is set
+ if (this.algorithm.startsWith("HS")) {
+ if (this.tokenSecret == null || this.tokenSecret.isBlank()) {
+ throw new InvalidConfigurationException(
+ String.format("There is no secret set for algorithm '%s'", this.algorithm));
+ }
+ }
+ //if rs256 or rs512 check if secret(private key) and pubkey are set
+ if (this.algorithm.startsWith("RS")) {
+ if (this.tokenSecret == null || this.tokenSecret.isBlank()) {
+ throw new InvalidConfigurationException(
+ String.format("There is no secret set for algorithm '%s'", this.algorithm));
+ }
+ if (this.tokenPubKey == null || this.tokenPubKey.isBlank()) {
+ throw new InvalidConfigurationException(
+ String.format("There is no public key for algorithm '%s'", this.algorithm));
+ }
+ }
+ //if client rs256 or client rs512 check if pubkey are set
+ if (this.algorithm.startsWith("Client")) {
+ if (this.tokenPubKey == null || this.tokenPubKey.isBlank()) {
+ throw new InvalidConfigurationException(
+ String.format("There is no public key for algorithm '%s'", this.algorithm));
+ }
+ }
+ }
+
+ @JsonIgnore
public boolean doSupportOdlUsers() {
return "true".equals(this.supportOdlUsers);
}
- public static Config getInstance() throws IOException {
+ public static Config getInstance() throws IOException, InvalidConfigurationException {
return getInstance(DEFAULT_CONFIGFILENAME);
}
- public static Config getInstance(String filename) throws IOException {
+ public static Config getInstance(String filename) throws IOException, InvalidConfigurationException {
if (_instance == null) {
_instance = load(filename);
}
return _instance;
}
+ public boolean loginActive() {
+ return VALID_ALGORITHMS_FOR_INTERNAL_LOGIN.contains(this.algorithm);
+ }
+
}
diff --git a/sdnr/wt/oauth-provider/provider-jar/src/main/java/org/onap/ccsdk/features/sdnr/wt/oauthprovider/data/InvalidConfigurationException.java b/sdnr/wt/oauth-provider/provider-jar/src/main/java/org/onap/ccsdk/features/sdnr/wt/oauthprovider/data/InvalidConfigurationException.java
new file mode 100644
index 000000000..a0e97de74
--- /dev/null
+++ b/sdnr/wt/oauth-provider/provider-jar/src/main/java/org/onap/ccsdk/features/sdnr/wt/oauthprovider/data/InvalidConfigurationException.java
@@ -0,0 +1,32 @@
+/*
+ * ============LICENSE_START=======================================================
+ * ONAP : ccsdk features
+ * ================================================================================
+ * Copyright (C) 2020 highstreet technologies GmbH Intellectual Property.
+ * All rights reserved.
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END=========================================================
+ *
+ */
+package org.onap.ccsdk.features.sdnr.wt.oauthprovider.data;
+
+public class InvalidConfigurationException extends Exception {
+
+ public InvalidConfigurationException(String str) {
+ super(str);
+ }
+
+ private static final long serialVersionUID = 1L;
+
+}
diff --git a/sdnr/wt/oauth-provider/provider-jar/src/main/java/org/onap/ccsdk/features/sdnr/wt/oauthprovider/data/OAuthToken.java b/sdnr/wt/oauth-provider/provider-jar/src/main/java/org/onap/ccsdk/features/sdnr/wt/oauthprovider/data/OAuthToken.java
index b05d3948a..825286dd0 100644
--- a/sdnr/wt/oauth-provider/provider-jar/src/main/java/org/onap/ccsdk/features/sdnr/wt/oauthprovider/data/OAuthToken.java
+++ b/sdnr/wt/oauth-provider/provider-jar/src/main/java/org/onap/ccsdk/features/sdnr/wt/oauthprovider/data/OAuthToken.java
@@ -25,16 +25,19 @@ import com.auth0.jwt.JWT;
import com.auth0.jwt.interfaces.DecodedJWT;
import org.apache.shiro.authc.BearerToken;
+
public class OAuthToken {
private final String access_token;
private final String token_type;
private final long expires_at;
+ private final long issued_at;
public OAuthToken(BearerToken btoken) {
this.access_token = btoken.getToken();
this.token_type = "Bearer";
DecodedJWT token = JWT.decode(this.access_token);
this.expires_at = token.getExpiresAt().getTime() / 1000L;
+ this.issued_at = token.getIssuedAt().getTime() / 1000L;
}
public String getAccess_token() {
@@ -48,5 +51,8 @@ public class OAuthToken {
public long getExpires_at() {
return expires_at;
}
+ public long getIssued_at() {
+ return issued_at;
+ }
}
diff --git a/sdnr/wt/oauth-provider/provider-jar/src/main/java/org/onap/ccsdk/features/sdnr/wt/oauthprovider/data/UserTokenPayload.java b/sdnr/wt/oauth-provider/provider-jar/src/main/java/org/onap/ccsdk/features/sdnr/wt/oauthprovider/data/UserTokenPayload.java
index 229cdbf78..a983dd69f 100644
--- a/sdnr/wt/oauth-provider/provider-jar/src/main/java/org/onap/ccsdk/features/sdnr/wt/oauthprovider/data/UserTokenPayload.java
+++ b/sdnr/wt/oauth-provider/provider-jar/src/main/java/org/onap/ccsdk/features/sdnr/wt/oauthprovider/data/UserTokenPayload.java
@@ -30,11 +30,17 @@ public class UserTokenPayload {
private String givenName;
private String familyName;
private long exp;
+ private long iat;
+
public long getExp() {
return exp;
}
+ public long getIat() {
+ return this.iat;
+ }
+
public void setPreferredUsername(String preferredUsername) {
this.preferredUsername = preferredUsername;
}
@@ -51,6 +57,10 @@ public class UserTokenPayload {
this.exp = exp;
}
+ public void setIat(long iat) {
+ this.iat = iat;
+ }
+
public String getPreferredUsername() {
return preferredUsername;
}
diff --git a/sdnr/wt/oauth-provider/provider-jar/src/main/java/org/onap/ccsdk/features/sdnr/wt/oauthprovider/filters/AnyRoleHttpAuthenticationFilter.java b/sdnr/wt/oauth-provider/provider-jar/src/main/java/org/onap/ccsdk/features/sdnr/wt/oauthprovider/filters/AnyRoleHttpAuthenticationFilter.java
index 0dc58efff..e0714faf8 100644
--- a/sdnr/wt/oauth-provider/provider-jar/src/main/java/org/onap/ccsdk/features/sdnr/wt/oauthprovider/filters/AnyRoleHttpAuthenticationFilter.java
+++ b/sdnr/wt/oauth-provider/provider-jar/src/main/java/org/onap/ccsdk/features/sdnr/wt/oauthprovider/filters/AnyRoleHttpAuthenticationFilter.java
@@ -72,4 +72,4 @@ public class AnyRoleHttpAuthenticationFilter extends RolesAuthorizationFilter {
LOG.debug("no role matched: access denied");
return false;
}
-} \ No newline at end of file
+}
diff --git a/sdnr/wt/oauth-provider/provider-jar/src/main/java/org/onap/ccsdk/features/sdnr/wt/oauthprovider/http/AuthHttpServlet.java b/sdnr/wt/oauth-provider/provider-jar/src/main/java/org/onap/ccsdk/features/sdnr/wt/oauthprovider/http/AuthHttpServlet.java
index 686684f35..96faccba0 100644
--- a/sdnr/wt/oauth-provider/provider-jar/src/main/java/org/onap/ccsdk/features/sdnr/wt/oauthprovider/http/AuthHttpServlet.java
+++ b/sdnr/wt/oauth-provider/provider-jar/src/main/java/org/onap/ccsdk/features/sdnr/wt/oauthprovider/http/AuthHttpServlet.java
@@ -39,12 +39,14 @@ import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.ShiroException;
+import org.apache.shiro.authc.BearerToken;
import org.apache.shiro.codec.Base64;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;
import org.jolokia.osgi.security.Authenticator;
import org.onap.ccsdk.features.sdnr.wt.common.http.BaseHTTPClient;
import org.onap.ccsdk.features.sdnr.wt.oauthprovider.data.Config;
+import org.onap.ccsdk.features.sdnr.wt.oauthprovider.data.InvalidConfigurationException;
import org.onap.ccsdk.features.sdnr.wt.oauthprovider.data.NoDefinitionFoundException;
import org.onap.ccsdk.features.sdnr.wt.oauthprovider.data.OAuthProviderConfig;
import org.onap.ccsdk.features.sdnr.wt.oauthprovider.data.OAuthToken;
@@ -56,7 +58,6 @@ import org.onap.ccsdk.features.sdnr.wt.oauthprovider.providers.MdSalAuthorizatio
import org.onap.ccsdk.features.sdnr.wt.oauthprovider.providers.OAuthProviderFactory;
import org.onap.ccsdk.features.sdnr.wt.oauthprovider.providers.TokenCreator;
import org.opendaylight.aaa.api.IdMService;
-import org.apache.shiro.authc.BearerToken;
import org.opendaylight.mdsal.binding.api.DataBroker;
import org.opendaylight.yang.gen.v1.urn.opendaylight.aaa.app.config.rev170619.ShiroConfiguration;
import org.opendaylight.yang.gen.v1.urn.opendaylight.aaa.app.config.rev170619.shiro.configuration.Main;
@@ -101,7 +102,7 @@ public class AuthHttpServlet extends HttpServlet {
private static ShiroConfiguration shiroConfiguration;
private static MdSalAuthorizationStore mdsalAuthStore;
- public AuthHttpServlet() throws IOException {
+ public AuthHttpServlet() throws IllegalArgumentException, IOException, InvalidConfigurationException {
this.config = Config.getInstance();
this.tokenCreator = TokenCreator.getInstance(this.config);
this.mapper = new ObjectMapper();
@@ -300,7 +301,7 @@ public class AuthHttpServlet extends HttpServlet {
private UserTokenPayload getUserInfo(HttpServletRequest req) {
if (isBearer(req)) {
- UserTokenPayload data = TokenCreator.getInstance(this.config).decode(req);
+ UserTokenPayload data = this.tokenCreator.decode(req);
if (data != null) {
return data;
}
@@ -414,7 +415,7 @@ public class AuthHttpServlet extends HttpServlet {
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
LOG.debug("POST request for {}", req.getRequestURI());
- if (this.config.doSupportOdlUsers() && LOGINURI.equals(req.getRequestURI())) {
+ if (this.config.loginActive() && this.config.doSupportOdlUsers() && LOGINURI.equals(req.getRequestURI())) {
final String username = req.getParameter("username");
final String domain = req.getParameter("domain");
BearerToken token =
@@ -443,6 +444,7 @@ public class AuthHttpServlet extends HttpServlet {
data.setPreferredUsername(username);
data.setFamilyName("");
data.setGivenName(username);
+ data.setIat(this.tokenCreator.getDefaultIat());
data.setExp(this.tokenCreator.getDefaultExp());
data.setRoles(roles);
return this.tokenCreator.createNewJWT(data);
diff --git a/sdnr/wt/oauth-provider/provider-jar/src/main/java/org/onap/ccsdk/features/sdnr/wt/oauthprovider/providers/AuthService.java b/sdnr/wt/oauth-provider/provider-jar/src/main/java/org/onap/ccsdk/features/sdnr/wt/oauthprovider/providers/AuthService.java
index f16975f6f..bb0857ab6 100644
--- a/sdnr/wt/oauth-provider/provider-jar/src/main/java/org/onap/ccsdk/features/sdnr/wt/oauthprovider/providers/AuthService.java
+++ b/sdnr/wt/oauth-provider/provider-jar/src/main/java/org/onap/ccsdk/features/sdnr/wt/oauthprovider/providers/AuthService.java
@@ -41,13 +41,13 @@ import java.util.stream.Collectors;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
+import org.apache.shiro.authc.BearerToken;
import org.onap.ccsdk.features.sdnr.wt.oauthprovider.data.OAuthProviderConfig;
import org.onap.ccsdk.features.sdnr.wt.oauthprovider.data.OAuthResponseData;
import org.onap.ccsdk.features.sdnr.wt.oauthprovider.data.UserTokenPayload;
import org.onap.ccsdk.features.sdnr.wt.oauthprovider.http.AuthHttpServlet;
import org.onap.ccsdk.features.sdnr.wt.oauthprovider.http.client.MappedBaseHttpResponse;
import org.onap.ccsdk.features.sdnr.wt.oauthprovider.http.client.MappingBaseHttpClient;
-import org.apache.shiro.authc.BearerToken;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -74,7 +74,7 @@ public abstract class AuthService {
protected abstract String getLoginUrl(String callbackUrl);
- protected abstract UserTokenPayload requestUserRoles(String access_token, long expires_at);
+ protected abstract UserTokenPayload requestUserRoles(String access_token, long issued_at, long expires_at);
protected abstract boolean verifyState(String state);
@@ -128,7 +128,8 @@ public abstract class AuthService {
if (this.doSeperateRolesRequest()) {
//long expiresAt = this.tokenCreator.getDefaultExp(Math.round(response.getExpires_in()));
long expiresAt = this.tokenCreator.getDefaultExp();
- UserTokenPayload data = this.requestUserRoles(response.getAccess_token(), expiresAt);
+ long issuedAt = this.tokenCreator.getDefaultIat();
+ UserTokenPayload data = this.requestUserRoles(response.getAccess_token(), issuedAt, expiresAt);
if (data != null) {
this.handleUserInfoToken(data, resp, host);
} else {
diff --git a/sdnr/wt/oauth-provider/provider-jar/src/main/java/org/onap/ccsdk/features/sdnr/wt/oauthprovider/providers/GitlabProviderService.java b/sdnr/wt/oauth-provider/provider-jar/src/main/java/org/onap/ccsdk/features/sdnr/wt/oauthprovider/providers/GitlabProviderService.java
index 4a8bdfa1b..1111603c9 100644
--- a/sdnr/wt/oauth-provider/provider-jar/src/main/java/org/onap/ccsdk/features/sdnr/wt/oauthprovider/providers/GitlabProviderService.java
+++ b/sdnr/wt/oauth-provider/provider-jar/src/main/java/org/onap/ccsdk/features/sdnr/wt/oauthprovider/providers/GitlabProviderService.java
@@ -95,7 +95,7 @@ public class GitlabProviderService extends AuthService {
}
@Override
- protected UserTokenPayload requestUserRoles(String access_token, long expires_at) {
+ protected UserTokenPayload requestUserRoles(String access_token, long issued_at, long expires_at) {
LOG.info("reqesting user roles with token={}", access_token);
Map<String, String> authHeaders = new HashMap<>();
authHeaders.put("Authorization", String.format("Bearer %s", access_token));
@@ -116,6 +116,7 @@ public class GitlabProviderService extends AuthService {
data.setPreferredUsername(uInfo.getUsername());
data.setGivenName(uInfo.getName());
data.setFamilyName(uInfo.getName());
+ data.setIat(issued_at);
data.setExp(expires_at);
List<String> roles = new ArrayList<>();
GitlabGroupInfo[] uRoles = groupInfos.get().body;
diff --git a/sdnr/wt/oauth-provider/provider-jar/src/main/java/org/onap/ccsdk/features/sdnr/wt/oauthprovider/providers/KeycloakProviderService.java b/sdnr/wt/oauth-provider/provider-jar/src/main/java/org/onap/ccsdk/features/sdnr/wt/oauthprovider/providers/KeycloakProviderService.java
index c226a14dc..dbc577664 100644
--- a/sdnr/wt/oauth-provider/provider-jar/src/main/java/org/onap/ccsdk/features/sdnr/wt/oauthprovider/providers/KeycloakProviderService.java
+++ b/sdnr/wt/oauth-provider/provider-jar/src/main/java/org/onap/ccsdk/features/sdnr/wt/oauthprovider/providers/KeycloakProviderService.java
@@ -84,6 +84,7 @@ public class KeycloakProviderService extends AuthService {
protected UserTokenPayload mapAccessToken(String spayload) throws JsonMappingException, JsonProcessingException {
KeycloakUserTokenPayload payload = mapper.readValue(spayload, KeycloakUserTokenPayload.class);
UserTokenPayload data = new UserTokenPayload();
+ data.setIat(payload.getIat() * 1000L);
data.setExp(payload.getExp() * 1000L);
data.setFamilyName(payload.getFamilyName());
data.setGivenName(payload.getGivenName());
@@ -93,7 +94,7 @@ public class KeycloakProviderService extends AuthService {
}
@Override
- protected UserTokenPayload requestUserRoles(String access_token, long expires_at) {
+ protected UserTokenPayload requestUserRoles(String access_token, long issued_at, long expires_at) {
return null;
}
diff --git a/sdnr/wt/oauth-provider/provider-jar/src/main/java/org/onap/ccsdk/features/sdnr/wt/oauthprovider/providers/MdSalAuthorizationStore.java b/sdnr/wt/oauth-provider/provider-jar/src/main/java/org/onap/ccsdk/features/sdnr/wt/oauthprovider/providers/MdSalAuthorizationStore.java
index 293fe33f9..ca7f47138 100644
--- a/sdnr/wt/oauth-provider/provider-jar/src/main/java/org/onap/ccsdk/features/sdnr/wt/oauthprovider/providers/MdSalAuthorizationStore.java
+++ b/sdnr/wt/oauth-provider/provider-jar/src/main/java/org/onap/ccsdk/features/sdnr/wt/oauthprovider/providers/MdSalAuthorizationStore.java
@@ -50,7 +50,9 @@ public class MdSalAuthorizationStore {
public Optional<OdlPolicy> getPolicy(String path, List<String> userRoles) {
InstanceIdentifier<Policies> iif = InstanceIdentifier.create(HttpAuthorization.class).child(Policies.class);
Optional<Policies> odata = Optional.empty();
- try (ReadTransaction transaction = this.dataBroker.newReadOnlyTransaction()) {
+ // The implicite close is not handled correctly by underlaying opendaylight netconf service
+ ReadTransaction transaction = this.dataBroker.newReadOnlyTransaction();
+ try {
odata = transaction.read(LogicalDatastoreType.CONFIGURATION, iif).get();
} catch (ExecutionException e) {
LOG.warn("unable to read policies from mdsal: ", e);
diff --git a/sdnr/wt/oauth-provider/provider-jar/src/main/java/org/onap/ccsdk/features/sdnr/wt/oauthprovider/providers/NextcloudProviderService.java b/sdnr/wt/oauth-provider/provider-jar/src/main/java/org/onap/ccsdk/features/sdnr/wt/oauthprovider/providers/NextcloudProviderService.java
index 03b0f4f75..b6f045cdd 100644
--- a/sdnr/wt/oauth-provider/provider-jar/src/main/java/org/onap/ccsdk/features/sdnr/wt/oauthprovider/providers/NextcloudProviderService.java
+++ b/sdnr/wt/oauth-provider/provider-jar/src/main/java/org/onap/ccsdk/features/sdnr/wt/oauthprovider/providers/NextcloudProviderService.java
@@ -71,7 +71,7 @@ public class NextcloudProviderService extends AuthService {
}
@Override
- protected UserTokenPayload requestUserRoles(String access_token, long expires_at) {
+ protected UserTokenPayload requestUserRoles(String access_token, long issued_at, long expires_at) {
// TODO Auto-generated method stub
return null;
}
diff --git a/sdnr/wt/oauth-provider/provider-jar/src/main/java/org/onap/ccsdk/features/sdnr/wt/oauthprovider/providers/PemUtils.java b/sdnr/wt/oauth-provider/provider-jar/src/main/java/org/onap/ccsdk/features/sdnr/wt/oauthprovider/providers/PemUtils.java
new file mode 100644
index 000000000..fac46f6b1
--- /dev/null
+++ b/sdnr/wt/oauth-provider/provider-jar/src/main/java/org/onap/ccsdk/features/sdnr/wt/oauthprovider/providers/PemUtils.java
@@ -0,0 +1,106 @@
+/*
+ * ============LICENSE_START=======================================================
+ * ONAP : ccsdk features
+ * ================================================================================
+ * Copyright (C) 2020 highstreet technologies GmbH Intellectual Property.
+ * All rights reserved.
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END=========================================================
+ *
+ */
+package org.onap.ccsdk.features.sdnr.wt.oauthprovider.providers;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.Reader;
+import java.io.StringReader;
+import java.security.KeyFactory;
+import java.security.NoSuchAlgorithmException;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.security.spec.EncodedKeySpec;
+import java.security.spec.InvalidKeySpecException;
+import java.security.spec.PKCS8EncodedKeySpec;
+import java.security.spec.X509EncodedKeySpec;
+import org.bouncycastle.util.io.pem.PemObject;
+import org.bouncycastle.util.io.pem.PemReader;
+
+public class PemUtils {
+
+ private static byte[] parsePEMFile(File pemFile) throws IOException {
+ if (!pemFile.isFile() || !pemFile.exists()) {
+ throw new FileNotFoundException(String.format("The file '%s' doesn't exist.", pemFile.getAbsolutePath()));
+ }
+ return parsePEMFile(new FileReader(pemFile));
+ }
+ private static byte[] parsePEMFile(Reader inputReader) throws IOException {
+ PemReader reader = new PemReader(inputReader);
+ PemObject pemObject = reader.readPemObject();
+ byte[] content = pemObject.getContent();
+ reader.close();
+ return content;
+ }
+ private static PublicKey getPublicKey(byte[] keyBytes, String algorithm) {
+ PublicKey publicKey = null;
+ try {
+ KeyFactory kf = KeyFactory.getInstance(algorithm);
+ EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
+ publicKey = kf.generatePublic(keySpec);
+ } catch (NoSuchAlgorithmException e) {
+ System.out.println("Could not reconstruct the public key, the given algorithm could not be found.");
+ } catch (InvalidKeySpecException e) {
+ System.out.println("Could not reconstruct the public key");
+ }
+
+ return publicKey;
+ }
+
+ private static PrivateKey getPrivateKey(byte[] keyBytes, String algorithm) {
+ PrivateKey privateKey = null;
+ try {
+ KeyFactory kf = KeyFactory.getInstance(algorithm);
+ EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);
+ privateKey = kf.generatePrivate(keySpec);
+ } catch (NoSuchAlgorithmException e) {
+ System.out.println("Could not reconstruct the private key, the given algorithm could not be found.");
+ } catch (InvalidKeySpecException e) {
+ System.out.println("Could not reconstruct the private key");
+ }
+
+ return privateKey;
+ }
+
+ public static PublicKey readPublicKeyFromFile(String filepath, String algorithm) throws IOException {
+ byte[] bytes = PemUtils.parsePEMFile(new File(filepath));
+ return PemUtils.getPublicKey(bytes, algorithm);
+ }
+
+ public static PublicKey readPublicKey(String filecontent, String algorithm) throws IOException {
+ byte[] bytes = PemUtils.parsePEMFile(new StringReader(filecontent));
+ return PemUtils.getPublicKey(bytes, algorithm);
+ }
+
+ public static PrivateKey readPrivateKeyFromFile(String filepath, String algorithm) throws IOException {
+ byte[] bytes = PemUtils.parsePEMFile(new File(filepath));
+ return PemUtils.getPrivateKey(bytes, algorithm);
+ }
+
+ public static PrivateKey readPrivateKey(String filecontent, String algorithm) throws IOException {
+ byte[] bytes = PemUtils.parsePEMFile(new StringReader(filecontent));
+ return PemUtils.getPrivateKey(bytes, algorithm);
+ }
+
+} \ No newline at end of file
diff --git a/sdnr/wt/oauth-provider/provider-jar/src/main/java/org/onap/ccsdk/features/sdnr/wt/oauthprovider/providers/RSAKeyReader.java b/sdnr/wt/oauth-provider/provider-jar/src/main/java/org/onap/ccsdk/features/sdnr/wt/oauthprovider/providers/RSAKeyReader.java
new file mode 100644
index 000000000..028dff9dd
--- /dev/null
+++ b/sdnr/wt/oauth-provider/provider-jar/src/main/java/org/onap/ccsdk/features/sdnr/wt/oauthprovider/providers/RSAKeyReader.java
@@ -0,0 +1,47 @@
+/*
+ * ============LICENSE_START=======================================================
+ * ONAP : ccsdk features
+ * ================================================================================
+ * Copyright (C) 2020 highstreet technologies GmbH Intellectual Property.
+ * All rights reserved.
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END=========================================================
+ *
+ */
+package org.onap.ccsdk.features.sdnr.wt.oauthprovider.providers;
+
+import java.io.IOException;
+import java.security.interfaces.RSAPrivateKey;
+import java.security.interfaces.RSAPublicKey;
+
+public class RSAKeyReader {
+
+ private static final String PREFIX_FILEURL = "file://";
+
+ public static RSAPrivateKey getPrivateKey(String filenameOrContent) throws IOException {
+ if (filenameOrContent.startsWith(PREFIX_FILEURL)) {
+ return (RSAPrivateKey) PemUtils.readPrivateKeyFromFile(filenameOrContent.substring(PREFIX_FILEURL.length()),
+ "RSA");
+ }
+ return (RSAPrivateKey) PemUtils.readPrivateKey(filenameOrContent, "RSA");
+ }
+
+ public static RSAPublicKey getPublicKey(String filenameOrContent) throws IOException {
+ if (filenameOrContent.startsWith(PREFIX_FILEURL)) {
+ return (RSAPublicKey) PemUtils.readPublicKeyFromFile(filenameOrContent.substring(PREFIX_FILEURL.length()),
+ "RSA");
+ }
+ return (RSAPublicKey) PemUtils.readPublicKey(filenameOrContent, "RSA");
+ }
+}
diff --git a/sdnr/wt/oauth-provider/provider-jar/src/main/java/org/onap/ccsdk/features/sdnr/wt/oauthprovider/providers/TokenCreator.java b/sdnr/wt/oauth-provider/provider-jar/src/main/java/org/onap/ccsdk/features/sdnr/wt/oauthprovider/providers/TokenCreator.java
index c2515e2b9..238f888bb 100644
--- a/sdnr/wt/oauth-provider/provider-jar/src/main/java/org/onap/ccsdk/features/sdnr/wt/oauthprovider/providers/TokenCreator.java
+++ b/sdnr/wt/oauth-provider/provider-jar/src/main/java/org/onap/ccsdk/features/sdnr/wt/oauthprovider/providers/TokenCreator.java
@@ -27,56 +27,96 @@ import com.auth0.jwt.exceptions.JWTDecodeException;
import com.auth0.jwt.exceptions.JWTVerificationException;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.auth0.jwt.interfaces.JWTVerifier;
+import java.io.IOException;
+import java.security.Security;
import java.util.Arrays;
import java.util.Date;
import javax.servlet.http.HttpServletRequest;
+import org.apache.shiro.authc.BearerToken;
+import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.onap.ccsdk.features.sdnr.wt.oauthprovider.data.Config;
import org.onap.ccsdk.features.sdnr.wt.oauthprovider.data.UserTokenPayload;
import org.onap.ccsdk.features.sdnr.wt.oauthprovider.http.AuthHttpServlet;
-import org.apache.shiro.authc.BearerToken;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class TokenCreator {
private static final Logger LOG = LoggerFactory.getLogger(AuthHttpServlet.class.getName());
- private static final long DEFAULT_TOKEN_LIFETIME_MS = 30 * 60 * 1000L;
private final String issuer;
private static TokenCreator _instance;
- private final String secret;
+ private final long tokenLifetimeSeconds;
+ private final Algorithm algorithm;
private static final String ROLES_CLAIM = "roles";
private static final String FAMILYNAME_CLAIM = "family_name";
private static final String NAME_CLAIM = "name";
- public static TokenCreator getInstance(Config config) {
+ static {
+ Security.addProvider(
+ new BouncyCastleProvider()
+ );
+ }
+ public static TokenCreator getInstance(Config config) throws IllegalArgumentException, IOException {
if (_instance == null) {
_instance = new TokenCreator(config);
}
return _instance;
}
- public static TokenCreator getInstance(String secret, String issuer) {
+
+ public static TokenCreator getInstance(String alg, String secret, String issuer, long tokenLifetime)
+ throws IllegalArgumentException, IOException {
+ return getInstance(alg, secret, null, issuer, tokenLifetime);
+ }
+
+ public static TokenCreator getInstance(String alg, String secret, String pubkey, String issuer, long tokenLifetime)
+ throws IllegalArgumentException, IOException {
if (_instance == null) {
- _instance = new TokenCreator(secret, issuer);
+ _instance = new TokenCreator(alg, secret, pubkey, issuer, tokenLifetime);
}
return _instance;
}
- private TokenCreator(Config config) {
- this(config.getTokenSecret(),config.getTokenIssuer());
+ private TokenCreator(Config config) throws IllegalArgumentException, IOException {
+ this(config.getAlgorithm(), config.getTokenSecret(), config.getPublicKey(), config.getTokenIssuer(),
+ config.getTokenLifetime());
}
- private TokenCreator(String secret, String issuer) {
- this.secret = secret;
+
+ private TokenCreator(String alg, String secret, String pubkey, String issuer, long tokenLifetime)
+ throws IllegalArgumentException, IOException {
this.issuer = issuer;
+ this.tokenLifetimeSeconds = tokenLifetime;
+ this.algorithm = this.createAlgorithm(alg, secret, pubkey);
+ }
+
+ private Algorithm createAlgorithm(String alg, String secret, String pubkey)
+ throws IllegalArgumentException, IOException {
+ if(alg==null) {
+ alg = Config.TOKENALG_HS256;
+ }
+ switch (alg) {
+ case Config.TOKENALG_HS256:
+ return Algorithm.HMAC256(secret);
+ case Config.TOKENALG_RS256:
+ return Algorithm.RSA256(RSAKeyReader.getPublicKey(pubkey), RSAKeyReader.getPrivateKey(secret));
+ case Config.TOKENALG_RS512:
+ return Algorithm.RSA512(RSAKeyReader.getPublicKey(pubkey), RSAKeyReader.getPrivateKey(secret));
+ case Config.TOKENALG_CLIENT_RS256:
+ return Algorithm.RSA256(RSAKeyReader.getPublicKey(pubkey), null);
+ case Config.TOKENALG_CLIENT_RS512:
+ return Algorithm.RSA512(RSAKeyReader.getPublicKey(pubkey), null);
+ }
+ throw new IllegalArgumentException(String.format("unable to find algorithm for %s", alg));
+
}
public BearerToken createNewJWT(UserTokenPayload data) {
- Algorithm algorithm = Algorithm.HMAC256(secret);
final String token = JWT.create().withIssuer(issuer).withExpiresAt(new Date(data.getExp()))
- .withSubject(data.getPreferredUsername()).withClaim(NAME_CLAIM, data.getGivenName())
- .withClaim(FAMILYNAME_CLAIM, data.getFamilyName())
+ .withIssuedAt(new Date(data.getIat())).withSubject(data.getPreferredUsername())
+ .withClaim(NAME_CLAIM, data.getGivenName()).withClaim(FAMILYNAME_CLAIM, data.getFamilyName())
.withArrayClaim(ROLES_CLAIM, data.getRoles().toArray(new String[data.getRoles().size()]))
- .sign(algorithm);
+ .sign(this.algorithm);
+ LOG.trace("token created: {}", token);
return new BearerToken(token);
}
@@ -84,8 +124,7 @@ public class TokenCreator {
DecodedJWT jwt = null;
LOG.debug("try to verify token {}", token);
try {
- Algorithm algorithm = Algorithm.HMAC256(secret);
- JWTVerifier verifier = JWT.require(algorithm).withIssuer(issuer).build();
+ JWTVerifier verifier = JWT.require(this.algorithm).withIssuer(issuer).build();
jwt = verifier.verify(token);
} catch (JWTVerificationException e) {
@@ -95,13 +134,17 @@ public class TokenCreator {
}
public long getDefaultExp() {
- return new Date().getTime() + DEFAULT_TOKEN_LIFETIME_MS;
+ return new Date().getTime() + (this.tokenLifetimeSeconds * 1000);
}
public long getDefaultExp(long expIn) {
return new Date().getTime() + expIn;
}
+ public long getDefaultIat() {
+ return new Date().getTime();
+ }
+
public UserTokenPayload decode(HttpServletRequest req) throws JWTDecodeException {
final String authHeader = req.getHeader("Authorization");
if (authHeader == null || !authHeader.startsWith("Bearer")) {
@@ -117,4 +160,5 @@ public class TokenCreator {
return data;
}
+
}
diff --git a/sdnr/wt/oauth-provider/provider-jar/src/test/java/org/onap/ccsdk/features/sdnr/wt/oauthprovider/test/TestAuthHttpServlet.java b/sdnr/wt/oauth-provider/provider-jar/src/test/java/org/onap/ccsdk/features/sdnr/wt/oauthprovider/test/TestAuthHttpServlet.java
index 1fbe43a07..ab6dc4ec2 100644
--- a/sdnr/wt/oauth-provider/provider-jar/src/test/java/org/onap/ccsdk/features/sdnr/wt/oauthprovider/test/TestAuthHttpServlet.java
+++ b/sdnr/wt/oauth-provider/provider-jar/src/test/java/org/onap/ccsdk/features/sdnr/wt/oauthprovider/test/TestAuthHttpServlet.java
@@ -41,6 +41,7 @@ import java.util.Optional;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
+import org.apache.shiro.authc.BearerToken;
import org.jolokia.osgi.security.Authenticator;
import org.json.JSONArray;
import org.junit.BeforeClass;
@@ -49,6 +50,7 @@ import org.onap.ccsdk.features.sdnr.wt.common.http.BaseHTTPClient;
import org.onap.ccsdk.features.sdnr.wt.common.test.ServletOutputStreamToByteArrayOutputStream;
import org.onap.ccsdk.features.sdnr.wt.oauthprovider.data.Config;
import org.onap.ccsdk.features.sdnr.wt.oauthprovider.data.CustomObjectMapper;
+import org.onap.ccsdk.features.sdnr.wt.oauthprovider.data.InvalidConfigurationException;
import org.onap.ccsdk.features.sdnr.wt.oauthprovider.data.OdlPolicy;
import org.onap.ccsdk.features.sdnr.wt.oauthprovider.data.UserTokenPayload;
import org.onap.ccsdk.features.sdnr.wt.oauthprovider.http.AuthHttpServlet;
@@ -57,7 +59,6 @@ import org.onap.ccsdk.features.sdnr.wt.oauthprovider.providers.TokenCreator;
import org.onap.ccsdk.features.sdnr.wt.oauthprovider.test.helper.OdlJsonMapper;
import org.onap.ccsdk.features.sdnr.wt.oauthprovider.test.helper.OdlXmlMapper;
import org.opendaylight.aaa.api.IdMService;
-import org.apache.shiro.authc.BearerToken;
import org.opendaylight.mdsal.binding.api.DataBroker;
import org.opendaylight.mdsal.binding.api.ReadTransaction;
import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
@@ -84,14 +85,15 @@ public class TestAuthHttpServlet {
// Map.of("Authorization", BaseHTTPClient.getAuthorizationHeaderValue("admin@sdn", "admin")));
@BeforeClass
- public static void init() {
+ public static void init() throws IllegalArgumentException, Exception {
try {
Config config = createConfigFile();
tokenCreator = TokenCreator.getInstance(config);
servlet = new TestServlet();
shiroConfiguration = loadShiroConfig(TESTSHIROCONFIGFILE);
- } catch (IOException e) {
+ } catch (IOException | InvalidConfigurationException e) {
+ e.printStackTrace();
fail(e.getMessage());
}
servlet.setDataBroker(dataBroker);
@@ -124,7 +126,7 @@ public class TestAuthHttpServlet {
return mapper.readValue(new File(filename), ShiroConfigurationBuilder.class).build();
}
- private static Config createConfigFile() throws IOException {
+ private static Config createConfigFile() throws IOException, InvalidConfigurationException {
return Config.getInstance(TESTCONFIGFILE);
}
@@ -351,7 +353,7 @@ public class TestAuthHttpServlet {
private static final long serialVersionUID = 1L;
- public TestServlet() throws IOException {
+ public TestServlet() throws IllegalArgumentException, Exception {
super();
}
diff --git a/sdnr/wt/oauth-provider/provider-jar/src/test/java/org/onap/ccsdk/features/sdnr/wt/oauthprovider/test/TestConfig.java b/sdnr/wt/oauth-provider/provider-jar/src/test/java/org/onap/ccsdk/features/sdnr/wt/oauthprovider/test/TestConfig.java
index d07950de7..80ae8cf95 100644
--- a/sdnr/wt/oauth-provider/provider-jar/src/test/java/org/onap/ccsdk/features/sdnr/wt/oauthprovider/test/TestConfig.java
+++ b/sdnr/wt/oauth-provider/provider-jar/src/test/java/org/onap/ccsdk/features/sdnr/wt/oauthprovider/test/TestConfig.java
@@ -21,25 +21,60 @@
*/
package org.onap.ccsdk.features.sdnr.wt.oauthprovider.test;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
import java.io.IOException;
import org.junit.Test;
import org.onap.ccsdk.features.sdnr.wt.oauthprovider.data.Config;
+import org.onap.ccsdk.features.sdnr.wt.oauthprovider.data.InvalidConfigurationException;
public class TestConfig {
public static String TEST_CONFIG_FILENAME = "src/test/resources/test.config.json";
public static String TEST_OOMCONFIG_FILENAME = "src/test/resources/oom.test.config.json";
+ public static String TEST_RS256_FILENAME = "src/test/resources/test.configRS256.json";
+ public static String TEST_RS256INVALID_FILENAME = "src/test/resources/test.configRS256-invalid.json";
+ public static String TEST_RS512_FILENAME = "src/test/resources/test.configRS512.json";
+
+
@Test
- public void test() throws IOException {
+ public void test() throws IOException, InvalidConfigurationException {
Config config = Config.load(TEST_CONFIG_FILENAME);
System.out.println("config="+config);
+ assertEquals(60*60,config.getTokenLifetime());
+ assertNotNull(config.getAlgorithm());
+ assertNotNull(config.getTokenSecret());
+ //assertNotNull(config.getPublicKey());
+ assertEquals(Config.TOKENALG_HS256, config.getAlgorithm());
}
@Test
- public void testOom() throws IOException {
+ public void testOom() throws IOException, InvalidConfigurationException {
Config config = Config.load(TEST_OOMCONFIG_FILENAME);
System.out.println("config="+config);
+ assertEquals(30*60,config.getTokenLifetime());
+
+ }
+ @Test
+ public void testRS256() throws IOException, InvalidConfigurationException {
+
+ Config config = Config.load(TEST_RS256_FILENAME);
+ System.out.println("config="+config);
+ assertEquals(60*60,config.getTokenLifetime());
+
+ }
+ @Test
+ public void testRS512() throws IOException, InvalidConfigurationException {
+
+ Config config = Config.load(TEST_RS512_FILENAME);
+ System.out.println("config="+config);
+ assertEquals(60*60,config.getTokenLifetime());
+
+ }
+ @Test(expected = InvalidConfigurationException.class)
+ public void testRS256Invalid() throws IOException, InvalidConfigurationException {
+ Config.load(TEST_RS256INVALID_FILENAME);
}
}
diff --git a/sdnr/wt/oauth-provider/provider-jar/src/test/java/org/onap/ccsdk/features/sdnr/wt/oauthprovider/test/TestDeserializer.java b/sdnr/wt/oauth-provider/provider-jar/src/test/java/org/onap/ccsdk/features/sdnr/wt/oauthprovider/test/TestDeserializer.java
index 65ef2cbd6..421b61919 100644
--- a/sdnr/wt/oauth-provider/provider-jar/src/test/java/org/onap/ccsdk/features/sdnr/wt/oauthprovider/test/TestDeserializer.java
+++ b/sdnr/wt/oauth-provider/provider-jar/src/test/java/org/onap/ccsdk/features/sdnr/wt/oauthprovider/test/TestDeserializer.java
@@ -40,8 +40,6 @@ public class TestDeserializer {
final String token = "eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJ1OHNXaTF4QWxjT1pyelY4X0l2VjliMlJTaFdZUWV4aXZYUXNYLTFTME"
+ "RNIn0.eyJleHAiOjE2MTAzNjE2OTQsImlhdCI6MTYxMDM2MTM5NCwianRpIjoiOWRhOThmMTYtOTEyOS00N2NmLTgzOGQtNWQzYmVkYzYyZTJjIiwiaXNzIjoiaHR0cDovLzEwLjIwLjExLjE2MDo4MDgwL2F1dGgvcmVhbG1zL21hc3RlciIsInN1YiI6IjE4MzhjNGYyLTVmZTMtNGYwYy1iMmQyLWQzNjRiMjdhNDk5NyIsInR5cCI6IkJlYXJlciIsImF6cCI6ImFkbWluLWNsaSIsInNlc3Npb25fc3RhdGUiOiJjYzcxZmMxZi1hZGQ0LTRhODYtYWU1ZS1jMzRkZjQwM2M3NzIiLCJhY3IiOiIxIiwic2NvcGUiOiJlbWFpbCBwcm9maWxlIiwiZW1haWxfdmVyaWZpZWQiOmZhbHNlLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJhZG1pbiJ9.PUT4NzCM1ej3sNMMCkQa1NuQQwDgn19G-OnWL4NgLvZ3ocJUZ1Yfr9KAPkrJHaiK_HXQqwTA-Ma6Qn7BBMoXNdFjwu0k_HpqyUbBDilGN4wpkGiUeS1p5SW4T_hnWJtwCJ5BYkEvF6WaEbi7MFCbEVO9LVcUvsa-7St1WZ8V8RVfbWgjAu7ejlxe6RYUDMYzIKDj5F5y1-qCyoKzGIjt5ajcA9FWrexHifLJECKO8ZG08Wp7xQld1sYPOdde6XHMwiyNelTwd_EzCBgUw_8664rETGDVtyfuYchowo5Z6fmn4U87L6EGjEuxiAE8f3USy_jh6UF0LnvyTyq_9I"
+ "M1VA";
- final String token2 = "eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJ1OHNXaTF4QWxjT1pyelY4X0l2VjliMlJTaFdZUWV4aXZYUXNYLTFTMERNIn0."
- + "eyJleHAiOjE2MTAzNzA3MDcsImlhdCI6MTYxMDM3MDQwNywianRpIjoiMTczMmI0YzQtNDJlYS00ZWM4LTlhNjMtMTY2YTg4ZTk5ZjQ0IiwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDo4MDgwL2F1dGgvcmVhbG1zL21hc3RlciIsInN1YiI6IjE4MzhjNGYyLTVmZTMtNGYwYy1iMmQyLWQzNjRiMjdhNDk5NyIsInR5cCI6IkJlYXJlciIsImF6cCI6ImFkbWluLWNsaSIsInNlc3Npb25fc3RhdGUiOiJhZjVkYTk2NS1jYmIzLTQzOTYtYmNjNi1kZTBkMDUyOWMyNDgiLCJhY3IiOiIxIiwic2NvcGUiOiJlbWFpbCBwcm9maWxlIiwiZW1haWxfdmVyaWZpZWQiOmZhbHNlLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJhZG1pbiJ9.G_1ByqQlPuJ6_5nuIECfY1VqGufzWQpnFKuOy8YPOOug_jJsIwhVo-JQJiKAxYbHbmDNLrpRJTFlSub0K-1AFyxMw0k_W_YLV0dOTqIakVMTKk9obHFAYtthvhdbt5zb9-33OdCRMMKjA-arj8UeOLEAeFkaeYYBARCD4mEnMFG0vzEiovCCD-jXsfISiS-lOYnCd3hWK8e0brk_bvauxS9W4Z6nptE2564wshe9N_j9-3bQRRAHiAt6f755PhbYgJAu87GdA0bLh_TDe6fie-03goIFMssHoq4n67i-8501UoIG_LccijnfexCS-YwxkfTLbz5d8PvsNadqvFlvig";
final String response =
"{\"access_token\":\"eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJ1OHNXaTF4QWxjT1pyelY4X0l2VjliMlJTaFdZUWV4aXZYUXNYLTFTME"
+ "RNIn0.eyJleHAiOjE2MTAzNjE2OTQsImlhdCI6MTYxMDM2MTM5NCwianRpIjoiOWRhOThmMTYtOTEyOS00N2NmLTgzOGQtNWQzYmVkYzYyZTJjIiwiaXNzIjoiaHR0cDovLzEwLjIwLjExLjE2MDo4MDgwL2F1dGgvcmVhbG1zL21hc3RlciIsInN1YiI6IjE4MzhjNGYyLTVmZTMtNGYwYy1iMmQyLWQzNjRiMjdhNDk5NyIsInR5cCI6IkJlYXJlciIsImF6cCI6I"
diff --git a/sdnr/wt/oauth-provider/provider-jar/src/test/java/org/onap/ccsdk/features/sdnr/wt/oauthprovider/test/TestGitlabAuthService.java b/sdnr/wt/oauth-provider/provider-jar/src/test/java/org/onap/ccsdk/features/sdnr/wt/oauthprovider/test/TestGitlabAuthService.java
index 6c46ed25f..dda3ba1e0 100644
--- a/sdnr/wt/oauth-provider/provider-jar/src/test/java/org/onap/ccsdk/features/sdnr/wt/oauthprovider/test/TestGitlabAuthService.java
+++ b/sdnr/wt/oauth-provider/provider-jar/src/test/java/org/onap/ccsdk/features/sdnr/wt/oauthprovider/test/TestGitlabAuthService.java
@@ -41,6 +41,7 @@ import javax.servlet.http.HttpServletResponse;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
+import org.onap.ccsdk.features.sdnr.wt.oauthprovider.data.Config;
import org.onap.ccsdk.features.sdnr.wt.oauthprovider.data.OAuthProviderConfig;
import org.onap.ccsdk.features.sdnr.wt.oauthprovider.providers.GitlabProviderService;
import org.onap.ccsdk.features.sdnr.wt.oauthprovider.providers.TokenCreator;
@@ -57,9 +58,9 @@ public class TestGitlabAuthService {
private static final String REDIRECT_URI = "/odlux/token?";
@BeforeClass
- public static void init() {
+ public static void init() throws IllegalArgumentException, Exception {
- TokenCreator tokenCreator = TokenCreator.getInstance(TOKENCREATOR_SECRET, "issuer");
+ TokenCreator tokenCreator = TokenCreator.getInstance(Config.TOKENALG_HS256, TOKENCREATOR_SECRET, "issuer", 30*60);
OAuthProviderConfig config = new OAuthProviderConfig("git", GITURL, null, "odlux.app", OAUTH_SECRET, "openid",
"gitlab test", "", false);
oauthService = new GitlabProviderServiceToTest(config, REDIRECT_URI, tokenCreator);
@@ -160,7 +161,6 @@ public class TestGitlabAuthService {
final String uri = t.getRequestURI().toString();
System.out.println(String.format("req received: %s %s", method, t.getRequestURI()));
OutputStream os = null;
- String response = "";
try {
if (method.equals("GET")) {
if (uri.equals(GITLAB_USER_ENDPOINT)) {
diff --git a/sdnr/wt/oauth-provider/provider-jar/src/test/java/org/onap/ccsdk/features/sdnr/wt/oauthprovider/test/TestKeycloakAuthService.java b/sdnr/wt/oauth-provider/provider-jar/src/test/java/org/onap/ccsdk/features/sdnr/wt/oauthprovider/test/TestKeycloakAuthService.java
index 30b24af03..e4c5e4d82 100644
--- a/sdnr/wt/oauth-provider/provider-jar/src/test/java/org/onap/ccsdk/features/sdnr/wt/oauthprovider/test/TestKeycloakAuthService.java
+++ b/sdnr/wt/oauth-provider/provider-jar/src/test/java/org/onap/ccsdk/features/sdnr/wt/oauthprovider/test/TestKeycloakAuthService.java
@@ -41,6 +41,7 @@ import javax.servlet.http.HttpServletResponse;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
+import org.onap.ccsdk.features.sdnr.wt.oauthprovider.data.Config;
import org.onap.ccsdk.features.sdnr.wt.oauthprovider.data.OAuthProviderConfig;
import org.onap.ccsdk.features.sdnr.wt.oauthprovider.providers.KeycloakProviderService;
import org.onap.ccsdk.features.sdnr.wt.oauthprovider.providers.TokenCreator;
@@ -57,9 +58,9 @@ public class TestKeycloakAuthService {
private static final String REDIRECT_URI = "/odlux/token?";
@BeforeClass
- public static void init() {
+ public static void init() throws IllegalArgumentException, Exception {
- TokenCreator tokenCreator = TokenCreator.getInstance(TOKENCREATOR_SECRET, "issuer");
+ TokenCreator tokenCreator = TokenCreator.getInstance(Config.TOKENALG_HS256, TOKENCREATOR_SECRET, "issuer", 30*60);
OAuthProviderConfig config = new OAuthProviderConfig("kc", KEYCLOAKURL, null, "odlux.app", OAUTH_SECRET,
"openid", "keycloak test", "onap", false);
oauthService = new KeycloakProviderServiceToTest(config, REDIRECT_URI, tokenCreator);
diff --git a/sdnr/wt/oauth-provider/provider-jar/src/test/java/org/onap/ccsdk/features/sdnr/wt/oauthprovider/test/TestRSAAlgorithms.java b/sdnr/wt/oauth-provider/provider-jar/src/test/java/org/onap/ccsdk/features/sdnr/wt/oauthprovider/test/TestRSAAlgorithms.java
new file mode 100644
index 000000000..84d8e0a96
--- /dev/null
+++ b/sdnr/wt/oauth-provider/provider-jar/src/test/java/org/onap/ccsdk/features/sdnr/wt/oauthprovider/test/TestRSAAlgorithms.java
@@ -0,0 +1,108 @@
+/*
+ * ============LICENSE_START=======================================================
+ * ONAP : ccsdk features
+ * ================================================================================
+ * Copyright (C) 2020 highstreet technologies GmbH Intellectual Property.
+ * All rights reserved.
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END=========================================================
+ *
+ */
+package org.onap.ccsdk.features.sdnr.wt.oauthprovider.test;
+
+import static org.junit.Assert.fail;
+import com.auth0.jwt.JWT;
+import com.auth0.jwt.algorithms.Algorithm;
+import com.auth0.jwt.exceptions.JWTVerificationException;
+import com.auth0.jwt.interfaces.JWTVerifier;
+import java.io.IOException;
+import java.security.Security;
+import java.security.interfaces.RSAPrivateKey;
+import java.security.interfaces.RSAPublicKey;
+import java.util.Date;
+import org.bouncycastle.jce.provider.BouncyCastleProvider;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.onap.ccsdk.features.sdnr.wt.oauthprovider.providers.RSAKeyReader;
+
+/**
+ *
+ * @author jack
+ *
+ */
+public class TestRSAAlgorithms {
+
+ private static final String ISSUER = "jwttest";
+ private static final String SUBJECT = "meandmymonkey";
+
+ @BeforeClass
+ public static void init() {
+ Security.addProvider(
+ new BouncyCastleProvider()
+ );
+ }
+
+ /**
+ * private and public key were generated in ubuntu 20.04 with
+ * $ ssh-keygen -t rsa -b 4096 -m PEM -P "" -f jwtRS512.key
+ * $ openssl rsa -in jwtRS512.key -pubout -outform PEM -out jwtRS512.key.pub
+ */
+ @Test
+ public void testRSA512() {
+ RSAPrivateKey privKey = null;
+ RSAPublicKey pubKey = null;
+ try {
+ privKey = RSAKeyReader.getPrivateKey("file://src/test/resources/jwtRS512.key");
+ pubKey = RSAKeyReader.getPublicKey("file://src/test/resources/jwtRS512.key.pub");
+ } catch (IOException e) {
+ e.printStackTrace();
+ fail(e.getMessage());
+ }
+ verifyAlg(Algorithm.RSA512(pubKey, privKey));
+ }
+
+ /**
+ * private and public key were generated in ubuntu 20.04 with
+ * $ openssl genrsa 2048 -out rsa-2048bit-jwtRS256.key
+ * $ openssl rsa -in jwtRS256.key -pubout > jwtRS256.key.pub
+ */
+ @Test
+ public void testRSA256() {
+ RSAPrivateKey privKey = null;
+ RSAPublicKey pubKey = null;
+ try {
+ privKey = RSAKeyReader.getPrivateKey("file://src/test/resources/jwtRS256.key");
+ pubKey = RSAKeyReader.getPublicKey("file://src/test/resources/jwtRS256.key.pub");
+ } catch (IOException e) {
+ e.printStackTrace();
+ fail(e.getMessage());
+ }
+ verifyAlg(Algorithm.RSA512(pubKey, privKey));
+ }
+
+ private static void verifyAlg(Algorithm a) {
+ long now = new Date().getTime();
+ final String token = JWT.create().withIssuer(ISSUER).withExpiresAt(new Date(now+10000))
+ .withIssuedAt(new Date(now))
+ .withSubject(SUBJECT)
+ .sign(a);
+ try {
+ JWTVerifier verifier = JWT.require(a).withIssuer(ISSUER).build();
+ verifier.verify(token);
+
+ } catch (JWTVerificationException e) {
+ fail(e.getMessage());
+ }
+ }
+}
diff --git a/sdnr/wt/oauth-provider/provider-jar/src/test/java/org/onap/ccsdk/features/sdnr/wt/oauthprovider/test/TestRealm.java b/sdnr/wt/oauth-provider/provider-jar/src/test/java/org/onap/ccsdk/features/sdnr/wt/oauthprovider/test/TestRealm.java
index 4b2011836..c08f395fb 100644
--- a/sdnr/wt/oauth-provider/provider-jar/src/test/java/org/onap/ccsdk/features/sdnr/wt/oauthprovider/test/TestRealm.java
+++ b/sdnr/wt/oauth-provider/provider-jar/src/test/java/org/onap/ccsdk/features/sdnr/wt/oauthprovider/test/TestRealm.java
@@ -34,6 +34,7 @@ import java.util.List;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
+import org.apache.shiro.authc.BearerToken;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.subject.PrincipalCollection;
@@ -44,7 +45,6 @@ import org.onap.ccsdk.features.sdnr.wt.oauthprovider.data.Config;
import org.onap.ccsdk.features.sdnr.wt.oauthprovider.data.UserTokenPayload;
import org.onap.ccsdk.features.sdnr.wt.oauthprovider.providers.TokenCreator;
import org.opendaylight.aaa.api.shiro.principal.ODLPrincipal;
-import org.apache.shiro.authc.BearerToken;
import org.opendaylight.aaa.shiro.tokenauthrealm.auth.AuthenticationManager;
import org.opendaylight.aaa.shiro.tokenauthrealm.auth.TokenAuthenticators;
import org.opendaylight.aaa.shiro.web.env.ThreadLocals;
@@ -55,7 +55,7 @@ public class TestRealm {
private static TokenCreator tokenCreator;
@BeforeClass
- public static void init() {
+ public static void init() throws IllegalArgumentException, Exception {
ThreadLocals.AUTH_SETVICE_TL.set(new AuthenticationManager());
ThreadLocals.TOKEN_AUTHENICATORS_TL.set(new TokenAuthenticators());
try {
@@ -135,6 +135,7 @@ public class TestRealm {
fail(e.getMessage());
}
//odl token use case
+ ai=null;
atoken = new UsernamePasswordToken("admin", "admin");
try {
ai = realm.doGetAuthenticationInfo(atoken);
@@ -155,7 +156,7 @@ public class TestRealm {
public static class OAuth2RealmToTest extends OAuth2Realm {
- public OAuth2RealmToTest() throws IOException {
+ public OAuth2RealmToTest() throws IllegalArgumentException, Exception {
super();
}
diff --git a/sdnr/wt/oauth-provider/provider-jar/src/test/resources/jwtRS256.key b/sdnr/wt/oauth-provider/provider-jar/src/test/resources/jwtRS256.key
new file mode 100644
index 000000000..c0c15e014
--- /dev/null
+++ b/sdnr/wt/oauth-provider/provider-jar/src/test/resources/jwtRS256.key
@@ -0,0 +1,27 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEpQIBAAKCAQEAyzd6BwZLS1UKchZENYyVycHZWp9iRTtLx31dZHfG8h0PLawG
+y+dXPEW8W/zVB13/Rdci9HXCnskBhzkFu9Ep+nI7X5C+lO3vxxNnGQ1CrRyHxHbb
+BYlm6J55l6tQox5qVcWe4iMbLm7F2eNKFPqEUu8OInjmLFZvS9C0qtfpqdeoyt4G
+XucUHcGZ/0E6yeq882+zYyb4pWN5PogAsP2KYeT1T6P0VCw4tda9GtokD3zOSaOg
+IvhIqe9jLAVcqWkxpuhV+IQdULBOxcJziW3AdQcB5IFQ7/SfZ9SnO5OpDTe02R5q
+bjH9k0iihrpI9HnlVrHqIEtFwDjuoPSeAOBjjwIDAQABAoIBAQCOfNeTFVa1+2rX
+k8U/xtNAJCvC3v6IjIsV1VEmoNVd7gI2g+hAEHWaTUtFNIIqKD5VOgPIZMmRjF8F
+8XWTu5UzheUbnOIEitEVRQWFC0c1GkwX9T6dIzqE4JlhPz3LIghtG6PL69GjPQh9
+PmEzVHRzsiq3AQ5jCDgBcNU89SdhbhPsfNpDq9+GaWUaVJ4MmJw52qLeSW0nh4NZ
+fMSINAfGZ/3Q2Nfe55zIk4KICyatKYLUMdcwynMwWYdZzg1e/4gxemdWdgFVUdPl
+rE6y404m+FrHl/nntL153u0C24jtEU0CJvLasu7hLjzAoANBzohcXxLY46jeNqk9
+yS4juMgBAoGBAPxn9hRH5vMxFCfT23/s1RnUB9Sal6OL8/hZ8OpwrnLaLmWDvvr5
+FBcDThhrHnJTLj0pOAxFX8kLjKgQdWB0ZqrEsG1R9AAVHxM4hXc92kDsAk4QJgCG
+tKDtzk9PKy8Jt1LnOF9n6NDLZuZim9Sv7qim6tt0L7K/mGrlCN4Gq6E3AoGBAM4c
+N2r0vObiSboryfY4xNSUZ1qLWAEJz4gyUQljSrlu2Gj5DK4rrTEd8Qyk9ehUdjuR
+giejpdjIvmjQ7NNPUogJbIoSbtKmx+k8qF7ieRulJjVBiJZLwNtGhiB4e6oZdhNl
+fJETn8MhkbOt8Sa1eEiR9u2O7IAYVwZLU/khkNxpAoGARxqKSgBPYSbsRKP767et
++I6wfgXmvd3JJqc/pOuFWTl5ZIOOo2jTbgAyWdKjSxV/qx8XeO16JEqqnxWz2y4v
+Vd/+y20QzY0lqeZ8QrEb8LoLlC4cZn2MGOGlAtaMlb2o9SPJz6aYAWmrXS9eMrY1
+BzGua4/5d+Ndbo+CxfkfFFUCgYEAjFimW8w+/TDFZ2H96g2J6f8LyZns2PgnOuSY
+Tb4w2cfi0MgVnFvdWP68bxG86PDqeXGBoSBMBCvdjF4HhXQUDNHt+K7Ii+RJaEaH
+l+S69tokBEuViFIZBrclCeNAwfkIb/jBM8CbHzIylpkxBly3hSLvc5/I5wir6XtN
+uOzkSVECgYEAy2oGf68OkNL74/WKDmQvnRxWkn78rCTzVAe0iJmJ3rAdak/Jb2Lj
+iihXn0XPsedZOZStbZYCG6GtcZCRypPi9HjO6DRRYFv3+aicjS7tVuJ3u39e5nIR
+K6eMAgFn1TAToc3gt/hUCnmreZ4ZUfQfuFK21Lqmn1FYJtck9ZHx0sw=
+-----END RSA PRIVATE KEY-----
diff --git a/sdnr/wt/oauth-provider/provider-jar/src/test/resources/jwtRS256.key.pub b/sdnr/wt/oauth-provider/provider-jar/src/test/resources/jwtRS256.key.pub
new file mode 100644
index 000000000..add863aef
--- /dev/null
+++ b/sdnr/wt/oauth-provider/provider-jar/src/test/resources/jwtRS256.key.pub
@@ -0,0 +1,9 @@
+-----BEGIN PUBLIC KEY-----
+MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyzd6BwZLS1UKchZENYyV
+ycHZWp9iRTtLx31dZHfG8h0PLawGy+dXPEW8W/zVB13/Rdci9HXCnskBhzkFu9Ep
++nI7X5C+lO3vxxNnGQ1CrRyHxHbbBYlm6J55l6tQox5qVcWe4iMbLm7F2eNKFPqE
+Uu8OInjmLFZvS9C0qtfpqdeoyt4GXucUHcGZ/0E6yeq882+zYyb4pWN5PogAsP2K
+YeT1T6P0VCw4tda9GtokD3zOSaOgIvhIqe9jLAVcqWkxpuhV+IQdULBOxcJziW3A
+dQcB5IFQ7/SfZ9SnO5OpDTe02R5qbjH9k0iihrpI9HnlVrHqIEtFwDjuoPSeAOBj
+jwIDAQAB
+-----END PUBLIC KEY-----
diff --git a/sdnr/wt/oauth-provider/provider-jar/src/test/resources/jwtRS512.key b/sdnr/wt/oauth-provider/provider-jar/src/test/resources/jwtRS512.key
new file mode 100644
index 000000000..6b4e8c7bc
--- /dev/null
+++ b/sdnr/wt/oauth-provider/provider-jar/src/test/resources/jwtRS512.key
@@ -0,0 +1,51 @@
+-----BEGIN RSA PRIVATE KEY-----
+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
+-----END RSA PRIVATE KEY-----
diff --git a/sdnr/wt/oauth-provider/provider-jar/src/test/resources/jwtRS512.key.pub b/sdnr/wt/oauth-provider/provider-jar/src/test/resources/jwtRS512.key.pub
new file mode 100644
index 000000000..7191c95f8
--- /dev/null
+++ b/sdnr/wt/oauth-provider/provider-jar/src/test/resources/jwtRS512.key.pub
@@ -0,0 +1,14 @@
+-----BEGIN PUBLIC KEY-----
+MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA5vZBjfLjlUPK0b/F8FbG
+AyT1jXNVv2vjl+ZGUlThDX1jn0WhXER5CL9CfkHKjJE47r8pQsO6nX9s5y+XzmAU
+9+QggtaDA+g0Px+cvCJQzJbtDbh094m3uC50S+SSnYvr7vY1zy+jdswf/pXg1z05
+9FokRxGso36SkSv81NYbN/WQrTKogY6jkZXfPP8/sn8KV8uf7jYy2ZyHtakM9c9o
+CopWH78mhf9ioUNbgJsAxZmiohQUN5a3GbLS/nsTBOcVxUezvjvfb732iChKoARj
+3NiNN7HFHpXEXfiZ10OjrtAb9Y1K9RZsu/MKcFxBhDZusXjee6/x+NluQwT3Rybg
+kCyV/i97Sroc37wOqimxtoSJ+MZYZXNAUGNbNySkjvIGL8jWMj6w/zvyiHVbQg+D
+qY2Qds7Tdk29swYsMQQlz9v0FS/pGFVWo+5HTm+3MMlaMjSofw6j5/sE4OvJ4RCc
+nX8Cj1Zq9PrsMLLSF5MBOCSiclpIC1EYQ9Oi6XrcL3bbyyKGwB/u1X1HHnUmhRdK
+dVwKpSHR54XlfBDDoYtVnb1HTTxXMuiGU0XQRLvdnytJX1Lk6NJg/UUUKhrVXiH0
+5CZsxlPFjDlhEhp4Jh+f/mdf6llXvsXn8k9ujBZBBD6PI4X7GkKB45H9zicbwt65
+f/MjhEohkbL5oZAKySzaUuMCAwEAAQ==
+-----END PUBLIC KEY-----
diff --git a/sdnr/wt/oauth-provider/provider-jar/src/test/resources/test.config.json b/sdnr/wt/oauth-provider/provider-jar/src/test/resources/test.config.json
index 260b77da7..a55576b9e 100644
--- a/sdnr/wt/oauth-provider/provider-jar/src/test/resources/test.config.json
+++ b/sdnr/wt/oauth-provider/provider-jar/src/test/resources/test.config.json
@@ -4,6 +4,7 @@
"publicUrl": "http://nasp.diasf.de",
"redirectUri": "/index.html#redirect=",
"supportOdlUsers": "true",
+ "tokenLifetime":3600,
"providers": [
{
"id": "keycloak",
diff --git a/sdnr/wt/oauth-provider/provider-jar/src/test/resources/test.configRS256-invalid.json b/sdnr/wt/oauth-provider/provider-jar/src/test/resources/test.configRS256-invalid.json
new file mode 100644
index 000000000..30b80c45a
--- /dev/null
+++ b/sdnr/wt/oauth-provider/provider-jar/src/test/resources/test.configRS256-invalid.json
@@ -0,0 +1,24 @@
+{
+ "tokenSecret": "",
+ "tokenPubKey": "file:///src/test/resources/jwtRS256.key.pub",
+ "algorithm":"RS256",
+ "tokenIssuer": "ONAP SDNC",
+ "publicUrl": "http://nasp.diasf.de",
+ "redirectUri": "/index.html#redirect=",
+ "supportOdlUsers": "true",
+ "tokenLifetime":3600,
+ "providers": [
+ {
+ "id": "keycloak",
+ "type": "KEYCLOAK",
+ "url": "http://10.20.11.160:8080",
+ "clientId": "odlux.app",
+ "secret": "5da4ea3d-8cc9-4669-bd7e-3ecb91d120cd",
+ "publickey": "",
+ "algorithm":"RS256",
+ "scope": "openid",
+ "title": "OSNL Keycloak Provider",
+ "realmName":"onap"
+ }
+ ]
+} \ No newline at end of file
diff --git a/sdnr/wt/oauth-provider/provider-jar/src/test/resources/test.configRS256.json b/sdnr/wt/oauth-provider/provider-jar/src/test/resources/test.configRS256.json
new file mode 100644
index 000000000..02a4e8f5f
--- /dev/null
+++ b/sdnr/wt/oauth-provider/provider-jar/src/test/resources/test.configRS256.json
@@ -0,0 +1,22 @@
+{
+ "tokenSecret": "file:///src/test/resources/jwtRS256.key",
+ "tokenPubKey": "file:///src/test/resources/jwtRS256.key.pub",
+ "algorithm":"RS256",
+ "tokenIssuer": "ONAP SDNC",
+ "publicUrl": "http://nasp.diasf.de",
+ "redirectUri": "/index.html#redirect=",
+ "supportOdlUsers": "true",
+ "tokenLifetime":3600,
+ "providers": [
+ {
+ "id": "keycloak",
+ "type": "KEYCLOAK",
+ "url": "http://10.20.11.160:8080",
+ "clientId": "odlux.app",
+ "secret": "5da4ea3d-8cc9-4669-bd7e-3ecb91d120cd",
+ "scope": "openid",
+ "title": "OSNL Keycloak Provider",
+ "realmName":"onap"
+ }
+ ]
+} \ No newline at end of file
diff --git a/sdnr/wt/oauth-provider/provider-jar/src/test/resources/test.configRS512.json b/sdnr/wt/oauth-provider/provider-jar/src/test/resources/test.configRS512.json
new file mode 100644
index 000000000..eddc6c362
--- /dev/null
+++ b/sdnr/wt/oauth-provider/provider-jar/src/test/resources/test.configRS512.json
@@ -0,0 +1,22 @@
+{
+ "tokenSecret": "file:///src/test/resources/jwtRS512.key",
+ "tokenPubKey": "file:///src/test/resources/jwtRS512.key.pub",
+ "algorithm":"RS512",
+ "tokenIssuer": "ONAP SDNC",
+ "publicUrl": "http://nasp.diasf.de",
+ "redirectUri": "/index.html#redirect=",
+ "supportOdlUsers": "true",
+ "tokenLifetime":3600,
+ "providers": [
+ {
+ "id": "keycloak",
+ "type": "KEYCLOAK",
+ "url": "http://10.20.11.160:8080",
+ "clientId": "odlux.app",
+ "secret": "5da4ea3d-8cc9-4669-bd7e-3ecb91d120cd",
+ "scope": "openid",
+ "title": "OSNL Keycloak Provider",
+ "realmName":"onap"
+ }
+ ]
+} \ No newline at end of file