Skip to content

Commit

Permalink
Update ELIXIR Permissions handling (CENTRAL interaction)
Browse files Browse the repository at this point in the history
  • Loading branch information
asenf committed Apr 28, 2018
1 parent 55ad560 commit ee3acc2
Show file tree
Hide file tree
Showing 6 changed files with 204 additions and 22 deletions.
16 changes: 15 additions & 1 deletion src/main/java/zuulserver/config/MyConfiguration.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,27 @@ public class MyConfiguration {
String configToken;
@Value("${spring.oauth2.resource.userInfoUri}")
String elixirUserInfo;
@Value("${spring.oauth2.resource.introspectUri}")
String elixirIntrospect;
@Value("${auth.server.clientId}")
String elixirClient;
@Value("${auth.server.clientsecret}")
String elixirClientSecret;
@Value("${manual.basic.user}")
String basicUser;
@Value("${manual.basic.password}")
String basicPass;

@Bean
public MyServerSettings MyServerSettings() {
return new MyServerSettings(configInternal, configUrl, configToken, elixirUserInfo, basicUser, basicPass);
return new MyServerSettings(configInternal,
configUrl,
configToken,
elixirUserInfo,
elixirIntrospect,
elixirClient,
elixirClientSecret,
basicUser,
basicPass);
}
}
21 changes: 21 additions & 0 deletions src/main/java/zuulserver/config/MyServerSettings.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,19 +23,28 @@ public class MyServerSettings {
private final String url;
private final String token;
private final String elixirUrl;
private final String elixirIntrospect;
private final String elixirClient;
private final String elixirSecret;
private final String basicUser;
private final String basicPass;

public MyServerSettings(String internal,
String url,
String token,
String elixirUrl,
String elixirIntrospect,
String elixirClient,
String elixirSecret,
String basicUser,
String basicPass) {
this.internal = internal;
this.url = url;
this.token = token;
this.elixirUrl = elixirUrl;
this.elixirIntrospect = elixirIntrospect;
this.elixirClient = elixirClient;
this.elixirSecret = elixirSecret;
this.basicUser = basicUser;
this.basicPass = basicPass;
}
Expand All @@ -56,6 +65,18 @@ public String getElixirUrl() {
return this.elixirUrl;
}

public String getElixirIntrospect() {
return this.elixirIntrospect;
}

public String getElixirClient() {
return this.elixirClient;
}

public String getElixirSecret() {
return this.elixirSecret;
}

public String getBasicUser() {
return this.basicUser;
}
Expand Down
48 changes: 48 additions & 0 deletions src/main/java/zuulserver/dto/Permission.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/*
* Copyright 2018 ELIXIR EGA
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package zuulserver.dto;

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

/**
*
* @author asenf
*/
@NoArgsConstructor
@AllArgsConstructor
@Setter
@Getter
public class Permission {
private String affiliation;
private String source_signature;
private String source_timestamp;
private String url_prefix;
private String[] datasets;

public String getSignatureString() {
String result = "";

for (int i=0; i<datasets.length; i++)
result += datasets[i] + ",";
result += source_timestamp + ",";
result += source_signature;

return result;
}
}
34 changes: 34 additions & 0 deletions src/main/java/zuulserver/dto/Permissions.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*
* Copyright 2018 ELIXIR EGA
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package zuulserver.dto;

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

/**
*
* @author asenf
*/
@NoArgsConstructor
@AllArgsConstructor
@Setter
@Getter
public class Permissions {
private Permission[] permissions;

}
100 changes: 84 additions & 16 deletions src/main/java/zuulserver/filters/MyZuulFilter.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Random;
import org.springframework.security.oauth2.common.exceptions.InvalidTokenException;
import zuulserver.dto.Permission;
import zuulserver.dto.Permissions;

/**
* @author asenf
Expand Down Expand Up @@ -83,23 +86,42 @@ public Object run() {
// Only perform this for ELIXIR tokens - pass EGA tokens straight to the API
boolean isElixirToken = determineTokenOrigin(access_token);
if (isElixirToken) {
String userElixirSub = getElixirSub(access_token);
String userElixirSub = null;
try {
userElixirSub = getElixirSub(access_token);
} catch (InvalidTokenException ex) {
ctx.setResponseBody(ex.toString());
System.out.println("X: " + ex.toString());
return null;
}

System.out.println("Elixir Sub: " + userElixirSub);
/*
* Old Code
*/
// Contact EGA for Datasets & Elixir User
List<String> permissions = getElixirPermissions(userElixirSub);
String permissions_ = "";
for (int i = 0; i < permissions.size(); i++) { // Neet to test: Is this always 1 String now??
permissions_ += permissions.get(i);
if (i < permissions.size() - 1)
permissions_ += ","; // New - is a Base64 encoded, signed String from EGA
}
ctx.addZuulRequestHeader("X-Permissions", permissions_);
// List<String> permissions = getElixirPermissions(userElixirSub);
// String permissions_ = "";
// for (int i = 0; i < permissions.size(); i++) { // Neet to test: Is this always 1 String now??
// permissions_ += permissions.get(i);
// if (i < permissions.size() - 1)
// permissions_ += ","; // New - is a Base64 encoded, signed String from EGA
// }
// ctx.addZuulRequestHeader("X-Permissions", permissions_);

/*
* New Code
*/
Permission p = getElixirPermissionsNew(userElixirSub);
ctx.addZuulRequestHeader("X-Permissions", p.getSignatureString());
System.out.println("Signature String: " + p.getSignatureString());

} else {
}

