added cliend_id and clent_secret parameter passed as Basic Authorization in header to make it oauth2 compliant
git-svn-id: http://svn.research-infrastructures.eu/public/d4science/gcube/trunk/portal/oauth@178642 82a268e6-3cf1-43bd-a215-b396298e98cf
This commit is contained in:
parent
841a078d43
commit
4f2d348682
|
@ -0,0 +1,23 @@
|
||||||
|
package org.gcube.portal.oauth;
|
||||||
|
|
||||||
|
public class CredentialsBean {
|
||||||
|
|
||||||
|
private String clientId;
|
||||||
|
private String clientSecret;
|
||||||
|
|
||||||
|
public CredentialsBean(String clientId, String clientSecret) {
|
||||||
|
super();
|
||||||
|
this.clientId = clientId;
|
||||||
|
this.clientSecret = clientSecret;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getClientId() {
|
||||||
|
return clientId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getClientSecret() {
|
||||||
|
return clientSecret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -2,19 +2,23 @@ package org.gcube.portal.oauth;
|
||||||
|
|
||||||
import static org.gcube.common.authorization.client.Constants.authorizationService;
|
import static org.gcube.common.authorization.client.Constants.authorizationService;
|
||||||
|
|
||||||
|
import java.net.URLDecoder;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
import javax.inject.Singleton;
|
import javax.inject.Singleton;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import javax.ws.rs.Consumes;
|
import javax.ws.rs.Consumes;
|
||||||
import javax.ws.rs.FormParam;
|
import javax.ws.rs.FormParam;
|
||||||
import javax.ws.rs.GET;
|
import javax.ws.rs.GET;
|
||||||
import javax.ws.rs.POST;
|
import javax.ws.rs.POST;
|
||||||
import javax.ws.rs.Path;
|
import javax.ws.rs.Path;
|
||||||
import javax.ws.rs.Produces;
|
import javax.ws.rs.Produces;
|
||||||
|
import javax.ws.rs.core.Context;
|
||||||
import javax.ws.rs.core.MediaType;
|
import javax.ws.rs.core.MediaType;
|
||||||
import javax.ws.rs.core.Response;
|
import javax.ws.rs.core.Response;
|
||||||
import javax.ws.rs.core.Response.Status;
|
import javax.ws.rs.core.Response.Status;
|
||||||
|
import javax.xml.bind.DatatypeConverter;
|
||||||
|
|
||||||
import org.gcube.common.authorization.library.ClientType;
|
import org.gcube.common.authorization.library.ClientType;
|
||||||
import org.gcube.common.authorization.library.provider.AuthorizationProvider;
|
import org.gcube.common.authorization.library.provider.AuthorizationProvider;
|
||||||
|
@ -26,6 +30,7 @@ import org.gcube.portal.oauth.cache.CacheCleaner;
|
||||||
import org.gcube.portal.oauth.input.PushCodeBean;
|
import org.gcube.portal.oauth.input.PushCodeBean;
|
||||||
import org.gcube.portal.oauth.output.AccessTokenBeanResponse;
|
import org.gcube.portal.oauth.output.AccessTokenBeanResponse;
|
||||||
import org.gcube.portal.oauth.output.AccessTokenErrorResponse;
|
import org.gcube.portal.oauth.output.AccessTokenErrorResponse;
|
||||||
|
import org.gcube.smartgears.Constants;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
|
||||||
|
@ -36,6 +41,9 @@ public class OauthService {
|
||||||
public static final String OAUTH_TOKEN_GET_METHOD_NAME_REQUEST = "access-token";
|
public static final String OAUTH_TOKEN_GET_METHOD_NAME_REQUEST = "access-token";
|
||||||
private static final String GRANT_TYPE_VALUE = "authorization_code";
|
private static final String GRANT_TYPE_VALUE = "authorization_code";
|
||||||
|
|
||||||
|
private static final String AUTHORIZATION_HEADER = "Authorization";
|
||||||
|
|
||||||
|
|
||||||
private static final org.slf4j.Logger logger = LoggerFactory.getLogger(OauthService.class);
|
private static final org.slf4j.Logger logger = LoggerFactory.getLogger(OauthService.class);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -158,17 +166,29 @@ public class OauthService {
|
||||||
@FormParam("client_secret") String clientSecret, // i.e., application token
|
@FormParam("client_secret") String clientSecret, // i.e., application token
|
||||||
@FormParam("redirect_uri") String redirectUri,
|
@FormParam("redirect_uri") String redirectUri,
|
||||||
@FormParam("code") String code,
|
@FormParam("code") String code,
|
||||||
@FormParam("grant_type") String grantType // it must always be equal to "authorization_code"
|
@FormParam("grant_type") String grantType, // it must always be equal to "authorization_code"
|
||||||
|
@Context HttpServletRequest request
|
||||||
){
|
){
|
||||||
|
|
||||||
Status status = Status.BAD_REQUEST;
|
Status status = Status.BAD_REQUEST;
|
||||||
logger.info("Request to exchange code for token");
|
logger.info("Request to exchange code for token");
|
||||||
logger.info("Params are client_id = " + clientId + ", client_secret = " + clientSecret +
|
|
||||||
"*******************"+ ", redirect_uri = " +redirectUri + ", code = " + code + "*******************" + ", grant_type = " + grantType);
|
|
||||||
|
|
||||||
try{
|
try{
|
||||||
|
CredentialsBean credentials = new CredentialsBean(clientId, clientSecret);
|
||||||
|
|
||||||
|
if (clientId == null)
|
||||||
|
credentials = getCredentialFromBasicAuthorization(request);
|
||||||
|
else if (request.getHeader(AUTHORIZATION_HEADER)!=null)
|
||||||
|
throw new Exception("he client MUST NOT use more than one authentication method");
|
||||||
|
|
||||||
|
logger.info("Params are client_id = " + credentials.getClientId() + ", client_secret = " + credentials.getClientSecret() +
|
||||||
|
"*******************"+ ", redirect_uri = " +redirectUri + ", code = " + code + "*******************" + ", grant_type = " + grantType);
|
||||||
|
|
||||||
// check if something is missing
|
// check if something is missing
|
||||||
String errorMessage = checkRequest(clientId, clientSecret, redirectUri, code, grantType);
|
String errorMessage = checkRequest(credentials, redirectUri, code, grantType, request);
|
||||||
|
|
||||||
if(errorMessage != null){
|
if(errorMessage != null){
|
||||||
logger.error("The request fails because of " + errorMessage);
|
logger.error("The request fails because of " + errorMessage);
|
||||||
return Response.status(status).entity(new AccessTokenErrorResponse(errorMessage, null)).build();
|
return Response.status(status).entity(new AccessTokenErrorResponse(errorMessage, null)).build();
|
||||||
|
@ -186,6 +206,18 @@ public class OauthService {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private CredentialsBean getCredentialFromBasicAuthorization(HttpServletRequest request) {
|
||||||
|
String basicAuthorization = request.getHeader(AUTHORIZATION_HEADER);
|
||||||
|
String base64Credentials = basicAuthorization.substring("Basic".length()).trim();
|
||||||
|
String credentials = new String(DatatypeConverter.parseBase64Binary(base64Credentials));
|
||||||
|
// credentials = username:password
|
||||||
|
String[] splitCreds = credentials.split(":");
|
||||||
|
String clientId = URLDecoder.decode(splitCreds[0]);
|
||||||
|
String clientSecret = URLDecoder.decode(splitCreds[1]);
|
||||||
|
return new CredentialsBean(clientId, clientSecret);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check request parameters
|
* Check request parameters
|
||||||
* @param clientId
|
* @param clientId
|
||||||
|
@ -195,19 +227,19 @@ public class OauthService {
|
||||||
* @param grantType
|
* @param grantType
|
||||||
* @return see https://tools.ietf.org/html/rfc6749#section-5.2
|
* @return see https://tools.ietf.org/html/rfc6749#section-5.2
|
||||||
*/
|
*/
|
||||||
private String checkRequest(String clientId, String clientSecret,
|
private String checkRequest(CredentialsBean credentials,
|
||||||
String redirectUri, String code, String grantType) {
|
String redirectUri, String code, String grantType, HttpServletRequest request) {
|
||||||
try{
|
try{
|
||||||
if(clientId == null || clientSecret == null || redirectUri == null || code == null || grantType == null)
|
if(credentials.getClientId() == null || credentials.getClientSecret() == null || redirectUri == null || code == null || grantType == null )
|
||||||
return "invalid_request";
|
return "invalid_request";
|
||||||
if(clientId.isEmpty() || clientSecret.isEmpty() || redirectUri.isEmpty() || code.isEmpty() || grantType.isEmpty())
|
if(credentials.getClientId().isEmpty() || credentials.getClientSecret().isEmpty() || redirectUri.isEmpty() || code.isEmpty() || grantType.isEmpty())
|
||||||
return "invalid_request";
|
return "invalid_request";
|
||||||
if(!checkIsapplicationTokenType(authorizationService().get(clientSecret).getClientInfo().getType())) // it is not an app token or it is not a token
|
if(!checkIsapplicationTokenType(authorizationService().get(credentials.getClientSecret()).getClientInfo().getType())) // it is not an app token or it is not a token
|
||||||
return "invalid_client";
|
return "invalid_client";
|
||||||
if(!entries.containsKey(code) || CacheBean.isExpired(entries.get(code)))
|
if(!entries.containsKey(code) || CacheBean.isExpired(entries.get(code)))
|
||||||
return "invalid_grant";
|
return "invalid_grant";
|
||||||
CacheBean entry = entries.get(code);
|
CacheBean entry = entries.get(code);
|
||||||
if(!entry.getRedirectUri().equals(redirectUri) || !entry.getClientId().equals(clientId))
|
if(!entry.getRedirectUri().equals(redirectUri) || !entry.getClientId().equals(credentials.getClientId()))
|
||||||
return "invalid_grant";
|
return "invalid_grant";
|
||||||
if(!grantType.equals(GRANT_TYPE_VALUE))
|
if(!grantType.equals(GRANT_TYPE_VALUE))
|
||||||
return "unsupported_grant_type";
|
return "unsupported_grant_type";
|
||||||
|
|
Loading…
Reference in New Issue