completed implementation for Feature #5143: smartgears service authentication portlet with client id and secret checking
git-svn-id: http://svn.research-infrastructures.eu/public/d4science/gcube/trunk/portlets/user/my-vres@141567 82a268e6-3cf1-43bd-a215-b396298e98cf
This commit is contained in:
parent
dd69469e4e
commit
5fec8824b6
|
@ -1,12 +1,12 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="src" output="target/my-vres-2.2.0-SNAPSHOT/WEB-INF/classes" path="src/main/java">
|
||||
<classpathentry kind="src" output="target/my-vres-2.3.0-SNAPSHOT/WEB-INF/classes" path="src/main/java">
|
||||
<attributes>
|
||||
<attribute name="optional" value="true"/>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry excluding="**" kind="src" output="target/my-vres-2.2.0-SNAPSHOT/WEB-INF/classes" path="src/main/resources">
|
||||
<classpathentry excluding="**" kind="src" output="target/my-vres-2.3.0-SNAPSHOT/WEB-INF/classes" path="src/main/resources">
|
||||
<attributes>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
|
@ -38,5 +38,5 @@
|
|||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="output" path="target/my-vres-2.2.0-SNAPSHOT/WEB-INF/classes"/>
|
||||
<classpathentry kind="output" path="target/my-vres-2.3.0-SNAPSHOT/WEB-INF/classes"/>
|
||||
</classpath>
|
||||
|
|
|
@ -1,23 +1,35 @@
|
|||
<ReleaseNotes>
|
||||
<Changeset component="org.gcube.portlet.user.my-vres.2-2-0" date="2016-11-17">
|
||||
<Changeset component="org.gcube.portlet.user.my-vres.2-3-0"
|
||||
date="2017-01-07">
|
||||
<Change>Fix for bug not allowing to click on vre missing logos</Change>
|
||||
<Change>Adapted so support VRE selection upon authorisation requests</Change>
|
||||
</Changeset>
|
||||
<Changeset component="org.gcube.portlet.user.my-vres.2-2-0"
|
||||
date="2016-11-17">
|
||||
<Change>Removed ASL Session</Change>
|
||||
<Change>Implemented Feature #4877 remove VRE association to single Category constraint</Change>
|
||||
<Change>Implemented Feature #4877 remove VRE association to single
|
||||
Category constraint</Change>
|
||||
</Changeset>
|
||||
<Changeset component="org.gcube.portlet.user.my-vres.2-1-0" date="2016-09-12">
|
||||
<Change>Shows only the virtual groups available in the Site it is deployed on</Change>
|
||||
<Change>VRE was not updated in the portlet due to liferay versioning of Document Library</Change>
|
||||
<Changeset component="org.gcube.portlet.user.my-vres.2-1-0"
|
||||
date="2016-09-12">
|
||||
<Change>Shows only the virtual groups available in the Site it is
|
||||
deployed on</Change>
|
||||
<Change>VRE was not updated in the portlet due to liferay versioning
|
||||
of Document Library</Change>
|
||||
</Changeset>
|
||||
<Changeset component="org.gcube.portlet.user.my-vres.2-0-1" date="2016-04-02">
|
||||
<Changeset component="org.gcube.portlet.user.my-vres.2-0-1"
|
||||
date="2016-04-02">
|
||||
<Change>Ported to Liferay 6.2</Change>
|
||||
</Changeset>
|
||||
<Changeset component="org.gcube.portlet.user.my-vres.1-6-0"
|
||||
<Changeset component="org.gcube.portlet.user.my-vres.1-6-0"
|
||||
date="2015-11-22">
|
||||
<Change>Bug #1855, does not show join welcome message to new users anymore</Change>
|
||||
<Change>Bug #1855, does not show join welcome message to new users
|
||||
anymore</Change>
|
||||
<Change>Feature #861, categorized VREs by virtualGroups</Change>
|
||||
</Changeset>
|
||||
<Changeset component="org.gcube.portlet.user.my-vres.1-5-0"
|
||||
date="2015-10-22">
|
||||
|
||||
|
||||
</Changeset>
|
||||
<Changeset component="org.gcube.portlet.user.my-vres.1-4-0"
|
||||
date="2014-10-27">
|
||||
|
|
17
pom.xml
17
pom.xml
|
@ -13,7 +13,7 @@
|
|||
<groupId>org.gcube.portlets.user</groupId>
|
||||
<artifactId>my-vres</artifactId>
|
||||
<packaging>war</packaging>
|
||||
<version>2.2.0-SNAPSHOT</version>
|
||||
<version>2.3.0-SNAPSHOT</version>
|
||||
<name>My VREs Portlet</name>
|
||||
<description>
|
||||
gCube My VREs Portlet shows only the VO and VREs a user is member of, divided by category.
|
||||
|
@ -65,6 +65,21 @@
|
|||
<groupId>org.gcube.dvos</groupId>
|
||||
<artifactId>usermanagement-core</artifactId>
|
||||
</dependency>
|
||||
<!-- FWS DEPS -->
|
||||
<dependency>
|
||||
<groupId>org.gcube.resources.discovery</groupId>
|
||||
<artifactId>ic-client</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.gcube.core</groupId>
|
||||
<artifactId>common-scope-maps</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.gcube.core</groupId>
|
||||
<artifactId>common-encryption</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.liferay.portal</groupId>
|
||||
<artifactId>portal-service</artifactId>
|
||||
|
|
|
@ -4,13 +4,20 @@ public class GetParameters {
|
|||
String redirectURI;
|
||||
String state;
|
||||
String context;
|
||||
public GetParameters(String redirectURI, String state, String context) {
|
||||
String clientId;
|
||||
String clientSecret;
|
||||
|
||||
|
||||
|
||||
public GetParameters(String redirectURI, String state, String context, String clientId, String clientSecret) {
|
||||
super();
|
||||
this.redirectURI = redirectURI;
|
||||
this.state = state;
|
||||
this.context = context;
|
||||
this.clientId = clientId;
|
||||
this.clientSecret = clientSecret;
|
||||
}
|
||||
|
||||
|
||||
public String getRedirectURI() {
|
||||
return redirectURI;
|
||||
}
|
||||
|
@ -23,10 +30,20 @@ public class GetParameters {
|
|||
return context;
|
||||
}
|
||||
|
||||
public String getClientId() {
|
||||
return clientId;
|
||||
}
|
||||
|
||||
public String getClientSecret() {
|
||||
return clientSecret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "GetParameters [redirectURI=" + redirectURI + ", state=" + state + ", context=" + context + "]";
|
||||
return "GetParameters [redirectURI=" + redirectURI + ", state=" + state + ", context=" + context + ", clientId="
|
||||
+ clientId + ", clientSecret=" + clientSecret + "]";
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -19,6 +19,8 @@ public class MyVREs implements EntryPoint {
|
|||
public static final String GET_REDIRECTURI_PARAMETER = "redirect_uri";
|
||||
public static final String GET_STATE_PARAMETER = "state";
|
||||
public static final String GET_CONTEXT_PARAMETER = "context";
|
||||
public static final String GET_CLIENT_ID_PARAMETER = "client_id";
|
||||
public static final String GET_CLIENT_SECRET_PARAMETER = "client_secret";
|
||||
|
||||
public static final String GET_AUTH_TOKEN_PARAMETER = "gcube-token";
|
||||
|
||||
|
@ -47,20 +49,23 @@ public class MyVREs implements EntryPoint {
|
|||
RootPanel.get("myVREsDIV").add(new VresPanel(params));
|
||||
}
|
||||
else {
|
||||
myVREsService.getUserToken(params.context, params.state, new AsyncCallback<AuthorizationBean>() {
|
||||
myVREsService.getUserToken(params.context, params.state, params.clientId, params.clientSecret, new AsyncCallback<AuthorizationBean>() {
|
||||
@Override
|
||||
public void onSuccess(AuthorizationBean result) {
|
||||
if (result.isSuccess()) {
|
||||
Location.assign(params.redirectURI+"?"+GET_AUTH_TOKEN_PARAMETER+"="+result.getToken()+"&"+GET_STATE_PARAMETER+"="+result.getState());
|
||||
} else {
|
||||
RootPanel.get("myVREsDIV").add(new HTML("There were issues in managing this request: " + result.getErrorDescription()));
|
||||
HTML message = new HTML("There were issues in managing this request: " + result.getErrorDescription());
|
||||
message.setStyleName("portlet-msg-error");
|
||||
RootPanel.get("myVREsDIV").insert(message, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(Throwable caught) {
|
||||
RootPanel.get("myVREsDIV").add(new HTML("An error occurred in the server: " + caught.getMessage()));
|
||||
|
||||
HTML message = new HTML("An error occurred in the server: " + caught.getMessage());
|
||||
message.setStyleName("portlet-msg-error");
|
||||
RootPanel.get("myVREsDIV").insert(message, 0);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -74,6 +79,9 @@ public class MyVREs implements EntryPoint {
|
|||
String redirectURI = Window.Location.getParameter(GET_REDIRECTURI_PARAMETER);
|
||||
String state = Window.Location.getParameter(GET_STATE_PARAMETER);
|
||||
String context = Window.Location.getParameter(GET_CONTEXT_PARAMETER);
|
||||
return new GetParameters(redirectURI, state, context);
|
||||
String clientId = Window.Location.getParameter(GET_CLIENT_ID_PARAMETER);
|
||||
String clientSecret = Window.Location.getParameter(GET_CLIENT_SECRET_PARAMETER);
|
||||
|
||||
return new GetParameters(redirectURI, state, context, clientId, clientSecret);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,5 +18,5 @@ public interface MyVREsService extends RemoteService {
|
|||
|
||||
String getSiteLandingPagePath();
|
||||
|
||||
AuthorizationBean getUserToken(String context, String state);
|
||||
AuthorizationBean getUserToken(String context, String state, String clientId, String clientSecret);
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@ public interface MyVREsServiceAsync {
|
|||
|
||||
void getSiteLandingPagePath(AsyncCallback<String> callback);
|
||||
|
||||
void getUserToken(String context, String state, AsyncCallback<AuthorizationBean> callback);
|
||||
void getUserToken(String context, String state, String clientId, String clientSecret,
|
||||
AsyncCallback<AuthorizationBean> callback);
|
||||
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@ import com.google.gwt.event.dom.client.ClickEvent;
|
|||
import com.google.gwt.event.dom.client.ClickHandler;
|
||||
import com.google.gwt.event.dom.client.MouseOverEvent;
|
||||
import com.google.gwt.event.dom.client.MouseOverHandler;
|
||||
import com.google.gwt.event.shared.HandlerRegistration;
|
||||
import com.google.gwt.user.client.Timer;
|
||||
import com.google.gwt.user.client.Window.Location;
|
||||
import com.google.gwt.user.client.rpc.AsyncCallback;
|
||||
|
@ -33,8 +34,8 @@ public class ClickableVRE extends HTML {
|
|||
|
||||
public static final String LOADING_IMAGE = GWT.getModuleBaseURL() + "../images/loading.gif";
|
||||
public static final String VLAB_IMAGE = GWT.getModuleBaseURL() + "../images/vlab.png";
|
||||
private String html = "";
|
||||
|
||||
private String html = "";
|
||||
private HandlerRegistration handleReg;
|
||||
|
||||
public ClickableVRE(final MyVREsServiceAsync myVREsService, final VRE vre, final boolean showImage, final GetParameters params) {
|
||||
super.setPixelSize(WIDTH, HEIGHT);
|
||||
|
@ -61,13 +62,15 @@ public class ClickableVRE extends HTML {
|
|||
if (params != null) {
|
||||
addClickHandler(new ClickHandler() {
|
||||
public void onClick(ClickEvent event) {
|
||||
myVREsService.getUserToken(vre.getContext(), params.getState(), new AsyncCallback<AuthorizationBean>() {
|
||||
myVREsService.getUserToken(vre.getContext(), params.getState(), params.getClientId(), params.getClientSecret(), new AsyncCallback<AuthorizationBean>() {
|
||||
@Override
|
||||
public void onSuccess(AuthorizationBean result) {
|
||||
if (result.isSuccess()) {
|
||||
Location.assign(params.getRedirectURI()+"?"+MyVREs.GET_AUTH_TOKEN_PARAMETER+"="+result.getToken()+"&"+MyVREs.GET_STATE_PARAMETER+"="+result.getState());
|
||||
} else {
|
||||
RootPanel.get("myVREsDIV").add(new HTML("There were issues in managing this request: " + result.getErrorDescription()));
|
||||
HTML message = new HTML("There were issues in managing this request: " + result.getErrorDescription());
|
||||
message.setStyleName("portlet-msg-error");
|
||||
RootPanel.get("myVREsDIV").insert(message, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -99,7 +102,7 @@ public class ClickableVRE extends HTML {
|
|||
});
|
||||
}
|
||||
|
||||
addMouseOverHandler(new MouseOverHandler() {
|
||||
handleReg = addMouseOverHandler(new MouseOverHandler() {
|
||||
@Override
|
||||
public void onMouseOver(MouseOverEvent event) {
|
||||
if (!showImage) {
|
||||
|
@ -112,10 +115,14 @@ public class ClickableVRE extends HTML {
|
|||
"<span style=\"vertical-align:middle; display: table-cell;\"><img style=\"width: " + imageWidth + "px;\" src=\"" +imageUrl + "\" /></span>" +
|
||||
"</div>";
|
||||
setHTML(html);
|
||||
GWT.log("Show");
|
||||
handleReg.removeHandler();
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
package org.gcube.portlet.user.my_vres.server;
|
||||
|
||||
import static org.gcube.resources.discovery.icclient.ICFactory.clientFor;
|
||||
import static org.gcube.resources.discovery.icclient.ICFactory.queryFor;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashMap;
|
||||
|
@ -7,12 +10,19 @@ import java.util.List;
|
|||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import org.gcube.common.encryption.StringEncrypter;
|
||||
import org.gcube.common.portal.GCubePortalConstants;
|
||||
import org.gcube.common.portal.PortalContext;
|
||||
import org.gcube.common.resources.gcore.ServiceEndpoint;
|
||||
import org.gcube.common.resources.gcore.ServiceEndpoint.AccessPoint;
|
||||
import org.gcube.common.resources.gcore.utils.Group;
|
||||
import org.gcube.common.scope.api.ScopeProvider;
|
||||
import org.gcube.portlet.user.my_vres.client.MyVREsService;
|
||||
import org.gcube.portlet.user.my_vres.shared.AuthorizationBean;
|
||||
import org.gcube.portlet.user.my_vres.shared.UserBelonging;
|
||||
import org.gcube.portlet.user.my_vres.shared.VRE;
|
||||
import org.gcube.resources.discovery.client.api.DiscoveryClient;
|
||||
import org.gcube.resources.discovery.client.queries.api.SimpleQuery;
|
||||
import org.gcube.vomanagement.usermanagement.GroupManager;
|
||||
import org.gcube.vomanagement.usermanagement.exception.GroupRetrievalFault;
|
||||
import org.gcube.vomanagement.usermanagement.exception.UserManagementSystemException;
|
||||
|
@ -44,7 +54,7 @@ public class MyVREsServiceImpl extends RemoteServiceServlet implements MyVREsSer
|
|||
|
||||
public static final String ADD_MORE_CATEGORY = "Add More";
|
||||
public static final String ADD_MORE_IMAGE_PATH= "images/More.png";
|
||||
|
||||
private static final String SERVICE_ENDPOINT_CATEGORY = "Portal";
|
||||
|
||||
@Override
|
||||
public String getSiteLandingPagePath() {
|
||||
|
@ -247,7 +257,20 @@ public class MyVREsServiceImpl extends RemoteServiceServlet implements MyVREsSer
|
|||
}
|
||||
|
||||
@Override
|
||||
public AuthorizationBean getUserToken( String context, String state) {
|
||||
public AuthorizationBean getUserToken(String context, String state, String clientId, String clientSecret) {
|
||||
if (clientId == null || clientId.compareTo("")== 0) {
|
||||
return new AuthorizationBean(null, null, false, "client_id is null, you MUST register your application to allow users connect with their D4Science Credentials");
|
||||
}
|
||||
if (clientSecret == null || clientSecret.compareTo("")== 0) {
|
||||
return new AuthorizationBean(null, null, false, "client_secret is null, you MUST pass the clientSecret related to your client_id registered application to allow users connect with their D4Science Credentials");
|
||||
}
|
||||
String registeredClientSecret = getClientSecretFromIs(clientId);
|
||||
if (registeredClientSecret == null) {
|
||||
return new AuthorizationBean(null, null, false, "Your client_id ("+ clientId +") is not registered in the infrastructure, you MUST register your client_id to allow users connect with their D4Science Credentials");
|
||||
}
|
||||
if (registeredClientSecret.compareTo(clientSecret)!=0) {
|
||||
return new AuthorizationBean(null, null, false, "The client_secret for clientId ("+ clientId +"), does not match");
|
||||
}
|
||||
if (state == null || state.compareTo("")== 0) {
|
||||
return new AuthorizationBean(null, null, false, "State is null, please use a unique string value of your choice that is hard to guess (e.g. state=7d12bf13-111c-4f46-ab06-9e9e08ad377b). Used to prevent CSRF attacks");
|
||||
}
|
||||
|
@ -288,5 +311,65 @@ public class MyVREsServiceImpl extends RemoteServiceServlet implements MyVREsSer
|
|||
return new AuthorizationBean(token, state, true, null);
|
||||
}
|
||||
|
||||
//TODO: check the query, it doesn work
|
||||
private List<ServiceEndpoint> getPortalConfigurationFromIS(String infrastructureName, String gatewayName) throws Exception {
|
||||
String scope = "/" + infrastructureName;
|
||||
String currScope = ScopeProvider.instance.get();
|
||||
ScopeProvider.instance.set(scope);
|
||||
SimpleQuery query = queryFor(ServiceEndpoint.class);
|
||||
query.addCondition("$resource/Profile/Category/text() eq '"+ SERVICE_ENDPOINT_CATEGORY +"'");
|
||||
query.addCondition("$resource/Profile/Name/text() eq '"+ gatewayName +"'");
|
||||
DiscoveryClient<ServiceEndpoint> client = clientFor(ServiceEndpoint.class);
|
||||
List<ServiceEndpoint> toReturn = client.submit(query);
|
||||
ScopeProvider.instance.set(currScope);
|
||||
return toReturn;
|
||||
}
|
||||
/**
|
||||
* look for the clientId AccessEndpoint passes as parameter
|
||||
* @param gatewayName
|
||||
* @param clientId
|
||||
* @return the client secret related to the id, or null if non existent
|
||||
*/
|
||||
private String getClientSecretFromIs(String clientId) {
|
||||
PortalContext pContext = PortalContext.getConfiguration();
|
||||
String gatewayName = pContext.getGatewayName(getThreadLocalRequest());
|
||||
String scope = "/"+pContext.getInfrastructureName();
|
||||
try {
|
||||
List<ServiceEndpoint> list = getPortalConfigurationFromIS(pContext.getInfrastructureName(), gatewayName);
|
||||
if (list.size() > 1) {
|
||||
_log.error("Too many Service Endpoints having name " + gatewayName +" in this scope having Category " + SERVICE_ENDPOINT_CATEGORY);
|
||||
}
|
||||
else if (list.size() == 0){
|
||||
_log.warn("There is no Service Endpoint having name " + gatewayName +" and Category " + SERVICE_ENDPOINT_CATEGORY + " in this scope: " + scope);
|
||||
}
|
||||
else {
|
||||
for (ServiceEndpoint res : list) {
|
||||
Group<AccessPoint> apGroup = res.profile().accessPoints();
|
||||
AccessPoint[] accessPoints = (AccessPoint[]) apGroup.toArray(new AccessPoint[apGroup.size()]);
|
||||
for (int i = 0; i < accessPoints.length; i++) {
|
||||
if (accessPoints[i].name().compareTo(clientId) == 0) {
|
||||
_log.info("Found credentials for " + clientId);
|
||||
AccessPoint found = accessPoints[i];
|
||||
//String thumbnailURL = found.address();
|
||||
String encrPassword = found.password();
|
||||
String clientSecret = "";
|
||||
try {
|
||||
clientSecret = StringEncrypter.getEncrypter().decrypt( encrPassword);
|
||||
_log.debug("clientSecret for " + clientId + " found");
|
||||
return clientSecret;
|
||||
} catch (Exception e) {
|
||||
_log.error("Something went wrong while decrypting password for " + clientId);
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue