Added filter to extract formparams before the access-token method is called. Unfortunately it is called after the smartgears' one, and the priority property doesn't work. Dependencies fixed in pom.xml
git-svn-id: http://svn.research-infrastructures.eu/public/d4science/gcube/trunk/portal/oauth@141889 82a268e6-3cf1-43bd-a215-b396298e98cf
This commit is contained in:
parent
5623845caa
commit
807cea8e60
|
@ -5,6 +5,6 @@
|
|||
<wb-resource deploy-path="/WEB-INF/classes" source-path="/src/main/java"/>
|
||||
<wb-resource deploy-path="/WEB-INF/classes" source-path="/src/main/resources"/>
|
||||
<property name="java-output-path" value="/oauth/target/classes"/>
|
||||
<property name="context-root" value="oauth_gCube_App"/>
|
||||
<property name="context-root" value="gcube-oauth"/>
|
||||
</wb-module>
|
||||
</project-modules>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<faceted-project>
|
||||
<fixed facet="wst.jsdt.web"/>
|
||||
<installed facet="jst.web" version="2.3"/>
|
||||
<installed facet="jst.web" version="3.0"/>
|
||||
<installed facet="wst.jsdt.web" version="1.0"/>
|
||||
<installed facet="java" version="1.7"/>
|
||||
<installed facet="jst.jaxrs" version="2.0"/>
|
||||
|
|
51
pom.xml
51
pom.xml
|
@ -13,9 +13,9 @@
|
|||
<artifactId>oauth</artifactId>
|
||||
<packaging>war</packaging>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
<name>oauth gCube App</name>
|
||||
|
||||
<properties>
|
||||
<name>gcube-oauth</name>
|
||||
|
||||
<properties>
|
||||
<java-version>1.7</java-version>
|
||||
<version.jersey>2.22.1</version.jersey>
|
||||
<distroDirectory>${project.basedir}/distro</distroDirectory>
|
||||
|
@ -44,23 +44,6 @@
|
|||
</dependencyManagement>
|
||||
|
||||
<dependencies>
|
||||
<!-- SmartGears -->
|
||||
<dependency>
|
||||
<groupId>org.gcube.core</groupId>
|
||||
<artifactId>common-smartgears</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.gcube.core</groupId>
|
||||
<artifactId>common-smartgears-app</artifactId>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.servlet</groupId>
|
||||
<artifactId>servlet-api</artifactId>
|
||||
<version>3.0-alpha-1</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.glassfish.jersey.containers</groupId>
|
||||
<!-- if your container implements Servlet API older than 3.0, use "jersey-container-servlet-core" -->
|
||||
|
@ -87,10 +70,27 @@
|
|||
<artifactId>jersey-media-sse</artifactId>
|
||||
<version>${version.jersey}</version>
|
||||
</dependency>
|
||||
<!-- <dependency> -->
|
||||
<!-- <groupId>org.glassfish.jersey.ext</groupId> -->
|
||||
<!-- <artifactId>jersey-bean-validation</artifactId> -->
|
||||
<!-- <version>${version.jersey}</version> -->
|
||||
<!-- </dependency> -->
|
||||
<dependency>
|
||||
<groupId>org.glassfish.jersey.ext</groupId>
|
||||
<artifactId>jersey-bean-validation</artifactId>
|
||||
<version>${version.jersey}</version>
|
||||
<groupId>javax.servlet</groupId>
|
||||
<artifactId>servlet-api</artifactId>
|
||||
<version>3.0-alpha-1</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<!-- SmartGears -->
|
||||
<dependency>
|
||||
<groupId>org.gcube.core</groupId>
|
||||
<artifactId>common-smartgears</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.gcube.core</groupId>
|
||||
<artifactId>common-smartgears-app</artifactId>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
|
@ -98,6 +98,11 @@
|
|||
<version>3.8.1</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-io</artifactId>
|
||||
<version>1.3.2</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<build>
|
||||
<finalName>${name}</finalName>
|
||||
|
|
|
@ -8,6 +8,7 @@ import java.util.concurrent.ConcurrentHashMap;
|
|||
import javax.inject.Singleton;
|
||||
import javax.ws.rs.Consumes;
|
||||
import javax.ws.rs.FormParam;
|
||||
import javax.ws.rs.GET;
|
||||
import javax.ws.rs.POST;
|
||||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.Produces;
|
||||
|
@ -28,22 +29,27 @@ import org.gcube.portal.oauth.output.AccessTokenErrorResponse;
|
|||
import org.slf4j.LoggerFactory;
|
||||
|
||||
|
||||
@Path("v2/")
|
||||
@Path("/v2")
|
||||
@Singleton
|
||||
public class OauthService {
|
||||
|
||||
public static final String OAUTH_TOKEN_GET_METHOD_NAME_REQUEST = "access-token";
|
||||
private static final String GRANT_TYPE_VALUE = "authorization_code";
|
||||
|
||||
private static final org.slf4j.Logger logger = LoggerFactory.getLogger(OauthService.class);
|
||||
|
||||
/**
|
||||
* This map contains couples <code, {qualifier-token, insert time}>
|
||||
*/
|
||||
private Map<String, CacheBean> entries = new ConcurrentHashMap<String, CacheBean>();
|
||||
private Map<String, CacheBean> entries;
|
||||
|
||||
/**
|
||||
* Since this is a singleton sub-service, there will be just one call to this constructor and one running thread
|
||||
* to clean up expired codes.
|
||||
*/
|
||||
public OauthService() {
|
||||
logger.info("Singleton gcube-oauth service built.");
|
||||
entries = new ConcurrentHashMap<String, CacheBean>();
|
||||
CacheCleaner cleaner = new CacheCleaner(entries);
|
||||
cleaner.start();
|
||||
}
|
||||
|
@ -67,6 +73,13 @@ public class OauthService {
|
|||
private boolean checkIsapplicationTokenType(ClientType clientType){
|
||||
return clientType.equals(ClientType.EXTERNALSERVICE);
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("check")
|
||||
@Produces(MediaType.TEXT_PLAIN)
|
||||
public Response checkService(){
|
||||
return Response.status(Status.OK).entity("Ready!").build();
|
||||
}
|
||||
|
||||
|
||||
@POST
|
||||
|
@ -101,7 +114,7 @@ public class OauthService {
|
|||
@POST
|
||||
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Path("access-token")
|
||||
@Path(OAUTH_TOKEN_GET_METHOD_NAME_REQUEST)
|
||||
/**
|
||||
* The method should accept input values or in a json object or as FormParam. The request is validated here and not from SmartGears.
|
||||
* @param requestInJson
|
||||
|
@ -122,7 +135,8 @@ public class OauthService {
|
|||
|
||||
Status status = Status.BAD_REQUEST;
|
||||
logger.info("Request to exchange code for token");
|
||||
logger.info("Params are + client_id = " + clientId + ", client_secret = " + clientSecret.substring(0, 10) + ", redirect_uri = " +redirectUri + ", code = " + code.substring(0, 10));
|
||||
logger.info("Params are client_id = " + clientId + ", client_secret = " + clientSecret.substring(0, 10) +
|
||||
"*******************"+ ", redirect_uri = " +redirectUri + ", code = " + code.substring(0, 10) + "*******************" + ", grant_type = " + grantType);
|
||||
|
||||
try{
|
||||
// check if something is missing
|
||||
|
@ -167,7 +181,7 @@ public class OauthService {
|
|||
CacheBean entry = entries.get(code);
|
||||
if(!entry.getRedirectUri().equals(redirectUri) || !entry.getClientId().equals(clientId))
|
||||
return "invalid_grant";
|
||||
if(!grantType.equals("authorization_code"))
|
||||
if(!grantType.equals(GRANT_TYPE_VALUE))
|
||||
return "unsupported_grant_type";
|
||||
return null;
|
||||
}catch(Exception e){
|
||||
|
|
|
@ -9,17 +9,21 @@ import com.fasterxml.jackson.annotation.JsonProperty;
|
|||
* @author Costantino Perciante at ISTI-CNR (costantino.perciante@isti.cnr.it)
|
||||
*/
|
||||
public class AccessTokenErrorResponse {
|
||||
|
||||
|
||||
@NotNull
|
||||
@JsonProperty("error")
|
||||
private String error;
|
||||
|
||||
|
||||
@JsonProperty("error_description")
|
||||
private String errorDescription;
|
||||
|
||||
|
||||
@JsonProperty("error_uri")
|
||||
private String errorUri;
|
||||
|
||||
public AccessTokenErrorResponse() {
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param error
|
||||
* @param errorDescription
|
||||
|
|
|
@ -0,0 +1,56 @@
|
|||
package org.gcube.portal.oauth.request.filter;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.annotation.Priority;
|
||||
import javax.ws.rs.container.ContainerRequestContext;
|
||||
import javax.ws.rs.container.ContainerRequestFilter;
|
||||
import javax.ws.rs.core.Context;
|
||||
import javax.ws.rs.core.Form;
|
||||
import javax.ws.rs.core.MultivaluedMap;
|
||||
import javax.ws.rs.core.UriInfo;
|
||||
import javax.ws.rs.ext.Provider;
|
||||
|
||||
import org.gcube.portal.oauth.OauthService;
|
||||
import org.glassfish.jersey.server.internal.InternalServerProperties;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* This filter is used to manage request directed to the method "access-token".
|
||||
* It maps the "security_code" of the request into the gcube-token and then redirect this call
|
||||
* to the SmartGears's filters. Please note that FormParams are put by previous filters under
|
||||
* a property named InternalServerProperties.FORM_DECODED_PROPERTY.
|
||||
*/
|
||||
@Provider
|
||||
@Priority(value = 0) // it should be the highest (so that it is called before the smartgears'one)
|
||||
public class OauthFilter implements ContainerRequestFilter{
|
||||
|
||||
private static final org.slf4j.Logger logger = LoggerFactory.getLogger(OauthFilter.class);
|
||||
|
||||
@Context UriInfo info;
|
||||
|
||||
@Override
|
||||
public void filter(ContainerRequestContext requestContext)
|
||||
throws IOException {
|
||||
|
||||
logger.debug("Filter oauth called, checking the called method");
|
||||
logger.debug("Request method type is " + requestContext.getMethod());
|
||||
String pathRequest = info.getAbsolutePath().toString();
|
||||
logger.debug("Requested method url is " + info.getAbsolutePath());
|
||||
|
||||
if(pathRequest.endsWith(OauthService.OAUTH_TOKEN_GET_METHOD_NAME_REQUEST)){
|
||||
|
||||
Form propertiesForm = (Form)requestContext.getProperty(InternalServerProperties.FORM_DECODED_PROPERTY);
|
||||
MultivaluedMap<String, String> map = propertiesForm.asMap();
|
||||
logger.debug("Request form parameters are " + map);
|
||||
|
||||
if(map.containsKey("client_secret")){
|
||||
requestContext.getHeaders().add("gcube-token", map.get("client_secret").get(0));
|
||||
}else{
|
||||
logger.error("Parameter client_secret is missing");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
<application mode='online'>
|
||||
<name>oauth</name>
|
||||
<group>Portal</group>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
<description>gCube OAUTH Service</description>
|
||||
<local-persistence location='target' />
|
||||
<exclude>/v2/check</exclude>
|
||||
</application>
|
|
@ -1,7 +1,25 @@
|
|||
<!DOCTYPE web-app PUBLIC
|
||||
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
|
||||
"http://java.sun.com/dtd/web-app_2_3.dtd" >
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
|
||||
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
|
||||
version="3.0">
|
||||
|
||||
<web-app>
|
||||
<display-name>Archetype Created Web Application</display-name>
|
||||
<display-name>RESTFul Web Service - OAUTH</display-name>
|
||||
<servlet>
|
||||
<servlet-name>jersey-servlet</servlet-name>
|
||||
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
|
||||
<init-param>
|
||||
<param-name>jersey.config.server.provider.packages</param-name>
|
||||
<param-value>org.gcube.portal.oauth,org.gcube.portal.oauth.filter</param-value>
|
||||
</init-param>
|
||||
<load-on-startup>1</load-on-startup>
|
||||
</servlet>
|
||||
<servlet-mapping>
|
||||
<servlet-name>jersey-servlet</servlet-name>
|
||||
<url-pattern>/*</url-pattern>
|
||||
</servlet-mapping>
|
||||
<welcome-file-list>
|
||||
<welcome-file>index.jsp</welcome-file>
|
||||
</welcome-file-list>
|
||||
</web-app>
|
||||
|
||||
|
|
Loading…
Reference in New Issue