return null;
}

/*
private String getElixirUserEmail(String accessToken) {
String url = serverSettings.getElixirUrl();
UserInfoTokenServices tokenService = new UserInfoTokenServices(url, "");
Expand All @@ -119,10 +141,10 @@ private String getElixirUserId(String accessToken) {
return id;
}

*/
private String getElixirSub(String accessToken) {
String url = serverSettings.getElixirUrl();
UserInfoTokenServices tokenService = new UserInfoTokenServices(url, "");
UserInfoTokenServices tokenService = new UserInfoTokenServices(url, serverSettings.getElixirClient());
OAuth2Authentication auth = tokenService.loadAuthentication(accessToken);
LinkedHashMap<String, String> details = (LinkedHashMap<String, String>) auth.getUserAuthentication().getDetails();
String sub = details.get("sub");
Expand Down Expand Up @@ -173,21 +195,67 @@ private List<String> getElixirPermissions(String user_id) {
return result;
}

private Permission getElixirPermissionsNew(String user_id) {
String baseApi = serverSettings.isInternal() ? getInternalUrl() : serverSettings.getElixirUrl(); // MUST BE CHANGED TO "https://ega.ebi.ac.uk/elixir/central/.." IN LOCAL (NON-EBI) INSTALLATIONS
String accessToken = serverSettings.getToken();

OkHttpClient.Builder builder = new OkHttpClient.Builder();
OkHttpClient okHttpClient = builder
.addNetworkInterceptor(new ResponseCacheInterceptor()) // Enable response caching
.cache(new Cache(new File("apiResponses"), 5 * 1024 * 1024)) // Set the cache location and size (5 MB)
.build();

// List all Datasets
Request datasetRequest = new Request.Builder()
.url(baseApi + "/app/user/" + user_id + "/")
.addHeader("Authorization", "Basic " + getBasicEncoded(serverSettings.getBasicUser(), serverSettings.getBasicPass()))
.build();
Moshi MOSHI = new Moshi.Builder().build();
JsonAdapter<Permissions> STRING_JSON_ADAPTER = MOSHI.adapter(Permissions.class);

Permissions result = null;
try {
// Execute the request and retrieve the response.
Response response = null;
int tryCount = 3;
while (tryCount-- > 0 && (response == null || !response.isSuccessful())) {
try {
System.out.println(" --- " + datasetRequest.toString());
response = okHttpClient.newCall(datasetRequest).execute();
} catch (Exception ex) {
System.out.println("ERROR " + ex.toString());
}
}
if (response.code() != 200) {
throw new IOException(response.toString());
}

ResponseBody body = response.body();
result = STRING_JSON_ADAPTER.fromJson(body.source());
body.close();

} catch (IOException ex) {
System.out.println("Error getting Datasets: " + ex.toString());
}

return result.getPermissions()[0];
}

// Returns 'true' if token originated from ELIXIR
private boolean determineTokenOrigin(String access_token) {
if (access_token == null || access_token.length() == 0)
return false;

Jwt decoded_token = JwtHelper.decode(access_token);
String claims = decoded_token.getClaims();
return (claims.contains("perun.elixir-czech.cz"));
return (claims.contains(".elixir-czech."));
}

// Returns URL for CENTRAL (Internal Only)
private String getInternalUrl() {
String[] baseApi = {"http://pg-ega-pro-06:9153",
"http://pg-ega-pro-07:9153",
"http://pg-ega-pro-08:9153"};
String[] baseApi = {"http://pg-ega-pro-06.ebi.ac.uk:9153",
"http://pg-ega-pro-07.ebi.ac.uk:9153",
"http://pg-ega-pro-08.ebi.ac.uk:9153"};

Random r = new Random();
int index = r.nextInt(3);
Expand Down
7 changes: 2 additions & 5 deletions zuulserver.properties
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ server.ssl.key-store-password: ....
security.basic.enabled = false

#ELIXIR OpenID Connect AAI IdP
spring.oauth2.resource.userInfoUri = https://perun.elixir-czech.cz/oauth/rpc/json/oidcManager/userinfo
spring.oauth2.resource.userInfoUri = https://login.elixir-czech.org/oidc/userinfo

auth.server.url: https://perun.elixir-czech.cz/oidc/token
auth.server.url: https://login.elixir-czech.ord/oidc/token
auth.server.clientId: client
auth.server.clientsecret: secret

Expand All @@ -30,9 +30,6 @@ info.component: Zuul Server

zuul.prefix: /elixir
zuul.ignoredServices: '*'
zuul.routes.access.path: /access/**
zuul.routes.access.serviceId: ACCESS
zuul.routes.access.sensitive-headers=Cookie,Set-Cookie
zuul.routes.dsedge.path: /data/**
zuul.routes.dsedge.serviceId: DSEDGE
zuul.routes.dsedge.sensitive-headers=Cookie,Set-Cookie
Expand Down

0 comments on commit ee3acc2

Please sign in to comment.