Compare commits
24 Commits
Author | SHA1 | Date |
---|---|---|
Mauro Mugnaini | ee90e6e97f | |
Mauro Mugnaini | ccce7944ee | |
Mauro Mugnaini | 83041827c4 | |
Mauro Mugnaini | 098bfc9fef | |
Mauro Mugnaini | 6da3a9f55a | |
Mauro Mugnaini | ed5ea15599 | |
Alfredo Oliviero | 33a22f9448 | |
Alfredo Oliviero | 7c1597d479 | |
Mauro Mugnaini | fccbedb299 | |
Mauro Mugnaini | fea71c720c | |
Mauro Mugnaini | bbcd35e14f | |
Mauro Mugnaini | a37cd40b99 | |
Mauro Mugnaini | bee9d59f22 | |
Mauro Mugnaini | 3c201dd6f0 | |
Mauro Mugnaini | 79c45245dd | |
Mauro Mugnaini | c5a9dca54c | |
Mauro Mugnaini | 17e503c786 | |
Mauro Mugnaini | 527f04fb67 | |
Mauro Mugnaini | abe7e42937 | |
Mauro Mugnaini | 032168aed6 | |
Mauro Mugnaini | e82d2be4b9 | |
Mauro Mugnaini | ac26a35417 | |
Mauro Mugnaini | 7689b2238e | |
Mauro Mugnaini | 784896bda0 |
26
.classpath
26
.classpath
|
@ -3,23 +3,14 @@
|
|||
<classpathentry excluding="**" kind="src" output="target/classes" path="src/main/resources">
|
||||
<attributes>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
<attribute name="optional" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry excluding="**" kind="src" output="target/test-classes" path="src/test/resources">
|
||||
<attributes>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
<attribute name="test" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8">
|
||||
<attributes>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
|
||||
<attributes>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
<attribute name="org.eclipse.jst.component.nondependency" value=""/>
|
||||
<attribute name="optional" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="src" output="target/classes" path="src/main/java">
|
||||
|
@ -30,9 +21,20 @@
|
|||
</classpathentry>
|
||||
<classpathentry kind="src" output="target/test-classes" path="src/test/java">
|
||||
<attributes>
|
||||
<attribute name="test" value="true"/>
|
||||
<attribute name="optional" value="true"/>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
<attribute name="test" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-11">
|
||||
<attributes>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
|
||||
<attributes>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
<attribute name="org.eclipse.jst.component.nondependency" value=""/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="output" path="target/classes"/>
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
eclipse.preferences.version=1
|
||||
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
|
||||
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
|
||||
org.eclipse.jdt.core.compiler.compliance=1.8
|
||||
org.eclipse.jdt.core.compiler.codegen.targetPlatform=11
|
||||
org.eclipse.jdt.core.compiler.compliance=11
|
||||
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
|
||||
org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled
|
||||
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
|
||||
org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
|
||||
org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning
|
||||
org.eclipse.jdt.core.compiler.release=disabled
|
||||
org.eclipse.jdt.core.compiler.source=1.8
|
||||
org.eclipse.jdt.core.compiler.source=11
|
||||
|
|
|
@ -1,6 +1,14 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?><project-modules id="moduleCoreId" project-version="1.5.0">
|
||||
|
||||
|
||||
<wb-module deploy-name="oidc-library">
|
||||
|
||||
|
||||
<wb-resource deploy-path="/" source-path="/src/main/resources"/>
|
||||
<wb-resource deploy-path="/" source-path="/src/main/java"/>
|
||||
|
||||
|
||||
</wb-module>
|
||||
|
||||
|
||||
</project-modules>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<faceted-project>
|
||||
<installed facet="java" version="1.8"/>
|
||||
<installed facet="jst.utility" version="1.0"/>
|
||||
<installed facet="java" version="11"/>
|
||||
</faceted-project>
|
||||
|
|
19
CHANGELOG.md
19
CHANGELOG.md
|
@ -2,6 +2,25 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
|
|||
|
||||
# Changelog for "oidc-library"
|
||||
|
||||
## [v1.3.3-SNAPSHOT]
|
||||
Added JSON parsed instance of the refresh token to `JWTToken` class, the getter and methods to checks its presence and expiration
|
||||
|
||||
## [v1.3.2]
|
||||
- Header X-D4Science-Context in query exchange and refresh
|
||||
- Token exchange (#27099)
|
||||
- PerformQueryTokenWithPOST accepts also optional headers
|
||||
- PerformURLEncodedPOSTSendData accepts also optional headers
|
||||
- Moved from `maven-portal-bom` to `gcube-bom`
|
||||
|
||||
## [v1.3.1]
|
||||
- Added `Catalogue-Manager` and `Catalogue-Moderator` roles to the enum (#23623)
|
||||
|
||||
## [v1.3.0]
|
||||
- Added method to retrieve UMA token by using `clientId` and `clientSecret` in a specific `audience` (aka context) that can now be provided in both encoded and not encoded form (starts with "/" check is performed).
|
||||
|
||||
## [v1.2.1]
|
||||
- "Data-Editor" role added (#20896), some logs changed to debug level
|
||||
|
||||
## [v1.2.0]
|
||||
- Site is now comparable. Added JTI value getter and essentials info dump in JWT. Revised get avatar helper.
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# OIDC Library
|
||||
|
||||
**OIDC library** provides the basic common classes for OpenId Connect (OIDC) integration and some helper abstract functions for the gCube framework integration
|
||||
**OIDC Library** provides the basic common classes for OpenId Connect (OIDC) integration and some helper abstract functions for the gCube framework integration
|
||||
|
||||
## Structure of the project
|
||||
|
||||
|
|
42
pom.xml
42
pom.xml
|
@ -7,20 +7,20 @@
|
|||
<parent>
|
||||
<artifactId>maven-parent</artifactId>
|
||||
<groupId>org.gcube.tools</groupId>
|
||||
<version>1.1.0</version>
|
||||
<version>1.2.0</version>
|
||||
<relativePath />
|
||||
</parent>
|
||||
|
||||
<groupId>org.gcube.common</groupId>
|
||||
<artifactId>oidc-library</artifactId>
|
||||
<version>1.2.0</version>
|
||||
<version>1.3.3-SNAPSHOT</version>
|
||||
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.gcube.distribution</groupId>
|
||||
<artifactId>maven-portal-bom</artifactId>
|
||||
<version>3.6.0</version>
|
||||
<artifactId>gcube-bom</artifactId>
|
||||
<version>2.4.0</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
|
@ -33,29 +33,47 @@
|
|||
<url>https://code-repo.d4science.org/gCubeSystem/${project.artifactId}</url>
|
||||
</scm>
|
||||
|
||||
<properties>
|
||||
<java.version>8</java.version>
|
||||
<maven.compiler.source>${java.version}</maven.compiler.source>
|
||||
<maven.compiler.target>${java.version}</maven.compiler.target>
|
||||
<slf4j-log4j12.version>1.6.4</slf4j-log4j12.version>
|
||||
<log4j.version>1.2.16</log4j.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-api</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-log4j12</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>log4j</groupId>
|
||||
<artifactId>log4j</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.googlecode.json-simple</groupId>
|
||||
<artifactId>json-simple</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-log4j12</artifactId>
|
||||
<version>${slf4j-log4j12.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>log4j</groupId>
|
||||
<artifactId>log4j</artifactId>
|
||||
<version>${log4j.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>4.12</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<build />
|
||||
|
|
|
@ -15,7 +15,7 @@ public abstract class AbstractOIDCToSitesAndRolesMapper implements OIDCToSitesAn
|
|||
public AbstractOIDCToSitesAndRolesMapper(Map<String, List<String>> resourceName2AccessRoles) {
|
||||
super();
|
||||
this.resourceName2AccessRoles = resourceName2AccessRoles;
|
||||
logger.info("Resource name to access roles: {}", resourceName2AccessRoles);
|
||||
logger.debug("Resource name to access roles: {}", resourceName2AccessRoles);
|
||||
}
|
||||
|
||||
}
|
|
@ -12,6 +12,9 @@ public class D4ScienceMappings {
|
|||
ACCOUNTING_MANAGER("Accounting-Manager"),
|
||||
CATALOGUE_ADMIN("Catalogue-Admin"),
|
||||
CATALOGUE_EDITOR("Catalogue-Editor"),
|
||||
CATALOGUE_MANAGER("Catalogue-Manager"),
|
||||
CATALOGUE_MODERATOR("Catalogue-Moderator"),
|
||||
DATA_EDITOR("Data-Editor"),
|
||||
DATA_MANAGER("Data-Manager"),
|
||||
DATAMINER_MANAGER("DataMiner-Manager"),
|
||||
INFRASTRUCTURE_MANAGER("Infrastructure-Manager"),
|
||||
|
@ -48,23 +51,4 @@ public class D4ScienceMappings {
|
|||
|
||||
}
|
||||
|
||||
public enum Scope {
|
||||
|
||||
BELONGS("belongs");
|
||||
// TODO will be defined later
|
||||
// LIST("list"),
|
||||
// READ("read"),
|
||||
// WRITE("write"),
|
||||
// EXECUTE("execute");
|
||||
|
||||
private String str;
|
||||
|
||||
Scope(String str) {
|
||||
this.str = str;
|
||||
}
|
||||
|
||||
public String asString() {
|
||||
return str;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -33,7 +33,7 @@ public class SlashSeparatedContextMapper extends AbstractOIDCToSitesAndRolesMapp
|
|||
// Sorting sites, the containers site should come before contained one
|
||||
Site gwSitesTree = null;
|
||||
for (String site : sites) {
|
||||
logger.info("Checking site: " + site);
|
||||
logger.debug("Checking site: " + site);
|
||||
List<String> roles = resourceName2AccessRoles.get(site);
|
||||
logger.debug("Roles for site are: {}", roles);
|
||||
String[] siteTokens = site.split(SPLIT_REGEXP);
|
||||
|
@ -45,10 +45,10 @@ public class SlashSeparatedContextMapper extends AbstractOIDCToSitesAndRolesMapp
|
|||
String rootVO = siteTokens[ROOT_VO_TOKEN_INDEX];
|
||||
logger.debug("Root VO is: {}", rootVO);
|
||||
if (!rootSite.equals(rootVO)) {
|
||||
logger.info("Skipping evaluation of site tree not belonging to this Root VO: {}", rootVO);
|
||||
logger.debug("Skipping evaluation of site tree not belonging to this Root VO: {}", rootVO);
|
||||
continue;
|
||||
} else {
|
||||
logger.info("Site belongs to this Root VO");
|
||||
logger.debug("Site belongs to this Root VO");
|
||||
}
|
||||
if (siteTokens.length >= VO_TOKEN_INDEX + 1) {
|
||||
if (gwSitesTree == null) {
|
||||
|
@ -64,19 +64,19 @@ public class SlashSeparatedContextMapper extends AbstractOIDCToSitesAndRolesMapp
|
|||
}
|
||||
String vre = siteTokens[VRE_TOKEN_INDEX];
|
||||
logger.debug("VRE is: {}", vre);
|
||||
logger.info("Adding leaf site: {}", vre);
|
||||
logger.debug("Adding leaf site: {}", vre);
|
||||
gwSitesTree.getChildren().get(vo).getChildren().put(vre, new Site(vre, roles));
|
||||
} else if (!gwSitesTree.getChildren().containsKey(vo)) {
|
||||
logger.info("Creating site for VO: {}", vo);
|
||||
logger.debug("Creating site for VO: {}", vo);
|
||||
gwSitesTree.getChildren().put(vo, new Site(vo, roles));
|
||||
}
|
||||
} else {
|
||||
if (gwSitesTree == null) {
|
||||
logger.info("Creating site for Root VO: {}", rootVO);
|
||||
logger.debug("Creating site for Root VO: {}", rootVO);
|
||||
gwSitesTree = new Site(rootVO, roles);
|
||||
} else {
|
||||
if (gwSitesTree.getRoles() == null) {
|
||||
logger.info("Setting out of order roles for Root VO");
|
||||
logger.debug("Setting out of order roles for Root VO");
|
||||
} else {
|
||||
logger.warn("Duplicated roles definition for Root VO");
|
||||
}
|
||||
|
|
|
@ -26,8 +26,9 @@ public class JWTToken implements Serializable {
|
|||
public static final String ACCOUNT_RESOURCE = "account";
|
||||
|
||||
private String raw;
|
||||
private JSONObject token;
|
||||
private JSONObject tokens;
|
||||
private JSONObject payload;
|
||||
private JSONObject refreshToken;
|
||||
|
||||
public static JWTToken fromString(String tokenString) {
|
||||
if (tokenString == null) {
|
||||
|
@ -47,9 +48,14 @@ public class JWTToken implements Serializable {
|
|||
}
|
||||
|
||||
private void parse() throws ParseException {
|
||||
token = (JSONObject) new JSONParser().parse(this.raw);
|
||||
tokens = (JSONObject) new JSONParser().parse(this.raw);
|
||||
String[] parts = getAccessTokenString().split("\\.");
|
||||
payload = (JSONObject) new JSONParser().parse(new String(Base64.getDecoder().decode(parts[1])));
|
||||
String refreshTokenString = getRefreshTokenString();
|
||||
if (refreshTokenString != null) {
|
||||
refreshToken = (JSONObject) new JSONParser()
|
||||
.parse(new String(Base64.getDecoder().decode(refreshTokenString.split("\\.")[1])));
|
||||
}
|
||||
}
|
||||
|
||||
public String getRaw() {
|
||||
|
@ -57,11 +63,11 @@ public class JWTToken implements Serializable {
|
|||
}
|
||||
|
||||
public String getAccessTokenString() {
|
||||
return (String) token.get("access_token");
|
||||
return (String) tokens.get("access_token");
|
||||
}
|
||||
|
||||
public String getRefreshTokenString() {
|
||||
return (String) token.get("refresh_token");
|
||||
return (String) tokens.get("refresh_token");
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -81,6 +87,14 @@ public class JWTToken implements Serializable {
|
|||
return payload;
|
||||
}
|
||||
|
||||
public boolean hasRefreshToken() {
|
||||
return refreshToken != null;
|
||||
}
|
||||
|
||||
public JSONObject getRefreshToken() {
|
||||
return refreshToken;
|
||||
}
|
||||
|
||||
public String getAzp() {
|
||||
return (String) getPayload().get("azp");
|
||||
}
|
||||
|
@ -89,10 +103,18 @@ public class JWTToken implements Serializable {
|
|||
return (Long) getPayload().get("exp");
|
||||
}
|
||||
|
||||
public Long getRefreshTokenExp() {
|
||||
return hasRefreshToken() ? (Long) getRefreshToken().get("exp") : 0;
|
||||
}
|
||||
|
||||
public Date getExpAsDate() {
|
||||
return new Date(getExp() * 1000);
|
||||
}
|
||||
|
||||
public Date getRefreshTokenExpAsDate() {
|
||||
return new Date(getRefreshTokenExp() * 1000);
|
||||
}
|
||||
|
||||
public Calendar getExpAsCalendar() {
|
||||
Calendar cal = Calendar.getInstance();
|
||||
cal.setTime(getExpAsDate());
|
||||
|
@ -103,6 +125,10 @@ public class JWTToken implements Serializable {
|
|||
return new Date().after(getExpAsDate());
|
||||
}
|
||||
|
||||
public boolean isRefreshTokenExpired() {
|
||||
return new Date().after(getRefreshTokenExpAsDate());
|
||||
}
|
||||
|
||||
public List<String> getAud() {
|
||||
List<String> audienceStrings = new ArrayList<>();
|
||||
Object audience = getPayload().get("aud");
|
||||
|
|
|
@ -13,6 +13,7 @@ import java.net.ProtocolException;
|
|||
import java.net.URL;
|
||||
import java.net.URLEncoder;
|
||||
import java.util.Arrays;
|
||||
import java.util.Base64;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
@ -58,9 +59,35 @@ public class OpenIdConnectRESTHelper {
|
|||
return q;
|
||||
}
|
||||
|
||||
/**
|
||||
* Queries from the OIDC server an OIDC access token, by using provided clientId and client secret.
|
||||
*
|
||||
* @param clientId the client id
|
||||
* @param clientSecret the client secret
|
||||
* @param tokenUrl the token endpoint {@link URL} of the OIDC server
|
||||
* @return the issued token
|
||||
* @throws OpenIdConnectRESTHelperException if an error occurs (also an unauthorized call), inspect the exception for details
|
||||
*/
|
||||
public static JWTToken queryClientToken(String clientId, String clientSecret, URL tokenURL)
|
||||
throws OpenIdConnectRESTHelperException {
|
||||
|
||||
return queryClientToken(clientId, clientSecret, tokenURL, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Queries from the OIDC server an OIDC access token, by using provided clientId and client secret.
|
||||
*
|
||||
* @param clientId the client id
|
||||
* @param clientSecret the client secret
|
||||
* @param tokenUrl the token endpoint {@link URL} of the OIDC server
|
||||
* @param extraHeaders extra HTTP headers to add to the request (e.g. <code>X-D4Science-Context</code> custom header), may be <code>null</code>
|
||||
* @return the issued token
|
||||
* @throws OpenIdConnectRESTHelperException if an error occurs (also an unauthorized call), inspect the exception for details
|
||||
*/
|
||||
public static JWTToken queryClientToken(String clientId, String clientSecret, URL tokenURL,
|
||||
Map<String, String> extraHeaders)
|
||||
throws OpenIdConnectRESTHelperException {
|
||||
|
||||
Map<String, List<String>> params = new HashMap<>();
|
||||
params.put("grant_type", Arrays.asList("client_credentials"));
|
||||
try {
|
||||
|
@ -73,28 +100,41 @@ public class OpenIdConnectRESTHelper {
|
|||
} catch (UnsupportedEncodingException e) {
|
||||
logger.error("Cannot URL encode 'client_secret'", e);
|
||||
}
|
||||
return performQueryTokenWithPOST(tokenURL, null, params);
|
||||
return performQueryTokenWithPOST(tokenURL, null, params, extraHeaders);
|
||||
}
|
||||
|
||||
public static JWTToken queryToken(String clientId, URL tokenURL, String code, String scope,
|
||||
String redirectURI) throws Exception {
|
||||
|
||||
return queryToken(clientId, tokenURL, code, scope, redirectURI, null);
|
||||
}
|
||||
|
||||
public static JWTToken queryToken(String clientId, URL tokenURL, String code, String scope,
|
||||
String redirectURI, Map<String, String> extraHeaders) throws Exception {
|
||||
|
||||
Map<String, List<String>> params = new HashMap<>();
|
||||
params.put("client_id", Arrays.asList(URLEncoder.encode(clientId, "UTF-8")));
|
||||
params.put("grant_type", Arrays.asList("authorization_code"));
|
||||
params.put("scope", Arrays.asList(URLEncoder.encode(scope, "UTF-8")));
|
||||
params.put("code", Arrays.asList(URLEncoder.encode(code, "UTF-8")));
|
||||
params.put("redirect_uri", Arrays.asList(URLEncoder.encode(redirectURI, "UTF-8")));
|
||||
return performQueryTokenWithPOST(tokenURL, null, params);
|
||||
return performQueryTokenWithPOST(tokenURL, null, params, extraHeaders);
|
||||
}
|
||||
|
||||
public static JWTToken performQueryTokenWithPOST(URL tokenURL, String authorization,
|
||||
protected static JWTToken performQueryTokenWithPOST(URL tokenURL, String authorization,
|
||||
Map<String, List<String>> params) throws OpenIdConnectRESTHelperException {
|
||||
|
||||
return performQueryTokenWithPOST(tokenURL, authorization, params, null);
|
||||
}
|
||||
|
||||
protected static JWTToken performQueryTokenWithPOST(URL tokenURL, String authorization,
|
||||
Map<String, List<String>> params, Map<String, String> headers) throws OpenIdConnectRESTHelperException {
|
||||
|
||||
logger.debug("Querying access token from OIDC server with URL: {}", tokenURL);
|
||||
StringBuilder sb;
|
||||
try {
|
||||
HttpURLConnection httpURLConnection = performURLEncodedPOSTSendData(tokenURL, params, authorization);
|
||||
HttpURLConnection httpURLConnection = performURLEncodedPOSTSendData(tokenURL, params, authorization,
|
||||
headers);
|
||||
|
||||
sb = new StringBuilder();
|
||||
int httpResultCode = httpURLConnection.getResponseCode();
|
||||
|
@ -134,6 +174,12 @@ public class OpenIdConnectRESTHelper {
|
|||
|
||||
protected static HttpURLConnection performURLEncodedPOSTSendData(URL url, Map<String, List<String>> params,
|
||||
String authorization) throws IOException, ProtocolException, UnsupportedEncodingException {
|
||||
return performURLEncodedPOSTSendData(url, params, authorization, null);
|
||||
}
|
||||
|
||||
protected static HttpURLConnection performURLEncodedPOSTSendData(URL url, Map<String, List<String>> params,
|
||||
String authorization, Map<String, String> headers)
|
||||
throws IOException, ProtocolException, UnsupportedEncodingException {
|
||||
|
||||
HttpURLConnection con = (HttpURLConnection) url.openConnection();
|
||||
con.setRequestMethod("POST");
|
||||
|
@ -145,6 +191,12 @@ public class OpenIdConnectRESTHelper {
|
|||
logger.debug("Adding authorization header as: {}", authorization);
|
||||
con.setRequestProperty("Authorization", authorization);
|
||||
}
|
||||
|
||||
if (headers != null) {
|
||||
for (String key : headers.keySet()) {
|
||||
con.setRequestProperty(key, headers.get(key));
|
||||
}
|
||||
}
|
||||
OutputStream os = con.getOutputStream();
|
||||
|
||||
String queryString = mapToQueryString(params);
|
||||
|
@ -154,11 +206,87 @@ public class OpenIdConnectRESTHelper {
|
|||
return con;
|
||||
}
|
||||
|
||||
public static JWTToken queryUMAToken(URL tokenUrl, String authorizationToken, String audience,
|
||||
/**
|
||||
* Queries from the OIDC server an UMA token, by using provided clientId and client secret for the given audience
|
||||
* (context), in URLEncoded form or not, and optionally a list of permissions.
|
||||
*
|
||||
* @param tokenUrl the token endpoint {@link URL} of the OIDC server
|
||||
* @param clientId the client id
|
||||
* @param clientSecret the client secret
|
||||
* @param audience the audience (context) where to request the issuing of the token (URLEncoded or not)
|
||||
* @param permissions a list of permissions, can be <code>null</code>
|
||||
* @return the issued token
|
||||
* @throws OpenIdConnectRESTHelperException if an error occurs (also an unauthorized call), inspect the exception for details
|
||||
*/
|
||||
public static JWTToken queryUMAToken(URL tokenUrl, String clientId, String clientSecret, String audience,
|
||||
List<String> permissions) throws OpenIdConnectRESTHelperException {
|
||||
|
||||
return queryUMAToken(tokenUrl, clientId, clientSecret, audience, permissions, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Queries from the OIDC server an UMA token, by using provided clientId and client secret for the given audience
|
||||
* (context), in URLEncoded form or not, and optionally a list of permissions.
|
||||
*
|
||||
* @param tokenUrl the token endpoint {@link URL} of the OIDC server
|
||||
* @param clientId the client id
|
||||
* @param clientSecret the client secret
|
||||
* @param audience the audience (context) where to request the issuing of the token (URLEncoded or not)
|
||||
* @param permissions a list of permissions, can be <code>null</code>
|
||||
* @param extraHeaders extra HTTP headers to add to the request (e.g. <code>X-D4Science-Context</code> custom header), may be <code>null</code>
|
||||
* @return the issued token
|
||||
* @throws OpenIdConnectRESTHelperException if an error occurs (also an unauthorized call), inspect the exception for details
|
||||
*/
|
||||
public static JWTToken queryUMAToken(URL tokenUrl, String clientId, String clientSecret, String audience,
|
||||
List<String> permissions, Map<String, String> extraHeaders) throws OpenIdConnectRESTHelperException {
|
||||
|
||||
return queryUMAToken(tokenUrl,
|
||||
"Basic " + Base64.getEncoder().encodeToString((clientId + ":" + clientSecret).getBytes()),
|
||||
audience, permissions, extraHeaders);
|
||||
}
|
||||
|
||||
/**
|
||||
* Queries from the OIDC server an UMA token, by using provided access token, for the given audience (context),
|
||||
* in URLEncoded form or not, and optionally a list of permissions.
|
||||
*
|
||||
* @param tokenUrl the token endpoint {@link URL} of the OIDC server
|
||||
* @param authorization the auth token (the access token URLEncoded by the "Bearer " string)
|
||||
* @param audience the audience (context) where to request the issuing of the token (URLEncoded or not)
|
||||
* @param permissions a list of permissions, can be <code>null</code>
|
||||
* @return the issued token
|
||||
* @throws OpenIdConnectRESTHelperException if an error occurs (also an unauthorized call), inspect the exception for details
|
||||
*/
|
||||
public static JWTToken queryUMAToken(URL tokenUrl, String authorization, String audience,
|
||||
List<String> permissions) throws OpenIdConnectRESTHelperException {
|
||||
|
||||
return queryUMAToken(tokenUrl, authorization, audience, permissions, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Queries from the OIDC server an UMA token, by using provided access token, for the given audience (context),
|
||||
* in URLEncoded form or not, and optionally a list of permissions.
|
||||
*
|
||||
* @param tokenUrl the token endpoint {@link URL} of the OIDC server
|
||||
* @param authorization the auth token (the access token URLEncoded by the "Bearer " string)
|
||||
* @param audience the audience (context) where to request the issuing of the token (URLEncoded or not)
|
||||
* @param permissions a list of permissions, can be <code>null</code>
|
||||
* @param extraHeaders extra HTTP headers to add to the request (e.g. <code>X-D4Science-Context</code> custom header), may be <code>null</code>
|
||||
* @return the issued token
|
||||
* @throws OpenIdConnectRESTHelperException if an error occurs (also an unauthorized call), inspect the exception for details
|
||||
*/
|
||||
public static JWTToken queryUMAToken(URL tokenUrl, String authorization, String audience,
|
||||
List<String> permissions, Map<String, String> extraHeaders) throws OpenIdConnectRESTHelperException {
|
||||
|
||||
Map<String, List<String>> params = new HashMap<>();
|
||||
params.put("grant_type", Arrays.asList("urn:ietf:params:oauth:grant-type:uma-ticket"));
|
||||
if (audience.startsWith("/")) {
|
||||
try {
|
||||
logger.trace("Audience was provided in non URL encoded form, encoding it");
|
||||
audience = URLEncoder.encode(audience, "UTF-8");
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
logger.error("Cannot URL encode 'audience'", e);
|
||||
}
|
||||
}
|
||||
try {
|
||||
params.put("audience", Arrays.asList(URLEncoder.encode(audience, "UTF-8")));
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
|
@ -174,18 +302,143 @@ public class OpenIdConnectRESTHelper {
|
|||
}
|
||||
}).collect(Collectors.toList()));
|
||||
}
|
||||
return performQueryTokenWithPOST(tokenUrl, authorizationToken, params);
|
||||
return performQueryTokenWithPOST(tokenUrl, authorization, params, extraHeaders);
|
||||
}
|
||||
|
||||
/**
|
||||
* Queries from the OIDC server an exchanged token by using provided access token, optionally for the given audience (context)
|
||||
* in URLEncoded form or not.
|
||||
*
|
||||
* @param tokenUrl the token endpoint {@link URL} of the OIDC server
|
||||
* @param authorization the auth token (the access token URLEncoded by the "Bearer " string)
|
||||
* @param audience the audience (context) where to request the issuing of the token (URLEncoded or not), may be <code>null</code>
|
||||
* @param clientId the client id
|
||||
* @param clientSecret the client secret
|
||||
* @param extraHeaders extra HTTP headers to add to the request (e.g. <code>X-D4Science-Context</code> custom header), may be <code>null</code>
|
||||
* @return the issued token
|
||||
* @throws OpenIdConnectRESTHelperException if an error occurs (also an unauthorized call), inspect the exception for details
|
||||
*/
|
||||
public static JWTToken queryExchangeToken(URL tokenUrl, String authorization, String audience, String client_id,
|
||||
String client_secret, Map<String, String> extraHeaders) throws OpenIdConnectRESTHelperException {
|
||||
|
||||
return queryExchangeToken(tokenUrl, authorization, audience, client_id, client_secret,
|
||||
"urn:ietf:params:oauth:token-type:access_token", null, extraHeaders);
|
||||
}
|
||||
|
||||
/**
|
||||
* Queries from the OIDC server an exchanged token by using provided access token, optionally for the given audience (context)
|
||||
* in URLEncoded form or not.
|
||||
*
|
||||
* @param tokenUrl the token endpoint {@link URL} of the OIDC server
|
||||
* @param authorization the auth token (the access token URLEncoded by the "Bearer " string)
|
||||
* @param audience the audience (context) where to request the issuing of the token (URLEncoded or not), may be <code>null</code>
|
||||
* @param clientId the client id
|
||||
* @param clientSecret the client secret
|
||||
* @param withRefreshToken request also the refresh token (forced to <code>true</code> for offline requests)
|
||||
* @param offline request a refresh token of offline type (TYP claim)
|
||||
* @param extraHeaders extra HTTP headers to add to the request (e.g. <code>X-D4Science-Context</code> custom header), may be <code>null</code>
|
||||
* @return the issued token
|
||||
* @throws OpenIdConnectRESTHelperException if an error occurs (also an unauthorized call), inspect the exception for details
|
||||
*/
|
||||
public static JWTToken queryExchangeToken(URL tokenUrl, String authorization, String audience, String clientId,
|
||||
String clientSecret, boolean withRefreshToken, boolean offline, Map<String, String> extraHeaders)
|
||||
throws OpenIdConnectRESTHelperException {
|
||||
|
||||
return queryExchangeToken(tokenUrl, authorization, audience, clientId, clientSecret,
|
||||
withRefreshToken || offline ? "urn:ietf:params:oauth:token-type:refresh_token"
|
||||
: "urn:ietf:params:oauth:token-type:access_token",
|
||||
offline ? "offline_access" : null, extraHeaders);
|
||||
}
|
||||
|
||||
/**
|
||||
* Queries from the OIDC server an exchanged token by using provided access token, optionally for the given audience (context)
|
||||
* in URLEncoded form or not.
|
||||
*
|
||||
* @param tokenUrl the token endpoint {@link URL} of the OIDC server
|
||||
* @param authorization the auth token (the access token URLEncoded by the "Bearer " string)
|
||||
* @param audience the audience (context) where to request the issuing of the token (URLEncoded or not), may be <code>null</code>
|
||||
* @param clientId the client id
|
||||
* @param clientSecret the client secret
|
||||
* @param requestedTokenType the requested token type (e.g. <code>urn:ietf:params:oauth:token-type:refresh_token</code> for refresh token)
|
||||
* @param scope the optional scope to request (e.g. <code>offline_access</code> for an offline token)
|
||||
* @param extraHeaders extra HTTP headers to add to the request (e.g. <code>X-D4Science-Context</code> custom header), may be <code>null</code>
|
||||
* @return the issued token
|
||||
* @throws OpenIdConnectRESTHelperException if an error occurs (also an unauthorized call), inspect the exception for details
|
||||
*/
|
||||
public static JWTToken queryExchangeToken(URL tokenUrl, String authorization, String audience, String clientId,
|
||||
String clientSecret, String requestedTokenType, String scope, Map<String, String> extraHeaders)
|
||||
throws OpenIdConnectRESTHelperException {
|
||||
|
||||
logger.info("Querying exchange token for context: " + audience);
|
||||
|
||||
Map<String, List<String>> params = new HashMap<>();
|
||||
|
||||
params.put("subject_token", Arrays.asList(authorization));
|
||||
params.put("client_id", Arrays.asList(clientId));
|
||||
params.put("client_secret", Arrays.asList(clientSecret));
|
||||
params.put("grant_type", Arrays.asList("urn:ietf:params:oauth:grant-type:token-exchange"));
|
||||
params.put("subject_token_type", Arrays.asList("urn:ietf:params:oauth:token-type:access_token"));
|
||||
params.put("requested_token_type", Arrays.asList(requestedTokenType));
|
||||
if (scope != null) {
|
||||
params.put("scope", Arrays.asList(scope));
|
||||
}
|
||||
|
||||
if (audience != null) {
|
||||
if (audience.startsWith("/")) {
|
||||
try {
|
||||
logger.trace("Audience was provided in non URL encoded form, encoding it");
|
||||
audience = URLEncoder.encode(audience, "UTF-8");
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
logger.error("Cannot URL encode 'audience'", e);
|
||||
}
|
||||
}
|
||||
try {
|
||||
params.put("audience", Arrays.asList(URLEncoder.encode(audience, "UTF-8")));
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
logger.error("Cannot URL encode 'audience'", e);
|
||||
}
|
||||
}
|
||||
|
||||
return performQueryTokenWithPOST(tokenUrl, null, params, extraHeaders);
|
||||
}
|
||||
|
||||
/**
|
||||
* Refreshes the token from the OIDC server.
|
||||
*
|
||||
* @param tokenUrl the token endpoint {@link URL} of the OIDC server
|
||||
* @param token the token to be refreshed
|
||||
* @return a new token refreshed from the previous one
|
||||
* @throws OpenIdConnectRESTHelperException if an error occurs (also an unauthorized call), inspect the exception for details
|
||||
*/
|
||||
public static JWTToken refreshToken(URL tokenURL, JWTToken token) throws OpenIdConnectRESTHelperException {
|
||||
return refreshToken(tokenURL, null, null, token);
|
||||
}
|
||||
|
||||
/**
|
||||
* Refreshes the token from the OIDC server for a specific client represented by the client id.
|
||||
*
|
||||
* @param tokenUrl the token endpoint {@link URL} of the OIDC server
|
||||
* @param clientId the client id
|
||||
* @param token the token to be refreshed
|
||||
* @return a new token refreshed from the previous one
|
||||
* @throws OpenIdConnectRESTHelperException if an error occurs (also an unauthorized call), inspect the exception for details
|
||||
*/
|
||||
public static JWTToken refreshToken(URL tokenURL, String clientId, JWTToken token)
|
||||
throws OpenIdConnectRESTHelperException {
|
||||
|
||||
return refreshToken(tokenURL, clientId, null, token);
|
||||
}
|
||||
|
||||
/**
|
||||
* Refreshes the token from the OIDC server for a specific client represented by the client id.
|
||||
*
|
||||
* @param tokenUrl the token endpoint {@link URL} of the OIDC server
|
||||
* @param clientId the client id
|
||||
* @param clientSecret the client secret
|
||||
* @param token the token to be refreshed
|
||||
* @return a new token refreshed from the previous one
|
||||
* @throws OpenIdConnectRESTHelperException if an error occurs (also an unauthorized call), inspect the exception for details
|
||||
*/
|
||||
public static JWTToken refreshToken(URL tokenURL, String clientId, String clientSecret, JWTToken token)
|
||||
throws OpenIdConnectRESTHelperException {
|
||||
|
||||
|
@ -233,10 +486,27 @@ public class OpenIdConnectRESTHelper {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs the logout (SSOut) from all the sessions opened in the OIDC server.
|
||||
*
|
||||
* @param logoutUrl the logut endpoint {@link URL} of the OIDC server
|
||||
* @param token the token used to take info from
|
||||
* @return <code>true</code> if the logout is performed correctly, <code>false</code> otherwise
|
||||
* @throws IOException if an I/O error occurs during the communication with the server
|
||||
*/
|
||||
public static boolean logout(URL logoutUrl, JWTToken token) throws IOException {
|
||||
return logout(logoutUrl, null, token);
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs the logout from the session related to the provided client id in the OIDC server.
|
||||
*
|
||||
* @param logoutUrl the logut endpoint {@link URL} of the OIDC server
|
||||
* @param clientId the client id
|
||||
* @param token the token used to take info from
|
||||
* @return <code>true</code> if the logout is performed correctly, <code>false</code> otherwise
|
||||
* @throws IOException if an I/O error occurs during the communication with the server
|
||||
*/
|
||||
public static boolean logout(URL logoutUrl, String clientId, JWTToken token) throws IOException {
|
||||
Map<String, List<String>> params = new HashMap<>();
|
||||
if (clientId == null) {
|
||||
|
@ -276,9 +546,9 @@ public class OpenIdConnectRESTHelper {
|
|||
}
|
||||
if (conn.getResponseCode() == 200) {
|
||||
String contentType = conn.getContentType();
|
||||
|
||||
|
||||
logger.debug("Getting the stream to the avatar resource with MIME: {}", contentType);
|
||||
|
||||
|
||||
InputStream is = conn.getInputStream();
|
||||
buffer = new ByteArrayOutputStream();
|
||||
int nRead;
|
||||
|
@ -286,7 +556,7 @@ public class OpenIdConnectRESTHelper {
|
|||
while ((nRead = is.read(data, 0, data.length)) != -1) {
|
||||
buffer.write(data, 0, nRead);
|
||||
}
|
||||
|
||||
|
||||
buffer.flush();
|
||||
return buffer.toByteArray();
|
||||
} else {
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
package org.gcube.oidc.rest;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;;
|
||||
|
||||
public class JWTTokenTest {
|
||||
|
||||
private static String tokenString = "{\"access_token\":\"eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJfNEdzbmg3eGZpQ2VNOUFFOTU4S0FqeG5hcllmZlBMbDRrVEpjajN5bThFIn0.eyJleHAiOjE1OTA2NzU4NDEsImlhdCI6MTU5MDY3NTU0MSwiYXV0aF90aW1lIjoxNTkwNjc1NTQwLCJqdGkiOiIxZDc2MjZmMi0xYjcxLTQ2NmEtOWNjNS0wNmYyNWYwODgzZDciLCJpc3MiOiJodHRwczovL251YmlzMi5pbnQuZDRzY2llbmNlLm5ldC9hdXRoL3JlYWxtcy9kNHNjaWVuY2UiLCJhdWQiOlsiJTJGZ2N1YmUiLCIlMkZnY3ViZSUyRmRldk5leHQlMkZOZXh0TmV4dCIsIiUyRmdjdWJlJTJGZGV2c2VjJTJGZGV2VlJFIiwiYWNjb3VudCJdLCJzdWIiOiIzNTQ5MjQ2MS0yZjY4LTQ1YTctOGQyNy1iOGNjNzgyOTJkNGEiLCJ0eXAiOiJCZWFyZXIiLCJhenAiOiJwb3J0YWwiLCJzZXNzaW9uX3N0YXRlIjoiYzA4MzYzOWUtMjNlMy00ZWU2LTg3YjgtODRkMDcxMDBkY2Y2IiwiYWNyIjoiMSIsImFsbG93ZWQtb3JpZ2lucyI6WyIqIl0sInJlYWxtX2FjY2VzcyI6eyJyb2xlcyI6WyJvZmZsaW5lX2FjY2VzcyIsInVtYV9hdXRob3JpemF0aW9uIl19LCJyZXNvdXJjZV9hY2Nlc3MiOnsiJTJGZ2N1YmUiOnsicm9sZXMiOlsiTWVtYmVyIl19LCIlMkZnY3ViZSUyRmRldk5leHQlMkZOZXh0TmV4dCI6eyJyb2xlcyI6WyJNZW1iZXIiXX0sIiUyRmdjdWJlJTJGZGV2c2VjJTJGZGV2VlJFIjp7InJvbGVzIjpbIk1lbWJlciJdfSwiYWNjb3VudCI6eyJyb2xlcyI6WyJtYW5hZ2UtYWNjb3VudCIsIm1hbmFnZS1hY2NvdW50LWxpbmtzIiwidmlldy1wcm9maWxlIl19fSwic2NvcGUiOiJvcGVuaWQgcHJvZmlsZSBlbWFpbCIsImVtYWlsX3ZlcmlmaWVkIjp0cnVlLCJuYW1lIjoiTWF1cm8gTXVnbmFpbmkiLCJncm91cHMiOltdLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJtYXVybyIsImdpdmVuX25hbWUiOiJNYXVybyIsImZhbWlseV9uYW1lIjoiTXVnbmFpbmkiLCJlbWFpbCI6Im1hdXJvLm11Z25haW5pQG51Ymlzd2FyZS5jb20ifQ.dYHmdm23iqO3swhUllyICnzhJlH8h1pTmT8n7S7w-y2b2pNTgK98YiRspSbIC-yPzreAf_GkvsUWyVXeRKnbstiwonIeH5EjVglEF1LgppzTClqaMel1C1AcbPdccno7uIzsE0m03ErKwhzOS8o3SiZEZfELg6bH-UtdOrqnB0Hk8EGVZ7wfso-LwumMw_t600l7E_m4wuPw2UqQNHVtu714043_1cAi4YQXg-KVGzhLcwX-zZj--EJgmm8voTHTENQ-mKYuM-UCK2iZkVYOLcz4I6W97nLbk_Vx59ysTZh4J21cbh7sQRwhp5kE3itYV1ec-xHfjWDjTY-DDZNJ-Q\",\"expires_in\":300,\"refresh_expires_in\":1800,\"refresh_token\":\"eyJhbGciOiJIUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICIzZjUyZDcxMS01Nzk5LTRjYjYtOGExMi02MzEyNjg2NGU0ODAifQ.eyJleHAiOjE1OTA2NzczNDEsImlhdCI6MTU5MDY3NTU0MSwianRpIjoiODdkNDAwN2EtMjQ4MC00MDliLTgyZTAtODFkOTIwZmFiM2E5IiwiaXNzIjoiaHR0cHM6Ly9udWJpczIuaW50LmQ0c2NpZW5jZS5uZXQvYXV0aC9yZWFsbXMvZDRzY2llbmNlIiwiYXVkIjoiaHR0cHM6Ly9udWJpczIuaW50LmQ0c2NpZW5jZS5uZXQvYXV0aC9yZWFsbXMvZDRzY2llbmNlIiwic3ViIjoiMzU0OTI0NjEtMmY2OC00NWE3LThkMjctYjhjYzc4MjkyZDRhIiwidHlwIjoiUmVmcmVzaCIsImF6cCI6InBvcnRhbCIsInNlc3Npb25fc3RhdGUiOiJjMDgzNjM5ZS0yM2UzLTRlZTYtODdiOC04NGQwNzEwMGRjZjYiLCJzY29wZSI6Im9wZW5pZCBwcm9maWxlIGVtYWlsIn0.8Mz_hlZ7635YRW_f1c4fHEzUzutRLxuooA0XAu3g24w\",\"token_type\":\"bearer\",\"id_token\":\"eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJfNEdzbmg3eGZpQ2VNOUFFOTU4S0FqeG5hcllmZlBMbDRrVEpjajN5bThFIn0.eyJleHAiOjE1OTA2NzU4NDEsImlhdCI6MTU5MDY3NTU0MSwiYXV0aF90aW1lIjoxNTkwNjc1NTQwLCJqdGkiOiJkM2M1Mjc5NC00ZTJkLTQ4MWQtODBhNy0wMjdiZWIxNzM0YmIiLCJpc3MiOiJodHRwczovL251YmlzMi5pbnQuZDRzY2llbmNlLm5ldC9hdXRoL3JlYWxtcy9kNHNjaWVuY2UiLCJhdWQiOiJwb3J0YWwiLCJzdWIiOiIzNTQ5MjQ2MS0yZjY4LTQ1YTctOGQyNy1iOGNjNzgyOTJkNGEiLCJ0eXAiOiJJRCIsImF6cCI6InBvcnRhbCIsInNlc3Npb25fc3RhdGUiOiJjMDgzNjM5ZS0yM2UzLTRlZTYtODdiOC04NGQwNzEwMGRjZjYiLCJhY3IiOiIxIiwiZW1haWxfdmVyaWZpZWQiOnRydWUsIm5hbWUiOiJNYXVybyBNdWduYWluaSIsImdyb3VwcyI6W10sInByZWZlcnJlZF91c2VybmFtZSI6Im1hdXJvIiwiZ2l2ZW5fbmFtZSI6Ik1hdXJvIiwiZmFtaWx5X25hbWUiOiJNdWduYWluaSIsImVtYWlsIjoibWF1cm8ubXVnbmFpbmlAbnViaXN3YXJlLmNvbSJ9.X4aY7q3cQ5TFk8phfpKlomE1kttu4hIySEfNjeasQl3lDMiGspnS2LmilSV9agFkDs2z8sdvWLUmmCpevZ_eOdDK0WgsmuYunXXOOCBbNyzzw6AmyDK4DYC2aUUfe8wNndgi7e7bf1TTA4TuFJgC_-xaWfwBrIU8NmDZyozBsms2s4oXxMXUGSb_WmJnXARnHIfWR0F72fngF7jkGs_S6UjyB3g4ZKFk1F3ctrxNT8S49Y82w6n7RqjaLkPBq_WtSXnOQG0Osagv1lkkg2FeXrE6lKZVdAsxbVFVN9epFlvn5aFB7OK1smevjYd_PQxk498rm11H4WLkXBgUqifKWg\",\"not-before-policy\":0,\"session_state\":\"c083639e-23e3-4ee6-87b8-84d07100dcf6\",\"scope\":\"openid profile email\"}";
|
||||
|
@ -7,8 +10,17 @@ public class JWTTokenTest {
|
|||
public JWTTokenTest() {
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
@Test
|
||||
public void testTokenConstruction() {
|
||||
JWTToken token = JWTToken.fromString(tokenString);
|
||||
System.out.println(token.getAud());
|
||||
Assert.assertNotNull(token.getAud());
|
||||
Assert.assertNotNull(token.getAzp());
|
||||
Assert.assertNotNull(token.getAccessTokenString());
|
||||
Assert.assertNotNull(token.getSub());
|
||||
Assert.assertNotNull(token.getExp());
|
||||
Assert.assertTrue(token.isExpired());
|
||||
Assert.assertNotNull(token.getRefreshToken());
|
||||
Assert.assertTrue(token.isRefreshTokenExpired());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -8,34 +8,43 @@ public class RestHelperTest {
|
|||
public RestHelperTest() {
|
||||
}
|
||||
|
||||
/**
|
||||
* To be re-enabled when the token is took programmatically
|
||||
*/
|
||||
// @Test
|
||||
// @Test
|
||||
public void getAvatar() throws MalformedURLException {
|
||||
String accessTokenBearer = "Bearer eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJSSklZNEpoNF9qdDdvNmREY0NlUDFfS1l0akcxVExXVW9oMkQ2Tzk1bFNBIn0.eyJleHAiOjE1OTc0MTc4MzEsImlhdCI6MTU5NzQxNzUzMSwiYXV0aF90aW1lIjoxNTk3NDE3NTI5LCJqdGkiOiI5ZjAwMzM1Yy1jM2NlLTQ3ZTktYTRhZS05MmM4ZDc1NmUyOWMiLCJpc3MiOiJodHRwczovL2FjY291bnRzLmRldi5kNHNjaWVuY2Uub3JnL2F1dGgvcmVhbG1zL2Q0c2NpZW5jZSIsImF1ZCI6ImFjY291bnQiLCJzdWIiOiIzZTcwMzBhNS00M2MzLTRiNjUtYWMwYS0xNTJkYmU3MDI0NTIiLCJ0eXAiOiJCZWFyZXIiLCJhenAiOiJwcmVwcm9kMi5kNHNjaWVuY2Uub3JnIiwic2Vzc2lvbl9zdGF0ZSI6IjAxOWEzMTVjLTY3MTQtNDQyZi1hNDE2LWM4MjAxNWFhYzFmNSIsImFjciI6IjEiLCJyZWFsbV9hY2Nlc3MiOnsicm9sZXMiOlsib2ZmbGluZV9hY2Nlc3MiLCJ1bWFfYXV0aG9yaXphdGlvbiJdfSwicmVzb3VyY2VfYWNjZXNzIjp7ImFjY291bnQiOnsicm9sZXMiOlsibWFuYWdlLWFjY291bnQiLCJtYW5hZ2UtYWNjb3VudC1saW5rcyIsInZpZXctcHJvZmlsZSJdfX0sInNjb3BlIjoib3BlbmlkIGVtYWlsIHByb2ZpbGUiLCJlbWFpbF92ZXJpZmllZCI6dHJ1ZSwibmFtZSI6Ik1hdXJvIE11Z25haW5pIiwicHJlZmVycmVkX3VzZXJuYW1lIjoidGhlbWF4eDc2IiwiZ2l2ZW5fbmFtZSI6Ik1hdXJvIiwiZmFtaWx5X25hbWUiOiJNdWduYWluaSIsInBpY3R1cmUiOiJodHRwczovL2xoMy5nb29nbGV1c2VyY29udGVudC5jb20vYS0vQU9oMTRHaUFxUzZRc00xaDNXV1BqMU15VUdlRFA2VnFaQlhtOTZ4cHhZLXNndyIsImVtYWlsIjoidGhlbWF4eDc2QGdtYWlsLmNvbSJ9.WMddlUQujlpmzW07Lrk50vOyWpiT1Tp_RsBWRbzyrQnu5EQQSCq1uGOuSf7Z3VZFv8fbnzWekMZRNzhngEddzOQHgAlsgRdqNI_-ucjmb_8SfR2I5PkYJLTG0jF-Urqi-GvfJtLr2B8dBDnMDO6FLFsg1e5qb-5HkV60eEtY2Wult1PGxlkD05w-K2w513IOMkVIl25ZxKbP61-Iu1qfV_q3QFvUHl_pdqL7uKC5bkl1lqTVeuCwrXrKubHnKc-UzpHtHp8XY0Iao7LdLtON7SODYhU8EkZ860ZlFTSCszmLUpSH4t_shSk9Fiqd8wBKAet5ngmyAPzKx9TT2FK65g";
|
||||
URL avatarURL = new URL("https://accounts.dev.d4science.org/auth/realms/d4science/avatar-provider/");
|
||||
|
||||
byte[] avatarBytes = OpenIdConnectRESTHelper.getUserAvatar(avatarURL, accessTokenBearer);
|
||||
// assertNotNull(avatarBytes);
|
||||
// assertNotNull(avatarBytes);
|
||||
}
|
||||
|
||||
// @Test
|
||||
// @Test
|
||||
public void getUMATokenWithBasicAuth()
|
||||
throws MalformedURLException, OpenIdConnectRESTHelperException, InterruptedException {
|
||||
URL tokenURL = new URL(
|
||||
"https://accounts.dev.d4science.org/auth/realms/d4science/protocol/openid-connect/token");
|
||||
JWTToken token = OpenIdConnectRESTHelper.queryUMAToken(tokenURL, "storage-manager-trigger",
|
||||
"e2591a99-b694-4dbe-8f7b-9755a3db80af",
|
||||
"/gcube", null);
|
||||
System.out.println(token.getAccessTokenString());
|
||||
}
|
||||
|
||||
// @Test
|
||||
public void getExp() throws MalformedURLException, OpenIdConnectRESTHelperException, InterruptedException {
|
||||
URL tokenURL = new URL("https://accounts.dev.d4science.org/auth/realms/d4science/protocol/openid-connect/token");
|
||||
JWTToken token = OpenIdConnectRESTHelper.queryClientToken("lr62_portal", "28726d01-9f24-4ef4-a057-3d208d96aaa0",
|
||||
URL tokenURL = new URL(
|
||||
"https://accounts.dev.d4science.org/auth/realms/d4science/protocol/openid-connect/token");
|
||||
JWTToken token = OpenIdConnectRESTHelper.queryClientToken("robcomp", "0fec31cb-23c3-44e2-9359-d6db6784b7d3",
|
||||
tokenURL);
|
||||
System.out.println(token.getExpAsDate());
|
||||
System.out.println(token.getAzp());
|
||||
Thread.sleep((token.getExp() * 1000 - System.currentTimeMillis() + 5000));
|
||||
// Thread.sleep((token.getExp() * 1000 - System.currentTimeMillis() + 5000));
|
||||
System.out.println(token.isExpired());
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
RestHelperTest rht = new RestHelperTest();
|
||||
// rht.getAvatar();
|
||||
// rht.getAvatar();
|
||||
try {
|
||||
rht.getExp();
|
||||
rht.getUMATokenWithBasicAuth();
|
||||
} catch (OpenIdConnectRESTHelperException e) {
|
||||
if (e.hasJSONPayload()) {
|
||||
System.out.println("JSON response: " + e.getResponseString());
|
||||
|
|
Loading…
Reference in New Issue