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:
Lucio Lelii 2019-03-21 13:39:33 +00:00
parent 841a078d43
commit 4f2d348682
2 changed files with 65 additions and 10 deletions

View File

@ -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;
}
}

View File

@ -2,19 +2,23 @@ package org.gcube.portal.oauth;
import static org.gcube.common.authorization.client.Constants.authorizationService;
import java.net.URLDecoder;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import javax.inject.Singleton;
import javax.servlet.http.HttpServletRequest;
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;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
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.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.output.AccessTokenBeanResponse;
import org.gcube.portal.oauth.output.AccessTokenErrorResponse;
import org.gcube.smartgears.Constants;
import org.slf4j.LoggerFactory;
@ -36,6 +41,9 @@ 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 String AUTHORIZATION_HEADER = "Authorization";
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("redirect_uri") String redirectUri,
@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;
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{
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
String errorMessage = checkRequest(clientId, clientSecret, redirectUri, code, grantType);
String errorMessage = checkRequest(credentials, redirectUri, code, grantType, request);
if(errorMessage != null){
logger.error("The request fails because of " + errorMessage);
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
* @param clientId
@ -195,19 +227,19 @@ public class OauthService {
* @param grantType
* @return see https://tools.ietf.org/html/rfc6749#section-5.2
*/
private String checkRequest(String clientId, String clientSecret,
String redirectUri, String code, String grantType) {
private String checkRequest(CredentialsBean credentials,
String redirectUri, String code, String grantType, HttpServletRequest request) {
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";
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";
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";
if(!entries.containsKey(code) || CacheBean.isExpired(entries.get(code)))
return "invalid_grant";
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";
if(!grantType.equals(GRANT_TYPE_VALUE))
return "unsupported_grant_type";